diff --git a/e-invoice-domain/src/main/kotlin/net/codinux/invoicing/calculator/AmountsCalculator.kt b/e-invoice-domain/src/main/kotlin/net/codinux/invoicing/calculator/AmountsCalculator.kt new file mode 100644 index 0000000..fe67927 --- /dev/null +++ b/e-invoice-domain/src/main/kotlin/net/codinux/invoicing/calculator/AmountsCalculator.kt @@ -0,0 +1,44 @@ +package net.codinux.invoicing.calculator + +import net.codinux.invoicing.mapper.MustangMapper +import net.codinux.invoicing.model.Invoice +import net.codinux.invoicing.model.TotalAmounts +import org.mustangproject.ZUGFeRD.IExportableTransaction +import org.mustangproject.ZUGFeRD.TransactionCalculator +import java.math.BigDecimal + +open class AmountsCalculator { + + protected open val mapper by lazy { MustangMapper() } // lazy to avoid circular dependency creation with MustangMapper + + + open fun calculateTotalAmounts(invoice: Invoice) = + calculateTotalAmounts(mapper.mapToTransaction(invoice)) + + open fun calculateTotalAmounts(invoice: IExportableTransaction): TotalAmounts { + val calculator = MustangTransactionCalculator(invoice) + + return TotalAmounts( + lineTotalAmount = calculator.lineTotalAmount, + chargeTotalAmount = calculator.chargeTotal, + allowanceTotalAmount = calculator.allowanceTotal, + taxBasisTotalAmount = calculator.taxBasisTotalAmount, + taxTotalAmount = calculator.taxTotalAmount, + grandTotalAmount = calculator.grandTotal, + totalPrepaidAmount = calculator.totalPrepaidAmount, + duePayableAmount = calculator.duePayableAmount + ) + } + + + protected open class MustangTransactionCalculator(invoice: IExportableTransaction): TransactionCalculator(invoice) { + val lineTotalAmount: BigDecimal = this.total + + val taxBasisTotalAmount: BigDecimal = this.taxBasis + val taxTotalAmount: BigDecimal by lazy { this.getGrandTotal().subtract(this.taxBasis) } + + val totalPrepaidAmount: BigDecimal = this.totalPrepaid + val duePayableAmount: BigDecimal by lazy { this.getGrandTotal().subtract(this.totalPrepaid) } + } + +} \ No newline at end of file diff --git a/e-invoice-domain/src/main/kotlin/net/codinux/invoicing/mapper/MustangMapper.kt b/e-invoice-domain/src/main/kotlin/net/codinux/invoicing/mapper/MustangMapper.kt index c1177d8..b1114e1 100644 --- a/e-invoice-domain/src/main/kotlin/net/codinux/invoicing/mapper/MustangMapper.kt +++ b/e-invoice-domain/src/main/kotlin/net/codinux/invoicing/mapper/MustangMapper.kt @@ -1,5 +1,6 @@ package net.codinux.invoicing.mapper +import net.codinux.invoicing.calculator.AmountsCalculator import net.codinux.invoicing.model.AmountAdjustments import net.codinux.invoicing.model.ChargeOrAllowance import net.codinux.invoicing.model.InvoiceItem @@ -13,7 +14,9 @@ import java.time.LocalDate import java.time.ZoneId import java.util.* -open class MustangMapper { +open class MustangMapper( + protected open val calculator: AmountsCalculator = AmountsCalculator() +) { open fun mapToTransaction(invoice: net.codinux.invoicing.model.Invoice): IExportableTransaction = Invoice().apply { this.number = invoice.invoiceNumber @@ -33,6 +36,10 @@ open class MustangMapper { adjustments.charges.forEach { this.addCharge(mapCharge(it)) } adjustments.allowances.forEach { this.addAllowance(mapAllowance(it)) } } + + if (invoice.totalAmounts == null) { + invoice.totalAmounts = calculator.calculateTotalAmounts(this) + } } open fun mapParty(party: Party): TradeParty = TradeParty( @@ -95,6 +102,8 @@ open class MustangMapper { buyerReference = invoice.referenceNumber, amountAdjustments = mapAmountAdjustments(invoice), + + totalAmounts = calculator.calculateTotalAmounts(invoice) ) open fun mapParty(party: TradeParty) = Party(