Refactor domain models (DomFunktionaer, DomReiter, DomPferd) to align with ZNS conventions: simplify naming, update properties, and enhance parser logic. Adjust related controllers, repository methods, and tests. Update MASTER_ROADMAP with changes to domain models.

This commit is contained in:
2026-04-06 00:00:20 +02:00
parent 1e5fa3d053
commit f50d4deb16
57 changed files with 811 additions and 532 deletions
@@ -1,13 +1,13 @@
package at.mocode.zns.parser
import at.mocode.core.domain.model.DatenQuelleE
import at.mocode.core.domain.model.LizenzKlasseE
import at.mocode.core.domain.model.ReiterLizenzKlasseE
import at.mocode.core.domain.model.PferdeGeschlechtE
import at.mocode.core.utils.parser.FixedWidthLineReader
import at.mocode.masterdata.domain.model.DomFunktionaer
import at.mocode.masterdata.domain.model.DomPferd
import at.mocode.masterdata.domain.model.DomReiter
import at.mocode.masterdata.domain.model.DomVerein
import at.mocode.masterdata.domain.model.Funktionaer
import at.mocode.masterdata.domain.model.Pferd
import at.mocode.masterdata.domain.model.Reiter
import at.mocode.masterdata.domain.model.Verein
import kotlin.uuid.ExperimentalUuidApi
import kotlin.uuid.Uuid
@@ -23,7 +23,7 @@ object ZnsLegacyParsers {
/**
* Parses a line from VEREIN01.DAT.
*/
fun parseVerein(line: String): DomVerein? {
fun parseVerein(line: String): Verein? {
if (line.isBlank() || line.length < 5) return null
val reader = FixedWidthLineReader(line)
@@ -33,9 +33,9 @@ object ZnsLegacyParsers {
if (vereinsNummer.isBlank() || vereinsName.isBlank()) return null
return DomVerein(
return Verein(
vereinsNummer = vereinsNummer,
name = vereinsName,
vereinName = vereinsName,
datenQuelle = DatenQuelleE.IMPORT_ZNS
)
}
@@ -43,7 +43,7 @@ object ZnsLegacyParsers {
/**
* Parses a line from LIZENZ01.DAT.
*/
fun parseLizenz(line: String): DomReiter? {
fun parseLizenz(line: String): Reiter? {
if (line.isBlank() || line.length < 57) return null
val reader = FixedWidthLineReader(line)
@@ -79,8 +79,9 @@ object ZnsLegacyParsers {
val feiId = reader.getString(190, 8)
val sperrListe = reader.getString(198, 1)
val lizenzInfo = reader.getString(201, 10)
val lizenzKlasse = mapLizenz(reiterLizenz)
return DomReiter(
return Reiter(
personId = Uuid.random(),
satznummer = satznummer,
nachname = nachname,
@@ -102,7 +103,7 @@ object ZnsLegacyParsers {
feiId = feiId.ifBlank { null },
sperrListe = sperrListe.ifBlank { null },
lizenzInfo = lizenzInfo.ifBlank { null },
lizenzKlasse = mapLizenz(reiterLizenz),
lizenzKlasse = lizenzKlasse,
datenQuelle = DatenQuelleE.IMPORT_ZNS
)
}
@@ -110,12 +111,16 @@ object ZnsLegacyParsers {
/**
* Parses a line from PFERDE01.DAT.
*/
fun parsePferd(line: String): DomPferd? {
if (line.isBlank() || line.trim().length < 40) return null
fun parsePferd(line: String): Pferd? {
if (line.isBlank() || line.trim().length < 4) return null
val reader = FixedWidthLineReader(line)
val kopfnummer = reader.getString(1, 4)
val name = reader.getString(5, 30)
// We need at least a name to identify a horse record
if (name.isBlank()) return null
val lebensnummer = reader.getString(35, 9)
val geschlechtChar = reader.getString(44, 1)
val geschlecht = mapGeschlecht(geschlechtChar)
@@ -128,16 +133,15 @@ object ZnsLegacyParsers {
val vaterName = reader.getString(162, 30)
val feiPass = reader.getString(192, 10)
val satznummer = reader.getString(202, 10)
// Some lines might not have a satznummer, but we need at least a name to identify it
if (satznummer.isBlank() && name.isBlank()) return null
return DomPferd(
return Pferd(
personId = Uuid.random(),
pferdeName = name,
geschlecht = geschlecht,
geburtsjahr = geburtsjahr,
lebensnummer = lebensnummer.ifBlank { null },
kopfnummer = kopfnummer.ifBlank { null },
satznummer = satznummer,
satznummer = satznummer.ifBlank { null },
farbe = farbe.ifBlank { null },
abstammung = abstammung.ifBlank { null },
vereinNummer = vereinNummer,
@@ -152,7 +156,7 @@ object ZnsLegacyParsers {
/**
* Parses a line from RICHT01.DAT (Richter oder Parcoursbauer).
*/
fun parseFunktionaer(line: String): DomFunktionaer? {
fun parseFunktionaer(line: String): Funktionaer? {
if (line.isBlank() || line.length < 8) return null
val reader = FixedWidthLineReader(line)
@@ -171,8 +175,9 @@ object ZnsLegacyParsers {
.map { it.trim() }
.filter { it.isNotBlank() }
return DomFunktionaer(
satzID = satzID,
return Funktionaer(
personId = null,
satzId = satzID,
satzNummer = satzNummer,
name = name.ifBlank { null },
qualifikationen = qualifikationen,
@@ -180,18 +185,15 @@ object ZnsLegacyParsers {
)
}
private fun mapLizenz(lizenz: String): LizenzKlasseE {
private fun mapLizenz(lizenz: String): ReiterLizenzKlasseE {
return when (lizenz.uppercase()) {
"R1" -> LizenzKlasseE.R1
"R2" -> LizenzKlasseE.R2
"R3" -> LizenzKlasseE.R3
"RD1" -> LizenzKlasseE.RD1
"RD2" -> LizenzKlasseE.RD2
"RD3" -> LizenzKlasseE.RD3
"JN" -> LizenzKlasseE.JN
"JG" -> LizenzKlasseE.JG
"YR" -> LizenzKlasseE.YR
else -> LizenzKlasseE.LIZENZFREI
"R1" -> ReiterLizenzKlasseE.R1
"R2" -> ReiterLizenzKlasseE.R2
"R3" -> ReiterLizenzKlasseE.R3
"RD1" -> ReiterLizenzKlasseE.RD1
"RD2" -> ReiterLizenzKlasseE.RD2
"RD3" -> ReiterLizenzKlasseE.RD3
else -> ReiterLizenzKlasseE.LIZENZFREI
}
}
@@ -14,7 +14,7 @@ class ZnsLegacyParsersTest {
assertNotNull(result)
assertEquals("1234", result.vereinsNummer)
assertEquals("Reitverein Test", result.name)
assertEquals("Reitverein Test", result.vereinName)
}
@Test
@@ -82,7 +82,7 @@ class ZnsLegacyParsersTest {
val result = ZnsLegacyParsers.parseFunktionaer(line)
assertNotNull(result)
assertEquals("X", result.satzID)
assertEquals("X", result.satzId)
assertEquals(10128, result.satzNummer)
assertEquals("Zitterbart Rainer", result.name)
assertEquals(listOf("PI-A"), result.qualifikationen)
@@ -94,7 +94,7 @@ class ZnsLegacyParsersTest {
val line1 = "X139552Mc Mullen Elizabeth DIOR"
val result1 = ZnsLegacyParsers.parseFunktionaer(line1)
assertNotNull(result1)
assertEquals("X", result1.satzID)
assertEquals("X", result1.satzId)
assertEquals(139552, result1.satzNummer)
assertEquals("Mc Mullen Elizabeth", result1.name)
assertEquals(listOf("DIOR"), result1.qualifikationen)
@@ -111,10 +111,28 @@ class ZnsLegacyParsersTest {
val line3 = "Y002211Salusek Andreas Christian P3,PL2"
val result3 = ZnsLegacyParsers.parseFunktionaer(line3)
assertNotNull(result3)
assertEquals("Y", result3.satzID)
assertEquals("Y", result3.satzId)
assertEquals(2211, result3.satzNummer)
assertEquals("Salusek Andreas Christian", result3.name)
assertEquals(listOf("P3", "PL2"), result3.qualifikationen)
// X001061Kager Franz DPF,DSGP,GAR-SP,GAR-VS,SPF
val line4 = "X001061Kager Franz DPF,DSGP,GAR-SP,GAR-VS,SPF"
val result4 = ZnsLegacyParsers.parseFunktionaer(line4)
assertNotNull(result4)
assertEquals("X", result4.satzId)
assertEquals(1061, result4.satzNummer)
assertEquals("Kager Franz", result4.name)
assertEquals(listOf("DPF", "DSGP", "GAR-SP", "GAR-VS", "SPF"), result4.qualifikationen)
// X001112Keiblinger Brigitta DPF,DSGP,SPF,SS,VS,VSILEV1"
val line5 = "X001112Keiblinger Brigitta DPF,DSGP,SPF,SS,VS,VSILEV1"
val result5 = ZnsLegacyParsers.parseFunktionaer(line5)
assertNotNull(result5)
assertEquals("X", result5.satzId)
assertEquals(1112, result5.satzNummer)
assertEquals("Keiblinger Brigitta", result5.name)
assertEquals(listOf("DPF", "DSGP", "SPF", "SS", "VS", "VSILEV1"), result5.qualifikationen)
}
@Test
@@ -145,6 +163,20 @@ class ZnsLegacyParsersTest {
assertEquals("5637401268", result.satznummer)
}
@Test
fun `parsePferd should extract shortened PFERDE01 correctly`() {
// A line that ends after the name
val line = "1234Fuchur"
val result = ZnsLegacyParsers.parsePferd(line)
assertNotNull(result)
assertEquals("1234", result.kopfnummer)
assertEquals("Fuchur", result.pferdeName)
assertEquals(null, result.satznummer)
assertEquals(null, result.lebensnummer)
assertEquals(PferdeGeschlechtE.UNBEKANNT, result.geschlecht)
}
@Test
fun `parseLizenz should extract real LIZENZ01 correctly for Ebner Sarah`() {
// Real example from user: