18 KiB
| title | subtitle | author | date | lang |
|---|---|---|---|---|
| Rapport de Projet — ERP SUARL Rayhan | Projet de Fin d'Études — Ali Guennari | Ali Guennari | Avril 2026 | 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 :
- Le client envoie ses identifiants à
POST /api/auth/signin - Le serveur valide et retourne un JWT signé (valable 24h)
- Le client inclut
Authorization: Bearer <token>dans chaque requête - Le filtre
AuthTokenFilterintercepte 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 :
@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
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
# É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 :
- Ouvrir https://rayhan-erp.bolbol.tn/swagger-ui/index.html
- Exécuter
POST /api/auth/signinavec{"username":"admin","password":"Rayhan2024!"} - Copier le token de la réponse
- Cliquer sur Authorize 🔒 → coller le token → Authorize
- 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é) :
- Écran de connexion — formulaire login/password, stockage du token
- Tableau de bord — affichage des KPIs (chiffre d'affaires, alertes stock, OF en cours)
- Articles — liste, recherche, fiche détail, ajout/modification
- Cycle de vente — liste commandes, création, bon de livraison
- Cycle d'achat — liste commandes, création, bon de réception
- Production — BOM, ordres de fabrication, lancement/terminaison
- Stock — historique des mouvements, ajustements
Architecture Flutter proposée :
- State management : Provider ou Riverpod
- HTTP client :
httpoudio - 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
# 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 :
- L'utilisateur saisit son identifiant et mot de passe
- L'application envoie une requête
POST /api/auth/signin - Le serveur retourne un token JWT signé (validité 24h)
- Le token est stocké localement via
shared_preferences - Chaque requête API suivante inclut automatiquement
Authorization: Bearer <token> - À 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 :
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 à
/loginest 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
[Section à compléter avec captures d'écran lors de la finalisation du rapport]