Pārlūkot izejas kodu

Merge branch 'production' into stockTakeUpdate

stockTakeUpdate
CANCERYS\kw093 pirms 1 nedēļas
vecāks
revīzija
143211d2bb
8 mainītis faili ar 545 papildinājumiem un 0 dzēšanām
  1. +32
    -0
      src/main/java/com/ffii/fpsms/modules/pickOrder/entity/TruckLaneRenameLog.kt
  2. +9
    -0
      src/main/java/com/ffii/fpsms/modules/pickOrder/entity/TruckLaneRenameLogRepository.kt
  3. +61
    -0
      src/main/java/com/ffii/fpsms/modules/pickOrder/service/TruckLaneRenameRules.kt
  4. +336
    -0
      src/main/java/com/ffii/fpsms/modules/pickOrder/service/TruckLaneRenameService.kt
  5. +26
    -0
      src/main/java/com/ffii/fpsms/modules/pickOrder/service/TruckLaneVersionService.kt
  6. +15
    -0
      src/main/java/com/ffii/fpsms/modules/pickOrder/web/TruckController.kt
  7. +43
    -0
      src/main/java/com/ffii/fpsms/modules/pickOrder/web/models/TruckLaneRenameModels.kt
  8. +23
    -0
      src/main/resources/db/changelog/changes/20261026_truck_lane_rename/01_create_truck_lane_rename_log.sql

+ 32
- 0
src/main/java/com/ffii/fpsms/modules/pickOrder/entity/TruckLaneRenameLog.kt Parādīt failu

@@ -0,0 +1,32 @@
package com.ffii.fpsms.modules.pickOrder.entity

import com.ffii.core.entity.BaseEntity
import jakarta.persistence.Column
import jakarta.persistence.Entity
import jakarta.persistence.Table

@Entity
@Table(name = "truck_lane_rename_log")
open class TruckLaneRenameLog : BaseEntity<Long>() {
@Column(name = "oldCode", nullable = false, length = 50)
open var oldCode: String = ""

@Column(name = "newCode", nullable = false, length = 50)
open var newCode: String = ""

@Column(name = "storeId", nullable = false, length = 10)
open var storeId: String = ""

@Column(name = "remark", length = 255)
open var remark: String? = null

/** A clock time, or `mixed` when rows in the bucket did not share one time. */
@Column(name = "oldDepartureTime", length = 20)
open var oldDepartureTime: String? = null

@Column(name = "newDepartureTime", length = 20)
open var newDepartureTime: String? = null

@Column(name = "ticketCount", nullable = false)
open var ticketCount: Int = 0
}

+ 9
- 0
src/main/java/com/ffii/fpsms/modules/pickOrder/entity/TruckLaneRenameLogRepository.kt Parādīt failu

@@ -0,0 +1,9 @@
package com.ffii.fpsms.modules.pickOrder.entity

import org.springframework.data.jpa.repository.JpaRepository
import org.springframework.stereotype.Repository

@Repository
interface TruckLaneRenameLogRepository : JpaRepository<TruckLaneRenameLog, Long> {
fun findTop50ByDeletedFalseOrderByIdDesc(): List<TruckLaneRenameLog>
}

+ 61
- 0
src/main/java/com/ffii/fpsms/modules/pickOrder/service/TruckLaneRenameRules.kt Parādīt failu

@@ -0,0 +1,61 @@
package com.ffii.fpsms.modules.pickOrder.service

