Stock Consommables
{{ alertsCount }} alerte(s) de stock bas
Chargement...
📦
{{ dashboard.stats.total_products }}
Produits
✅
{{ dashboard.stats.movements_today }}
Mouvements aujourd'hui
⚠
{{ dashboard.stats.alerts_count }}
Alertes reappro
❌
{{ dashboard.stats.stock_zero }}
Stock a zero
Activite 30 jours
{{ shortDate(d.jour) }}
Entrees
Sorties
Aucune donnee
Derniers mouvements
Aucun mouvement
{{ m.nom_commercial || m.libelle }}
{{ formatDateShort(m.created_at) }} - {{ m.operateur || '-' }}
Top produits (7j)
Aucune donnee
{{ p.nom_commercial }}
{{ p.client }} - {{ p.nb_mouvements }} ops
+{{ p.total_in }}
-{{ p.total_out }}
Par operateur (7j)
Aucune donnee
{{ op.operateur }}
{{ op.nb_ops }} ops
{{ op.total_qty }} unites
{{ rapidCount }} op(s)
{{ scannedProduct.libelle || scannedProduct.nom_commercial }}
{{ typeLabel(scannedType) }}Format
{{ scannedProduct.format_conditionnement || '-' }}
Poids etiq. unitaire
{{ scannedType === 'etiq_fiole' ? scannedProduct.poids_etiq_fiole : scannedProduct.poids_etiq_boite }} g
Poids mandrin
{{ scannedType === 'etiq_fiole' ? scannedProduct.poids_mandrin_etiq_fiole : scannedProduct.poids_mandrin_etiq_boite }} g
Poids boite ind.
{{ scannedProduct.poids_boite_ind }} g
Stock actuel
{{ currentStock }}
Client
{{ scannedProduct.client || '-' }}
Emplacement
{{ scannedProduct.emplacement || '-' }}
0 && updateStock(rapidMode ? rapidOperation : 'add')"
class="flex-1 rounded-lg border border-slate-300 px-4 py-2.5 text-sm focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-transparent">
grammes
Quantite calculee : {{ calculatedQty }} unites
{{ scanMessage.text }}
Dernieres operations de la session
{{ op.product }}
{{ op.op === 'add' ? '+' : '-' }}{{ op.qty }}
{{ op.stockAfter }}
{{ op.time }}
Reapprovisionnement
{{ alertDetails.length }} alerte(s)Chargement...
Aucune alerte. Tous les stocks sont au-dessus des seuils.
Configurez les seuils via l'onglet "Gerer les seuils" ci-dessus.
Configurez les seuils via l'onglet "Gerer les seuils" ci-dessus.
| Client | Produit | Type | Stock | Seuil | Manquant | Fournisseur | Emplacement |
|---|---|---|---|---|---|---|---|
| {{ a.client }} | {{ a.nom_commercial }} | {{ typeLabel(a.alertType) }} | {{ a.stock }} | {{ a.seuil }} | {{ a.manquant }} | {{ a.fournisseur || '-' }} | {{ a.emplacement || '-' }} |
Modifiez les seuils directement dans le tableau puis cliquez sur Sauvegarder. Les champs modifies apparaissent en surbrillance.
Chargement...
| Client | Produit | Gamme | Stock Fioles | Seuil Fioles | Stock Boites | Seuil Boites | Stock Bt. Ind. | Seuil Bt. Ind. |
|---|---|---|---|---|---|---|---|---|
| Aucun produit. | ||||||||
| {{ p.client || '-' }} | {{ p.nom_commercial || p.libelle }} | {{ p.gamme || '-' }} | {{ p.stock_etiq_fiole ?? 0 }} | {{ p.stock_etiq_boite ?? 0 }} | {{ p.stock_boite_ind ?? 0 }} | |||
Produits ({{ productsTotal }})
| Client | Gamme | Nom commercial | Format | Stock Fioles | Stock Boites | Stock Bt. Ind. | Emplacement | Actions |
|---|---|---|---|---|---|---|---|---|
| Chargement... | ||||||||
| Aucun produit. | ||||||||
| {{ p.client }} | {{ p.gamme }} | {{ p.nom_commercial }} | {{ p.format_conditionnement }} | {{ p.stock_etiq_fiole || 0 }} | {{ p.stock_etiq_boite || 0 }} | {{ p.stock_boite_ind || 0 }} | {{ p.emplacement || '-' }} | Archive |
{{ productsPage }} / {{ productsPages }}
Modifications produits ({{ editsTotal }})
| Date | Utilisateur | Produit | Champ | Ancienne valeur | Nouvelle valeur | Actions |
|---|---|---|---|---|---|---|
| Chargement... | ||||||
| Aucune modification. | ||||||
| {{ formatDate(e.created_at) }} | {{ e.user_nom }} | {{ e.nom_commercial || e.libelle }} {{ e.client }} |
{{ fieldLabel(e.champ) }} | {{ e.ancienne_valeur || '(vide)' }} | {{ e.nouvelle_valeur || '(vide)' }} | Annule par {{ e.annule_par }} |
{{ editsPage }} / {{ editsPages }}
Previsions de consommation
{{ forecasts.length }} produit(s)Estimation du nombre de jours avant d'atteindre le seuil de reappro, basee sur la consommation nette (sorties - entrees) de la periode.
Chargement...
Aucune consommation detectee sur cette periode.
| Client | Produit | Type | Stock | Seuil | Conso/jour | Entrees/jour | Flux net/jour | Jours restants | Emplacement |
|---|---|---|---|---|---|---|---|---|---|
| {{ f.client || '-' }} | {{ f.nom_commercial || f.libelle }} | {{ typeLabel(f.type) }} | {{ f.stock_actuel }} | {{ f.seuil || '-' }} | -{{ f.conso_moy_jour }} | +{{ f.entrees_moy_jour }} | -{{ f.flux_net_jour }}/j Stable | {{ forecastLabel(f.jours_restants) }} | {{ f.emplacement || '-' }} |
Inventaires physiques
Chargement...
Aucun inventaire. Cliquez sur "Nouvel inventaire" pour commencer.
| # | Nom | Cree par | Date | Progression | Statut | Actions |
|---|---|---|---|---|---|---|
| {{ inv.id }} | {{ inv.nom }} | {{ inv.user_nom }} | {{ new Date(inv.created_at).toLocaleDateString('fr-FR') }} |
{{ inv.counted_lines || 0 }}/{{ inv.total_lines || 0 }}
|
{{ inv.statut === 'en_cours' ? 'En cours' : inv.statut === 'termine' ? 'Termine' : 'Annule' }} |
{{ currentInventory.nom }}
{{ currentInventory.statut === 'en_cours' ? 'En cours' : 'Termine' }}📋
{{ inventoryStats.total }}
Lignes total
✅
{{ inventoryStats.counted }}
Comptees
⚠
{{ inventoryStats.ecarts }}
Avec ecart
📊
{{ inventoryStats.total > 0 ? Math.round(inventoryStats.counted / inventoryStats.total * 100) : 0 }}%
Progression
Chargement...
| Client | Produit | Type | Emplacement | Stock theorique | Stock reel | Ecart | Ajuste |
|---|---|---|---|---|---|---|---|
| {{ line.client || '-' }} | {{ line.nom_commercial || line.libelle }} | {{ line.type === 'etiq_fiole' ? 'Etiq. fiole' : line.type === 'etiq_boite' ? 'Etiq. boite' : 'Boite ind.' }} | {{ line.emplacement || '-' }} | {{ line.stock_theorique }} | {{ line.stock_reel !== null ? line.stock_reel : '-' }} | {{ line.ecart > 0 ? '+' : '' }}{{ line.ecart }} 0 - | Oui |
Ecarts de stock
{{ discrepancies.length }} ecart(s)
Periode :
Produits ayant plus de sorties que d'entrees (mouvements non annules). Sans filtre de dates = depuis le debut.
| Client | Produit | Type | Entrees | Sorties | Ecart | Stock actuel | Derniere sortie | Emplacement |
|---|---|---|---|---|---|---|---|---|
| Chargement... | ||||||||
| Aucun ecart detecte. Tous les produits ont autant ou plus d'entrees que de sorties. | ||||||||
| {{ d.client }} | {{ d.nom_commercial || d.libelle }} | {{ typeLabel(d.type) }} | +{{ d.total_entrees }} | -{{ d.total_sorties }} | -{{ d.delta }} | {{ d.stock_actuel }} | {{ d.derniere_sortie ? formatDate(d.derniere_sortie) : '-' }} | {{ d.emplacement || '-' }} |
Historique ({{ historyTotal }})
Exporter CSV| Date | Produit | Type | Op. | Qte | Poids | Avant | Apres | Operateur | Actions |
|---|---|---|---|---|---|---|---|---|---|
| Chargement... | |||||||||
| Aucun mouvement. | |||||||||
| {{ formatDate(m.created_at) }} | {{ m.nom_commercial || m.libelle }} | {{ typeLabel(m.type) }} | {{ m.operation === 'add' ? '+ Ajout' : '- Retrait' }} | {{ m.quantity }} | {{ m.poids_saisi ? m.poids_saisi + ' g' : '-' }} | {{ m.stock_avant }} | {{ m.stock_apres }} | {{ m.operateur || '-' }} | Annule par {{ m.annule_par }} |
{{ historyPage }} / {{ historyPages }}
Utilisateurs
| Identifiant | Nom | Role | Statut | Cree le | Actions |
|---|---|---|---|---|---|
| Aucun utilisateur. | |||||
| {{ u.username }} | {{ u.nom }} | {{ u.role }} | {{ u.actif ? 'Actif' : 'Inactif' }} | {{ formatDate(u.created_at) }} | |
Chargement...
Destinataires des alertes
| Nom | Alerte seuil | Alerte prevision | Statut | Actions | |
|---|---|---|---|---|---|
| Aucun destinataire configure. | |||||
| {{ r.email }} | {{ r.nom || '—' }} | {{ r.notify_threshold ? 'Oui' : 'Non' }} | {{ r.notify_forecast ? 'Oui' : 'Non' }} | {{ r.actif ? 'Actif' : 'Inactif' }} | |
Historique des notifications (50 dernieres)
| Date | Type | Produit | Stock type | Stock | Seuil | Jours rest. | Envoye a |
|---|---|---|---|---|---|---|---|
| Aucune notification envoyee. | |||||||
| {{ formatDate(log.created_at) }} | {{ notifTypeLabel(log.type) }} | {{ log.nom_commercial || log.libelle || '—' }} | {{ notifStockTypeLabel(log.stock_type) }} | {{ log.stock_level }} | {{ log.seuil ?? '—' }} | {{ log.jours_restants != null ? log.jours_restants + 'j' : '—' }} | {{ log.email_sent_to }} |