6.5 KiB
6.5 KiB
💰 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
@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
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
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:
{
"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
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
curl -X GET http://localhost:8080/api/v1/devis/{id}/pdf \
-H "Accept: application/pdf" \
--output devis.pdf
Créer facture depuis devis
curl -X POST http://localhost:8080/api/v1/factures/depuis-devis/{devisId}
🔧 Services métier
DevisService
Méthodes principales:
create(DevisDTO)- Créer deviscalculerMontants(UUID id)- Calculer HT/TVA/TTCenvoyer(UUID id)- Envoyer au clientaccepter(UUID id)- Accepterrefuser(UUID id)- RefusergenererPDF(UUID id)- Générer PDF
FactureService
Méthodes principales:
create(FactureDTO)- Créer facturecreerDepuisDevis(UUID devisId)- Créer depuis devisgenererPDF(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
Dernière mise à jour: 2025-09-30
Version: 1.0