2import 'dart:developer';
4import 'package:aidra_drive/core/constants/assets.dart';
5import 'package:flutter/services.dart';
6import 'package:open_file/open_file.dart';
7import 'package:path_provider/path_provider.dart';
8import 'package:pdf/pdf.dart';
9import 'package:pdf/widgets.dart' as pw;
11import '../../common/models/manifest_document.dart';
16 final pdf = pw.Document();
17 pw.MemoryImage? driverSignatureImage;
18 pw.MemoryImage? warehouseSignatureImage;
22 if (warehouseSignatureBase64!= null && warehouseSignatureBase64.isNotEmpty) {
23 final Uint8List signatureData = base64Decode(warehouseSignatureBase64);
24 warehouseSignatureImage = pw.MemoryImage(signatureData);
26 if (driverSignatureBase64 != null && driverSignatureBase64.isNotEmpty) {
27 final Uint8List signatureData = base64Decode(driverSignatureBase64);
28 driverSignatureImage = pw.MemoryImage(signatureData);
31 log(
'Error loading signature: $e');
35 final Uint8List logoData = logoBytes.buffer.asUint8List();
36 final pw.MemoryImage logoImage = pw.MemoryImage(logoData);
38 final fontData = await rootBundle.load(
'assets/fonts/cairo_regular_font.ttf');
39 final ttf = pw.Font.ttf(fontData);
41 final theme = pw.ThemeData.withFont(
49 if (
date == null)
return '--';
50 return '${date.day}/${date.month}/${date.year}';
56 pageFormat: PdfPageFormat.a4,
57 build: (pw.Context context) {
59 crossAxisAlignment: pw.CrossAxisAlignment.start,
63 mainAxisAlignment: pw.MainAxisAlignment.spaceBetween,
65 pw.Image(logoImage, width: 80, height: 80),
72 fontWeight: pw.FontWeight.bold,
75 pw.SizedBox(height: 10),
77 'Document Number: WB-2515422',
80 fontWeight: pw.FontWeight.bold,
87 pw.SizedBox(height: 20),
91 decoration: pw.BoxDecoration(
92 border: pw.Border.all(),
95 crossAxisAlignment: pw.CrossAxisAlignment.start,
102 _buildTableRowForSide([
103 pw.Text(
'Weighbridge Ticket', style: pw.TextStyle(fontSize: 10)),
107 decoration: pw.BoxDecoration(
108 color: PdfColors.white,
109 border: pw.Border.all(width: 0),
111 const pw.BorderRadius.all(pw.Radius.zero),
114 _buildTableRowForSide([
115 pw.Text(
'Delivery Instructions Comments', style: pw.TextStyle(fontSize: 10)),
119 decoration: pw.BoxDecoration(
120 color: PdfColors.white,
121 border: pw.Border.all(width: 0),
123 const pw.BorderRadius.all(pw.Radius.zero),
128 decoration: pw.BoxDecoration(
129 color: PdfColors.white,
130 border: pw.Border.all(width: 0),
132 const pw.BorderRadius.all(pw.Radius.zero),
135 mainAxisAlignment: pw.MainAxisAlignment.center,
138 'Oil Collection for Waste Transfer Company (ORTCP)',
140 fontWeight: pw.FontWeight.bold),
141 textAlign: pw.TextAlign.center,
143 pw.SizedBox(height: 5),
144 pw.Text(
'Al-Karj Road, Riyadh'),
145 pw.Text(
'H.O.: P.O. Box 14339'),
146 pw.Text(
'Riyadh City 14339 - Saudi Arabia'),
147 pw.Text(
'Tel: 011 240 3700'),
161 _buildTableRowForSide([
162 pw.Text(
'1st Weight', style: pw.TextStyle(fontSize: 10)),
163 pw.Text(
'2nd Weight', style: pw.TextStyle(fontSize: 10)),
164 pw.Text(
'Date/Time', style: pw.TextStyle(fontSize: 10)),
165 pw.Text(
'In / Out', style: pw.TextStyle(fontSize: 10)),
168 _buildTableRowForSide([
169 pw.Text(
'${manifest.firstWeight ?? ''}', style: pw.TextStyle(fontSize: 9)),
170 pw.Text(
'${manifest.secondWeight ?? ''}', style: pw.TextStyle(fontSize: 9)),
171 pw.Text(formatDate(manifest.collectionDate), style: pw.TextStyle(fontSize: 9)),
172 pw.Text(
'In', style: pw.TextStyle(fontSize: 9)),
178 decoration: pw.BoxDecoration(
179 color: PdfColors.grey200,
180 border: pw.Border.all(width: 0),
182 const pw.BorderRadius.all(pw.Radius.zero),
189 alignment: pw.Alignment.center,
190 decoration: pw.BoxDecoration(
192 right: pw.BorderSide(),
193 bottom: pw.BorderSide()),
197 style: pw.TextStyle(fontSize: 10),
204 alignment: pw.Alignment.center,
205 decoration: pw.BoxDecoration(
207 right: pw.BorderSide(),
208 bottom: pw.BorderSide()),
212 style: pw.TextStyle(fontSize: 10),
219 alignment: pw.Alignment.center,
220 decoration: pw.BoxDecoration(
221 border: pw.Border(bottom: pw.BorderSide()),
225 style: pw.TextStyle(fontSize: 10),
236 decoration: pw.BoxDecoration(
237 color: PdfColors.white,
238 border: pw.Border.all(width: 0),
245 alignment: pw.Alignment.center,
246 decoration: pw.BoxDecoration(
248 right: pw.BorderSide(),
249 bottom: pw.BorderSide()),
251 child: pw.Text(
'', style: pw.TextStyle(fontSize: 9)),
257 alignment: pw.Alignment.center,
258 decoration: pw.BoxDecoration(
260 right: pw.BorderSide(),
261 bottom: pw.BorderSide()),
263 child: pw.Text(manifest.reference ??
'', style: pw.TextStyle(fontSize: 9)),
269 alignment: pw.Alignment.center,
270 decoration: pw.BoxDecoration(
271 border: pw.Border(bottom: pw.BorderSide()),
273 child: pw.Text(manifest.vehiclePlate ??
'', style: pw.TextStyle(fontSize: 9)),
281 _buildTableRowForSide([
282 pw.Text(
'Raw Material', style: pw.TextStyle(fontSize: 9)),
283 pw.Text(
'Net Weight', style: pw.TextStyle(fontSize: 10)),
284 pw.Text(
'Price/Tonne', style: pw.TextStyle(fontSize: 10)),
285 pw.Text(
'Total Price', style: pw.TextStyle(fontSize: 10)),
288 _buildTableRowForSide([
289 pw.Text(manifest.productName?.get(
'en_US') ??
'', style: pw.TextStyle(fontSize: 9)),
290 pw.Text(
'${manifest.totalQuantity ?? ''}', style: pw.TextStyle(fontSize: 9)),
291 pw.Text(
'', style: pw.TextStyle(fontSize: 9)),
292 pw.Text(
'', style: pw.TextStyle(fontSize: 9)),
300 _buildTableRowForSide([
301 pw.Text(
'Driver Name', style: pw.TextStyle(fontSize: 10)),
302 pw.Text(
'Driver Signature', style: pw.TextStyle(fontSize: 10)),
308 _buildTableRowForSide([
309 pw.Text(manifest.driver?.name ??
'', style: pw.TextStyle(fontSize: 9)),
311 child: pw.Image(driverSignatureImage!)
319 _buildTableRowForSide([
320 pw.Text(
'Weighbridge Operator', style: pw.TextStyle(fontSize: 10)),
321 pw.Text(
'Operator Signature', style: pw.TextStyle(fontSize: 10)),
327 _buildTableRowForSide([
328 pw.Text(manifest.warehouseResponsible ??
'N/A', style: pw.TextStyle(fontSize: 9)),
330 child: pw.Image(warehouseSignatureImage!)
351 final output = await getTemporaryDirectory();
352 final file = File(
'${output.path}/delivery_voucher.pdf');
353 await file.writeAsBytes(await pdf.save());
354 OpenFile.open(file.path);
357pw.Widget _buildTableRowForSide(
358 List<pw.Widget> cells, {
359 List<int>? columnSpans,
360 bool isHeader =
false,
361 double rowHeight = 40,
363 final spans = columnSpans ?? List.filled(cells.length, 1);
367 decoration: pw.BoxDecoration(
368 color: isHeader ? PdfColors.grey200 : PdfColors.white,
369 border: pw.Border(bottom: pw.BorderSide()),
372 children: List.generate(
374 (index) => pw.Expanded(
377 alignment: pw.Alignment.center,
378 decoration: pw.BoxDecoration(
379 border: index < cells.length - 1
380 ? pw.Border(right: pw.BorderSide())
class App extends StatefulWidget build(BuildContext context)
static const String tajmielogo
final String driverSignature
final String warehouseSignature
Future< void > generateDeliveryVoucher(ManifestDocument manifest,) async