This commit is contained in:
Phuoc Nguyen
2025-10-29 15:52:24 +07:00
parent 2905668358
commit cb4df363ab
6 changed files with 707 additions and 137 deletions

View File

@@ -0,0 +1,368 @@
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<void> 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',
);
}
}