Renamed LineItem to InvoiceItem, price to unitPrice and vatPercentage to vatRate

This commit is contained in:
dankito 2024-11-24 16:06:02 +01:00
parent 3418ab9b0f
commit 556c59ba3a
7 changed files with 33 additions and 32 deletions

View File

@ -68,7 +68,7 @@ private fun createInvoice() = Invoice(
invoicingDate = LocalDate.now(), invoicingDate = LocalDate.now(),
sender = Party("codinux GmbH & Co. KG", "Fun Street 1", "12345", "Glückstadt"), sender = Party("codinux GmbH & Co. KG", "Fun Street 1", "12345", "Glückstadt"),
recipient = Party("Abzock GmbH", "Ausbeutstr.", "12345", "Abzockhausen"), recipient = Party("Abzock GmbH", "Ausbeutstr.", "12345", "Abzockhausen"),
items = listOf(LineItem("Erbrachte Dienstleistungen", "HUR", BigDecimal(170), BigDecimal(1_000_000), BigDecimal(19))) // HUR = EN code for hour items = listOf(InvoiceItem("Erbrachte Dienstleistungen", BigDecimal(170), "HUR", BigDecimal(105), BigDecimal(19))) // HUR = EN code for hour
) )
``` ```

View File

@ -1,6 +1,6 @@
package net.codinux.invoicing.mapper package net.codinux.invoicing.mapper
import net.codinux.invoicing.model.LineItem 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
@ -45,9 +45,9 @@ open class MustangMapper {
} }
} }
open fun mapLineItem(item: LineItem): IZUGFeRDExportableItem = Item( open fun mapLineItem(item: InvoiceItem): IZUGFeRDExportableItem = Item(
// description has to be an empty string if not set // description has to be an empty string if not set
Product(item.name, item.description ?: "", item.unit, item.vatPercentage), item.price, item.quantity Product(item.name, item.description ?: "", item.unit, item.vatRate), item.unitPrice, item.quantity
).apply { ).apply {
} }
@ -72,8 +72,8 @@ open class MustangMapper {
party.bankDetails?.firstOrNull()?.let { net.codinux.invoicing.model.BankDetails(it.iban, it.bic, it.accountName) } party.bankDetails?.firstOrNull()?.let { net.codinux.invoicing.model.BankDetails(it.iban, it.bic, it.accountName) }
) )
open fun mapLineItem(item: IZUGFeRDExportableItem) = LineItem( open fun mapLineItem(item: IZUGFeRDExportableItem) = InvoiceItem(
item.product.name, item.product.unit, item.quantity, 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() }
) )

View File

@ -7,7 +7,7 @@ class Invoice(
val invoicingDate: LocalDate, val invoicingDate: LocalDate,
val sender: Party, val sender: Party,
val recipient: Party, val recipient: Party,
val items: List<LineItem>, val items: List<InvoiceItem>,
val dueDate: LocalDate? = null, val dueDate: LocalDate? = null,
val paymentDescription: String? = null, val paymentDescription: String? = null,

View File

@ -2,13 +2,13 @@ package net.codinux.invoicing.model
import java.math.BigDecimal import java.math.BigDecimal
class LineItem( class InvoiceItem(
val name: String, val name: String,
val unit: String,
val quantity: BigDecimal, val quantity: BigDecimal,
val price: BigDecimal, val unit: String,
val vatPercentage: BigDecimal, val unitPrice: BigDecimal,
val vatRate: BigDecimal,
val description: String? = null, val description: String? = null,
) { ) {
override fun toString() = "$name, $quantity x $price, $vatPercentage %" override fun toString() = "$name, $quantity x $unitPrice, $vatRate %"
} }

View File

@ -4,7 +4,7 @@ import net.codinux.invoicing.creation.EInvoiceCreator
import net.codinux.invoicing.mail.MailAccount import net.codinux.invoicing.mail.MailAccount
import net.codinux.invoicing.mail.MailReader import net.codinux.invoicing.mail.MailReader
import net.codinux.invoicing.model.Invoice import net.codinux.invoicing.model.Invoice
import net.codinux.invoicing.model.LineItem import net.codinux.invoicing.model.InvoiceItem
import net.codinux.invoicing.model.Party import net.codinux.invoicing.model.Party
import net.codinux.invoicing.reader.EInvoiceReader import net.codinux.invoicing.reader.EInvoiceReader
import net.codinux.invoicing.validation.EInvoiceValidator import net.codinux.invoicing.validation.EInvoiceValidator
@ -83,6 +83,6 @@ class Demonstration {
invoicingDate = LocalDate.now(), invoicingDate = LocalDate.now(),
sender = Party("codinux GmbH & Co. KG", "Fun Street 1", "12345", "Glückstadt"), sender = Party("codinux GmbH & Co. KG", "Fun Street 1", "12345", "Glückstadt"),
recipient = Party("Abzock GmbH", "Ausbeutstr.", "12345", "Abzockhausen"), recipient = Party("Abzock GmbH", "Ausbeutstr.", "12345", "Abzockhausen"),
items = listOf(LineItem("Erbrachte Dienstleistungen", "HUR", BigDecimal(170), BigDecimal(1_000_000), BigDecimal(19))) // HUR = EN code for hour items = listOf(InvoiceItem("Erbrachte Dienstleistungen", BigDecimal(170), "HUR", BigDecimal(1_000_000), BigDecimal(19))) // HUR = EN code for hour
) )
} }

