fix UI
This commit is contained in:
368
lib/core/services/print_service.dart
Normal file
368
lib/core/services/print_service.dart
Normal 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',
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user