3import 'package:another_flushbar/flushbar.dart';
4import 'package:connect/core/constants/assets.dart';
5import 'package:connect/core/services/service_locator.dart';
6import 'package:connect/core/ui/widgets/custom_snackbar.dart';
7import 'package:connect/core/utils/number_conversion.dart';
8import 'package:flutter/material.dart';
9import 'package:flutter/services.dart';
10import 'package:flutter_screenutil/flutter_screenutil.dart';
11import 'package:open_filex/open_filex.dart';
12import 'package:pdf/pdf.dart';
13import 'package:pdf/widgets.dart' as pw;
14import 'package:path_provider/path_provider.dart';
16import '../../../../../../../../../../core/api/api_client.dart';
19 {required String collectionName}) async {
22 final response = await apiClient.get(
26 'https://dev-api.aidra.tech/document/collectionDocument/$collectionName',
32 return CollectionVoucherDocumentModel.fromJson(response);
39 String collectionName,
42 final data = await
fetchData(collectionName: collectionName);
46 margin: EdgeInsets.all(10),
47 borderRadius: BorderRadius.circular(10),
49 message:
'Voucher generation failed. Please try again.',
50 duration: Duration(seconds: 2),
55 final pdf = pw.Document();
58 final fontData = await rootBundle.load(
'assets/fonts/notokufi_font.ttf');
59 final ttf = pw.Font.ttf(fontData);
62 await rootBundle.load(
"assets/fonts/NotoKufiArabic-Bold.ttf");
63 final ttf2 = pw.Font.ttf(boldyFont);
66 final theme = pw.ThemeData.withFont(
74 String extractName(String? productName) {
75 if (productName == null || productName.isEmpty) {
79 final Map<String, dynamic> decoded = jsonDecode(productName);
80 return decoded[
'en_US'] ??
'';
83 final qrCode = pw.BarcodeWidget(
84 barcode: pw.Barcode.qrCode(),
85 data: data?.collection.name ??
'',
90 String _formatDate(String? dateString) {
91 if (dateString == null || dateString.isEmpty)
return '--';
94 DateTime parsedDate = DateTime.parse(dateString);
95 return '${parsedDate.day}/${parsedDate.month}/${parsedDate.year}';
101 final directorSignature = pw.Column(
104 'Driver / Collector : Driver 26',
106 font: ttf, fontSize: 10, fontWeight: pw.FontWeight.bold),
116 fit: pw.BoxFit.contain,
123 final collectorSignature = pw.Column(
126 'Collection Point : ${data?.collection.partnerId?.name ?? ''}',
128 font: ttf, fontSize: 10, fontWeight: pw.FontWeight.bold),
140 fit: pw.BoxFit.contain,
150 pageFormat: PdfPageFormat.a4,
154 crossAxisAlignment: pw.CrossAxisAlignment.center,
157 'Collection Voucher',
159 font: ttf, fontSize: 20, fontWeight: pw.FontWeight.bold),
161 pw.SizedBox(height: 8),
163 'Document Number : ${data?.collection.name ?? ''}',
167 fontWeight: pw.FontWeight.normal,
168 color: PdfColors.blue,
171 pw.SizedBox(height: 25),
173 alignment: pw.Alignment.centerLeft,
175 crossAxisAlignment: pw.CrossAxisAlignment.start,
179 textDirection: pw.TextDirection.rtl,
183 fontWeight: pw.FontWeight.bold,
184 color: PdfColors.blue,
188 data?.collection.partnerId?.name ??
'',
189 textDirection: pw.TextDirection.rtl,
193 fontWeight: pw.FontWeight.normal),
195 pw.SizedBox(height: 8),
201 fontWeight: pw.FontWeight.bold,
202 color: PdfColors.blue,
206 data?.collection.partnerId?.street ??
'',
207 textDirection: pw.TextDirection.rtl,
211 fontWeight: pw.FontWeight.normal,
217 pw.SizedBox(height: 30),
219 border: pw.TableBorder.all(),
224 padding: const pw.EdgeInsets.all(8),
229 fontWeight: pw.FontWeight.bold,
234 padding: const pw.EdgeInsets.all(8),
236 _formatDate(data?.collection
238 style: pw.TextStyle(font: ttf),
242 padding: const pw.EdgeInsets.all(8),
247 fontWeight: pw.FontWeight.bold,
252 padding: const pw.EdgeInsets.all(8),
254 data?.collection.paymentBillRef ??
'',
255 style: pw.TextStyle(font: ttf),
263 padding: const pw.EdgeInsets.all(8),
265 'Collection Order Ref',
268 fontWeight: pw.FontWeight.bold,
273 padding: const pw.EdgeInsets.all(8),
275 data?.collection.collectionOrderRef ??
'',
276 style: pw.TextStyle(font: ttf),
280 padding: const pw.EdgeInsets.all(8),
285 fontWeight: pw.FontWeight.bold,
290 padding: const pw.EdgeInsets.all(8),
293 style: pw.TextStyle(font: ttf),
300 pw.SizedBox(height: 25),
303 border: pw.TableBorder.all(),
307 decoration: pw.BoxDecoration(color: PdfColors.grey200),
308 children: [
'Product',
'Quantity Received',
'Quantity Billed']
309 .map((header) => pw.Container(
310 padding: const pw.EdgeInsets.all(8),
311 alignment: pw.Alignment.center,
316 fontWeight: pw.FontWeight.bold,
326 padding: const pw.EdgeInsets.all(8),
327 alignment: pw.Alignment.centerLeft,
329 extractName(data?.product),
330 style: pw.TextStyle(font: ttf),
334 padding: const pw.EdgeInsets.all(8),
335 alignment: pw.Alignment.centerLeft,
337 '${NumberConversionService.convertAndFormatWeight(data?.quantityReceived)} ',
338 style: pw.TextStyle(font: ttf),
342 padding: const pw.EdgeInsets.all(8),
343 alignment: pw.Alignment.centerLeft,
345 '${NumberConversionService.convertAndFormatWeight(data?.quantityBilled)} ',
346 style: pw.TextStyle(font: ttf),
353 pw.SizedBox(height: 30),
355 mainAxisAlignment: pw.MainAxisAlignment.spaceBetween,
356 children: [directorSignature, collectorSignature],
358 pw.SizedBox(height: 30),
362 pw.Column(children: [
364 mainAxisAlignment: pw.MainAxisAlignment.spaceBetween,
367 pw.SizedBox(width: 10),
370 pw.SizedBox(height: 10),
372 'STRICTLY CONFIDENTIAL',
376 fontWeight: pw.FontWeight.normal,
377 color: const PdfColor(0.5, 0.5, 0.5),
389 final output = await getTemporaryDirectory();
390 final file = File(
'${output.path}/collection_voucher_document.pdf');
391 await file.writeAsBytes(await pdf.save());
392 OpenFilex.open(file.path);
395class CollectionVoucherDocumentModel {
398 final String? product;
399 final double? quantityBilled;
400 final double? quantityReceived;
402 CollectionVoucherDocumentModel({
405 required this.product,
406 required this.quantityBilled,
407 required this.quantityReceived,
410 factory CollectionVoucherDocumentModel.fromJson(Map<String, dynamic> json) {
411 return CollectionVoucherDocumentModel(
412 collection: Collection.fromJson(json[
'collection']),
413 priceUnit: json[
'priceUnit']?.toDouble() ?? 0.0,
414 product: json[
'product'] ??
'',
415 quantityBilled: json[
'quantityBilled']?.toDouble() ?? 0,
416 quantityReceived: json[
'quantityReceived']?.toDouble() ?? 0,
420 Map<String, dynamic>
toJson() {
425 'quantityBilled': quantityBilled,
426 'quantityReceived': quantityReceived,
432 final String? billStatus;
433 final String? collectionConfirmRef;
434 final String? collectionOrderRef;
435 final String? confirmationDate;
439 final String? paymentBillRef;
440 final String? receiptStatus;
441 final String? status;
444 required this.billStatus,
445 required this.collectionConfirmRef,
446 required this.collectionOrderRef,
447 required this.confirmationDate,
451 required this.paymentBillRef,
452 required this.receiptStatus,
453 required this.status,
456 factory Collection.
fromJson(Map<String, dynamic> json) {
458 billStatus: json[
'billStatus'] ??
'',
459 collectionConfirmRef: json[
'collectionConfirmRef'] ??
'',
460 collectionOrderRef: json[
'collectionOrderRef'] ??
'',
461 confirmationDate: json[
'confirmationDate'] ??
'',
463 name: json[
'name'] ??
'',
464 partnerId: Partner.fromJson(json[
'partnerId']),
465 paymentBillRef: json[
'paymentBillRef'] ??
'',
466 receiptStatus: json[
'receiptStatus'] ??
'',
467 status: json[
'status'] ??
'',
471 Map<String, dynamic>
toJson() {
473 'billStatus': billStatus,
474 'collectionConfirmRef': collectionConfirmRef,
475 'collectionOrderRef': collectionOrderRef,
476 'confirmationDate': confirmationDate,
480 'paymentBillRef': paymentBillRef,
481 'receiptStatus': receiptStatus,
488 final String? contactName;
490 final bool? isCompany;
493 final String? partnerLatitude;
494 final String? partnerLongitude;
495 final String? street;
498 required this.contactName,
500 required this.isCompany,
502 required this.parentId,
503 required this.partnerLatitude,
504 required this.partnerLongitude,
505 required this.street,
508 factory Partner.
fromJson(Map<String, dynamic> json) {
510 contactName: json[
'contactName'] ??
'',
512 isCompany: json[
'isCompany'] ??
false,
513 name: json[
'name'] ??
'',
514 parentId: json[
'parentId'] ?? 0,
515 partnerLatitude: json[
'partnerLatitude'] ??
'',
516 partnerLongitude: json[
'partnerLongitude'] ??
'',
517 street: json[
'street'] ??
'',
521 Map<String, dynamic>
toJson() {
523 'contactName': contactName,
525 'isCompany': isCompany,
527 'parentId': parentId,
528 'partnerLatitude': partnerLatitude,
529 'partnerLongitude': partnerLongitude,
class CalenderTransactionsSummaryVeiw extends StatefulWidget collection
static const String collectorSign
static const String directorSign
factory CurrencyModel fromJson(Map< String, dynamic > json)
final Color backgroundColor
Future< CollectionVoucherDocumentModel?> fetchData({required String collectionName}) async
Future< void > generateCollectionVoucher(String collectionName, BuildContext context,) async
override Widget build(BuildContext context)
Map< String, dynamic > toJson()