From f23cb15e27ef82dbb8206c96e6b11a17235b4adc Mon Sep 17 00:00:00 2001 From: "Tommy\\2Fi-Staff" Date: Fri, 9 Jan 2026 17:48:36 +0800 Subject: [PATCH] Add "add shop in trucklane"&"add trucklane" feature --- .../pickOrder/entity/TruckRepository.kt | 58 +++++++++++++- .../modules/pickOrder/service/TruckService.kt | 78 ++++++++++++++++++- .../modules/pickOrder/web/TruckController.kt | 68 ++++++++++++++-- .../pickOrder/web/models/SaveTruckRequest.kt | 16 +++- 4 files changed, 206 insertions(+), 14 deletions(-) diff --git a/src/main/java/com/ffii/fpsms/modules/pickOrder/entity/TruckRepository.kt b/src/main/java/com/ffii/fpsms/modules/pickOrder/entity/TruckRepository.kt index dd905bc..95942dc 100644 --- a/src/main/java/com/ffii/fpsms/modules/pickOrder/entity/TruckRepository.kt +++ b/src/main/java/com/ffii/fpsms/modules/pickOrder/entity/TruckRepository.kt @@ -30,6 +30,8 @@ interface TruckRepository : AbstractRepository { // 按 TruckLanceCode 查询 fun findByTruckLanceCode(truckLanceCode: String): Truck? + @Query("SELECT t FROM Truck t WHERE t.truckLanceCode = :truckLanceCode AND t.deleted = false") + fun findAllByTruckLanceCodeAndDeletedFalse(@Param("truckLanceCode") truckLanceCode: String): List fun findByShopNameAndStoreIdAndTruckLanceCode(shopName: String, storeId: String, truckLanceCode: String): Truck? fun findByShopCodeAndStoreId(shopCode: String, storeId: String): Truck? @@ -74,7 +76,7 @@ fun findByShopIdAndStoreIdAndDayOfWeek( @Query( nativeQuery = true, value = """ - SELECT s.id as id, t.ShopCode as code, s.name as name, s.contactNo as contactNo, + SELECT s.id as id, t.ShopCode as code, t.ShopName as name, s.contactNo as contactNo, s.contactEmail as contactEmail, s.contactName as contactName, s.addr1 as addr1, s.addr2 as addr2, s.addr3 as addr3, s.type as type, t.TruckLanceCode as truckLanceCode, t.DepartureTime as departureTime, @@ -87,4 +89,58 @@ fun findByShopIdAndStoreIdAndDayOfWeek( """ ) fun findAllFromShopAndTruckByTruckLanceCodeAndDeletedFalse(@Param("truckLanceCode") truckLanceCode: String): List + + @Query( + nativeQuery = true, + value = """ + SELECT DISTINCT t.ShopName as name, t.ShopCode as code + FROM truck t + WHERE t.deleted = false + AND t.ShopName IS NOT NULL + AND t.ShopCode IS NOT NULL + AND t.ShopName != '' + AND t.ShopCode != '' + ORDER BY t.ShopName, t.ShopCode + """ + ) + fun findAllUniqueShopNamesAndCodesFromTrucks(): List> + + @Query( + nativeQuery = true, + value = """ + SELECT DISTINCT t.remark as remark + FROM truck t + WHERE t.deleted = false + AND t.remark IS NOT NULL + AND t.remark != '' + ORDER BY t.remark + """ + ) + fun findAllUniqueRemarksFromTrucks(): List + + @Query( + nativeQuery = true, + value = """ + SELECT DISTINCT t.ShopCode as code + FROM truck t + WHERE t.deleted = false + AND t.ShopCode IS NOT NULL + AND t.ShopCode != '' + ORDER BY t.ShopCode + """ + ) + fun findAllUniqueShopCodesFromTrucks(): List + + @Query( + nativeQuery = true, + value = """ + SELECT DISTINCT t.ShopName as name + FROM truck t + WHERE t.deleted = false + AND t.ShopName IS NOT NULL + AND t.ShopName != '' + ORDER BY t.ShopName + """ + ) + fun findAllUniqueShopNamesFromTrucks(): List } \ No newline at end of file diff --git a/src/main/java/com/ffii/fpsms/modules/pickOrder/service/TruckService.kt b/src/main/java/com/ffii/fpsms/modules/pickOrder/service/TruckService.kt index efe1a08..e9a7b84 100644 --- a/src/main/java/com/ffii/fpsms/modules/pickOrder/service/TruckService.kt +++ b/src/main/java/com/ffii/fpsms/modules/pickOrder/service/TruckService.kt @@ -9,12 +9,13 @@ import org.springframework.stereotype.Service import com.ffii.fpsms.modules.pickOrder.entity.Truck import com.ffii.fpsms.modules.pickOrder.entity.TruckRepository 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 java.time.LocalTime import java.time.format.DateTimeFormatter import com.ffii.fpsms.modules.master.entity.ShopRepository import com.ffii.fpsms.modules.master.entity.projections.ShopAndTruck import com.ffii.fpsms.modules.pickOrder.web.models.SaveTruckLane -import com.ffii.fpsms.modules.pickOrder.web.models.UpdateLoadingSequenceRequest import jakarta.transaction.Transactional @@ -222,7 +223,7 @@ open class TruckService( } @Transactional - open fun createTruck(request: SaveTruckRequest): Truck { + open fun createTruckInShop(request: SaveTruckRequest): Truck { // Always create a new truck, ignore id if provided val truck = Truck() val shop = shopRepository.findById(request.shopId).orElse(null) @@ -254,13 +255,84 @@ open class TruckService( return truckRepository.findAllFromShopAndTruckByTruckLanceCodeAndDeletedFalse(truckLanceCode) } + open fun findAllByTruckLanceCodeAndDeletedFalse(truckLanceCode: String): List { + return truckRepository.findAllByTruckLanceCodeAndDeletedFalse(truckLanceCode) + } + + open fun findAllUniqueShopNamesAndCodesFromTrucks(): List> { + return truckRepository.findAllUniqueShopNamesAndCodesFromTrucks() + } + + open fun findAllUniqueRemarksFromTrucks(): List { + return truckRepository.findAllUniqueRemarksFromTrucks() + } + + open fun findAllUniqueShopCodesFromTrucks(): List { + return truckRepository.findAllUniqueShopCodesFromTrucks() + } + + open fun findAllUniqueShopNamesFromTrucks(): List { + return truckRepository.findAllUniqueShopNamesFromTrucks() + } + @Transactional - open fun updateLoadingSequence(request: UpdateLoadingSequenceRequest): Truck { + open fun updateTruckShopDetails(request: UpdateTruckShopDetailsRequest): Truck { val truck = truckRepository.findById(request.id).orElseThrow { IllegalArgumentException("Truck not found with id: ${request.id}") } + // Update shop relationship if shopId is provided + if (request.shopId != null) { + val shop = shopRepository.findById(request.shopId).orElse(null) + if (shop != null) { + truck.shop = shop + } else { + throw IllegalArgumentException("Shop not found with id: ${request.shopId}") + } + } + + // Always use shopName and shopCode from request (from truck table), not from shop entity + // This allows truck table to have different shop names/codes than shop table + if (request.shopName != null) { + truck.shopName = request.shopName + } + + if (request.shopCode != null) { + truck.shopCode = request.shopCode + } + + // Update loadingSequence truck.loadingSequence = request.loadingSequence + + // Update remark - only set if storeId is "4F", otherwise set to null + val storeIdStr = truck.storeId + if (storeIdStr == "4F") { + truck.remark = request.remark + } else { + truck.remark = null + } + + return truckRepository.save(truck) + } + + @Transactional + open fun createTruckWithoutShop(request: CreateTruckWithoutShopRequest): Truck { + // Create a new truck without a shop + val truck = Truck() + + truck.apply { + this.storeId = request.store_id + this.truckLanceCode = request.truckLanceCode + this.departureTime = request.departureTime + this.shop = null + this.shopName = "Unassign" + this.shopCode = "Unassign" + this.loadingSequence = request.loadingSequence + this.districtReference = request.districtReference + // Only set remark if store_id is "4F", otherwise set to null + this.remark = if (request.store_id == "4F") request.remark else null + } + return truckRepository.save(truck) } diff --git a/src/main/java/com/ffii/fpsms/modules/pickOrder/web/TruckController.kt b/src/main/java/com/ffii/fpsms/modules/pickOrder/web/TruckController.kt index e68700e..65e0694 100644 --- a/src/main/java/com/ffii/fpsms/modules/pickOrder/web/TruckController.kt +++ b/src/main/java/com/ffii/fpsms/modules/pickOrder/web/TruckController.kt @@ -12,11 +12,12 @@ import org.springframework.web.bind.annotation.* 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.TruckService import com.ffii.fpsms.modules.pickOrder.entity.TruckRepository import com.ffii.fpsms.modules.pickOrder.web.models.SaveTruckLane import com.ffii.fpsms.modules.pickOrder.web.models.deleteTruckLane -import com.ffii.fpsms.modules.pickOrder.web.models.UpdateLoadingSequenceRequest import jakarta.validation.Valid @RestController @@ -53,10 +54,10 @@ class TruckController( } } - @PostMapping("/create") - fun createTruck(@Valid @RequestBody request: SaveTruckRequest): MessageResponse { + @PostMapping("/createTruckInShop") + fun createTruckInShop(@Valid @RequestBody request: SaveTruckRequest): MessageResponse { try { - val truck = truckService.createTruck(request) + val truck = truckService.createTruckInShop(request) return MessageResponse( id = truck.id, name = truck.shopName, @@ -187,16 +188,67 @@ class TruckController( return truckService.findAllFromShopAndTruckByTruckLanceCodeAndDeletedFalse(truckLanceCode) } - @PostMapping("/updateLoadingSequence") - fun updateLoadingSequence(@Valid @RequestBody request: UpdateLoadingSequenceRequest): MessageResponse { + @GetMapping("/findAllByTruckLanceCodeAndDeletedFalse") + fun findAllByTruckLanceCodeAndDeletedFalse(@RequestParam truckLanceCode: String): List { + return truckService.findAllByTruckLanceCodeAndDeletedFalse(truckLanceCode) + } + + @GetMapping("/findAllUniqueShopNamesAndCodesFromTrucks") + fun findAllUniqueShopNamesAndCodesFromTrucks(): List> { + return truckService.findAllUniqueShopNamesAndCodesFromTrucks() + } + + @GetMapping("/findAllUniqueRemarksFromTrucks") + fun findAllUniqueRemarksFromTrucks(): List { + return truckService.findAllUniqueRemarksFromTrucks() + } + + @GetMapping("/findAllUniqueShopCodesFromTrucks") + fun findAllUniqueShopCodesFromTrucks(): List { + return truckService.findAllUniqueShopCodesFromTrucks() + } + + @GetMapping("/findAllUniqueShopNamesFromTrucks") + fun findAllUniqueShopNamesFromTrucks(): List { + return truckService.findAllUniqueShopNamesFromTrucks() + } + + @PostMapping("/updateTruckShopDetails") + fun updateTruckShopDetails(@Valid @RequestBody request: UpdateTruckShopDetailsRequest): MessageResponse { try { - val truck = truckService.updateLoadingSequence(request) + val truck = truckService.updateTruckShopDetails(request) return MessageResponse( id = truck.id, name = truck.shopName, code = truck.truckLanceCode, type = "truck", - message = "Loading sequence updated successfully", + message = "Truck shop details updated successfully", + errorPosition = null, + entity = truck + ) + } catch (e: Exception) { + return MessageResponse( + id = null, + name = null, + code = null, + type = "truck", + message = "Error: ${e.message}", + errorPosition = null, + entity = null + ) + } + } + + @PostMapping("/createTruckWithoutShop") + fun createTruckWithoutShop(@Valid @RequestBody request: CreateTruckWithoutShopRequest): MessageResponse { + try { + val truck = truckService.createTruckWithoutShop(request) + return MessageResponse( + id = truck.id, + name = truck.shopName, + code = truck.truckLanceCode, + type = "truck", + message = "Truck created successfully", errorPosition = null, entity = truck ) diff --git a/src/main/java/com/ffii/fpsms/modules/pickOrder/web/models/SaveTruckRequest.kt b/src/main/java/com/ffii/fpsms/modules/pickOrder/web/models/SaveTruckRequest.kt index c0f8a6b..708b4b3 100644 --- a/src/main/java/com/ffii/fpsms/modules/pickOrder/web/models/SaveTruckRequest.kt +++ b/src/main/java/com/ffii/fpsms/modules/pickOrder/web/models/SaveTruckRequest.kt @@ -24,7 +24,19 @@ data class SaveTruckLane( data class deleteTruckLane( val id: Long ) -data class UpdateLoadingSequenceRequest( +data class UpdateTruckShopDetailsRequest( val id: Long, - val loadingSequence: Int + val shopId: Long? = null, + val shopName: String?, + val shopCode: String?, + val loadingSequence: Int, + val remark: String? = null, +) +data class CreateTruckWithoutShopRequest( + val store_id: String, + val truckLanceCode: String, + val departureTime: LocalTime, + val loadingSequence: Int = 0, + val districtReference: Int? = null, + val remark: String? = null, )