commit
This commit is contained in:
commit
45688ec98a
@ -24,6 +24,13 @@ final List<PaymentMethod> paymentMethods = [
|
|||||||
icon: Icons.phone,
|
icon: Icons.phone,
|
||||||
color: Color(0xFF4285F4),
|
color: Color(0xFF4285F4),
|
||||||
),
|
),
|
||||||
|
const PaymentMethod(
|
||||||
|
id: 'orange_money',
|
||||||
|
name: 'Orange Money',
|
||||||
|
description: 'Paiement mobile Orange Money',
|
||||||
|
icon: Icons.phone,
|
||||||
|
color: Color(0xFF4285F4),
|
||||||
|
),
|
||||||
const PaymentMethod(
|
const PaymentMethod(
|
||||||
id: 'carte',
|
id: 'carte',
|
||||||
name: 'Carte Bancaire',
|
name: 'Carte Bancaire',
|
||||||
|
|||||||
@ -135,6 +135,14 @@ class _FactureScreenState extends State<FactureScreen> {
|
|||||||
'Contact: +261 34 12 34 56',
|
'Contact: +261 34 12 34 56',
|
||||||
style: TextStyle(fontSize: 12, color: Colors.black87),
|
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),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -60,6 +60,8 @@ class PlatformPrintService {
|
|||||||
'ville': 'Madagascar',
|
'ville': 'Madagascar',
|
||||||
'contact': '261348415301',
|
'contact': '261348415301',
|
||||||
'email': 'contact@careeragency.mg',
|
'email': 'contact@careeragency.mg',
|
||||||
|
'nif': '4002141594',
|
||||||
|
'stat': '10715 33 2025 0 00414',
|
||||||
};
|
};
|
||||||
|
|
||||||
final factureNumber =
|
final factureNumber =
|
||||||
@ -69,223 +71,267 @@ class PlatformPrintService {
|
|||||||
pdf.addPage(
|
pdf.addPage(
|
||||||
pw.Page(
|
pw.Page(
|
||||||
pageFormat: ticket58mmFormat,
|
pageFormat: ticket58mmFormat,
|
||||||
|
margin: const pw.EdgeInsets.all(2), // 🔧 Marges minimales
|
||||||
build: (pw.Context context) {
|
build: (pw.Context context) {
|
||||||
return pw.Column(
|
return pw.Container(
|
||||||
crossAxisAlignment: pw.CrossAxisAlignment.center,
|
width: double.infinity, // 🔧 Forcer la largeur complète
|
||||||
children: [
|
child: pw.Column(
|
||||||
// En-tête Restaurant (centré et compact)
|
crossAxisAlignment:
|
||||||
pw.Text(
|
pw.CrossAxisAlignment.start, // 🔧 Alignement à gauche
|
||||||
restaurantInfo['nom']!,
|
children: [
|
||||||
style: pw.TextStyle(
|
// En-tête Restaurant (centré et compact)
|
||||||
fontSize: titleSize,
|
pw.Container(
|
||||||
fontWeight: pw.FontWeight.bold,
|
width: double.infinity,
|
||||||
|
child: pw.Text(
|
||||||
|
restaurantInfo['nom']!,
|
||||||
|
style: pw.TextStyle(
|
||||||
|
fontSize: titleSize,
|
||||||
|
fontWeight: pw.FontWeight.bold,
|
||||||
|
),
|
||||||
|
textAlign: pw.TextAlign.center,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
textAlign: pw.TextAlign.center,
|
|
||||||
),
|
|
||||||
|
|
||||||
pw.SizedBox(height: 1),
|
pw.SizedBox(height: 1),
|
||||||
|
|
||||||
pw.Text(
|
pw.Container(
|
||||||
restaurantInfo['adresse']!,
|
width: double.infinity,
|
||||||
style: pw.TextStyle(fontSize: smallSize),
|
child: pw.Text(
|
||||||
textAlign: pw.TextAlign.center,
|
restaurantInfo['adresse']!,
|
||||||
),
|
style: pw.TextStyle(fontSize: smallSize),
|
||||||
|
textAlign: pw.TextAlign.center,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
pw.Text(
|
pw.Container(
|
||||||
restaurantInfo['ville']!,
|
width: double.infinity,
|
||||||
style: pw.TextStyle(fontSize: smallSize),
|
child: pw.Text(
|
||||||
textAlign: pw.TextAlign.center,
|
restaurantInfo['ville']!,
|
||||||
),
|
style: pw.TextStyle(fontSize: smallSize),
|
||||||
|
textAlign: pw.TextAlign.center,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
pw.Text(
|
pw.Container(
|
||||||
'Tel: ${restaurantInfo['contact']!}',
|
width: double.infinity,
|
||||||
style: pw.TextStyle(fontSize: smallSize),
|
child: pw.Text(
|
||||||
textAlign: pw.TextAlign.center,
|
'Tel: ${restaurantInfo['contact']!}',
|
||||||
),
|
style: pw.TextStyle(fontSize: smallSize),
|
||||||
|
textAlign: pw.TextAlign.center,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
pw.SizedBox(height: 3),
|
pw.SizedBox(height: 3),
|
||||||
|
|
||||||
// Ligne de séparation
|
// Ligne de séparation
|
||||||
pw.Container(
|
pw.Container(
|
||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
height: 0.5,
|
height: 0.5,
|
||||||
color: PdfColors.black,
|
color: PdfColors.black,
|
||||||
),
|
),
|
||||||
|
|
||||||
pw.SizedBox(height: 2),
|
pw.SizedBox(height: 2),
|
||||||
|
|
||||||
// Informations ticket
|
// Informations ticket
|
||||||
pw.Row(
|
pw.Container(
|
||||||
mainAxisAlignment: pw.MainAxisAlignment.spaceBetween,
|
width: double.infinity,
|
||||||
children: [
|
child: pw.Row(
|
||||||
pw.Text(
|
mainAxisAlignment: pw.MainAxisAlignment.spaceBetween,
|
||||||
'Ticket: $factureNumber',
|
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,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
// 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.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.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(
|
style: pw.TextStyle(
|
||||||
fontSize: bodySize,
|
fontSize: bodySize,
|
||||||
fontWeight: pw.FontWeight.bold,
|
fontStyle: pw.FontStyle.italic,
|
||||||
),
|
),
|
||||||
|
textAlign: pw.TextAlign.center,
|
||||||
),
|
),
|
||||||
pw.Text(
|
|
||||||
'Via: ${commande.tablename ?? 'Table inconnue'}',
|
|
||||||
style: pw.TextStyle(fontSize: bodySize),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
|
|
||||||
pw.SizedBox(height: 1),
|
|
||||||
|
|
||||||
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(
|
|
||||||
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.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,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
pw.Text(
|
|
||||||
'${commande.totalTtc.toStringAsFixed(2)}MGA',
|
|
||||||
style: pw.TextStyle(
|
|
||||||
fontSize: titleSize,
|
|
||||||
fontWeight: pw.FontWeight.bold,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
|
|
||||||
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(
|
pw.Container(
|
||||||
'A bientôt !',
|
width: double.infinity,
|
||||||
style: pw.TextStyle(fontSize: smallSize),
|
child: pw.Text(
|
||||||
textAlign: pw.TextAlign.center,
|
'A bientôt !',
|
||||||
),
|
style: pw.TextStyle(fontSize: smallSize),
|
||||||
|
textAlign: pw.TextAlign.center,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
pw.SizedBox(height: 3),
|
pw.SizedBox(height: 3),
|
||||||
|
|
||||||
// Code de suivi (optionnel)
|
// Code de suivi (optionnel)
|
||||||
pw.Text(
|
pw.Container(
|
||||||
'Code: ${factureNumber}',
|
width: double.infinity,
|
||||||
style: pw.TextStyle(fontSize: smallSize),
|
child: pw.Text(
|
||||||
textAlign: pw.TextAlign.center,
|
'Code: ${factureNumber}',
|
||||||
),
|
style: pw.TextStyle(fontSize: smallSize),
|
||||||
|
textAlign: pw.TextAlign.center,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
pw.SizedBox(height: 4),
|
pw.SizedBox(height: 4),
|
||||||
|
|
||||||
// Ligne de découpe
|
// Ligne de découpe
|
||||||
pw.Text(
|
pw.Container(
|
||||||
'- - - - - - - - - - - - - - - -',
|
width: double.infinity,
|
||||||
style: pw.TextStyle(fontSize: smallSize),
|
child: pw.Text(
|
||||||
textAlign: pw.TextAlign.center,
|
'- - - - - - - - - - - - - - - -',
|
||||||
),
|
style: pw.TextStyle(fontSize: smallSize),
|
||||||
|
textAlign: pw.TextAlign.center,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
pw.SizedBox(height: 2),
|
pw.SizedBox(height: 2),
|
||||||
],
|
],
|
||||||
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|||||||
@ -238,48 +238,48 @@ class AppBottomNavigation extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
const SizedBox(width: 20),
|
// const SizedBox(width: 20),
|
||||||
|
|
||||||
GestureDetector(
|
// GestureDetector(
|
||||||
onTap: () => onItemTapped(6),
|
// onTap: () => onItemTapped(6),
|
||||||
child: Container(
|
// child: Container(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
|
// padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
|
||||||
decoration: BoxDecoration(
|
// decoration: BoxDecoration(
|
||||||
color:
|
// color:
|
||||||
selectedIndex == 5
|
// selectedIndex == 5
|
||||||
? Colors.green.shade700
|
// ? Colors.green.shade700
|
||||||
: Colors.transparent,
|
// : Colors.transparent,
|
||||||
borderRadius: BorderRadius.circular(20),
|
// borderRadius: BorderRadius.circular(20),
|
||||||
),
|
// ),
|
||||||
child: Row(
|
// child: Row(
|
||||||
mainAxisSize: MainAxisSize.min,
|
// mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
// children: [
|
||||||
Icon(
|
// Icon(
|
||||||
Icons.payment,
|
// Icons.payment,
|
||||||
color:
|
// color:
|
||||||
selectedIndex == 5
|
// selectedIndex == 5
|
||||||
? Colors.white
|
// ? Colors.white
|
||||||
: Colors.grey.shade600,
|
// : Colors.grey.shade600,
|
||||||
size: 16,
|
// size: 16,
|
||||||
),
|
// ),
|
||||||
const SizedBox(width: 6),
|
// const SizedBox(width: 6),
|
||||||
Text(
|
// Text(
|
||||||
'Historique',
|
// 'Historique',
|
||||||
style: TextStyle(
|
// style: TextStyle(
|
||||||
color:
|
// color:
|
||||||
selectedIndex == 5
|
// selectedIndex == 5
|
||||||
? Colors.white
|
// ? Colors.white
|
||||||
: Colors.grey.shade600,
|
// : Colors.grey.shade600,
|
||||||
fontWeight:
|
// fontWeight:
|
||||||
selectedIndex == 5
|
// selectedIndex == 5
|
||||||
? FontWeight.w500
|
// ? FontWeight.w500
|
||||||
: FontWeight.normal,
|
// : FontWeight.normal,
|
||||||
),
|
// ),
|
||||||
),
|
// ),
|
||||||
],
|
// ],
|
||||||
),
|
// ),
|
||||||
),
|
// ),
|
||||||
),
|
// ),
|
||||||
|
|
||||||
const Spacer(),
|
const Spacer(),
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user