feat(frontend): module Achats complet (commandes, réception, stock)

- Modèles Fournisseur, PurchaseOrder, PurchaseOrderLine
- FournisseurService + PurchaseOrderService (create, receive)
- AchatsProvider : chargement parallèle commandes + fournisseurs
- AchatsScreen : liste avec badges statut colorés (violet)
- PurchaseOrderFormScreen : lignes dynamiques, calcul HT/TVA/TTC
- PurchaseOrderDetailScreen : détail + bouton Réceptionner
- Réception → entrée stock automatique via backend

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-20 20:35:41 +01:00
co-authored by Claude Sonnet 4.6
parent c3278327e9
commit 0811013abe
9 changed files with 1089 additions and 1 deletions
+55
View File
@@ -0,0 +1,55 @@
class Fournisseur {
final int? id;
final String raisonSociale;
final String? matriculeFiscal;
final String? telephone;
final String? email;
final String? adresse;
final String? ville;
final String? pays;
final String? categorieProduit;
final String? modePaiement;
final bool actif;
Fournisseur({
this.id,
required this.raisonSociale,
this.matriculeFiscal,
this.telephone,
this.email,
this.adresse,
this.ville,
this.pays = 'Tunisie',
this.categorieProduit,
this.modePaiement,
this.actif = true,
});
factory Fournisseur.fromJson(Map<String, dynamic> json) => Fournisseur(
id: json['id'],
raisonSociale: json['raisonSociale'] ?? '',
matriculeFiscal: json['matriculeFiscal'],
telephone: json['telephone'],
email: json['email'],
adresse: json['adresse'],
ville: json['ville'],
pays: json['pays'] ?? 'Tunisie',
categorieProduit: json['categorieProduit'],
modePaiement: json['modePaiement'],
actif: json['actif'] ?? true,
);
Map<String, dynamic> toJson() => {
if (id != null) 'id': id,
'raisonSociale': raisonSociale,
if (matriculeFiscal != null) 'matriculeFiscal': matriculeFiscal,
if (telephone != null) 'telephone': telephone,
if (email != null) 'email': email,
if (adresse != null) 'adresse': adresse,
if (ville != null) 'ville': ville,
'pays': pays ?? 'Tunisie',
if (categorieProduit != null) 'categorieProduit': categorieProduit,
if (modePaiement != null) 'modePaiement': modePaiement,
'actif': actif,
};
}