162 lines
6.1 KiB
Dart
162 lines
6.1 KiB
Dart
import 'package:flutter/widgets.dart' show AssetImage;
|
|
import 'package:pdf/pdf.dart';
|
|
import 'package:pdf/widgets.dart' as pw;
|
|
import 'package:printing/printing.dart';
|
|
import '../../models/document_model.dart';
|
|
|
|
class PdfService {
|
|
static Future<void> generateAndPrintReceipt(DocumentModel document) async {
|
|
final pdf = pw.Document();
|
|
|
|
// Load PFM logo asset
|
|
final logoImage = await flutterImageProvider(const AssetImage('assets/logo.png'));
|
|
|
|
// Add page
|
|
pdf.addPage(
|
|
pw.Page(
|
|
pageFormat: PdfPageFormat.a4,
|
|
build: (pw.Context context) {
|
|
return pw.Column(
|
|
crossAxisAlignment: pw.CrossAxisAlignment.start,
|
|
children: [
|
|
// Header & Title
|
|
pw.Row(
|
|
mainAxisAlignment: pw.MainAxisAlignment.spaceBetween,
|
|
children: [
|
|
pw.Text('RECEIPT OF DELIVERY', style: pw.TextStyle(fontSize: 24, fontWeight: pw.FontWeight.bold)),
|
|
pw.SizedBox(
|
|
width: 60,
|
|
height: 60,
|
|
child: pw.Image(logoImage),
|
|
),
|
|
]
|
|
),
|
|
pw.SizedBox(height: 20),
|
|
|
|
// Document Headers
|
|
pw.Container(
|
|
padding: const pw.EdgeInsets.all(10),
|
|
decoration: pw.BoxDecoration(
|
|
border: pw.Border.all(color: PdfColors.grey),
|
|
borderRadius: const pw.BorderRadius.all(pw.Radius.circular(8)),
|
|
),
|
|
child: pw.Column(
|
|
crossAxisAlignment: pw.CrossAxisAlignment.start,
|
|
children: [
|
|
_buildTextRow('Tanggal', document.tanggal),
|
|
_buildTextRow('No PO', document.noPo),
|
|
_buildTextRow('No SO', document.noSo),
|
|
_buildTextRow('No DO', document.noDo),
|
|
]
|
|
),
|
|
),
|
|
pw.SizedBox(height: 20),
|
|
|
|
// Shipment Data
|
|
pw.Text('Shipment Details', style: pw.TextStyle(fontSize: 16, fontWeight: pw.FontWeight.bold)),
|
|
pw.SizedBox(height: 8),
|
|
pw.Container(
|
|
padding: const pw.EdgeInsets.all(10),
|
|
decoration: pw.BoxDecoration(
|
|
color: PdfColors.grey100,
|
|
borderRadius: const pw.BorderRadius.all(pw.Radius.circular(8)),
|
|
),
|
|
child: pw.Column(
|
|
crossAxisAlignment: pw.CrossAxisAlignment.start,
|
|
children: [
|
|
_buildTextRow('Kepada Yth', document.kepadaYth),
|
|
_buildTextRow('Order Untuk', document.orderUntuk),
|
|
_buildTextRow('Alamat', document.alamat),
|
|
_buildTextRow('Plat Truk', document.platTruk),
|
|
_buildTextRow('Nama Driver', document.namaDriver),
|
|
]
|
|
),
|
|
),
|
|
pw.SizedBox(height: 20),
|
|
|
|
// Items Table
|
|
pw.Text('Items Delivered', style: pw.TextStyle(fontSize: 16, fontWeight: pw.FontWeight.bold)),
|
|
pw.SizedBox(height: 8),
|
|
pw.Table.fromTextArray(
|
|
context: context,
|
|
border: pw.TableBorder.all(color: PdfColors.grey),
|
|
headerDecoration: const pw.BoxDecoration(color: PdfColors.grey300),
|
|
headerHeight: 25,
|
|
cellHeight: 25,
|
|
columnWidths: {
|
|
0: const pw.FixedColumnWidth(80), // SKU
|
|
1: const pw.FlexColumnWidth(2), // Nama Barang
|
|
2: const pw.FixedColumnWidth(70), // Banyak
|
|
3: const pw.FixedColumnWidth(70), // Jumlah
|
|
},
|
|
cellAlignments: {
|
|
0: pw.Alignment.centerLeft,
|
|
1: pw.Alignment.centerLeft,
|
|
2: pw.Alignment.centerRight,
|
|
3: pw.Alignment.centerRight,
|
|
},
|
|
headers: ['Nomor SKU', 'Nama Barang', 'Banyak', 'Jumlah'],
|
|
data: document.items.map((item) {
|
|
return [
|
|
item.nomorSku,
|
|
item.namaBarang,
|
|
item.banyak,
|
|
item.jumlah,
|
|
];
|
|
}).toList(),
|
|
),
|
|
|
|
pw.Spacer(),
|
|
|
|
// Footer & Signatures
|
|
pw.Row(
|
|
mainAxisAlignment: pw.MainAxisAlignment.spaceBetween,
|
|
children: [
|
|
pw.Column(
|
|
children: [
|
|
pw.SizedBox(height: 40),
|
|
pw.Text(document.namaDriver.isNotEmpty ? document.namaDriver : '_______________________', style: pw.TextStyle(fontWeight: pw.FontWeight.bold)),
|
|
pw.SizedBox(height: 4),
|
|
pw.Text('Pengirim (Driver)'),
|
|
]
|
|
),
|
|
pw.Column(
|
|
children: [
|
|
pw.SizedBox(height: 40),
|
|
pw.Text(document.namaPenerima.isNotEmpty ? document.namaPenerima : '_______________________', style: pw.TextStyle(fontWeight: pw.FontWeight.bold)),
|
|
pw.SizedBox(height: 4),
|
|
pw.Text('Penerima (Penjaga Toko)'),
|
|
]
|
|
)
|
|
]
|
|
)
|
|
],
|
|
);
|
|
},
|
|
),
|
|
);
|
|
|
|
// Prompt user to view/print/save the PDF natively
|
|
await Printing.layoutPdf(
|
|
onLayout: (PdfPageFormat format) async => pdf.save(),
|
|
format: PdfPageFormat.a4,
|
|
name: 'Document_${document.noDo.replaceAll('/', '_')}',
|
|
);
|
|
}
|
|
|
|
static pw.Widget _buildTextRow(String label, String value) {
|
|
return pw.Padding(
|
|
padding: const pw.EdgeInsets.symmetric(vertical: 2),
|
|
child: pw.Row(
|
|
crossAxisAlignment: pw.CrossAxisAlignment.start,
|
|
children: [
|
|
pw.SizedBox(width: 100, child: pw.Text(label, style: pw.TextStyle(fontWeight: pw.FontWeight.bold))),
|
|
pw.Expanded(
|
|
child: pw.Text(': $value', softWrap: true),
|
|
),
|
|
]
|
|
)
|
|
);
|
|
}
|
|
}
|