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
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;
|
|
}
|
|
}
|