diff --git a/CHANGELOG.md b/CHANGELOG.md index 7c95f387..c3d99032 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,8 @@ Versionierung folgt [Semantic Versioning](https://semver.org/lang/de/). - **Infrastruktur:** Docker-Integration für `billing-service` (Port 8087) und API-Gateway Routing vervollständigt. - **Service Discovery:** Alle relevanten Microservices (`masterdata`, `events`, `results`, `series`, `billing`) sind nun bei Consul registriert. - **Frontend Billing:** `BillingRepository` und `BillingViewModel` auf reale API-Anbindung (Ktor) umgestellt; `BillingScreen` funktionalisiert. + - **Backend (Series):** JPA-Entitäten `Serie` und `SeriePunkt` im `series-service` stabilisiert und Flyway-Migrationen für das Datenbankschema erstellt. + - **Fix:** Behebung von IDE-Mapping-Warnungen durch explizite `@Column` Namen in den JPA-Entitäten. - **Backend Fixes - 12.04.2026:** - **Infrastruktur:** Behebung von Startfehlern im `events-service` (DataSource) und `masterdata-service` (Consul). - **Build:** Integration von `results-service` und `series-service` in `settings.gradle.kts`. diff --git a/backend/services/billing/billing-service/src/test/resources/application-test.yml b/backend/services/billing/billing-service/src/test/resources/application-test.yml index 76f87a33..c505389a 100644 --- a/backend/services/billing/billing-service/src/test/resources/application-test.yml +++ b/backend/services/billing/billing-service/src/test/resources/application-test.yml @@ -1,4 +1,11 @@ spring: + application: + name: billing-service-test + cloud: + consul: + enabled: false + discovery: + enabled: false datasource: url: jdbc:h2:mem:billing_test;DB_CLOSE_DELAY=-1 driver-class-name: org.h2.Driver diff --git a/docs/01_Architecture/MASTER_ROADMAP.md b/docs/01_Architecture/MASTER_ROADMAP.md index cef95a5c..5d3300bb 100644 --- a/docs/01_Architecture/MASTER_ROADMAP.md +++ b/docs/01_Architecture/MASTER_ROADMAP.md @@ -248,12 +248,14 @@ und über definierte Schnittstellen kommunizieren. * [x] **Frontend-Integration:** Stammdaten-Infrastruktur (Repositories, ViewModels) für Reiter, Pferde, Funktionäre und Vereine im `turnier-feature` implementiert. ✓ * [x] **Nennungs-Management:** Funktionalisierung des Nennungs-Tabs mit Echt-Datenanbindung und Suche. ✓ * [x] **`series-context`:** Pluggable Berechnungsmodell (Streichresultate, Alles zählt), konfigurierbare Paar-Bindung (Reiter+Pferd vs. Einzelwertung) implementiert. ✓ +* [x] **Backend-Integration:** `series-service` als Microservice mit JPA-Persistenz, Flyway-Migrationen und Gateway-Routing vervollständigt. ✓ ### PHASE 11: Ergebniserfassung & Platzierung ✅ ABGESCHLOSSEN *Ziel: Vollständige Ergebniserfassung und automatisierte Platzierungsberechnung.* * [x] **Backend (Results):** Implementierung der Geschäftslogik für Wertnoten, Zeitfehler und ÖTO-konforme Platzierungen. ✓ +* [x] **Backend-Infrastruktur:** `results-service` in Docker-Compose und API-Gateway integriert; Service-Discovery via Consul aktiviert. ✓ * [x] **Frontend UI:** `ErgebnisEditDialog` zur schnellen Ergebniserfassung und `TurnierErgebnislistenTab` zur Anzeige realer Ergebnisse. ✓ * [x] **PDF-Export:** Generierung von PDF-Ergebnislisten (Bewerbe und Serien). ✓ @@ -261,6 +263,8 @@ und über definierte Schnittstellen kommunizieren. *Ziel: Vollständige Kassa-Funktionalität und Turnier-Abrechnung.* +* [x] **Backend-Infrastruktur:** `billing-service` initialisiert, Docker-Integration und Gateway-Routing (Port 8087) konfiguriert. ✓ +* [x] **Frontend-Anbindung:** `BillingRepository` (Ktor) und `BillingViewModel` auf reale API-Kommunikation umgestellt. ✓ * [ ] **Buchungs-Logik:** Implementierung von Soll/Haben-Buchungen (Startgebühren, Nenngelder, Boxen). * [ ] **Offene Posten:** Liste aller unbezahlten Beträge pro Teilnehmer/Pferd. * [ ] **Rechnungserstellung:** Generierung von PDF-Rechnungen und Zahlungsbestätigungen. diff --git a/docs/04_Agents/Logs/2026-04-12_Abrechnung_Integration_Curator_Log.md b/docs/04_Agents/Logs/2026-04-12_Abrechnung_Integration_Curator_Log.md index bc74b4ea..c23ce0a4 100644 --- a/docs/04_Agents/Logs/2026-04-12_Abrechnung_Integration_Curator_Log.md +++ b/docs/04_Agents/Logs/2026-04-12_Abrechnung_Integration_Curator_Log.md @@ -22,6 +22,10 @@ ## 🧹 Fixes & Aufräumarbeiten - Behebung von `Unresolved reference` Fehlern in der DI-Konfiguration des `billing-service`. - Konsolidierung der Koin-Module im `billing-feature`. +- **Series Service Hardening:** + - JPA-Entitäten `Serie` und `SeriePunkt` stabilisiert und gegen JPA-Warnings optimiert. + - Flyway-Migration `V1__Create_Series_Tables.sql` für Persistenz-Layer erstellt. + - `DataSource` und `Consul` Konfigurationen in allen neuen Services (`results`, `series`, `events`) validiert. ## 🛤️ Roadmap-Status - Phase 12 (Billing) von "Geplant" auf "In Arbeit" gesetzt. diff --git a/frontend/features/billing-feature/src/commonMain/kotlin/at/mocode/frontend/features/billing/data/DefaultBillingRepository.kt b/frontend/features/billing-feature/src/commonMain/kotlin/at/mocode/frontend/features/billing/data/DefaultBillingRepository.kt index 93dc3943..0c5859a6 100644 --- a/frontend/features/billing-feature/src/commonMain/kotlin/at/mocode/frontend/features/billing/data/DefaultBillingRepository.kt +++ b/frontend/features/billing-feature/src/commonMain/kotlin/at/mocode/frontend/features/billing/data/DefaultBillingRepository.kt @@ -23,6 +23,12 @@ class DefaultBillingRepository( }.body() } + override suspend fun getKonten(veranstaltungId: String): Result> = runCatching { + client.get(ApiRoutes.Billing.KONTEN) { + parameter("veranstaltungId", veranstaltungId) + }.body() + } + override suspend fun getBuchungen(kontoId: String): Result> = runCatching { client.get(ApiRoutes.Billing.buchungen(kontoId)).body() } diff --git a/frontend/features/billing-feature/src/commonMain/kotlin/at/mocode/frontend/features/billing/domain/BillingRepository.kt b/frontend/features/billing-feature/src/commonMain/kotlin/at/mocode/frontend/features/billing/domain/BillingRepository.kt index aa587feb..3fe4d1aa 100644 --- a/frontend/features/billing-feature/src/commonMain/kotlin/at/mocode/frontend/features/billing/domain/BillingRepository.kt +++ b/frontend/features/billing-feature/src/commonMain/kotlin/at/mocode/frontend/features/billing/domain/BillingRepository.kt @@ -12,6 +12,11 @@ interface BillingRepository { personName: String = "Unbekannt" ): Result + /** + * Holt alle Teilnehmer-Konten für eine Veranstaltung. + */ + suspend fun getKonten(veranstaltungId: String): Result> + /** * Holt die Buchungshistorie für ein bestimmtes Konto. */ diff --git a/frontend/features/billing-feature/src/commonMain/kotlin/at/mocode/frontend/features/billing/presentation/BillingScreen.kt b/frontend/features/billing-feature/src/commonMain/kotlin/at/mocode/frontend/features/billing/presentation/BillingScreen.kt index de31fe7e..01390b7b 100644 --- a/frontend/features/billing-feature/src/commonMain/kotlin/at/mocode/frontend/features/billing/presentation/BillingScreen.kt +++ b/frontend/features/billing-feature/src/commonMain/kotlin/at/mocode/frontend/features/billing/presentation/BillingScreen.kt @@ -30,7 +30,7 @@ fun BillingScreen( var showBuchungsDialog by remember { mutableStateOf(false) } LaunchedEffect(veranstaltungId) { - viewModel.loadKonten(veranstaltungId) + viewModel.loadKonten(veranstaltungId.toString()) } Column(modifier = Modifier.fillMaxSize().padding(16.dp)) { @@ -40,7 +40,7 @@ fun BillingScreen( Spacer(Modifier.width(8.dp)) Text("Teilnehmer-Abrechnung", style = MaterialTheme.typography.headlineSmall) Spacer(Modifier.weight(1f)) - IconButton(onClick = { viewModel.loadKonten(veranstaltungId) }) { + IconButton(onClick = { viewModel.loadKonten(veranstaltungId.toString()) }) { Icon(Icons.Default.Refresh, contentDescription = "Aktualisieren") } } diff --git a/frontend/features/billing-feature/src/commonMain/kotlin/at/mocode/frontend/features/billing/presentation/BillingViewModel.kt b/frontend/features/billing-feature/src/commonMain/kotlin/at/mocode/frontend/features/billing/presentation/BillingViewModel.kt index 2c3bff6c..5fba5cf7 100644 --- a/frontend/features/billing-feature/src/commonMain/kotlin/at/mocode/frontend/features/billing/presentation/BillingViewModel.kt +++ b/frontend/features/billing-feature/src/commonMain/kotlin/at/mocode/frontend/features/billing/presentation/BillingViewModel.kt @@ -2,12 +2,14 @@ package at.mocode.frontend.features.billing.presentation import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope -import at.mocode.frontend.features.billing.domain.* +import at.mocode.frontend.features.billing.domain.BillingRepository +import at.mocode.frontend.features.billing.domain.BuchungDto +import at.mocode.frontend.features.billing.domain.BuchungRequest +import at.mocode.frontend.features.billing.domain.TeilnehmerKontoDto import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.launch import kotlin.uuid.ExperimentalUuidApi -import kotlin.uuid.Uuid data class BillingUiState( val isLoading: Boolean = false, @@ -24,6 +26,19 @@ class BillingViewModel( private val _uiState = MutableStateFlow(BillingUiState()) val uiState = _uiState.asStateFlow() + fun loadKonten(veranstaltungId: String) { + viewModelScope.launch { + _uiState.value = _uiState.value.copy(isLoading = true) + repository.getKonten(veranstaltungId) + .onSuccess { konten -> + _uiState.value = _uiState.value.copy(konten = konten, isLoading = false, error = null) + } + .onFailure { + _uiState.value = _uiState.value.copy(isLoading = false, error = it.message) + } + } + } + fun loadKonto(veranstaltungId: String, personId: String, personName: String) { viewModelScope.launch { _uiState.value = _uiState.value.copy(isLoading = true)