|
|
|
@ -27,7 +27,8 @@ class _GestionCommandesPageState extends State<GestionCommandesPage> { |
|
|
|
StatutCommande? _selectedStatut; |
|
|
|
DateTime? _selectedDate; |
|
|
|
final TextEditingController _searchController = TextEditingController(); |
|
|
|
bool _showCancelledOrders = false; // Nouveau: contrôle l'affichage des commandes annulées |
|
|
|
bool _showCancelledOrders = |
|
|
|
false; // Nouveau: contrôle l'affichage des commandes annulées |
|
|
|
|
|
|
|
@override |
|
|
|
void initState() { |
|
|
|
@ -43,6 +44,7 @@ class _GestionCommandesPageState extends State<GestionCommandesPage> { |
|
|
|
_filterCommandes(); |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
Future<Uint8List> loadImage() async { |
|
|
|
final data = await rootBundle.load('assets/youmaz2.png'); |
|
|
|
return data.buffer.asUint8List(); |
|
|
|
@ -52,17 +54,23 @@ class _GestionCommandesPageState extends State<GestionCommandesPage> { |
|
|
|
final query = _searchController.text.toLowerCase(); |
|
|
|
setState(() { |
|
|
|
_filteredCommandes = _commandes.where((commande) { |
|
|
|
final matchesSearch = commande.clientNomComplet.toLowerCase().contains(query) || |
|
|
|
final matchesSearch = |
|
|
|
commande.clientNomComplet.toLowerCase().contains(query) || |
|
|
|
commande.id.toString().contains(query); |
|
|
|
final matchesStatut = _selectedStatut == null || commande.statut == _selectedStatut; |
|
|
|
final matchesStatut = |
|
|
|
_selectedStatut == null || commande.statut == _selectedStatut; |
|
|
|
final matchesDate = _selectedDate == null || |
|
|
|
DateFormat('yyyy-MM-dd').format(commande.dateCommande) == |
|
|
|
DateFormat('yyyy-MM-dd').format(_selectedDate!); |
|
|
|
|
|
|
|
// Nouveau: filtrer les commandes annulées selon le toggle |
|
|
|
final shouldShowCancelled = _showCancelledOrders || commande.statut != StatutCommande.annulee; |
|
|
|
final shouldShowCancelled = |
|
|
|
_showCancelledOrders || commande.statut != StatutCommande.annulee; |
|
|
|
|
|
|
|
return matchesSearch && matchesStatut && matchesDate && shouldShowCancelled; |
|
|
|
return matchesSearch && |
|
|
|
matchesStatut && |
|
|
|
matchesDate && |
|
|
|
shouldShowCancelled; |
|
|
|
}).toList(); |
|
|
|
}); |
|
|
|
} |
|
|
|
@ -148,12 +156,11 @@ class _GestionCommandesPageState extends State<GestionCommandesPage> { |
|
|
|
width: 100, |
|
|
|
height: 80, |
|
|
|
decoration: pw.BoxDecoration( |
|
|
|
border: pw.Border.all(color: PdfColors.blue900, width: 2), |
|
|
|
border: |
|
|
|
pw.Border.all(color: PdfColors.blue900, width: 2), |
|
|
|
borderRadius: pw.BorderRadius.circular(8), |
|
|
|
), |
|
|
|
child: pw.Center( |
|
|
|
child: pw.Image(image) |
|
|
|
), |
|
|
|
child: pw.Center(child: pw.Image(image)), |
|
|
|
), |
|
|
|
pw.SizedBox(height: 10), |
|
|
|
pw.Text('guycom', style: headerStyle), |
|
|
|
@ -175,7 +182,8 @@ class _GestionCommandesPageState extends State<GestionCommandesPage> { |
|
|
|
child: pw.Column( |
|
|
|
crossAxisAlignment: pw.CrossAxisAlignment.start, |
|
|
|
children: [ |
|
|
|
pw.Text('FACTURE', |
|
|
|
pw.Text( |
|
|
|
'FACTURE', |
|
|
|
style: pw.TextStyle( |
|
|
|
fontSize: 20, |
|
|
|
fontWeight: pw.FontWeight.bold, |
|
|
|
@ -184,7 +192,8 @@ class _GestionCommandesPageState extends State<GestionCommandesPage> { |
|
|
|
), |
|
|
|
pw.SizedBox(height: 8), |
|
|
|
pw.Text('N°: ${commande.id}', style: titleStyle), |
|
|
|
pw.Text('Date: ${DateFormat('dd/MM/yyyy').format(commande.dateCommande)}'), |
|
|
|
pw.Text( |
|
|
|
'Date: ${DateFormat('dd/MM/yyyy').format(commande.dateCommande)}'), |
|
|
|
], |
|
|
|
), |
|
|
|
), |
|
|
|
@ -212,7 +221,8 @@ class _GestionCommandesPageState extends State<GestionCommandesPage> { |
|
|
|
style: pw.TextStyle(fontSize: 12)), |
|
|
|
if (client?.telephone != null) |
|
|
|
pw.Text('Tél: ${client!.telephone}', |
|
|
|
style: pw.TextStyle(fontSize: 10, color: PdfColors.grey600)), |
|
|
|
style: pw.TextStyle( |
|
|
|
fontSize: 10, color: PdfColors.grey600)), |
|
|
|
], |
|
|
|
), |
|
|
|
), |
|
|
|
@ -224,15 +234,21 @@ class _GestionCommandesPageState extends State<GestionCommandesPage> { |
|
|
|
pw.SizedBox(height: 10), |
|
|
|
|
|
|
|
pw.Table( |
|
|
|
border: pw.TableBorder.all(color: PdfColors.grey400, width: 0.5), |
|
|
|
border: |
|
|
|
pw.TableBorder.all(color: PdfColors.grey400, width: 0.5), |
|
|
|
children: [ |
|
|
|
pw.TableRow( |
|
|
|
decoration: const pw.BoxDecoration(color: PdfColors.blue900), |
|
|
|
decoration: |
|
|
|
const pw.BoxDecoration(color: PdfColors.blue900), |
|
|
|
children: [ |
|
|
|
_buildTableCell('Produit', titleStyle.copyWith(color: PdfColors.white)), |
|
|
|
_buildTableCell('Qté', titleStyle.copyWith(color: PdfColors.white)), |
|
|
|
_buildTableCell('Prix unit.', titleStyle.copyWith(color: PdfColors.white)), |
|
|
|
_buildTableCell('Total', titleStyle.copyWith(color: PdfColors.white)), |
|
|
|
_buildTableCell('Produit', |
|
|
|
titleStyle.copyWith(color: PdfColors.white)), |
|
|
|
_buildTableCell( |
|
|
|
'Qté', titleStyle.copyWith(color: PdfColors.white)), |
|
|
|
_buildTableCell('Prix unit.', |
|
|
|
titleStyle.copyWith(color: PdfColors.white)), |
|
|
|
_buildTableCell( |
|
|
|
'Total', titleStyle.copyWith(color: PdfColors.white)), |
|
|
|
], |
|
|
|
), |
|
|
|
...details.asMap().entries.map((entry) { |
|
|
|
@ -247,8 +263,10 @@ class _GestionCommandesPageState extends State<GestionCommandesPage> { |
|
|
|
children: [ |
|
|
|
_buildTableCell(detail.produitNom ?? 'Produit inconnu'), |
|
|
|
_buildTableCell(detail.quantite.toString()), |
|
|
|
_buildTableCell('${detail.prixUnitaire.toStringAsFixed(2)} DA'), |
|
|
|
_buildTableCell('${detail.sousTotal.toStringAsFixed(2)} DA'), |
|
|
|
_buildTableCell( |
|
|
|
'${detail.prixUnitaire.toStringAsFixed(2)} DA'), |
|
|
|
_buildTableCell( |
|
|
|
'${detail.sousTotal.toStringAsFixed(2)} DA'), |
|
|
|
], |
|
|
|
); |
|
|
|
}), |
|
|
|
@ -301,7 +319,8 @@ class _GestionCommandesPageState extends State<GestionCommandesPage> { |
|
|
|
pw.SizedBox(height: 5), |
|
|
|
pw.Text( |
|
|
|
'Cette facture est générée automatiquement par le système Youmaz Gestion', |
|
|
|
style: pw.TextStyle(fontSize: 8, color: PdfColors.grey600), |
|
|
|
style: |
|
|
|
pw.TextStyle(fontSize: 8, color: PdfColors.grey600), |
|
|
|
), |
|
|
|
], |
|
|
|
), |
|
|
|
@ -464,7 +483,8 @@ class _GestionCommandesPageState extends State<GestionCommandesPage> { |
|
|
|
controller: _searchController, |
|
|
|
decoration: InputDecoration( |
|
|
|
labelText: 'Rechercher par client ou numéro de commande', |
|
|
|
prefixIcon: Icon(Icons.search, color: Colors.blue.shade800), |
|
|
|
prefixIcon: |
|
|
|
Icon(Icons.search, color: Colors.blue.shade800), |
|
|
|
border: OutlineInputBorder( |
|
|
|
borderRadius: BorderRadius.circular(12), |
|
|
|
borderSide: BorderSide.none, |
|
|
|
@ -501,7 +521,8 @@ class _GestionCommandesPageState extends State<GestionCommandesPage> { |
|
|
|
value: _selectedStatut, |
|
|
|
decoration: InputDecoration( |
|
|
|
labelText: 'Filtrer par statut', |
|
|
|
prefixIcon: Icon(Icons.filter_list, color: Colors.blue.shade600), |
|
|
|
prefixIcon: Icon(Icons.filter_list, |
|
|
|
color: Colors.blue.shade600), |
|
|
|
border: OutlineInputBorder( |
|
|
|
borderRadius: BorderRadius.circular(12), |
|
|
|
borderSide: BorderSide.none, |
|
|
|
@ -590,11 +611,13 @@ class _GestionCommandesPageState extends State<GestionCommandesPage> { |
|
|
|
}); |
|
|
|
} |
|
|
|
}, |
|
|
|
icon: Icon(Icons.calendar_today, color: Colors.blue.shade600), |
|
|
|
icon: Icon(Icons.calendar_today, |
|
|
|
color: Colors.blue.shade600), |
|
|
|
label: Text( |
|
|
|
_selectedDate == null |
|
|
|
? 'Date' |
|
|
|
: DateFormat('dd/MM/yyyy').format(_selectedDate!), |
|
|
|
: DateFormat('dd/MM/yyyy') |
|
|
|
.format(_selectedDate!), |
|
|
|
style: const TextStyle(color: Colors.black87), |
|
|
|
), |
|
|
|
), |
|
|
|
@ -647,7 +670,8 @@ class _GestionCommandesPageState extends State<GestionCommandesPage> { |
|
|
|
), |
|
|
|
], |
|
|
|
), |
|
|
|
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), |
|
|
|
padding: |
|
|
|
const EdgeInsets.symmetric(horizontal: 16, vertical: 8), |
|
|
|
child: Row( |
|
|
|
children: [ |
|
|
|
Icon( |
|
|
|
@ -756,7 +780,8 @@ class _GestionCommandesPageState extends State<GestionCommandesPage> { |
|
|
|
Icon( |
|
|
|
_getStatutIcon(commande.statut), |
|
|
|
size: 20, |
|
|
|
color: commande.statut == StatutCommande.annulee |
|
|
|
color: |
|
|
|
commande.statut == StatutCommande.annulee |
|
|
|
? Colors.red |
|
|
|
: Colors.blue.shade600, |
|
|
|
), |
|
|
|
@ -790,7 +815,8 @@ class _GestionCommandesPageState extends State<GestionCommandesPage> { |
|
|
|
), |
|
|
|
const SizedBox(width: 4), |
|
|
|
Text( |
|
|
|
DateFormat('dd/MM/yyyy').format(commande.dateCommande), |
|
|
|
DateFormat('dd/MM/yyyy') |
|
|
|
.format(commande.dateCommande), |
|
|
|
style: TextStyle( |
|
|
|
fontSize: 12, |
|
|
|
color: Colors.grey.shade600, |
|
|
|
@ -811,7 +837,8 @@ class _GestionCommandesPageState extends State<GestionCommandesPage> { |
|
|
|
style: TextStyle( |
|
|
|
fontSize: 11, |
|
|
|
fontWeight: FontWeight.w600, |
|
|
|
color: commande.statut == StatutCommande.annulee |
|
|
|
color: commande.statut == |
|
|
|
StatutCommande.annulee |
|
|
|
? Colors.red |
|
|
|
: Colors.blue.shade700, |
|
|
|
), |
|
|
|
@ -829,7 +856,7 @@ class _GestionCommandesPageState extends State<GestionCommandesPage> { |
|
|
|
), |
|
|
|
const SizedBox(width: 4), |
|
|
|
Text( |
|
|
|
'${commande.montantTotal.toStringAsFixed(2)} DA', |
|
|
|
'${commande.montantTotal.toStringAsFixed(2)} MGA', |
|
|
|
style: TextStyle( |
|
|
|
fontSize: 14, |
|
|
|
fontWeight: FontWeight.bold, |
|
|
|
@ -982,10 +1009,13 @@ class _CommandeDetails extends StatelessWidget { |
|
|
|
), |
|
|
|
...details.map((detail) => TableRow( |
|
|
|
children: [ |
|
|
|
_buildTableCell(detail.produitNom ?? 'Produit inconnu'), |
|
|
|
_buildTableCell( |
|
|
|
detail.produitNom ?? 'Produit inconnu'), |
|
|
|
_buildTableCell('${detail.quantite}'), |
|
|
|
_buildTableCell('${detail.prixUnitaire.toStringAsFixed(2)} DA'), |
|
|
|
_buildTableCell('${detail.sousTotal.toStringAsFixed(2)} DA'), |
|
|
|
_buildTableCell( |
|
|
|
'${detail.prixUnitaire.toStringAsFixed(2)} MGA'), |
|
|
|
_buildTableCell( |
|
|
|
'${detail.sousTotal.toStringAsFixed(2)} MGA'), |
|
|
|
], |
|
|
|
)), |
|
|
|
], |
|
|
|
@ -1010,7 +1040,7 @@ class _CommandeDetails extends StatelessWidget { |
|
|
|
), |
|
|
|
), |
|
|
|
Text( |
|
|
|
'${commande.montantTotal.toStringAsFixed(2)} DA', |
|
|
|
'${commande.montantTotal.toStringAsFixed(2)} MGA', |
|
|
|
style: TextStyle( |
|
|
|
fontWeight: FontWeight.bold, |
|
|
|
fontSize: 18, |
|
|
|
@ -1204,7 +1234,8 @@ class _CommandeActions extends StatelessWidget { |
|
|
|
child: Row( |
|
|
|
mainAxisSize: MainAxisSize.min, |
|
|
|
children: [ |
|
|
|
Icon(Icons.check_circle, color: Colors.green.shade600, size: 16), |
|
|
|
Icon(Icons.check_circle, |
|
|
|
color: Colors.green.shade600, size: 16), |
|
|
|
const SizedBox(width: 8), |
|
|
|
Text( |
|
|
|
'Commande livrée', |
|
|
|
|