🎯 Objectif du Guide
Ce guide fournit toutes les spécifications techniques nécessaires pour développer l'application complète, indépendamment de la technologie choisie.
⚠️ Important : Les exemples de code et structures de données sont fournis à titre indicatif. Vous êtes libre d'adapter selon votre stack technologique.
📊 Modèle de Données
Entité : Restaurant
{
id: string (unique),
nom: string,
type: "stock-principal" | "cuisine-centrale" | "restaurant",
adresse: string (optionnel),
telephone: string (optionnel),
email: string (optionnel),
actif: boolean,
dateCreation: date,
dateModification: date
}
Exemples :
{
id: "R001",
nom: "Stock Principal",
type: "stock-principal"
}
{
id: "R002",
nom: "Cuisine Centrale",
type: "cuisine-centrale"
}
{
id: "R003",
nom: "FF Paul Langevin",
type: "restaurant",
adresse: "Bd Paul Langevin, Abidjan"
}
Entité : Article
{
code: string (unique, clé primaire),
designation: string,
categorie: string,
unite: string,
typeArticle: "matiere-brute" | "produit-semi-fini",
format: string (optionnel - pour FF Koumassi),
prixUnitaireMoyen: number (optionnel),
actif: boolean,
dateCreation: date,
dateModification: date
}
Exemples :
// Matière brute
{
code: "LLC-MB-BOEUF-HACHE",
designation: "Bœuf haché frais",
categorie: "Viandes",
unite: "kg",
typeArticle: "matiere-brute",
actif: true
}
// Produit semi-fini
{
code: "LLC-SF-BOUL-BOEUF",
designation: "Boulettes de bœuf",
categorie: "Produits transformés",
unite: "pièce",
typeArticle: "produit-semi-fini",
actif: true
}
Entité : Nomenclature (Recette de Fabrication)
{
id: string (unique),
produitCode: string (référence Article),
produitDesignation: string,
quantiteBase: number,
uniteBase: string,
ingredients: [
{
articleCode: string (référence Article),
designation: string,
quantiteRequise: number,
unite: string
}
],
rendementAttendu: number (en %),
tempsFabrication: number (en minutes),
instructions: string (texte libre),
actif: boolean,
dateCreation: date,
dateModification: date
}
Exemple :
{
id: "NOM001",
produitCode: "LLC-SF-BOUL-BOEUF",
produitDesignation: "Boulettes de bœuf",
quantiteBase: 100,
uniteBase: "pièces de 110g",
ingredients: [
{
articleCode: "LLC-MB-BOEUF-HACHE",
designation: "Bœuf haché",
quantiteRequise: 12,
unite: "kg"
},
{
articleCode: "LLC-MB-EPICES",
designation: "Épices mélange",
quantiteRequise: 0.4,
unite: "kg"
},
{
articleCode: "LLC-MB-CHAPELURE",
designation: "Chapelure",
quantiteRequise: 1,
unite: "kg"
},
{
articleCode: "LLC-MB-OEUFS",
designation: "Œufs",
quantiteRequise: 10,
unite: "pièce"
}
],
rendementAttendu: 90,
tempsFabrication: 240,
instructions: "1. Mélanger tous les ingrédients\n2. Former les boulettes\n3. Cuire...",
actif: true
}
Entité : Lot
{
numeroLot: string (unique, format: LOT-YYYYMMDD-NNN),
articleCode: string (référence Article),
typeLot: "fournisseur" | "production",
// Si lot fournisseur
fournisseur: string (optionnel),
numeroLotFournisseur: string (optionnel),
// Si lot production
bonFabricationRef: string (optionnel),
quantiteInitiale: number,
quantiteRestante: number,
unite: string,
dateFabrication: date (ou date réception si fournisseur),
dateLimiteUtilisation: date (DLU),
statut: "disponible" | "partiellement-utilise" | "epuise" | "perime",
dateCreation: date,
dateModification: date
}
Exemples :
// Lot fournisseur
{
numeroLot: "LOT-FOUR-20250116-001",
articleCode: "LLC-MB-BOEUF-HACHE",
typeLot: "fournisseur",
fournisseur: "SOPAL",
numeroLotFournisseur: "SOL-20250116-BH",
quantiteInitiale: 100,
quantiteRestante: 64,
unite: "kg",
dateFabrication: "2025-01-16",
dateLimiteUtilisation: "2025-01-18",
statut: "partiellement-utilise"
}
// Lot production
{
numeroLot: "LOT-20250118-001",
articleCode: "LLC-SF-BOUL-BOEUF",
typeLot: "production",
bonFabricationRef: "BF-2025-001",
quantiteInitiale: 285,
quantiteRestante: 135,
unite: "pièce",
dateFabrication: "2025-01-18",
dateLimiteUtilisation: "2025-01-23",
statut: "partiellement-utilise"
}
Entité : Document
{
id: string (unique),
numero: string (format: TYPE-YYYY-NNN, ex: BC-2025-001),
type: "BRF" | "BRP" | "BSP" | "BF" | "BRETP" | "BC" | "BS" | "BL" | "BR",
restaurantId: string (référence Restaurant),
restaurantOrigine: string (optionnel, pour transferts),
restaurantDestination: string (optionnel, pour transferts),
date: date,
dateCreation: date,
statut: "brouillon" | "valide" | "en-transit" | "livre" | "recu" | "annule",
lignes: [
{
articleCode: string,
designation: string,
unite: string,
quantiteCommandee: number (optionnel),
quantiteLivree: number (optionnel),
quantiteRecue: number (optionnel),
quantiteAcceptee: number (optionnel),
quantiteRefusee: number (optionnel),
motifRefus: string (optionnel),
lotNumero: string (optionnel),
dlu: date (optionnel),
prixUnitaire: number (optionnel),
montant: number (optionnel),
format: string (optionnel),
poidsTotal: number (optionnel),
observations: string (optionnel)
}
],
// Champs spécifiques selon type
fournisseur: string (optionnel, pour BRF),
numeroDocumentFournisseur: string (optionnel),
produitFabrique: string (optionnel, pour BF),
rendement: number (optionnel, pour BF),
livreur: string (optionnel, pour BL),
vehicule: string (optionnel, pour BL),
heureDepart: datetime (optionnel),
heureArrivee: datetime (optionnel),
expediteur: string,
recepteur: string,
observations: string,
dateModification: date
}
Entité : Mouvement de Stock
{
id: string (unique),
articleCode: string (référence Article),
restaurantId: string (référence Restaurant),
type: "entree" | "sortie",
quantite: number,
unite: string,
lotNumero: string (optionnel),
prixUnitaire: number (optionnel),
montant: number (optionnel),
date: datetime,
documentId: string (référence Document),
documentNumero: string,
documentType: string,
motif: string (optionnel),
stockAvant: number,
stockApres: number,
utilisateurId: string,
dateCreation: date
}
Exemple :
{
id: "MVT001",
articleCode: "LLC-SF-BOUL-BOEUF",
restaurantId: "R001", // Stock Principal
type: "sortie",
quantite: 150,
unite: "pièce",
lotNumero: "LOT-20250118-001",
date: "2025-01-19T09:30:00",
documentId: "DOC123",
documentNumero: "BS-2025-001",
documentType: "BS",
stockAvant: 285,
stockApres: 135,
utilisateurId: "USER01"
}
Entité : Stock
{
id: string (unique),
articleCode: string (référence Article),
restaurantId: string (référence Restaurant),
quantiteDisponible: number,
unite: string,
valeurTotale: number,
prixUnitaireMoyen: number,
dateMAJ: datetime,
// Pour les produits semi-finis - détail par lot
lots: [
{
numeroLot: string,
quantite: number,
dlu: date
}
]
}
Exemple :
{
id: "STK001",
articleCode: "LLC-SF-BOUL-BOEUF",
restaurantId: "R001",
quantiteDisponible: 135,
unite: "pièce",
valeurTotale: 67500, // Si prix 500 FCFA/pièce
prixUnitaireMoyen: 500,
dateMAJ: "2025-01-19T09:30:00",
lots: [
{
numeroLot: "LOT-20250118-001",
quantite: 135,
dlu: "2025-01-23"
}
]
}
🔢 Règles de Numérotation
| Document | Format | Exemples |
|---|---|---|
| Bon Réception Fournisseur | BRF-YYYY-NNN | BRF-2025-001, BRF-2025-002... |
| Bon Réquisition Production | BRP-YYYY-NNN | BRP-2025-001, BRP-2025-002... |
| Bon Sortie Production | BSP-YYYY-NNN | BSP-2025-001, BSP-2025-002... |
| Bon Fabrication | BF-YYYY-NNN | BF-2025-001, BF-2025-002... |
| Bon Retour Production | BRETP-YYYY-NNN | BRETP-2025-001, BRETP-2025-002... |
| Bon Commande | BC-YYYY-NNN | BC-2025-001, BC-2025-002... |
| Bon Sortie | BS-YYYY-NNN | BS-2025-001, BS-2025-002... |
| Bon Livraison | BL-YYYY-NNN | BL-2025-001, BL-2025-002... |
| Bon Réception | BR-YYYY-NNN | BR-2025-001, BR-2025-002... |
| Lot Production | LOT-YYYYMMDD-NNN | LOT-20250118-001, LOT-20250118-002... |
Algorithme de Génération
function genererNumeroDocument(typeDocument) {
// 1. Récupérer l'année en cours
annee = getCurrentYear()
// 2. Trouver le dernier numéro pour ce type + année
dernierNumero = database.query(
"SELECT MAX(numero) FROM documents
WHERE type = ? AND YEAR(date) = ?",
[typeDocument, annee]
)
// 3. Incrémenter
if (dernierNumero exists) {
nouveauNumero = dernierNumero + 1
} else {
nouveauNumero = 1
}
// 4. Formater avec padding (001, 002, etc.)
numeroFormate = pad(nouveauNumero, 3) // "001"
// 5. Construire le numéro complet
return typeDocument + "-" + annee + "-" + numeroFormate
// Exemples de résultats:
// "BC-2025-001"
// "BS-2025-045"
// "BF-2025-012"
}
function genererNumeroLot(date) {
dateStr = formatDate(date, "YYYYMMDD") // "20250118"
dernierNumero = database.query(
"SELECT MAX(numeroLot) FROM lots
WHERE numeroLot LIKE 'LOT-" + dateStr + "-%'"
)
if (dernierNumero exists) {
nouveauNumero = extraireNumero(dernierNumero) + 1
} else {
nouveauNumero = 1
}
numeroFormate = pad(nouveauNumero, 3)
return "LOT-" + dateStr + "-" + numeroFormate
// Exemple: "LOT-20250118-001"
}
⚠️ CRITIQUE : La génération de numéros doit être "thread-safe" et "transactionnelle" pour éviter les doublons en cas d'accès concurrent.
⚙️ Règles de Gestion Critiques
RG-001 : Stock Jamais Négatif
function validerSortieStock(articleCode, restaurantId, quantite) {
stockActuel = getStock(articleCode, restaurantId)
if (stockActuel.quantiteDisponible < quantite) {
throw new Error(
"Stock insuffisant. Disponible: " + stockActuel.quantiteDisponible +
", Demandé: " + quantite
)
}
// OK, peut continuer
}
RG-002 : Validation Irréversible
function validerDocument(documentId) {
document = getDocument(documentId)
// Vérifier statut
if (document.statut != "brouillon") {
throw new Error("Seuls les documents en brouillon peuvent être validés")
}
// Vérifier cohérence
validerCoherence(document)
// Transaction atomique
database.beginTransaction()
try {
// 1. Mettre à jour le document
document.statut = "valide"
document.dateValidation = now()
saveDocument(document)
// 2. Créer les mouvements de stock SI APPLICABLE
if (documentImpacteStock(document.type)) {
creerMouvementsStock(document)
}
// 3. Mettre à jour les stocks
if (documentImpacteStock(document.type)) {
mettreAJourStocks(document)
}
// 4. Commit
database.commit()
// ⚠️ APRÈS VALIDATION: IMPOSSIBLE D'ANNULER
// Seule option: créer un document correctif
} catch (error) {
database.rollback()
throw error
}
}
RG-003 : Calcul Automatique Nomenclature
function calculerBesoinsProduction(produitCode, quantiteSouhaitee) {
// 1. Récupérer la nomenclature
nomenclature = getNomenclature(produitCode)
if (!nomenclature || !nomenclature.actif) {
throw new Error("Aucune nomenclature active pour ce produit")
}
// 2. Calculer le ratio
ratio = quantiteSouhaitee / nomenclature.quantiteBase
// 3. Calculer besoins pour chaque ingrédient
besoins = []
for (ingredient in nomenclature.ingredients) {
quantiteRequise = ingredient.quantiteRequise * ratio
stockDispo = getStock(ingredient.articleCode, "STOCK_PRINCIPAL")
besoins.push({
articleCode: ingredient.articleCode,
designation: ingredient.designation,
quantiteRequise: quantiteRequise,
unite: ingredient.unite,
stockDisponible: stockDispo.quantiteDisponible,
suffisant: stockDispo.quantiteDisponible >= quantiteRequise
})
}
return {
produit: produitCode,
quantiteSouhaitee: quantiteSouhaitee,
besoins: besoins,
tousDisponibles: besoins.every(b => b.suffisant)
}
}
Exemple d'utilisation :
resultat = calculerBesoinsProduction("LLC-SF-BOUL-BOEUF", 300)
// Résultat:
{
produit: "LLC-SF-BOUL-BOEUF",
quantiteSouhaitee: 300,
besoins: [
{
articleCode: "LLC-MB-BOEUF-HACHE",
designation: "Bœuf haché",
quantiteRequise: 36,
unite: "kg",
stockDisponible: 100,
suffisant: true
},
{
articleCode: "LLC-MB-CHAPELURE",
designation: "Chapelure",
quantiteRequise: 3,
unite: "kg",
stockDisponible: 2,
suffisant: false ❌
}
],
tousDisponibles: false
}
RG-004 : Validation Rendement
function validerBonFabrication(bonFabrication) {
// Calculer rendement
totalMatieresConsommees = sum(bonFabrication.matieres.map(m => m.quantite))
quantiteObtenue = bonFabrication.quantiteObtenue
rendement = (quantiteObtenue / totalMatieresConsommees) * 100
bonFabrication.rendement = rendement
// Validation selon seuils
if (rendement > 100) {
throw new Error(
"Rendement impossible > 100%. Vérifier les quantités saisies."
)
}
if (rendement < 70) {
return {
valide: false,
alerte: "BLOCAGE",
message: "Rendement anormalement bas (" + rendement + "%). " +
"Justification obligatoire.",
requiertJustification: true
}
}
if (rendement >= 70 && rendement < 85) {
return {
valide: true,
alerte: "WARNING",
message: "Rendement faible (" + rendement + "%). Vérifier la production.",
requiertConfirmation: true
}
}
// Rendement 85-100%
return {
valide: true,
alerte: "OK",
message: "Rendement acceptable (" + rendement + "%)"
}
}
RG-005 : Gestion DLU et FIFO
function selectionnerLotsPourSortie(articleCode, quantiteDemandee, dateLivraison) {
// 1. Récupérer tous les lots disponibles de cet article
lots = database.query(
"SELECT * FROM lots
WHERE articleCode = ?
AND statut IN ('disponible', 'partiellement-utilise')
AND quantiteRestante > 0
ORDER BY dateLimiteUtilisation ASC", // FIFO: Plus anciens d'abord
[articleCode]
)
lotsSelectionnes = []
quantiteRestante = quantiteDemandee
alertes = []
for (lot in lots) {
// Vérifier DLU
joursRestants = daysBetween(now(), lot.dateLimiteUtilisation)
joursApresLivraison = daysBetween(dateLivraison, lot.dateLimiteUtilisation)
// Bloquer si DLU dépassée
if (lot.dateLimiteUtilisation < now()) {
continue // Lot périmé, ignorer
}
// Alerter si DLU proche après livraison
if (joursApresLivraison < 2) {
alertes.push({
type: "WARNING",
lot: lot.numeroLot,
message: "DLU proche: " + lot.dateLimiteUtilisation +
". À consommer rapidement par le restaurant."
})
}
// Sélectionner le lot
quantiteAPrendre = Math.min(lot.quantiteRestante, quantiteRestante)
lotsSelectionnes.push({
numeroLot: lot.numeroLot,
quantite: quantiteAPrendre,
dlu: lot.dateLimiteUtilisation
})
quantiteRestante -= quantiteAPrendre
if (quantiteRestante <= 0) {
break // Quantité demandée satisfaite
}
}
// Vérifier si quantité suffisante
if (quantiteRestante > 0) {
throw new Error(
"Stock insuffisant. Manque: " + quantiteRestante +
" (lots disponibles épuisés)"
)
}
return {
lots: lotsSelectionnes,
alertes: alertes
}
}
Exemple d'utilisation :
resultat = selectionnerLotsPourSortie(
"LLC-SF-BOUL-BOEUF",
150,
"2025-01-19"
)
// Résultat:
{
lots: [
{
numeroLot: "LOT-20250113-001",
quantite: 45,
dlu: "2025-01-18"
},
{
numeroLot: "LOT-20250118-001",
quantite: 105,
dlu: "2025-01-23"
}
],
alertes: [
{
type: "WARNING",
lot: "LOT-20250113-001",
message: "DLU proche: 2025-01-18. À consommer rapidement."
}
]
}
RG-006 : Scan Quotidien DLU
// Tâche planifiée (CRON) à exécuter tous les jours à 6h00
function scanQuotidienDLU() {
aujourdhui = today()
demain = addDays(aujourdhui, 1)
dansDeuJours = addDays(aujourdhui, 2)
// 1. Lots périmés aujourd'hui
lotsPérimes = database.query(
"SELECT * FROM lots
WHERE dateLimiteUtilisation <= ?
AND statut != 'perime'",
[aujourdhui]
)
for (lot in lotsPérimes) {
// Bloquer le lot
lot.statut = "perime"
saveLot(lot)
// Notification critique
envoyerNotification({
type: "CRITIQUE",
priorite: "URGENT",
destinataires: ["gestionnaire.stock@laloui sette.com", "admin@lalou isette.com"],
sujet: "⚠️ LOT PÉRIMÉ: " + lot.numeroLot,
message: "Le lot " + lot.numeroLot + " (" + lot.articleCode + ") " +
"a atteint sa DLU. Quantité à détruire: " + lot.quantiteRestante
})
}
// 2. Lots périmant demain
lotsDemain = database.query(
"SELECT * FROM lots
WHERE dateLimiteUtilisation = ?
AND statut IN ('disponible', 'partiellement-utilise')",
[demain]
)
for (lot in lotsDemain) {
envoyerNotification({
type: "ALERTE",
priorite: "HAUTE",
destinataires: ["gestionnaire.stock@lalou isette.com"],
sujet: "⚠️ DLU DEMAIN: " + lot.numeroLot,
message: "Le lot " + lot.numeroLot + " périme demain. " +
"Quantité restante: " + lot.quantiteRestante + ". " +
"À écouler en priorité."
})
}
// 3. Lots périmant dans 2 jours
lotsDansDeuJours = database.query(
"SELECT * FROM lots
WHERE dateLimiteUtilisation = ?
AND statut IN ('disponible', 'partiellement-utilise')",
[dansDeuJours]
)
for (lot in lotsDansDeuJours) {
envoyerNotification({
type: "INFO",
priorite: "NORMALE",
destinataires: ["gestionnaire.stock@lalou isette.com"],
sujet: "ℹ️ DLU dans 2 jours: " + lot.numeroLot,
message: "Le lot " + lot.numeroLot + " périme dans 2 jours. " +
"Quantité: " + lot.quantiteRestante
})
}
// 4. Génération rapport quotidien
genererRapportDLU(aujourdhui)
}
📄 Génération de Documents
Spécifications PDF
⚠️ CONTRAINTE ABSOLUE : Tous les PDF doivent être en orientation PAYSAGE (landscape), jamais portrait.
Configuration PDF :
{
format: "A4",
orientation: "landscape", // ⚠️ OBLIGATOIRE
marges: {
top: 20,
right: 15,
bottom: 20,
left: 15
},
unite: "mm"
}
Structure de base :
┌─────────────────────────────────────────────────┐
│ EN-TÊTE │
│ - Logo (si disponible) │
│ - Nom établissement │
│ - Type de document │
│ - Numéro document │
│ - Date │
├─────────────────────────────────────────────────┤
│ INFORMATIONS DOCUMENT │
│ - Restaurant/Fournisseur │
│ - Dates │
│ - Références │
├─────────────────────────────────────────────────┤
│ TABLEAU ARTICLES │
│ (Largeur maximisée grâce au format paysage) │
│ │
│ Colonnes selon type de document: │
│ - Code | Désignation | Unité | Quantités... │
├─────────────────────────────────────────────────┤
│ PIED DE PAGE │
│ - Observations │
│ - Signatures (Expéditeur / Récepteur) │
│ - Date d'impression │
└─────────────────────────────────────────────────┘
Spécifications Excel
Feuilles à créer selon type: Pour Bon de Commande / Sortie / Livraison / Réception: - Feuille 1: "Document" (tableau principal) - Feuille 2: "Récapitulatif" (totaux, statistiques) Pour Fiche de Stock: - Feuille 1: "Fiche Stock" (mouvements détaillés) - Colonnes: * Code Article * Désignation * Unité * Stock Initial (Qté | PU | Montant) * Entrées (Qté | PU | Montant) * Sorties (Qté | PU | Montant) * Stock Final (Qté | PU | Montant) Mise en forme: - En-tête: Police gras, fond gris, bordures - Données: Bordures fines, alternance lignes - Nombres: Format numérique avec séparateurs milliers - Montants: Format monétaire (FCFA) - Largeurs colonnes: Auto-ajustées au contenu
Modèles Spécifiques par Restaurant
| Restaurant | Colonnes Spécifiques |
|---|---|
| FF Paul Langevin | Standard: Code | Désignation | Unité (g/kg/L) | Qté | Observations |
| FF Koumassi | + Format | Poids Total (calculé) |
| Ma Glace | + Colonne "g" (grammes) |
| Villa | Standard |
| Casa Mexicana | À définir (utiliser standard par défaut) |
🔐 Sécurité et Authentification
Profils Utilisateurs
{
id: string,
nom: string,
prenom: string,
email: string,
motDePasse: string (hashé),
profil: "admin" | "stock-principal" | "cuisine-centrale" | "restaurant" | "consultation",
restaurantAffecte: string (optionnel, pour profils restaurant),
actif: boolean,
dateCreation: date,
derniereConnexion: date
}
Matrice de Droits
| Fonctionnalité | Admin | Stock Principal | Cuisine Centrale | Restaurant |
|---|---|---|---|---|
| Gestion utilisateurs | ✅ | ❌ | ❌ | ❌ |
| Gestion articles | ✅ | ✅ | 👁️ Lecture | 👁️ Lecture |
| Gestion nomenclatures | ✅ | 👁️ Lecture | ✅ | ❌ |
| BRF (Réception Fournisseur) | ✅ | ✅ | ❌ | ❌ |
| BRP (Réquisition Production) | ✅ | 👁️ Lecture | ✅ | ❌ |
| BSP (Sortie Production) | ✅ | ✅ | 👁️ Lecture | ❌ |
| BF (Fabrication) | ✅ | 👁️ Lecture | ✅ | ❌ |
| BRETP (Retour Production) | ✅ | 👁️ Lecture | ✅ | ❌ |
| BC (Bon Commande) | ✅ | 👁️ Lecture | ❌ | ✅ (Son restaurant) |
| BS/BL (Sortie/Livraison) | ✅ | ✅ | ❌ | 👁️ Lecture |
| BR (Réception) | ✅ | 👁️ Lecture | ❌ | ✅ (Son restaurant) |
| Vue stock global | ✅ | ✅ | 👁️ Stock Principal | ❌ (Uniquement son resto) |
✅ Critères d'Acceptation
Groupe 1 : Gestion de Base
- ☐ CRUD Restaurants complet (6 établissements)
- ☐ CRUD Articles (minimum 150 articles)
- ☐ Catégorisation articles (Matière brute / Produit semi-fini)
- ☐ Gestion utilisateurs avec 5 profils
- ☐ Authentification sécurisée
Groupe 2 : Documents
- ☐ Création et validation des 9 types de documents
- ☐ Numérotation automatique séquentielle
- ☐ Statuts documents (brouillon → validé → ...)
- ☐ Génération PDF paysage pour tous documents
- ☐ Génération Excel pour tous documents
- ☐ Modèles spécifiques par restaurant respectés
Groupe 3 : Stock
- ☐ Calcul stock en temps réel par restaurant
- ☐ Mouvements d'entrée/sortie tracés
- ☐ Impossibilité stock négatif
- ☐ Gestion lots fournisseurs
- ☐ Gestion lots production avec DLU
- ☐ FIFO automatique pour produits semi-finis
- ☐ Scan quotidien DLU avec notifications
- ☐ Alertes stock bas configurables
Groupe 4 : Production
- ☐ CRUD Nomenclatures de fabrication
- ☐ Calcul automatique besoins selon nomenclature
- ☐ Cycle complet BRP → BSP → BF → BRETP
- ☐ Validation rendement (70-100%)
- ☐ Blocage si rendement < 70%
- ☐ Attribution automatique N° lot et DLU
Groupe 5 : Traçabilité
- ☐ Traçabilité ascendante (produit → matières)
- ☐ Traçabilité descendante (matière → produits)
- ☐ Historique complet tous mouvements
- ☐ Audit trail (qui, quand, quoi)
Groupe 6 : Rapports
- ☐ Fiche de stock par restaurant
- ☐ Rapport mouvements par période
- ☐ Rapport DLU (lots à écouler)
- ☐ Rapport production (rendement, volumes)
- ☐ Rapport valorisation stock
Groupe 7 : Interface
- ☐ Tableau de bord par profil
- ☐ Interface responsive (mobile, tablette, desktop)
- ☐ Navigation intuitive
- ☐ Recherche et filtres performants
- ☐ Notifications en temps réel
🎯 Planning de Développement Recommandé
| Phase | Durée | Livrables |
|---|---|---|
| Phase 1 : Fondations | 3 semaines |
- Base de données - Authentification - CRUD Restaurants & Articles - Gestion utilisateurs |
| Phase 2 : Stock Principal | 2 semaines |
- Module stock principal - BRF (Réception fournisseurs) - Gestion lots - Alertes DLU |
| Phase 3 : Production | 3 semaines |
- Nomenclatures - Cycle complet production (4 docs) - Calcul rendement - Gestion DLU produits |
| Phase 4 : Restaurants | 2 semaines |
- BC, BS, BL, BR - Stock restaurants - FIFO automatique |
| Phase 5 : Documents & Rapports | 2 semaines |
- Génération PDF/Excel - Modèles par restaurant - Rapports |
| Phase 6 : Tests & Déploiement | 1 semaine |
- Tests complets - Corrections - Déploiement - Formation |
Total estimé : 13 semaines pour une application complète et fonctionnelle.
📚 Ressources & Références
Documentation Complète
- Architecture du système - Les 3 niveaux et flux
- Documentation des documents - Les 9 types détaillés
- Processus métier - Scénarios complets
Fichiers JSON de Référence
Les fichiers JSON originaux fournis par le client se trouvent dans :
d:\TRAVAIL\Docs\Bons - Copie\
├── FF PL\
│ ├── Bon_de_commande_PL.json
│ └── Fiche de stock ff PL.json
├── FF KOUMASSI\
│ └── Bon de commande ff koumassi.json
├── MA GLACE\
│ └── Bon de commande ma glace.json
└── VILLA\
└── Bon_de commande Villa.json
Contact
Pour toute question ou clarification, contacter le chef de projet.
🎉 Vous avez maintenant toutes les informations nécessaires !
Cette documentation complète vous permet de développer l'application de A à Z.
Bon développement ! 💪