{% extends '@EasyAdmin/page/content.html.twig' %} {% block page_title %}{{ produit.name }}{% endblock %} {% block main %} {% import '_graphiques.html.twig' as graph %} {% set niveau = ea_niveau_alerte(produit.stock, produit.association) %}

{{ produit.name }}

{% if produit.rayon %}{{ produit.rayon.label }} · {% endif %} {{ produit.sellingPrice|number_format(2, ',', ' ') }} € {%- if suitLaMarge and produit.purchasePrice %} · achat {{ produit.purchasePrice|number_format(2, ',', ' ') }} €{% endif %}
Stock actuel {% if niveau %} {{ produit.stock }} {% else %}{{ produit.stock }}{% endif %}
CA cette semaine {{ dossier.semaine.chiffreAffaires|number_format(2, ',', ' ') }} €
Vendus — {{ periode.libelle|lower }} {{ dossier.quantite }}
CA — {{ periode.libelle|lower }} {{ dossier.chiffreAffaires|number_format(2, ',', ' ') }} €

Évolution sur deux semaines

Cette semaine {{ dossier.evolution.actuel|number_format(2, ',', ' ') }} €
{{ dossier.evolution.libellePrecedent }} {{ dossier.evolution.precedent|number_format(2, ',', ' ') }} €
Variation {% if dossier.evolution.variation is null %} — {% else %} {{ dossier.evolution.variation > 0 ? '+' : '' }}{{ dossier.evolution.variation|number_format(1, ',', ' ') }} % {% endif %}

Ruptures — {{ periode.libelle|lower }}

Jours à zéro {{ dossier.ruptures.rupture }}
Jours en négatif {{ dossier.ruptures.decrochage }}
Ventes perduesestimation {{ dossier.perdues.quantite }}
{% if dossier.perdues.quantite > 0 %}

Estimation, pas mesure : {{ dossier.perdues.joursSansStock }} jour{{ dossier.perdues.joursSansStock > 1 ? 's' : '' }} sans stock × {{ dossier.perdues.moyenneParJour|number_format(2, ',', ' ') }} vendus un jour ordinaire.

{% endif %}
{# ===== Son année ==================================================== Indépendante du filtre de période de l'écran : une saisonnalité ne se voit que sur douze mois, et on ne va pas demander à l'utilisateur de changer de filtre pour la trouver. #}

Son année

{{ dossier.annee.libelle }} · quantités vendues
{{ graph.batons(dossier.annee.parMois) }}

Douze mois, même ceux sans vente : c'est ce qui rend un creux visible. Les mois à venir portent un tiret.

{% if dossier.annee.parJourDOuverture|length > 1 %}

Ses jours

quantités
{{ graph.batons(dossier.annee.parJourDOuverture) }}

Sur quelle récré ce produit-là se vend. Un jour faible n'appelle pas la même décision qu'un produit faible : c'est peut-être l'assortiment de ce jour-là qu'il faut revoir.

{% endif %}

Ce qu'il pèse

part du chiffre de l'année

Ce que ce produit représente dans la recette de l'association sur l'année. C'est cette part qui dit si une rupture se verrait — ou passerait inaperçue.

{# L'historique du stock jour par jour : c'est lui qui montre *quand* le produit a manqué, ce qu'un stock actuel ne dira jamais. #} {% if dossier.parJour|length > 1 %}

Le stock jour par jour

{% set maxi = max(dossier.parJour|map(v => v > 0 ? v : 0)) %} {% for jour, stock in dossier.parJour %}
{% endfor %}

Une barre rouge signale un jour à zéro ou en négatif. Le stock est reconstruit depuis le journal des mouvements ; il ne remonte pas avant la première écriture du produit, parce qu'avant elle on ne sait rien.

{% endif %}

Mouvements de stock

{{ mouvements|length }} sur la période
{% for mouvement in mouvements|reverse %} {% else %} {% endfor %}
DateTypeQuantitéMotifPar
{{ mouvement.createdAt|date('d/m/Y H:i') }} {{ mouvement.type.label }} {{ mouvement.quantity > 0 ? '+' : '' }}{{ mouvement.quantity }} {{ mouvement.reason ?: '—' }} {% if mouvement.createdBy %}{{ mouvement.createdBy.firstName }} {{ mouvement.createdBy.lastName }}{% else %}—{% endif %}
Aucun mouvement sur la période.

Retour à la liste

{% endblock %}