feat(core+frontend+domain): add ZNS Bewerb parser and integrate start list feature

- **Parser Implementation:**
  - Introduced `ZnsBewerbParser` to parse n2-XXXXX.dat files and map B-Satz lines to the `ZnsBewerb` domain model.
  - Added test coverage for parsing B-Satz lines and edge cases in `ZnsParserTest`.

- **Frontend Integration:**
  - Integrated ZNS import functionality into the `BewerbeTabContent` for uploading and previewing Bewerb data before import.
  - Enhanced `BewerbViewModel` with state and intents for managing ZNS import, preview dialogs, and import confirmation.
  - Supported start list generation and added modal for previewing generated start lists.

- **Domain Services:**
  - Implemented `StartlistenService` to generate and calculate start times for start lists with respect to participant preferences.
  - Added extensive test coverage in `StartlistenServiceTest` to validate sorting, preferences, and time calculations.

- **UI Enhancements:**
  - Updated `Bewerbe` tab layout with search, filtering, and action buttons for ZNS import and start list generation.
  - Introduced dialogs for ZNS import previews and start list previews.
This commit is contained in:
2026-04-10 09:59:28 +02:00
parent a3007b01ee
commit 363aa80fe4
12 changed files with 622 additions and 25 deletions
@@ -49,6 +49,7 @@ kotlin {
implementation(projects.frontend.core.sync)
implementation(projects.frontend.core.localDb)
implementation(projects.frontend.core.auth)
implementation(projects.core.znsParser)
// Feature-Module
implementation(projects.frontend.features.nennungFeature)
@@ -3,6 +3,7 @@ package at.mocode.desktop.screens.preview
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import at.mocode.turnier.feature.presentation.*
import at.mocode.zns.parser.ZnsBewerb
import at.mocode.veranstalter.feature.presentation.VeranstalterAuswahlScreen
import at.mocode.veranstalter.feature.presentation.VeranstalterDetailScreen
import at.mocode.veranstalter.feature.presentation.VeranstalterNeuScreen
@@ -112,8 +113,13 @@ fun PreviewTurnierOrganisationTab() {
@ComponentPreview
@Composable
fun PreviewTurnierBewerbeTab() {
val mockRepo = object : BewerbRepository {
override suspend fun listByTurnier(turnierId: Long): List<BewerbListItem> = emptyList()
override suspend fun importBewerbe(turnierId: Long, bewerbe: List<ZnsBewerb>): Result<Unit> = Result.success(Unit)
}
val vm = BewerbViewModel(mockRepo, 1L)
MaterialTheme {
BewerbeTabContent()
BewerbeTabContent(viewModel = vm, turnierId = 1L)
}
}