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