279 lines
6.5 KiB
Markdown
279 lines
6.5 KiB
Markdown
# 💰 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
|
|
|