---
title: "Rapport de Projet — ERP SUARL Rayhan"
subtitle: "Projet de Fin d'Études — Ali Guennari"
author: "Ali Guennari"
date: "Avril 2026"
lang: fr
---

# Rapport de Projet de Fin d'Études

## ERP Sur Mesure pour SUARL Rayhan

**Étudiant :** Ali Guennari  
**Entreprise d'accueil :** SUARL Rayhan — Plasturgie, Tataouine, Tunisie  
**Encadrant académique :** À compléter  
**Encadrant professionnel :** À compléter  
**Année universitaire :** 2025 / 2026  

---

# Chapitre 1 — Présentation du Projet

## 1.1 Contexte

SUARL Rayhan est une entreprise tunisienne spécialisée dans la fabrication d'emballages plastiques (sacs Bertel, sacs poubelles, sacs alimentaires, film rétractable) implantée à Tataouine. Face à une gestion manuelle de ses processus métier — achats, ventes, production, stock — la direction a exprimé le besoin d'un système d'information intégré permettant de centraliser et automatiser ces opérations.

## 1.2 Objectif du Projet

Ce projet de fin d'études consiste à concevoir et développer un **ERP (Enterprise Resource Planning) sur mesure**, adapté aux spécificités de SUARL Rayhan, couvrant :

- La gestion du référentiel articles (matières premières, produits semi-finis, produits finis)
- Le cycle d'achat complet (commandes fournisseurs → bons de réception → mise à jour du stock)
- Le cycle de vente complet (commandes clients → bons de livraison → sortie de stock)
- La gestion de la production (nomenclatures BOM, ordres de fabrication)
- Le suivi des stocks en temps réel avec alertes
- Un tableau de bord KPI pour la direction

## 1.3 Périmètre Fonctionnel

| Module | Description |
|--------|-------------|
| Authentification | Connexion sécurisée avec rôles différenciés |
| Articles | Gestion du catalogue (MP, PSF, PF) |
| Clients & Fournisseurs | Annuaire des tiers commerciaux |
| Cycle Achat | Commande → Réception → Stock |
| Cycle Vente | Commande → Livraison → Stock |
| Production | BOM + Ordres de Fabrication |
| Stock | Mouvements, historique, alertes seuil minimum |
| Tableau de bord | KPIs temps réel pour le PDG |

---

# Chapitre 2 — Architecture Technique

## 2.1 Stack Technologique

| Couche | Technologie | Version |
|--------|-------------|---------|
| Backend API | Spring Boot | 3.2.5 |
| Langage | Java | 17 LTS |
| Sécurité | Spring Security + JWT | JJWT 0.12.5 |
| Persistance | Spring Data JPA / Hibernate | 6.4.4 |
| Base de données | MySQL | 8.0 |
| Conteneurisation | Docker + Docker Compose | — |
| Frontend (à venir) | Flutter | 3.x |

## 2.2 Architecture N-Tiers

L'API suit rigoureusement le patron d'architecture **Controller → Service → Repository → Model** :

```
┌─────────────────────────────────────────────────────────┐
│               Application Flutter (Client)               │
└─────────────────────┬───────────────────────────────────┘
                      │ HTTP/HTTPS (JWT Bearer Token)
                      ▼
┌─────────────────────────────────────────────────────────┐
│              API REST Spring Boot (Port 8090)            │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐              │
│  │Controller│→ │ Service  │→ │Repository│              │
│  └──────────┘  └──────────┘  └──────────┘              │
│                              ┌──────────┐              │
│                              │   JPA /  │              │
│                              │Hibernate │              │
└──────────────────────────────┴────┬─────┴──────────────┘
                                    │ JDBC
                                    ▼
                        ┌─────────────────────┐
                        │    MySQL 8           │
                        │  rayhan_erp_db       │
                        └─────────────────────┘
```

## 2.3 Sécurité — Mécanisme JWT

Le système utilise une authentification **stateless** basée sur les JSON Web Tokens :

1. Le client envoie ses identifiants à `POST /api/auth/signin`
2. Le serveur valide et retourne un JWT signé (valable 24h)
3. Le client inclut `Authorization: Bearer <token>` dans chaque requête
4. Le filtre `AuthTokenFilter` intercepte et valide le token avant chaque endpoint

