feat(fournée): ajoute une gestion du conditionnement pour faciliter les dosages
This commit is contained in:
parent
ee076ef6d7
commit
790678bf1b
@ -33,8 +33,8 @@ admin_site.register(models.Pain, PainAdmin)
|
||||
|
||||
|
||||
class FournitureAdmin(admin.ModelAdmin):
|
||||
list_display = ["nom", "ordre", "couleur"]
|
||||
list_editable = ["ordre", "couleur"]
|
||||
list_display = ["nom", "ordre", "couleur", "conditionnement", "emballage"]
|
||||
list_editable = ["ordre", "couleur", "conditionnement", "emballage"]
|
||||
actions = None
|
||||
save_as = True
|
||||
|
||||
@ -229,16 +229,16 @@ class FournéeAdmin(nested_admin.NestedModelAdmin):
|
||||
""" on créé les tableaux coulée / ingrédient """
|
||||
extra_context["coulées"] = []
|
||||
for c in obj.coulée_set.all():
|
||||
quantités = [c, ]
|
||||
ingrédients = c.pâte.ingrédient_set.values_list(
|
||||
'fourniture__nom',
|
||||
'fourniture__couleur'
|
||||
)
|
||||
for i, _ in ingrédients:
|
||||
quantités.append((c.quantité / c.pâte.poids_de_base * sum(
|
||||
c.pâte.ingrédient_set.filter(fourniture__nom=i)
|
||||
.values_list("quantité", flat=True)
|
||||
)).quantize(Decimal('1.000')).normalize())
|
||||
quantités = [[None, c]]
|
||||
ingrédients = c.pâte.ingrédient_set.all()
|
||||
for i in ingrédients:
|
||||
quantités.append([
|
||||
i,
|
||||
(c.quantité / c.pâte.poids_de_base * sum(
|
||||
c.pâte.ingrédient_set.filter(pk=i.pk)
|
||||
.values_list("quantité", flat=True)
|
||||
)).quantize(Decimal('1.000')).normalize(),
|
||||
])
|
||||
|
||||
masse_coulée = sum(
|
||||
obj.coulée_set.filter(pâte=c.pâte).values_list(
|
||||
@ -276,7 +276,9 @@ class FournéeAdmin(nested_admin.NestedModelAdmin):
|
||||
pk__in=obj.commande_set.exclude(réservation__isnull=True)
|
||||
.values_list("pains", flat=True)
|
||||
).values_list("nom", flat=True)
|
||||
totaux = [sum(obj.coulée_set.values_list('quantité', flat=True))]
|
||||
totaux = [
|
||||
[None, sum(obj.coulée_set.values_list('quantité', flat=True))]
|
||||
]
|
||||
for i in ingrédients:
|
||||
total = sum([
|
||||
qté * qté_unit / unit
|
||||
@ -290,7 +292,7 @@ class FournéeAdmin(nested_admin.NestedModelAdmin):
|
||||
'pâte__poids_de_base',
|
||||
)
|
||||
]).quantize(Decimal('1.000')).normalize()
|
||||
totaux.append(total)
|
||||
totaux.append([i, total])
|
||||
extra_context["totaux_coulées"] = totaux
|
||||
|
||||
""" liste des pains, vérifiant s'ils sont coulés """
|
||||
|
17
fournée/core/migrations/0014_fourniture_emballage.py
Normal file
17
fournée/core/migrations/0014_fourniture_emballage.py
Normal file
@ -0,0 +1,17 @@
|
||||
# Generated by Django 4.2.13 on 2024-05-14 16:56
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
dependencies = [
|
||||
("core", "0013_alter_fourniture_nom"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="fourniture",
|
||||
name="emballage",
|
||||
field=models.CharField(blank=True, max_length=64),
|
||||
),
|
||||
]
|
@ -33,6 +33,8 @@ class Fourniture(models.Model):
|
||||
nom = models.CharField(max_length=64, unique=True)
|
||||
ordre = models.SmallIntegerField(default=0)
|
||||
couleur = ColorField(default='#000000')
|
||||
conditionnement = models.DecimalField(max_digits=6, decimal_places=3)
|
||||
emballage = models.CharField(max_length=64, blank=True)
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.nom}"
|
||||
|
@ -1,6 +1,7 @@
|
||||
from django import template
|
||||
from django.contrib.admin.templatetags.admin_modify import submit_row
|
||||
from django.contrib.admin.templatetags.base import InclusionAdminNode
|
||||
from django.utils.safestring import mark_safe
|
||||
|
||||
register = template.Library()
|
||||
|
||||
@ -12,4 +13,29 @@ def submit_row_tag(parser, token):
|
||||
)
|
||||
|
||||
|
||||
@register.simple_tag
|
||||
def emballe(quantité, fourniture):
|
||||
quotient = quantité // fourniture.conditionnement
|
||||
reste = quantité % fourniture.conditionnement
|
||||
if not quotient and reste < fourniture.conditionnement/2:
|
||||
return None
|
||||
if quotient == 1 and reste < fourniture.conditionnement/2:
|
||||
return f"{quotient} {fourniture.emballage} et {reste} kg"
|
||||
if quotient > 1 and reste < fourniture.conditionnement/2:
|
||||
return f"{quotient} {fourniture.emballage}s et {reste} kg"
|
||||
|
||||
retrait = fourniture.conditionnement - reste
|
||||
if not quotient and reste >= fourniture.conditionnement/2:
|
||||
return f"{quotient + 1} {fourniture.emballage} moins {retrait} kg"
|
||||
if quotient == 1 and reste >= fourniture.conditionnement/2:
|
||||
return mark_safe(
|
||||
f"{quotient} {fourniture.emballage} et {reste} kg"
|
||||
"<br>ou</br>"
|
||||
f"{quotient + 1} {fourniture.emballage}s moins {retrait} kg"
|
||||
)
|
||||
if quotient > 1 and reste >= fourniture.conditionnement/2:
|
||||
return mark_safe(
|
||||
f"{quotient} {fourniture.emballage}s et {reste} kg"
|
||||
"<br>ou</br>"
|
||||
f"{quotient + 1} {fourniture.emballage}s moins {retrait} kg"
|
||||
)
|
||||
|
@ -5,6 +5,14 @@
|
||||
|
||||
{% block submit_buttons_bottom %}{% fournée_submit_row %}{% endblock %}
|
||||
|
||||
|
||||
{% block extrahead %}{{ block.super }}
|
||||
<style>
|
||||
.alt { display: none}
|
||||
.fournee-alternative.fournee-show > .alt { display: inline; }
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
{% block after_field_sets %}
|
||||
{% if commandes %}
|
||||
<h2>Résumé des commandes</h2>
|
||||
@ -30,11 +38,13 @@
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
{% for p in totaux_coulées %}
|
||||
{% for i, p in totaux_coulées %}
|
||||
{% if forloop.first %}
|
||||
<th>Total pain : {{p}} kg</th>
|
||||
{% else %}
|
||||
<th scope="col" style="text-align:center">{{ p }}</th>
|
||||
<th scope="col" style="text-align:center">
|
||||
{{ p }} kg
|
||||
</th>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</tr>
|
||||
@ -42,23 +52,36 @@
|
||||
</table>
|
||||
<div style="display:inline-grid">
|
||||
{% for problems, ingrédients, quantités in coulées %}
|
||||
<h3 style="margin-top: 2em;{% if problems %} color: var(--delete-button-hover-bg);{% endif %}">{{ quantités.0 }}{% if problems %} ({{ problems }}){% endif %}</h3>
|
||||
<h3 style="margin-top: 2em;{% if problems %} color: var(--delete-button-hover-bg);{% endif %}">{{ quantités.0.1 }}{% if problems %} ({{ problems }}){% endif %}</h3>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
{% for i, c in ingrédients %}
|
||||
<th scope="col" style="text-align:center;{% if c != '#000000' %} background-color: {{ c }};{% endif %}">{{ i }}</th>
|
||||
{% for i in ingrédients %}
|
||||
<th scope="col" style="text-align:center;{% if i.fourniture.couleur != '#000000' %} background-color: {{ i.fourniture.couleur }};{% endif %}">{{ i.fourniture.nom }}</th>
|
||||
{% endfor %}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
{% for q in quantités %}
|
||||
{% for i, q in quantités %}
|
||||
{% if forloop.first %}
|
||||
<th scope="row">{{ q.pâte.nom }}</th>
|
||||
{% else %}
|
||||
<td style="text-align:center">{{ q }}</td>
|
||||
{% if i.fourniture.conditionnement %}
|
||||
{% emballe q i.fourniture as alt %}
|
||||
{% if alt %}
|
||||
<td style="text-align:center" class="fournee-alternative">
|
||||
{{ q }} kg
|
||||
<img style="vertical-align:top;" src="{% static "admin/img/icon-viewlink.svg" %}" alt="symbole œil" title="Bascule l'affichage avec ou sans conditionnement">
|
||||
<span class="alt"><br>({{ alt }})</span>
|
||||
</td>
|
||||
{% else %}
|
||||
<td style="text-align:center">
|
||||
{{ q }} kg
|
||||
</td>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</tr>
|
||||
@ -103,4 +126,14 @@
|
||||
</table>
|
||||
<p></p>
|
||||
{% endif %}
|
||||
|
||||
<script>
|
||||
const qtes = document.querySelectorAll(".fournee-alternative");
|
||||
|
||||
qtes.forEach(function (qte) {
|
||||
qte.addEventListener("click", (event) => {
|
||||
event.target.classList.toggle("fournee-show");
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
Loading…
Reference in New Issue
Block a user