Add audit logging for Bewerb changes, implement ZNS B-Satz export, enhance Zeitplan tab with audit log display, export dialog, and clickable Bewerb items, and integrate FixedWidthLineBuilder utility.

This commit is contained in:
2026-04-11 21:23:33 +02:00
parent d224e2c521
commit 92aecf9abf
11 changed files with 402 additions and 62 deletions
@@ -1,6 +1,7 @@
package at.mocode.core.utils.parser
import kotlinx.datetime.LocalDate
import kotlinx.datetime.number
/**
* A simple utility to parse fixed-width strings based on 1-based start positions and lengths.
@@ -61,3 +62,34 @@ class FixedWidthLineReader(private val line: String) {
}
}
}
/**
* Utility to build fixed-width lines based on 1-based start positions and lengths.
*/
class FixedWidthLineBuilder(length: Int) {
private val buffer = CharArray(length) { ' ' }
fun setString(start1Based: Int, length: Int, value: String?) {
if (value == null) return
val start0Based = start1Based - 1
val v = value.take(length)
v.forEachIndexed { index, c ->
if (start0Based + index < buffer.size) {
buffer[start0Based + index] = c
}
}
}
fun setInt(start1Based: Int, length: Int, value: Int?) {
if (value == null) return
setString(start1Based, length, value.toString().padStart(length, '0'))
}
fun setLocalDate(start1Based: Int, value: LocalDate?) {
if (value == null) return
val str = "${value.year}${value.month.number.toString().padStart(2, '0')}${value.day.toString().padStart(2, '0')}"
setString(start1Based, 8, str)
}
override fun toString(): String = buffer.concatToString()
}
@@ -3,7 +3,7 @@ package at.mocode.core.utils.database
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import org.jetbrains.exposed.v1.core.Transaction
import org.jetbrains.exposed.v1.jdbc.transactions.experimental.newSuspendedTransaction
import org.jetbrains.exposed.v1.jdbc.transactions.suspendTransaction
/**
* Utility for database operations using Exposed.
@@ -15,7 +15,7 @@ object DatabaseFactory {
*/
suspend fun <T> dbQuery(block: suspend Transaction.() -> T): T =
withContext(Dispatchers.IO) {
newSuspendedTransaction {
suspendTransaction {
block()
}
}