feat(billing): add automatic booking for Sportförderbeitrag in compliance with § 16 ÖTO

Signed-off-by: Stefan Mogeritsch <stefan.mo.co@gmail.com>
This commit is contained in:
2026-04-15 11:17:25 +02:00
parent c542094196
commit 8c804832d8
5 changed files with 55 additions and 9 deletions
@@ -63,6 +63,7 @@ enum class BuchungsTyp {
NACHNENNGEBUEHR,
STARTGEBUEHR,
BOXENGEBUEHR,
SPORTFOERDERBEITRAG,
ZAHLUNG_BAR,
ZAHLUNG_KARTE,
GUTSCHRIFT,
@@ -59,6 +59,7 @@ class TeilnehmerKontoService(
BuchungsTyp.NENNGEBUEHR,
BuchungsTyp.NACHNENNGEBUEHR,
BuchungsTyp.STARTGEBUEHR,
BuchungsTyp.SPORTFOERDERBEITRAG,
BuchungsTyp.BOXENGEBUEHR -> if (betragCent > 0) -betragCent else betragCent
BuchungsTyp.ZAHLUNG_BAR,
@@ -4,7 +4,6 @@ package at.mocode.entries.service.usecase
import at.mocode.billing.domain.model.BuchungsTyp
import at.mocode.billing.service.TeilnehmerKontoService
import at.mocode.entries.service.notification.MailService
import at.mocode.core.domain.model.NennStatusE
import at.mocode.entries.api.*
import at.mocode.entries.domain.model.Nennung
@@ -12,6 +11,7 @@ import at.mocode.entries.domain.model.NennungsTransfer
import at.mocode.entries.domain.repository.NennungRepository
import at.mocode.entries.domain.repository.NennungsTransferRepository
import at.mocode.entries.service.bewerbe.BewerbRepository
import at.mocode.entries.service.notification.MailService
import org.slf4j.LoggerFactory
import org.springframework.stereotype.Service
import kotlin.uuid.Uuid
@@ -109,6 +109,14 @@ class NennungUseCases(
zweck = "Nachnenngebühr Bewerb ${bewerb.bezeichnung}"
)
}
// Sportförderbeitrag buchen (1€ gemäß § 16 ÖTO)
kontoService.buche(
kontoId = konto.kontoId,
betragCent = -100, // 1,00 EUR
typ = BuchungsTyp.SPORTFOERDERBEITRAG,
zweck = "Sportförderbeitrag ÖTO (§ 16)"
)
} catch (e: Exception) {
log.error("Fehler bei der automatischen Buchung für Nennung {}: {}", saved.nennungId, e.message, e)
// Wir lassen die Nennung bestehen, loggen aber den Fehler.
@@ -98,15 +98,15 @@ class NennungBillingIntegrationTest {
// WHEN: Nennung einreichen
nennungUseCases.nennungEinreichen(request)
// THEN: Konto muss existieren und Saldo muss -25,00 EUR sein (Gebühr)
// THEN: Konto muss existieren und Saldo muss -26,00 EUR sein (25,00 Gebühr + 1,00 Sportförderbeitrag)
val konto = kontoService.getKonto(turnierId, reiterId)
assertNotNull(konto, "Konto sollte automatisch erstellt worden sein")
assertEquals(-2500L, konto?.saldoCent)
assertEquals(-2600L, konto?.saldoCent)
val buchungen = kontoService.getBuchungsHistorie(konto!!.kontoId)
assertEquals(1, buchungen.size)
assertEquals(BuchungsTyp.NENNGELD, buchungen[0].typ)
assertEquals(-2500L, buchungen[0].betragCent)
assertEquals(2, buchungen.size)
assertNotNull(buchungen.find { it.typ == BuchungsTyp.NENNGELD })
assertNotNull(buchungen.find { it.typ == BuchungsTyp.SPORTFOERDERBEITRAG })
}
@Test
@@ -165,13 +165,14 @@ class NennungBillingIntegrationTest {
// WHEN: Nennung einreichen
nennungUseCases.nennungEinreichen(request)
// THEN: Saldo muss -45,00 EUR sein (-30 - 15)
// THEN: Saldo muss -46,00 EUR sein (-30 - 15 - 1 Sportförderbeitrag)
val konto = kontoService.getKonto(turnierId, reiterId)
assertEquals(-4500L, konto?.saldoCent)
assertEquals(-4600L, konto?.saldoCent)
val buchungen = kontoService.getBuchungsHistorie(konto!!.kontoId)
assertEquals(2, buchungen.size)
assertEquals(3, buchungen.size)
// Einer muss NACHNENNGEBUEHR sein
assertNotNull(buchungen.find { it.typ == BuchungsTyp.NACHNENNGEBUEHR })
assertNotNull(buchungen.find { it.typ == BuchungsTyp.SPORTFOERDERBEITRAG })
}
}