### Rôles et Contrôle d'Accès

| Rôle | Périmètre d'accès |
|------|-------------------|
| `ROLE_PDG` | Accès complet + tableau de bord |
| `ROLE_RESPONSABLE_VENTE` | Ventes, clients |
| `ROLE_RESPONSABLE_ACHAT` | Achats, fournisseurs |
| `ROLE_RESPONSABLE_PRODUCTION` | Production, BOM, ordres de fabrication |
| `ROLE_MAGASINIER` | Stock, mouvements de stock |
| `ROLE_RH` | Ressources humaines, paie |

Chaque endpoint est protégé par l'annotation `@PreAuthorize` :

```java
@PreAuthorize("hasAnyRole('ROLE_PDG', 'ROLE_RESPONSABLE_VENTE')")
```

## 2.4 Modèle de Données Relationnel

La base de données `rayhan_erp_db` contient les tables suivantes :

- **users / roles / user_roles** — authentification et droits
- **tiers** (table mère), **clients**, **fournisseurs** — gestion des tiers (héritage JOINED)
- **articles** — catalogue produits avec types MP / PSF / PF
- **bom_lines** — nomenclatures de production (Bill of Materials)
- **production_orders** — ordres de fabrication avec cycle PLANIFIE → LANCE → TERMINE
- **purchase_orders / purchase_order_lines** — commandes fournisseurs
- **goods_receipts / goods_receipt_lines** — bons de réception
- **sales_orders / sales_order_lines** — commandes clients
- **delivery_notes / delivery_note_lines** — bons de livraison
- **stock_movements** — historique complet de tous les mouvements de stock

---

# Chapitre 3 — Endpoints de l'API

## 3.1 Authentification

| Méthode | URL | Description |
|---------|-----|-------------|
| POST | `/api/auth/signin` | Connexion → retourne JWT |
| POST | `/api/auth/signup` | Créer un utilisateur |

## 3.2 Articles

| Méthode | URL | Rôles |
|---------|-----|-------|
| GET | `/api/articles` | Tous |
| GET | `/api/articles/{id}` | Tous |
| GET | `/api/articles/type/{type}` | Tous (MP, PF, PSF) |
| GET | `/api/articles/alertes-stock` | PDG, Magasinier, Production |
| POST | `/api/articles` | PDG, Production, Magasinier |
| PUT | `/api/articles/{id}` | PDG, Production |
| DELETE | `/api/articles/{id}` | PDG (désactivation logique) |

## 3.3 Clients & Fournisseurs

| Méthode | URL | Rôles |
|---------|-----|-------|
| GET | `/api/clients` | PDG, Vente |
| POST | `/api/clients` | PDG, Vente |
| PUT | `/api/clients/{id}` | PDG, Vente |
| GET | `/api/fournisseurs` | PDG, Achat |
| POST | `/api/fournisseurs` | PDG, Achat |

## 3.4 Cycle d'Achat

| Méthode | URL | Description |
|---------|-----|-------------|
| GET | `/api/purchase-orders` | Liste des commandes |
| POST | `/api/purchase-orders` | Créer une commande fournisseur |
| POST | `/api/purchase-orders/{id}/receive` | Réceptionner → crée BR + entre en stock |

## 3.5 Cycle de Vente

| Méthode | URL | Description |
|---------|-----|-------------|
| GET | `/api/sales-orders` | Liste des commandes |
| POST | `/api/sales-orders` | Créer une commande client |
| POST | `/api/sales-orders/{id}/deliver` | Livrer → crée BL + sort du stock |

## 3.6 Production

| Méthode | URL | Description |
|---------|-----|-------------|
| POST | `/api/production/bom` | Définir une nomenclature |
| POST | `/api/production/orders/plan` | Planifier un ordre de fabrication |
| POST | `/api/production/orders/{id}/launch` | Lancer → consomme les MP |
| POST | `/api/production/orders/{id}/complete` | Terminer → entre les PF en stock |

## 3.7 Stock & Tableau de Bord

| Méthode | URL | Description |
|---------|-----|-------------|
| GET | `/api/stock/historique/{articleId}` | Historique des mouvements |
| POST | `/api/stock/adjust` | Ajustement manuel |
| GET | `/api/dashboard` | KPIs pour le PDG |