View File

@ -2,7 +2,7 @@ package net.codinux.invoicing.test
import net.codinux.invoicing.model.BankDetails import net.codinux.invoicing.model.BankDetails
import net.codinux.invoicing.model.Invoice import net.codinux.invoicing.model.Invoice
import net.codinux.invoicing.model.LineItem import net.codinux.invoicing.model.InvoiceItem
import net.codinux.invoicing.model.Party import net.codinux.invoicing.model.Party
import java.math.BigDecimal import java.math.BigDecimal
import java.time.LocalDate import java.time.LocalDate
@ -35,10 +35,10 @@ object DataGenerator {
val RecipientBankDetails: BankDetails? = null val RecipientBankDetails: BankDetails? = null
const val ItemName = "Erbrachte Dienstleistungen" const val ItemName = "Erbrachte Dienstleistungen"
const val ItemUnit = "HUR" // EN code for 'hour'
val ItemQuantity = BigDecimal(1) val ItemQuantity = BigDecimal(1)
val ItemPrice = BigDecimal(99) const val ItemUnit = "HUR" // EN code for 'hour'
val ItemVatPercentage = BigDecimal(19) val ItemUnitPrice = BigDecimal(99)
val ItemVatRate = BigDecimal(19)
val ItemDescription: String? = null val ItemDescription: String? = null
@ -49,7 +49,7 @@ object DataGenerator {
bankDetails = SenderBankDetails), bankDetails = SenderBankDetails),
recipient: Party = createParty(RecipientName, RecipientStreet, RecipientPostalCode, RecipientCity, RecipientCountry, RecipientVatId, RecipientEmail, RecipientPhone, recipient: Party = createParty(RecipientName, RecipientStreet, RecipientPostalCode, RecipientCity, RecipientCountry, RecipientVatId, RecipientEmail, RecipientPhone,
bankDetails = RecipientBankDetails), bankDetails = RecipientBankDetails),
items: List<LineItem> = listOf(createItem()), items: List<InvoiceItem> = listOf(createItem()),
dueDate: LocalDate? = DueDate, dueDate: LocalDate? = DueDate,
paymentDescription: String? = dueDate?.let { "Zahlbar ohne Abzug bis ${DateTimeFormatter.ofPattern("dd.MM.yyyy").format(dueDate)}" }, paymentDescription: String? = dueDate?.let { "Zahlbar ohne Abzug bis ${DateTimeFormatter.ofPattern("dd.MM.yyyy").format(dueDate)}" },
buyerReference: String? = null buyerReference: String? = null
@ -71,11 +71,11 @@ object DataGenerator {
fun createItem( fun createItem(
name: String = ItemName, name: String = ItemName,
unit: String = ItemUnit,
quantity: BigDecimal = ItemQuantity, quantity: BigDecimal = ItemQuantity,
price: BigDecimal = ItemPrice, unit: String = ItemUnit,
vatPercentage: BigDecimal = ItemVatPercentage, unitPrice: BigDecimal = ItemUnitPrice,
vatRate: BigDecimal = ItemVatRate,
description: String? = ItemDescription, description: String? = ItemDescription,
) = LineItem(name, unit, quantity, price, vatPercentage, description) ) = InvoiceItem(name, quantity, unit, unitPrice, vatRate, description)
} }

