import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; import 'package:pdf/pdf.dart'; import 'package:pdf/widgets.dart' as pw; import 'package:printing/printing.dart'; /// Service for generating and printing warehouse export forms class PrintService { /// Generate and print a warehouse export form static Future printWarehouseExport({ required BuildContext context, required String warehouseName, required int productId, required String productCode, required String productName, String? stageName, required double passedKg, required int passedPcs, required double issuedKg, required int issuedPcs, String? responsibleName, String? barcodeData, }) async { final pdf = pw.Document(); // Format current date final dt = DateFormat('dd/MM/yyyy HH:mm').format(DateTime.now()); // Add page to PDF pdf.addPage( pw.Page( pageFormat: PdfPageFormat.a4, margin: const pw.EdgeInsets.all(12), build: (pw.Context pdfContext) { return pw.Container( padding: const pw.EdgeInsets.all(12), child: pw.Column( crossAxisAlignment: pw.CrossAxisAlignment.start, children: [ // Title pw.Center( child: pw.Column( children: [ pw.Text( 'PHIẾU XUẤT KHO', style: pw.TextStyle( fontSize: 20, fontWeight: pw.FontWeight.bold, ), ), pw.SizedBox(height: 8), pw.Text( 'Công ty TNHH Cơ Khí Chính Xác Minh Thư', style: const pw.TextStyle(fontSize: 16), ), pw.SizedBox(height: 4), pw.Text( warehouseName, style: const pw.TextStyle(fontSize: 14), ), pw.SizedBox(height: 4), pw.Text( 'Ngày: $dt', style: pw.TextStyle( fontSize: 12, color: PdfColors.grey700, ), ), ], ), ), pw.SizedBox(height: 16), // Product information box pw.Container( decoration: pw.BoxDecoration( border: pw.Border.all(color: PdfColors.black, width: 0.5), borderRadius: pw.BorderRadius.circular(8), ), padding: const pw.EdgeInsets.all(8), child: pw.Column( children: [ pw.Row( children: [ pw.Expanded( child: pw.Column( crossAxisAlignment: pw.CrossAxisAlignment.start, children: [ pw.Text( 'ProductId', style: pw.TextStyle( fontSize: 10, color: PdfColors.grey700, ), ), pw.SizedBox(height: 2), pw.Text( '$productId', style: pw.TextStyle( fontSize: 12, fontWeight: pw.FontWeight.bold, ), ), ], ), ), pw.Expanded( child: pw.Column( crossAxisAlignment: pw.CrossAxisAlignment.start, children: [ pw.Text( 'Mã sản phẩm', style: pw.TextStyle( fontSize: 10, color: PdfColors.grey700, ), ), pw.SizedBox(height: 2), pw.Text( productCode, style: pw.TextStyle( fontSize: 12, fontWeight: pw.FontWeight.bold, ), ), ], ), ), ], ), pw.SizedBox(height: 8), pw.Row( children: [ pw.Expanded( child: pw.Column( crossAxisAlignment: pw.CrossAxisAlignment.start, children: [ pw.Text( 'Tên sản phẩm', style: pw.TextStyle( fontSize: 10, color: PdfColors.grey700, ), ), pw.SizedBox(height: 2), pw.Text( productName, style: pw.TextStyle( fontSize: 12, fontWeight: pw.FontWeight.bold, ), ), ], ), ), pw.Expanded( child: pw.Column( crossAxisAlignment: pw.CrossAxisAlignment.start, children: [ pw.Text( 'Công đoạn', style: pw.TextStyle( fontSize: 10, color: PdfColors.grey700, ), ), pw.SizedBox(height: 2), pw.Text( stageName ?? '-', style: pw.TextStyle( fontSize: 12, fontWeight: pw.FontWeight.bold, ), ), ], ), ), ], ), ], ), ), pw.SizedBox(height: 12), // Quantities box pw.Container( decoration: pw.BoxDecoration( border: pw.Border.all(color: PdfColors.black, width: 0.5), borderRadius: pw.BorderRadius.circular(8), ), padding: const pw.EdgeInsets.all(8), child: pw.Column( crossAxisAlignment: pw.CrossAxisAlignment.start, children: [ pw.Text( 'Số lượng:', style: pw.TextStyle( fontSize: 10, color: PdfColors.grey700, ), ), pw.SizedBox(height: 6), pw.Table( border: pw.TableBorder.all( color: PdfColors.black, width: 0.5, ), children: [ // Header pw.TableRow( decoration: const pw.BoxDecoration( color: PdfColors.grey300, ), children: [ pw.Padding( padding: const pw.EdgeInsets.all(8), child: pw.Text( 'Loại', style: pw.TextStyle( fontWeight: pw.FontWeight.bold, ), ), ), pw.Padding( padding: const pw.EdgeInsets.all(8), child: pw.Text( 'KG', style: pw.TextStyle( fontWeight: pw.FontWeight.bold, ), ), ), pw.Padding( padding: const pw.EdgeInsets.all(8), child: pw.Text( 'PCS', style: pw.TextStyle( fontWeight: pw.FontWeight.bold, ), ), ), ], ), // Passed quantity row pw.TableRow( children: [ pw.Padding( padding: const pw.EdgeInsets.all(8), child: pw.Text('Hàng đạt'), ), pw.Padding( padding: const pw.EdgeInsets.all(8), child: pw.Text(passedKg.toStringAsFixed(2)), ), pw.Padding( padding: const pw.EdgeInsets.all(8), child: pw.Text('$passedPcs'), ), ], ), // Issued quantity row pw.TableRow( children: [ pw.Padding( padding: const pw.EdgeInsets.all(8), child: pw.Text('Hàng lỗi'), ), pw.Padding( padding: const pw.EdgeInsets.all(8), child: pw.Text(issuedKg.toStringAsFixed(2)), ), pw.Padding( padding: const pw.EdgeInsets.all(8), child: pw.Text('$issuedPcs'), ), ], ), ], ), ], ), ), pw.SizedBox(height: 12), // Responsible person box pw.Container( decoration: pw.BoxDecoration( border: pw.Border.all(color: PdfColors.black, width: 0.5), borderRadius: pw.BorderRadius.circular(8), ), padding: const pw.EdgeInsets.all(8), child: pw.Row( children: [ pw.Text( 'Nhân viên kho: ', style: pw.TextStyle( fontSize: 10, color: PdfColors.grey700, ), ), pw.Text( responsibleName ?? '-', style: pw.TextStyle( fontSize: 12, fontWeight: pw.FontWeight.bold, ), ), ], ), ), pw.SizedBox(height: 12), // Barcode section if (barcodeData != null && barcodeData.isNotEmpty) pw.Center( child: pw.BarcodeWidget( barcode: pw.Barcode.code128(), data: barcodeData, width: 200, height: 60, ), ), pw.Spacer(), // Footer signature section pw.Row( mainAxisAlignment: pw.MainAxisAlignment.center, children: [ pw.Container( width: 150, child: pw.Column( children: [ pw.Text( 'Người nhận', style: pw.TextStyle( fontSize: 10, color: PdfColors.grey700, ), ), pw.SizedBox(height: 40), pw.Container( height: 1, color: PdfColors.grey700, ), ], ), ), ], ), ], ), ); }, ), ); // Show print preview dialog await Printing.layoutPdf( onLayout: (PdfPageFormat format) async => pdf.save(), name: 'warehouse_export_${productCode}_${DateTime.now().millisecondsSinceEpoch}.pdf', ); } }