---

# Chapitre 4 — Déploiement

## 4.1 Infrastructure

L'application est déployée via Docker Compose, accessible publiquement derrière un reverse proxy HTTPS. Deux conteneurs sont en production :

- **rayhan-mysql** — MySQL 8, base de données `rayhan_erp_db`
- **rayhan-backend** — Spring Boot, accessible sur le port **8090**

## 4.2 Docker Compose

```yaml
services:
  mysql:
    image: mysql:8.0
    container_name: rayhan-mysql
    environment:
      MYSQL_DATABASE: rayhan_erp_db
    volumes:
      - mysql_data:/var/lib/mysql

  backend:
    build: ./backend
    container_name: rayhan-backend
    ports:
      - "8090:8080"
    depends_on:
      mysql:
        condition: service_healthy
```

## 4.3 Dockerfile — Build Multi-Étapes

```dockerfile
# Étape 1 : Compilation Maven
FROM maven:3.9.6-eclipse-temurin-17 AS build
WORKDIR /app
COPY pom.xml .
RUN mvn dependency:go-offline
COPY src ./src
RUN mvn clean package -DskipTests

# Étape 2 : Image d'exécution légère
FROM eclipse-temurin:17-jre-alpine
WORKDIR /app
COPY --from=build /app/target/erp-1.0.0-SNAPSHOT.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]
```

## 4.4 Accès à l'Application

| Service | URL |
|---------|-----|
| API REST | https://rayhan-erp.bolbol.tn |
| Documentation Swagger UI | https://rayhan-erp.bolbol.tn/swagger-ui/index.html |
| Dépôt source (Gitea) | https://gitea.bolbol.tn/bolbol/rayhan-erp |

---

# Chapitre 5 — Tests et Validation

## 5.1 Interface Swagger UI

L'API intègre **Swagger UI** (SpringDoc OpenAPI 2.5.0), accessible depuis n'importe quel navigateur. Cette interface permet de :

- Visualiser tous les endpoints disponibles
- Tester chaque endpoint directement depuis le navigateur
- S'authentifier avec le JWT via le bouton "Authorize"

**Procédure de test :**

1. Ouvrir https://rayhan-erp.bolbol.tn/swagger-ui/index.html
2. Exécuter `POST /api/auth/signin` avec `{"username":"admin","password":"Rayhan2024!"}`
3. Copier le token de la réponse
4. Cliquer sur **Authorize 🔒** → coller le token → Authorize
5. Tester librement tous les endpoints

## 5.2 Scénario de Test Complet

| Étape | Action | Résultat attendu |
|-------|--------|-----------------|
| 1 | Connexion admin | Token JWT retourné |
| 2 | Créer article MP-HDPE | Article créé, stock = 0 |
| 3 | Créer commande fournisseur | Statut CONFIRMEE |
| 4 | Réceptionner commande | Stock MP augmente |
| 5 | Créer nomenclature BOM | Lien PF ↔ MP créé |
| 6 | Planifier + Lancer OF | Stock MP diminue (consommation) |
| 7 | Terminer OF | Stock PF augmente |
| 8 | Créer commande client | Statut CONFIRMEE |
| 9 | Livrer commande | Stock PF diminue |
| 10 | Tableau de bord | KPIs mis à jour |

---

# Chapitre 6 — Ce qui reste à faire

## 6.1 Frontend Flutter

Le frontend mobile/desktop sera développé avec Flutter et se connectera à l'API REST via des appels HTTP avec token JWT.

**Écrans à développer (par priorité) :**

