Initial commit
This commit is contained in:
360
docs/concepts/01-CHANTIER.md
Normal file
360
docs/concepts/01-CHANTIER.md
Normal file
@@ -0,0 +1,360 @@
|
||||
# 🏗️ CONCEPT: CHANTIER
|
||||
|
||||
## 📌 Vue d'ensemble
|
||||
|
||||
Le concept **CHANTIER** est le **cœur métier** de l'application BTPXpress. Il représente un projet de construction BTP avec toutes ses caractéristiques : localisation, dates, budget, statut, phases, et relations avec les clients, devis, factures, etc.
|
||||
|
||||
**Importance**: ⭐⭐⭐⭐⭐ (Concept central)
|
||||
|
||||
---
|
||||
|
||||
## 🗂️ Fichiers concernés
|
||||
|
||||
### **Entités JPA** (`domain/core/entity/`)
|
||||
| Fichier | Description | Lignes |
|
||||
|---------|-------------|--------|
|
||||
| `Chantier.java` | Entité principale représentant un chantier BTP | 224 |
|
||||
| `StatutChantier.java` | Enum des statuts possibles d'un chantier | 24 |
|
||||
| `TypeChantier.java` | Entité type de chantier (configurable) | ~150 |
|
||||
| `TypeChantierBTP.java` | Enum types BTP prédéfinis | ~50 |
|
||||
| `Phase.java` | Phase générique de chantier | ~100 |
|
||||
| `PhaseChantier.java` | Phase spécifique à un chantier | ~180 |
|
||||
| `PhaseTemplate.java` | Template de phase réutilisable | ~120 |
|
||||
| `SousPhaseTemplate.java` | Sous-phase de template | ~80 |
|
||||
| `TacheTemplate.java` | Template de tâche | ~100 |
|
||||
| `StatutPhaseChantier.java` | Enum statuts de phase | ~40 |
|
||||
| `TypePhaseChantier.java` | Enum types de phase | ~30 |
|
||||
| `PrioritePhase.java` | Enum priorités de phase | ~25 |
|
||||
|
||||
### **DTOs** (`domain/shared/dto/`)
|
||||
| Fichier | Description |
|
||||
|---------|-------------|
|
||||
| `ChantierCreateDTO.java` | DTO pour créer/modifier un chantier |
|
||||
| `PhaseChantierDTO.java` | DTO pour les phases de chantier |
|
||||
|
||||
### **Services** (`application/service/`)
|
||||
| Fichier | Description |
|
||||
|---------|-------------|
|
||||
| `ChantierService.java` | Service métier principal pour les chantiers |
|
||||
| `PhaseChantierService.java` | Service pour la gestion des phases |
|
||||
| `PhaseTemplateService.java` | Service pour les templates de phases |
|
||||
| `TacheTemplateService.java` | Service pour les templates de tâches |
|
||||
|
||||
### **Resources (API REST)** (`adapter/http/`)
|
||||
| Fichier | Description |
|
||||
|---------|-------------|
|
||||
| `ChantierResource.java` | Endpoints REST pour les chantiers |
|
||||
| `PhaseChantierResource.java` | Endpoints REST pour les phases |
|
||||
|
||||
---
|
||||
|
||||
## 📊 Modèle de données
|
||||
|
||||
### **Entité Chantier**
|
||||
|
||||
<augment_code_snippet path="btpxpress-server/src/main/java/dev/lions/btpxpress/domain/core/entity/Chantier.java" mode="EXCERPT">
|
||||
````java
|
||||
@Entity
|
||||
@Table(name = "chantiers")
|
||||
@Data
|
||||
@Builder
|
||||
public class Chantier extends PanacheEntityBase {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.UUID)
|
||||
private UUID id;
|
||||
|
||||
@NotBlank(message = "Le nom du chantier est obligatoire")
|
||||
@Column(name = "nom", nullable = false, length = 200)
|
||||
private String nom;
|
||||
|
||||
@Column(name = "code", unique = true, length = 50)
|
||||
private String code;
|
||||
|
||||
@NotBlank(message = "L'adresse du chantier est obligatoire")
|
||||
@Column(name = "adresse", nullable = false, length = 500)
|
||||
private String adresse;
|
||||
|
||||
@Enumerated(EnumType.STRING)
|
||||
@Column(name = "statut", nullable = false)
|
||||
private StatutChantier statut = StatutChantier.PLANIFIE;
|
||||
|
||||
@Column(name = "montant_prevu", precision = 10, scale = 2)
|
||||
private BigDecimal montantPrevu;
|
||||
|
||||
// Relations
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "client_id", nullable = false)
|
||||
private Client client;
|
||||
|
||||
@OneToMany(mappedBy = "chantier", cascade = CascadeType.ALL)
|
||||
private List<Devis> devis;
|
||||
|
||||
@OneToMany(mappedBy = "chantier", cascade = CascadeType.ALL)
|
||||
private List<Facture> factures;
|
||||
// ...
|
||||
}
|
||||
````
|
||||
</augment_code_snippet>
|
||||
|
||||
### **Enum StatutChantier**
|
||||
|
||||
<augment_code_snippet path="btpxpress-server/src/main/java/dev/lions/btpxpress/domain/core/entity/StatutChantier.java" mode="EXCERPT">
|
||||
````java
|
||||
public enum StatutChantier {
|
||||
PLANIFIE("Planifié"),
|
||||
EN_COURS("En cours"),
|
||||
TERMINE("Terminé"),
|
||||
ANNULE("Annulé"),
|
||||
SUSPENDU("Suspendu");
|
||||
|
||||
private final String label;
|
||||
|
||||
StatutChantier(String label) {
|
||||
this.label = label;
|
||||
}
|
||||
|
||||
public String getLabel() {
|
||||
return label;
|
||||
}
|
||||
}
|
||||
````
|
||||
</augment_code_snippet>
|
||||
|
||||
### **Champs principaux**
|
||||
|
||||
| Champ | Type | Obligatoire | Description |
|
||||
|-------|------|-------------|-------------|
|
||||
| `id` | UUID | Oui | Identifiant unique |
|
||||
| `nom` | String(200) | Oui | Nom du chantier |
|
||||
| `code` | String(50) | Non | Code unique du chantier |
|
||||
| `description` | TEXT | Non | Description détaillée |
|
||||
| `adresse` | String(500) | Oui | Adresse du chantier |
|
||||
| `codePostal` | String(10) | Non | Code postal |
|
||||
| `ville` | String(100) | Non | Ville |
|
||||
| `dateDebut` | LocalDate | Oui | Date de début |
|
||||
| `dateDebutPrevue` | LocalDate | Non | Date de début prévue |
|
||||
| `dateDebutReelle` | LocalDate | Non | Date de début réelle |
|
||||
| `dateFinPrevue` | LocalDate | Non | Date de fin prévue |
|
||||
| `dateFinReelle` | LocalDate | Non | Date de fin réelle |
|
||||
| `statut` | StatutChantier | Oui | Statut actuel (défaut: PLANIFIE) |
|
||||
| `montantPrevu` | BigDecimal | Non | Montant prévu |
|
||||
| `montantReel` | BigDecimal | Non | Montant réel |
|
||||
| `typeChantier` | TypeChantierBTP | Non | Type de chantier |
|
||||
| `actif` | Boolean | Oui | Chantier actif (défaut: true) |
|
||||
| `dateCreation` | LocalDateTime | Auto | Date de création |
|
||||
| `dateModification` | LocalDateTime | Auto | Date de modification |
|
||||
|
||||
### **Relations**
|
||||
|
||||
| Relation | Type | Entité cible | Description |
|
||||
|----------|------|--------------|-------------|
|
||||
| `client` | ManyToOne | Client | Client propriétaire (obligatoire) |
|
||||
| `chefChantier` | ManyToOne | User | Chef de chantier responsable |
|
||||
| `devis` | OneToMany | Devis | Liste des devis associés |
|
||||
| `factures` | OneToMany | Facture | Liste des factures |
|
||||
|
||||
---
|
||||
|
||||
## 🔌 API REST
|
||||
|
||||
### **Base URL**: `/api/v1/chantiers`
|
||||
|
||||
### **Endpoints disponibles**
|
||||
|
||||
| Méthode | Endpoint | Description | Authentification |
|
||||
|---------|----------|-------------|------------------|
|
||||
| GET | `/api/v1/chantiers` | Liste tous les chantiers | Optionnelle |
|
||||
| GET | `/api/v1/chantiers/actifs` | Liste chantiers actifs | Optionnelle |
|
||||
| GET | `/api/v1/chantiers/{id}` | Détails d'un chantier | Optionnelle |
|
||||
| POST | `/api/v1/chantiers` | Créer un chantier | Optionnelle |
|
||||
| PUT | `/api/v1/chantiers/{id}` | Modifier un chantier | Optionnelle |
|
||||
| DELETE | `/api/v1/chantiers/{id}` | Supprimer un chantier | Optionnelle |
|
||||
| GET | `/api/v1/chantiers/statut/{statut}` | Chantiers par statut | Optionnelle |
|
||||
| GET | `/api/v1/chantiers/client/{clientId}` | Chantiers d'un client | Optionnelle |
|
||||
| GET | `/api/v1/chantiers/search` | Recherche de chantiers | Optionnelle |
|
||||
| GET | `/api/v1/chantiers/stats` | Statistiques chantiers | Optionnelle |
|
||||
|
||||
### **Paramètres de requête (Query Params)**
|
||||
|
||||
| Paramètre | Type | Description | Exemple |
|
||||
|-----------|------|-------------|---------|
|
||||
| `search` | String | Terme de recherche | `?search=villa` |
|
||||
| `statut` | String | Filtrer par statut | `?statut=EN_COURS` |
|
||||
| `clientId` | UUID | Filtrer par client | `?clientId=uuid` |
|
||||
|
||||
---
|
||||
|
||||
## 💻 Exemples d'utilisation
|
||||
|
||||
### **1. Récupérer tous les chantiers**
|
||||
|
||||
```bash
|
||||
curl -X GET http://localhost:8080/api/v1/chantiers \
|
||||
-H "Accept: application/json"
|
||||
```
|
||||
|
||||
**Réponse** (200 OK):
|
||||
```json
|
||||
[
|
||||
{
|
||||
"id": "550e8400-e29b-41d4-a716-446655440000",
|
||||
"nom": "Construction Villa Moderne",
|
||||
"code": "CHANT-2025-001",
|
||||
"adresse": "123 Avenue des Champs",
|
||||
"codePostal": "75008",
|
||||
"ville": "Paris",
|
||||
"statut": "EN_COURS",
|
||||
"montantPrevu": 250000.00,
|
||||
"dateDebut": "2025-01-15",
|
||||
"dateFinPrevue": "2025-12-31",
|
||||
"actif": true
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
### **2. Créer un nouveau chantier**
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:8080/api/v1/chantiers \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"nom": "Rénovation Appartement",
|
||||
"adresse": "45 Rue de la Paix",
|
||||
"codePostal": "75002",
|
||||
"ville": "Paris",
|
||||
"dateDebut": "2025-10-01",
|
||||
"dateFinPrevue": "2025-12-15",
|
||||
"montantPrevu": 75000.00,
|
||||
"clientId": "client-uuid-here",
|
||||
"statut": "PLANIFIE"
|
||||
}'
|
||||
```
|
||||
|
||||
**Réponse** (201 Created):
|
||||
```json
|
||||
{
|
||||
"id": "generated-uuid",
|
||||
"nom": "Rénovation Appartement",
|
||||
"statut": "PLANIFIE",
|
||||
"dateCreation": "2025-09-30T10:30:00"
|
||||
}
|
||||
```
|
||||
|
||||
### **3. Rechercher des chantiers**
|
||||
|
||||
```bash
|
||||
# Par nom
|
||||
curl -X GET "http://localhost:8080/api/v1/chantiers?search=villa"
|
||||
|
||||
# Par statut
|
||||
curl -X GET "http://localhost:8080/api/v1/chantiers?statut=EN_COURS"
|
||||
|
||||
# Par client
|
||||
curl -X GET "http://localhost:8080/api/v1/chantiers?clientId=uuid-client"
|
||||
```
|
||||
|
||||
### **4. Obtenir les statistiques**
|
||||
|
||||
```bash
|
||||
curl -X GET http://localhost:8080/api/v1/chantiers/stats
|
||||
```
|
||||
|
||||
**Réponse**:
|
||||
```json
|
||||
{
|
||||
"totalChantiers": 45,
|
||||
"chantiersActifs": 38,
|
||||
"enCours": 12,
|
||||
"planifies": 8,
|
||||
"termines": 15,
|
||||
"suspendus": 2,
|
||||
"annules": 1,
|
||||
"montantTotalPrevu": 5250000.00,
|
||||
"montantTotalReel": 4890000.00
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔧 Services métier
|
||||
|
||||
### **ChantierService**
|
||||
|
||||
**Méthodes principales**:
|
||||
|
||||
| Méthode | Description | Retour |
|
||||
|---------|-------------|--------|
|
||||
| `findAll()` | Récupère tous les chantiers | `List<Chantier>` |
|
||||
| `findActifs()` | Récupère chantiers actifs | `List<Chantier>` |
|
||||
| `findById(UUID id)` | Récupère par ID | `Optional<Chantier>` |
|
||||
| `create(ChantierCreateDTO dto)` | Crée un chantier | `Chantier` |
|
||||
| `update(UUID id, ChantierCreateDTO dto)` | Met à jour | `Chantier` |
|
||||
| `delete(UUID id)` | Supprime (soft delete) | `void` |
|
||||
| `findByStatut(StatutChantier statut)` | Filtre par statut | `List<Chantier>` |
|
||||
| `findByClient(UUID clientId)` | Chantiers d'un client | `List<Chantier>` |
|
||||
| `search(String term)` | Recherche textuelle | `List<Chantier>` |
|
||||
| `getStatistics()` | Statistiques globales | `Object` |
|
||||
|
||||
---
|
||||
|
||||
## 🔐 Permissions requises
|
||||
|
||||
| Permission | Description | Rôles autorisés |
|
||||
|------------|-------------|-----------------|
|
||||
| `CHANTIERS_READ` | Lecture des chantiers | ADMIN, MANAGER, CHEF_CHANTIER, COMPTABLE, OUVRIER |
|
||||
| `CHANTIERS_CREATE` | Création de chantiers | ADMIN, MANAGER |
|
||||
| `CHANTIERS_UPDATE` | Modification de chantiers | ADMIN, MANAGER, CHEF_CHANTIER |
|
||||
| `CHANTIERS_DELETE` | Suppression de chantiers | ADMIN, MANAGER |
|
||||
| `CHANTIERS_PHASES` | Gestion des phases | ADMIN, MANAGER, CHEF_CHANTIER |
|
||||
| `CHANTIERS_BUDGET` | Gestion du budget | ADMIN, MANAGER, COMPTABLE |
|
||||
|
||||
---
|
||||
|
||||
## 📈 Relations avec autres concepts
|
||||
|
||||
### **Dépendances directes**:
|
||||
- **CLIENT** ⬅️ Un chantier appartient à un client (obligatoire)
|
||||
- **USER** ⬅️ Un chantier peut avoir un chef de chantier
|
||||
- **DEVIS** ➡️ Un chantier peut avoir plusieurs devis
|
||||
- **FACTURE** ➡️ Un chantier peut avoir plusieurs factures
|
||||
- **PHASE** ➡️ Un chantier est divisé en phases
|
||||
- **BUDGET** ➡️ Un chantier a un budget associé
|
||||
- **PLANNING** ➡️ Un chantier a un planning
|
||||
- **DOCUMENT** ➡️ Un chantier peut avoir des documents (plans, photos, etc.)
|
||||
|
||||
---
|
||||
|
||||
## 🧪 Tests
|
||||
|
||||
### **Tests unitaires**
|
||||
- Fichier: `ChantierServiceTest.java`
|
||||
- Couverture: Logique métier, validations, calculs
|
||||
|
||||
### **Tests d'intégration**
|
||||
- Fichier: `ChantierResourceTest.java`
|
||||
- Couverture: Endpoints REST, sérialisation JSON
|
||||
|
||||
### **Commande pour exécuter les tests**:
|
||||
```bash
|
||||
cd btpxpress-server
|
||||
./mvnw test -Dtest=ChantierServiceTest
|
||||
./mvnw test -Dtest=ChantierResourceTest
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📚 Références
|
||||
|
||||
- [API Documentation complète](../API.md#chantiers)
|
||||
- [Schéma de base de données](../DATABASE.md#table-chantiers)
|
||||
- [Guide d'architecture](../architecture/domain-model.md#chantier)
|
||||
- [Service ChantierService](../../src/main/java/dev/lions/btpxpress/application/service/ChantierService.java)
|
||||
- [Resource ChantierResource](../../src/main/java/dev/lions/btpxpress/adapter/http/ChantierResource.java)
|
||||
|
||||
---
|
||||
|
||||
**Dernière mise à jour**: 2025-09-30
|
||||
**Version**: 1.0
|
||||
**Auteur**: Documentation BTPXpress
|
||||
|
||||
380
docs/concepts/02-CLIENT.md
Normal file
380
docs/concepts/02-CLIENT.md
Normal file
@@ -0,0 +1,380 @@
|
||||
# 👤 CONCEPT: CLIENT
|
||||
|
||||
## 📌 Vue d'ensemble
|
||||
|
||||
Le concept **CLIENT** représente les clients de l'entreprise BTP, qu'ils soient **particuliers** ou **professionnels**. Il gère toutes les informations de contact, coordonnées, et relations avec les chantiers et devis.
|
||||
|
||||
**Importance**: ⭐⭐⭐⭐⭐ (Concept fondamental)
|
||||
|
||||
---
|
||||
|
||||
## 🗂️ Fichiers concernés
|
||||
|
||||
### **Entités JPA** (`domain/core/entity/`)
|
||||
| Fichier | Description | Lignes |
|
||||
|---------|-------------|--------|
|
||||
| `Client.java` | Entité principale représentant un client | 113 |
|
||||
| `TypeClient.java` | Enum des types de clients (PARTICULIER, PROFESSIONNEL) | 21 |
|
||||
|
||||
### **DTOs** (`domain/shared/dto/`)
|
||||
| Fichier | Description |
|
||||
|---------|-------------|
|
||||
| `ClientCreateDTO.java` | DTO pour créer/modifier un client |
|
||||
|
||||
### **Services** (`application/service/`)
|
||||
| Fichier | Description |
|
||||
|---------|-------------|
|
||||
| `ClientService.java` | Service métier pour la gestion des clients |
|
||||
|
||||
### **Resources (API REST)** (`adapter/http/`)
|
||||
| Fichier | Description |
|
||||
|---------|-------------|
|
||||
| `ClientResource.java` | Endpoints REST pour les clients |
|
||||
|
||||
---
|
||||
|
||||
## 📊 Modèle de données
|
||||
|
||||
### **Entité Client**
|
||||
|
||||
<augment_code_snippet path="btpxpress-server/src/main/java/dev/lions/btpxpress/domain/core/entity/Client.java" mode="EXCERPT">
|
||||
````java
|
||||
@Entity
|
||||
@Table(name = "clients")
|
||||
@Data
|
||||
@Builder
|
||||
public class Client extends PanacheEntityBase {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.UUID)
|
||||
private UUID id;
|
||||
|
||||
@NotBlank(message = "Le nom est obligatoire")
|
||||
@Column(name = "nom", nullable = false, length = 100)
|
||||
private String nom;
|
||||
|
||||
@NotBlank(message = "Le prénom est obligatoire")
|
||||
@Column(name = "prenom", nullable = false, length = 100)
|
||||
private String prenom;
|
||||
|
||||
@Column(name = "entreprise", length = 200)
|
||||
private String entreprise;
|
||||
|
||||
@Email(message = "Email invalide")
|
||||
@Column(name = "email", unique = true, length = 255)
|
||||
private String email;
|
||||
|
||||
@Pattern(regexp = "^(?:(?:\\+|00)33|0)\\s*[1-9](?:[\\s.-]*\\d{2}){4}$")
|
||||
@Column(name = "telephone", length = 20)
|
||||
private String telephone;
|
||||
|
||||
@Enumerated(EnumType.STRING)
|
||||
@Column(name = "type_client", length = 20)
|
||||
private TypeClient type = TypeClient.PARTICULIER;
|
||||
|
||||
// Relations
|
||||
@OneToMany(mappedBy = "client", cascade = CascadeType.ALL)
|
||||
private List<Chantier> chantiers;
|
||||
|
||||
@OneToMany(mappedBy = "client", cascade = CascadeType.ALL)
|
||||
private List<Devis> devis;
|
||||
}
|
||||
````
|
||||
</augment_code_snippet>
|
||||
|
||||
### **Enum TypeClient**
|
||||
|
||||
<augment_code_snippet path="btpxpress-server/src/main/java/dev/lions/btpxpress/domain/core/entity/TypeClient.java" mode="EXCERPT">
|
||||
````java
|
||||
public enum TypeClient {
|
||||
PARTICULIER("Particulier"),
|
||||
PROFESSIONNEL("Professionnel");
|
||||
|
||||
private final String label;
|
||||
|
||||
TypeClient(String label) {
|
||||
this.label = label;
|
||||
}
|
||||
|
||||
public String getLabel() {
|
||||
return label;
|
||||
}
|
||||
}
|
||||
````
|
||||
</augment_code_snippet>
|
||||
|
||||
### **Champs principaux**
|
||||
|
||||
| Champ | Type | Obligatoire | Description |
|
||||
|-------|------|-------------|-------------|
|
||||
| `id` | UUID | Oui | Identifiant unique |
|
||||
| `nom` | String(100) | Oui | Nom du client |
|
||||
| `prenom` | String(100) | Oui | Prénom du client |
|
||||
| `entreprise` | String(200) | Non | Nom de l'entreprise (si professionnel) |
|
||||
| `email` | String(255) | Non | Email (unique) |
|
||||
| `telephone` | String(20) | Non | Téléphone (format français validé) |
|
||||
| `adresse` | String(500) | Non | Adresse postale |
|
||||
| `codePostal` | String(10) | Non | Code postal |
|
||||
| `ville` | String(100) | Non | Ville |
|
||||
| `numeroTVA` | String(20) | Non | Numéro de TVA intracommunautaire |
|
||||
| `siret` | String(14) | Non | Numéro SIRET (entreprises françaises) |
|
||||
| `type` | TypeClient | Oui | Type de client (défaut: PARTICULIER) |
|
||||
| `actif` | Boolean | Oui | Client actif (défaut: true) |
|
||||
| `dateCreation` | LocalDateTime | Auto | Date de création |
|
||||
| `dateModification` | LocalDateTime | Auto | Date de modification |
|
||||
|
||||
### **Relations**
|
||||
|
||||
| Relation | Type | Entité cible | Description |
|
||||
|----------|------|--------------|-------------|
|
||||
| `chantiers` | OneToMany | Chantier | Liste des chantiers du client |
|
||||
| `devis` | OneToMany | Devis | Liste des devis du client |
|
||||
|
||||
---
|
||||
|
||||
## 🔌 API REST
|
||||
|
||||
### **Base URL**: `/api/v1/clients`
|
||||
|
||||
### **Endpoints disponibles**
|
||||
|
||||
| Méthode | Endpoint | Description | Permission |
|
||||
|---------|----------|-------------|------------|
|
||||
| GET | `/api/v1/clients` | Liste tous les clients | CLIENTS_READ |
|
||||
| GET | `/api/v1/clients/{id}` | Détails d'un client | CLIENTS_READ |
|
||||
| POST | `/api/v1/clients` | Créer un client | CLIENTS_CREATE |
|
||||
| PUT | `/api/v1/clients/{id}` | Modifier un client | CLIENTS_UPDATE |
|
||||
| DELETE | `/api/v1/clients/{id}` | Supprimer un client | CLIENTS_DELETE |
|
||||
| GET | `/api/v1/clients/search` | Rechercher des clients | CLIENTS_READ |
|
||||
| GET | `/api/v1/clients/stats` | Statistiques clients | CLIENTS_READ |
|
||||
|
||||
### **Paramètres de requête (Query Params)**
|
||||
|
||||
| Paramètre | Type | Description | Exemple |
|
||||
|-----------|------|-------------|---------|
|
||||
| `page` | Integer | Numéro de page (0-based) | `?page=0` |
|
||||
| `size` | Integer | Taille de la page | `?size=20` |
|
||||
| `search` | String | Terme de recherche | `?search=dupont` |
|
||||
|
||||
---
|
||||
|
||||
## 💻 Exemples d'utilisation
|
||||
|
||||
### **1. Récupérer tous les clients**
|
||||
|
||||
```bash
|
||||
curl -X GET http://localhost:8080/api/v1/clients \
|
||||
-H "Accept: application/json"
|
||||
```
|
||||
|
||||
**Réponse** (200 OK):
|
||||
```json
|
||||
[
|
||||
{
|
||||
"id": "550e8400-e29b-41d4-a716-446655440000",
|
||||
"nom": "Dupont",
|
||||
"prenom": "Jean",
|
||||
"email": "jean.dupont@example.com",
|
||||
"telephone": "+33 6 12 34 56 78",
|
||||
"adresse": "123 Rue de la Paix",
|
||||
"codePostal": "75002",
|
||||
"ville": "Paris",
|
||||
"type": "PARTICULIER",
|
||||
"actif": true,
|
||||
"dateCreation": "2025-01-15T10:30:00"
|
||||
},
|
||||
{
|
||||
"id": "660e8400-e29b-41d4-a716-446655440001",
|
||||
"nom": "Martin",
|
||||
"prenom": "Sophie",
|
||||
"entreprise": "BTP Solutions SARL",
|
||||
"email": "contact@btpsolutions.fr",
|
||||
"telephone": "+33 1 23 45 67 89",
|
||||
"siret": "12345678901234",
|
||||
"numeroTVA": "FR12345678901",
|
||||
"type": "PROFESSIONNEL",
|
||||
"actif": true
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
### **2. Créer un nouveau client particulier**
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:8080/api/v1/clients \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"nom": "Durand",
|
||||
"prenom": "Pierre",
|
||||
"email": "pierre.durand@example.com",
|
||||
"telephone": "+33 6 98 76 54 32",
|
||||
"adresse": "45 Avenue des Champs",
|
||||
"codePostal": "75008",
|
||||
"ville": "Paris",
|
||||
"type": "PARTICULIER"
|
||||
}'
|
||||
```
|
||||
|
||||
**Réponse** (201 Created):
|
||||
```json
|
||||
{
|
||||
"id": "generated-uuid",
|
||||
"nom": "Durand",
|
||||
"prenom": "Pierre",
|
||||
"email": "pierre.durand@example.com",
|
||||
"type": "PARTICULIER",
|
||||
"actif": true,
|
||||
"dateCreation": "2025-09-30T14:25:00"
|
||||
}
|
||||
```
|
||||
|
||||
### **3. Créer un client professionnel**
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:8080/api/v1/clients \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"nom": "Entreprise",
|
||||
"prenom": "Construction",
|
||||
"entreprise": "ABC Construction SA",
|
||||
"email": "contact@abc-construction.fr",
|
||||
"telephone": "+33 1 45 67 89 01",
|
||||
"adresse": "10 Boulevard Haussmann",
|
||||
"codePostal": "75009",
|
||||
"ville": "Paris",
|
||||
"siret": "98765432109876",
|
||||
"numeroTVA": "FR98765432109",
|
||||
"type": "PROFESSIONNEL"
|
||||
}'
|
||||
```
|
||||
|
||||
### **4. Rechercher des clients**
|
||||
|
||||
```bash
|
||||
# Par nom
|
||||
curl -X GET "http://localhost:8080/api/v1/clients/search?search=dupont"
|
||||
|
||||
# Avec pagination
|
||||
curl -X GET "http://localhost:8080/api/v1/clients?page=0&size=10"
|
||||
```
|
||||
|
||||
### **5. Obtenir les statistiques**
|
||||
|
||||
```bash
|
||||
curl -X GET http://localhost:8080/api/v1/clients/stats
|
||||
```
|
||||
|
||||
**Réponse**:
|
||||
```json
|
||||
{
|
||||
"totalClients": 156,
|
||||
"clientsActifs": 142,
|
||||
"particuliers": 98,
|
||||
"professionnels": 58,
|
||||
"nouveauxCeMois": 12,
|
||||
"avecChantiers": 87,
|
||||
"sansChantiers": 69
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔧 Services métier
|
||||
|
||||
### **ClientService**
|
||||
|
||||
**Méthodes principales**:
|
||||
|
||||
| Méthode | Description | Retour |
|
||||
|---------|-------------|--------|
|
||||
| `findAll()` | Récupère tous les clients | `List<Client>` |
|
||||
| `findAll(int page, int size)` | Récupère avec pagination | `List<Client>` |
|
||||
| `findById(UUID id)` | Récupère par ID | `Optional<Client>` |
|
||||
| `findByIdRequired(UUID id)` | Récupère par ID (exception si absent) | `Client` |
|
||||
| `create(ClientCreateDTO dto)` | Crée un client | `Client` |
|
||||
| `update(UUID id, ClientCreateDTO dto)` | Met à jour | `Client` |
|
||||
| `delete(UUID id)` | Supprime (soft delete) | `void` |
|
||||
| `search(String term)` | Recherche textuelle | `List<Client>` |
|
||||
| `findByType(TypeClient type)` | Filtre par type | `List<Client>` |
|
||||
| `findActifs()` | Clients actifs uniquement | `List<Client>` |
|
||||
| `getStatistics()` | Statistiques globales | `Object` |
|
||||
|
||||
---
|
||||
|
||||
## 🔐 Permissions requises
|
||||
|
||||
| Permission | Description | Rôles autorisés |
|
||||
|------------|-------------|-----------------|
|
||||
| `CLIENTS_READ` | Lecture des clients | ADMIN, MANAGER, CHEF_CHANTIER, COMPTABLE |
|
||||
| `CLIENTS_CREATE` | Création de clients | ADMIN, MANAGER |
|
||||
| `CLIENTS_UPDATE` | Modification de clients | ADMIN, MANAGER |
|
||||
| `CLIENTS_DELETE` | Suppression de clients | ADMIN, MANAGER |
|
||||
| `CLIENTS_ASSIGN` | Assignation à des chantiers | ADMIN, MANAGER |
|
||||
|
||||
---
|
||||
|
||||
## 📈 Relations avec autres concepts
|
||||
|
||||
### **Dépendances directes**:
|
||||
- **CHANTIER** ➡️ Un client peut avoir plusieurs chantiers
|
||||
- **DEVIS** ➡️ Un client peut avoir plusieurs devis
|
||||
- **FACTURE** ➡️ Un client peut avoir plusieurs factures (via chantiers)
|
||||
|
||||
### **Utilisé par**:
|
||||
- **CHANTIER** - Chaque chantier appartient à un client
|
||||
- **DEVIS** - Chaque devis est lié à un client
|
||||
- **FACTURE** - Chaque facture est adressée à un client
|
||||
|
||||
---
|
||||
|
||||
## ✅ Validations
|
||||
|
||||
### **Validations automatiques**:
|
||||
- ✅ **Nom** : Obligatoire, max 100 caractères
|
||||
- ✅ **Prénom** : Obligatoire, max 100 caractères
|
||||
- ✅ **Email** : Format email valide, unique
|
||||
- ✅ **Téléphone** : Format français valide (regex)
|
||||
- ✅ **SIRET** : 14 caractères (si renseigné)
|
||||
- ✅ **Type** : PARTICULIER ou PROFESSIONNEL
|
||||
|
||||
### **Règles métier**:
|
||||
- Un client professionnel devrait avoir un SIRET et/ou numéro TVA
|
||||
- Un client particulier n'a généralement pas d'entreprise
|
||||
- L'email doit être unique dans le système
|
||||
- Le téléphone doit respecter le format français
|
||||
|
||||
---
|
||||
|
||||
## 🧪 Tests
|
||||
|
||||
### **Tests unitaires**
|
||||
- Fichier: `ClientServiceTest.java`
|
||||
- Couverture: Logique métier, validations, recherche
|
||||
|
||||
### **Tests d'intégration**
|
||||
- Fichier: `ClientResourceTest.java`
|
||||
- Couverture: Endpoints REST, sérialisation JSON
|
||||
|
||||
### **Commande pour exécuter les tests**:
|
||||
```bash
|
||||
cd btpxpress-server
|
||||
./mvnw test -Dtest=ClientServiceTest
|
||||
./mvnw test -Dtest=ClientResourceTest
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📚 Références
|
||||
|
||||
- [API Documentation complète](../API.md#clients)
|
||||
- [Schéma de base de données](../DATABASE.md#table-clients)
|
||||
- [Guide d'architecture](../architecture/domain-model.md#client)
|
||||
- [Service ClientService](../../src/main/java/dev/lions/btpxpress/application/service/ClientService.java)
|
||||
- [Resource ClientResource](../../src/main/java/dev/lions/btpxpress/adapter/http/ClientResource.java)
|
||||
|
||||
---
|
||||
|
||||
**Dernière mise à jour**: 2025-09-30
|
||||
**Version**: 1.0
|
||||
**Auteur**: Documentation BTPXpress
|
||||
|
||||
417
docs/concepts/03-MATERIEL.md
Normal file
417
docs/concepts/03-MATERIEL.md
Normal file
@@ -0,0 +1,417 @@
|
||||
# 🔧 CONCEPT: MATERIEL
|
||||
|
||||
## 📌 Vue d'ensemble
|
||||
|
||||
Le concept **MATERIEL** gère l'ensemble des équipements, outils, véhicules et matériaux de l'entreprise BTP. Il inclut la gestion du stock, de la maintenance, des réservations, et des caractéristiques techniques ultra-détaillées.
|
||||
|
||||
**Importance**: ⭐⭐⭐⭐⭐ (Concept stratégique)
|
||||
|
||||
---
|
||||
|
||||
## 🗂️ Fichiers concernés
|
||||
|
||||
### **Entités JPA** (`domain/core/entity/`)
|
||||
| Fichier | Description | Lignes |
|
||||
|---------|-------------|--------|
|
||||
| `Materiel.java` | Entité principale du matériel | 226 |
|
||||
| `MaterielBTP.java` | Matériel BTP ultra-détaillé (spécifications techniques) | ~300 |
|
||||
| `StatutMateriel.java` | Enum statuts (DISPONIBLE, UTILISE, MAINTENANCE, etc.) | 15 |
|
||||
| `TypeMateriel.java` | Enum types (VEHICULE, OUTIL_ELECTRIQUE, etc.) | 20 |
|
||||
| `ProprieteMateriel.java` | Enum propriété (PROPRE, LOUE, SOUS_TRAITANCE) | ~25 |
|
||||
| `MarqueMateriel.java` | Entité marque de matériel | ~80 |
|
||||
| `CompetenceMateriel.java` | Compétences requises pour utiliser le matériel | ~60 |
|
||||
| `OutillageMateriel.java` | Outillage associé au matériel | ~70 |
|
||||
| `TestQualiteMateriel.java` | Tests qualité du matériel | ~90 |
|
||||
| `DimensionsTechniques.java` | Dimensions techniques détaillées | ~100 |
|
||||
| `AdaptationClimatique.java` | Adaptation aux zones climatiques | ~80 |
|
||||
| `ContrainteConstruction.java` | Contraintes de construction | ~70 |
|
||||
|
||||
### **Services** (`application/service/`)
|
||||
| Fichier | Description |
|
||||
|---------|-------------|
|
||||
| `MaterielService.java` | Service métier principal |
|
||||
| `MaterielFournisseurService.java` | Gestion relation matériel-fournisseur |
|
||||
|
||||
### **Resources (API REST)** (`adapter/http/`)
|
||||
| Fichier | Description |
|
||||
|---------|-------------|
|
||||
| `MaterielResource.java` | Endpoints REST pour le matériel |
|
||||
|
||||
---
|
||||
|
||||
## 📊 Modèle de données
|
||||
|
||||
### **Entité Materiel**
|
||||
|
||||
<augment_code_snippet path="btpxpress-server/src/main/java/dev/lions/btpxpress/domain/core/entity/Materiel.java" mode="EXCERPT">
|
||||
````java
|
||||
@Entity
|
||||
@Table(name = "materiels")
|
||||
@Data
|
||||
@Builder
|
||||
public class Materiel extends PanacheEntityBase {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.UUID)
|
||||
private UUID id;
|
||||
|
||||
@NotBlank(message = "Le nom du matériel est obligatoire")
|
||||
@Column(name = "nom", nullable = false, length = 100)
|
||||
private String nom;
|
||||
|
||||
@Column(name = "marque", length = 100)
|
||||
private String marque;
|
||||
|
||||
@Column(name = "modele", length = 100)
|
||||
private String modele;
|
||||
|
||||
@Column(name = "numero_serie", unique = true, length = 100)
|
||||
private String numeroSerie;
|
||||
|
||||
@NotNull
|
||||
@Enumerated(EnumType.STRING)
|
||||
@Column(name = "type", nullable = false)
|
||||
private TypeMateriel type;
|
||||
|
||||
@Enumerated(EnumType.STRING)
|
||||
@Column(name = "statut", nullable = false)
|
||||
private StatutMateriel statut = StatutMateriel.DISPONIBLE;
|
||||
|
||||
@Column(name = "quantite_stock", precision = 10, scale = 3)
|
||||
private BigDecimal quantiteStock = BigDecimal.ZERO;
|
||||
|
||||
@Column(name = "seuil_minimum", precision = 10, scale = 3)
|
||||
private BigDecimal seuilMinimum = BigDecimal.ZERO;
|
||||
|
||||
// Relations
|
||||
@OneToMany(mappedBy = "materiel", cascade = CascadeType.ALL)
|
||||
private List<MaintenanceMateriel> maintenances;
|
||||
|
||||
@ManyToMany(mappedBy = "materiels")
|
||||
private List<PlanningEvent> planningEvents;
|
||||
}
|
||||
````
|
||||
</augment_code_snippet>
|
||||
|
||||
### **Enum StatutMateriel**
|
||||
|
||||
<augment_code_snippet path="btpxpress-server/src/main/java/dev/lions/btpxpress/domain/core/entity/StatutMateriel.java" mode="EXCERPT">
|
||||
````java
|
||||
public enum StatutMateriel {
|
||||
DISPONIBLE, // Disponible pour utilisation
|
||||
UTILISE, // Actuellement utilisé
|
||||
MAINTENANCE, // En maintenance préventive
|
||||
HORS_SERVICE, // Hors service (panne)
|
||||
RESERVE, // Réservé pour un chantier
|
||||
EN_REPARATION // En cours de réparation
|
||||
}
|
||||
````
|
||||
</augment_code_snippet>
|
||||
|
||||
### **Enum TypeMateriel**
|
||||
|
||||
<augment_code_snippet path="btpxpress-server/src/main/java/dev/lions/btpxpress/domain/core/entity/TypeMateriel.java" mode="EXCERPT">
|
||||
````java
|
||||
public enum TypeMateriel {
|
||||
VEHICULE, // Véhicules (camions, fourgons)
|
||||
OUTIL_ELECTRIQUE, // Outils électriques (perceuse, scie)
|
||||
OUTIL_MANUEL, // Outils manuels (marteau, pelle)
|
||||
ECHAFAUDAGE, // Échafaudages
|
||||
BETONIERE, // Bétonnières
|
||||
GRUE, // Grues
|
||||
COMPRESSEUR, // Compresseurs
|
||||
GENERATEUR, // Générateurs électriques
|
||||
ENGIN_CHANTIER, // Engins de chantier (pelleteuse, bulldozer)
|
||||
MATERIEL_MESURE, // Matériel de mesure (niveau laser, théodolite)
|
||||
EQUIPEMENT_SECURITE, // Équipements de sécurité (casques, harnais)
|
||||
OUTILLAGE, // Outillage général
|
||||
MATERIAUX_CONSTRUCTION, // Matériaux de construction
|
||||
AUTRE // Autre type
|
||||
}
|
||||
````
|
||||
</augment_code_snippet>
|
||||
|
||||
### **Champs principaux**
|
||||
|
||||
| Champ | Type | Obligatoire | Description |
|
||||
|-------|------|-------------|-------------|
|
||||
| `id` | UUID | Oui | Identifiant unique |
|
||||
| `nom` | String(100) | Oui | Nom du matériel |
|
||||
| `marque` | String(100) | Non | Marque du matériel |
|
||||
| `modele` | String(100) | Non | Modèle |
|
||||
| `numeroSerie` | String(100) | Non | Numéro de série (unique) |
|
||||
| `type` | TypeMateriel | Oui | Type de matériel |
|
||||
| `description` | String(1000) | Non | Description détaillée |
|
||||
| `dateAchat` | LocalDate | Non | Date d'achat |
|
||||
| `valeurAchat` | BigDecimal | Non | Valeur d'achat |
|
||||
| `valeurActuelle` | BigDecimal | Non | Valeur actuelle (amortissement) |
|
||||
| `statut` | StatutMateriel | Oui | Statut actuel (défaut: DISPONIBLE) |
|
||||
| `localisation` | String(200) | Non | Localisation actuelle |
|
||||
| `proprietaire` | String(200) | Non | Propriétaire (si location) |
|
||||
| `coutUtilisation` | BigDecimal | Non | Coût d'utilisation (par heure/jour) |
|
||||
| `quantiteStock` | BigDecimal | Oui | Quantité en stock (défaut: 0) |
|
||||
| `seuilMinimum` | BigDecimal | Oui | Seuil minimum de stock (défaut: 0) |
|
||||
| `unite` | String(20) | Non | Unité de mesure (pièce, kg, m, etc.) |
|
||||
| `actif` | Boolean | Oui | Matériel actif (défaut: true) |
|
||||
| `dateCreation` | LocalDateTime | Auto | Date de création |
|
||||
| `dateModification` | LocalDateTime | Auto | Date de modification |
|
||||
|
||||
### **Relations**
|
||||
|
||||
| Relation | Type | Entité cible | Description |
|
||||
|----------|------|--------------|-------------|
|
||||
| `maintenances` | OneToMany | MaintenanceMateriel | Historique des maintenances |
|
||||
| `planningEvents` | ManyToMany | PlanningEvent | Événements de planning |
|
||||
| `catalogueEntrees` | OneToMany | CatalogueFournisseur | Offres fournisseurs |
|
||||
| `reservations` | OneToMany | ReservationMateriel | Réservations |
|
||||
|
||||
---
|
||||
|
||||
## 🔌 API REST
|
||||
|
||||
### **Base URL**: `/api/v1/materiels`
|
||||
|
||||
### **Endpoints disponibles**
|
||||
|
||||
| Méthode | Endpoint | Description | Permission |
|
||||
|---------|----------|-------------|------------|
|
||||
| GET | `/api/v1/materiels` | Liste tous les matériels | MATERIELS_READ |
|
||||
| GET | `/api/v1/materiels/{id}` | Détails d'un matériel | MATERIELS_READ |
|
||||
| POST | `/api/v1/materiels` | Créer un matériel | MATERIELS_CREATE |
|
||||
| PUT | `/api/v1/materiels/{id}` | Modifier un matériel | MATERIELS_UPDATE |
|
||||
| DELETE | `/api/v1/materiels/{id}` | Supprimer un matériel | MATERIELS_DELETE |
|
||||
| GET | `/api/v1/materiels/disponibles` | Matériels disponibles | MATERIELS_READ |
|
||||
| GET | `/api/v1/materiels/type/{type}` | Matériels par type | MATERIELS_READ |
|
||||
| GET | `/api/v1/materiels/stock-faible` | Matériels en stock faible | MATERIELS_READ |
|
||||
| GET | `/api/v1/materiels/stats` | Statistiques matériel | MATERIELS_READ |
|
||||
|
||||
---
|
||||
|
||||
## 💻 Exemples d'utilisation
|
||||
|
||||
### **1. Récupérer tous les matériels**
|
||||
|
||||
```bash
|
||||
curl -X GET http://localhost:8080/api/v1/materiels \
|
||||
-H "Accept: application/json"
|
||||
```
|
||||
|
||||
**Réponse** (200 OK):
|
||||
```json
|
||||
[
|
||||
{
|
||||
"id": "550e8400-e29b-41d4-a716-446655440000",
|
||||
"nom": "Perceuse sans fil Makita",
|
||||
"marque": "Makita",
|
||||
"modele": "DHP484",
|
||||
"numeroSerie": "MAK-2025-001",
|
||||
"type": "OUTIL_ELECTRIQUE",
|
||||
"statut": "DISPONIBLE",
|
||||
"quantiteStock": 5,
|
||||
"seuilMinimum": 2,
|
||||
"unite": "pièce",
|
||||
"valeurAchat": 250.00,
|
||||
"valeurActuelle": 200.00,
|
||||
"actif": true
|
||||
},
|
||||
{
|
||||
"id": "660e8400-e29b-41d4-a716-446655440001",
|
||||
"nom": "Camion benne Renault",
|
||||
"marque": "Renault",
|
||||
"modele": "Master",
|
||||
"numeroSerie": "REN-2024-042",
|
||||
"type": "VEHICULE",
|
||||
"statut": "UTILISE",
|
||||
"quantiteStock": 1,
|
||||
"coutUtilisation": 150.00,
|
||||
"localisation": "Chantier Villa Moderne",
|
||||
"actif": true
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
### **2. Créer un nouveau matériel**
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:8080/api/v1/materiels \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"nom": "Bétonnière électrique",
|
||||
"marque": "Altrad",
|
||||
"modele": "B180",
|
||||
"type": "BETONIERE",
|
||||
"description": "Bétonnière électrique 180L",
|
||||
"dateAchat": "2025-09-15",
|
||||
"valeurAchat": 450.00,
|
||||
"quantiteStock": 2,
|
||||
"seuilMinimum": 1,
|
||||
"unite": "pièce",
|
||||
"statut": "DISPONIBLE"
|
||||
}'
|
||||
```
|
||||
|
||||
**Réponse** (201 Created):
|
||||
```json
|
||||
{
|
||||
"id": "generated-uuid",
|
||||
"nom": "Bétonnière électrique",
|
||||
"type": "BETONIERE",
|
||||
"statut": "DISPONIBLE",
|
||||
"quantiteStock": 2,
|
||||
"dateCreation": "2025-09-30T15:10:00"
|
||||
}
|
||||
```
|
||||
|
||||
### **3. Rechercher matériels disponibles**
|
||||
|
||||
```bash
|
||||
curl -X GET http://localhost:8080/api/v1/materiels/disponibles
|
||||
```
|
||||
|
||||
### **4. Matériels en stock faible**
|
||||
|
||||
```bash
|
||||
curl -X GET http://localhost:8080/api/v1/materiels/stock-faible
|
||||
```
|
||||
|
||||
**Réponse**:
|
||||
```json
|
||||
[
|
||||
{
|
||||
"id": "uuid",
|
||||
"nom": "Casques de sécurité",
|
||||
"quantiteStock": 3,
|
||||
"seuilMinimum": 10,
|
||||
"unite": "pièce",
|
||||
"alerte": "STOCK_CRITIQUE"
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
### **5. Statistiques matériel**
|
||||
|
||||
```bash
|
||||
curl -X GET http://localhost:8080/api/v1/materiels/stats
|
||||
```
|
||||
|
||||
**Réponse**:
|
||||
```json
|
||||
{
|
||||
"totalMateriels": 245,
|
||||
"disponibles": 180,
|
||||
"utilises": 45,
|
||||
"enMaintenance": 12,
|
||||
"horsService": 8,
|
||||
"valeurTotale": 125000.00,
|
||||
"stockFaible": 15,
|
||||
"parType": {
|
||||
"OUTIL_ELECTRIQUE": 85,
|
||||
"VEHICULE": 12,
|
||||
"ENGIN_CHANTIER": 8,
|
||||
"ECHAFAUDAGE": 45
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔧 Services métier
|
||||
|
||||
### **MaterielService**
|
||||
|
||||
**Méthodes principales**:
|
||||
|
||||
| Méthode | Description | Retour |
|
||||
|---------|-------------|--------|
|
||||
| `findAll()` | Récupère tous les matériels | `List<Materiel>` |
|
||||
| `findById(UUID id)` | Récupère par ID | `Optional<Materiel>` |
|
||||
| `create(MaterielDTO dto)` | Crée un matériel | `Materiel` |
|
||||
| `update(UUID id, MaterielDTO dto)` | Met à jour | `Materiel` |
|
||||
| `delete(UUID id)` | Supprime (soft delete) | `void` |
|
||||
| `findDisponibles()` | Matériels disponibles | `List<Materiel>` |
|
||||
| `findByType(TypeMateriel type)` | Filtre par type | `List<Materiel>` |
|
||||
| `findStockFaible()` | Stock sous seuil minimum | `List<Materiel>` |
|
||||
| `changerStatut(UUID id, StatutMateriel statut)` | Change le statut | `Materiel` |
|
||||
| `ajusterStock(UUID id, BigDecimal quantite)` | Ajuste le stock | `Materiel` |
|
||||
| `getStatistics()` | Statistiques globales | `Object` |
|
||||
|
||||
---
|
||||
|
||||
## 🔐 Permissions requises
|
||||
|
||||
| Permission | Description | Rôles autorisés |
|
||||
|------------|-------------|-----------------|
|
||||
| `MATERIELS_READ` | Lecture du matériel | ADMIN, MANAGER, CHEF_CHANTIER, OUVRIER |
|
||||
| `MATERIELS_CREATE` | Création de matériel | ADMIN, MANAGER |
|
||||
| `MATERIELS_UPDATE` | Modification de matériel | ADMIN, MANAGER, CHEF_CHANTIER |
|
||||
| `MATERIELS_DELETE` | Suppression de matériel | ADMIN, MANAGER |
|
||||
| `MATERIELS_STOCK` | Gestion du stock | ADMIN, MANAGER, CHEF_CHANTIER |
|
||||
|
||||
---
|
||||
|
||||
## 📈 Relations avec autres concepts
|
||||
|
||||
### **Dépendances directes**:
|
||||
- **MAINTENANCE** ➡️ Un matériel a un historique de maintenances
|
||||
- **RESERVATION_MATERIEL** ➡️ Un matériel peut être réservé
|
||||
- **PLANNING** ➡️ Un matériel apparaît dans le planning
|
||||
- **FOURNISSEUR** ➡️ Un matériel peut avoir plusieurs fournisseurs (catalogue)
|
||||
- **LIVRAISON** ➡️ Un matériel peut être livré
|
||||
|
||||
### **Utilisé par**:
|
||||
- **CHANTIER** - Matériel affecté aux chantiers
|
||||
- **EMPLOYE** - Matériel utilisé par les employés
|
||||
- **BON_COMMANDE** - Matériel commandé
|
||||
|
||||
---
|
||||
|
||||
## ✅ Validations
|
||||
|
||||
### **Validations automatiques**:
|
||||
- ✅ **Nom** : Obligatoire, max 100 caractères
|
||||
- ✅ **Type** : Obligatoire, valeur de l'enum TypeMateriel
|
||||
- ✅ **Numéro de série** : Unique si renseigné
|
||||
- ✅ **Quantité stock** : Nombre positif ou zéro
|
||||
- ✅ **Seuil minimum** : Nombre positif ou zéro
|
||||
|
||||
### **Règles métier**:
|
||||
- Le stock ne peut pas être négatif
|
||||
- Alerte si quantiteStock < seuilMinimum
|
||||
- Un matériel HORS_SERVICE ne peut pas être réservé
|
||||
- Un matériel en MAINTENANCE ne peut pas être utilisé
|
||||
|
||||
---
|
||||
|
||||
## 🧪 Tests
|
||||
|
||||
### **Tests unitaires**
|
||||
- Fichier: `MaterielServiceTest.java`
|
||||
- Couverture: Logique métier, gestion stock, validations
|
||||
|
||||
### **Tests d'intégration**
|
||||
- Fichier: `MaterielResourceTest.java`
|
||||
- Couverture: Endpoints REST, sérialisation JSON
|
||||
|
||||
### **Commande pour exécuter les tests**:
|
||||
```bash
|
||||
cd btpxpress-server
|
||||
./mvnw test -Dtest=MaterielServiceTest
|
||||
./mvnw test -Dtest=MaterielResourceTest
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📚 Références
|
||||
|
||||
- [API Documentation complète](../API.md#materiels)
|
||||
- [Schéma de base de données](../DATABASE.md#table-materiels)
|
||||
- [Concept MAINTENANCE](./12-MAINTENANCE.md)
|
||||
- [Concept RESERVATION_MATERIEL](./04-RESERVATION_MATERIEL.md)
|
||||
- [Service MaterielService](../../src/main/java/dev/lions/btpxpress/application/service/MaterielService.java)
|
||||
|
||||
---
|
||||
|
||||
**Dernière mise à jour**: 2025-09-30
|
||||
**Version**: 1.0
|
||||
**Auteur**: Documentation BTPXpress
|
||||
|
||||
186
docs/concepts/04-RESERVATION_MATERIEL.md
Normal file
186
docs/concepts/04-RESERVATION_MATERIEL.md
Normal file
@@ -0,0 +1,186 @@
|
||||
# 📅 CONCEPT: RESERVATION_MATERIEL
|
||||
|
||||
## 📌 Vue d'ensemble
|
||||
|
||||
Le concept **RESERVATION_MATERIEL** gère les réservations et affectations de matériel aux chantiers. Il permet de planifier l'utilisation du matériel, éviter les conflits, et optimiser l'allocation des ressources.
|
||||
|
||||
**Importance**: ⭐⭐⭐ (Concept important)
|
||||
|
||||
---
|
||||
|
||||
## 🗂️ Fichiers concernés
|
||||
|
||||
### **Entités JPA** (`domain/core/entity/`)
|
||||
| Fichier | Description | Lignes |
|
||||
|---------|-------------|--------|
|
||||
| `ReservationMateriel.java` | Entité principale de réservation | ~180 |
|
||||
| `StatutReservationMateriel.java` | Enum statuts (PLANIFIEE, VALIDEE, EN_COURS, TERMINEE, REFUSEE, ANNULEE) | ~20 |
|
||||
| `PrioriteReservation.java` | Enum priorités de réservation | ~25 |
|
||||
| `PlanningMateriel.java` | Planning d'utilisation du matériel | ~200 |
|
||||
| `StatutPlanning.java` | Enum statuts de planning | ~30 |
|
||||
| `TypePlanning.java` | Enum types de planning | ~25 |
|
||||
|
||||
### **Services** (`application/service/`)
|
||||
| Fichier | Description |
|
||||
|---------|-------------|
|
||||
| `ReservationMaterielService.java` | Service métier pour les réservations |
|
||||
| `PlanningMaterielService.java` | Service de gestion du planning matériel |
|
||||
|
||||
---
|
||||
|
||||
## 📊 Modèle de données
|
||||
|
||||
### **Entité ReservationMateriel**
|
||||
|
||||
```java
|
||||
@Entity
|
||||
@Table(name = "reservations_materiel")
|
||||
public class ReservationMateriel extends PanacheEntityBase {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.UUID)
|
||||
private UUID id;
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "materiel_id", nullable = false)
|
||||
private Materiel materiel;
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "chantier_id", nullable = false)
|
||||
private Chantier chantier;
|
||||
|
||||
@Column(name = "date_debut", nullable = false)
|
||||
private LocalDate dateDebut;
|
||||
|
||||
@Column(name = "date_fin", nullable = false)
|
||||
private LocalDate dateFin;
|
||||
|
||||
@Enumerated(EnumType.STRING)
|
||||
@Column(name = "statut", nullable = false)
|
||||
private StatutReservationMateriel statut = StatutReservationMateriel.PLANIFIEE;
|
||||
|
||||
@Column(name = "quantite", precision = 10, scale = 3)
|
||||
private BigDecimal quantite;
|
||||
|
||||
@Enumerated(EnumType.STRING)
|
||||
@Column(name = "priorite")
|
||||
private PrioriteReservation priorite;
|
||||
}
|
||||
```
|
||||
|
||||
### **Enum StatutReservationMateriel**
|
||||
|
||||
```java
|
||||
public enum StatutReservationMateriel {
|
||||
PLANIFIEE, // Réservation planifiée
|
||||
VALIDEE, // Réservation validée
|
||||
EN_COURS, // Réservation en cours d'utilisation
|
||||
TERMINEE, // Réservation terminée
|
||||
REFUSEE, // Réservation refusée
|
||||
ANNULEE // Réservation annulée
|
||||
}
|
||||
```
|
||||
|
||||
### **Champs principaux**
|
||||
|
||||
| Champ | Type | Obligatoire | Description |
|
||||
|-------|------|-------------|-------------|
|
||||
| `id` | UUID | Oui | Identifiant unique |
|
||||
| `materiel` | Materiel | Oui | Matériel réservé |
|
||||
| `chantier` | Chantier | Oui | Chantier destinataire |
|
||||
| `dateDebut` | LocalDate | Oui | Date de début de réservation |
|
||||
| `dateFin` | LocalDate | Oui | Date de fin de réservation |
|
||||
| `statut` | StatutReservationMateriel | Oui | Statut actuel |
|
||||
| `quantite` | BigDecimal | Non | Quantité réservée |
|
||||
| `priorite` | PrioriteReservation | Non | Priorité de la réservation |
|
||||
| `commentaire` | String | Non | Commentaire |
|
||||
|
||||
---
|
||||
|
||||
## 🔌 API REST
|
||||
|
||||
### **Base URL**: `/api/v1/reservations-materiel`
|
||||
|
||||
### **Endpoints disponibles**
|
||||
|
||||
| Méthode | Endpoint | Description |
|
||||
|---------|----------|-------------|
|
||||
| GET | `/api/v1/reservations-materiel` | Liste toutes les réservations |
|
||||
| GET | `/api/v1/reservations-materiel/{id}` | Détails d'une réservation |
|
||||
| POST | `/api/v1/reservations-materiel` | Créer une réservation |
|
||||
| PUT | `/api/v1/reservations-materiel/{id}` | Modifier une réservation |
|
||||
| DELETE | `/api/v1/reservations-materiel/{id}` | Annuler une réservation |
|
||||
| GET | `/api/v1/reservations-materiel/materiel/{id}` | Réservations d'un matériel |
|
||||
| GET | `/api/v1/reservations-materiel/chantier/{id}` | Réservations d'un chantier |
|
||||
| GET | `/api/v1/reservations-materiel/conflits` | Détecter les conflits |
|
||||
|
||||
---
|
||||
|
||||
## 💻 Exemples d'utilisation
|
||||
|
||||
### **1. Créer une réservation**
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:8080/api/v1/reservations-materiel \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"materielId": "materiel-uuid",
|
||||
"chantierId": "chantier-uuid",
|
||||
"dateDebut": "2025-10-01",
|
||||
"dateFin": "2025-10-15",
|
||||
"quantite": 2,
|
||||
"priorite": "NORMALE"
|
||||
}'
|
||||
```
|
||||
|
||||
### **2. Vérifier les conflits**
|
||||
|
||||
```bash
|
||||
curl -X GET "http://localhost:8080/api/v1/reservations-materiel/conflits?materielId=uuid&dateDebut=2025-10-01&dateFin=2025-10-15"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔧 Services métier
|
||||
|
||||
### **ReservationMaterielService**
|
||||
|
||||
**Méthodes principales**:
|
||||
- `create(ReservationDTO dto)` - Créer une réservation
|
||||
- `verifierDisponibilite(UUID materielId, LocalDate debut, LocalDate fin)` - Vérifier disponibilité
|
||||
- `detecterConflits(UUID materielId, LocalDate debut, LocalDate fin)` - Détecter conflits
|
||||
- `valider(UUID id)` - Valider une réservation
|
||||
- `annuler(UUID id)` - Annuler une réservation
|
||||
|
||||
---
|
||||
|
||||
## 📈 Relations avec autres concepts
|
||||
|
||||
- **MATERIEL** ⬅️ Une réservation concerne un matériel
|
||||
- **CHANTIER** ⬅️ Une réservation est liée à un chantier
|
||||
- **PLANNING** ➡️ Les réservations alimentent le planning
|
||||
- **LIVRAISON** ➡️ Une réservation peut générer une livraison
|
||||
|
||||
---
|
||||
|
||||
## ✅ Validations
|
||||
|
||||
- ✅ Date de fin doit être après date de début
|
||||
- ✅ Le matériel doit être disponible
|
||||
- ✅ Pas de conflit avec d'autres réservations
|
||||
- ✅ Quantité disponible suffisante
|
||||
|
||||
---
|
||||
|
||||
## 📚 Références
|
||||
|
||||
- [Concept MATERIEL](./03-MATERIEL.md)
|
||||
- [Concept CHANTIER](./01-CHANTIER.md)
|
||||
- [Concept PLANNING](./13-PLANNING.md)
|
||||
|
||||
---
|
||||
|
||||
**Dernière mise à jour**: 2025-09-30
|
||||
**Version**: 1.0
|
||||
**Auteur**: Documentation BTPXpress
|
||||
|
||||
213
docs/concepts/05-LIVRAISON.md
Normal file
213
docs/concepts/05-LIVRAISON.md
Normal file
@@ -0,0 +1,213 @@
|
||||
# 🚚 CONCEPT: LIVRAISON
|
||||
|
||||
## 📌 Vue d'ensemble
|
||||
|
||||
Le concept **LIVRAISON** gère la logistique et le suivi des livraisons de matériel sur les chantiers. Il couvre le transport, le suivi en temps réel, et la gestion des transporteurs.
|
||||
|
||||
**Importance**: ⭐⭐⭐ (Concept important)
|
||||
|
||||
---
|
||||
|
||||
## 🗂️ Fichiers concernés
|
||||
|
||||
### **Entités JPA** (`domain/core/entity/`)
|
||||
| Fichier | Description | Lignes |
|
||||
|---------|-------------|--------|
|
||||
| `LivraisonMateriel.java` | Entité principale de livraison | ~200 |
|
||||
| `StatutLivraison.java` | Enum statuts (PLANIFIEE, EN_PREPARATION, EN_TRANSIT, LIVREE, ANNULEE, RETARDEE) | ~30 |
|
||||
| `ModeLivraison.java` | Enum modes de livraison | ~25 |
|
||||
| `TypeTransport.java` | Enum types de transport | ~20 |
|
||||
|
||||
### **Services** (`application/service/`)
|
||||
| Fichier | Description |
|
||||
|---------|-------------|
|
||||
| `LivraisonMaterielService.java` | Service métier pour les livraisons |
|
||||
|
||||
---
|
||||
|
||||
## 📊 Modèle de données
|
||||
|
||||
### **Entité LivraisonMateriel**
|
||||
|
||||
```java
|
||||
@Entity
|
||||
@Table(name = "livraisons_materiel")
|
||||
public class LivraisonMateriel extends PanacheEntityBase {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.UUID)
|
||||
private UUID id;
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "reservation_id")
|
||||
private ReservationMateriel reservation;
|
||||
|
||||
@Column(name = "date_livraison_prevue", nullable = false)
|
||||
private LocalDateTime dateLivraisonPrevue;
|
||||
|
||||
@Column(name = "date_livraison_reelle")
|
||||
private LocalDateTime dateLivraisonReelle;
|
||||
|
||||
@Enumerated(EnumType.STRING)
|
||||
@Column(name = "statut", nullable = false)
|
||||
private StatutLivraison statut = StatutLivraison.PLANIFIEE;
|
||||
|
||||
@Column(name = "transporteur", length = 200)
|
||||
private String transporteur;
|
||||
|
||||
@Column(name = "numero_suivi", length = 100)
|
||||
private String numeroSuivi;
|
||||
|
||||
@Enumerated(EnumType.STRING)
|
||||
@Column(name = "mode_livraison")
|
||||
private ModeLivraison modeLivraison;
|
||||
|
||||
@Column(name = "adresse_livraison", length = 500)
|
||||
private String adresseLivraison;
|
||||
|
||||
@Column(name = "cout_livraison", precision = 10, scale = 2)
|
||||
private BigDecimal coutLivraison;
|
||||
}
|
||||
```
|
||||
|
||||
### **Enum StatutLivraison**
|
||||
|
||||
```java
|
||||
public enum StatutLivraison {
|
||||
PLANIFIEE, // Livraison planifiée
|
||||
EN_PREPARATION, // En cours de préparation
|
||||
EN_TRANSIT, // En transit
|
||||
LIVREE, // Livrée avec succès
|
||||
ANNULEE, // Livraison annulée
|
||||
RETARDEE // Livraison retardée
|
||||
}
|
||||
```
|
||||
|
||||
### **Champs principaux**
|
||||
|
||||
| Champ | Type | Obligatoire | Description |
|
||||
|-------|------|-------------|-------------|
|
||||
| `id` | UUID | Oui | Identifiant unique |
|
||||
| `reservation` | ReservationMateriel | Non | Réservation associée |
|
||||
| `dateLivraisonPrevue` | LocalDateTime | Oui | Date/heure prévue |
|
||||
| `dateLivraisonReelle` | LocalDateTime | Non | Date/heure réelle |
|
||||
| `statut` | StatutLivraison | Oui | Statut actuel |
|
||||
| `transporteur` | String(200) | Non | Nom du transporteur |
|
||||
| `numeroSuivi` | String(100) | Non | Numéro de suivi |
|
||||
| `modeLivraison` | ModeLivraison | Non | Mode de livraison |
|
||||
| `adresseLivraison` | String(500) | Non | Adresse de livraison |
|
||||
| `coutLivraison` | BigDecimal | Non | Coût de la livraison |
|
||||
|
||||
---
|
||||
|
||||
## 🔌 API REST
|
||||
|
||||
### **Base URL**: `/api/v1/livraisons`
|
||||
|
||||
### **Endpoints disponibles**
|
||||
|
||||
| Méthode | Endpoint | Description |
|
||||
|---------|----------|-------------|
|
||||
| GET | `/api/v1/livraisons` | Liste toutes les livraisons |
|
||||
| GET | `/api/v1/livraisons/{id}` | Détails d'une livraison |
|
||||
| POST | `/api/v1/livraisons` | Créer une livraison |
|
||||
| PUT | `/api/v1/livraisons/{id}` | Modifier une livraison |
|
||||
| PUT | `/api/v1/livraisons/{id}/statut` | Changer le statut |
|
||||
| GET | `/api/v1/livraisons/en-cours` | Livraisons en cours |
|
||||
| GET | `/api/v1/livraisons/retardees` | Livraisons retardées |
|
||||
| GET | `/api/v1/livraisons/stats` | Statistiques livraisons |
|
||||
|
||||
---
|
||||
|
||||
## 💻 Exemples d'utilisation
|
||||
|
||||
### **1. Créer une livraison**
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:8080/api/v1/livraisons \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"reservationId": "reservation-uuid",
|
||||
"dateLivraisonPrevue": "2025-10-05T09:00:00",
|
||||
"transporteur": "Transport Express",
|
||||
"modeLivraison": "STANDARD",
|
||||
"adresseLivraison": "123 Rue du Chantier, 75001 Paris"
|
||||
}'
|
||||
```
|
||||
|
||||
### **2. Mettre à jour le statut**
|
||||
|
||||
```bash
|
||||
curl -X PUT http://localhost:8080/api/v1/livraisons/{id}/statut \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"statut": "EN_TRANSIT",
|
||||
"numeroSuivi": "TRACK123456"
|
||||
}'
|
||||
```
|
||||
|
||||
### **3. Livraisons en cours**
|
||||
|
||||
```bash
|
||||
curl -X GET http://localhost:8080/api/v1/livraisons/en-cours
|
||||
```
|
||||
|
||||
**Réponse**:
|
||||
```json
|
||||
[
|
||||
{
|
||||
"id": "uuid",
|
||||
"statut": "EN_TRANSIT",
|
||||
"transporteur": "Transport Express",
|
||||
"numeroSuivi": "TRACK123456",
|
||||
"dateLivraisonPrevue": "2025-10-05T09:00:00",
|
||||
"adresseLivraison": "123 Rue du Chantier"
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔧 Services métier
|
||||
|
||||
### **LivraisonMaterielService**
|
||||
|
||||
**Méthodes principales**:
|
||||
- `create(LivraisonDTO dto)` - Créer une livraison
|
||||
- `changerStatut(UUID id, StatutLivraison statut)` - Changer le statut
|
||||
- `findEnCours()` - Livraisons en cours
|
||||
- `findRetardees()` - Livraisons retardées
|
||||
- `calculerDelai(UUID id)` - Calculer le délai
|
||||
- `getStatistics()` - Statistiques
|
||||
|
||||
---
|
||||
|
||||
## 📈 Relations avec autres concepts
|
||||
|
||||
- **RESERVATION_MATERIEL** ⬅️ Une livraison peut être liée à une réservation
|
||||
- **CHANTIER** ⬅️ Une livraison est destinée à un chantier
|
||||
- **MATERIEL** ⬅️ Une livraison concerne du matériel
|
||||
|
||||
---
|
||||
|
||||
## ✅ Validations
|
||||
|
||||
- ✅ Date de livraison prévue obligatoire
|
||||
- ✅ Adresse de livraison valide
|
||||
- ✅ Statut cohérent avec les transitions
|
||||
- ✅ Coût de livraison positif
|
||||
|
||||
---
|
||||
|
||||
## 📚 Références
|
||||
|
||||
- [Concept RESERVATION_MATERIEL](./04-RESERVATION_MATERIEL.md)
|
||||
- [Concept MATERIEL](./03-MATERIEL.md)
|
||||
- [Concept CHANTIER](./01-CHANTIER.md)
|
||||
|
||||
---
|
||||
|
||||
**Dernière mise à jour**: 2025-09-30
|
||||
**Version**: 1.0
|
||||
**Auteur**: Documentation BTPXpress
|
||||
|
||||
254
docs/concepts/06-FOURNISSEUR.md
Normal file
254
docs/concepts/06-FOURNISSEUR.md
Normal file
@@ -0,0 +1,254 @@
|
||||
# 🏪 CONCEPT: FOURNISSEUR
|
||||
|
||||
## 📌 Vue d'ensemble
|
||||
|
||||
Le concept **FOURNISSEUR** gère les fournisseurs de matériel et services BTP. Il inclut le catalogue produits, les comparaisons de prix, et les conditions commerciales.
|
||||
|
||||
**Importance**: ⭐⭐⭐⭐ (Concept stratégique)
|
||||
|
||||
---
|
||||
|
||||
## 🗂️ Fichiers concernés
|
||||
|
||||
### **Entités JPA** (`domain/core/entity/`)
|
||||
| Fichier | Description | Lignes |
|
||||
|---------|-------------|--------|
|
||||
| `Fournisseur.java` | Entité principale fournisseur | ~150 |
|
||||
| `FournisseurMateriel.java` | Relation fournisseur-matériel | ~80 |
|
||||
| `CatalogueFournisseur.java` | Catalogue produits fournisseur | ~120 |
|
||||
| `ComparaisonFournisseur.java` | Comparaison entre fournisseurs | ~100 |
|
||||
| `StatutFournisseur.java` | Enum statuts (ACTIF, INACTIF, SUSPENDU, BLOQUE) | ~20 |
|
||||
| `SpecialiteFournisseur.java` | Enum spécialités (MATERIAUX_GROS_OEUVRE, etc.) | ~70 |
|
||||
| `ConditionsPaiement.java` | Enum conditions de paiement | ~40 |
|
||||
| `CritereComparaison.java` | Enum critères de comparaison | ~25 |
|
||||
|
||||
### **DTOs** (`domain/shared/dto/`)
|
||||
| Fichier | Description |
|
||||
|---------|-------------|
|
||||
| `FournisseurDTO.java` | DTO fournisseur avec enum TypeFournisseur |
|
||||
|
||||
### **Services** (`application/service/`)
|
||||
| Fichier | Description |
|
||||
|---------|-------------|
|
||||
| `FournisseurService.java` | Service métier fournisseurs |
|
||||
| `ComparaisonFournisseurService.java` | Service de comparaison |
|
||||
|
||||
---
|
||||
|
||||
## 📊 Modèle de données
|
||||
|
||||
### **Entité Fournisseur**
|
||||
|
||||
```java
|
||||
@Entity
|
||||
@Table(name = "fournisseurs")
|
||||
public class Fournisseur extends PanacheEntityBase {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
|
||||
@NotBlank
|
||||
@Column(name = "nom", nullable = false, length = 100)
|
||||
private String nom;
|
||||
|
||||
@Column(name = "siret", length = 20)
|
||||
private String siret;
|
||||
|
||||
@Column(name = "numero_tva", length = 15)
|
||||
private String numeroTva;
|
||||
|
||||
@Email
|
||||
@Column(name = "email", length = 100)
|
||||
private String email;
|
||||
|
||||
@Column(name = "telephone", length = 20)
|
||||
private String telephone;
|
||||
|
||||
@Column(name = "adresse", length = 200)
|
||||
private String adresse;
|
||||
|
||||
@Enumerated(EnumType.STRING)
|
||||
@Column(name = "statut")
|
||||
private StatutFournisseur statut = StatutFournisseur.ACTIF;
|
||||
|
||||
@ElementCollection
|
||||
@CollectionTable(name = "fournisseur_specialites")
|
||||
@Enumerated(EnumType.STRING)
|
||||
private List<SpecialiteFournisseur> specialites;
|
||||
|
||||
@Enumerated(EnumType.STRING)
|
||||
@Column(name = "conditions_paiement")
|
||||
private ConditionsPaiement conditionsPaiement;
|
||||
|
||||
@Column(name = "delai_paiement_jours")
|
||||
private Integer delaiPaiementJours;
|
||||
}
|
||||
```
|
||||
|
||||
### **Enum SpecialiteFournisseur**
|
||||
|
||||
```java
|
||||
public enum SpecialiteFournisseur {
|
||||
// Matériaux de construction
|
||||
MATERIAUX_GROS_OEUVRE("Matériaux gros œuvre", "Béton, ciment, parpaings"),
|
||||
MATERIAUX_CHARPENTE("Matériaux charpente", "Bois de charpente"),
|
||||
MATERIAUX_COUVERTURE("Matériaux couverture", "Tuiles, ardoises"),
|
||||
MATERIAUX_ISOLATION("Matériaux isolation", "Isolants thermiques"),
|
||||
|
||||
// Équipements techniques
|
||||
PLOMBERIE("Plomberie", "Tuyauterie, robinetterie"),
|
||||
ELECTRICITE("Électricité", "Câbles, tableaux électriques"),
|
||||
CHAUFFAGE("Chauffage", "Chaudières, radiateurs"),
|
||||
|
||||
// Équipements et outils
|
||||
LOCATION_MATERIEL("Location matériel", "Location engins et outils"),
|
||||
OUTILLAGE("Outillage", "Outils électriques et manuels"),
|
||||
|
||||
// Services
|
||||
TRANSPORT("Transport", "Transport de matériaux"),
|
||||
MULTI_SPECIALITES("Multi-spécialités", "Fournisseur généraliste"),
|
||||
AUTRE("Autre", "Autre spécialité")
|
||||
}
|
||||
```
|
||||
|
||||
### **Champs principaux**
|
||||
|
||||
| Champ | Type | Obligatoire | Description |
|
||||
|-------|------|-------------|-------------|
|
||||
| `id` | Long | Oui | Identifiant unique |
|
||||
| `nom` | String(100) | Oui | Nom du fournisseur |
|
||||
| `siret` | String(20) | Non | Numéro SIRET |
|
||||
| `numeroTva` | String(15) | Non | Numéro TVA |
|
||||
| `email` | String(100) | Non | Email de contact |
|
||||
| `telephone` | String(20) | Non | Téléphone |
|
||||
| `adresse` | String(200) | Non | Adresse |
|
||||
| `statut` | StatutFournisseur | Oui | Statut (défaut: ACTIF) |
|
||||
| `specialites` | List<SpecialiteFournisseur> | Non | Spécialités |
|
||||
| `conditionsPaiement` | ConditionsPaiement | Non | Conditions de paiement |
|
||||
| `delaiPaiementJours` | Integer | Non | Délai de paiement en jours |
|
||||
|
||||
---
|
||||
|
||||
## 🔌 API REST
|
||||
|
||||
### **Base URL**: `/api/v1/fournisseurs`
|
||||
|
||||
### **Endpoints disponibles**
|
||||
|
||||
| Méthode | Endpoint | Description |
|
||||
|---------|----------|-------------|
|
||||
| GET | `/api/v1/fournisseurs` | Liste tous les fournisseurs |
|
||||
| GET | `/api/v1/fournisseurs/{id}` | Détails d'un fournisseur |
|
||||
| POST | `/api/v1/fournisseurs` | Créer un fournisseur |
|
||||
| PUT | `/api/v1/fournisseurs/{id}` | Modifier un fournisseur |
|
||||
| DELETE | `/api/v1/fournisseurs/{id}` | Supprimer un fournisseur |
|
||||
| GET | `/api/v1/fournisseurs/specialite/{specialite}` | Par spécialité |
|
||||
| GET | `/api/v1/fournisseurs/comparer` | Comparer des fournisseurs |
|
||||
| GET | `/api/v1/fournisseurs/stats` | Statistiques |
|
||||
|
||||
---
|
||||
|
||||
## 💻 Exemples d'utilisation
|
||||
|
||||
### **1. Créer un fournisseur**
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:8080/api/v1/fournisseurs \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"nom": "Matériaux Pro",
|
||||
"siret": "12345678901234",
|
||||
"email": "contact@materiauxpro.fr",
|
||||
"telephone": "+33 1 23 45 67 89",
|
||||
"adresse": "10 Rue de l Industrie, 75001 Paris",
|
||||
"specialites": ["MATERIAUX_GROS_OEUVRE", "MATERIAUX_ISOLATION"],
|
||||
"conditionsPaiement": "NET_30",
|
||||
"delaiPaiementJours": 30
|
||||
}'
|
||||
```
|
||||
|
||||
### **2. Rechercher par spécialité**
|
||||
|
||||
```bash
|
||||
curl -X GET "http://localhost:8080/api/v1/fournisseurs/specialite/MATERIAUX_GROS_OEUVRE"
|
||||
```
|
||||
|
||||
### **3. Comparer des fournisseurs**
|
||||
|
||||
```bash
|
||||
curl -X GET "http://localhost:8080/api/v1/fournisseurs/comparer?materielId=uuid&fournisseurIds=id1,id2,id3"
|
||||
```
|
||||
|
||||
**Réponse**:
|
||||
```json
|
||||
{
|
||||
"materiel": "Ciment Portland 25kg",
|
||||
"comparaisons": [
|
||||
{
|
||||
"fournisseur": "Matériaux Pro",
|
||||
"prix": 8.50,
|
||||
"delaiLivraison": 2,
|
||||
"conditionsPaiement": "NET_30",
|
||||
"note": 4.5
|
||||
},
|
||||
{
|
||||
"fournisseur": "BTP Discount",
|
||||
"prix": 7.90,
|
||||
"delaiLivraison": 5,
|
||||
"conditionsPaiement": "NET_45",
|
||||
"note": 4.2
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔧 Services métier
|
||||
|
||||
### **FournisseurService**
|
||||
|
||||
**Méthodes principales**:
|
||||
- `findAll()` - Tous les fournisseurs
|
||||
- `findBySpecialite(SpecialiteFournisseur)` - Par spécialité
|
||||
- `findActifs()` - Fournisseurs actifs
|
||||
- `create(FournisseurDTO)` - Créer
|
||||
- `update(Long id, FournisseurDTO)` - Modifier
|
||||
|
||||
### **ComparaisonFournisseurService**
|
||||
|
||||
**Méthodes principales**:
|
||||
- `comparerPrix(UUID materielId, List<Long> fournisseurIds)` - Comparer prix
|
||||
- `getMeilleurFournisseur(UUID materielId, CritereComparaison)` - Meilleur fournisseur
|
||||
|
||||
---
|
||||
|
||||
## 📈 Relations avec autres concepts
|
||||
|
||||
- **MATERIEL** ➡️ Un fournisseur propose du matériel (catalogue)
|
||||
- **BON_COMMANDE** ➡️ Un fournisseur reçoit des bons de commande
|
||||
- **FACTURE** ➡️ Un fournisseur émet des factures
|
||||
|
||||
---
|
||||
|
||||
## ✅ Validations
|
||||
|
||||
- ✅ Nom obligatoire
|
||||
- ✅ Email au format valide
|
||||
- ✅ SIRET 14 caractères si renseigné
|
||||
- ✅ Au moins une spécialité
|
||||
|
||||
---
|
||||
|
||||
## 📚 Références
|
||||
|
||||
- [Concept MATERIEL](./03-MATERIEL.md)
|
||||
- [Concept BON_COMMANDE](./08-BON_COMMANDE.md)
|
||||
|
||||
---
|
||||
|
||||
**Dernière mise à jour**: 2025-09-30
|
||||
**Version**: 1.0
|
||||
**Auteur**: Documentation BTPXpress
|
||||
|
||||
182
docs/concepts/07-STOCK.md
Normal file
182
docs/concepts/07-STOCK.md
Normal file
@@ -0,0 +1,182 @@
|
||||
# 📦 CONCEPT: STOCK
|
||||
|
||||
## 📌 Vue d'ensemble
|
||||
|
||||
Le concept **STOCK** gère les stocks de matériaux et fournitures avec suivi des mouvements, alertes de rupture, et inventaires.
|
||||
|
||||
**Importance**: ⭐⭐⭐ (Concept important)
|
||||
|
||||
---
|
||||
|
||||
## 🗂️ Fichiers concernés
|
||||
|
||||
### **Entités JPA**
|
||||
| Fichier | Description |
|
||||
|---------|-------------|
|
||||
| `Stock.java` | Entité principale stock |
|
||||
| `CategorieStock.java` | Catégorie de stock |
|
||||
| `SousCategorieStock.java` | Sous-catégorie |
|
||||
| `StatutStock.java` | Enum (DISPONIBLE, RESERVE, RUPTURE, COMMANDE, PERIME) |
|
||||
| `UniteMesure.java` | Enum unités (UNITE, KG, M, L, etc.) |
|
||||
| `UnitePrix.java` | Enum unités de prix |
|
||||
|
||||
### **Services**
|
||||
| Fichier | Description |
|
||||
|---------|-------------|
|
||||
| `StockService.java` | Service métier stock |
|
||||
|
||||
---
|
||||
|
||||
## 📊 Modèle de données
|
||||
|
||||
```java
|
||||
@Entity
|
||||
@Table(name = "stocks")
|
||||
public class Stock extends PanacheEntityBase {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.UUID)
|
||||
private UUID id;
|
||||
|
||||
@Column(name = "designation", nullable = false)
|
||||
private String designation;
|
||||
|
||||
@Column(name = "reference", unique = true)
|
||||
private String reference;
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "categorie_id")
|
||||
private CategorieStock categorie;
|
||||
|
||||
@Column(name = "quantite", precision = 10, scale = 3)
|
||||
private BigDecimal quantite = BigDecimal.ZERO;
|
||||
|
||||
@Column(name = "seuil_alerte", precision = 10, scale = 3)
|
||||
private BigDecimal seuilAlerte;
|
||||
|
||||
@Enumerated(EnumType.STRING)
|
||||
@Column(name = "unite")
|
||||
private UniteMesure unite;
|
||||
|
||||
@Enumerated(EnumType.STRING)
|
||||
@Column(name = "statut")
|
||||
private StatutStock statut = StatutStock.DISPONIBLE;
|
||||
|
||||
@Column(name = "prix_unitaire", precision = 10, scale = 2)
|
||||
private BigDecimal prixUnitaire;
|
||||
}
|
||||
```
|
||||
|
||||
### **Enum UniteMesure**
|
||||
|
||||
```java
|
||||
public enum UniteMesure {
|
||||
UNITE, PAIRE, LOT, KIT, // Quantité
|
||||
GRAMME, KILOGRAMME, TONNE, // Poids
|
||||
MILLIMETRE, CENTIMETRE, METRE, // Longueur
|
||||
METRE_CARRE, METRE_CUBE, // Surface/Volume
|
||||
LITRE, MILLILITRE, // Volume liquide
|
||||
AUTRE
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔌 API REST
|
||||
|
||||
### **Endpoints**
|
||||
|
||||
| Méthode | Endpoint | Description |
|
||||
|---------|----------|-------------|
|
||||
| GET | `/api/v1/stocks` | Liste stocks |
|
||||
| GET | `/api/v1/stocks/{id}` | Détails stock |
|
||||
| POST | `/api/v1/stocks` | Créer stock |
|
||||
| PUT | `/api/v1/stocks/{id}` | Modifier stock |
|
||||
| POST | `/api/v1/stocks/{id}/mouvement` | Enregistrer mouvement |
|
||||
| GET | `/api/v1/stocks/alertes` | Stocks en alerte |
|
||||
| GET | `/api/v1/stocks/stats` | Statistiques |
|
||||
|
||||
---
|
||||
|
||||
## 💻 Exemples
|
||||
|
||||
### **Créer un article en stock**
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:8080/api/v1/stocks \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"designation": "Ciment Portland 25kg",
|
||||
"reference": "CIM-PORT-25",
|
||||
"categorieId": 1,
|
||||
"quantite": 100,
|
||||
"seuilAlerte": 20,
|
||||
"unite": "UNITE",
|
||||
"prixUnitaire": 8.50
|
||||
}'
|
||||
```
|
||||
|
||||
### **Enregistrer un mouvement**
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:8080/api/v1/stocks/{id}/mouvement \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"type": "SORTIE",
|
||||
"quantite": 10,
|
||||
"motif": "Chantier Villa Moderne",
|
||||
"chantierId": "uuid"
|
||||
}'
|
||||
```
|
||||
|
||||
### **Stocks en alerte**
|
||||
|
||||
```bash
|
||||
curl -X GET http://localhost:8080/api/v1/stocks/alertes
|
||||
```
|
||||
|
||||
**Réponse**:
|
||||
```json
|
||||
[
|
||||
{
|
||||
"id": "uuid",
|
||||
"designation": "Ciment Portland 25kg",
|
||||
"quantite": 15,
|
||||
"seuilAlerte": 20,
|
||||
"statut": "ALERTE_STOCK"
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔧 Services métier
|
||||
|
||||
**StockService - Méthodes**:
|
||||
- `findAll()` - Tous les stocks
|
||||
- `ajouterStock(UUID id, BigDecimal quantite)` - Ajouter
|
||||
- `retirerStock(UUID id, BigDecimal quantite)` - Retirer
|
||||
- `findAlertes()` - Stocks en alerte
|
||||
- `inventaire()` - Inventaire complet
|
||||
|
||||
---
|
||||
|
||||
## 📈 Relations
|
||||
|
||||
- **MATERIEL** ⬅️ Un stock peut être lié à du matériel
|
||||
- **BON_COMMANDE** ➡️ Commandes pour réapprovisionner
|
||||
- **CHANTIER** ➡️ Sorties de stock pour chantiers
|
||||
|
||||
---
|
||||
|
||||
## ✅ Validations
|
||||
|
||||
- ✅ Quantité ne peut pas être négative
|
||||
- ✅ Seuil d'alerte positif
|
||||
- ✅ Référence unique
|
||||
- ✅ Unité de mesure cohérente
|
||||
|
||||
---
|
||||
|
||||
**Dernière mise à jour**: 2025-09-30
|
||||
**Version**: 1.0
|
||||
|
||||
229
docs/concepts/08-BON_COMMANDE.md
Normal file
229
docs/concepts/08-BON_COMMANDE.md
Normal file
@@ -0,0 +1,229 @@
|
||||
# 📋 CONCEPT: BON_COMMANDE
|
||||
|
||||
## 📌 Vue d'ensemble
|
||||
|
||||
Le concept **BON_COMMANDE** gère les bons de commande auprès des fournisseurs pour l'achat de matériel, fournitures et services.
|
||||
|
||||
**Importance**: ⭐⭐⭐ (Concept important)
|
||||
|
||||
---
|
||||
|
||||
## 🗂️ Fichiers concernés
|
||||
|
||||
### **Entités JPA**
|
||||
| Fichier | Description |
|
||||
|---------|-------------|
|
||||
| `BonCommande.java` | Entité principale bon de commande |
|
||||
| `LigneBonCommande.java` | Ligne de bon de commande |
|
||||
| `StatutBonCommande.java` | Enum (BROUILLON, VALIDEE, ENVOYEE, CONFIRMEE, LIVREE, ANNULEE) |
|
||||
| `StatutLigneBonCommande.java` | Enum statuts ligne |
|
||||
| `TypeBonCommande.java` | Enum types (ACHAT, LOCATION, PRESTATIONS, etc.) |
|
||||
| `PrioriteBonCommande.java` | Enum priorités |
|
||||
|
||||
### **Services**
|
||||
| Fichier | Description |
|
||||
|---------|-------------|
|
||||
| `BonCommandeService.java` | Service métier |
|
||||
| `LigneBonCommandeService.java` | Service lignes |
|
||||
|
||||
---
|
||||
|
||||
## 📊 Modèle de données
|
||||
|
||||
```java
|
||||
@Entity
|
||||
@Table(name = "bons_commande")
|
||||
public class BonCommande extends PanacheEntityBase {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.UUID)
|
||||
private UUID id;
|
||||
|
||||
@Column(name = "numero", unique = true, nullable = false)
|
||||
private String numero;
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "fournisseur_id", nullable = false)
|
||||
private Fournisseur fournisseur;
|
||||
|
||||
@Column(name = "date_commande", nullable = false)
|
||||
private LocalDate dateCommande;
|
||||
|
||||
@Column(name = "date_livraison_souhaitee")
|
||||
private LocalDate dateLivraisonSouhaitee;
|
||||
|
||||
@Enumerated(EnumType.STRING)
|
||||
@Column(name = "statut", nullable = false)
|
||||
private StatutBonCommande statut = StatutBonCommande.BROUILLON;
|
||||
|
||||
@Enumerated(EnumType.STRING)
|
||||
@Column(name = "type")
|
||||
private TypeBonCommande type;
|
||||
|
||||
@OneToMany(mappedBy = "bonCommande", cascade = CascadeType.ALL)
|
||||
private List<LigneBonCommande> lignes;
|
||||
|
||||
@Column(name = "montant_total", precision = 10, scale = 2)
|
||||
private BigDecimal montantTotal = BigDecimal.ZERO;
|
||||
|
||||
@Column(name = "commentaire", length = 1000)
|
||||
private String commentaire;
|
||||
}
|
||||
```
|
||||
|
||||
### **Enum StatutBonCommande**
|
||||
|
||||
```java
|
||||
public enum StatutBonCommande {
|
||||
BROUILLON, // En cours de rédaction
|
||||
VALIDEE, // Validée en interne
|
||||
ENVOYEE, // Envoyée au fournisseur
|
||||
CONFIRMEE, // Confirmée par le fournisseur
|
||||
LIVREE, // Livrée
|
||||
ANNULEE // Annulée
|
||||
}
|
||||
```
|
||||
|
||||
### **Enum TypeBonCommande**
|
||||
|
||||
```java
|
||||
public enum TypeBonCommande {
|
||||
ACHAT, // Achat de matériel
|
||||
LOCATION, // Location de matériel
|
||||
PRESTATIONS, // Prestations de service
|
||||
FOURNITURES, // Fournitures consommables
|
||||
TRAVAUX, // Travaux sous-traités
|
||||
MAINTENANCE, // Maintenance
|
||||
TRANSPORT, // Transport
|
||||
AUTRE
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔌 API REST
|
||||
|
||||
### **Endpoints**
|
||||
|
||||
| Méthode | Endpoint | Description |
|
||||
|---------|----------|-------------|
|
||||
| GET | `/api/v1/bons-commande` | Liste bons de commande |
|
||||
| GET | `/api/v1/bons-commande/{id}` | Détails |
|
||||
| POST | `/api/v1/bons-commande` | Créer |
|
||||
| PUT | `/api/v1/bons-commande/{id}` | Modifier |
|
||||
| PUT | `/api/v1/bons-commande/{id}/valider` | Valider |
|
||||
| PUT | `/api/v1/bons-commande/{id}/envoyer` | Envoyer |
|
||||
| DELETE | `/api/v1/bons-commande/{id}` | Annuler |
|
||||
| GET | `/api/v1/bons-commande/stats` | Statistiques |
|
||||
|
||||
---
|
||||
|
||||
## 💻 Exemples
|
||||
|
||||
### **Créer un bon de commande**
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:8080/api/v1/bons-commande \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"fournisseurId": 1,
|
||||
"dateCommande": "2025-10-01",
|
||||
"dateLivraisonSouhaitee": "2025-10-10",
|
||||
"type": "ACHAT",
|
||||
"lignes": [
|
||||
{
|
||||
"designation": "Ciment Portland 25kg",
|
||||
"quantite": 50,
|
||||
"prixUnitaire": 8.50,
|
||||
"unite": "UNITE"
|
||||
},
|
||||
{
|
||||
"designation": "Sable 0/4 - 1 tonne",
|
||||
"quantite": 10,
|
||||
"prixUnitaire": 45.00,
|
||||
"unite": "TONNE"
|
||||
}
|
||||
],
|
||||
"commentaire": "Livraison sur chantier Villa Moderne"
|
||||
}'
|
||||
```
|
||||
|
||||
**Réponse**:
|
||||
```json
|
||||
{
|
||||
"id": "uuid",
|
||||
"numero": "BC-2025-001",
|
||||
"fournisseur": "Matériaux Pro",
|
||||
"dateCommande": "2025-10-01",
|
||||
"statut": "BROUILLON",
|
||||
"montantTotal": 875.00,
|
||||
"lignes": [
|
||||
{
|
||||
"designation": "Ciment Portland 25kg",
|
||||
"quantite": 50,
|
||||
"prixUnitaire": 8.50,
|
||||
"montant": 425.00
|
||||
},
|
||||
{
|
||||
"designation": "Sable 0/4 - 1 tonne",
|
||||
"quantite": 10,
|
||||
"prixUnitaire": 45.00,
|
||||
"montant": 450.00
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### **Valider un bon de commande**
|
||||
|
||||
```bash
|
||||
curl -X PUT http://localhost:8080/api/v1/bons-commande/{id}/valider
|
||||
```
|
||||
|
||||
### **Envoyer au fournisseur**
|
||||
|
||||
```bash
|
||||
curl -X PUT http://localhost:8080/api/v1/bons-commande/{id}/envoyer \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"emailFournisseur": "contact@materiauxpro.fr",
|
||||
"message": "Veuillez trouver ci-joint notre bon de commande"
|
||||
}'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔧 Services métier
|
||||
|
||||
**BonCommandeService - Méthodes**:
|
||||
- `create(BonCommandeDTO)` - Créer
|
||||
- `valider(UUID id)` - Valider
|
||||
- `envoyer(UUID id)` - Envoyer au fournisseur
|
||||
- `annuler(UUID id)` - Annuler
|
||||
- `calculerMontantTotal(UUID id)` - Calculer total
|
||||
- `findByStatut(StatutBonCommande)` - Par statut
|
||||
- `findByFournisseur(Long fournisseurId)` - Par fournisseur
|
||||
|
||||
---
|
||||
|
||||
## 📈 Relations
|
||||
|
||||
- **FOURNISSEUR** ⬅️ Un bon de commande est adressé à un fournisseur
|
||||
- **CHANTIER** ⬅️ Un bon peut être lié à un chantier
|
||||
- **STOCK** ➡️ Réception met à jour le stock
|
||||
|
||||
---
|
||||
|
||||
## ✅ Validations
|
||||
|
||||
- ✅ Numéro unique et obligatoire
|
||||
- ✅ Fournisseur obligatoire
|
||||
- ✅ Au moins une ligne
|
||||
- ✅ Quantités positives
|
||||
- ✅ Prix unitaires positifs
|
||||
- ✅ Transitions de statut cohérentes
|
||||
|
||||
---
|
||||
|
||||
**Dernière mise à jour**: 2025-09-30
|
||||
**Version**: 1.0
|
||||
|
||||
278
docs/concepts/09-DEVIS.md
Normal file
278
docs/concepts/09-DEVIS.md
Normal file
@@ -0,0 +1,278 @@
|
||||
# 💰 CONCEPT: DEVIS
|
||||
|
||||
## 📌 Vue d'ensemble
|
||||
|
||||
Le concept **DEVIS** gère les devis et la facturation des chantiers. Il inclut les lignes de devis, calculs automatiques, et génération PDF.
|
||||
|
||||
**Importance**: ⭐⭐⭐⭐ (Concept stratégique)
|
||||
|
||||
---
|
||||
|
||||
## 🗂️ Fichiers concernés
|
||||
|
||||
### **Entités JPA**
|
||||
| Fichier | Description |
|
||||
|---------|-------------|
|
||||
| `Devis.java` | Entité principale devis |
|
||||
| `LigneDevis.java` | Ligne de devis |
|
||||
| `StatutDevis.java` | Enum (BROUILLON, ENVOYE, ACCEPTE, REFUSE, EXPIRE) |
|
||||
| `Facture.java` | Entité facture |
|
||||
| `LigneFacture.java` | Ligne de facture |
|
||||
|
||||
### **Services**
|
||||
| Fichier | Description |
|
||||
|---------|-------------|
|
||||
| `DevisService.java` | Service métier devis |
|
||||
| `FactureService.java` | Service métier factures |
|
||||
| `PdfGeneratorService.java` | Génération PDF |
|
||||
|
||||
### **Resources**
|
||||
| Fichier | Description |
|
||||
|---------|-------------|
|
||||
| `DevisResource.java` | API REST devis |
|
||||
| `FactureResource.java` | API REST factures |
|
||||
|
||||
---
|
||||
|
||||
## 📊 Modèle de données
|
||||
|
||||
### **Entité Devis**
|
||||
|
||||
```java
|
||||
@Entity
|
||||
@Table(name = "devis")
|
||||
public class Devis extends PanacheEntityBase {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.UUID)
|
||||
private UUID id;
|
||||
|
||||
@Column(name = "numero", unique = true, nullable = false)
|
||||
private String numero;
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "client_id", nullable = false)
|
||||
private Client client;
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "chantier_id")
|
||||
private Chantier chantier;
|
||||
|
||||
@Column(name = "date_emission", nullable = false)
|
||||
private LocalDate dateEmission;
|
||||
|
||||
@Column(name = "date_validite")
|
||||
private LocalDate dateValidite;
|
||||
|
||||
@Enumerated(EnumType.STRING)
|
||||
@Column(name = "statut", nullable = false)
|
||||
private StatutDevis statut = StatutDevis.BROUILLON;
|
||||
|
||||
@OneToMany(mappedBy = "devis", cascade = CascadeType.ALL)
|
||||
private List<LigneDevis> lignes;
|
||||
|
||||
@Column(name = "montant_ht", precision = 10, scale = 2)
|
||||
private BigDecimal montantHT = BigDecimal.ZERO;
|
||||
|
||||
@Column(name = "montant_tva", precision = 10, scale = 2)
|
||||
private BigDecimal montantTVA = BigDecimal.ZERO;
|
||||
|
||||
@Column(name = "montant_ttc", precision = 10, scale = 2)
|
||||
private BigDecimal montantTTC = BigDecimal.ZERO;
|
||||
|
||||
@Column(name = "taux_tva", precision = 5, scale = 2)
|
||||
private BigDecimal tauxTVA = new BigDecimal("20.00");
|
||||
}
|
||||
```
|
||||
|
||||
### **Enum StatutDevis**
|
||||
|
||||
```java
|
||||
public enum StatutDevis {
|
||||
BROUILLON, // En cours de rédaction
|
||||
ENVOYE, // Envoyé au client
|
||||
ACCEPTE, // Accepté par le client
|
||||
REFUSE, // Refusé par le client
|
||||
EXPIRE // Expiré (date de validité dépassée)
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔌 API REST
|
||||
|
||||
### **Endpoints Devis**
|
||||
|
||||
| Méthode | Endpoint | Description |
|
||||
|---------|----------|-------------|
|
||||
| GET | `/api/v1/devis` | Liste devis |
|
||||
| GET | `/api/v1/devis/{id}` | Détails |
|
||||
| POST | `/api/v1/devis` | Créer |
|
||||
| PUT | `/api/v1/devis/{id}` | Modifier |
|
||||
| PUT | `/api/v1/devis/{id}/envoyer` | Envoyer au client |
|
||||
| PUT | `/api/v1/devis/{id}/accepter` | Accepter |
|
||||
| PUT | `/api/v1/devis/{id}/refuser` | Refuser |
|
||||
| GET | `/api/v1/devis/{id}/pdf` | Générer PDF |
|
||||
| GET | `/api/v1/devis/stats` | Statistiques |
|
||||
|
||||
### **Endpoints Factures**
|
||||
|
||||
| Méthode | Endpoint | Description |
|
||||
|---------|----------|-------------|
|
||||
| GET | `/api/v1/factures` | Liste factures |
|
||||
| GET | `/api/v1/factures/{id}` | Détails |
|
||||
| POST | `/api/v1/factures` | Créer |
|
||||
| POST | `/api/v1/factures/depuis-devis/{devisId}` | Créer depuis devis |
|
||||
| GET | `/api/v1/factures/{id}/pdf` | Générer PDF |
|
||||
|
||||
---
|
||||
|
||||
## 💻 Exemples
|
||||
|
||||
### **Créer un devis**
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:8080/api/v1/devis \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"clientId": "client-uuid",
|
||||
"chantierId": "chantier-uuid",
|
||||
"dateEmission": "2025-10-01",
|
||||
"dateValidite": "2025-11-01",
|
||||
"tauxTVA": 20.00,
|
||||
"lignes": [
|
||||
{
|
||||
"designation": "Terrassement et fondations",
|
||||
"quantite": 1,
|
||||
"unite": "FORFAIT",
|
||||
"prixUnitaireHT": 5000.00
|
||||
},
|
||||
{
|
||||
"designation": "Maçonnerie murs porteurs",
|
||||
"quantite": 45,
|
||||
"unite": "METRE_CARRE",
|
||||
"prixUnitaireHT": 120.00
|
||||
},
|
||||
{
|
||||
"designation": "Charpente traditionnelle",
|
||||
"quantite": 1,
|
||||
"unite": "FORFAIT",
|
||||
"prixUnitaireHT": 8000.00
|
||||
}
|
||||
]
|
||||
}'
|
||||
```
|
||||
|
||||
**Réponse**:
|
||||
```json
|
||||
{
|
||||
"id": "uuid",
|
||||
"numero": "DEV-2025-001",
|
||||
"client": "Jean Dupont",
|
||||
"chantier": "Construction Villa Moderne",
|
||||
"dateEmission": "2025-10-01",
|
||||
"dateValidite": "2025-11-01",
|
||||
"statut": "BROUILLON",
|
||||
"lignes": [
|
||||
{
|
||||
"designation": "Terrassement et fondations",
|
||||
"quantite": 1,
|
||||
"prixUnitaireHT": 5000.00,
|
||||
"montantHT": 5000.00
|
||||
},
|
||||
{
|
||||
"designation": "Maçonnerie murs porteurs",
|
||||
"quantite": 45,
|
||||
"prixUnitaireHT": 120.00,
|
||||
"montantHT": 5400.00
|
||||
},
|
||||
{
|
||||
"designation": "Charpente traditionnelle",
|
||||
"quantite": 1,
|
||||
"prixUnitaireHT": 8000.00,
|
||||
"montantHT": 8000.00
|
||||
}
|
||||
],
|
||||
"montantHT": 18400.00,
|
||||
"montantTVA": 3680.00,
|
||||
"montantTTC": 22080.00
|
||||
}
|
||||
```
|
||||
|
||||
### **Envoyer un devis**
|
||||
|
||||
```bash
|
||||
curl -X PUT http://localhost:8080/api/v1/devis/{id}/envoyer \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"emailClient": "jean.dupont@example.com",
|
||||
"message": "Veuillez trouver ci-joint notre devis"
|
||||
}'
|
||||
```
|
||||
|
||||
### **Générer PDF**
|
||||
|
||||
```bash
|
||||
curl -X GET http://localhost:8080/api/v1/devis/{id}/pdf \
|
||||
-H "Accept: application/pdf" \
|
||||
--output devis.pdf
|
||||
```
|
||||
|
||||
### **Créer facture depuis devis**
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:8080/api/v1/factures/depuis-devis/{devisId}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔧 Services métier
|
||||
|
||||
### **DevisService**
|
||||
|
||||
**Méthodes principales**:
|
||||
- `create(DevisDTO)` - Créer devis
|
||||
- `calculerMontants(UUID id)` - Calculer HT/TVA/TTC
|
||||
- `envoyer(UUID id)` - Envoyer au client
|
||||
- `accepter(UUID id)` - Accepter
|
||||
- `refuser(UUID id)` - Refuser
|
||||
- `genererPDF(UUID id)` - Générer PDF
|
||||
|
||||
### **FactureService**
|
||||
|
||||
**Méthodes principales**:
|
||||
- `create(FactureDTO)` - Créer facture
|
||||
- `creerDepuisDevis(UUID devisId)` - Créer depuis devis
|
||||
- `genererPDF(UUID id)` - Générer PDF
|
||||
|
||||
---
|
||||
|
||||
## 📈 Relations
|
||||
|
||||
- **CLIENT** ⬅️ Un devis est adressé à un client
|
||||
- **CHANTIER** ⬅️ Un devis peut être lié à un chantier
|
||||
- **FACTURE** ➡️ Un devis accepté génère une facture
|
||||
|
||||
---
|
||||
|
||||
## ✅ Validations
|
||||
|
||||
- ✅ Numéro unique
|
||||
- ✅ Client obligatoire
|
||||
- ✅ Au moins une ligne
|
||||
- ✅ Montants positifs
|
||||
- ✅ Date validité > date émission
|
||||
- ✅ Taux TVA entre 0 et 100
|
||||
|
||||
---
|
||||
|
||||
## 📚 Références
|
||||
|
||||
- [Concept CLIENT](./02-CLIENT.md)
|
||||
- [Concept CHANTIER](./01-CHANTIER.md)
|
||||
- [Concept BUDGET](./10-BUDGET.md)
|
||||
|
||||
---
|
||||
|
||||
**Dernière mise à jour**: 2025-09-30
|
||||
**Version**: 1.0
|
||||
|
||||
142
docs/concepts/10-BUDGET.md
Normal file
142
docs/concepts/10-BUDGET.md
Normal file
@@ -0,0 +1,142 @@
|
||||
# 💵 CONCEPT: BUDGET
|
||||
|
||||
## 📌 Vue d'ensemble
|
||||
|
||||
Le concept **BUDGET** gère les budgets prévisionnels et réels des chantiers avec suivi des dépenses et écarts.
|
||||
|
||||
**Importance**: ⭐⭐⭐ (Concept important)
|
||||
|
||||
---
|
||||
|
||||
## 🗂️ Fichiers concernés
|
||||
|
||||
### **Entités JPA**
|
||||
| Fichier | Description |
|
||||
|---------|-------------|
|
||||
| `Budget.java` | Entité principale budget |
|
||||
|
||||
### **Services**
|
||||
| Fichier | Description |
|
||||
|---------|-------------|
|
||||
| `BudgetService.java` | Service métier budget |
|
||||
|
||||
### **Resources**
|
||||
| Fichier | Description |
|
||||
|---------|-------------|
|
||||
| `BudgetResource.java` | API REST budget |
|
||||
|
||||
---
|
||||
|
||||
## 📊 Modèle de données
|
||||
|
||||
```java
|
||||
@Entity
|
||||
@Table(name = "budgets")
|
||||
public class Budget extends PanacheEntityBase {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.UUID)
|
||||
private UUID id;
|
||||
|
||||
@OneToOne
|
||||
@JoinColumn(name = "chantier_id", nullable = false)
|
||||
private Chantier chantier;
|
||||
|
||||
@Column(name = "montant_prevu", precision = 12, scale = 2)
|
||||
private BigDecimal montantPrevu;
|
||||
|
||||
@Column(name = "montant_depense", precision = 12, scale = 2)
|
||||
private BigDecimal montantDepense = BigDecimal.ZERO;
|
||||
|
||||
@Column(name = "montant_restant", precision = 12, scale = 2)
|
||||
private BigDecimal montantRestant;
|
||||
|
||||
@Column(name = "pourcentage_utilise", precision = 5, scale = 2)
|
||||
private BigDecimal pourcentageUtilise = BigDecimal.ZERO;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔌 API REST
|
||||
|
||||
### **Endpoints**
|
||||
|
||||
| Méthode | Endpoint | Description |
|
||||
|---------|----------|-------------|
|
||||
| GET | `/api/v1/budgets` | Liste budgets |
|
||||
| GET | `/api/v1/budgets/{id}` | Détails |
|
||||
| GET | `/api/v1/budgets/chantier/{id}` | Budget d'un chantier |
|
||||
| POST | `/api/v1/budgets` | Créer |
|
||||
| PUT | `/api/v1/budgets/{id}` | Modifier |
|
||||
| POST | `/api/v1/budgets/{id}/depense` | Enregistrer dépense |
|
||||
| GET | `/api/v1/budgets/{id}/ecarts` | Analyse écarts |
|
||||
|
||||
---
|
||||
|
||||
## 💻 Exemples
|
||||
|
||||
### **Créer un budget**
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:8080/api/v1/budgets \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"chantierId": "chantier-uuid",
|
||||
"montantPrevu": 250000.00
|
||||
}'
|
||||
```
|
||||
|
||||
### **Enregistrer une dépense**
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:8080/api/v1/budgets/{id}/depense \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"montant": 5000.00,
|
||||
"categorie": "MATERIAUX",
|
||||
"description": "Achat ciment et sable"
|
||||
}'
|
||||
```
|
||||
|
||||
### **Analyse des écarts**
|
||||
|
||||
```bash
|
||||
curl -X GET http://localhost:8080/api/v1/budgets/{id}/ecarts
|
||||
```
|
||||
|
||||
**Réponse**:
|
||||
```json
|
||||
{
|
||||
"montantPrevu": 250000.00,
|
||||
"montantDepense": 180000.00,
|
||||
"montantRestant": 70000.00,
|
||||
"pourcentageUtilise": 72.00,
|
||||
"ecart": -70000.00,
|
||||
"statut": "DANS_BUDGET",
|
||||
"alertes": []
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔧 Services métier
|
||||
|
||||
**BudgetService - Méthodes**:
|
||||
- `create(BudgetDTO)` - Créer
|
||||
- `enregistrerDepense(UUID id, BigDecimal montant)` - Dépense
|
||||
- `calculerEcarts(UUID id)` - Calculer écarts
|
||||
- `getStatutBudget(UUID id)` - Statut
|
||||
|
||||
---
|
||||
|
||||
## 📈 Relations
|
||||
|
||||
- **CHANTIER** ⬅️ Un budget est lié à un chantier (OneToOne)
|
||||
- **DEVIS** ⬅️ Le budget initial vient du devis
|
||||
- **FACTURE** ➡️ Les factures impactent le budget
|
||||
|
||||
---
|
||||
|
||||
**Dernière mise à jour**: 2025-09-30
|
||||
**Version**: 1.0
|
||||
|
||||
252
docs/concepts/11-EMPLOYE.md
Normal file
252
docs/concepts/11-EMPLOYE.md
Normal file
@@ -0,0 +1,252 @@
|
||||
# 👷 CONCEPT: EMPLOYE
|
||||
|
||||
## 📌 Vue d'ensemble
|
||||
|
||||
Le concept **EMPLOYE** gère les ressources humaines : employés, compétences, équipes, et affectations aux chantiers.
|
||||
|
||||
**Importance**: ⭐⭐⭐⭐ (Concept stratégique)
|
||||
|
||||
---
|
||||
|
||||
## 🗂️ Fichiers concernés
|
||||
|
||||
### **Entités JPA**
|
||||
| Fichier | Description |
|
||||
|---------|-------------|
|
||||
| `Employe.java` | Entité principale employé |
|
||||
| `EmployeCompetence.java` | Compétences d'un employé |
|
||||
| `FonctionEmploye.java` | Enum fonctions |
|
||||
| `StatutEmploye.java` | Enum (ACTIF, CONGE, ARRET_MALADIE, FORMATION, INACTIF) |
|
||||
| `NiveauCompetence.java` | Enum niveaux de compétence |
|
||||
| `Equipe.java` | Entité équipe |
|
||||
| `StatutEquipe.java` | Enum (ACTIVE, INACTIVE, EN_MISSION, DISPONIBLE) |
|
||||
|
||||
### **Services**
|
||||
| Fichier | Description |
|
||||
|---------|-------------|
|
||||
| `EmployeService.java` | Service métier employés |
|
||||
| `EquipeService.java` | Service métier équipes |
|
||||
|
||||
### **Resources**
|
||||
| Fichier | Description |
|
||||
|---------|-------------|
|
||||
| `EmployeResource.java` | API REST employés |
|
||||
| `EquipeResource.java` | API REST équipes |
|
||||
|
||||
---
|
||||
|
||||
## 📊 Modèle de données
|
||||
|
||||
### **Entité Employe**
|
||||
|
||||
```java
|
||||
@Entity
|
||||
@Table(name = "employes")
|
||||
public class Employe extends PanacheEntityBase {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.UUID)
|
||||
private UUID id;
|
||||
|
||||
@Column(name = "nom", nullable = false)
|
||||
private String nom;
|
||||
|
||||
@Column(name = "prenom", nullable = false)
|
||||
private String prenom;
|
||||
|
||||
@Column(name = "email", unique = true)
|
||||
private String email;
|
||||
|
||||
@Column(name = "telephone")
|
||||
private String telephone;
|
||||
|
||||
@Enumerated(EnumType.STRING)
|
||||
@Column(name = "fonction")
|
||||
private FonctionEmploye fonction;
|
||||
|
||||
@Enumerated(EnumType.STRING)
|
||||
@Column(name = "statut")
|
||||
private StatutEmploye statut = StatutEmploye.ACTIF;
|
||||
|
||||
@Column(name = "date_embauche")
|
||||
private LocalDate dateEmbauche;
|
||||
|
||||
@Column(name = "taux_horaire", precision = 10, scale = 2)
|
||||
private BigDecimal tauxHoraire;
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "equipe_id")
|
||||
private Equipe equipe;
|
||||
|
||||
@OneToMany(mappedBy = "employe", cascade = CascadeType.ALL)
|
||||
private List<EmployeCompetence> competences;
|
||||
}
|
||||
```
|
||||
|
||||
### **Enum FonctionEmploye**
|
||||
|
||||
```java
|
||||
public enum FonctionEmploye {
|
||||
CHEF_CHANTIER,
|
||||
CONDUCTEUR_TRAVAUX,
|
||||
MACON,
|
||||
ELECTRICIEN,
|
||||
PLOMBIER,
|
||||
CHARPENTIER,
|
||||
COUVREUR,
|
||||
PEINTRE,
|
||||
CARRELEUR,
|
||||
MENUISIER,
|
||||
TERRASSIER,
|
||||
GRUTIER,
|
||||
MANOEUVRE,
|
||||
AUTRE
|
||||
}
|
||||
```
|
||||
|
||||
### **Enum StatutEmploye**
|
||||
|
||||
```java
|
||||
public enum StatutEmploye {
|
||||
ACTIF, // Actif et disponible
|
||||
CONGE, // En congé
|
||||
ARRET_MALADIE, // Arrêt maladie
|
||||
FORMATION, // En formation
|
||||
INACTIF // Inactif (démission, licenciement)
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔌 API REST
|
||||
|
||||
### **Endpoints Employés**
|
||||
|
||||
| Méthode | Endpoint | Description |
|
||||
|---------|----------|-------------|
|
||||
| GET | `/api/v1/employes` | Liste employés |
|
||||
| GET | `/api/v1/employes/{id}` | Détails |
|
||||
| POST | `/api/v1/employes` | Créer |
|
||||
| PUT | `/api/v1/employes/{id}` | Modifier |
|
||||
| DELETE | `/api/v1/employes/{id}` | Supprimer |
|
||||
| GET | `/api/v1/employes/disponibles` | Employés disponibles |
|
||||
| GET | `/api/v1/employes/fonction/{fonction}` | Par fonction |
|
||||
| GET | `/api/v1/employes/stats` | Statistiques |
|
||||
|
||||
### **Endpoints Équipes**
|
||||
|
||||
| Méthode | Endpoint | Description |
|
||||
|---------|----------|-------------|
|
||||
| GET | `/api/v1/equipes` | Liste équipes |
|
||||
| GET | `/api/v1/equipes/{id}` | Détails |
|
||||
| POST | `/api/v1/equipes` | Créer |
|
||||
| PUT | `/api/v1/equipes/{id}` | Modifier |
|
||||
| POST | `/api/v1/equipes/{id}/membres` | Ajouter membre |
|
||||
| DELETE | `/api/v1/equipes/{id}/membres/{employeId}` | Retirer membre |
|
||||
|
||||
---
|
||||
|
||||
## 💻 Exemples
|
||||
|
||||
### **Créer un employé**
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:8080/api/v1/employes \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"nom": "Martin",
|
||||
"prenom": "Pierre",
|
||||
"email": "pierre.martin@btpxpress.fr",
|
||||
"telephone": "+33 6 12 34 56 78",
|
||||
"fonction": "MACON",
|
||||
"dateEmbauche": "2025-01-15",
|
||||
"tauxHoraire": 25.00,
|
||||
"competences": [
|
||||
{
|
||||
"nom": "Maçonnerie traditionnelle",
|
||||
"niveau": "EXPERT"
|
||||
},
|
||||
{
|
||||
"nom": "Coffrage",
|
||||
"niveau": "CONFIRME"
|
||||
}
|
||||
]
|
||||
}'
|
||||
```
|
||||
|
||||
### **Créer une équipe**
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:8080/api/v1/equipes \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"nom": "Équipe Gros Œuvre A",
|
||||
"chefEquipeId": "employe-uuid",
|
||||
"membreIds": ["uuid1", "uuid2", "uuid3"]
|
||||
}'
|
||||
```
|
||||
|
||||
### **Employés disponibles**
|
||||
|
||||
```bash
|
||||
curl -X GET http://localhost:8080/api/v1/employes/disponibles
|
||||
```
|
||||
|
||||
**Réponse**:
|
||||
```json
|
||||
[
|
||||
{
|
||||
"id": "uuid",
|
||||
"nom": "Martin",
|
||||
"prenom": "Pierre",
|
||||
"fonction": "MACON",
|
||||
"statut": "ACTIF",
|
||||
"equipe": "Équipe Gros Œuvre A",
|
||||
"competences": ["Maçonnerie", "Coffrage"]
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔧 Services métier
|
||||
|
||||
### **EmployeService**
|
||||
|
||||
**Méthodes principales**:
|
||||
- `findAll()` - Tous les employés
|
||||
- `findDisponibles()` - Employés disponibles
|
||||
- `findByFonction(FonctionEmploye)` - Par fonction
|
||||
- `create(EmployeDTO)` - Créer
|
||||
- `update(UUID id, EmployeDTO)` - Modifier
|
||||
- `changerStatut(UUID id, StatutEmploye)` - Changer statut
|
||||
|
||||
### **EquipeService**
|
||||
|
||||
**Méthodes principales**:
|
||||
- `create(EquipeDTO)` - Créer équipe
|
||||
- `ajouterMembre(UUID equipeId, UUID employeId)` - Ajouter membre
|
||||
- `retirerMembre(UUID equipeId, UUID employeId)` - Retirer membre
|
||||
|
||||
---
|
||||
|
||||
## 📈 Relations
|
||||
|
||||
- **EQUIPE** ⬅️ Un employé appartient à une équipe
|
||||
- **CHANTIER** ➡️ Un employé peut être affecté à des chantiers
|
||||
- **USER** ⬅️ Un employé peut avoir un compte utilisateur
|
||||
|
||||
---
|
||||
|
||||
## ✅ Validations
|
||||
|
||||
- ✅ Nom et prénom obligatoires
|
||||
- ✅ Email unique
|
||||
- ✅ Fonction obligatoire
|
||||
- ✅ Taux horaire positif
|
||||
- ✅ Date d'embauche cohérente
|
||||
|
||||
---
|
||||
|
||||
**Dernière mise à jour**: 2025-09-30
|
||||
**Version**: 1.0
|
||||
|
||||
222
docs/concepts/12-MAINTENANCE.md
Normal file
222
docs/concepts/12-MAINTENANCE.md
Normal file
@@ -0,0 +1,222 @@
|
||||
# 🔧 CONCEPT: MAINTENANCE
|
||||
|
||||
## 📌 Vue d'ensemble
|
||||
|
||||
Le concept **MAINTENANCE** gère la maintenance préventive et corrective du matériel BTP avec planification et historique.
|
||||
|
||||
**Importance**: ⭐⭐⭐ (Concept important)
|
||||
|
||||
---
|
||||
|
||||
## 🗂️ Fichiers concernés
|
||||
|
||||
### **Entités JPA**
|
||||
| Fichier | Description |
|
||||
|---------|-------------|
|
||||
| `MaintenanceMateriel.java` | Entité principale maintenance |
|
||||
| `StatutMaintenance.java` | Enum (PLANIFIEE, EN_COURS, TERMINEE, ANNULEE, REPORTEE) |
|
||||
| `TypeMaintenance.java` | Enum (PREVENTIVE, CORRECTIVE, CURATIVE, PREDICTIVE) |
|
||||
|
||||
### **Services**
|
||||
| Fichier | Description |
|
||||
|---------|-------------|
|
||||
| `MaintenanceService.java` | Service métier maintenance |
|
||||
|
||||
### **Resources**
|
||||
| Fichier | Description |
|
||||
|---------|-------------|
|
||||
| `MaintenanceResource.java` | API REST maintenance |
|
||||
|
||||
---
|
||||
|
||||
## 📊 Modèle de données
|
||||
|
||||
```java
|
||||
@Entity
|
||||
@Table(name = "maintenances_materiel")
|
||||
public class MaintenanceMateriel extends PanacheEntityBase {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.UUID)
|
||||
private UUID id;
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "materiel_id", nullable = false)
|
||||
private Materiel materiel;
|
||||
|
||||
@Enumerated(EnumType.STRING)
|
||||
@Column(name = "type", nullable = false)
|
||||
private TypeMaintenance type;
|
||||
|
||||
@Enumerated(EnumType.STRING)
|
||||
@Column(name = "statut", nullable = false)
|
||||
private StatutMaintenance statut = StatutMaintenance.PLANIFIEE;
|
||||
|
||||
@Column(name = "date_prevue", nullable = false)
|
||||
private LocalDate datePrevue;
|
||||
|
||||
@Column(name = "date_realisee")
|
||||
private LocalDate dateRealisee;
|
||||
|
||||
@Column(name = "description", length = 1000)
|
||||
private String description;
|
||||
|
||||
@Column(name = "cout", precision = 10, scale = 2)
|
||||
private BigDecimal cout;
|
||||
|
||||
@Column(name = "technicien", length = 100)
|
||||
private String technicien;
|
||||
|
||||
@Column(name = "observations", length = 2000)
|
||||
private String observations;
|
||||
}
|
||||
```
|
||||
|
||||
### **Enum TypeMaintenance**
|
||||
|
||||
```java
|
||||
public enum TypeMaintenance {
|
||||
PREVENTIVE, // Maintenance préventive planifiée
|
||||
CORRECTIVE, // Correction d'un dysfonctionnement
|
||||
CURATIVE, // Réparation d'une panne
|
||||
PREDICTIVE // Maintenance prédictive (IoT, capteurs)
|
||||
}
|
||||
```
|
||||
|
||||
### **Enum StatutMaintenance**
|
||||
|
||||
```java
|
||||
public enum StatutMaintenance {
|
||||
PLANIFIEE, // Planifiée
|
||||
EN_COURS, // En cours de réalisation
|
||||
TERMINEE, // Terminée avec succès
|
||||
ANNULEE, // Annulée
|
||||
REPORTEE // Reportée à une date ultérieure
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔌 API REST
|
||||
|
||||
### **Endpoints**
|
||||
|
||||
| Méthode | Endpoint | Description |
|
||||
|---------|----------|-------------|
|
||||
| GET | `/api/v1/maintenances` | Liste maintenances |
|
||||
| GET | `/api/v1/maintenances/{id}` | Détails |
|
||||
| POST | `/api/v1/maintenances` | Créer |
|
||||
| PUT | `/api/v1/maintenances/{id}` | Modifier |
|
||||
| PUT | `/api/v1/maintenances/{id}/terminer` | Terminer |
|
||||
| GET | `/api/v1/maintenances/materiel/{id}` | Maintenances d'un matériel |
|
||||
| GET | `/api/v1/maintenances/planifiees` | Maintenances planifiées |
|
||||
| GET | `/api/v1/maintenances/stats` | Statistiques |
|
||||
|
||||
---
|
||||
|
||||
## 💻 Exemples
|
||||
|
||||
### **Créer une maintenance préventive**
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:8080/api/v1/maintenances \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"materielId": "materiel-uuid",
|
||||
"type": "PREVENTIVE",
|
||||
"datePrevue": "2025-11-01",
|
||||
"description": "Révision annuelle - Vidange et contrôle général",
|
||||
"technicien": "Service Maintenance"
|
||||
}'
|
||||
```
|
||||
|
||||
### **Terminer une maintenance**
|
||||
|
||||
```bash
|
||||
curl -X PUT http://localhost:8080/api/v1/maintenances/{id}/terminer \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"dateRealisee": "2025-11-01",
|
||||
"cout": 250.00,
|
||||
"observations": "Révision effectuée. Remplacement filtre à huile. Matériel en bon état."
|
||||
}'
|
||||
```
|
||||
|
||||
### **Historique maintenance d'un matériel**
|
||||
|
||||
```bash
|
||||
curl -X GET http://localhost:8080/api/v1/maintenances/materiel/{materielId}
|
||||
```
|
||||
|
||||
**Réponse**:
|
||||
```json
|
||||
[
|
||||
{
|
||||
"id": "uuid",
|
||||
"type": "PREVENTIVE",
|
||||
"statut": "TERMINEE",
|
||||
"datePrevue": "2025-11-01",
|
||||
"dateRealisee": "2025-11-01",
|
||||
"description": "Révision annuelle",
|
||||
"cout": 250.00,
|
||||
"technicien": "Service Maintenance"
|
||||
},
|
||||
{
|
||||
"id": "uuid2",
|
||||
"type": "CORRECTIVE",
|
||||
"statut": "TERMINEE",
|
||||
"datePrevue": "2025-08-15",
|
||||
"dateRealisee": "2025-08-16",
|
||||
"description": "Réparation système hydraulique",
|
||||
"cout": 450.00
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
### **Maintenances planifiées**
|
||||
|
||||
```bash
|
||||
curl -X GET http://localhost:8080/api/v1/maintenances/planifiees
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔧 Services métier
|
||||
|
||||
**MaintenanceService - Méthodes**:
|
||||
- `create(MaintenanceDTO)` - Créer maintenance
|
||||
- `terminer(UUID id, MaintenanceTermineeDTO)` - Terminer
|
||||
- `reporter(UUID id, LocalDate nouvelleDate)` - Reporter
|
||||
- `findByMateriel(UUID materielId)` - Historique matériel
|
||||
- `findPlanifiees()` - Maintenances planifiées
|
||||
- `findEnRetard()` - Maintenances en retard
|
||||
- `planifierPreventive(UUID materielId)` - Planifier préventive
|
||||
|
||||
---
|
||||
|
||||
## 📈 Relations
|
||||
|
||||
- **MATERIEL** ⬅️ Une maintenance concerne un matériel
|
||||
- **EMPLOYE** ⬅️ Un technicien (employé) peut réaliser la maintenance
|
||||
|
||||
---
|
||||
|
||||
## ✅ Validations
|
||||
|
||||
- ✅ Matériel obligatoire
|
||||
- ✅ Type obligatoire
|
||||
- ✅ Date prévue obligatoire
|
||||
- ✅ Coût positif
|
||||
- ✅ Date réalisée >= date prévue
|
||||
|
||||
---
|
||||
|
||||
## 📚 Références
|
||||
|
||||
- [Concept MATERIEL](./03-MATERIEL.md)
|
||||
- [Concept EMPLOYE](./11-EMPLOYE.md)
|
||||
|
||||
---
|
||||
|
||||
**Dernière mise à jour**: 2025-09-30
|
||||
**Version**: 1.0
|
||||
|
||||
151
docs/concepts/13-PLANNING.md
Normal file
151
docs/concepts/13-PLANNING.md
Normal file
@@ -0,0 +1,151 @@
|
||||
# 📅 CONCEPT: PLANNING
|
||||
|
||||
## 📌 Vue d'ensemble
|
||||
|
||||
Le concept **PLANNING** gère le planning général avec événements, rendez-vous, affectations de ressources et calendrier.
|
||||
|
||||
**Importance**: ⭐⭐⭐⭐ (Concept stratégique)
|
||||
|
||||
---
|
||||
|
||||
## 🗂️ Fichiers concernés
|
||||
|
||||
### **Entités JPA**
|
||||
| Fichier | Description |
|
||||
|---------|-------------|
|
||||
| `PlanningEvent.java` | Événement de planning |
|
||||
| `StatutPlanningEvent.java` | Enum statuts |
|
||||
| `TypePlanningEvent.java` | Enum types |
|
||||
| `PrioritePlanningEvent.java` | Enum priorités |
|
||||
| `RappelPlanningEvent.java` | Rappels |
|
||||
| `TypeRappel.java` | Enum types rappel |
|
||||
| `VuePlanning.java` | Enum vues (JOUR, SEMAINE, MOIS, ANNEE) |
|
||||
|
||||
### **Services**
|
||||
| Fichier | Description |
|
||||
|---------|-------------|
|
||||
| `PlanningService.java` | Service métier planning |
|
||||
|
||||
### **Resources**
|
||||
| Fichier | Description |
|
||||
|---------|-------------|
|
||||
| `PlanningResource.java` | API REST planning |
|
||||
|
||||
---
|
||||
|
||||
## 📊 Modèle de données
|
||||
|
||||
```java
|
||||
@Entity
|
||||
@Table(name = "planning_events")
|
||||
public class PlanningEvent extends PanacheEntityBase {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.UUID)
|
||||
private UUID id;
|
||||
|
||||
@Column(name = "titre", nullable = false)
|
||||
private String titre;
|
||||
|
||||
@Column(name = "description", length = 2000)
|
||||
private String description;
|
||||
|
||||
@Column(name = "date_debut", nullable = false)
|
||||
private LocalDateTime dateDebut;
|
||||
|
||||
@Column(name = "date_fin", nullable = false)
|
||||
private LocalDateTime dateFin;
|
||||
|
||||
@Enumerated(EnumType.STRING)
|
||||
@Column(name = "type")
|
||||
private TypePlanningEvent type;
|
||||
|
||||
@Enumerated(EnumType.STRING)
|
||||
@Column(name = "statut")
|
||||
private StatutPlanningEvent statut;
|
||||
|
||||
@Enumerated(EnumType.STRING)
|
||||
@Column(name = "priorite")
|
||||
private PrioritePlanningEvent priorite;
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "chantier_id")
|
||||
private Chantier chantier;
|
||||
|
||||
@ManyToMany
|
||||
@JoinTable(name = "planning_event_employes")
|
||||
private List<Employe> employes;
|
||||
|
||||
@ManyToMany
|
||||
@JoinTable(name = "planning_event_materiels")
|
||||
private List<Materiel> materiels;
|
||||
|
||||
@Column(name = "lieu", length = 500)
|
||||
private String lieu;
|
||||
|
||||
@Column(name = "tout_la_journee")
|
||||
private Boolean toutLaJournee = false;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔌 API REST
|
||||
|
||||
### **Endpoints**
|
||||
|
||||
| Méthode | Endpoint | Description |
|
||||
|---------|----------|-------------|
|
||||
| GET | `/api/v1/planning` | Liste événements |
|
||||
| GET | `/api/v1/planning/{id}` | Détails |
|
||||
| POST | `/api/v1/planning` | Créer |
|
||||
| PUT | `/api/v1/planning/{id}` | Modifier |
|
||||
| DELETE | `/api/v1/planning/{id}` | Supprimer |
|
||||
| GET | `/api/v1/planning/periode` | Par période |
|
||||
| GET | `/api/v1/planning/chantier/{id}` | Par chantier |
|
||||
| GET | `/api/v1/planning/employe/{id}` | Par employé |
|
||||
|
||||
---
|
||||
|
||||
## 💻 Exemples
|
||||
|
||||
### **Créer un événement**
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:8080/api/v1/planning \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"titre": "Coulage dalle béton",
|
||||
"description": "Coulage de la dalle du RDC",
|
||||
"dateDebut": "2025-10-15T08:00:00",
|
||||
"dateFin": "2025-10-15T17:00:00",
|
||||
"type": "CHANTIER",
|
||||
"priorite": "HAUTE",
|
||||
"chantierId": "chantier-uuid",
|
||||
"employeIds": ["emp1-uuid", "emp2-uuid"],
|
||||
"materielIds": ["mat1-uuid"],
|
||||
"lieu": "Chantier Villa Moderne"
|
||||
}'
|
||||
```
|
||||
|
||||
### **Événements par période**
|
||||
|
||||
```bash
|
||||
curl -X GET "http://localhost:8080/api/v1/planning/periode?debut=2025-10-01&fin=2025-10-31"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔧 Services métier
|
||||
|
||||
**PlanningService - Méthodes**:
|
||||
- `create(PlanningEventDTO)` - Créer
|
||||
- `findByPeriode(LocalDate debut, LocalDate fin)` - Par période
|
||||
- `findByChantier(UUID chantierId)` - Par chantier
|
||||
- `findByEmploye(UUID employeId)` - Par employé
|
||||
- `detecterConflits(PlanningEventDTO)` - Détecter conflits
|
||||
|
||||
---
|
||||
|
||||
**Dernière mise à jour**: 2025-09-30
|
||||
**Version**: 1.0
|
||||
|
||||
128
docs/concepts/14-DOCUMENT.md
Normal file
128
docs/concepts/14-DOCUMENT.md
Normal file
@@ -0,0 +1,128 @@
|
||||
# 📄 CONCEPT: DOCUMENT
|
||||
|
||||
## 📌 Vue d'ensemble
|
||||
|
||||
Le concept **DOCUMENT** gère la GED (Gestion Électronique des Documents) : plans, photos, rapports, contrats, etc.
|
||||
|
||||
**Importance**: ⭐⭐⭐ (Concept important)
|
||||
|
||||
---
|
||||
|
||||
## 🗂️ Fichiers concernés
|
||||
|
||||
### **Entités JPA**
|
||||
| Fichier | Description |
|
||||
|---------|-------------|
|
||||
| `Document.java` | Entité principale document |
|
||||
| `TypeDocument.java` | Enum types (PLAN, PERMIS, RAPPORT, PHOTO, CONTRAT, etc.) |
|
||||
|
||||
### **Services**
|
||||
| Fichier | Description |
|
||||
|---------|-------------|
|
||||
| `DocumentService.java` | Service métier documents |
|
||||
|
||||
### **Resources**
|
||||
| Fichier | Description |
|
||||
|---------|-------------|
|
||||
| `DocumentResource.java` | API REST documents |
|
||||
| `PhotoResource.java` | API REST photos |
|
||||
|
||||
---
|
||||
|
||||
## 📊 Modèle de données
|
||||
|
||||
```java
|
||||
@Entity
|
||||
@Table(name = "documents")
|
||||
public class Document extends PanacheEntityBase {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.UUID)
|
||||
private UUID id;
|
||||
|
||||
@Column(name = "nom", nullable = false)
|
||||
private String nom;
|
||||
|
||||
@Enumerated(EnumType.STRING)
|
||||
@Column(name = "type")
|
||||
private TypeDocument type;
|
||||
|
||||
@Column(name = "chemin_fichier", nullable = false)
|
||||
private String cheminFichier;
|
||||
|
||||
@Column(name = "taille_octets")
|
||||
private Long tailleOctets;
|
||||
|
||||
@Column(name = "mime_type")
|
||||
private String mimeType;
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "chantier_id")
|
||||
private Chantier chantier;
|
||||
|
||||
@Column(name = "description", length = 1000)
|
||||
private String description;
|
||||
|
||||
@Column(name = "date_upload")
|
||||
private LocalDateTime dateUpload;
|
||||
}
|
||||
```
|
||||
|
||||
### **Enum TypeDocument**
|
||||
|
||||
```java
|
||||
public enum TypeDocument {
|
||||
PLAN, // Plans architecturaux
|
||||
PERMIS_CONSTRUIRE, // Permis de construire
|
||||
RAPPORT_CHANTIER, // Rapports de chantier
|
||||
PHOTO_CHANTIER, // Photos de chantier
|
||||
CONTRAT, // Contrats
|
||||
DEVIS, // Devis
|
||||
FACTURE, // Factures
|
||||
CERTIFICAT, // Certificats
|
||||
AUTRE
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔌 API REST
|
||||
|
||||
### **Endpoints**
|
||||
|
||||
| Méthode | Endpoint | Description |
|
||||
|---------|----------|-------------|
|
||||
| GET | `/api/v1/documents` | Liste documents |
|
||||
| GET | `/api/v1/documents/{id}` | Détails |
|
||||
| POST | `/api/v1/documents/upload` | Upload document |
|
||||
| GET | `/api/v1/documents/{id}/download` | Télécharger |
|
||||
| DELETE | `/api/v1/documents/{id}` | Supprimer |
|
||||
| GET | `/api/v1/documents/chantier/{id}` | Par chantier |
|
||||
| GET | `/api/v1/documents/type/{type}` | Par type |
|
||||
|
||||
---
|
||||
|
||||
## 💻 Exemples
|
||||
|
||||
### **Upload document**
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:8080/api/v1/documents/upload \
|
||||
-F "file=@plan.pdf" \
|
||||
-F "nom=Plan RDC" \
|
||||
-F "type=PLAN" \
|
||||
-F "chantierId=chantier-uuid" \
|
||||
-F "description=Plan du rez-de-chaussée"
|
||||
```
|
||||
|
||||
### **Télécharger document**
|
||||
|
||||
```bash
|
||||
curl -X GET http://localhost:8080/api/v1/documents/{id}/download \
|
||||
--output document.pdf
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**Dernière mise à jour**: 2025-09-30
|
||||
**Version**: 1.0
|
||||
|
||||
114
docs/concepts/15-MESSAGE.md
Normal file
114
docs/concepts/15-MESSAGE.md
Normal file
@@ -0,0 +1,114 @@
|
||||
# 💬 CONCEPT: MESSAGE
|
||||
|
||||
## 📌 Vue d'ensemble
|
||||
|
||||
Le concept **MESSAGE** gère la messagerie interne entre utilisateurs avec catégorisation et priorités.
|
||||
|
||||
**Importance**: ⭐⭐ (Concept utile)
|
||||
|
||||
---
|
||||
|
||||
## 🗂️ Fichiers concernés
|
||||
|
||||
### **Entités JPA**
|
||||
| Fichier | Description |
|
||||
|---------|-------------|
|
||||
| `Message.java` | Entité principale message |
|
||||
| `TypeMessage.java` | Enum types (NORMAL, CHANTIER, MAINTENANCE, URGENT, etc.) |
|
||||
| `PrioriteMessage.java` | Enum priorités |
|
||||
|
||||
### **Services**
|
||||
| Fichier | Description |
|
||||
|---------|-------------|
|
||||
| `MessageService.java` | Service métier messages |
|
||||
|
||||
### **Resources**
|
||||
| Fichier | Description |
|
||||
|---------|-------------|
|
||||
| `MessageResource.java` | API REST messages |
|
||||
|
||||
---
|
||||
|
||||
## 📊 Modèle de données
|
||||
|
||||
```java
|
||||
@Entity
|
||||
@Table(name = "messages")
|
||||
public class Message extends PanacheEntityBase {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.UUID)
|
||||
private UUID id;
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "expediteur_id", nullable = false)
|
||||
private User expediteur;
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "destinataire_id", nullable = false)
|
||||
private User destinataire;
|
||||
|
||||
@Column(name = "sujet", nullable = false)
|
||||
private String sujet;
|
||||
|
||||
@Column(name = "contenu", length = 5000, nullable = false)
|
||||
private String contenu;
|
||||
|
||||
@Enumerated(EnumType.STRING)
|
||||
@Column(name = "type")
|
||||
private TypeMessage type;
|
||||
|
||||
@Enumerated(EnumType.STRING)
|
||||
@Column(name = "priorite")
|
||||
private PrioriteMessage priorite;
|
||||
|
||||
@Column(name = "lu")
|
||||
private Boolean lu = false;
|
||||
|
||||
@Column(name = "date_envoi")
|
||||
private LocalDateTime dateEnvoi;
|
||||
|
||||
@Column(name = "date_lecture")
|
||||
private LocalDateTime dateLecture;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔌 API REST
|
||||
|
||||
### **Endpoints**
|
||||
|
||||
| Méthode | Endpoint | Description |
|
||||
|---------|----------|-------------|
|
||||
| GET | `/api/v1/messages` | Liste messages |
|
||||
| GET | `/api/v1/messages/{id}` | Détails |
|
||||
| POST | `/api/v1/messages` | Envoyer |
|
||||
| PUT | `/api/v1/messages/{id}/lire` | Marquer comme lu |
|
||||
| DELETE | `/api/v1/messages/{id}` | Supprimer |
|
||||
| GET | `/api/v1/messages/recus` | Messages reçus |
|
||||
| GET | `/api/v1/messages/envoyes` | Messages envoyés |
|
||||
| GET | `/api/v1/messages/non-lus` | Messages non lus |
|
||||
|
||||
---
|
||||
|
||||
## 💻 Exemples
|
||||
|
||||
### **Envoyer un message**
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:8080/api/v1/messages \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"destinataireId": "user-uuid",
|
||||
"sujet": "Livraison matériel",
|
||||
"contenu": "La livraison de ciment est prévue demain à 9h",
|
||||
"type": "CHANTIER",
|
||||
"priorite": "NORMALE"
|
||||
}'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**Dernière mise à jour**: 2025-09-30
|
||||
**Version**: 1.0
|
||||
|
||||
109
docs/concepts/16-NOTIFICATION.md
Normal file
109
docs/concepts/16-NOTIFICATION.md
Normal file
@@ -0,0 +1,109 @@
|
||||
# 🔔 CONCEPT: NOTIFICATION
|
||||
|
||||
## 📌 Vue d'ensemble
|
||||
|
||||
Le concept **NOTIFICATION** gère les notifications système pour alerter les utilisateurs d'événements importants.
|
||||
|
||||
**Importance**: ⭐⭐ (Concept utile)
|
||||
|
||||
---
|
||||
|
||||
## 🗂️ Fichiers concernés
|
||||
|
||||
### **Entités JPA**
|
||||
| Fichier | Description |
|
||||
|---------|-------------|
|
||||
| `Notification.java` | Entité principale notification |
|
||||
| `TypeNotification.java` | Enum types |
|
||||
| `PrioriteNotification.java` | Enum priorités |
|
||||
|
||||
### **Services**
|
||||
| Fichier | Description |
|
||||
|---------|-------------|
|
||||
| `NotificationService.java` | Service métier notifications |
|
||||
|
||||
### **Resources**
|
||||
| Fichier | Description |
|
||||
|---------|-------------|
|
||||
| `NotificationResource.java` | API REST notifications |
|
||||
|
||||
---
|
||||
|
||||
## 📊 Modèle de données
|
||||
|
||||
```java
|
||||
@Entity
|
||||
@Table(name = "notifications")
|
||||
public class Notification extends PanacheEntityBase {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.UUID)
|
||||
private UUID id;
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "user_id", nullable = false)
|
||||
private User user;
|
||||
|
||||
@Column(name = "titre", nullable = false)
|
||||
private String titre;
|
||||
|
||||
@Column(name = "message", length = 1000)
|
||||
private String message;
|
||||
|
||||
@Enumerated(EnumType.STRING)
|
||||
@Column(name = "type")
|
||||
private TypeNotification type;
|
||||
|
||||
@Column(name = "lue")
|
||||
private Boolean lue = false;
|
||||
|
||||
@Column(name = "date_creation")
|
||||
private LocalDateTime dateCreation;
|
||||
|
||||
@Column(name = "date_lecture")
|
||||
private LocalDateTime dateLecture;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔌 API REST
|
||||
|
||||
### **Endpoints**
|
||||
|
||||
| Méthode | Endpoint | Description |
|
||||
|---------|----------|-------------|
|
||||
| GET | `/api/v1/notifications` | Liste notifications |
|
||||
| GET | `/api/v1/notifications/non-lues` | Non lues |
|
||||
| PUT | `/api/v1/notifications/{id}/lire` | Marquer comme lue |
|
||||
| PUT | `/api/v1/notifications/tout-lire` | Tout marquer comme lu |
|
||||
| DELETE | `/api/v1/notifications/{id}` | Supprimer |
|
||||
|
||||
---
|
||||
|
||||
## 💻 Exemples
|
||||
|
||||
### **Notifications non lues**
|
||||
|
||||
```bash
|
||||
curl -X GET http://localhost:8080/api/v1/notifications/non-lues
|
||||
```
|
||||
|
||||
**Réponse**:
|
||||
```json
|
||||
[
|
||||
{
|
||||
"id": "uuid",
|
||||
"titre": "Stock faible",
|
||||
"message": "Le stock de ciment est en dessous du seuil minimum",
|
||||
"type": "ALERTE",
|
||||
"lue": false,
|
||||
"dateCreation": "2025-09-30T10:00:00"
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**Dernière mise à jour**: 2025-09-30
|
||||
**Version**: 1.0
|
||||
|
||||
144
docs/concepts/17-USER.md
Normal file
144
docs/concepts/17-USER.md
Normal file
@@ -0,0 +1,144 @@
|
||||
# 👤 CONCEPT: USER
|
||||
|
||||
## 📌 Vue d'ensemble
|
||||
|
||||
Le concept **USER** gère les utilisateurs, authentification, rôles et permissions via Keycloak.
|
||||
|
||||
**Importance**: ⭐⭐⭐⭐⭐ (Concept fondamental)
|
||||
|
||||
---
|
||||
|
||||
## 🗂️ Fichiers concernés
|
||||
|
||||
### **Entités JPA**
|
||||
| Fichier | Description |
|
||||
|---------|-------------|
|
||||
| `User.java` | Entité principale utilisateur |
|
||||
| `UserRole.java` | Enum (ADMIN, MANAGER, CHEF_CHANTIER, COMPTABLE, OUVRIER) |
|
||||
| `UserStatus.java` | Enum (ACTIVE, INACTIVE, LOCKED, SUSPENDED) |
|
||||
| `Permission.java` | Enum permissions |
|
||||
|
||||
### **Services**
|
||||
| Fichier | Description |
|
||||
|---------|-------------|
|
||||
| `UserService.java` | Service métier utilisateurs |
|
||||
| `PermissionService.java` | Service permissions |
|
||||
|
||||
### **Resources**
|
||||
| Fichier | Description |
|
||||
|---------|-------------|
|
||||
| `UserResource.java` | API REST utilisateurs |
|
||||
| `AuthResource.java` | API authentification |
|
||||
|
||||
---
|
||||
|
||||
## 📊 Modèle de données
|
||||
|
||||
```java
|
||||
@Entity
|
||||
@Table(name = "users")
|
||||
public class User extends PanacheEntityBase {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.UUID)
|
||||
private UUID id;
|
||||
|
||||
@Column(name = "keycloak_id", unique = true)
|
||||
private String keycloakId;
|
||||
|
||||
@Column(name = "username", unique = true, nullable = false)
|
||||
private String username;
|
||||
|
||||
@Column(name = "email", unique = true, nullable = false)
|
||||
private String email;
|
||||
|
||||
@Column(name = "nom")
|
||||
private String nom;
|
||||
|
||||
@Column(name = "prenom")
|
||||
private String prenom;
|
||||
|
||||
@Enumerated(EnumType.STRING)
|
||||
@Column(name = "role")
|
||||
private UserRole role;
|
||||
|
||||
@Enumerated(EnumType.STRING)
|
||||
@Column(name = "status")
|
||||
private UserStatus status = UserStatus.ACTIVE;
|
||||
|
||||
@OneToOne
|
||||
@JoinColumn(name = "employe_id")
|
||||
private Employe employe;
|
||||
}
|
||||
```
|
||||
|
||||
### **Enum UserRole**
|
||||
|
||||
```java
|
||||
public enum UserRole {
|
||||
ADMIN, // Administrateur système
|
||||
MANAGER, // Manager/Directeur
|
||||
CHEF_CHANTIER, // Chef de chantier
|
||||
COMPTABLE, // Comptable
|
||||
OUVRIER // Ouvrier
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔌 API REST
|
||||
|
||||
### **Endpoints**
|
||||
|
||||
| Méthode | Endpoint | Description |
|
||||
|---------|----------|-------------|
|
||||
| GET | `/api/v1/users` | Liste utilisateurs |
|
||||
| GET | `/api/v1/users/{id}` | Détails |
|
||||
| POST | `/api/v1/users` | Créer |
|
||||
| PUT | `/api/v1/users/{id}` | Modifier |
|
||||
| DELETE | `/api/v1/users/{id}` | Supprimer |
|
||||
| GET | `/api/v1/users/me` | Utilisateur connecté |
|
||||
| POST | `/api/v1/auth/login` | Connexion |
|
||||
| POST | `/api/v1/auth/logout` | Déconnexion |
|
||||
|
||||
---
|
||||
|
||||
## 💻 Exemples
|
||||
|
||||
### **Créer un utilisateur**
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:8080/api/v1/users \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"username": "jdupont",
|
||||
"email": "jean.dupont@btpxpress.fr",
|
||||
"nom": "Dupont",
|
||||
"prenom": "Jean",
|
||||
"role": "CHEF_CHANTIER",
|
||||
"password": "SecurePass123!"
|
||||
}'
|
||||
```
|
||||
|
||||
### **Utilisateur connecté**
|
||||
|
||||
```bash
|
||||
curl -X GET http://localhost:8080/api/v1/users/me \
|
||||
-H "Authorization: Bearer $TOKEN"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔐 Authentification
|
||||
|
||||
L'authentification se fait via **Keycloak** avec OAuth2/OIDC :
|
||||
|
||||
1. L'utilisateur se connecte via Keycloak
|
||||
2. Keycloak retourne un JWT token
|
||||
3. Le token est envoyé dans le header `Authorization: Bearer <token>`
|
||||
4. Le backend valide le token auprès de Keycloak
|
||||
|
||||
---
|
||||
|
||||
**Dernière mise à jour**: 2025-09-30
|
||||
**Version**: 1.0
|
||||
|
||||
53
docs/concepts/18-ENTREPRISE.md
Normal file
53
docs/concepts/18-ENTREPRISE.md
Normal file
@@ -0,0 +1,53 @@
|
||||
# 🏢 CONCEPT: ENTREPRISE
|
||||
|
||||
## 📌 Vue d'ensemble
|
||||
|
||||
Le concept **ENTREPRISE** gère les profils d'entreprises BTP et leurs avis/évaluations.
|
||||
|
||||
**Importance**: ⭐⭐ (Concept secondaire)
|
||||
|
||||
---
|
||||
|
||||
## 🗂️ Fichiers concernés
|
||||
|
||||
### **Entités JPA**
|
||||
| Fichier | Description |
|
||||
|---------|-------------|
|
||||
| `EntrepriseProfile.java` | Profil entreprise |
|
||||
| `AvisEntreprise.java` | Avis sur entreprise |
|
||||
| `StatutAvis.java` | Enum (EN_ATTENTE, PUBLIE, REJETE, SIGNALE, ARCHIVE) |
|
||||
|
||||
---
|
||||
|
||||
## 📊 Modèle de données
|
||||
|
||||
```java
|
||||
@Entity
|
||||
@Table(name = "entreprises_profiles")
|
||||
public class EntrepriseProfile extends PanacheEntityBase {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.UUID)
|
||||
private UUID id;
|
||||
|
||||
@Column(name = "nom", nullable = false)
|
||||
private String nom;
|
||||
|
||||
@Column(name = "siret")
|
||||
private String siret;
|
||||
|
||||
@Column(name = "description", length = 2000)
|
||||
private String description;
|
||||
|
||||
@Column(name = "note_moyenne", precision = 3, scale = 2)
|
||||
private BigDecimal noteMoyenne;
|
||||
|
||||
@OneToMany(mappedBy = "entreprise")
|
||||
private List<AvisEntreprise> avis;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**Dernière mise à jour**: 2025-09-30
|
||||
**Version**: 1.0
|
||||
|
||||
65
docs/concepts/19-DISPONIBILITE.md
Normal file
65
docs/concepts/19-DISPONIBILITE.md
Normal file
@@ -0,0 +1,65 @@
|
||||
# 📆 CONCEPT: DISPONIBILITE
|
||||
|
||||
## 📌 Vue d'ensemble
|
||||
|
||||
Le concept **DISPONIBILITE** gère les disponibilités des employés et du matériel pour la planification.
|
||||
|
||||
**Importance**: ⭐⭐ (Concept secondaire)
|
||||
|
||||
---
|
||||
|
||||
## 🗂️ Fichiers concernés
|
||||
|
||||
### **Entités JPA**
|
||||
| Fichier | Description |
|
||||
|---------|-------------|
|
||||
| `DisponibiliteEmploye.java` | Disponibilité employé |
|
||||
| `DisponibiliteMateriel.java` | Disponibilité matériel |
|
||||
|
||||
---
|
||||
|
||||
## 📊 Modèle de données
|
||||
|
||||
```java
|
||||
@Entity
|
||||
@Table(name = "disponibilites_employe")
|
||||
public class DisponibiliteEmploye extends PanacheEntityBase {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.UUID)
|
||||
private UUID id;
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "employe_id", nullable = false)
|
||||
private Employe employe;
|
||||
|
||||
@Column(name = "date_debut", nullable = false)
|
||||
private LocalDate dateDebut;
|
||||
|
||||
@Column(name = "date_fin", nullable = false)
|
||||
private LocalDate dateFin;
|
||||
|
||||
@Column(name = "disponible", nullable = false)
|
||||
private Boolean disponible = true;
|
||||
|
||||
@Column(name = "motif", length = 500)
|
||||
private String motif;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔌 API REST
|
||||
|
||||
### **Endpoints**
|
||||
|
||||
| Méthode | Endpoint | Description |
|
||||
|---------|----------|-------------|
|
||||
| GET | `/api/v1/disponibilites/employe/{id}` | Disponibilités employé |
|
||||
| POST | `/api/v1/disponibilites/employe` | Créer disponibilité |
|
||||
| GET | `/api/v1/disponibilites/materiel/{id}` | Disponibilités matériel |
|
||||
|
||||
---
|
||||
|
||||
**Dernière mise à jour**: 2025-09-30
|
||||
**Version**: 1.0
|
||||
|
||||
78
docs/concepts/20-ZONE_CLIMATIQUE.md
Normal file
78
docs/concepts/20-ZONE_CLIMATIQUE.md
Normal file
@@ -0,0 +1,78 @@
|
||||
# 🌡️ CONCEPT: ZONE_CLIMATIQUE
|
||||
|
||||
## 📌 Vue d'ensemble
|
||||
|
||||
Le concept **ZONE_CLIMATIQUE** gère les zones climatiques pour adapter les matériaux et techniques de construction.
|
||||
|
||||
**Importance**: ⭐ (Concept spécialisé)
|
||||
|
||||
---
|
||||
|
||||
## 🗂️ Fichiers concernés
|
||||
|
||||
### **Entités JPA**
|
||||
| Fichier | Description |
|
||||
|---------|-------------|
|
||||
| `ZoneClimatique.java` | Zone climatique |
|
||||
| `TypeZoneClimatique.java` | Enum types |
|
||||
| `NiveauHumidite.java` | Enum niveaux humidité |
|
||||
|
||||
---
|
||||
|
||||
## 📊 Modèle de données
|
||||
|
||||
```java
|
||||
@Entity
|
||||
@Table(name = "zones_climatiques")
|
||||
public class ZoneClimatique extends PanacheEntityBase {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.UUID)
|
||||
private UUID id;
|
||||
|
||||
@Column(name = "nom", nullable = false)
|
||||
private String nom;
|
||||
|
||||
@Enumerated(EnumType.STRING)
|
||||
@Column(name = "type")
|
||||
private TypeZoneClimatique type;
|
||||
|
||||
@Column(name = "temperature_min")
|
||||
private BigDecimal temperatureMin;
|
||||
|
||||
@Column(name = "temperature_max")
|
||||
private BigDecimal temperatureMax;
|
||||
|
||||
@Enumerated(EnumType.STRING)
|
||||
@Column(name = "niveau_humidite")
|
||||
private NiveauHumidite niveauHumidite;
|
||||
}
|
||||
```
|
||||
|
||||
### **Enum TypeZoneClimatique**
|
||||
|
||||
```java
|
||||
public enum TypeZoneClimatique {
|
||||
OCEANIQUE,
|
||||
CONTINENTAL,
|
||||
MEDITERRANEEN,
|
||||
MONTAGNARD,
|
||||
TROPICAL
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔌 API REST
|
||||
|
||||
### **Endpoints**
|
||||
|
||||
| Méthode | Endpoint | Description |
|
||||
|---------|----------|-------------|
|
||||
| GET | `/api/v1/zones-climatiques` | Liste zones |
|
||||
| GET | `/api/v1/zones-climatiques/{id}` | Détails |
|
||||
|
||||
---
|
||||
|
||||
**Dernière mise à jour**: 2025-09-30
|
||||
**Version**: 1.0
|
||||
|
||||
80
docs/concepts/21-ABONNEMENT.md
Normal file
80
docs/concepts/21-ABONNEMENT.md
Normal file
@@ -0,0 +1,80 @@
|
||||
# 💳 CONCEPT: ABONNEMENT
|
||||
|
||||
## 📌 Vue d'ensemble
|
||||
|
||||
Le concept **ABONNEMENT** gère les abonnements et plans tarifaires pour les entreprises utilisant BTPXpress.
|
||||
|
||||
**Importance**: ⭐⭐ (Concept commercial)
|
||||
|
||||
---
|
||||
|
||||
## 🗂️ Fichiers concernés
|
||||
|
||||
### **Entités JPA**
|
||||
| Fichier | Description |
|
||||
|---------|-------------|
|
||||
| `Abonnement.java` | Entité abonnement |
|
||||
|
||||
---
|
||||
|
||||
## 📊 Modèle de données
|
||||
|
||||
```java
|
||||
@Entity
|
||||
@Table(name = "abonnements")
|
||||
public class Abonnement extends PanacheEntityBase {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.UUID)
|
||||
private UUID id;
|
||||
|
||||
@Column(name = "nom_plan", nullable = false)
|
||||
private String nomPlan;
|
||||
|
||||
@Column(name = "prix_mensuel", precision = 10, scale = 2)
|
||||
private BigDecimal prixMensuel;
|
||||
|
||||
@Column(name = "date_debut", nullable = false)
|
||||
private LocalDate dateDebut;
|
||||
|
||||
@Column(name = "date_fin")
|
||||
private LocalDate dateFin;
|
||||
|
||||
@Column(name = "actif")
|
||||
private Boolean actif = true;
|
||||
|
||||
@Column(name = "nombre_utilisateurs_max")
|
||||
private Integer nombreUtilisateursMax;
|
||||
|
||||
@Column(name = "nombre_chantiers_max")
|
||||
private Integer nombreChantiersMax;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔌 API REST
|
||||
|
||||
### **Endpoints**
|
||||
|
||||
| Méthode | Endpoint | Description |
|
||||
|---------|----------|-------------|
|
||||
| GET | `/api/v1/abonnements` | Liste abonnements |
|
||||
| GET | `/api/v1/abonnements/{id}` | Détails |
|
||||
| POST | `/api/v1/abonnements` | Créer |
|
||||
| PUT | `/api/v1/abonnements/{id}` | Modifier |
|
||||
|
||||
---
|
||||
|
||||
## 💻 Plans disponibles
|
||||
|
||||
| Plan | Prix/mois | Utilisateurs | Chantiers |
|
||||
|------|-----------|--------------|-----------|
|
||||
| STARTER | 49€ | 3 | 5 |
|
||||
| BUSINESS | 99€ | 10 | 20 |
|
||||
| ENTERPRISE | 199€ | Illimité | Illimité |
|
||||
|
||||
---
|
||||
|
||||
**Dernière mise à jour**: 2025-09-30
|
||||
**Version**: 1.0
|
||||
|
||||
237
docs/concepts/22-SERVICES_TRANSVERSES.md
Normal file
237
docs/concepts/22-SERVICES_TRANSVERSES.md
Normal file
@@ -0,0 +1,237 @@
|
||||
# ⚙️ CONCEPT: SERVICES_TRANSVERSES
|
||||
|
||||
## 📌 Vue d'ensemble
|
||||
|
||||
Le concept **SERVICES_TRANSVERSES** regroupe les services utilitaires et techniques utilisés par l'ensemble de l'application.
|
||||
|
||||
**Importance**: ⭐⭐⭐ (Concept technique)
|
||||
|
||||
---
|
||||
|
||||
## 🗂️ Fichiers concernés
|
||||
|
||||
### **Services** (`application/service/`)
|
||||
| Fichier | Description |
|
||||
|---------|-------------|
|
||||
| `EmailService.java` | Service d'envoi d'emails |
|
||||
| `PdfGeneratorService.java` | Génération de PDF |
|
||||
| `ExportService.java` | Export de données (Excel, CSV) |
|
||||
| `ImportService.java` | Import de données |
|
||||
|
||||
---
|
||||
|
||||
## 📊 Services disponibles
|
||||
|
||||
### **1. EmailService**
|
||||
|
||||
Service d'envoi d'emails transactionnels et notifications.
|
||||
|
||||
**Méthodes principales**:
|
||||
```java
|
||||
public class EmailService {
|
||||
void sendEmail(String to, String subject, String body);
|
||||
void sendEmailWithAttachment(String to, String subject, String body, File attachment);
|
||||
void sendTemplateEmail(String to, String templateName, Map<String, Object> variables);
|
||||
}
|
||||
```
|
||||
|
||||
**Exemples d'utilisation**:
|
||||
- Envoi de devis par email
|
||||
- Notifications de livraison
|
||||
- Alertes de stock faible
|
||||
- Rappels de maintenance
|
||||
|
||||
---
|
||||
|
||||
### **2. PdfGeneratorService**
|
||||
|
||||
Service de génération de documents PDF.
|
||||
|
||||
**Méthodes principales**:
|
||||
```java
|
||||
public class PdfGeneratorService {
|
||||
byte[] genererDevisPdf(UUID devisId);
|
||||
byte[] genererFacturePdf(UUID factureId);
|
||||
byte[] genererBonCommandePdf(UUID bonCommandeId);
|
||||
byte[] genererRapportChantierPdf(UUID chantierId);
|
||||
}
|
||||
```
|
||||
|
||||
**Technologies utilisées**:
|
||||
- iText ou Apache PDFBox
|
||||
- Templates HTML/CSS convertis en PDF
|
||||
- Génération de graphiques et tableaux
|
||||
|
||||
---
|
||||
|
||||
### **3. ExportService**
|
||||
|
||||
Service d'export de données vers différents formats.
|
||||
|
||||
**Méthodes principales**:
|
||||
```java
|
||||
public class ExportService {
|
||||
byte[] exportToExcel(List<?> data, String sheetName);
|
||||
byte[] exportToCsv(List<?> data);
|
||||
byte[] exportToJson(List<?> data);
|
||||
}
|
||||
```
|
||||
|
||||
**Cas d'usage**:
|
||||
- Export liste de chantiers
|
||||
- Export inventaire matériel
|
||||
- Export historique factures
|
||||
- Export planning mensuel
|
||||
|
||||
---
|
||||
|
||||
### **4. ImportService**
|
||||
|
||||
Service d'import de données depuis fichiers externes.
|
||||
|
||||
**Méthodes principales**:
|
||||
```java
|
||||
public class ImportService {
|
||||
ImportResult importFromExcel(MultipartFile file, String entityType);
|
||||
ImportResult importFromCsv(MultipartFile file, String entityType);
|
||||
ValidationResult validateImportData(List<?> data);
|
||||
}
|
||||
```
|
||||
|
||||
**Fonctionnalités**:
|
||||
- Import en masse de matériel
|
||||
- Import de clients
|
||||
- Import de fournisseurs
|
||||
- Validation des données avant import
|
||||
|
||||
---
|
||||
|
||||
## 🔌 API REST
|
||||
|
||||
### **Endpoints Export**
|
||||
|
||||
| Méthode | Endpoint | Description |
|
||||
|---------|----------|-------------|
|
||||
| GET | `/api/v1/export/chantiers/excel` | Export chantiers Excel |
|
||||
| GET | `/api/v1/export/materiels/csv` | Export matériel CSV |
|
||||
| GET | `/api/v1/export/factures/pdf` | Export factures PDF |
|
||||
|
||||
### **Endpoints Import**
|
||||
|
||||
| Méthode | Endpoint | Description |
|
||||
|---------|----------|-------------|
|
||||
| POST | `/api/v1/import/materiels` | Import matériel |
|
||||
| POST | `/api/v1/import/clients` | Import clients |
|
||||
| POST | `/api/v1/import/validate` | Valider données |
|
||||
|
||||
---
|
||||
|
||||
## 💻 Exemples
|
||||
|
||||
### **Export Excel**
|
||||
|
||||
```bash
|
||||
curl -X GET http://localhost:8080/api/v1/export/chantiers/excel \
|
||||
-H "Accept: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" \
|
||||
--output chantiers.xlsx
|
||||
```
|
||||
|
||||
### **Import matériel**
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:8080/api/v1/import/materiels \
|
||||
-F "file=@materiels.xlsx" \
|
||||
-F "validateOnly=false"
|
||||
```
|
||||
|
||||
**Réponse**:
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"totalRows": 150,
|
||||
"imported": 145,
|
||||
"errors": 5,
|
||||
"errorDetails": [
|
||||
{
|
||||
"row": 12,
|
||||
"error": "Référence déjà existante"
|
||||
},
|
||||
{
|
||||
"row": 45,
|
||||
"error": "Type de matériel invalide"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔧 Configuration
|
||||
|
||||
### **Email (application.properties)**
|
||||
|
||||
```properties
|
||||
# Configuration SMTP
|
||||
quarkus.mailer.host=smtp.gmail.com
|
||||
quarkus.mailer.port=587
|
||||
quarkus.mailer.username=noreply@btpxpress.fr
|
||||
quarkus.mailer.password=${SMTP_PASSWORD}
|
||||
quarkus.mailer.from=noreply@btpxpress.fr
|
||||
quarkus.mailer.tls=true
|
||||
```
|
||||
|
||||
### **PDF Generator**
|
||||
|
||||
```properties
|
||||
# Configuration PDF
|
||||
pdf.generator.font.path=/fonts/
|
||||
pdf.generator.logo.path=/images/logo.png
|
||||
pdf.generator.template.path=/templates/pdf/
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📈 Utilisation
|
||||
|
||||
Ces services sont utilisés par de nombreux concepts :
|
||||
|
||||
- **DEVIS** ➡️ PdfGeneratorService, EmailService
|
||||
- **FACTURE** ➡️ PdfGeneratorService, EmailService
|
||||
- **BON_COMMANDE** ➡️ PdfGeneratorService, EmailService
|
||||
- **MATERIEL** ➡️ ExportService, ImportService
|
||||
- **CHANTIER** ➡️ ExportService, PdfGeneratorService
|
||||
- **NOTIFICATION** ➡️ EmailService
|
||||
|
||||
---
|
||||
|
||||
## ✅ Bonnes pratiques
|
||||
|
||||
### **Gestion des erreurs**
|
||||
- Validation des données avant traitement
|
||||
- Logs détaillés des erreurs
|
||||
- Retry automatique pour les emails
|
||||
|
||||
### **Performance**
|
||||
- Génération asynchrone des PDF volumineux
|
||||
- Cache des templates
|
||||
- Compression des exports
|
||||
|
||||
### **Sécurité**
|
||||
- Validation des fichiers uploadés
|
||||
- Limitation de la taille des fichiers
|
||||
- Scan antivirus des uploads
|
||||
|
||||
---
|
||||
|
||||
## 📚 Références
|
||||
|
||||
- [Configuration Quarkus Mailer](https://quarkus.io/guides/mailer)
|
||||
- [iText PDF Library](https://itextpdf.com/)
|
||||
- [Apache POI (Excel)](https://poi.apache.org/)
|
||||
|
||||
---
|
||||
|
||||
**Dernière mise à jour**: 2025-09-30
|
||||
**Version**: 1.0
|
||||
**Auteur**: Documentation BTPXpress
|
||||
|
||||
Reference in New Issue
Block a user