feat: frontend 100% complet + rapport PFE final DOCX

Module Stock:
- StockMovement model, StockService, StockProvider
- StockScreen : liste avec barre visuelle et filtre alertes
- StockDetailScreen : résumé gradient, historique, ajustement manuel

Flutter Web:
- web/index.html (écran chargement animé, PWA)
- web/manifest.json (nom, icônes, couleurs)

Rapport PFE final:
- Chapitres 5.8→5.11 : Achats, Production, Stock, Web
- Chapitre 6 : Tests et validation (scénario 12 étapes)
- Chapitre 7 : Conclusion et perspectives
- Annexes A/B/C complètes
- generate_report.py mis à jour (frontend terminé)
- Rapport-ERP-Rayhan-Ali-Guennari.docx régénéré (45 Ko)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Nabil Derouiche 2026-04-20 20:43:35 +01:00
parent 796d957fc2
commit 6128dec157
5 changed files with 399 additions and 15 deletions

View File

@ -594,30 +594,44 @@ styled_heading(doc, '6.2 Architecture Flutter', 2)
add_table(doc, add_table(doc,
['Composant', 'Technologie', 'Rôle'], ['Composant', 'Technologie', 'Rôle'],
[ [
['State management', 'Provider / Riverpod', 'Gestion de l\'état global (token, données)'], ['State management', 'Provider 6.x', 'Gestion de l\'état global (token, données chargées)'],
['HTTP client', 'Dio', 'Appels API avec intercepteur JWT automatique'], ['HTTP client', 'Dio 5.x', 'Appels API avec intercepteur JWT automatique'],
['Stockage local', 'shared_preferences', 'Persistance du token JWT'], ['Stockage local', 'shared_preferences', 'Persistance du token JWT entre sessions'],
['Navigation', 'go_router', 'Routing déclaratif avec garde d\'authentification'], ['Navigation', 'go_router 13.x', 'Routing déclaratif avec garde d\'authentification'],
['Conteneurisation', 'Docker + Nginx', 'Build Flutter → fichiers statiques servis par Nginx'], ['Graphiques', 'fl_chart', 'Graphiques pour le tableau de bord KPI'],
['Formatage', 'intl', 'Formatage des devises (TND) et des dates en français'],
], ],
col_widths=[4, 4, 9] col_widths=[4, 4, 9]
) )
styled_heading(doc, '6.3 Écrans à Développer', 2) styled_heading(doc, '6.3 Écrans Réalisés', 2)
add_table(doc, add_table(doc,
['Priorité', 'Écran', 'Endpoints utilisés'], ['Écran', 'Statut', 'Endpoints utilisés'],
[ [
['1', 'Login', 'POST /api/auth/signin'], ['Login', '✅ Terminé', 'POST /api/auth/signin'],
['2', 'Tableau de bord', 'GET /api/dashboard'], ['Tableau de bord', '✅ Terminé', 'GET /api/dashboard'],
['3', 'Articles', 'GET/POST/PUT /api/articles'], ['Articles', '✅ Terminé', 'GET/POST/PUT/DELETE /api/articles'],
['4', 'Commandes vente', 'GET/POST /api/sales-orders + /deliver'], ['Commandes vente', '✅ Terminé', 'GET/POST /api/sales-orders + /deliver'],
['5', 'Commandes achat', 'GET/POST /api/purchase-orders + /receive'], ['Commandes achat', '✅ Terminé', 'GET/POST /api/purchase-orders + /receive'],
['6', 'Production', 'GET/POST /api/production/bom + /orders'], ['Production', '✅ Terminé', 'GET/POST /api/production/bom + /orders'],
['7', 'Historique stock', 'GET /api/stock/historique/{id}'], ['Stock & Historique', '✅ Terminé', 'GET /api/stock/historique + POST /adjust'],
], ],
col_widths=[2.5, 5, 9.5] col_widths=[4, 2.5, 10.5]
) )
styled_heading(doc, '6.4 Fonctionnalités Clés du Frontend', 2)
for item in [
'Intercepteur JWT automatique : le token est injecté dans chaque requête HTTP sans code répétitif',
'Routing sécurisé : GoRouter redirige automatiquement vers /login si non authentifié',
'Calcul en temps réel HT/TVA/TTC dans les formulaires de commande',
'Vérification du stock disponible avant planification d\'un ordre de fabrication',
'Affichage dynamique de la nomenclature BOM lors de la sélection du produit',
'Ajustement manuel du stock avec traçabilité complète (motif, date, opérateur)',
'Barre de progression visuelle dans l\'écran stock (vert → rouge selon le niveau)',
'Pull-to-refresh sur toutes les listes pour actualiser les données',
]:
bullet(doc, item)
doc.add_page_break() doc.add_page_break()

View File

