Added AmountAdjustments
This commit is contained in:
parent
556c59ba3a
commit
f1a364866c
|
@ -1,10 +1,13 @@
|
||||||
package net.codinux.invoicing.mapper
|
package net.codinux.invoicing.mapper
|
||||||
|
|
||||||
|
import net.codinux.invoicing.model.AmountAdjustments
|
||||||
|
import net.codinux.invoicing.model.ChargeOrAllowance
|
||||||
import net.codinux.invoicing.model.InvoiceItem
|
import net.codinux.invoicing.model.InvoiceItem
|
||||||
import net.codinux.invoicing.model.Party
|
import net.codinux.invoicing.model.Party
|
||||||
import org.mustangproject.*
|
import org.mustangproject.*
|
||||||
import org.mustangproject.ZUGFeRD.IExportableTransaction
|
import org.mustangproject.ZUGFeRD.IExportableTransaction
|
||||||
import org.mustangproject.ZUGFeRD.IZUGFeRDExportableItem
|
import org.mustangproject.ZUGFeRD.IZUGFeRDExportableItem
|
||||||
|
import java.math.BigDecimal
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
import java.time.LocalDate
|
import java.time.LocalDate
|
||||||
import java.time.ZoneId
|
import java.time.ZoneId
|
||||||
|
@ -24,6 +27,12 @@ open class MustangMapper {
|
||||||
this.paymentTermDescription = invoice.paymentDescription
|
this.paymentTermDescription = invoice.paymentDescription
|
||||||
|
|
||||||
this.referenceNumber = invoice.buyerReference
|
this.referenceNumber = invoice.buyerReference
|
||||||
|
|
||||||
|
invoice.amountAdjustments?.let { adjustments ->
|
||||||
|
this.totalPrepaidAmount = adjustments.prepaidAmounts
|
||||||
|
adjustments.charges.forEach { this.addCharge(mapCharge(it)) }
|
||||||
|
adjustments.allowances.forEach { this.addAllowance(mapAllowance(it)) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun mapParty(party: Party): TradeParty = TradeParty(
|
open fun mapParty(party: Party): TradeParty = TradeParty(
|
||||||
|
@ -52,6 +61,26 @@ open class MustangMapper {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected open fun mapCharge(charge: ChargeOrAllowance) = Charge(charge.actualAmount).apply {
|
||||||
|
this.percent = charge.calculationPercent
|
||||||
|
|
||||||
|
this.reason = charge.reason
|
||||||
|
this.reasonCode = charge.reasonCode
|
||||||
|
|
||||||
|
this.taxPercent = charge.taxRateApplicablePercent
|
||||||
|
this.categoryCode = charge.taxCategoryCode
|
||||||
|
}
|
||||||
|
|
||||||
|
protected open fun mapAllowance(allowance: ChargeOrAllowance) = Allowance(allowance.actualAmount).apply {
|
||||||
|
this.percent = allowance.calculationPercent
|
||||||
|
|
||||||
|
this.reason = allowance.reason
|
||||||
|
this.reasonCode = allowance.reasonCode
|
||||||
|
|
||||||
|
this.taxPercent = allowance.taxRateApplicablePercent
|
||||||
|
this.categoryCode = allowance.taxCategoryCode
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
open fun mapToInvoice(invoice: Invoice) = net.codinux.invoicing.model.Invoice(
|
open fun mapToInvoice(invoice: Invoice) = net.codinux.invoicing.model.Invoice(
|
||||||
invoiceNumber = invoice.number,
|
invoiceNumber = invoice.number,
|
||||||
|
@ -63,7 +92,9 @@ open class MustangMapper {
|
||||||
dueDate = map(invoice.dueDate ?: invoice.paymentTerms?.dueDate),
|
dueDate = map(invoice.dueDate ?: invoice.paymentTerms?.dueDate),
|
||||||
paymentDescription = invoice.paymentTermDescription ?: invoice.paymentTerms?.description,
|
paymentDescription = invoice.paymentTermDescription ?: invoice.paymentTerms?.description,
|
||||||
|
|
||||||
buyerReference = invoice.referenceNumber
|
buyerReference = invoice.referenceNumber,
|
||||||
|
|
||||||
|
amountAdjustments = mapAmountAdjustments(invoice),
|
||||||
)
|
)
|
||||||
|
|
||||||
open fun mapParty(party: TradeParty) = Party(
|
open fun mapParty(party: TradeParty) = Party(
|
||||||
|
@ -76,6 +107,23 @@ open class MustangMapper {
|
||||||
item.product.name, item.quantity, item.product.unit, item.price, item.product.vatPercent, item.product.description.takeUnless { it.isBlank() }
|
item.product.name, item.quantity, item.product.unit, item.price, item.product.vatPercent, item.product.description.takeUnless { it.isBlank() }
|
||||||
)
|
)
|
||||||
|
|
||||||
|
protected open fun mapAmountAdjustments(invoice: Invoice): AmountAdjustments? {
|
||||||
|
if ((invoice.totalPrepaidAmount == null || invoice.totalPrepaidAmount == BigDecimal.ZERO) && invoice.zfCharges.isEmpty() && invoice.zfAllowances.isEmpty()) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
return AmountAdjustments(
|
||||||
|
invoice.totalPrepaidAmount,
|
||||||
|
invoice.zfCharges.mapNotNull { mapChargeOrAllowance(it as? Charge) },
|
||||||
|
invoice.zfAllowances.mapNotNull { mapChargeOrAllowance(it as? Allowance ?: it as? Charge) }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun mapChargeOrAllowance(chargeOrAllowance: Charge?) = chargeOrAllowance?.let {
|
||||||
|
ChargeOrAllowance(it.totalAmount, null, null, it.percent, it.reason, it.reasonCode, it.taxPercent, it.categoryCode)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@JvmName("mapNullable")
|
@JvmName("mapNullable")
|
||||||
protected fun map(date: LocalDate?) =
|
protected fun map(date: LocalDate?) =
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
package net.codinux.invoicing.model
|
||||||
|
|
||||||
|
import java.math.BigDecimal
|
||||||
|
|
||||||
|
class AmountAdjustments(
|
||||||
|
/**
|
||||||
|
* Vorauszahlungen.
|
||||||
|
*/
|
||||||
|
val prepaidAmounts: BigDecimal = BigDecimal.ZERO,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Zusätzliche Gebühren.
|
||||||
|
*/
|
||||||
|
val charges: List<ChargeOrAllowance> = emptyList(),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abzüge / Nachlässe.
|
||||||
|
*/
|
||||||
|
val allowances: List<ChargeOrAllowance> = emptyList()
|
||||||
|
) {
|
||||||
|
override fun toString() = "${prepaidAmounts.toPlainString()} prepaid, ${charges.size} charges, ${allowances.size} allowances"
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
package net.codinux.invoicing.model
|
||||||
|
|
||||||
|
import java.math.BigDecimal
|
||||||
|
|
||||||
|
class ChargeOrAllowance(
|
||||||
|
/**
|
||||||
|
* Gesamtbetrag der Gebühr oder des Nachlasses.
|
||||||
|
* Evtl. berechnet aus [basisAmount] und [calculationPercent].
|
||||||
|
*/
|
||||||
|
val actualAmount: BigDecimal,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Der Ausgangsbetrag auf den die Gebühr oder der Nachlass angewendet wird.
|
||||||
|
*/
|
||||||
|
val basisAmount: BigDecimal? = null,
|
||||||
|
/**
|
||||||
|
* Menge der Ware oder Dienstleistung auf die die Gebühr oder der Nachlass angewendet wird.
|
||||||
|
*/
|
||||||
|
val basisQuantity: BigDecimal? = null,
|
||||||
|
/**
|
||||||
|
* Der auf [basisAmount] anwendbare Prozentsatz der Gebühr oder des Nachlasses.
|
||||||
|
*/
|
||||||
|
val calculationPercent: BigDecimal? = null,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Menschenlesbare Beschreibung der Gebühr oder des Nachlasses.
|
||||||
|
*/
|
||||||
|
val reason: String? = null,
|
||||||
|
/**
|
||||||
|
* Code für Begründung der Gebühr oder des Nachlasses aus [UNTDID 5189](https://unece.org/fileadmin/DAM/trade/untdid/d16b/tred/tred5189.htm).
|
||||||
|
*/
|
||||||
|
val reasonCode: String? = null,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Anzuwendender Steuersatz (z. B. in Deutschland 7 % oder 19 %).
|
||||||
|
*/
|
||||||
|
val taxRateApplicablePercent: BigDecimal? = null,
|
||||||
|
/**
|
||||||
|
* Steuer Kategorie Code
|
||||||
|
*/
|
||||||
|
val taxCategoryCode: String? = null
|
||||||
|
) {
|
||||||
|
override fun toString() = "${reason?.let { "$it: " } ?: ""}${actualAmount.toPlainString()}"
|
||||||
|
}
|
|
@ -15,7 +15,9 @@ class Invoice(
|
||||||
/**
|
/**
|
||||||
* Unique reference number of the buyer, e.g. the Leitweg-ID required by German authorities (Behörden)
|
* Unique reference number of the buyer, e.g. the Leitweg-ID required by German authorities (Behörden)
|
||||||
*/
|
*/
|
||||||
val buyerReference: String? = null
|
val buyerReference: String? = null,
|
||||||
|
|
||||||
|
val amountAdjustments: AmountAdjustments? = null,
|
||||||
) {
|
) {
|
||||||
override fun toString() = "$invoicingDate $invoiceNumber to $recipient"
|
override fun toString() = "$invoicingDate $invoiceNumber to $recipient"
|
||||||
}
|
}
|
Loading…
Reference in New Issue