/**
* Bucket identity shared by the route board and the rename transaction.
* Remark is part of the key only on 4F. Comparison trims, and does not collapse inner spaces.
*/
object TruckLaneRenameRules {
const val RESERVED = "車線-X"
const val MAX_LEN = 50

data class BucketRef(
val code: String,
val floor: String,
val remarkKey: String,
)

fun floorOf(storeId: String?): String {
val compact = storeId?.trim()?.uppercase()?.replace(" ", "")?.replace("/", "") ?: ""
return if (compact == "4F") "4F" else "2F"
}

/** Blank, null, and whitespace-only remarks share the empty key. 2F ignores remark. */
fun remarkKey(floor: String, remark: String?): String {
if (floor != "4F") return ""
return remark?.trim().orEmpty()
}

/** Null when the name is acceptable. Otherwise a stable error code. */
fun validateNames(oldName: String, newName: String): String? {
val oldTrim = oldName.trim()
val newTrim = newName.trim()
if (oldTrim.isEmpty() || newTrim.isEmpty()) return "LANE_NAME_EMPTY"
if (newTrim.length > MAX_LEN) return "LANE_NAME_TOO_LONG"
if (oldTrim == RESERVED || newTrim == RESERVED) return "LANE_NAME_RESERVED"
return null
}

/**
* Same-remark collision ignores case and excludes the source bucket.
* A different remark refuses only when the trimmed new name is exactly the same,
* because tickets have no remark and could not tell the buckets apart.
*/
fun collisionCode(source: BucketRef, newCode: String, live: List<BucketRef>): String? {
val next = newCode.trim()
for (other in live) {
if (other.floor != source.floor) continue
val sameSource = other.remarkKey == source.remarkKey &&
other.code.trim().equals(source.code.trim(), ignoreCase = true)
if (sameSource) continue
if (other.remarkKey == source.remarkKey &&
other.code.trim().equals(next, ignoreCase = true)
) {
return "LANE_NAME_TAKEN"
}
if (other.remarkKey != source.remarkKey && other.code.trim() == next) {
return "LANE_NAME_REMARK_AMBIGUOUS"
}
}
return null
}
}

+ 336
- 0
src/main/java/com/ffii/fpsms/modules/pickOrder/service/TruckLaneRenameService.kt Parādīt failu

@@ -0,0 +1,336 @@
package com.ffii.fpsms.modules.pickOrder.service

import com.ffii.core.support.JdbcDao
import com.ffii.fpsms.modules.pickOrder.entity.Truck
import com.ffii.fpsms.modules.pickOrder.entity.TruckLaneRenameLog
import com.ffii.fpsms.modules.pickOrder.entity.TruckLaneRenameLogRepository
import com.ffii.fpsms.modules.pickOrder.entity.TruckRepository
import com.ffii.fpsms.modules.pickOrder.web.models.PreviewTruckLaneRenameRequest
import com.ffii.fpsms.modules.pickOrder.web.models.PreviewTruckLaneRenameResponse
import com.ffii.fpsms.modules.pickOrder.web.models.RenameTruckLaneRequest
import com.ffii.fpsms.modules.pickOrder.web.models.RenameTruckLaneResponse
import com.ffii.fpsms.modules.pickOrder.web.models.TruckLaneRenameLogResponse
import org.springframework.http.HttpStatus
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional
import org.springframework.web.server.ResponseStatusException
import java.time.LocalTime
import java.time.format.DateTimeParseException

