You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

342 lines
9.6 KiB

// Models/client.dart - Version corrigée pour MySQL
class Client {
final int? id;
final String nom;
final String prenom;
final String email;
final String telephone;
final String? adresse;
final DateTime dateCreation;
final bool actif;
Client({
this.id,
required this.nom,
required this.prenom,
required this.email,
required this.telephone,
this.adresse,
required this.dateCreation,
this.actif = true,
});
Map<String, dynamic> toMap() {
return {
'id': id,
'nom': nom,
'prenom': prenom,
'email': email,
'telephone': telephone,
'adresse': adresse,
'dateCreation': dateCreation.toIso8601String(),
'actif': actif ? 1 : 0,
};
}
// Fonction helper améliorée pour parser les dates
static DateTime _parseDateTime(dynamic dateValue) {
if (dateValue == null) return DateTime.now();
if (dateValue is DateTime) return dateValue;
if (dateValue is String) {
try {
return DateTime.parse(dateValue);
} catch (e) {
print("Erreur parsing date string: $dateValue, erreur: $e");
return DateTime.now();
}
}
// Pour MySQL qui peut retourner un Timestamp
if (dateValue is int) {
return DateTime.fromMillisecondsSinceEpoch(dateValue);
}
print("Type de date non reconnu: ${dateValue.runtimeType}, valeur: $dateValue");
return DateTime.now();
}
factory Client.fromMap(Map<String, dynamic> map) {
return Client(
id: map['id'] as int?,
nom: map['nom'] as String,
prenom: map['prenom'] as String,
email: map['email'] as String,
telephone: map['telephone'] as String,
adresse: map['adresse'] as String?,
dateCreation: _parseDateTime(map['dateCreation']),
actif: (map['actif'] as int?) == 1,
);
}
String get nomComplet => '$prenom $nom';
}
enum StatutCommande {
enAttente,
confirmee,
annulee
}
class Commande {
final int? id;
final int clientId;
final DateTime dateCommande;
final StatutCommande statut;
final double montantTotal;
final String? notes;
final DateTime? dateLivraison;
final int? commandeurId;
final int? validateurId;
final String? clientNom;
final String? clientPrenom;
final String? clientEmail;
final double? remisePourcentage;
final double? remiseMontant;
final double? montantApresRemise;
Commande({
this.id,
required this.clientId,
required this.dateCommande,
required this.statut,
required this.montantTotal,
this.notes,
this.dateLivraison,
this.commandeurId,
this.validateurId,
this.clientNom,
this.clientPrenom,
this.clientEmail,
this.remisePourcentage,
this.remiseMontant,
this.montantApresRemise,
});
String get clientNomComplet {
if (clientNom != null && clientPrenom != null) {
return '$clientPrenom $clientNom';
}
return 'Client inconnu';
}
String get statutLibelle {
switch (statut) {
case StatutCommande.enAttente:
return 'En attente';
case StatutCommande.confirmee:
return 'Confirmée';
case StatutCommande.annulee:
return 'Annulée';
}
}
Map<String, dynamic> toMap() {
return {
'id': id,
'clientId': clientId,
'dateCommande': dateCommande.toIso8601String(),
'statut': statut.index,
'montantTotal': montantTotal,
'notes': notes,
'dateLivraison': dateLivraison?.toIso8601String(),
'commandeurId': commandeurId,
'validateurId': validateurId,
'remisePourcentage': remisePourcentage,
'remiseMontant': remiseMontant,
'montantApresRemise': montantApresRemise,
};
}
factory Commande.fromMap(Map<String, dynamic> map) {
return Commande(
id: map['id'] as int?,
clientId: map['clientId'] as int,
dateCommande: Client._parseDateTime(map['dateCommande']),
statut: StatutCommande.values[(map['statut'] as int)],
montantTotal: (map['montantTotal'] as num).toDouble(),
notes: map['notes'] as String?,
dateLivraison: map['dateLivraison'] != null
? Client._parseDateTime(map['dateLivraison'])
: null,
commandeurId: map['commandeurId'] as int?,
validateurId: map['validateurId'] as int?,
clientNom: map['clientNom'] as String?,
clientPrenom: map['clientPrenom'] as String?,
clientEmail: map['clientEmail'] as String?,
remisePourcentage: map['remisePourcentage'] != null
? (map['remisePourcentage'] as num).toDouble()
: null,
remiseMontant: map['remiseMontant'] != null
? (map['remiseMontant'] as num).toDouble()
: null,
montantApresRemise: map['montantApresRemise'] != null
? (map['montantApresRemise'] as num).toDouble()
: null,
);
}
Commande copyWith({
int? id,
int? clientId,
DateTime? dateCommande,
StatutCommande? statut,
double? montantTotal,
String? notes,
DateTime? dateLivraison,
int? commandeurId,
int? validateurId,
String? clientNom,
String? clientPrenom,
String? clientEmail,
double? remisePourcentage,
double? remiseMontant,
double? montantApresRemise,
}) {
return Commande(
id: id ?? this.id,
clientId: clientId ?? this.clientId,
dateCommande: dateCommande ?? this.dateCommande,
statut: statut ?? this.statut,
montantTotal: montantTotal ?? this.montantTotal,
notes: notes ?? this.notes,
dateLivraison: dateLivraison ?? this.dateLivraison,
commandeurId: commandeurId ?? this.commandeurId,
validateurId: validateurId ?? this.validateurId,
clientNom: clientNom ?? this.clientNom,
clientPrenom: clientPrenom ?? this.clientPrenom,
clientEmail: clientEmail ?? this.clientEmail,
remisePourcentage: remisePourcentage ?? this.remisePourcentage,
remiseMontant: remiseMontant ?? this.remiseMontant,
montantApresRemise: montantApresRemise ?? this.montantApresRemise,
);
}
}
// REMPLACEZ COMPLÈTEMENT votre classe DetailCommande dans Models/client.dart par celle-ci :
class DetailCommande {
final int? id;
final int commandeId;
final int produitId;
final int quantite;
final double prixUnitaire;
final double sousTotal;
final String? produitNom;
final String? produitImage;
final String? produitReference;
final bool? estCadeau;
// NOUVEAUX CHAMPS POUR LA REMISE PAR PRODUIT
final double? remisePourcentage;
final double? remiseMontant;
final double? prixApresRemise;
DetailCommande({
this.id,
required this.commandeId,
required this.produitId,
required this.quantite,
required this.prixUnitaire,
required this.sousTotal,
this.produitNom,
this.produitImage,
this.produitReference,
this.estCadeau,
this.remisePourcentage,
this.remiseMontant,
this.prixApresRemise,
});
Map<String, dynamic> toMap() {
return {
'id': id,
'commandeId': commandeId,
'produitId': produitId,
'quantite': quantite,
'prixUnitaire': prixUnitaire,
'sousTotal': sousTotal,
'estCadeau': estCadeau == true ? 1 : 0,
'remisePourcentage': remisePourcentage,
'remiseMontant': remiseMontant,
'prixApresRemise': prixApresRemise,
};
}
factory DetailCommande.fromMap(Map<String, dynamic> map) {
return DetailCommande(
id: map['id'] as int?,
commandeId: map['commandeId'] as int,
produitId: map['produitId'] as int,
quantite: map['quantite'] as int,
prixUnitaire: (map['prixUnitaire'] as num).toDouble(),
sousTotal: (map['sousTotal'] as num).toDouble(),
produitNom: map['produitNom'] as String?,
produitImage: map['produitImage'] as String?,
produitReference: map['produitReference'] as String?,
estCadeau: map['estCadeau'] == 1,
remisePourcentage: map['remisePourcentage'] != null
? (map['remisePourcentage'] as num).toDouble()
: null,
remiseMontant: map['remiseMontant'] != null
? (map['remiseMontant'] as num).toDouble()
: null,
prixApresRemise: map['prixApresRemise'] != null
? (map['prixApresRemise'] as num).toDouble()
: null,
);
}
DetailCommande copyWith({
int? id,
int? commandeId,
int? produitId,
int? quantite,
double? prixUnitaire,
double? sousTotal,
String? produitNom,
String? produitImage,
String? produitReference,
bool? estCadeau,
double? remisePourcentage,
double? remiseMontant,
double? prixApresRemise,
}) {
return DetailCommande(
id: id ?? this.id,
commandeId: commandeId ?? this.commandeId,
produitId: produitId ?? this.produitId,
quantite: quantite ?? this.quantite,
prixUnitaire: prixUnitaire ?? this.prixUnitaire,
sousTotal: sousTotal ?? this.sousTotal,
produitNom: produitNom ?? this.produitNom,
produitImage: produitImage ?? this.produitImage,
produitReference: produitReference ?? this.produitReference,
estCadeau: estCadeau ?? this.estCadeau,
remisePourcentage: remisePourcentage ?? this.remisePourcentage,
remiseMontant: remiseMontant ?? this.remiseMontant,
prixApresRemise: prixApresRemise ?? this.prixApresRemise,
);
}
// GETTERS QUI RÉSOLVENT LE PROBLÈME "aUneRemise" INTROUVABLE
double get prixFinalUnitaire {
return prixApresRemise ?? prixUnitaire;
}
double get sousTotalAvecRemise {
return quantite * prixFinalUnitaire;
}
bool get aUneRemise {
return remisePourcentage != null || remiseMontant != null || prixApresRemise != null;
}
double get montantRemise {
if (prixApresRemise != null) {
return (prixUnitaire - prixApresRemise!) * quantite;
}
return 0.0;
}
}