feat(billing-feature): introduce billing module with Money class, calculation logic, and DI setup

- Added `Money` value class for precise monetary operations.
- Implemented `BillingCalculator` to handle fee calculations, including ÖTO-compliant contributions and prize distribution rules.
- Created `BillingModule` for dependency injection using Koin.
- Integrated `billing-feature` into the desktop shell and project dependencies.
- Introduced `TurnierWizardV2` and `VeranstalterAuswahlV2` screens with improved UI and billing synchronization support.

Signed-off-by: Stefan Mogeritsch <stefan.mo.co@gmail.com>
This commit is contained in:
2026-03-30 16:38:25 +02:00
parent 0503cf8bcc
commit b2e6158328
9 changed files with 462 additions and 9 deletions
@@ -0,0 +1,47 @@
/**
* Dieses Modul kapselt die Gebühren-Logik und Abrechnungs-Features (Billing-Sync).
*/
plugins {
alias(libs.plugins.kotlinMultiplatform)
alias(libs.plugins.composeMultiplatform)
alias(libs.plugins.composeCompiler)
alias(libs.plugins.kotlinSerialization)
}
group = "at.mocode.clients"
version = "1.0.0"
kotlin {
jvm()
sourceSets {
commonMain.dependencies {
implementation(projects.frontend.core.designSystem)
implementation(projects.frontend.core.network)
implementation(projects.frontend.core.domain)
implementation(projects.core.coreDomain)
implementation(compose.foundation)
implementation(compose.runtime)
implementation(compose.material3)
implementation(compose.ui)
implementation(compose.components.resources)
implementation(compose.materialIconsExtended)
implementation(libs.bundles.kmp.common)
implementation(libs.bundles.compose.common)
implementation(libs.koin.core)
implementation(libs.koin.compose)
}
commonTest.dependencies {
implementation(libs.kotlin.test)
implementation(libs.kotlinx.coroutines.test)
}
jvmMain.dependencies {
implementation(compose.uiTooling)
}
}
}
@@ -0,0 +1,8 @@
package at.mocode.frontend.features.billing.di
import at.mocode.frontend.features.billing.domain.BillingCalculator
import org.koin.dsl.module
val billingModule = module {
single { BillingCalculator() }
}
@@ -0,0 +1,58 @@
package at.mocode.frontend.features.billing.domain
import kotlinx.serialization.Serializable
/**
* Repräsentiert einen Geldbetrag in Cent zur Vermeidung von Floating-Point-Fehlern.
*/
@Serializable
@JvmInline
value class Money(val cents: Long) {
operator fun plus(other: Money) = Money(this.cents + other.cents)
operator fun times(factor: Int) = Money(this.cents * factor)
override fun toString(): String {
val euros = cents / 100
val rest = cents % 100
return "%d,%02d €".format(euros, if (rest < 0) -rest else rest)
}
}
enum class GebuehrTyp {
NENN_GEBUEHR,
START_GEBUEHR,
SPORTFOERDERBEITRAG,
BOXEN_GEBUEHR,
SYSTEM_GEBUEHR,
SONSTIGES
}
/**
* Logik für die Gebührenberechnung gemäß ÖTO.
*/
class BillingCalculator {
/**
* Berechnet die Gesamtsumme für eine Nennung.
* @param basisNenngeld Das Nenngeld des Bewerbs.
* @param sportfoerderbeitrag Der Sportförderbeitrag (standardmäßig 1,00 € gemäß ÖTO).
*/
fun berechneNennsumme(
basisNenngeld: Money,
sportfoerderbeitrag: Money = Money(100)
): Money {
return basisNenngeld + sportfoerderbeitrag
}
/**
* Berechnet das Preisgeld gemäß § 30 ÖTO (Verteilungsschlüssel).
* Einfache Implementierung für den Anfang.
*/
fun berechnePreisgeld(gesamtSumme: Money, platzierung: Int): Money {
return when (platzierung) {
1 -> Money((gesamtSumme.cents * 0.25).toLong())
2 -> Money((gesamtSumme.cents * 0.20).toLong())
3 -> Money((gesamtSumme.cents * 0.15).toLong())
else -> Money(0)
}
}
}