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(),
sender = Party("codinux GmbH & Co. KG", "Fun Street 1", "12345", "Glückstadt"),
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
import net.codinux.invoicing.model.LineItem
import net.codinux.invoicing.model.InvoiceItem
import net.codinux.invoicing.model.Party
import org.mustangproject.*
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
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 {
}
@ -72,8 +72,8 @@ open class MustangMapper {
party.bankDetails?.firstOrNull()?.let { net.codinux.invoicing.model.BankDetails(it.iban, it.bic, it.accountName) }
)
open fun mapLineItem(item: IZUGFeRDExportableItem) = LineItem(
item.product.name, item.product.unit, item.quantity, item.price, item.product.vatPercent, item.product.description.takeUnless { it.isBlank() }
open fun mapLineItem(item: IZUGFeRDExportableItem) = InvoiceItem(
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 sender: Party,
val recipient: Party,
val items: List<LineItem>,
val items: List<InvoiceItem>,
val dueDate: LocalDate? = null,
val paymentDescription: String? = null,

View File

@ -2,13 +2,13 @@ package net.codinux.invoicing.model
import java.math.BigDecimal
class LineItem(
class InvoiceItem(
val name: String,
val unit: String,
val quantity: BigDecimal,
val price: BigDecimal,
val vatPercentage: BigDecimal,
val unit: String,
val unitPrice: BigDecimal,
val vatRate: BigDecimal,
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.MailReader
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.reader.EInvoiceReader
import net.codinux.invoicing.validation.EInvoiceValidator
@ -83,6 +83,6 @@ class Demonstration {
invoicingDate = LocalDate.now(),
sender = Party("codinux GmbH & Co. KG", "Fun Street 1", "12345", "Glückstadt"),
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.Invoice
import net.codinux.invoicing.model.LineItem
import net.codinux.invoicing.model.InvoiceItem
import net.codinux.invoicing.model.Party
import java.math.BigDecimal
import java.time.LocalDate
@ -35,10 +35,10 @@ object DataGenerator {
val RecipientBankDetails: BankDetails? = null
const val ItemName = "Erbrachte Dienstleistungen"
const val ItemUnit = "HUR" // EN code for 'hour'
val ItemQuantity = BigDecimal(1)
val ItemPrice = BigDecimal(99)
val ItemVatPercentage = BigDecimal(19)
const val ItemUnit = "HUR" // EN code for 'hour'
val ItemUnitPrice = BigDecimal(99)
val ItemVatRate = BigDecimal(19)
val ItemDescription: String? = null
@ -49,7 +49,7 @@ object DataGenerator {
bankDetails = SenderBankDetails),
recipient: Party = createParty(RecipientName, RecipientStreet, RecipientPostalCode, RecipientCity, RecipientCountry, RecipientVatId, RecipientEmail, RecipientPhone,
bankDetails = RecipientBankDetails),
items: List<LineItem> = listOf(createItem()),
items: List<InvoiceItem> = listOf(createItem()),
dueDate: LocalDate? = DueDate,
paymentDescription: String? = dueDate?.let { "Zahlbar ohne Abzug bis ${DateTimeFormatter.ofPattern("dd.MM.yyyy").format(dueDate)}" },
buyerReference: String? = null
@ -71,11 +71,11 @@ object DataGenerator {
fun createItem(
name: String = ItemName,
unit: String = ItemUnit,
quantity: BigDecimal = ItemQuantity,
price: BigDecimal = ItemPrice,
vatPercentage: BigDecimal = ItemVatPercentage,
unit: String = ItemUnit,
unitPrice: BigDecimal = ItemUnitPrice,
vatRate: BigDecimal = ItemVatRate,
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 net.codinux.invoicing.model.BankDetails
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 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)
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) {
@ -42,14 +42,15 @@ object InvoiceAsserter {
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:SpecifiedLineTradeDelivery/ram:BilledQuantity/@unitCode", unit)
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:ApplicableTradeTax/ram:RateApplicablePercent", vatPercentage, 2)
asserter.xpathHasValue("$itemXPath/ram:SpecifiedLineTradeSettlement/ram:SpecifiedTradeSettlementLineMonetarySummation/ram:LineTotalAmount", unitPrice, 2)
asserter.xpathHasValue("$itemXPath/ram:SpecifiedLineTradeSettlement/ram:ApplicableTradeTax/ram:RateApplicablePercent",
vatRate, 2)
// 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)
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?) {
@ -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.unit).isEqualTo(unit)
assertThat(item.quantity).isEqualTo(quantity.setScale(4))
assertThat(item.price).isEqualTo(price.setScale(4))
assertThat(item.vatPercentage).isEqualTo(vatPercentage.setScale(2))
assertThat(item.unitPrice).isEqualTo(unitPrice.setScale(4))
assertThat(item.vatRate).isEqualTo(vatRate.setScale(2))
// assertThat(item.description).isEqualTo(description)
}