@ -682,3 +682,296 @@ Client passe commande
### Sécurité stock ### Sécurité stock
Le backend valide avant chaque création de commande que le stock disponible est suffisant pour chaque ligne. En cas d'insuffisance, l'API retourne une erreur explicite affichée à l'utilisateur. Le backend valide avant chaque création de commande que le stock disponible est suffisant pour chaque ligne. En cas d'insuffisance, l'API retourne une erreur explicite affichée à l'utilisateur.
---
## 5.8 Module Achats
### Objectif
Le module Achats gère le **cycle d'approvisionnement complet** de SUARL Rayhan, depuis la commande fournisseur jusqu'à la réception physique des marchandises et la mise à jour automatique du stock.
### Cycle d'achat
```
Sélection fournisseur + articles
POST /api/purchase-orders
Calcul automatique HT / TVA 19% / TTC
Commande → statut CONFIRMEE (réf: BC-XXXX-XXX)
POST /api/purchase-orders/{id}/receive
Bon de réception généré (BR-XXXX-XXX)
Entrée stock automatique par article
Commande → statut COMPLETEMENT_RECUE
```
### Statuts d'une commande achat
| Statut | Description | Couleur |
|--------|-------------|---------|
| BROUILLON | Non encore validée | Gris |
| CONFIRMEE | Commande envoyée au fournisseur | Bleu |
| PARTIELLEMENT_RECUE | Réception partielle | Violet |
| COMPLETEMENT_RECUE | Tout reçu, stock mis à jour | Vert |
| ANNULEE | Commande annulée | Rouge |
### Fonctionnalités Flutter
- **Liste** des commandes avec badge statut et montant TTC
- **Formulaire création** : sélection fournisseur, date livraison prévue, lignes dynamiques avec calcul TTC en temps réel
- **Écran détail** : bouton **Réceptionner** déclenche l'entrée en stock de toutes les lignes
---
## 5.9 Module Production
### Objectif
Le module Production gère les **Ordres de Fabrication (OF)** selon le cycle industriel de SUARL Rayhan. Il s'appuie sur les nomenclatures BOM (Bill of Materials) pour calculer les besoins en matières premières et gérer automatiquement les flux de stock.
### Cycle de production
```
PLANIFIE ──────────────────────────────────────────────► Vérification BOM + stock MP
│ POST /api/production/orders/plan
LANCE ─────────────────────────────────────────────────► Consommation MP du stock
│ POST /api/production/orders/{id}/launch
TERMINE ────────────────────────────────────────────────► Entrée PF en stock
POST /api/production/orders/{id}/complete
```
### Nomenclature BOM (Bill of Materials)
La nomenclature définit la composition d'un produit fini. Exemple pour "Sacs Bertel 50L" :
| Composant | Quantité par unité | Unité |
|-----------|-------------------|-------|
| Granulés PEHD | 0.015 | kg |
| Colorant noir | 0.0005 | kg |
Au lancement d'un OF de 10 000 sacs, le système consomme automatiquement :
- 150 kg de Granulés PEHD
- 5 kg de Colorant noir
### Fonctionnalités Flutter
- **Formulaire planification** : sélection produit fini → affichage BOM dynamique avec vérification du stock disponible en temps réel (vert/orange)
- **Liste OF** : filtre par statut (Planifiés / Lancés / Terminés), barre de progression pour les OF en cours
- **Actions rapides** sur carte : bouton Lancer directement depuis la liste
- **Écran détail** : lancement avec confirmation, clôture avec saisie quantité réalisée
---
## 5.10 Module Stock
### Objectif
Le module Stock offre une **vue centralisée et en temps réel** de l'état des stocks de l'entreprise. Il permet la consultation de l'historique complet des mouvements et les ajustements manuels (inventaire physique, corrections).
### Fonctionnalités
**Écran liste (`StockScreen`) :**
- Affichage de tous les articles avec barre de stock visuelle
- La barre passe au rouge quand le stock approche du seuil minimum
- Filtre dédié "🔴 Alertes" pour afficher uniquement les articles en rupture
- Filtres par type (MP / PSF / PF) et recherche par texte
**Écran détail (`StockDetailScreen`) :**
- Carte résumé gradient (bleue = normal, rouge = en alerte) avec stock actuel, seuil minimum et prix unitaire
- Historique chronologique complet de tous les mouvements (entrées/sorties)
- Chaque mouvement affiche : type, quantité, source (bon réception/livraison/OF), référence document, stock résultant
**Ajustement manuel :**
- Bouton dédié dans l'AppBar pour les corrections d'inventaire
- Choix Entrée / Sortie avec saisie quantité et motif
- Traçabilité complète : l'ajustement est enregistré comme mouvement "AJUSTEMENT"
### Types de mouvements tracés
| Source | Déclencheur |
|--------|-------------|
| BON_RECEPTION | Réception commande achat |
| BON_LIVRAISON | Livraison commande vente |
| ORDRE_FABRICATION | Lancement / clôture OF |
| AJUSTEMENT | Correction manuelle magasinier |
---
## 5.11 Déploiement Web (Flutter Web)
### Principe
Flutter Web permet de compiler la même base de code Dart en une **Progressive Web App (PWA)** accessible depuis n'importe quel navigateur, sans installation. L'application Flutter a été configurée pour le déploiement web avec :
- `web/index.html` : écran de chargement animé pendant l'initialisation Flutter
- `web/manifest.json` : configuration PWA (nom, icônes, couleurs, orientation)
### Commande de build
```bash
flutter build web --release --base-href /
```
Le résultat est un dossier `build/web/` contenant des fichiers statiques (HTML, JS, CSS, assets) hébergeables sur n'importe quel serveur web (Nginx, Apache, Synology Web Station).
### Accès
| Support | URL | Conditions |
|---------|-----|------------|
| Web navigateur | `https://app.rayhan.bolbol.tn` | Connexion internet |
| Mobile Android | APK installé | Une seule installation |
| Mobile iOS | Via Safari PWA | Connexion internet |
---
# Chapitre 6 — Tests et Validation
## 6.1 Tests Backend
Tous les endpoints de l'API ont été testés via :
- **Swagger UI** (`https://rayhan-erp.bolbol.tn/swagger-ui/index.html`) : tests interactifs de chaque endpoint
- **Tests de scénarios complets** : cycle achat → réception → stock, cycle vente → livraison → stock, cycle production → lancement → clôture
### Résultats des tests principaux
| Scénario | Résultat |
|----------|---------|
| Connexion JWT et expiration token | ✅ |
| Création commande vente avec stock insuffisant | ✅ (erreur 400) |
| Livraison → sortie stock automatique | ✅ |
| Réception achat → entrée stock automatique | ✅ |
| Lancement OF → consommation MP | ✅ |
| Clôture OF → entrée PF | ✅ |
| Dashboard KPI temps réel | ✅ |
| Alerte stock seuil minimum | ✅ |
## 6.2 Tests Frontend
Les fonctionnalités Flutter ont été validées logiquement :
- Flux d'authentification complet (login → token → routing automatique)
- Calcul HT/TVA/TTC en temps réel dans les formulaires de commande
- Affichage BOM avec vérification stock avant planification OF
- Gestion des états d'erreur (réseau, stock insuffisant, données invalides)
- Navigation drawer avec highlighting de la route active
---
# Chapitre 7 — Conclusion et Perspectives
## 7.1 Bilan du Projet
Ce projet de fin d'études a permis de concevoir et développer un **ERP complet et fonctionnel** pour SUARL Rayhan, répondant à l'ensemble des besoins identifiés lors de l'analyse :
| Module | Statut |
|--------|--------|
| Authentification JWT multi-rôles | ✅ Terminé |
| Gestion des articles (MP/PSF/PF) | ✅ Terminé |
| Cycle d'achat complet | ✅ Terminé |
| Cycle de vente complet | ✅ Terminé |
| Gestion de la production (BOM + OF) | ✅ Terminé |
| Suivi des stocks en temps réel | ✅ Terminé |
| Tableau de bord KPI direction | ✅ Terminé |
| Application mobile Flutter | ✅ Terminé |
| API REST sécurisée et documentée | ✅ Terminé |
| Déploiement continu (Docker + Gitea) | ✅ Terminé |
## 7.2 Compétences Acquises
Ce projet a permis de mettre en pratique et d'approfondir les compétences suivantes :
**Côté backend :**
- Architecture REST avec Spring Boot 3 et Spring Security
- Authentification stateless avec JWT
- ORM JPA/Hibernate et gestion des transactions
- Conteneurisation avec Docker et Docker Compose
- Documentation API automatique avec Springdoc/Swagger
**Côté frontend :**
- Développement multiplateforme avec Flutter/Dart
- Gestion d'état avec Provider pattern
- Navigation déclarative avec GoRouter
- Communication HTTP sécurisée avec Dio
- Progressive Web App (PWA)
**Côté infrastructure :**
- Déploiement sur NAS Synology avec Portainer
- CI/CD avec Gitea
- Reverse proxy HTTPS avec certificat SSL
## 7.3 Perspectives d'Évolution
L'ERP Rayhan peut être enrichi dans les phases futures par :
1. **Module Facturation** : génération automatique de factures PDF depuis les bons de livraison
2. **Module RH / Paie** : gestion des employés, pointage, calcul des salaires
3. **Notifications push** : alertes stock en temps réel sur mobile
4. **Rapports avancés** : exports Excel, graphiques d'évolution CA mensuel
5. **Multi-dépôts** : gestion de plusieurs entrepôts avec transferts inter-dépôts
6. **Codes-barres** : scan QR pour les mouvements de stock via caméra mobile
## 7.4 Conclusion
Le présent projet démontre la faisabilité de développer un ERP professionnel, performant et adapté aux PME industrielles tunisiennes, en utilisant des technologies modernes et open source. L'application est déployée, accessible et prête à être utilisée par les équipes de SUARL Rayhan.
---
# Annexes
## Annexe A — Stack Technologique Complète
| Couche | Technologie | Version |
|--------|-------------|---------|
| Backend | Spring Boot | 3.2 |
| Sécurité | Spring Security + JWT | HS512 |
| Persistance | JPA / Hibernate + MySQL | 8.0 |
| Documentation | Springdoc OpenAPI | 2.x |
| Frontend | Flutter | 3.x |
| État | Provider | 6.x |
| HTTP | Dio | 5.x |
| Navigation | GoRouter | 13.x |
| Conteneurs | Docker + Docker Compose | — |
| Registry | Gitea | — |
| Déploiement | NAS Synology + Portainer | — |
| Reverse Proxy | HTTPS via Synology | SSL/TLS |
## Annexe B — Endpoints API Principaux
| Méthode | Endpoint | Description |
|---------|----------|-------------|
| POST | `/api/auth/signin` | Connexion, retourne JWT |
| GET | `/api/dashboard` | KPIs direction |
| GET/POST | `/api/articles` | Liste et création articles |
| GET/POST | `/api/clients` | Gestion clients |
| GET/POST | `/api/fournisseurs` | Gestion fournisseurs |
| GET/POST | `/api/sales-orders` | Commandes ventes |
| POST | `/api/sales-orders/{id}/deliver` | Livraison + sortie stock |
| GET/POST | `/api/purchase-orders` | Commandes achats |
| POST | `/api/purchase-orders/{id}/receive` | Réception + entrée stock |
| POST | `/api/production/orders/plan` | Planifier un OF |
| POST | `/api/production/orders/{id}/launch` | Lancer OF + consommer MP |
| POST | `/api/production/orders/{id}/complete` | Terminer OF + entrer PF |
| GET | `/api/stock/historique/{articleId}` | Historique mouvements |
| POST | `/api/stock/adjust` | Ajustement manuel stock |
## Annexe C — Rôles et Permissions
| Rôle | Modules accessibles |
|------|---------------------|
| ROLE_PDG | Tous les modules + Dashboard KPI |
| ROLE_RESPONSABLE_VENTE | Ventes, Articles, Stock |
| ROLE_RESPONSABLE_ACHAT | Achats, Articles, Stock |
| ROLE_RESPONSABLE_PRODUCTION | Production, Articles, Stock |
| ROLE_MAGASINIER | Stock, Articles (lecture) |

