buildPdfTotalsBlock function
Widget
buildPdfTotalsBlock({
- required List<
InvoiceItem> items, - required InvoiceStyle style,
- InvoiceInfo? info,
- List<
InvoiceAdjustment> adjustments = const [], - double amountPaid = 0,
- bool taxInclusive = false,
- MonetaryPolicy? monetaryPolicy,
- InvoiceTotals? totals,
Builds the financial summary from the centralized calculation engine.
Implementation
pw.Widget buildPdfTotalsBlock({
required List<InvoiceItem> items,
required InvoiceStyle style,
InvoiceInfo? info,
List<InvoiceAdjustment> adjustments = const [],
double amountPaid = 0,
bool taxInclusive = false,
MonetaryPolicy? monetaryPolicy,
InvoiceTotals? totals,
}) {
final policy = monetaryPolicy ?? style.monetaryPolicy;
final resolvedTotals =
totals ??
InvoiceCalculator(policy: policy, taxInclusive: taxInclusive).calculate(
items: items,
adjustments: adjustments,
amountPaid: amountPaid,
);
final formatter = info != null
? style.currencyFormatter(info)
: const CurrencyFormatter();
pw.Widget buildRow(String label, double value, {bool isTotal = false}) {
final textStyle = isTotal
? style.boldBodyTextStyle.copyWith(fontSize: style.subtitleFontSize)
: style.bodyTextStyle;
return pw.Padding(
padding: const pw.EdgeInsets.symmetric(vertical: 4),
child: pw.Row(
mainAxisAlignment: pw.MainAxisAlignment.spaceBetween,
children: [
pw.Expanded(
child: pw.Text(
label,
style: isTotal
? textStyle
: textStyle.copyWith(color: style.mutedTextColor),
),
),
pw.SizedBox(width: 12),
pw.Text(formatter.format(value), style: textStyle),
],
),
);
}
return pw.Container(
width: 270,
alignment: pw.Alignment.centerRight,
child: pw.Column(
crossAxisAlignment: pw.CrossAxisAlignment.stretch,
children: [
buildRow(style.label('subtotal', 'Subtotal'), resolvedTotals.subtotal),
if (resolvedTotals.discount != 0)
buildRow(
style.label('discount', 'Discount'),
-resolvedTotals.discount.abs(),
),
if (resolvedTotals.tax != 0)
buildRow(style.label('tax', 'Tax'), resolvedTotals.tax),
for (final entry in resolvedTotals.adjustments)
buildRow(entry.adjustment.label, switch (entry.adjustment.type) {
InvoiceAdjustmentType.discount ||
InvoiceAdjustmentType.withholding => -entry.amount.abs(),
InvoiceAdjustmentType.shipping ||
InvoiceAdjustmentType.fee => entry.amount,
}),
pw.Divider(color: PdfColors.grey300, thickness: 0.5),
buildRow(
style.label('total', 'Total'),
resolvedTotals.grandTotal,
isTotal: true,
),
if (resolvedTotals.amountPaid != 0)
buildRow(
style.label('amountPaid', 'Amount Paid'),
-resolvedTotals.amountPaid.abs(),
),
if (resolvedTotals.amountPaid != 0)
buildRow(
style.label('balanceDue', 'Balance Due'),
resolvedTotals.balanceDue,
isTotal: true,
),
],
),
);
}