Using now Country and Currency enum to signal allowed values

This commit is contained in:
dankito 2024-12-04 23:07:41 +01:00
parent df9e554d3e
commit 806bdc6e4d
5 changed files with 39 additions and 13 deletions

View File

@ -2,6 +2,8 @@ package net.codinux.invoicing.mapper
import net.codinux.invoicing.calculator.AmountsCalculator
import net.codinux.invoicing.model.*
import net.codinux.invoicing.model.codes.Country
import net.codinux.invoicing.model.codes.Currency
import org.mustangproject.*
import org.mustangproject.BankDetails
import org.mustangproject.Invoice
@ -17,9 +19,18 @@ open class MustangMapper(
protected open val calculator: AmountsCalculator = AmountsCalculator()
) {
companion object {
val CountriesByIsoCode = Country.entries.associateBy { it.alpha2Code }
val CurrenciesByIsoCode = Currency.entries.associateBy { it.alpha3Code }
}
open fun mapToTransaction(invoice: net.codinux.invoicing.model.Invoice): IExportableTransaction = Invoice().apply {
this.number = invoice.details.invoiceNumber
this.issueDate = map(invoice.details.invoiceDate)
this.currency = invoice.details.currency.alpha3Code
this.sender = mapParty(invoice.supplier)
this.recipient = mapParty(invoice.customer)
@ -42,7 +53,7 @@ open class MustangMapper(
}
open fun mapParty(party: Party): TradeParty = TradeParty(
party.name, party.address, party.postalCode, party.city, party.countryIsoCode
party.name, party.address, party.postalCode, party.city, party.country.alpha2Code
).apply {
this.setAdditionalAddress(party.additionalAddressLine)
@ -94,7 +105,8 @@ open class MustangMapper(
open fun mapToInvoice(invoice: Invoice) = net.codinux.invoicing.model.Invoice(
details = InvoiceDetails(invoice.number, map(invoice.issueDate), map(invoice.dueDate ?: invoice.paymentTerms?.dueDate), invoice.paymentTermDescription ?: invoice.paymentTerms?.description),
// TODO: what to do if currency code is unknown? Currently it throws an exception, but i don't like that mapping fails just due to an unknown currency code
details = InvoiceDetails(invoice.number, map(invoice.issueDate), mapCurrency(invoice.currency), map(invoice.dueDate ?: invoice.paymentTerms?.dueDate), invoice.paymentTermDescription ?: invoice.paymentTerms?.description),
supplier = mapParty(invoice.sender),
customer = mapParty(invoice.recipient),
@ -108,7 +120,8 @@ open class MustangMapper(
)
open fun mapParty(party: TradeParty) = Party(
party.name, party.street, party.additionalAddress, party.zip, party.location, party.country, party.vatID,
// TODO: what to do if country code is unknown? Currently it throws an exception, but i don't like that mapping fails just due to an unknown country code
party.name, party.street, party.additionalAddress, party.zip, party.location, mapCountry(party.country), party.vatID,
party.email ?: party.contact?.eMail, party.contact?.phone, party.contact?.fax, party.contact?.name,
party.bankDetails?.firstOrNull()?.let { net.codinux.invoicing.model.BankDetails(it.iban, it.bic, it.accountName) }
)
@ -135,6 +148,13 @@ open class MustangMapper(
}
private fun mapCountry(isoAlpha2CountryCode: String?): Country =
CountriesByIsoCode[isoAlpha2CountryCode]
?: throw IllegalArgumentException("Unknown ISO Alpha-2 country code '$isoAlpha2CountryCode', therefore cannot map ISO code to Country")
private fun mapCurrency(isoCurrencyCode: String?): Currency =
CurrenciesByIsoCode[isoCurrencyCode]
?: throw IllegalArgumentException("Unknown ISO currency code '$isoCurrencyCode', therefore cannot map ISO code to Currency")
@JvmName("mapNullable")
protected fun map(date: LocalDate?) =

View File

@ -1,11 +1,14 @@
package net.codinux.invoicing.model
import net.codinux.invoicing.model.codes.Currency
import java.time.LocalDate
class InvoiceDetails(
val invoiceNumber: String,
val invoiceDate: LocalDate,
val currency: Currency = Currency.EUR,
val dueDate: LocalDate? = null,
val paymentDescription: String? = null,
) {

View File

@ -1,5 +1,7 @@
package net.codinux.invoicing.model
import net.codinux.invoicing.model.codes.Country
class Party(
val name: String,
@ -10,10 +12,7 @@ class Party(
val additionalAddressLine: String? = null,
var postalCode: String?,
val city: String,
/**
* Two letter country ISO code, e.g. "us" for USA, "fr" for France, ...
*/
val countryIsoCode: String? = null, // TODO: use the full country name here and map to ISO code in MustangMapper?
val country: Country = Country.DE,
val vatId: String? = null,

View File

@ -2,6 +2,8 @@ package net.codinux.invoicing.test
import net.codinux.invoicing.calculator.AmountsCalculator
import net.codinux.invoicing.model.*
import net.codinux.invoicing.model.codes.Country
import net.codinux.invoicing.model.codes.Currency
import java.math.BigDecimal
import java.time.LocalDate
import java.time.format.DateTimeFormatter
@ -17,7 +19,7 @@ object DataGenerator {
val SupplierAdditionalAddressLine: String? = null
const val SupplierPostalCode = "12345"
const val SupplierCity = "Glückstadt"
const val SupplierCountry = "DE"
val SupplierCountry = Country.DE
const val SupplierVatId = "DE123456789"
const val SupplierEmail = "working-class-hero@rock.me"
const val SupplierPhone = "+4917012345678"
@ -29,7 +31,7 @@ object DataGenerator {
val CustomerAdditionalAddressLine: String? = null
const val CustomerPostalCode = SupplierPostalCode
const val CustomerCity = SupplierCity
const val CustomerCountry = "DE"
val CustomerCountry = SupplierCountry
const val CustomerVatId = "DE987654321"
const val CustomerEmail = "exploiter@your.boss"
const val CustomerPhone = "+491234567890"
@ -53,9 +55,10 @@ object DataGenerator {
customer: Party = createParty(CustomerName, CustomerAddress, CustomerAdditionalAddressLine, CustomerPostalCode, CustomerCity, CustomerCountry,
CustomerVatId, CustomerEmail, CustomerPhone, CustomerFax, bankDetails = CustomerBankDetails),
items: List<InvoiceItem> = listOf(createItem()),
currency: Currency = Currency.EUR,
dueDate: LocalDate? = DueDate,
paymentDescription: String? = dueDate?.let { "Zahlbar ohne Abzug bis ${DateTimeFormatter.ofPattern("dd.MM.yyyy").format(dueDate)}" },
) = Invoice(InvoiceDetails(invoiceNumber, invoiceDate, dueDate, paymentDescription), supplier, customer, items).apply {
) = Invoice(InvoiceDetails(invoiceNumber, invoiceDate, currency, dueDate, paymentDescription), supplier, customer, items).apply {
this.totals = AmountsCalculator().calculateTotalAmounts(this)
}
@ -65,7 +68,7 @@ object DataGenerator {
additionalAddressLine: String? = SupplierAdditionalAddressLine,
postalCode: String = SupplierPostalCode,
city: String = SupplierCity,
country: String? = SupplierCountry,
country: Country = SupplierCountry,
vatId: String? = SupplierVatId,
email: String? = SupplierEmail,
phone: String? = SupplierPhone,

View File

@ -6,6 +6,7 @@ import net.codinux.invoicing.model.BankDetails
import net.codinux.invoicing.model.Invoice
import net.codinux.invoicing.model.InvoiceItem
import net.codinux.invoicing.model.Party
import net.codinux.invoicing.model.codes.Country
import java.math.BigDecimal
object InvoiceAsserter {
@ -70,13 +71,13 @@ object InvoiceAsserter {
assertLineItem(invoice.items.first(), DataGenerator.ItemName, DataGenerator.ItemQuantity, DataGenerator.ItemUnit, DataGenerator.ItemUnitPrice, DataGenerator.ItemVatRate, DataGenerator.ItemDescription)
}
private fun assertParty(party: Party, name: String, address: String, postalCode: String, city: String, country: String?, vatId: String, email: String, phone: String, bankDetails: BankDetails?) {
private fun assertParty(party: Party, name: String, address: String, postalCode: String, city: String, country: Country, vatId: String, email: String, phone: String, bankDetails: BankDetails?) {
assertThat(party.name).isEqualTo(name)
assertThat(party.address).isEqualTo(address)
assertThat(party.postalCode).isEqualTo(postalCode)
assertThat(party.city).isEqualTo(city)
assertThat(party.countryIsoCode).isEqualTo(country)
assertThat(party.country).isEqualTo(country)
assertThat(party.vatId).isEqualTo(vatId)