Extend Bewerb repository and service: add RichterEinsatz handling, enhance property mapping, and align DTOs with updated domain model.
This commit is contained in:
+110
-18
@@ -2,7 +2,11 @@
|
||||
|
||||
package at.mocode.entries.service.bewerbe
|
||||
|
||||
import at.mocode.core.domain.model.AbteilungsTeilungsTypE
|
||||
import at.mocode.core.domain.model.BeginnZeitTypE
|
||||
import at.mocode.entries.domain.model.RichterEinsatz
|
||||
import at.mocode.entries.service.persistence.AbteilungTable
|
||||
import at.mocode.entries.service.persistence.BewerbRichterEinsatzTable
|
||||
import at.mocode.entries.service.persistence.BewerbTable
|
||||
import at.mocode.entries.service.tenant.tenantTransaction
|
||||
import org.jetbrains.exposed.v1.core.ResultRow
|
||||
@@ -18,25 +22,92 @@ import kotlin.uuid.toKotlinUuid
|
||||
|
||||
class BewerbRepositoryImpl : BewerbRepository {
|
||||
|
||||
private fun rowToBewerb(row: ResultRow): Bewerb = Bewerb(
|
||||
id = row[BewerbTable.id].toKotlinUuid(),
|
||||
turnierId = row[BewerbTable.turnierId].toKotlinUuid(),
|
||||
klasse = row[BewerbTable.klasse],
|
||||
hoeheCm = row[BewerbTable.hoeheCm],
|
||||
bezeichnung = row[BewerbTable.bezeichnung]
|
||||
)
|
||||
private fun loadRichterEinsaetze(bewerbId: Uuid): List<RichterEinsatz> =
|
||||
BewerbRichterEinsatzTable
|
||||
.selectAll()
|
||||
.where { BewerbRichterEinsatzTable.bewerbId eq bewerbId.toJavaUuid() }
|
||||
.map { row ->
|
||||
RichterEinsatz(
|
||||
funktionaerId = row[BewerbRichterEinsatzTable.funktionaerId].toKotlinUuid(),
|
||||
position = row[BewerbRichterEinsatzTable.position]
|
||||
)
|
||||
}
|
||||
|
||||
private fun persistRichterEinsaetze(bewerbId: Uuid, einsaetze: List<RichterEinsatz>) {
|
||||
BewerbRichterEinsatzTable.deleteWhere { BewerbRichterEinsatzTable.bewerbId eq bewerbId.toJavaUuid() }
|
||||
einsaetze.forEach { re ->
|
||||
BewerbRichterEinsatzTable.insert { s ->
|
||||
s[BewerbRichterEinsatzTable.bewerbId] = bewerbId.toJavaUuid()
|
||||
s[BewerbRichterEinsatzTable.funktionaerId] = re.funktionaerId.toJavaUuid()
|
||||
s[BewerbRichterEinsatzTable.position] = re.position
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun rowToBewerb(row: ResultRow): Bewerb {
|
||||
val id = row[BewerbTable.id].toKotlinUuid()
|
||||
return Bewerb(
|
||||
id = id,
|
||||
turnierId = row[BewerbTable.turnierId].toKotlinUuid(),
|
||||
klasse = row[BewerbTable.klasse],
|
||||
hoeheCm = row[BewerbTable.hoeheCm],
|
||||
bezeichnung = row[BewerbTable.bezeichnung],
|
||||
// Abteilungs-Konfiguration
|
||||
teilungsTyp = row[BewerbTable.teilungsTyp]?.let { AbteilungsTeilungsTypE.valueOf(it) },
|
||||
// Text & Details
|
||||
beschreibung = row[BewerbTable.beschreibung],
|
||||
aufgabe = row[BewerbTable.aufgabe],
|
||||
aufgabenNummer = row[BewerbTable.aufgabenNummer],
|
||||
paraGrade = row[BewerbTable.paraGrade],
|
||||
// Ort & Funktionäre
|
||||
austragungsplatzId = row[BewerbTable.austragungsplatzId]?.toKotlinUuid(),
|
||||
richterEinsaetze = loadRichterEinsaetze(id),
|
||||
// Zeitplan – exposed-kotlin-datetime liefert kotlinx.datetime-Typen direkt
|
||||
geplantesDatum = row[BewerbTable.geplantesDatum],
|
||||
beginnZeitTyp = row[BewerbTable.beginnZeitTyp]?.let { BeginnZeitTypE.valueOf(it) },
|
||||
beginnZeit = row[BewerbTable.beginnZeit],
|
||||
reitdauerMinuten = row[BewerbTable.reitdauerMinuten],
|
||||
umbauMinuten = row[BewerbTable.umbauMinuten],
|
||||
besichtigungMinuten = row[BewerbTable.besichtigungMinuten],
|
||||
stechenGeplant = row[BewerbTable.stechenGeplant],
|
||||
// Finanzen
|
||||
startgeldCent = row[BewerbTable.startgeldCent],
|
||||
geldpreisAusbezahlt = row[BewerbTable.geldpreisAusbezahlt]
|
||||
)
|
||||
}
|
||||
|
||||
override suspend fun create(b: Bewerb): Bewerb = tenantTransaction {
|
||||
val now = Clock.System.now()
|
||||
BewerbTable.insert { s ->
|
||||
s[BewerbTable.id] = b.id.toJavaUuid()
|
||||
s[BewerbTable.turnierId] = b.turnierId.toJavaUuid()
|
||||
s[BewerbTable.klasse] = b.klasse
|
||||
s[BewerbTable.hoeheCm] = b.hoeheCm
|
||||
s[BewerbTable.bezeichnung] = b.bezeichnung
|
||||
s[BewerbTable.createdAt] = now
|
||||
s[BewerbTable.updatedAt] = now
|
||||
s[BewerbTable.id] = b.id.toJavaUuid()
|
||||
s[BewerbTable.turnierId] = b.turnierId.toJavaUuid()
|
||||
s[BewerbTable.klasse] = b.klasse
|
||||
s[BewerbTable.hoeheCm] = b.hoeheCm
|
||||
s[BewerbTable.bezeichnung] = b.bezeichnung
|
||||
// Abteilungs-Konfiguration
|
||||
s[BewerbTable.teilungsTyp] = b.teilungsTyp?.name
|
||||
// Text & Details
|
||||
s[BewerbTable.beschreibung] = b.beschreibung
|
||||
s[BewerbTable.aufgabe] = b.aufgabe
|
||||
s[BewerbTable.aufgabenNummer] = b.aufgabenNummer
|
||||
s[BewerbTable.paraGrade] = b.paraGrade
|
||||
// Ort
|
||||
s[BewerbTable.austragungsplatzId] = b.austragungsplatzId?.toJavaUuid()
|
||||
// Zeitplan – kotlinx.datetime-Typen direkt übergeben
|
||||
s[BewerbTable.geplantesDatum] = b.geplantesDatum
|
||||
s[BewerbTable.beginnZeitTyp] = b.beginnZeitTyp?.name
|
||||
s[BewerbTable.beginnZeit] = b.beginnZeit
|
||||
s[BewerbTable.reitdauerMinuten] = b.reitdauerMinuten
|
||||
s[BewerbTable.umbauMinuten] = b.umbauMinuten
|
||||
s[BewerbTable.besichtigungMinuten] = b.besichtigungMinuten
|
||||
s[BewerbTable.stechenGeplant] = b.stechenGeplant
|
||||
// Finanzen
|
||||
s[BewerbTable.startgeldCent] = b.startgeldCent
|
||||
s[BewerbTable.geldpreisAusbezahlt] = b.geldpreisAusbezahlt
|
||||
s[BewerbTable.createdAt] = now
|
||||
s[BewerbTable.updatedAt] = now
|
||||
}
|
||||
persistRichterEinsaetze(b.id, b.richterEinsaetze)
|
||||
BewerbTable.selectAll().where { BewerbTable.id eq b.id.toJavaUuid() }.map(::rowToBewerb).single()
|
||||
}
|
||||
|
||||
@@ -54,11 +125,32 @@ class BewerbRepositoryImpl : BewerbRepository {
|
||||
override suspend fun update(b: Bewerb): Bewerb = tenantTransaction {
|
||||
val now = Clock.System.now()
|
||||
BewerbTable.update({ BewerbTable.id eq b.id.toJavaUuid() }) { s ->
|
||||
s[BewerbTable.klasse] = b.klasse
|
||||
s[BewerbTable.hoeheCm] = b.hoeheCm
|
||||
s[BewerbTable.bezeichnung] = b.bezeichnung
|
||||
s[BewerbTable.updatedAt] = now
|
||||
s[BewerbTable.klasse] = b.klasse
|
||||
s[BewerbTable.hoeheCm] = b.hoeheCm
|
||||
s[BewerbTable.bezeichnung] = b.bezeichnung
|
||||
// Abteilungs-Konfiguration
|
||||
s[BewerbTable.teilungsTyp] = b.teilungsTyp?.name
|
||||
// Text & Details
|
||||
s[BewerbTable.beschreibung] = b.beschreibung
|
||||
s[BewerbTable.aufgabe] = b.aufgabe
|
||||
s[BewerbTable.aufgabenNummer] = b.aufgabenNummer
|
||||
s[BewerbTable.paraGrade] = b.paraGrade
|
||||
// Ort
|
||||
s[BewerbTable.austragungsplatzId] = b.austragungsplatzId?.toJavaUuid()
|
||||
// Zeitplan – kotlinx.datetime-Typen direkt übergeben
|
||||
s[BewerbTable.geplantesDatum] = b.geplantesDatum
|
||||
s[BewerbTable.beginnZeitTyp] = b.beginnZeitTyp?.name
|
||||
s[BewerbTable.beginnZeit] = b.beginnZeit
|
||||
s[BewerbTable.reitdauerMinuten] = b.reitdauerMinuten
|
||||
s[BewerbTable.umbauMinuten] = b.umbauMinuten
|
||||
s[BewerbTable.besichtigungMinuten] = b.besichtigungMinuten
|
||||
s[BewerbTable.stechenGeplant] = b.stechenGeplant
|
||||
// Finanzen
|
||||
s[BewerbTable.startgeldCent] = b.startgeldCent
|
||||
s[BewerbTable.geldpreisAusbezahlt] = b.geldpreisAusbezahlt
|
||||
s[BewerbTable.updatedAt] = now
|
||||
}
|
||||
persistRichterEinsaetze(b.id, b.richterEinsaetze)
|
||||
BewerbTable.selectAll().where { BewerbTable.id eq b.id.toJavaUuid() }.map(::rowToBewerb).single()
|
||||
}
|
||||
|
||||
|
||||
+54
-6
@@ -6,6 +6,7 @@ import at.mocode.entries.domain.repository.NennungRepository
|
||||
import at.mocode.entries.service.errors.LockedException
|
||||
import at.mocode.entries.service.persistence.TurnierTable
|
||||
import at.mocode.entries.service.tenant.tenantTransaction
|
||||
import at.mocode.entries.domain.model.RichterEinsatz
|
||||
import org.jetbrains.exposed.v1.core.eq
|
||||
import org.jetbrains.exposed.v1.jdbc.selectAll
|
||||
import kotlin.uuid.Uuid
|
||||
@@ -21,14 +22,35 @@ class BewerbService(
|
||||
row?.get(TurnierTable.status) == "PUBLISHED"
|
||||
}
|
||||
|
||||
suspend fun create(turnierId: Uuid, klasse: String, hoeheCm: Int?, bezeichnung: String): Bewerb {
|
||||
suspend fun create(turnierId: Uuid, req: CreateBewerbRequest): Bewerb {
|
||||
if (isTurnierPublished(turnierId)) throw LockedException("Turnier ist PUBLISHED – Bewerbe können nicht angelegt werden")
|
||||
val b = Bewerb(
|
||||
id = Uuid.random(),
|
||||
turnierId = turnierId,
|
||||
klasse = klasse,
|
||||
hoeheCm = hoeheCm,
|
||||
bezeichnung = bezeichnung
|
||||
klasse = req.klasse,
|
||||
hoeheCm = req.hoeheCm,
|
||||
bezeichnung = req.bezeichnung,
|
||||
// Abteilungs-Konfiguration
|
||||
teilungsTyp = req.teilungsTyp,
|
||||
// Text & Details
|
||||
beschreibung = req.beschreibung,
|
||||
aufgabe = req.aufgabe,
|
||||
aufgabenNummer = req.aufgabenNummer,
|
||||
paraGrade = req.paraGrade,
|
||||
// Ort & Funktionäre
|
||||
austragungsplatzId = req.austragungsplatzId?.let { Uuid.parse(it) },
|
||||
richterEinsaetze = req.richterEinsaetze.map { RichterEinsatz(Uuid.parse(it.funktionaerId), it.position) },
|
||||
// Zeitplan
|
||||
geplantesDatum = req.geplantesDatum,
|
||||
beginnZeitTyp = req.beginnZeitTyp,
|
||||
beginnZeit = req.beginnZeit,
|
||||
reitdauerMinuten = req.reitdauerMinuten,
|
||||
umbauMinuten = req.umbauMinuten,
|
||||
besichtigungMinuten = req.besichtigungMinuten,
|
||||
stechenGeplant = req.stechenGeplant,
|
||||
// Finanzen
|
||||
startgeldCent = req.startgeldCent,
|
||||
geldpreisAusbezahlt = req.geldpreisAusbezahlt
|
||||
)
|
||||
return repo.create(b)
|
||||
}
|
||||
@@ -37,10 +59,36 @@ class BewerbService(
|
||||
|
||||
suspend fun get(id: Uuid): Bewerb = repo.findById(id) ?: throw NoSuchElementException("Bewerb $id nicht gefunden")
|
||||
|
||||
suspend fun update(id: Uuid, klasse: String, hoeheCm: Int?, bezeichnung: String): Bewerb {
|
||||
suspend fun update(id: Uuid, req: UpdateBewerbRequest): Bewerb {
|
||||
val current = get(id)
|
||||
if (isTurnierPublished(current.turnierId)) throw LockedException("Turnier ist PUBLISHED – Bewerbe können nicht geändert werden")
|
||||
return repo.update(current.copy(klasse = klasse, hoeheCm = hoeheCm, bezeichnung = bezeichnung))
|
||||
val updated = current.copy(
|
||||
klasse = req.klasse,
|
||||
hoeheCm = req.hoeheCm,
|
||||
bezeichnung = req.bezeichnung,
|
||||
// Abteilungs-Konfiguration
|
||||
teilungsTyp = req.teilungsTyp,
|
||||
// Text & Details
|
||||
beschreibung = req.beschreibung,
|
||||
aufgabe = req.aufgabe,
|
||||
aufgabenNummer = req.aufgabenNummer,
|
||||
paraGrade = req.paraGrade,
|
||||
// Ort & Funktionäre
|
||||
austragungsplatzId = req.austragungsplatzId?.let { Uuid.parse(it) },
|
||||
richterEinsaetze = req.richterEinsaetze.map { RichterEinsatz(Uuid.parse(it.funktionaerId), it.position) },
|
||||
// Zeitplan
|
||||
geplantesDatum = req.geplantesDatum,
|
||||
beginnZeitTyp = req.beginnZeitTyp,
|
||||
beginnZeit = req.beginnZeit,
|
||||
reitdauerMinuten = req.reitdauerMinuten,
|
||||
umbauMinuten = req.umbauMinuten,
|
||||
besichtigungMinuten = req.besichtigungMinuten,
|
||||
stechenGeplant = req.stechenGeplant,
|
||||
// Finanzen
|
||||
startgeldCent = req.startgeldCent,
|
||||
geldpreisAusbezahlt = req.geldpreisAusbezahlt,
|
||||
)
|
||||
return repo.update(updated)
|
||||
}
|
||||
|
||||
suspend fun delete(id: Uuid) {
|
||||
|
||||
Reference in New Issue
Block a user