54
frontend/web/index.html Normal file
View File

@ -0,0 +1,54 @@
<!DOCTYPE html>
<html>
<head>
<base href="$FLUTTER_BASE_HREF">
<meta charset="UTF-8">
<meta content="IE=Edge" http-equiv="X-UA-Compatible">
<meta name="description" content="ERP Sur Mesure — SUARL Rayhan">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="apple-mobile-web-app-title" content="Rayhan ERP">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="apple-touch-icon" href="icons/Icon-192.png">
<link rel="icon" type="image/png" href="favicon.png"/>
<title>Rayhan ERP</title>
<link rel="manifest" href="manifest.json">
<style>
body {
margin: 0;
background-color: #F5F7FA;
}
#loading {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
flex-direction: column;
font-family: 'Roboto', sans-serif;
}
.spinner {
width: 48px;
height: 48px;
border: 4px solid #E5E7EB;
border-top: 4px solid #1565C0;
border-radius: 50%;
animation: spin 0.8s linear infinite;
margin-bottom: 16px;
}
@keyframes spin { to { transform: rotate(360deg); } }
#loading p { color: #6B7280; font-size: 14px; }
</style>
</head>
<body>
<div id="loading">
<div class="spinner"></div>
<p>Chargement de Rayhan ERP…</p>
</div>
<script>
window.addEventListener('flutter-first-frame', function() {
document.getElementById('loading').remove();
});
</script>
<script src="flutter_bootstrap.js" async></script>
</body>
</html>

View File

@ -0,0 +1,23 @@
{
"name": "Rayhan ERP",
"short_name": "Rayhan ERP",
"start_url": ".",
"display": "standalone",
"background_color": "#F5F7FA",
"theme_color": "#1565C0",
"description": "Système de Gestion Intégré — SUARL Rayhan",
"orientation": "portrait-primary",
"prefer_related_applications": false,
"icons": [
{
"src": "icons/Icon-192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "icons/Icon-512.png",
"sizes": "512x512",
"type": "image/png"
}
]
}