1. **Écran de connexion** — formulaire login/password, stockage du token
2. **Tableau de bord** — affichage des KPIs (chiffre d'affaires, alertes stock, OF en cours)
3. **Articles** — liste, recherche, fiche détail, ajout/modification
4. **Cycle de vente** — liste commandes, création, bon de livraison
5. **Cycle d'achat** — liste commandes, création, bon de réception
6. **Production** — BOM, ordres de fabrication, lancement/terminaison
7. **Stock** — historique des mouvements, ajustements

**Architecture Flutter proposée :**

- **State management :** Provider ou Riverpod
- **HTTP client :** `http` ou `dio`
- **Stockage local :** `shared_preferences` (token JWT)
- **Navigation :** `go_router`

## 6.2 Modules Complémentaires API

| Module | Description | Priorité |
|--------|-------------|----------|
| Facturation | Génération de factures PDF | Haute |
| Paie / RH | Gestion des employés et salaires | Moyenne |
| Rapports | Export Excel/PDF des données | Moyenne |

---

# Annexes

## A — Initialisation Automatique

Au premier démarrage, le système crée automatiquement :

- Les 6 rôles dans la base de données
- L'utilisateur administrateur : **admin / Rayhan2024!** avec le rôle PDG

## B — Variables d'Environnement Docker

| Variable | Valeur |
|----------|--------|
| `SPRING_DATASOURCE_URL` | `jdbc:mysql://mysql:3306/rayhan_erp_db` |
| `SPRING_DATASOURCE_USERNAME` | `root` |
| `SPRING_DATASOURCE_PASSWORD` | `rayhan_erp_2024` |
| `RAYHAN_ERP_JWTSECRET` | Clé secrète JWT (256 bits) |
| `RAYHAN_ERP_JWTEXPIRATIONMS` | `86400000` (24 heures) |

## C — Commandes Docker Utiles

```bash
# Démarrer l'application
docker compose up -d

# Reconstruire après modification du code
docker compose up -d --build

# Voir les logs en temps réel
docker logs rayhan-backend -f

# Accéder à MySQL
docker exec -it rayhan-mysql mysql -u root -prayhan_erp_2024 rayhan_erp_db
```

---

# Chapitre 5 — Réalisation Frontend (Application Mobile Flutter)

## 5.1 Choix Technologique

L'interface utilisateur de l'ERP Rayhan est développée avec **Flutter**, le framework de Google permettant de créer des applications mobiles multiplateformes (Android et iOS) à partir d'une seule base de code Dart.

### Justification du choix Flutter

| Critère | Flutter | React Native | Natif Android/iOS |
|---------|---------|--------------|-------------------|
| Code partagé Android/iOS | 100% | ~85% | 0% |
| Performance | Excellente | Bonne | Excellente |
| Courbe d'apprentissage | Moyenne | Moyenne | Élevée |
| Écosystème packages | Riche | Riche | Natif |
| Rendu UI | Moteur propre (Skia) | Bridge natif | Natif |

Flutter a été retenu pour sa capacité à produire une application unique couvrant les deux plateformes mobiles majeures, tout en offrant des performances proches du natif grâce à son moteur de rendu indépendant.

## 5.2 Architecture du Projet Flutter

L'architecture adoptée suit le pattern **Provider + Services** :

```
frontend/
├── lib/
│   ├── main.dart                  # Point d'entrée, routing, thème
│   ├── screens/                   # Écrans de l'application
│   │   ├── login_screen.dart      # Écran de connexion
│   │   └── dashboard_screen.dart  # Tableau de bord KPI
│   ├── providers/                 # Gestion d'état (Provider)
│   │   └── auth_provider.dart     # État authentification
│   ├── services/                  # Appels API
│   │   ├── api_client.dart        # Client Dio + intercepteur JWT
│   │   └── auth_service.dart      # Service authentification
│   ├── models/                    # Modèles de données Dart
│   └── widgets/                   # Composants réutilisables
├── pubspec.yaml                   # Dépendances Flutter
└── android/                       # Configuration Android
```

### Dépendances principales

| Package | Version | Rôle |
|---------|---------|------|
| `dio` | ^5.4.0 | Client HTTP avec intercepteurs |
| `provider` | ^6.1.1 | Gestion d'état réactive |
| `shared_preferences` | ^2.2.2 | Stockage local du token JWT |
| `go_router` | ^13.2.0 | Navigation déclarative |
| `fl_chart` | ^0.67.0 | Graphiques pour le dashboard |
| `intl` | ^0.19.0 | Formatage dates et nombres |

## 5.3 Authentification et Sécurité

### Flux d'authentification

Le flux d'authentification suit le protocole JWT standard :

1. L'utilisateur saisit son identifiant et mot de passe
2. L'application envoie une requête `POST /api/auth/signin`
3. Le serveur retourne un token JWT signé (validité 24h)
4. Le token est stocké localement via `shared_preferences`
5. Chaque requête API suivante inclut automatiquement `Authorization: Bearer <token>`
6. À la déconnexion, le token est supprimé du stockage local

### Intercepteur JWT automatique

La classe `ApiClient` centralise toutes les communications HTTP et injecte automatiquement le token JWT dans les en-têtes via un intercepteur `Dio` :

```dart
class _AuthInterceptor extends Interceptor {
  @override
  void onRequest(RequestOptions options, RequestInterceptorHandler handler) async {
    final prefs = await SharedPreferences.getInstance();
    final token = prefs.getString('jwt_token');
    if (token != null) {
      options.headers['Authorization'] = 'Bearer $token';
    }
    handler.next(options);
  }
}
```

Cette approche centralise la gestion du token et évite sa répétition dans chaque appel API.

### Redirection automatique (GoRouter)

Le routeur détecte l'état d'authentification et redirige automatiquement :
- Un utilisateur non connecté est redirigé vers `/login`
- Un utilisateur déjà connecté accédant à `/login` est redirigé vers `/dashboard`

## 5.4 Écran de Connexion

L'écran de connexion (`LoginScreen`) présente une interface épurée et professionnelle :

**Composants UI :**
- Logo de l'application avec icône usine (représentant l'industrie plasturgie)
- Titre "RAYHAN ERP" et sous-titre
- Formulaire de connexion avec validation :
  - Champ identifiant avec icône
  - Champ mot de passe avec bouton afficher/masquer
  - Message d'erreur contextuel en cas d'échec
  - Bouton de connexion avec indicateur de chargement