@Service
open class TruckLaneRenameService(
private val jdbcDao: JdbcDao,
private val truckRepository: TruckRepository,
private val renameLogRepository: TruckLaneRenameLogRepository,
) {
@Transactional(readOnly = true)
open fun preview(req: PreviewTruckLaneRenameRequest): PreviewTruckLaneRenameResponse {
val code = req.truckLanceCode.trim()
if (code.isEmpty()) throw badRequest("LANE_NAME_EMPTY")
val floor = TruckLaneRenameRules.floorOf(req.storeId)
val remarkKey = TruckLaneRenameRules.remarkKey(floor, req.remark)
val params = ticketParams(code, floor, remarkKey)
return PreviewTruckLaneRenameResponse(
unfinishedCount = count(UNFINISHED_COUNT_SQL, params),
completedCount = count(COMPLETED_COUNT_SQL, params),
handlerNames = jdbcDao.queryForStrings(HANDLER_SQL, params)
.map { it.trim() }
.filter { it.isNotEmpty() }
.distinct(),
openScheduleCount = count(OPEN_SCHEDULE_COUNT_SQL, params),
)
}

@Transactional
open fun rename(req: RenameTruckLaneRequest): RenameTruckLaneResponse {
val oldCode = req.truckLanceCode.trim()
val newCode = req.replacementTruckLanceCode.trim()
val nameError = TruckLaneRenameRules.validateNames(oldCode, newCode)
if (nameError != null) throw badRequest(nameError)
val floor = TruckLaneRenameRules.floorOf(req.storeId)
val remarkKey = TruckLaneRenameRules.remarkKey(floor, req.remark)
val newTime = if (req.departureTimeChanged) parseTime(req.newDepartureTime) else null
if (req.departureTimeChanged && newTime == null) throw badRequest("LANE_TIME_INVALID")

jdbcDao.queryForList(
"SELECT id FROM truck WHERE deleted = 0 FOR UPDATE",
emptyMap<String, Any>(),
)

val live = truckRepository.findAllForRouteBoard().filter { it.deleted != true }
val sourceRows = live.filter { inBucket(it, oldCode, floor, remarkKey) }
if (sourceRows.isEmpty()) throw badRequest("LANE_NOT_FOUND")

val refs = liveBuckets(live)
val collision = TruckLaneRenameRules.collisionCode(
TruckLaneRenameRules.BucketRef(oldCode, floor, remarkKey),
newCode,
refs,
)
if (collision != null) throw conflict(collision)

val oldTimeLabel = describeTimes(sourceRows.map { it.departureTime })
val casings = sourceRows.map { it.truckLanceCode?.trim().orEmpty() }.filter { it.isNotEmpty() }.distinct()
var scheduleCount = 0
var ticketCount = 0
for (casing in casings) {
scheduleCount += applyOpenScheduleRename(casing, newCode, floor, remarkKey)
val params = ticketParams(casing, floor, remarkKey).toMutableMap()
params["newCode"] = newCode
ticketCount += jdbcDao.executeUpdate(
updateTicketSql(DOPO_UPDATE_SQL, req.departureTimeChanged),
withTime(params, newTime),
)
jdbcDao.executeUpdate(
updateTicketSql(PICK_UPDATE_SQL, req.departureTimeChanged),
withTime(params, newTime),
)
}
for (row in sourceRows) {
row.truckLanceCode = newCode
if (req.departureTimeChanged) row.departureTime = newTime
}
truckRepository.saveAll(sourceRows)

val log = TruckLaneRenameLog()
log.oldCode = oldCode
log.newCode = newCode
log.storeId = floor
log.remark = remarkKey.ifEmpty { null }
log.oldDepartureTime = oldTimeLabel
log.newDepartureTime = if (req.departureTimeChanged) newTime.toString() else oldTimeLabel
log.ticketCount = ticketCount
renameLogRepository.save(log)

return RenameTruckLaneResponse(
truckLanceCode = newCode,
ticketCount = ticketCount,
scheduleLineCount = scheduleCount,
)
}

/**
* Restore writes master rows back to the snapshot name and does not move unfinished tickets.
* Open schedule from/to that still point at the current name are moved back here.
*/
@Transactional
open fun rewriteOpenScheduleNames(
oldCode: String,
newCode: String,
storeId: String?,
remark: String?,
): Int {
val floor = TruckLaneRenameRules.floorOf(storeId)
val remarkKey = TruckLaneRenameRules.remarkKey(floor, remark)
return applyOpenScheduleRename(oldCode.trim(), newCode.trim(), floor, remarkKey)
}

@Transactional(readOnly = true)
open fun recentLogs(): List<TruckLaneRenameLogResponse> =
renameLogRepository.findTop50ByDeletedFalseOrderByIdDesc().map { row ->
TruckLaneRenameLogResponse(
id = row.id ?: 0,
created = row.created?.toString(),
createdBy = row.createdBy,
oldCode = row.oldCode,
newCode = row.newCode,
storeId = row.storeId,
remark = row.remark,
oldDepartureTime = row.oldDepartureTime,
newDepartureTime = row.newDepartureTime,
ticketCount = row.ticketCount,
)
}

private fun applyOpenScheduleRename(
oldCode: String,
newCode: String,
floor: String,
remarkKey: String,
): Int {
if (oldCode.isEmpty() || newCode.isEmpty() || oldCode == newCode) return 0
val params = ticketParams(oldCode, floor, remarkKey).toMutableMap()
params["newCode"] = newCode
val matched = count(OPEN_SCHEDULE_COUNT_SQL, params)
jdbcDao.executeUpdate(SCHEDULE_FROM_SQL, params)
jdbcDao.executeUpdate(SCHEDULE_TO_SQL, params)
return matched
}

private fun liveBuckets(live: List<Truck>): List<TruckLaneRenameRules.BucketRef> {
val grouped = linkedMapOf<Triple<String, String, String>, String>()
for (row in live) {
val code = row.truckLanceCode?.trim().orEmpty()
if (code.isEmpty()) continue
val floor = TruckLaneRenameRules.floorOf(row.storeId)
val remarkKey = TruckLaneRenameRules.remarkKey(floor, row.remark)
val key = Triple(code.lowercase(), floor, remarkKey)
grouped.putIfAbsent(key, code)
}
return grouped.map { (key, code) ->
TruckLaneRenameRules.BucketRef(code, key.second, key.third)
}
}

private fun inBucket(row: Truck, code: String, floor: String, remarkKey: String): Boolean {
val rowFloor = TruckLaneRenameRules.floorOf(row.storeId)
val rowRemark = TruckLaneRenameRules.remarkKey(rowFloor, row.remark)
return rowFloor == floor &&
rowRemark == remarkKey &&
row.truckLanceCode?.trim().orEmpty().equals(code, ignoreCase = true)
}

private fun describeTimes(times: List<LocalTime?>): String {
val labels = times.map { it?.withNano(0)?.toString() ?: "" }.distinct()
return if (labels.size <= 1) labels.firstOrNull().orEmpty() else "mixed"
}

private fun parseTime(raw: String?): LocalTime? {
val text = raw?.trim().orEmpty()
if (text.isEmpty()) return null
val normalized = if (text.length == 5) "$text:00" else text
return try {
LocalTime.parse(normalized)
} catch (_: DateTimeParseException) {
null
}
}

private fun withTime(params: MutableMap<String, Any?>, time: LocalTime?): Map<String, Any?> {
if (time != null) params["newTime"] = time.toString()
return params
}

private fun updateTicketSql(base: String, withTime: Boolean): String {
if (!withTime) return base
return base.replace("SET colCode = :newCode", "SET colCode = :newCode, colTime = :newTime")
.replace("SET TruckLanceCode = :newCode", "SET TruckLanceCode = :newCode, truck_departure_time = :newTime")
.replace("SET truckLanceCode = :newCode", "SET truckLanceCode = :newCode, truckDepartureTime = :newTime")
}

private fun ticketParams(code: String, floor: String, remarkKey: String): Map<String, Any?> = mapOf(
"oldCode" to code,
"floor" to floor,
"remark" to remarkKey,
"blankRemark" to if (remarkKey.isEmpty()) 1 else 0,
)

private fun count(sql: String, params: Map<String, Any?>): Int {
val row = jdbcDao.queryForList(sql, params).firstOrNull() ?: return 0
val value = row.values.firstOrNull()
return (value as? Number)?.toInt() ?: 0
}

private fun badRequest(code: String) = ResponseStatusException(HttpStatus.BAD_REQUEST, code)

private fun conflict(code: String) = ResponseStatusException(HttpStatus.CONFLICT, code)

companion object {
private const val FLOOR_MATCH = """
(
(:floor = '4F' AND UPPER(REPLACE(TRIM(storeCol), ' ', '')) IN ('4F', '4/F'))
OR (:floor <> '4F' AND UPPER(REPLACE(TRIM(storeCol), ' ', '')) IN ('2F', '2/F'))
)
"""

private const val REMARK_MATCH_4F = """
(
:floor <> '4F'
OR (
(:blankRemark = 1 AND (remarkCol IS NULL OR TRIM(remarkCol) = ''))
OR (:blankRemark = 0 AND TRIM(remarkCol) = :remark)
)
)
"""

private val UNFINISHED_COUNT_SQL = """
SELECT COUNT(*) AS cnt
FROM delivery_order_pick_order
WHERE deleted = 0
AND ticketStatus IN ('pending', 'released')
AND TRIM(truckLanceCode) = :oldCode
AND ${FLOOR_MATCH.replace("storeCol", "storeId")}
""".trimIndent()

private val COMPLETED_COUNT_SQL = """
SELECT COUNT(*) AS cnt
FROM delivery_order_pick_order
WHERE deleted = 0
AND ticketStatus = 'completed'
AND TRIM(truckLanceCode) = :oldCode
AND ${FLOOR_MATCH.replace("storeCol", "storeId")}
""".trimIndent()

private val HANDLER_SQL = """
SELECT DISTINCT TRIM(handlerName)
FROM delivery_order_pick_order
WHERE deleted = 0
AND ticketStatus IN ('pending', 'released')
AND handledBy IS NOT NULL
AND handlerName IS NOT NULL
AND TRIM(handlerName) <> ''
AND TRIM(truckLanceCode) = :oldCode
AND ${FLOOR_MATCH.replace("storeCol", "storeId")}
""".trimIndent()

private val DOPO_UPDATE_SQL = """
UPDATE delivery_order_pick_order
SET truckLanceCode = :newCode, version = version + 1
WHERE deleted = 0
AND ticketStatus IN ('pending', 'released')
AND TRIM(truckLanceCode) = :oldCode
AND ${FLOOR_MATCH.replace("storeCol", "storeId")}
""".trimIndent()

private val PICK_UPDATE_SQL = """
UPDATE do_pick_order
SET TruckLanceCode = :newCode, version = version + 1
WHERE deleted = 0
AND ticket_status IN ('pending', 'released')
AND TRIM(TruckLanceCode) = :oldCode
AND ${FLOOR_MATCH.replace("storeCol", "store_id")}
""".trimIndent()

private val OPEN_SCHEDULE_COUNT_SQL = """
SELECT COUNT(*) AS cnt
FROM truck_lane_schedule_line l
JOIN truck_lane_schedule s ON s.id = l.scheduleId
WHERE l.deleted = 0 AND s.deleted = 0
AND s.status NOT IN ('APPLIED', 'CANCELLED')
AND (
(
TRIM(l.fromTruckLanceCode) = :oldCode
AND ${FLOOR_MATCH.replace("storeCol", "l.fromStoreId")}
AND ${REMARK_MATCH_4F.replace("remarkCol", "l.fromRemark")}
)
OR (
TRIM(l.toTruckLanceCode) = :oldCode
AND ${FLOOR_MATCH.replace("storeCol", "l.toStoreId")}
AND ${REMARK_MATCH_4F.replace("remarkCol", "l.toRemark")}
)
)
""".trimIndent()

private val SCHEDULE_FROM_SQL = """
UPDATE truck_lane_schedule_line l
JOIN truck_lane_schedule s ON s.id = l.scheduleId
SET l.fromTruckLanceCode = :newCode, l.version = l.version + 1
WHERE l.deleted = 0 AND s.deleted = 0
AND s.status NOT IN ('APPLIED', 'CANCELLED')
AND TRIM(l.fromTruckLanceCode) = :oldCode
AND ${FLOOR_MATCH.replace("storeCol", "l.fromStoreId")}
AND ${REMARK_MATCH_4F.replace("remarkCol", "l.fromRemark")}
""".trimIndent()

private val SCHEDULE_TO_SQL = """
UPDATE truck_lane_schedule_line l
JOIN truck_lane_schedule s ON s.id = l.scheduleId
SET l.toTruckLanceCode = :newCode, l.version = l.version + 1
WHERE l.deleted = 0 AND s.deleted = 0
AND s.status NOT IN ('APPLIED', 'CANCELLED')
AND TRIM(l.toTruckLanceCode) = :oldCode
AND ${FLOOR_MATCH.replace("storeCol", "l.toStoreId")}
AND ${REMARK_MATCH_4F.replace("remarkCol", "l.toRemark")}
""".trimIndent()
}
}

