From c0a2f427bbec86fb52951a76fb62c01ea34aff50 Mon Sep 17 00:00:00 2001 From: Stephane Date: Sun, 3 Aug 2025 21:49:27 +0300 Subject: [PATCH 1/3] orange money --- lib/models/payment_method.dart | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/lib/models/payment_method.dart b/lib/models/payment_method.dart index b8a360c..f4f3b9f 100644 --- a/lib/models/payment_method.dart +++ b/lib/models/payment_method.dart @@ -24,6 +24,13 @@ final List paymentMethods = [ icon: Icons.phone, color: Color(0xFF4285F4), ), + const PaymentMethod( + id: 'orange_money', + name: 'Orange Money', + description: 'Paiement mobile Orange Money', + icon: Icons.phone, + color: Color(0xFF4285F4), + ), const PaymentMethod( id: 'carte', name: 'Carte Bancaire', From 9fdf8d084ff9c41b30d8e7015e75f01993e72176 Mon Sep 17 00:00:00 2001 From: Stephane Date: Sun, 3 Aug 2025 21:52:31 +0300 Subject: [PATCH 2/3] NIF STAT --- lib/pages/facture_screen.dart | 8 ++++++++ lib/services/pdf_service.dart | 2 ++ 2 files changed, 10 insertions(+) diff --git a/lib/pages/facture_screen.dart b/lib/pages/facture_screen.dart index 4953123..a561ace 100644 --- a/lib/pages/facture_screen.dart +++ b/lib/pages/facture_screen.dart @@ -135,6 +135,14 @@ class _FactureScreenState extends State { 'Contact: +261 34 12 34 56', style: TextStyle(fontSize: 12, color: Colors.black87), ), + Text( + 'NIF: 4002141594', + style: TextStyle(fontSize: 12, color: Colors.black87), + ), + Text( + 'STAT: 10715 33 2025 0 00414', + style: TextStyle(fontSize: 12, color: Colors.black87), + ), ], ); } diff --git a/lib/services/pdf_service.dart b/lib/services/pdf_service.dart index 5adef41..f9510b0 100644 --- a/lib/services/pdf_service.dart +++ b/lib/services/pdf_service.dart @@ -60,6 +60,8 @@ class PlatformPrintService { 'ville': 'Madagascar', 'contact': '261348415301', 'email': 'contact@careeragency.mg', + 'nif': '4002141594', + 'stat': '10715 33 2025 0 00414', }; final factureNumber = From 1207eeff13950f2b93d9d24582ce5934db0f42ad Mon Sep 17 00:00:00 2001 From: Stephane Date: Sun, 3 Aug 2025 22:04:25 +0300 Subject: [PATCH 3/3] impression --- lib/services/pdf_service.dart | 440 +++++++++++++++++++--------------- 1 file changed, 242 insertions(+), 198 deletions(-) diff --git a/lib/services/pdf_service.dart b/lib/services/pdf_service.dart index f9510b0..c18a76f 100644 --- a/lib/services/pdf_service.dart +++ b/lib/services/pdf_service.dart @@ -71,223 +71,267 @@ class PlatformPrintService { pdf.addPage( pw.Page( pageFormat: ticket58mmFormat, + margin: const pw.EdgeInsets.all(2), // 🔧 Marges minimales build: (pw.Context context) { - return pw.Column( - crossAxisAlignment: pw.CrossAxisAlignment.center, - children: [ - // En-tête Restaurant (centré et compact) - pw.Text( - restaurantInfo['nom']!, - style: pw.TextStyle( - fontSize: titleSize, - fontWeight: pw.FontWeight.bold, - ), - textAlign: pw.TextAlign.center, - ), - - pw.SizedBox(height: 1), - - pw.Text( - restaurantInfo['adresse']!, - style: pw.TextStyle(fontSize: smallSize), - textAlign: pw.TextAlign.center, - ), - - pw.Text( - restaurantInfo['ville']!, - style: pw.TextStyle(fontSize: smallSize), - textAlign: pw.TextAlign.center, - ), - - pw.Text( - 'Tel: ${restaurantInfo['contact']!}', - style: pw.TextStyle(fontSize: smallSize), - textAlign: pw.TextAlign.center, - ), - - pw.SizedBox(height: 3), - - // Ligne de séparation - pw.Container( - width: double.infinity, - height: 0.5, - color: PdfColors.black, - ), - - pw.SizedBox(height: 2), - - // Informations ticket - pw.Row( - mainAxisAlignment: pw.MainAxisAlignment.spaceBetween, - children: [ - pw.Text( - 'Ticket: $factureNumber', + return pw.Container( + width: double.infinity, // 🔧 Forcer la largeur complète + child: pw.Column( + crossAxisAlignment: + pw.CrossAxisAlignment.start, // 🔧 Alignement à gauche + children: [ + // En-tête Restaurant (centré et compact) + pw.Container( + width: double.infinity, + child: pw.Text( + restaurantInfo['nom']!, style: pw.TextStyle( - fontSize: bodySize, + fontSize: titleSize, fontWeight: pw.FontWeight.bold, ), + textAlign: pw.TextAlign.center, ), - pw.Text( - 'Via: ${commande.tablename ?? 'Table inconnue'}', - style: pw.TextStyle(fontSize: bodySize), - ), - ], - ), + ), + + pw.SizedBox(height: 1), - pw.SizedBox(height: 1), + pw.Container( + width: double.infinity, + child: pw.Text( + restaurantInfo['adresse']!, + style: pw.TextStyle(fontSize: smallSize), + textAlign: pw.TextAlign.center, + ), + ), - pw.Row( - mainAxisAlignment: pw.MainAxisAlignment.spaceBetween, - children: [ - pw.Text( - _formatDate(dateTime), + pw.Container( + width: double.infinity, + child: pw.Text( + restaurantInfo['ville']!, style: pw.TextStyle(fontSize: smallSize), + textAlign: pw.TextAlign.center, ), - pw.Text( - _formatTime(dateTime), + ), + + pw.Container( + width: double.infinity, + child: pw.Text( + 'Tel: ${restaurantInfo['contact']!}', style: pw.TextStyle(fontSize: smallSize), + textAlign: pw.TextAlign.center, ), - ], - ), - - pw.SizedBox(height: 2), - - // Ligne de séparation - pw.Container( - width: double.infinity, - height: 0.5, - color: PdfColors.black, - ), - - pw.SizedBox(height: 2), - - // Articles (format très compact) - ...commande.items - .map( - (item) => pw.Container( - margin: const pw.EdgeInsets.only(bottom: 1), - child: pw.Column( - crossAxisAlignment: pw.CrossAxisAlignment.start, - children: [ - // Nom du plat - pw.Text( - '${item.menuNom}', - style: pw.TextStyle(fontSize: bodySize), - maxLines: 2, - ), - - // Quantité, prix unitaire et total sur une ligne - pw.Row( - mainAxisAlignment: - pw.MainAxisAlignment.spaceBetween, - children: [ - pw.Text( - '${item.quantite}x ${item.prixUnitaire.toStringAsFixed(2)}MGA', - style: pw.TextStyle(fontSize: smallSize), + ), + + pw.SizedBox(height: 3), + + // Ligne de séparation + pw.Container( + width: double.infinity, + height: 0.5, + color: PdfColors.black, + ), + + pw.SizedBox(height: 2), + + // Informations ticket + pw.Container( + width: double.infinity, + child: pw.Row( + mainAxisAlignment: pw.MainAxisAlignment.spaceBetween, + children: [ + pw.Text( + 'Ticket: $factureNumber', + style: pw.TextStyle( + fontSize: bodySize, + fontWeight: pw.FontWeight.bold, + ), + ), + ], + ), + ), + + pw.SizedBox(height: 1), + + pw.Container( + width: double.infinity, + child: pw.Row( + mainAxisAlignment: pw.MainAxisAlignment.spaceBetween, + children: [ + pw.Text( + _formatDate(dateTime), + style: pw.TextStyle(fontSize: smallSize), + ), + pw.Text( + _formatTime(dateTime), + style: pw.TextStyle(fontSize: smallSize), + ), + ], + ), + ), + + pw.SizedBox(height: 2), + + // Ligne de séparation + pw.Container( + width: double.infinity, + height: 0.5, + color: PdfColors.black, + ), + + pw.SizedBox(height: 2), + + // Articles (format très compact) + ...commande.items + .map( + (item) => pw.Container( + width: double.infinity, // 🔧 Largeur complète + margin: const pw.EdgeInsets.only(bottom: 1), + child: pw.Column( + crossAxisAlignment: pw.CrossAxisAlignment.start, + children: [ + // Nom du plat + pw.Container( + width: double.infinity, + child: pw.Text( + '${item.menuNom}', + style: pw.TextStyle(fontSize: bodySize), + maxLines: 2, ), - pw.Text( - '${(item.prixUnitaire * item.quantite).toStringAsFixed(2)}MGA', - style: pw.TextStyle( - fontSize: bodySize, - fontWeight: pw.FontWeight.bold, - ), + ), + + // Quantité, prix unitaire et total sur une ligne + pw.Container( + width: double.infinity, + child: pw.Row( + mainAxisAlignment: + pw.MainAxisAlignment.spaceBetween, + children: [ + pw.Text( + '${item.quantite}x ${item.prixUnitaire.toStringAsFixed(2)}MGA', + style: pw.TextStyle(fontSize: smallSize), + ), + pw.Text( + '${(item.prixUnitaire * item.quantite).toStringAsFixed(2)}MGA', + style: pw.TextStyle( + fontSize: bodySize, + fontWeight: pw.FontWeight.bold, + ), + ), + ], ), - ], - ), - ], + ), + ], + ), ), - ), - ) - .toList(), - - pw.SizedBox(height: 2), - - // Ligne de séparation - pw.Container( - width: double.infinity, - height: 0.5, - color: PdfColors.black, - ), - - pw.SizedBox(height: 2), - - // Total - pw.Row( - mainAxisAlignment: pw.MainAxisAlignment.spaceBetween, - children: [ - pw.Text( - 'TOTAL', - style: pw.TextStyle( - fontSize: titleSize, - fontWeight: pw.FontWeight.bold, - ), + ) + .toList(), + + pw.SizedBox(height: 2), + + // Ligne de séparation + pw.Container( + width: double.infinity, + height: 0.5, + color: PdfColors.black, + ), + + pw.SizedBox(height: 2), + + // Total + pw.Container( + width: double.infinity, + child: pw.Row( + mainAxisAlignment: pw.MainAxisAlignment.spaceBetween, + children: [ + pw.Text( + 'TOTAL', + style: pw.TextStyle( + fontSize: titleSize, + fontWeight: pw.FontWeight.bold, + ), + ), + pw.Text( + '${commande.totalTtc.toStringAsFixed(2)}MGA', + style: pw.TextStyle( + fontSize: titleSize, + fontWeight: pw.FontWeight.bold, + ), + ), + ], + ), + ), + + pw.SizedBox(height: 3), + + // Mode de paiement + pw.Container( + width: double.infinity, + child: pw.Text( + 'Paiement: ${paymentMethod.toLowerCase()}', + style: pw.TextStyle(fontSize: bodySize), + textAlign: pw.TextAlign.center, ), - pw.Text( - '${commande.totalTtc.toStringAsFixed(2)}MGA', + ), + + pw.SizedBox(height: 3), + + // Ligne de séparation + pw.Container( + width: double.infinity, + height: 0.5, + color: PdfColors.black, + ), + + pw.SizedBox(height: 2), + + // Message de remerciement + pw.Container( + width: double.infinity, + child: pw.Text( + 'Merci de votre visite !', style: pw.TextStyle( - fontSize: titleSize, - fontWeight: pw.FontWeight.bold, + fontSize: bodySize, + fontStyle: pw.FontStyle.italic, ), + textAlign: pw.TextAlign.center, ), - ], - ), - - pw.SizedBox(height: 3), - - // Mode de paiement - pw.Text( - 'Paiement: ${_getPaymentMethodText(paymentMethod)}', - style: pw.TextStyle(fontSize: bodySize), - textAlign: pw.TextAlign.center, - ), - - pw.SizedBox(height: 3), - - // Ligne de séparation - pw.Container( - width: double.infinity, - height: 0.5, - color: PdfColors.black, - ), - - pw.SizedBox(height: 2), - - // Message de remerciement - pw.Text( - 'Merci de votre visite !', - style: pw.TextStyle( - fontSize: bodySize, - fontStyle: pw.FontStyle.italic, ), - textAlign: pw.TextAlign.center, - ), - - pw.Text( - 'A bientôt !', - style: pw.TextStyle(fontSize: smallSize), - textAlign: pw.TextAlign.center, - ), - - pw.SizedBox(height: 3), - - // Code de suivi (optionnel) - pw.Text( - 'Code: ${factureNumber}', - style: pw.TextStyle(fontSize: smallSize), - textAlign: pw.TextAlign.center, - ), - - pw.SizedBox(height: 4), - - // Ligne de découpe - pw.Text( - '- - - - - - - - - - - - - - - -', - style: pw.TextStyle(fontSize: smallSize), - textAlign: pw.TextAlign.center, - ), - - pw.SizedBox(height: 2), - ], + + pw.Container( + width: double.infinity, + child: pw.Text( + 'A bientôt !', + style: pw.TextStyle(fontSize: smallSize), + textAlign: pw.TextAlign.center, + ), + ), + + pw.SizedBox(height: 3), + + // Code de suivi (optionnel) + pw.Container( + width: double.infinity, + child: pw.Text( + 'Code: ${factureNumber}', + style: pw.TextStyle(fontSize: smallSize), + textAlign: pw.TextAlign.center, + ), + ), + + pw.SizedBox(height: 4), + + // Ligne de découpe + pw.Container( + width: double.infinity, + child: pw.Text( + '- - - - - - - - - - - - - - - -', + style: pw.TextStyle(fontSize: smallSize), + textAlign: pw.TextAlign.center, + ), + ), + + pw.SizedBox(height: 2), + ], + ), ); }, ),