- Footer © SUARL Rayhan

**Gestion des états :**
- État initial : formulaire vide
- État chargement : spinner animé, bouton désactivé
- État erreur : bandeau rouge avec message explicite
- État succès : redirection automatique vers le dashboard

---

## 5.5 Tableau de Bord KPI (Dashboard)

### Objectif

Le tableau de bord est l'écran central de l'application, accessible uniquement aux utilisateurs ayant le rôle **PDG**. Il synthétise en temps réel l'état de l'entreprise à travers des indicateurs clés de performance (KPI).

### Données affichées

L'écran récupère les données depuis l'endpoint `GET /api/dashboard` et les affiche en trois sections :

**Section Ventes (mois en cours)**

| KPI | Description |
|-----|-------------|
| Chiffre d'affaires | Montant total des ventes du mois en TND |
| Commandes ce mois | Nombre de bons de commande clients créés |
| Commandes en cours | Commandes en attente de livraison |

**Section Achats & Production**

| KPI | Description |
|-----|-------------|
| Achats en attente | Bons de commande fournisseurs non réceptionnés |
| OF en cours | Ordres de fabrication au statut LANCE |
| OF planifiés | Ordres de fabrication au statut PLANIFIE |

**Section Stock**

- Nombre d'articles dont le stock est inférieur au seuil minimum
- Liste détaillée des articles en alerte avec leur quantité en stock actuelle

### Architecture technique

La gestion du dashboard suit le pattern **Provider** :

```
GET /api/dashboard
       │
DashboardService.fetchKpis()
       │
DashboardProvider (ChangeNotifier)
  ├── isLoading
  ├── error
  └── kpi: DashboardKpi
            ├── VentesKpi
            ├── AchatsKpi
            ├── ProductionKpi
            └── StockKpi
       │
DashboardScreen (Consumer)
  ├── KpiCard × 6 (grille 2 colonnes)
  └── _StockSection (liste alertes)
```

### Navigation (Drawer)

Un menu latéral (`AppDrawer`) permet la navigation entre tous les modules :
- Tableau de bord
- Articles
- Ventes
- Achats
- Production
- Stock
- Déconnexion

Le drawer affiche le rôle de l'utilisateur connecté et met en surbrillance la section active.

### Comportement UI

- **Pull-to-refresh** : glisser vers le bas recharge les KPIs
- **Bouton actualiser** dans l'AppBar
- **État chargement** : spinner centré
- **État erreur** : message avec bouton "Réessayer"
- **Alertes stock** : icône verte si tout va bien, rouge avec liste si alertes

---