+ 26
- 0
src/main/java/com/ffii/fpsms/modules/pickOrder/service/TruckLaneVersionService.kt Parādīt failu

@@ -16,6 +16,7 @@ open class TruckLaneVersionService(
private val truckLaneVersionRepository: TruckLaneVersionRepository,
private val truckLaneVersionLineRepository: TruckLaneVersionLineRepository,
private val logisticRepository: LogisticRepository,
private val truckLaneRenameService: TruckLaneRenameService,
) {
private fun toResponse(v: TruckLaneVersion): TruckLaneVersionResponse =
TruckLaneVersionResponse(
@@ -271,6 +272,7 @@ open class TruckLaneVersionService(
}
}

rewriteOpenSchedulesBackToSnapshot(version, lines)
restoreRowsFromLines(version, lines)

if (!skipPostSnapshot) {
@@ -316,6 +318,7 @@ open class TruckLaneVersionService(
return "No snapshot lines for affected lanes (versionId=$versionId)"
}

rewriteOpenSchedulesBackToSnapshot(version, scopedLines)
val fullSnapshotIds = allLines.mapNotNull { it.truckRowId }.filter { it > 0 }.toSet()
for (lane in codes) {
val currentLane = truckRepository.findAllByTruckLanceCodeAndDeletedFalse(lane)
@@ -340,6 +343,29 @@ open class TruckLaneVersionService(
return "Restored ${scopedLines.size} rows in ${codes.size} lane(s) from versionId=$versionId"
}

/**
* Open schedule from/to that still use the live name are pointed back at the snapshot name.
* Unfinished delivery tickets are left on the current name.
*/
private fun rewriteOpenSchedulesBackToSnapshot(
version: TruckLaneVersion,
lines: List<TruckLaneVersionLine>,
) {
val ids = lines.mapNotNull { it.truckRowId }.filter { it > 0 }.distinct()
if (ids.isEmpty()) return
val trucks = truckRepository.findAllById(ids).associateBy { it.id }
val seen = HashSet<String>()
for (line in lines) {
val truck = trucks[line.truckRowId] ?: continue
val before = truck.truckLanceCode?.trim().orEmpty()
val after = (line.truckLanceCode ?: version.truckLanceCode)?.trim().orEmpty()
if (before.isEmpty() || after.isEmpty() || before == after) continue
val key = "$before|$after|${truck.storeId}|${truck.remark}"
if (!seen.add(key)) continue
truckLaneRenameService.rewriteOpenScheduleNames(before, after, truck.storeId, truck.remark)
}
}

private fun restoreRowsFromLines(
version: TruckLaneVersion,
lines: List<TruckLaneVersionLine>,


+ 15
- 0
src/main/java/com/ffii/fpsms/modules/pickOrder/web/TruckController.kt Parādīt failu

@@ -18,8 +18,11 @@ import org.springframework.web.multipart.MultipartHttpServletRequest
import com.ffii.fpsms.modules.pickOrder.web.models.SaveTruckRequest
import com.ffii.fpsms.modules.pickOrder.web.models.CreateTruckWithoutShopRequest
import com.ffii.fpsms.modules.pickOrder.web.models.UpdateTruckShopDetailsRequest
import com.ffii.fpsms.modules.pickOrder.service.TruckLaneRenameService
import com.ffii.fpsms.modules.pickOrder.service.TruckService
import com.ffii.fpsms.modules.pickOrder.entity.TruckRepository
import com.ffii.fpsms.modules.pickOrder.web.models.PreviewTruckLaneRenameRequest
import com.ffii.fpsms.modules.pickOrder.web.models.RenameTruckLaneRequest
import com.ffii.fpsms.modules.pickOrder.web.models.SaveTruckLane
import com.ffii.fpsms.modules.pickOrder.web.models.TruckLaneCombinationResponse
import com.ffii.fpsms.modules.pickOrder.web.models.ExportRouteLanesRequest
@@ -37,6 +40,7 @@ import jakarta.validation.Valid
open class TruckController(
private val truckService: TruckService,
private val truckRepository: TruckRepository,
private val truckLaneRenameService: TruckLaneRenameService,
) {

@@ -469,4 +473,15 @@ open class TruckController(
}
}

@PostMapping("/previewTruckLaneRename")
open fun previewTruckLaneRename(@RequestBody req: PreviewTruckLaneRenameRequest) =
truckLaneRenameService.preview(req)

@PostMapping("/renameTruckLane")
open fun renameTruckLane(@RequestBody req: RenameTruckLaneRequest) =
truckLaneRenameService.rename(req)

@GetMapping("/truckLaneRenameLog")
open fun truckLaneRenameLog() = truckLaneRenameService.recentLogs()

}

+ 43
- 0
src/main/java/com/ffii/fpsms/modules/pickOrder/web/models/TruckLaneRenameModels.kt Parādīt failu

@@ -0,0 +1,43 @@
package com.ffii.fpsms.modules.pickOrder.web.models

data class PreviewTruckLaneRenameRequest(
val truckLanceCode: String = "",
val storeId: String = "2F",
val remark: String? = null,
)

data class PreviewTruckLaneRenameResponse(
val unfinishedCount: Int = 0,
val completedCount: Int = 0,
val handlerNames: List<String> = emptyList(),
val openScheduleCount: Int = 0,
)

data class RenameTruckLaneRequest(
val truckLanceCode: String = "",
val storeId: String = "2F",
val remark: String? = null,
@param:com.fasterxml.jackson.annotation.JsonProperty("newTruckLanceCode")
val replacementTruckLanceCode: String = "",
val departureTimeChanged: Boolean = false,
val newDepartureTime: String? = null,
)

data class RenameTruckLaneResponse(
val truckLanceCode: String = "",
val ticketCount: Int = 0,
val scheduleLineCount: Int = 0,
)

data class TruckLaneRenameLogResponse(
val id: Long = 0,
val created: String? = null,
val createdBy: String? = null,
val oldCode: String = "",
val newCode: String = "",
val storeId: String = "",
val remark: String? = null,
val oldDepartureTime: String? = null,
val newDepartureTime: String? = null,
val ticketCount: Int = 0,
)

+ 23
- 0
src/main/resources/db/changelog/changes/20261026_truck_lane_rename/01_create_truck_lane_rename_log.sql Parādīt failu

@@ -0,0 +1,23 @@
-- liquibase formatted sql
-- changeset fpsms:20261026_01_create_truck_lane_rename_log
-- preconditions onFail:MARK_RAN
-- precondition-sql-check expectedResult:0 SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = DATABASE() AND table_name = 'truck_lane_rename_log'

CREATE TABLE IF NOT EXISTS `truck_lane_rename_log`
(
`id` BIGINT NOT NULL AUTO_INCREMENT,
`created` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
`createdBy` VARCHAR(30) NULL DEFAULT NULL,
`version` INT NOT NULL DEFAULT '0',
`modified` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
`modifiedBy` VARCHAR(30) NULL DEFAULT NULL,
`deleted` TINYINT(1) NOT NULL DEFAULT '0',
`oldCode` VARCHAR(50) NOT NULL,
`newCode` VARCHAR(50) NOT NULL,
`storeId` VARCHAR(10) NOT NULL,
`remark` VARCHAR(255) NULL DEFAULT NULL,
`oldDepartureTime` VARCHAR(20) NULL DEFAULT NULL,
`newDepartureTime` VARCHAR(20) NULL DEFAULT NULL,
`ticketCount` INT NOT NULL DEFAULT '0',
CONSTRAINT pk_truck_lane_rename_log PRIMARY KEY (`id`)
);

Notiek ielāde…
Atcelt
Saglabāt