// services/pdf_service.dart import 'dart:io'; import 'dart:typed_data'; import 'package:pdf/pdf.dart'; import 'package:pdf/widgets.dart' as pw; import 'package:printing/printing.dart'; import 'package:path_provider/path_provider.dart'; import 'package:share_plus/share_plus.dart'; import '../models/command_detail.dart'; class PdfService { static Future generateFacturePdf({ required CommandeDetail commande, required String paymentMethod, }) async { final pdf = pw.Document(); // Informations du restaurant final restaurantInfo = { 'nom': 'RESTAURANT', 'adresse': 'Moramanga, Antananarivo', 'contact': '+261 34 12 34 56', }; // Générer numéro de facture final factureNumber = 'F${DateTime.now().millisecondsSinceEpoch.toString().substring(7)}'; final dateTime = DateTime.now(); pdf.addPage( pw.Page( pageFormat: PdfPageFormat.a4, margin: const pw.EdgeInsets.all(32), build: (pw.Context context) { return pw.Column( crossAxisAlignment: pw.CrossAxisAlignment.start, children: [ // En-tête Restaurant pw.Center( child: pw.Column( children: [ pw.Text( restaurantInfo['nom']!, style: pw.TextStyle( fontSize: 24, fontWeight: pw.FontWeight.bold, ), ), pw.SizedBox(height: 8), pw.Text( 'Adresse: ${restaurantInfo['adresse']}', style: const pw.TextStyle(fontSize: 12), ), pw.Text( 'Contact: ${restaurantInfo['contact']}', style: const pw.TextStyle(fontSize: 12), ), ], ), ), pw.SizedBox(height: 30), // Informations facture pw.Center( child: pw.Column( children: [ pw.Text( 'Facture n° $factureNumber', style: pw.TextStyle( fontSize: 14, fontWeight: pw.FontWeight.bold, ), ), pw.SizedBox(height: 4), pw.Text( 'Date: ${_formatDateTime(dateTime)}', style: const pw.TextStyle(fontSize: 12), ), pw.SizedBox(height: 4), pw.Text( 'Table: ${commande.numeroCommande}', style: const pw.TextStyle(fontSize: 12), ), pw.SizedBox(height: 4), pw.Text( 'Paiement: ${_getPaymentMethodText(paymentMethod)}', style: const pw.TextStyle(fontSize: 12), ), ], ), ), pw.SizedBox(height: 30), // Tableau des articles pw.Table( border: pw.TableBorder.all(color: PdfColors.grey300), columnWidths: { 0: const pw.FlexColumnWidth(3), 1: const pw.FlexColumnWidth(1), 2: const pw.FlexColumnWidth(1), }, children: [ // En-tête du tableau pw.TableRow( decoration: const pw.BoxDecoration( color: PdfColors.grey100, ), children: [ pw.Padding( padding: const pw.EdgeInsets.all(8), child: pw.Text( 'Qté Désignation', style: pw.TextStyle(fontWeight: pw.FontWeight.bold), ), ), pw.Padding( padding: const pw.EdgeInsets.all(8), child: pw.Text( 'Prix', style: pw.TextStyle(fontWeight: pw.FontWeight.bold), textAlign: pw.TextAlign.right, ), ), ], ), // Lignes des articles ...commande.items .map( (item) => pw.TableRow( children: [ pw.Padding( padding: const pw.EdgeInsets.all(8), child: pw.Text( '${item.quantite} TESTNOMCOMMANDE', ), ), pw.Padding( padding: const pw.EdgeInsets.all(8), child: pw.Text( '${item.prixUnitaire.toStringAsFixed(2)} €', textAlign: pw.TextAlign.right, ), ), ], ), ) .toList(), ], ), pw.SizedBox(height: 20), // Total pw.Container( alignment: pw.Alignment.centerRight, child: pw.Container( padding: const pw.EdgeInsets.all(12), decoration: pw.BoxDecoration( border: pw.Border.all(color: PdfColors.grey400), color: PdfColors.grey50, ), child: pw.Text( 'Total: ${commande.totalTtc.toStringAsFixed(2)} €', style: pw.TextStyle( fontSize: 16, fontWeight: pw.FontWeight.bold, ), ), ), ), pw.Spacer(), // Message de remerciement pw.Center( child: pw.Text( 'Merci et à bientôt !', style: pw.TextStyle( fontSize: 12, fontStyle: pw.FontStyle.italic, ), ), ), ], ); }, ), ); return pdf.save(); } static String _formatDateTime(DateTime dateTime) { return '${dateTime.day.toString().padLeft(2, '0')}/${dateTime.month.toString().padLeft(2, '0')}/${dateTime.year} ${dateTime.hour.toString().padLeft(2, '0')}:${dateTime.minute.toString().padLeft(2, '0')}'; } static String _getPaymentMethodText(String method) { switch (method) { case 'mvola': return 'MVola'; case 'carte': return 'CB'; case 'especes': return 'Espèces'; default: return 'CB'; } } // Imprimer directement static Future printFacture({ required CommandeDetail commande, required String paymentMethod, }) async { try { final pdfData = await generateFacturePdf( commande: commande, paymentMethod: paymentMethod, ); await Printing.layoutPdf( onLayout: (PdfPageFormat format) async => pdfData, name: 'Facture_${commande.numeroCommande}_${DateTime.now().millisecondsSinceEpoch}', ); return true; } catch (e) { print('Erreur impression: $e'); return false; } } // Sauvegarder et partager le PDF static Future saveAndShareFacture({ required CommandeDetail commande, required String paymentMethod, }) async { try { final pdfData = await generateFacturePdf( commande: commande, paymentMethod: paymentMethod, ); final directory = await getApplicationDocumentsDirectory(); final fileName = 'Facture_${commande.numeroCommande}_${DateTime.now().millisecondsSinceEpoch}.pdf'; final file = File('${directory.path}/$fileName'); await file.writeAsBytes(pdfData); await Share.shareXFiles( [XFile(file.path)], subject: 'Facture ${commande.numeroCommande}', text: 'Facture de votre commande au restaurant', ); return true; } catch (e) { print('Erreur sauvegarde/partage: $e'); return false; } } }