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.
 
 
 
 
 
 

325 lines
9.1 KiB

// models/commande_detail.dart
class CommandeDetail {
final int id;
final int clientId;
final int tableId;
final int? reservationId;
final String numeroCommande;
final String statut;
final double totalHt;
final double totalTva;
final double totalTtc;
final String? modePaiement;
final String? commentaires;
final String serveur;
final DateTime dateCommande;
final DateTime? dateService;
final DateTime createdAt;
final DateTime updatedAt;
final List<CommandeItem> items;
CommandeDetail({
required this.id,
required this.clientId,
required this.tableId,
this.reservationId,
required this.numeroCommande,
required this.statut,
required this.totalHt,
required this.totalTva,
required this.totalTtc,
this.modePaiement,
this.commentaires,
required this.serveur,
required this.dateCommande,
this.dateService,
required this.createdAt,
required this.updatedAt,
required this.items,
});
factory CommandeDetail.fromJson(Map<String, dynamic> json) {
// Gérer les cas où les données sont dans "data" ou directement dans json
final data = json['data'] ?? json;
return CommandeDetail(
id: data['id'] ?? 0,
clientId: data['client_id'] ?? 0,
tableId: data['table_id'] ?? 0,
reservationId: data['reservation_id'],
numeroCommande: data['numero_commande'] ?? '',
statut: data['statut'] ?? 'en_cours',
totalHt: double.tryParse(data['total_ht']?.toString() ?? '0') ?? 0.0,
totalTva: double.tryParse(data['total_tva']?.toString() ?? '0') ?? 0.0,
totalTtc: double.tryParse(data['total_ttc']?.toString() ?? '0') ?? 0.0,
modePaiement: data['mode_paiement'],
commentaires: data['commentaires'],
serveur: data['serveur'] ?? 'Serveur par défaut',
dateCommande:
data['date_commande'] != null
? DateTime.parse(data['date_commande'])
: DateTime.now(),
dateService:
data['date_service'] != null
? DateTime.parse(data['date_service'])
: null,
createdAt:
data['created_at'] != null
? DateTime.parse(data['created_at'])
: DateTime.now(),
updatedAt:
data['updated_at'] != null
? DateTime.parse(data['updated_at'])
: DateTime.now(),
items:
(data['items'] as List<dynamic>?)
?.map((item) => CommandeItem.fromJson(item))
.toList() ??
[],
);
}
Map<String, dynamic> toJson() {
return {
'id': id,
'client_id': clientId,
'table_id': tableId,
'reservation_id': reservationId,
'numero_commande': numeroCommande,
'statut': statut,
'total_ht': totalHt.toString(),
'total_tva': totalTva.toString(),
'total_ttc': totalTtc.toString(),
'mode_paiement': modePaiement,
'commentaires': commentaires,
'serveur': serveur,
'date_commande': dateCommande.toIso8601String(),
'date_service': dateService?.toIso8601String(),
'created_at': createdAt.toIso8601String(),
'updated_at': updatedAt.toIso8601String(),
'items': items.map((item) => item.toJson()).toList(),
};
}
// Getters pour la compatibilité avec l'ancien code
String get commandeId => id.toString();
int get tableNumber => tableId;
double get total => totalTtc;
// Méthodes utilitaires
bool get isPaid => statut.toLowerCase() == 'payee';
bool get isInProgress => statut.toLowerCase() == 'en_cours';
bool get isReady => statut.toLowerCase() == 'pret';
bool get isCanceled => statut.toLowerCase() == 'annulee';
String get statutText {
switch (statut.toLowerCase()) {
case 'payee':
return 'Payée';
case 'en_cours':
return 'En cours';
case 'pret':
return 'Prête';
case 'annulee':
return 'Annulée';
case 'servie':
return 'Servie';
default:
return statut;
}
}
String get statutColor {
switch (statut.toLowerCase()) {
case 'payee':
return '#28A745'; // Vert
case 'en_cours':
return '#FFC107'; // Jaune
case 'pret':
return '#17A2B8'; // Bleu
case 'annulee':
return '#DC3545'; // Rouge
case 'servie':
return '#6F42C1'; // Violet
default:
return '#6C757D'; // Gris
}
}
// Calculs
double get totalItems => items.fold(0, (sum, item) => sum + item.totalItem);
int get totalQuantity => items.fold(0, (sum, item) => sum + item.quantite);
@override
String toString() {
return 'CommandeDetail{id: $id, numeroCommande: $numeroCommande, statut: $statut, totalTtc: $totalTtc}';
}
}
class CommandeItem {
final int id;
final int commandeId;
final int menuId;
final int quantite;
final double prixUnitaire;
final double totalItem;
final String? commentaires;
final String statut;
final DateTime createdAt;
final DateTime updatedAt;
final String menuNom;
final String? menuDescription;
final double menuPrixActuel;
CommandeItem({
required this.id,
required this.commandeId,
required this.menuId,
required this.quantite,
required this.prixUnitaire,
required this.totalItem,
this.commentaires,
required this.statut,
required this.createdAt,
required this.updatedAt,
required this.menuNom,
this.menuDescription,
required this.menuPrixActuel,
});
factory CommandeItem.fromJson(Map<String, dynamic> json) {
return CommandeItem(
id: json['id'] ?? 0,
commandeId: json['commande_id'] ?? 0,
menuId: json['menu_id'] ?? 0,
quantite: json['quantite'] ?? 1,
prixUnitaire:
double.tryParse(json['prix_unitaire']?.toString() ?? '0') ?? 0.0,
totalItem: double.tryParse(json['total_item']?.toString() ?? '0') ?? 0.0,
commentaires: json['commentaires'],
statut: json['statut'] ?? 'commande',
createdAt:
json['created_at'] != null
? DateTime.parse(json['created_at'])
: DateTime.now(),
updatedAt:
json['updated_at'] != null
? DateTime.parse(json['updated_at'])
: DateTime.now(),
menuNom: json['menu_nom'] ?? json['name'] ?? 'Article inconnu',
menuDescription: json['menu_description'] ?? json['description'],
menuPrixActuel:
double.tryParse(json['menu_prix_actuel']?.toString() ?? '0') ?? 0.0,
);
}
Map<String, dynamic> toJson() {
return {
'id': id,
'commande_id': commandeId,
'menu_id': menuId,
'quantite': quantite,
'prix_unitaire': prixUnitaire.toString(),
'total_item': totalItem.toString(),
'commentaires': commentaires,
'statut': statut,
'created_at': createdAt.toIso8601String(),
'updated_at': updatedAt.toIso8601String(),
'menu_nom': menuNom,
'menu_description': menuDescription,
'menu_prix_actuel': menuPrixActuel.toString(),
};
}
// Getters pour la compatibilité avec l'ancien code
String get name => menuNom;
int get quantity => quantite;
double get price => prixUnitaire;
// Méthodes utilitaires
String get statutText {
switch (statut.toLowerCase()) {
case 'commande':
return 'Commandé';
case 'preparation':
return 'En préparation';
case 'pret':
return 'Prêt';
case 'servi':
return 'Servi';
default:
return statut;
}
}
String get displayText => '$quantite× $menuNom';
bool get hasComments => commentaires != null && commentaires!.isNotEmpty;
@override
String toString() {
return 'CommandeItem{id: $id, menuNom: $menuNom, quantite: $quantite, totalItem: $totalItem}';
}
}
// Énumération pour les statuts de commande
enum CommandeStatut {
enCours('en_cours', 'En cours'),
pret('pret', 'Prête'),
servie('servie', 'Servie'),
payee('payee', 'Payée'),
annulee('annulee', 'Annulée');
const CommandeStatut(this.value, this.displayName);
final String value;
final String displayName;
static CommandeStatut fromString(String status) {
return CommandeStatut.values.firstWhere(
(e) => e.value == status.toLowerCase(),
orElse: () => CommandeStatut.enCours,
);
}
}
// Énumération pour les statuts d'items
enum ItemStatut {
commande('commande', 'Commandé'),
preparation('preparation', 'En préparation'),
pret('pret', 'Prêt'),
servi('servi', 'Servi');
const ItemStatut(this.value, this.displayName);
final String value;
final String displayName;
static ItemStatut fromString(String status) {
return ItemStatut.values.firstWhere(
(e) => e.value == status.toLowerCase(),
orElse: () => ItemStatut.commande,
);
}
}
// Classe de réponse API pour wrapper les données
class CommandeDetailResponse {
final bool success;
final CommandeDetail data;
final String? message;
CommandeDetailResponse({
required this.success,
required this.data,
this.message,
});
factory CommandeDetailResponse.fromJson(Map<String, dynamic> json) {
return CommandeDetailResponse(
success: json['success'] ?? false,
data: CommandeDetail.fromJson(json),
message: json['message'],
);
}
}