Created
June 18, 2025 16:58
-
-
Save gboliknow/9df593e3505f3cb03f09bfa063597728 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| pdf.addPage( | |
| pw.MultiPage( | |
| pageFormat: PdfPageFormat.a4, | |
| margin: const pw.EdgeInsets.all(24), | |
| build: (pw.Context context) { | |
| return [ | |
| _buildStoreInfoSection(invoice, formattedDate, storeLogo), | |
| pw.SizedBox(height: 24), | |
| _buildBillToInfo(invoice), | |
| pw.SizedBox(height: 24), | |
| _buildInvoiceSummaryCard(invoice, itemImages), | |
| pw.SizedBox(height: 24), | |
| if (invoice.termsAndConditions != "") _buildTermsAndConditions(invoice.termsAndConditions), | |
| if (invoice.supportingImages.isNotEmpty) ...[ | |
| pw.SizedBox(height: 10), | |
| _buildSupportingImages(invoice.supportingImages, supportingImages), | |
| pw.SizedBox(height: 10), | |
| ], | |
| pw.SizedBox(height: 40), | |
| _buildFooter(vendawLogo), | |
| ]; | |
| }, | |
| ), | |
| ); | |
| //InvoiceSummaryCard Section | |
| static pw.Widget _buildInvoiceSummaryCard(InvoiceModel invoice, Map<String, pw.MemoryImage> loadedItemImages) { | |
| return pw.Container( | |
| decoration: pw.BoxDecoration( | |
| border: pw.Border.all(color: flutterToPdfColor(AppColors.grey100)), | |
| borderRadius: pw.BorderRadius.circular(8), | |
| ), | |
| child: pw.Column( | |
| children: [ | |
| _buildInvoiceSummaryHeader(), | |
| _buildInvoiceItemList(invoice, loadedItemImages), | |
| _buildInvoiceSummaryDetails(invoice), | |
| _buildPaymentScheduleSection(invoice), | |
| ], | |
| ), | |
| ); | |
| } | |
| static pw.Widget _buildInvoiceItemList(InvoiceModel invoice, Map<String, pw.MemoryImage> loadedItemImages) { | |
| return pw.Padding( | |
| padding: const pw.EdgeInsets.all(8), | |
| child: pw.Column( | |
| mainAxisSize: pw.MainAxisSize.min, | |
| children: invoice.items | |
| .map( | |
| (item) => pw.Padding( | |
| padding: const pw.EdgeInsets.only(bottom: 12), | |
| child: _buildInvoiceSummaryItem(item, loadedItemImages), | |
| ), | |
| ) | |
| .toList(), | |
| ), | |
| ); | |
| } | |
| static pw.Widget _buildInvoiceSummaryDetails(InvoiceModel invoice) { | |
| double total = (invoice.total - invoice.fee).toDouble(); | |
| return pw.Padding( | |
| padding: const pw.EdgeInsets.symmetric(horizontal: 8), | |
| child: pw.Column( | |
| crossAxisAlignment: pw.CrossAxisAlignment.start, | |
| children: [ | |
| // pw.SizedBox(height: 8), | |
| _buildDottedLine(), | |
| pw.SizedBox(height: 16), | |
| _buildOrderSummaryPriceInfo("Subtotal", AppUtils.formatCurrencyWithoutSymbol(invoice.subtotal.toDouble())), | |
| pw.SizedBox(height: 8), | |
| _buildOrderSummaryPriceInfo("Discount", AppUtils.formatCurrencyWithoutSymbol(invoice.discount.toDouble())), | |
| pw.SizedBox(height: 8), | |
| _buildOrderSummaryPriceInfo( | |
| "Delivery Fee", AppUtils.formatCurrencyWithoutSymbol(invoice.deliveryFee.toDouble())), | |
| if (invoice.damagesCharge != 0) ...[ | |
| pw.SizedBox(height: 8), | |
| _buildOrderSummaryPriceInfo( | |
| "Damages Charge", AppUtils.formatCurrencyWithoutSymbol(invoice.damagesCharge.toDouble())), | |
| ], | |
| if (invoice.serviceCharge != 0) ...[ | |
| pw.SizedBox(height: 8), | |
| _buildOrderSummaryPriceInfo( | |
| "Service Charge", AppUtils.formatCurrencyWithoutSymbol(invoice.serviceCharge.toDouble())), | |
| ], | |
| if (invoice.vat != 0) ...[ | |
| pw.SizedBox(height: 8), | |
| _buildOrderSummaryPriceInfo("VAT", "${invoice.vat}%", isPrice: false), | |
| ], | |
| pw.SizedBox(height: 4), | |
| pw.Container( | |
| height: 1, | |
| width: double.infinity, | |
| color: flutterToPdfColor(AppColors.grey300), | |
| ), | |
| pw.SizedBox(height: 4), | |
| if (invoice.status.toLowerCase() == "partial_payment") | |
| _buildOrderSummaryPriceInfo( | |
| "Amount Paid", | |
| AppUtils.formatCurrencyWithoutSymbol( | |
| invoice.payments.isEmpty ? 0.0 : double.parse(invoice.payments.first.amount)), | |
| isBold: true, | |
| ) | |
| else | |
| _buildOrderSummaryPriceInfo( | |
| "Amount Paid", | |
| AppUtils.formatCurrencyWithoutSymbol(total), | |
| isBold: true, | |
| ), | |
| pw.SizedBox(height: 8), | |
| ], | |
| ), | |
| ); | |
| } | |
| static pw.Widget _buildPaymentScheduleSection(InvoiceModel invoice) { | |
| final sortedSchedule = [...invoice.paymentSchedule] | |
| ..sort((a, b) => (a.dueDate ?? DateTime(2100)).compareTo(b.dueDate ?? DateTime(2100))); | |
| if (sortedSchedule.isEmpty) return pw.SizedBox(); | |
| return pw.Container( | |
| width: double.infinity, | |
| padding: const pw.EdgeInsets.all(8), | |
| decoration: pw.BoxDecoration( | |
| color: flutterToPdfColor(AppColors.invoiceGrey), | |
| borderRadius: const pw.BorderRadius.only( | |
| bottomLeft: pw.Radius.circular(8), | |
| bottomRight: pw.Radius.circular(8), | |
| ), | |
| ), | |
| child: pw.Column( | |
| children: sortedSchedule.asMap().entries.map((entry) { | |
| final index = entry.key; | |
| final schedule = entry.value; | |
| return pw.Container( | |
| margin: pw.EdgeInsets.only(bottom: index < sortedSchedule.length - 1 ? 5 : 0), | |
| child: pw.Column( | |
| children: [ | |
| _buildPaymentScheduleItem(schedule, index, invoice.allowPartPayment), | |
| if (index < sortedSchedule.length - 1) | |
| pw.Container( | |
| margin: const pw.EdgeInsets.symmetric(vertical: 5), | |
| height: 1, | |
| width: double.infinity, | |
| color: flutterToPdfColor(AppColors.white.withOpacity(0.4)), | |
| ), | |
| ], | |
| ), | |
| ); | |
| }).toList(), | |
| ), | |
| ); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment