Refactor domain models (DomFunktionaer, DomReiter, DomPferd) for ZNS alignment: update properties, streamline validation logic, and enhance parser to support new format. Adjust controllers and repository methods accordingly.
This commit is contained in:
+27
-48
@@ -18,21 +18,14 @@ import kotlin.uuid.Uuid
|
||||
* Domain-Modell für einen Funktionär im actor-context.
|
||||
*
|
||||
* Repräsentiert eine Person mit einer definierten Rolle bei Turnieren (Richter, TBA,
|
||||
* Parcoursbauer etc.). Die Qualifikation wird gegen `RICHT01.DAT` aus dem ZNS geprüft.
|
||||
*
|
||||
* Aggregate Root des `officials`-Bounded Context.
|
||||
* Parcoursbauer etc.). Die Qualifikation wird gegen `RICHT01.DAT` oder `PARCO01.DAT`
|
||||
* aus dem ZNS geprüft.
|
||||
*
|
||||
* @property funktionaerId Eindeutige interne ID (UUID).
|
||||
* @property richterNummer ÖPS-Funktionärsnummer aus ZNS (RICHT01.dat), 6-stellig.
|
||||
* @property vorname Vorname der Person.
|
||||
* @property nachname Nachname der Person.
|
||||
* @property geburtsdatum Geburtsdatum (optional, für Altersklassen-Prüfung).
|
||||
* @property rollen Menge der Rollen, die diese Person ausüben darf (TBA, Richter, ...).
|
||||
* @property richterQualifikation Qualifikationsstufe als Richter (GA, G1–G3, International).
|
||||
* @property qualifiziertFuerSparten Sparten, für die eine Richter-Qualifikation vorliegt.
|
||||
* @property email E-Mail-Adresse für Kommunikation.
|
||||
* @property telefon Telefonnummer.
|
||||
* @property vereinsNummer Vereinsnummer des Heimvereins (Referenz auf DomVerein).
|
||||
* @property satzID Typ des Satzes (X = Richter, Y = Parcoursbauer). Aus ZNS (RICHT01.DAT / PARCO01.DAT).
|
||||
* @property satzNummer Satznummer (6-stellig). Aus ZNS (RICHT01.DAT / PARCO01.DAT).
|
||||
* @property name Vollständiger Name (Nachname, Vorname). Aus ZNS (RICHT01.DAT / PARCO01.DAT).
|
||||
* @property qualifikation Qualifikationen (getrennt durch `,`). Aus ZNS (RICHT01.DAT / PARCO01.DAT).
|
||||
* @property istAktiv Ob der Funktionär aktuell aktiv/einsatzbereit ist.
|
||||
* @property bemerkungen Interne Notizen.
|
||||
* @property datenQuelle Herkunft des Datensatzes (ZNS-Import oder manuell).
|
||||
@@ -43,26 +36,21 @@ import kotlin.uuid.Uuid
|
||||
data class DomFunktionaer(
|
||||
@Serializable(with = UuidSerializer::class)
|
||||
val funktionaerId: Uuid = Uuid.random(),
|
||||
val satzID: String,
|
||||
val satzNummer: Int,
|
||||
var name: String? = null, // Nachname, Vorname
|
||||
var qualifikationen: List<String> = emptyList(), // Liste der Qualifikations-Kürzel
|
||||
|
||||
// Identifikation
|
||||
val richterNummer: String? = null,
|
||||
|
||||
// Persönliche Daten
|
||||
var vorname: String,
|
||||
var nachname: String,
|
||||
var geburtsdatum: LocalDate? = null,
|
||||
|
||||
// Qualifikation & Rollen
|
||||
var rollen: Set<FunktionaerRolleE> = emptySet(),
|
||||
var richterQualifikation: RichterQualifikationE? = null,
|
||||
var qualifiziertFuerSparten: Set<SparteE> = emptySet(),
|
||||
|
||||
// Kontakt
|
||||
var email: String? = null,
|
||||
var telefon: String? = null,
|
||||
|
||||
// Vereinszugehörigkeit
|
||||
var vereinsNummer: String? = null,
|
||||
// var vorname: String,
|
||||
// var nachname: String,
|
||||
// var geburtsdatum: LocalDate? = null,
|
||||
// val richterNummer: String? = null,
|
||||
// var rollen: Set<FunktionaerRolleE> = emptySet(),
|
||||
// var richterQualifikation: RichterQualifikationE? = null,
|
||||
// var qualifiziertFuerSparten: Set<SparteE> = emptySet(),
|
||||
// var email: String? = null,
|
||||
// var telefon: String? = null,
|
||||
// var vereinsNummer: String? = null,
|
||||
|
||||
// Status & Verwaltung
|
||||
var istAktiv: Boolean = true,
|
||||
@@ -78,44 +66,35 @@ data class DomFunktionaer(
|
||||
/**
|
||||
* Gibt den vollständigen Anzeigenamen zurück.
|
||||
*/
|
||||
fun getDisplayName(): String = "$vorname $nachname"
|
||||
fun getDisplayName(): String = name ?: "Unbekannt"
|
||||
|
||||
/**
|
||||
* Gibt den Anzeigenamen mit Funktionärsnummer zurück (falls vorhanden).
|
||||
*/
|
||||
fun getDisplayNameWithNummer(): String =
|
||||
richterNummer?.let { "${getDisplayName()} ($it)" } ?: getDisplayName()
|
||||
satzNummer.let { "${getDisplayName()} ($it)" }
|
||||
|
||||
/**
|
||||
* Prüft, ob der Funktionär als Richter für eine bestimmte Sparte qualifiziert ist.
|
||||
* Prüft, ob der Funktionär als Richter qualifiziert ist.
|
||||
*/
|
||||
fun istRichterFuerSparte(sparte: SparteE): Boolean =
|
||||
rollen.contains(FunktionaerRolleE.RICHTER) && qualifiziertFuerSparten.contains(sparte)
|
||||
fun istRichter(): Boolean = satzID.uppercase() == "X"
|
||||
|
||||
/**
|
||||
* Prüft, ob der Funktionär die Rolle TBA ausüben darf.
|
||||
* Prüft, ob der Funktionär als Parcoursbauer qualifiziert ist.
|
||||
*/
|
||||
fun istTba(): Boolean = rollen.contains(FunktionaerRolleE.TBA)
|
||||
fun istParcoursbauer(): Boolean = satzID.uppercase() == "Y"
|
||||
|
||||
/**
|
||||
* Validiert die Pflichtfelder für den Turniereinsatz.
|
||||
* Gibt eine Liste von Warnungen zurück (kein harter Fehler – Override-Event möglich).
|
||||
*/
|
||||
fun validateFuerTurniereinsatz(rolle: FunktionaerRolleE, sparte: SparteE? = null): List<String> {
|
||||
fun validateFuerTurniereinsatz(): List<String> {
|
||||
val warnings = mutableListOf<String>()
|
||||
|
||||
if (!istAktiv) {
|
||||
warnings.add("Funktionär ${getDisplayName()} ist nicht aktiv.")
|
||||
}
|
||||
|
||||
if (!rollen.contains(rolle)) {
|
||||
warnings.add("Funktionär ${getDisplayName()} hat keine Qualifikation für Rolle $rolle.")
|
||||
}
|
||||
|
||||
if (rolle == FunktionaerRolleE.RICHTER && sparte != null && !istRichterFuerSparte(sparte)) {
|
||||
warnings.add("Funktionär ${getDisplayName()} ist nicht als Richter für Sparte $sparte qualifiziert.")
|
||||
}
|
||||
|
||||
return warnings
|
||||
}
|
||||
|
||||
|
||||
+50
-75
@@ -22,24 +22,19 @@ import kotlin.uuid.Uuid
|
||||
* It serves as the core aggregate root for the horse-registry bounded context.
|
||||
*
|
||||
* @property pferdId Unique internal identifier for this horse (UUID).
|
||||
* @property pferdeName Name of the horse.
|
||||
* @property geschlecht Gender of the horse (Hengst, Stute, Wallach).
|
||||
* @property geburtsdatum Birthdate of the horse.
|
||||
* @property rasse Breed of the horse.
|
||||
* @property farbe Color/coat of the horse.
|
||||
* @property besitzerId ID of the current owner (Person from member-management context).
|
||||
* @property verantwortlichePersonId ID of the responsible person (trainer, rider, etc.).
|
||||
* @property zuechterName Name of the breeder.
|
||||
* @property zuchtbuchNummer Studbook number if registered.
|
||||
* @property lebensnummer Life number (unique identification number).
|
||||
* @property chipNummer Microchip number for identification.
|
||||
* @property passNummer Passport number.
|
||||
* @property oepsNummer OEPS (Austrian Equestrian Federation) number.
|
||||
* @property feiNummer FEI (International Equestrian Federation) number.
|
||||
* @property vaterName Name of the sire (father).
|
||||
* @property mutterName Name of the dam (mother).
|
||||
* @property mutterVaterName Name of the maternal grandsire.
|
||||
* @property stockmass Height of the horse in cm.
|
||||
* @property kopfnummer Head number (Kopfnummer) used at tournaments (4 alphanumeric chars). From PFERDE01.DAT.
|
||||
* @property pferdeName Name of the horse. From PFERDE01.DAT.
|
||||
* @property lebensnummer Life number (unique identification number). From PFERDE01.DAT.
|
||||
* @property geschlecht Gender of the horse (Hengst, Stute, Wallach). Derived from PFERDE01.DAT.
|
||||
* @property geburtsjahr Birth year of the horse. From PFERDE01.DAT.
|
||||
* @property farbe Color/coat of the horse. From PFERDE01.DAT.
|
||||
* @property abstammung Breeding/Pedigree information. From PFERDE01.DAT.
|
||||
* @property vereinNummer Club number (OEPS). From PFERDE01.DAT.
|
||||
* @property lastPayYear Last year the horse's OEPS fee was paid. From PFERDE01.DAT.
|
||||
* @property verantwortlichePersonId Reference to the responsible person (Satznummer or ID). From PFERDE01.DAT.
|
||||
* @property vater Name of the sire (father). From PFERDE01.DAT.
|
||||
* @property feiPass FEI passport information. From PFERDE01.DAT.
|
||||
* @property satznummer 10-digit ZNS primary key for data exchange. From PFERDE01.DAT.
|
||||
* @property istAktiv Whether the horse is currently active in the system.
|
||||
* @property bemerkungen Additional notes or comments.
|
||||
* @property datenQuelle Source of the data (manual entry, import, etc.).
|
||||
@@ -51,56 +46,49 @@ data class DomPferd(
|
||||
@Serializable(with = UuidSerializer::class)
|
||||
val pferdId: Uuid = Uuid.random(),
|
||||
|
||||
// Basic Information
|
||||
// PFERDE01.DAT Information
|
||||
var kopfnummer: String? = null,
|
||||
var pferdeName: String,
|
||||
var geschlecht: PferdeGeschlechtE,
|
||||
var geburtsdatum: LocalDate? = null,
|
||||
var rasse: String? = null,
|
||||
var farbe: String? = null,
|
||||
|
||||
// Ownership and Responsibility
|
||||
@Serializable(with = UuidSerializer::class)
|
||||
var besitzerId: Uuid? = null,
|
||||
@Serializable(with = UuidSerializer::class)
|
||||
var verantwortlichePersonId: Uuid? = null,
|
||||
|
||||
// Breeding Information
|
||||
var zuechterName: String? = null,
|
||||
var zuchtbuchNummer: String? = null,
|
||||
|
||||
// Identification Numbers
|
||||
var lebensnummer: String? = null,
|
||||
var chipNummer: String? = null,
|
||||
var passNummer: String? = null,
|
||||
var oepsNummer: String? = null,
|
||||
var feiNummer: String? = null,
|
||||
var geschlecht: PferdeGeschlechtE,
|
||||
var geburtsjahr: Int? = null,
|
||||
var farbe: String? = null,
|
||||
var abstammung: String? = null,
|
||||
var vereinNummer: Int? = null,
|
||||
var lastPayYear: Int? = null,
|
||||
var verantwortlichePersonId: String? = null,
|
||||
var vater: String? = null,
|
||||
var feiPass: String? = null,
|
||||
var satznummer: String? = null,
|
||||
|
||||
// Pedigree Information
|
||||
var vaterName: String? = null,
|
||||
var mutterName: String? = null,
|
||||
var mutterVaterName: String? = null,
|
||||
// var geburtsdatum: LocalDate? = null,
|
||||
// var rasse: String? = null,
|
||||
// @Serializable(with = UuidSerializer::class)
|
||||
// var besitzerId: Uuid? = null,
|
||||
// var zuechterName: String? = null,
|
||||
// var zuchtbuchNummer: String? = null,
|
||||
// var chipNummer: String? = null,
|
||||
// var passNummer: String? = null,
|
||||
// var oepsNummer: String? = null,
|
||||
// var mutterName: String? = null,
|
||||
// var mutterVaterName: String? = null,
|
||||
// var stockmass: Int? = null, // Height in cm
|
||||
|
||||
// Physical Characteristics
|
||||
var stockmass: Int? = null, // Height in cm
|
||||
|
||||
// Status and Administrative
|
||||
var istAktiv: Boolean = true,
|
||||
var bemerkungen: String? = null,
|
||||
var datenQuelle: DatenQuelleE = DatenQuelleE.MANUELL,
|
||||
|
||||
// Audit Fields
|
||||
@Serializable(with = InstantSerializer::class)
|
||||
val createdAt: Instant = Clock.System.now(),
|
||||
@Serializable(with = InstantSerializer::class)
|
||||
var createdAt: Instant = Clock.System.now(),
|
||||
var updatedAt: Instant = Clock.System.now()
|
||||
) {
|
||||
/**
|
||||
* Returns the display name for the horse, combining name and birth year if available.
|
||||
*/
|
||||
fun getDisplayName(): String {
|
||||
return geburtsdatum?.let { birthDate ->
|
||||
"$pferdeName (${birthDate.year})"
|
||||
val basic = geburtsjahr?.let { year ->
|
||||
"$pferdeName ($year)"
|
||||
} ?: pferdeName
|
||||
|
||||
return kopfnummer?.let { "[$it] $basic" } ?: basic
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -108,40 +96,31 @@ data class DomPferd(
|
||||
*/
|
||||
fun hasCompleteIdentification(): Boolean {
|
||||
return !lebensnummer.isNullOrBlank() ||
|
||||
!chipNummer.isNullOrBlank() ||
|
||||
!passNummer.isNullOrBlank()
|
||||
!kopfnummer.isNullOrBlank() ||
|
||||
!satznummer.isNullOrBlank()
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the horse is registered with OEPS.
|
||||
*/
|
||||
fun isOepsRegistered(): Boolean {
|
||||
return !oepsNummer.isNullOrBlank()
|
||||
return false // OEPS registration information currently commented out
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the horse is registered with FEI.
|
||||
*/
|
||||
fun isFeiRegistered(): Boolean {
|
||||
return !feiNummer.isNullOrBlank()
|
||||
return !feiPass.isNullOrBlank()
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the age of the horse in years, or null if birth date is unknown.
|
||||
* Returns the age of the horse in years, or null if birth year is unknown.
|
||||
*/
|
||||
fun getAge(): Int? {
|
||||
return geburtsdatum?.let { birthDate ->
|
||||
return geburtsjahr?.let { birthYear ->
|
||||
val today = Clock.System.todayIn(kotlinx.datetime.TimeZone.currentSystemDefault())
|
||||
var age = today.year - birthDate.year
|
||||
|
||||
// Check if a birthday has occurred this year
|
||||
if (today.month.number < birthDate.month.number ||
|
||||
(today.month.number == birthDate.month.number && today.day < birthDate.day)
|
||||
) {
|
||||
age--
|
||||
}
|
||||
|
||||
age
|
||||
today.year - birthYear
|
||||
}
|
||||
}
|
||||
|
||||
@@ -156,11 +135,7 @@ data class DomPferd(
|
||||
}
|
||||
|
||||
if (!hasCompleteIdentification()) {
|
||||
errors.add("At least one identification number (life number, chip number, or passport number) is required")
|
||||
}
|
||||
|
||||
if (besitzerId == null) {
|
||||
errors.add("Owner is required")
|
||||
errors.add("At least one identification number (life number, or kopfnummer, or satznummer) is required")
|
||||
}
|
||||
|
||||
return errors
|
||||
|
||||
+69
-55
@@ -9,6 +9,7 @@ import at.mocode.core.domain.serialization.InstantSerializer
|
||||
import at.mocode.core.domain.serialization.LocalDateSerializer
|
||||
import at.mocode.core.domain.serialization.UuidSerializer
|
||||
import kotlinx.datetime.LocalDate
|
||||
import kotlinx.datetime.todayIn
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlin.time.Clock
|
||||
import kotlin.time.Instant
|
||||
@@ -21,27 +22,30 @@ import kotlin.uuid.Uuid
|
||||
* attributes such as license, start card, and competition eligibility.
|
||||
* Data is primarily sourced from the OEPS ZNS (LIZENZ01.DAT).
|
||||
*
|
||||
* Key rules (ÖTO):
|
||||
* - A rider requires an active Startkarte (annual fee paid) to compete nationally.
|
||||
* - LizenzKlasse determines which competition classes the rider may enter.
|
||||
* - Satznummer (6-digit) is the primary key for ZNS data exchange.
|
||||
* - Kopfnummer is NOT a unique identifier – it can change.
|
||||
*
|
||||
* @property reiterId Unique internal identifier (UUID).
|
||||
* @property personId Reference to the base DomPerson record (UUID).
|
||||
* @property satznummer 6-digit ZNS primary key for data exchange. Primary key for ZNS.
|
||||
* @property lizenzNummer OEPS license number (from ZNS LIZENZ01.DAT).
|
||||
* @property lizenzKlasse License class determining competition eligibility (e.g. R1, RD2).
|
||||
* @property lizenzSparten Disciplines for which the license is valid.
|
||||
* @property startkartAktiv Whether the annual start card fee has been paid.
|
||||
* @property startkartSaison Season year for which the start card is valid (e.g. 2026).
|
||||
* @property feiId FEI international rider ID (optional).
|
||||
* @property nation Nation code (e.g. AUT).
|
||||
* @property geburtsdatum Date of birth (for age class validation).
|
||||
* @property vereinsNummer Club number (OEPS).
|
||||
* @property vereinsName Club name.
|
||||
* @property istGastreiter Whether the rider is a guest rider (foreign nationality, not in Austrian club).
|
||||
* @property satznummer 6-digit ZNS primary key for data exchange. From LIZENZ01.DAT.
|
||||
* @property nachname Surname of the rider. From LIZENZ01.DAT.
|
||||
* @property vorname First name of the rider. From LIZENZ01.DAT.
|
||||
* @property bundeslandNummer State number (Bundesland). From LIZENZ01.DAT.
|
||||
* @property vereinsName Name of the club. From LIZENZ01.DAT.
|
||||
* @property nation Nationality of the rider. From LIZENZ01.DAT.
|
||||
* @property reiterLizenz Rider license information. From LIZENZ01.DAT.
|
||||
* @property startkarte Start card information. From LIZENZ01.DAT.
|
||||
* @property fahrLizenz Driving license information. From LIZENZ01.DAT.
|
||||
* @property altersklasseJgJrU25 Age class Jg/Jr/U25. From LIZENZ01.DAT.
|
||||
* @property altersklasseY Age class Young Rider. From LIZENZ01.DAT.
|
||||
* @property mitgliedsNummer Membership number. From LIZENZ01.DAT.
|
||||
* @property telefonNummer Phone number. From LIZENZ01.DAT.
|
||||
* @property kader Squad status. From LIZENZ01.DAT.
|
||||
* @property lastPayYear Last year the license was paid. From LIZENZ01.DAT.
|
||||
* @property geschlecht Gender of the rider. From LIZENZ01.DAT.
|
||||
* @property geburtsdatum Date of birth. From LIZENZ01.DAT (JJJJMMTT).
|
||||
* @property feiId FEI ID. From LIZENZ01.DAT.
|
||||
* @property sperrListe Suspension list information. From LIZENZ01.DAT.
|
||||
* @property lizenzInfo License info details. From LIZENZ01.DAT.
|
||||
* @property istAktiv Whether the rider is currently active in the system.
|
||||
* @property bemerkungen Additional notes or comments.
|
||||
* @property datenQuelle Source of the data.
|
||||
* @property createdAt Timestamp when this record was created.
|
||||
* @property updatedAt Timestamp when this record was last updated.
|
||||
@@ -56,37 +60,33 @@ data class DomReiter(
|
||||
val personId: Uuid,
|
||||
|
||||
// ZNS Identification
|
||||
val satznummer: String,
|
||||
val lizenzNummer: String? = null,
|
||||
|
||||
// License & Eligibility
|
||||
val lizenzKlasse: LizenzKlasseE = LizenzKlasseE.LIZENZFREI,
|
||||
val lizenzSparten: List<SparteE> = emptyList(),
|
||||
|
||||
// Start Card (Startkarte) – annual fee proof
|
||||
val startkartAktiv: Boolean = false,
|
||||
val startkartSaison: Int? = null,
|
||||
|
||||
// International
|
||||
val feiId: String? = null,
|
||||
val nation: String? = null,
|
||||
|
||||
// Personal Data (denormalized from DomPerson for performance)
|
||||
val nachname: String,
|
||||
val vorname: String,
|
||||
var satznummer: String?,
|
||||
var nachname: String,
|
||||
var vorname: String,
|
||||
var bundeslandNummer: Int? = null,
|
||||
var vereinsName: String? = null,
|
||||
var nation: String? = null,
|
||||
var reiterLizenz: String? = null,
|
||||
var startkarte: String? = null,
|
||||
var fahrLizenz: String? = null,
|
||||
var altersklasseJgJrU25: String? = null,
|
||||
var altersklasseY: String? = null,
|
||||
var mitgliedsNummer: Int? = null,
|
||||
var telefonNummer: String? = null,
|
||||
var kader: String? = null,
|
||||
var lastPayYear: Int? = null,
|
||||
var geschlecht: String? = null,
|
||||
@Serializable(with = LocalDateSerializer::class)
|
||||
val geburtsdatum: LocalDate? = null,
|
||||
var geburtsdatum: LocalDate? = null,
|
||||
var feiId: String? = null,
|
||||
var sperrListe: String? = null,
|
||||
var lizenzInfo: String? = null,
|
||||
|
||||
// Club Affiliation
|
||||
val vereinsNummer: String? = null,
|
||||
val vereinsName: String? = null,
|
||||
var lizenzKlasse: LizenzKlasseE = LizenzKlasseE.LIZENZFREI,
|
||||
|
||||
// Status
|
||||
val istGastreiter: Boolean = false,
|
||||
val istAktiv: Boolean = true,
|
||||
var bemerkungen: String? = null,
|
||||
val datenQuelle: DatenQuelleE = DatenQuelleE.IMPORT_ZNS,
|
||||
|
||||
// Audit Fields
|
||||
@Serializable(with = InstantSerializer::class)
|
||||
val createdAt: Instant = Clock.System.now(),
|
||||
@Serializable(with = InstantSerializer::class)
|
||||
@@ -99,31 +99,45 @@ data class DomReiter(
|
||||
|
||||
/**
|
||||
* Checks if the rider is eligible to compete nationally.
|
||||
* Requires an active start card (Startkarte).
|
||||
* Based on the last pay year.
|
||||
*/
|
||||
fun isStartberechtigt(): Boolean = istAktiv && startkartAktiv
|
||||
fun isStartberechtigt(): Boolean {
|
||||
val currentYear = Clock.System.todayIn(kotlinx.datetime.TimeZone.currentSystemDefault()).year
|
||||
return istAktiv && (lastPayYear ?: 0) >= currentYear
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the rider holds a license for the given discipline.
|
||||
* Checks if the rider holds a license.
|
||||
*/
|
||||
fun hasLizenzForSparte(sparte: SparteE): Boolean =
|
||||
lizenzKlasse == LizenzKlasseE.LIZENZFREI || lizenzSparten.contains(sparte)
|
||||
fun hasLizenz(): Boolean = !reiterLizenz.isNullOrBlank()
|
||||
|
||||
/**
|
||||
* Checks if the rider has a license for a specific sparte.
|
||||
*/
|
||||
fun hasLizenzForSparte(sparte: SparteE): Boolean {
|
||||
// If we have a license class, check if it's applicable for the sparte
|
||||
if (lizenzKlasse == LizenzKlasseE.LIZENZFREI) return false
|
||||
|
||||
return when (sparte) {
|
||||
SparteE.DRESSUR -> true // Everyone with a license can do dressage (simplified)
|
||||
SparteE.SPRINGEN -> !listOf(LizenzKlasseE.RD1, LizenzKlasseE.RD2, LizenzKlasseE.RD3).contains(lizenzKlasse)
|
||||
else -> true
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the rider for competition entry.
|
||||
* Returns a list of warning messages (never hard errors – TBA has final say).
|
||||
*/
|
||||
fun validateForNennung(sparte: SparteE): List<String> {
|
||||
fun validateForNennung(): List<String> {
|
||||
val warnings = mutableListOf<String>()
|
||||
|
||||
if (!istAktiv) {
|
||||
warnings.add("Reiter ${getDisplayName()} ist nicht aktiv")
|
||||
}
|
||||
if (!startkartAktiv) {
|
||||
warnings.add("Reiter ${getDisplayName()} hat keine aktive Startkarte für Saison $startkartSaison")
|
||||
}
|
||||
if (!hasLizenzForSparte(sparte)) {
|
||||
warnings.add("Reiter ${getDisplayName()} hat keine Lizenz für Sparte $sparte (Lizenzklasse: $lizenzKlasse)")
|
||||
|
||||
if (!isStartberechtigt()) {
|
||||
warnings.add("Reiter ${getDisplayName()} hat keine aktive Startkarte für das aktuelle Jahr")
|
||||
}
|
||||
|
||||
return warnings
|
||||
|
||||
+4
-42
@@ -22,42 +22,9 @@ interface FunktionaerRepository {
|
||||
suspend fun findById(id: Uuid): DomFunktionaer?
|
||||
|
||||
/**
|
||||
* Sucht einen Funktionär anhand seiner Richternummer.
|
||||
* Sucht einen Funktionär anhand seiner Satz-ID und Satznummer.
|
||||
*/
|
||||
suspend fun findByRichterNummer(richterNummer: String): DomFunktionaer?
|
||||
|
||||
/**
|
||||
* Sucht Funktionäre anhand von Vor- und/oder Nachname (Teilübereinstimmung).
|
||||
*/
|
||||
suspend fun findByName(searchTerm: String, limit: Int = 50): List<DomFunktionaer>
|
||||
|
||||
/**
|
||||
* Sucht alle Funktionäre mit einer bestimmten Rolle.
|
||||
*/
|
||||
suspend fun findByRolle(rolle: FunktionaerRolleE, activeOnly: Boolean = true): List<DomFunktionaer>
|
||||
|
||||
/**
|
||||
* Sucht alle Richter mit einer bestimmten Qualifikation.
|
||||
*/
|
||||
suspend fun findByRichterQualifikation(
|
||||
qualifikation: RichterQualifikationE,
|
||||
activeOnly: Boolean = true
|
||||
): List<DomFunktionaer>
|
||||
|
||||
/**
|
||||
* Sucht alle Funktionäre, die für eine bestimmte Sparte qualifiziert sind.
|
||||
*/
|
||||
suspend fun findBySparte(sparte: SparteE, activeOnly: Boolean = true): List<DomFunktionaer>
|
||||
|
||||
/**
|
||||
* Sucht alle Funktionäre eines bestimmten Vereins.
|
||||
*/
|
||||
suspend fun findByVereinsNummer(vereinsNummer: String, activeOnly: Boolean = true): List<DomFunktionaer>
|
||||
|
||||
/**
|
||||
* Gibt alle aktiven Funktionäre zurück (paginiert).
|
||||
*/
|
||||
suspend fun findAllActive(limit: Int = 100, offset: Int = 0): List<DomFunktionaer>
|
||||
suspend fun findBySatz(satzID: String, satzNummer: Int): DomFunktionaer?
|
||||
|
||||
/**
|
||||
* Gibt alle Funktionäre zurück (paginiert).
|
||||
@@ -82,12 +49,7 @@ interface FunktionaerRepository {
|
||||
suspend fun countActive(): Long
|
||||
|
||||
/**
|
||||
* Zählt alle Richter (Rolle = RICHTER) mit einer bestimmten Qualifikation.
|
||||
* Prüft ob ein Funktionär mit der gegebenen Satz-ID und Satznummer bereits existiert.
|
||||
*/
|
||||
suspend fun countByRichterQualifikation(qualifikation: RichterQualifikationE, activeOnly: Boolean = true): Long
|
||||
|
||||
/**
|
||||
* Prüft ob ein Funktionär mit der gegebenen Richternummer bereits existiert.
|
||||
*/
|
||||
suspend fun existsByRichterNummer(richterNummer: String): Boolean
|
||||
suspend fun existsBySatz(satzID: String, satzNummer: Int): Boolean
|
||||
}
|
||||
|
||||
+22
@@ -246,6 +246,28 @@ interface HorseRepository {
|
||||
*/
|
||||
suspend fun countFeiRegistered(activeOnly: Boolean = true): Long
|
||||
|
||||
/**
|
||||
* Finds horses by their head number (Kopfnummer).
|
||||
*
|
||||
* @param kopfnummer The head number to search for
|
||||
* @return The list of horses found
|
||||
*/
|
||||
suspend fun findByKopfnummer(kopfnummer: String): List<DomPferd>
|
||||
|
||||
/**
|
||||
* Finds a horse by its ZNS satznummer.
|
||||
*
|
||||
* @param satznummer The ZNS satznummer to search for
|
||||
* @return The horse if found, null otherwise
|
||||
*/
|
||||
suspend fun findBySatznummer(satznummer: String): DomPferd?
|
||||
|
||||
/**
|
||||
* Speichert ein Pferd basierend auf der ZNS satznummer (Upsert).
|
||||
* Wenn ein Pferd mit der satznummer existiert, wird es aktualisiert, ansonsten neu angelegt.
|
||||
*/
|
||||
suspend fun upsertBySatznummer(horse: DomPferd): DomPferd
|
||||
|
||||
/**
|
||||
* Speichert ein Pferd basierend auf der Lebensnummer (Upsert).
|
||||
* Wenn ein Pferd mit der Lebensnummer existiert, wird es aktualisiert, ansonsten neu angelegt.
|
||||
|
||||
+1
-38
@@ -2,8 +2,6 @@
|
||||
|
||||
package at.mocode.masterdata.domain.repository
|
||||
|
||||
import at.mocode.core.domain.model.LizenzKlasseE
|
||||
import at.mocode.core.domain.model.SparteE
|
||||
import at.mocode.masterdata.domain.model.DomReiter
|
||||
import kotlin.uuid.Uuid
|
||||
|
||||
@@ -23,42 +21,7 @@ interface ReiterRepository {
|
||||
/**
|
||||
* Sucht einen Reiter anhand seiner Satznummer (OEPS-Mitgliedsnummer).
|
||||
*/
|
||||
suspend fun findBySatznummer(satznummer: String): DomReiter?
|
||||
|
||||
/**
|
||||
* Sucht einen Reiter anhand seiner FEI-ID.
|
||||
*/
|
||||
suspend fun findByFeiId(feiId: String): DomReiter?
|
||||
|
||||
/**
|
||||
* Sucht Reiter anhand von Vor- und/oder Nachname (Teilübereinstimmung).
|
||||
*/
|
||||
suspend fun findByName(searchTerm: String, limit: Int = 50): List<DomReiter>
|
||||
|
||||
/**
|
||||
* Sucht alle Reiter eines bestimmten Vereins.
|
||||
*/
|
||||
suspend fun findByVereinsNummer(vereinsNummer: String, activeOnly: Boolean = true): List<DomReiter>
|
||||
|
||||
/**
|
||||
* Sucht alle Reiter mit einer bestimmten Lizenzklasse.
|
||||
*/
|
||||
suspend fun findByLizenzKlasse(lizenzKlasse: LizenzKlasseE, activeOnly: Boolean = true): List<DomReiter>
|
||||
|
||||
/**
|
||||
* Sucht alle Reiter, die für eine bestimmte Sparte lizenziert sind.
|
||||
*/
|
||||
suspend fun findBySparte(sparte: SparteE, activeOnly: Boolean = true): List<DomReiter>
|
||||
|
||||
/**
|
||||
* Sucht alle Gastreiter.
|
||||
*/
|
||||
suspend fun findGastreiter(activeOnly: Boolean = true): List<DomReiter>
|
||||
|
||||
/**
|
||||
* Gibt alle aktiven Reiter zurück (paginiert).
|
||||
*/
|
||||
suspend fun findAllActive(limit: Int = 100, offset: Int = 0): List<DomReiter>
|
||||
suspend fun findBySatznummer(satznummer: String?): DomReiter?
|
||||
|
||||
/**
|
||||
* Gibt alle Reiter zurück (paginiert).
|
||||
|
||||
+2
-6
@@ -95,9 +95,7 @@ class LicenseMatrixServiceTest {
|
||||
satznummer = "1",
|
||||
nachname = "R1",
|
||||
vorname = "Reiter",
|
||||
lizenzKlasse = LizenzKlasseE.R1,
|
||||
lizenzSparten = listOf(SparteE.SPRINGEN),
|
||||
startkartAktiv = true
|
||||
lizenzKlasse = LizenzKlasseE.R1
|
||||
)
|
||||
|
||||
val klasseA = turnierklassen.find { it.code == "A" }!!
|
||||
@@ -116,9 +114,7 @@ class LicenseMatrixServiceTest {
|
||||
satznummer = "2",
|
||||
nachname = "RD1",
|
||||
vorname = "Reiter",
|
||||
lizenzKlasse = LizenzKlasseE.RD1,
|
||||
lizenzSparten = listOf(SparteE.DRESSUR), // Nur Dressur
|
||||
startkartAktiv = true
|
||||
lizenzKlasse = LizenzKlasseE.RD1
|
||||
)
|
||||
|
||||
val klasseA = turnierklassen.find { it.code == "A" }!!
|
||||
|
||||
Reference in New Issue
Block a user