*[Section à compléter avec captures d'écran lors de la finalisation du rapport]*

---

## 5.6 Module Articles

### Objectif

Le module Articles permet de gérer le **catalogue complet** des références de l'entreprise, organisé en trois catégories correspondant au cycle industriel de SUARL Rayhan :

| Type | Code | Description |
|------|------|-------------|
| Matière Première | MP | Granulés PEHD/LDPE, colorants, additifs |
| Produit Semi-Fini | PSF | Film tubulaire non découpé |
| Produit Fini | PF | Sacs Bertel, sacs poubelles, film rétractable |

### Fonctionnalités

- **Liste filtrée** : affichage de tous les articles avec filtre par type (MP / PSF / PF) et barre de recherche en temps réel
- **Indicateur d'alerte** : les articles dont le stock est inférieur au seuil minimum sont signalés en rouge avec icône d'avertissement
- **Création** : formulaire complet (référence, désignation, type, unité de mesure, prix unitaire, stock initial, seuil d'alerte)
- **Modification** : édition de tous les champs sauf la référence (clé métier immuable)
- **Archivage** : suppression logique (l'article est marqué `actif=false`, pas effacé de la base)

### Architecture technique

```
ArticleService (Dio)          ArticleProvider (ChangeNotifier)
  ├── fetchAll()      ─────►    ├── _articles: List<Article>
  ├── fetchByType()             ├── _filterType: String
  ├── create()                  ├── _search: String
  ├── update()                  └── articles (getter filtré)
  └── delete()
                                       │
                              ArticlesScreen
                                ├── _SearchBar
                                ├── _FilterChips (TOUS / MP / PSF / PF)
                                └── ListView → _ArticleCard
                                               └── PopupMenu (Modifier / Supprimer)

                              ArticleFormScreen (création + édition)
                                ├── Section Identification (ref, désignation, type)
                                ├── Section Unité & Prix
                                └── Section Stock (actuel + seuil minimum)
```

### Modèle de données

```dart
class Article {
  int? id;
  String reference;      // Clé unique (ex: MP-001)
  String designation;    // Libellé
  String type;           // MP | PSF | PF
  String? uniteMesure;   // kg, unité, rouleau, m
  double prixUnitaire;   // En TND
  double stockActuel;    // Quantité en stock
  double stockMinimum;   // Seuil d'alerte
  bool actif;            // Soft delete
}
```

---

## 5.7 Module Ventes

### Objectif

Le module Ventes couvre le **cycle de vente complet** de SUARL Rayhan, de la prise de commande client jusqu'à la livraison et la mise à jour automatique du stock.

### Cycle de vente

```
Client passe commande
        │
  POST /api/sales-orders
        │
  Vérification stock disponible (backend)
        │
  Calcul automatique HT / TVA 19% / TTC
        │
  Commande → statut CONFIRMEE
        │
  POST /api/sales-orders/{id}/deliver
        │
  Bon de livraison généré (BL-XXXX-XXX)
        │
  Sortie de stock automatique
        │
  Commande → statut COMPLETEMENT_LIVREE
```

### Statuts d'une commande

| Statut | Description | Couleur |
|--------|-------------|---------|
| CONFIRMEE | Commande validée, stock vérifié | Bleu |
| EN_PREPARATION | En cours de préparation | Orange |
| PARTIELLEMENT_LIVREE | Livraison partielle effectuée | Violet |
| COMPLETEMENT_LIVREE | Toutes les lignes livrées | Vert |
| ANNULEE | Commande annulée | Rouge |

### Fonctionnalités Flutter

**Écran liste (`VentesScreen`) :**
- Liste de toutes les commandes avec badge statut coloré
- Montant TTC visible directement sur la carte
- Accès au détail par tap

**Formulaire création (`SalesOrderFormScreen`) :**
- Sélection du client (dropdown)
- Date de livraison souhaitée (sélecteur de date)
- Lignes dynamiques : ajout / suppression d'articles
  - Sélection article (avec pré-remplissage du prix)
  - Quantité + prix unitaire HT
- Calcul en temps réel du total HT / TVA / TTC
- Notes optionnelles

**Écran détail (`SalesOrderDetailScreen`) :**
- Toutes les informations de la commande
- Liste des lignes avec quantités et montants
- Récapitulatif financier HT / TVA / TTC
- Bouton **Livrer** (affiché uniquement si la commande est livrable)
- Confirmation de livraison avec mise à jour automatique du 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.

---

## 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) |