View File

@ -4,7 +4,7 @@ import assertk.assertThat
import assertk.assertions.* import assertk.assertions.*
import net.codinux.invoicing.model.BankDetails import net.codinux.invoicing.model.BankDetails
import net.codinux.invoicing.model.Invoice import net.codinux.invoicing.model.Invoice
import net.codinux.invoicing.model.LineItem import net.codinux.invoicing.model.InvoiceItem
import net.codinux.invoicing.model.Party import net.codinux.invoicing.model.Party
import java.math.BigDecimal import java.math.BigDecimal
@ -25,7 +25,7 @@ object InvoiceAsserter {
assertParty(asserter, receiverXPath, DataGenerator.RecipientName, DataGenerator.RecipientStreet, DataGenerator.RecipientPostalCode, DataGenerator.RecipientCity, DataGenerator.RecipientVatId, DataGenerator.RecipientEmail, DataGenerator.RecipientPhone) assertParty(asserter, receiverXPath, DataGenerator.RecipientName, DataGenerator.RecipientStreet, DataGenerator.RecipientPostalCode, DataGenerator.RecipientCity, DataGenerator.RecipientVatId, DataGenerator.RecipientEmail, DataGenerator.RecipientPhone)
val lineItemXPath = "//rsm:SupplyChainTradeTransaction/ram:IncludedSupplyChainTradeLineItem" val lineItemXPath = "//rsm:SupplyChainTradeTransaction/ram:IncludedSupplyChainTradeLineItem"
assertLineItem(asserter, lineItemXPath, DataGenerator.ItemName, DataGenerator.ItemUnit, DataGenerator.ItemQuantity, DataGenerator.ItemPrice, DataGenerator.ItemVatPercentage, DataGenerator.ItemDescription) assertLineItem(asserter, lineItemXPath, DataGenerator.ItemName, DataGenerator.ItemQuantity, DataGenerator.ItemUnit, DataGenerator.ItemUnitPrice, DataGenerator.ItemVatRate, DataGenerator.ItemDescription)
} }
private fun assertParty(asserter: XPathAsserter, partyXPath: String, name: String, street: String, postalCode: String, city: String, vatId: String, email: String, phone: String) { private fun assertParty(asserter: XPathAsserter, partyXPath: String, name: String, street: String, postalCode: String, city: String, vatId: String, email: String, phone: String) {
@ -42,14 +42,15 @@ object InvoiceAsserter {
asserter.xpathHasValue("$partyXPath/ram:DefinedTradeContact/ram:TelephoneUniversalCommunication/ram:CompleteNumber", phone) asserter.xpathHasValue("$partyXPath/ram:DefinedTradeContact/ram:TelephoneUniversalCommunication/ram:CompleteNumber", phone)
} }
private fun assertLineItem(asserter: XPathAsserter, itemXPath: String, name: String, unit: String, quantity: BigDecimal, price: BigDecimal, vatPercentage: BigDecimal, description: String?) { private fun assertLineItem(asserter: XPathAsserter, itemXPath: String, name: String, quantity: BigDecimal, unit: String, unitPrice: BigDecimal, vatRate: BigDecimal, description: String?) {
asserter.xpathHasValue("$itemXPath/ram:SpecifiedTradeProduct/ram:Name", name) asserter.xpathHasValue("$itemXPath/ram:SpecifiedTradeProduct/ram:Name", name)
asserter.xpathHasValue("$itemXPath/ram:SpecifiedLineTradeDelivery/ram:BilledQuantity/@unitCode", unit) asserter.xpathHasValue("$itemXPath/ram:SpecifiedLineTradeDelivery/ram:BilledQuantity/@unitCode", unit)
asserter.xpathHasValue("$itemXPath/ram:SpecifiedLineTradeDelivery/ram:BilledQuantity", quantity, 4) asserter.xpathHasValue("$itemXPath/ram:SpecifiedLineTradeDelivery/ram:BilledQuantity", quantity, 4)
asserter.xpathHasValue("$itemXPath/ram:SpecifiedLineTradeSettlement/ram:SpecifiedTradeSettlementLineMonetarySummation/ram:LineTotalAmount", price, 2) asserter.xpathHasValue("$itemXPath/ram:SpecifiedLineTradeSettlement/ram:SpecifiedTradeSettlementLineMonetarySummation/ram:LineTotalAmount", unitPrice, 2)
asserter.xpathHasValue("$itemXPath/ram:SpecifiedLineTradeSettlement/ram:ApplicableTradeTax/ram:RateApplicablePercent", vatPercentage, 2) asserter.xpathHasValue("$itemXPath/ram:SpecifiedLineTradeSettlement/ram:ApplicableTradeTax/ram:RateApplicablePercent",
vatRate, 2)
// asserter.xpathHasValue("$partyXPath/ram:URIUniversalCommunication/ram:URIID", description) // asserter.xpathHasValue("$partyXPath/ram:URIUniversalCommunication/ram:URIID", description)
} }
@ -66,7 +67,7 @@ object InvoiceAsserter {
assertParty(invoice.recipient, DataGenerator.RecipientName, DataGenerator.RecipientStreet, DataGenerator.RecipientPostalCode, DataGenerator.RecipientCity, DataGenerator.RecipientCountry, DataGenerator.RecipientVatId, DataGenerator.RecipientEmail, DataGenerator.RecipientPhone, DataGenerator.RecipientBankDetails) assertParty(invoice.recipient, DataGenerator.RecipientName, DataGenerator.RecipientStreet, DataGenerator.RecipientPostalCode, DataGenerator.RecipientCity, DataGenerator.RecipientCountry, DataGenerator.RecipientVatId, DataGenerator.RecipientEmail, DataGenerator.RecipientPhone, DataGenerator.RecipientBankDetails)
assertThat(invoice.items).hasSize(1) assertThat(invoice.items).hasSize(1)
assertLineItem(invoice.items.first(), DataGenerator.ItemName, DataGenerator.ItemUnit, DataGenerator.ItemQuantity, DataGenerator.ItemPrice, DataGenerator.ItemVatPercentage, DataGenerator.ItemDescription) assertLineItem(invoice.items.first(), DataGenerator.ItemName, DataGenerator.ItemQuantity, DataGenerator.ItemUnit, DataGenerator.ItemUnitPrice, DataGenerator.ItemVatRate, DataGenerator.ItemDescription)
} }
private fun assertParty(party: Party, name: String, street: String, postalCode: String, city: String, country: String?, vatId: String, email: String, phone: String, bankDetails: BankDetails?) { private fun assertParty(party: Party, name: String, street: String, postalCode: String, city: String, country: String?, vatId: String, email: String, phone: String, bankDetails: BankDetails?) {
@ -92,14 +93,14 @@ object InvoiceAsserter {
} }
} }
private fun assertLineItem(item: LineItem, name: String, unit: String, quantity: BigDecimal, price: BigDecimal, vatPercentage: BigDecimal, description: String?) { private fun assertLineItem(item: InvoiceItem, name: String, quantity: BigDecimal, unit: String, unitPrice: BigDecimal, vatRate: BigDecimal, description: String?) {
assertThat(item.name).isEqualTo(name) assertThat(item.name).isEqualTo(name)
assertThat(item.unit).isEqualTo(unit) assertThat(item.unit).isEqualTo(unit)
assertThat(item.quantity).isEqualTo(quantity.setScale(4)) assertThat(item.quantity).isEqualTo(quantity.setScale(4))
assertThat(item.price).isEqualTo(price.setScale(4)) assertThat(item.unitPrice).isEqualTo(unitPrice.setScale(4))
assertThat(item.vatPercentage).isEqualTo(vatPercentage.setScale(2)) assertThat(item.vatRate).isEqualTo(vatRate.setScale(2))
// assertThat(item.description).isEqualTo(description) // assertThat(item.description).isEqualTo(description)
} }