diff --git a/src/main/java/com/ffii/fpsms/modules/master/entity/ShopAndTruck.kt b/src/main/java/com/ffii/fpsms/modules/master/entity/ShopAndTruck.kt new file mode 100644 index 0000000..a559a86 --- /dev/null +++ b/src/main/java/com/ffii/fpsms/modules/master/entity/ShopAndTruck.kt @@ -0,0 +1,51 @@ +package com.ffii.fpsms.modules.master.entity + +import com.ffii.core.entity.BaseEntity +import com.ffii.fpsms.modules.master.enums.ShopType +import com.ffii.fpsms.modules.master.enums.ShopTypeConverter +import jakarta.persistence.Column +import jakarta.persistence.Entity +import jakarta.persistence.PrimaryKeyJoinColumn +import jakarta.persistence.SecondaryTable +import jakarta.persistence.Table +import jakarta.validation.constraints.Size +import jakarta.validation.constraints.NotNull +import jakarta.persistence.Convert +import java.time.LocalTime + +@Entity +@Table(name = "shop") +@SecondaryTable(name="Truck", pkJoinColumns = [PrimaryKeyJoinColumn(name = "shopId", referencedColumnName = "id")]) +open class ShopAndTruck : BaseEntity() { + + // --- Shop fields --- + @Size(max = 300) + @NotNull + @Column(name = "name", nullable = false, length = 300) + open var name: String? = null + + @Size(max = 50) + @NotNull + @Column(name = "code", nullable = false, length = 50) + open var code: String? = null + + @Convert(converter = ShopTypeConverter::class) + @Column(name = "type", length = 10) + open var type: ShopType? = null + + // --- Truck fields (secondary table) --- + @Column(table = "truck", name = "TruckLanceCode", length = 50) + open var truckLanceCode: String? = null + + @Column(table = "truck", name = "departureTime") + open var departureTime: LocalTime? = null + + @Column(table = "truck", name = "LoadingSequence") + open var loadingSequence: Long? = null + + @Column(table = "truck", name = "districtReference") + open var districtReference: Long? = null + + @Column(table = "truck", name = "Store_id") + open var storeId: Long? = null +} diff --git a/src/main/java/com/ffii/fpsms/modules/master/entity/ShopRepository.kt b/src/main/java/com/ffii/fpsms/modules/master/entity/ShopRepository.kt index 8647f2d..8f49f01 100644 --- a/src/main/java/com/ffii/fpsms/modules/master/entity/ShopRepository.kt +++ b/src/main/java/com/ffii/fpsms/modules/master/entity/ShopRepository.kt @@ -1,8 +1,10 @@ package com.ffii.fpsms.modules.master.entity +import com.ffii.fpsms.modules.master.entity.projections.ShopAndTruck import com.ffii.core.support.AbstractRepository import com.ffii.fpsms.modules.master.entity.projections.ShopCombo import com.ffii.fpsms.modules.master.enums.ShopType +import com.ffii.fpsms.modules.pickOrder.entity.Truck import org.springframework.data.jpa.repository.Query import org.springframework.stereotype.Repository @@ -27,4 +29,16 @@ interface ShopRepository : AbstractRepository { fun findShopComboByTypeAndDeletedIsFalse(type: ShopType): List fun findByCode(code: String): Shop? -} \ No newline at end of file + + @Query( + nativeQuery = true, + value = """ + SELECT s.id, s.code, s.name, s.contactNo, s.contactEmail, s.contactName, s.addr1, s.addr2, s.addr3, s.type, t.TruckLanceCode, t.LoadingSequence, t.districtReference,t.Store_id + FROM shop s LEFT JOIN truck t ON s.id = t.shopId + WHERE s.type = 'shop' + AND s.deleted = false; + """ + ) + fun findAllByTypeAndDeletedIsFalse(): List? + +} diff --git a/src/main/java/com/ffii/fpsms/modules/master/entity/projections/ShopAndTruck.kt b/src/main/java/com/ffii/fpsms/modules/master/entity/projections/ShopAndTruck.kt new file mode 100644 index 0000000..6543caf --- /dev/null +++ b/src/main/java/com/ffii/fpsms/modules/master/entity/projections/ShopAndTruck.kt @@ -0,0 +1,21 @@ +package com.ffii.fpsms.modules.master.entity.projections + +import java.time.LocalTime + +interface ShopAndTruck { + val id: Long + val name: String? + val code: String? + val contactNo: String? + val contactEmail: String? + val contactName: String? + val addr1: String? + val addr2: String? + val addr3: String? + val type: String? + val truckLanceCode: String? + val departureTime: LocalTime? + val LoadingSequence: Long? + val districtReference: Long? + val Store_id: Long? +} diff --git a/src/main/java/com/ffii/fpsms/modules/master/service/ShopService.kt b/src/main/java/com/ffii/fpsms/modules/master/service/ShopService.kt index fd3d1aa..d430d4b 100644 --- a/src/main/java/com/ffii/fpsms/modules/master/service/ShopService.kt +++ b/src/main/java/com/ffii/fpsms/modules/master/service/ShopService.kt @@ -2,6 +2,7 @@ package com.ffii.fpsms.modules.master.service import com.ffii.fpsms.modules.master.entity.Shop import com.ffii.fpsms.modules.master.entity.ShopRepository +import com.ffii.fpsms.modules.master.entity.projections.ShopAndTruck import com.ffii.fpsms.modules.master.entity.projections.ShopCombo import com.ffii.fpsms.modules.master.enums.ShopType import com.ffii.fpsms.modules.master.web.models.SaveShopRequest @@ -47,6 +48,9 @@ open class ShopService( return shopRepository.findShopComboByTypeAndDeletedIsFalse(ShopType.SHOP) } + open fun findAllByTypeAndDeletedIsFalse(): List?{ + return shopRepository.findAllByTypeAndDeletedIsFalse() + } open fun saveShop(request: SaveShopRequest): SaveShopResponse { val shop = if (request.m18Id != null) { when (request.type){ diff --git a/src/main/java/com/ffii/fpsms/modules/master/web/ShopController.kt b/src/main/java/com/ffii/fpsms/modules/master/web/ShopController.kt index 7532eb1..8cee075 100644 --- a/src/main/java/com/ffii/fpsms/modules/master/web/ShopController.kt +++ b/src/main/java/com/ffii/fpsms/modules/master/web/ShopController.kt @@ -1,7 +1,13 @@ package com.ffii.fpsms.modules.master.web +import com.ffii.fpsms.modules.master.entity.ShopRepository +import com.ffii.fpsms.modules.master.entity.Shop +import com.ffii.fpsms.modules.master.entity.projections.ShopAndTruck + import com.ffii.fpsms.modules.master.entity.projections.ShopCombo +import com.ffii.fpsms.modules.master.enums.ShopType import com.ffii.fpsms.modules.master.service.ShopService +import com.ffii.fpsms.modules.pickOrder.entity.Truck import org.springframework.web.bind.annotation.GetMapping import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.RestController @@ -20,4 +26,11 @@ class ShopController ( fun getSupplierCombo(): List { return shopService.findSupplierCombo(); } + + + @GetMapping("/combo/allShop") + fun test3(): List? { + return shopService.findAllByTypeAndDeletedIsFalse(); + } + } \ No newline at end of file diff --git a/src/main/java/com/ffii/fpsms/modules/master/web/models/SaveShopRequest.kt b/src/main/java/com/ffii/fpsms/modules/master/web/models/SaveShopRequest.kt index ce8cb7c..9b64d4f 100644 --- a/src/main/java/com/ffii/fpsms/modules/master/web/models/SaveShopRequest.kt +++ b/src/main/java/com/ffii/fpsms/modules/master/web/models/SaveShopRequest.kt @@ -18,4 +18,4 @@ data class SaveShopRequest ( val type: String?, val m18Id: Long?, val m18LastModifyDate: LocalDateTime?, -) \ No newline at end of file +) diff --git a/src/main/java/com/ffii/fpsms/modules/pickOrder/entity/Truck.kt b/src/main/java/com/ffii/fpsms/modules/pickOrder/entity/Truck.kt index d303941..90c7e59 100644 --- a/src/main/java/com/ffii/fpsms/modules/pickOrder/entity/Truck.kt +++ b/src/main/java/com/ffii/fpsms/modules/pickOrder/entity/Truck.kt @@ -34,4 +34,8 @@ open class Truck : BaseEntity() { @Column(name = "Store_id") open var storeId: Int? = null + + @Column(name = "districtReference") + open var districtReference: Int? = null + } \ No newline at end of file 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 b212b47..1d92351 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 @@ -4,6 +4,9 @@ import com.ffii.core.support.AbstractRepository import org.springframework.data.jpa.repository.Query import org.springframework.data.repository.query.Param import org.springframework.stereotype.Repository +import java.time.LocalTime +import java.util.Optional + @Repository interface TruckRepository : AbstractRepository { @@ -29,4 +32,9 @@ interface TruckRepository : AbstractRepository { fun findByTruckLanceCode(truckLanceCode: String): Truck? fun findByShopNameAndStoreIdAndTruckLanceCode(shopName: String, storeId: Int, truckLanceCode: String): Truck? fun findByShopCodeAndStoreId(shopCode: String, storeId: Int): Truck? + + + fun findAllByShopId(shopId :Long):List + //fun findByTruckLanceCode(truckLanceCode: String):List + //fun deleteByTruckLanceCodeAndDepartureTimeAndLoadingSequenceAndDistrictReferenceAndStoreId(truckLanceCode: String, departureTime: LocalTime, loadingSequence: Long, districtReference: Long, storeId: Long): String } \ 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 dd1ac4b..2a30fba 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 @@ -3,33 +3,19 @@ package com.ffii.fpsms.modules.pickOrder.service import com.ffii.core.support.AbstractBaseEntityService import com.ffii.core.support.JdbcDao import com.ffii.core.utils.ExcelUtils -import com.ffii.core.utils.JwtTokenUtil -import com.ffii.fpsms.modules.master.entity.ItemsRepository -import com.ffii.fpsms.modules.master.entity.Warehouse -import com.ffii.fpsms.modules.master.entity.WarehouseRepository -import com.ffii.fpsms.modules.master.entity.projections.WarehouseCombo -import com.ffii.fpsms.modules.master.web.models.SaveWarehouseRequest -import com.ffii.fpsms.modules.master.web.models.NewWarehouseRequest -import com.ffii.fpsms.modules.purchaseOrder.entity.PurchaseOrderLineRepository -import com.ffii.fpsms.modules.stock.entity.InventoryLotRepository -import com.ffii.fpsms.modules.stock.entity.StockInLine -import com.ffii.fpsms.modules.stock.entity.StockInLineRepository -import com.ffii.fpsms.modules.stock.entity.StockInRepository -import com.ffii.fpsms.modules.stock.service.InventoryLotService -import com.ffii.fpsms.modules.stock.service.StockInService import org.apache.poi.ss.usermodel.Sheet import org.apache.poi.ss.usermodel.Workbook -import org.slf4j.Logger -import org.slf4j.LoggerFactory import org.springframework.stereotype.Service -import java.math.BigDecimal -import kotlin.jvm.optionals.getOrNull 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 java.time.LocalTime import java.time.format.DateTimeFormatter import com.ffii.fpsms.modules.master.entity.ShopRepository +import com.ffii.fpsms.modules.pickOrder.web.models.SaveTruckLane +import jakarta.transaction.Transactional + + @Service open class TruckService( private val jdbcDao: JdbcDao, @@ -37,8 +23,8 @@ open class TruckService( private val shopRepository: ShopRepository, ) : AbstractBaseEntityService(jdbcDao, truckRepository) { open fun saveTruck(request: SaveTruckRequest): Truck { - val truck = request.id?.let { - truckRepository.findById(it).orElse(null) + val truck = request.id?.let { + truckRepository.findById(it).orElse(null) } ?: Truck() val shop = shopRepository.findById(request.shopId).orElse(null) if (shop == null) { @@ -91,22 +77,24 @@ open class TruckService( null } } + private fun normalizeShopCode(shopCode: String): String { val firstDigitIndex = shopCode.indexOfFirst { it.isDigit() } if (firstDigitIndex == -1) { - return shopCode + return shopCode } - + val letterPart = shopCode.substring(0, firstDigitIndex) val numberPart = shopCode.substring(firstDigitIndex) - + val normalizedNumber = if (numberPart.startsWith("0") && numberPart.length > 1) { - numberPart.substring(1) + numberPart.substring(1) } else { - numberPart + numberPart } return letterPart + normalizedNumber } + open fun importExcel(workbook: Workbook?): String { logger.info("--------- Start - Import Warehouse Excel -------"); @@ -160,14 +148,14 @@ open class TruckService( //println("shop: ${shop}") val existingTruck = truckRepository.findByShopCodeAndStoreId(shopCode, storeIdInt) if (existingTruck != null) { - + val truckRequest = SaveTruckRequest( id = existingTruck.id, - store_id = storeIdInt, + store_id = storeIdInt, truckLanceCode = truckLanceCode ?: existingTruck.truckLanceCode ?: "", departureTime = departureTime, shopId = shop?.id!!, - shopName = shopName?: "", + shopName = shopName ?: "", shopCode = normalizedShopCode, loadingSequence = loadingSequence ) @@ -176,11 +164,11 @@ open class TruckService( // 创建新记录 val truckRequest = SaveTruckRequest( id = null, - store_id = storeIdInt, + store_id = storeIdInt, truckLanceCode = truckLanceCode ?: "", departureTime = departureTime, shopId = shop?.id!!, - shopName = shopName?: "", + shopName = shopName ?: "", shopCode = normalizedShopCode, loadingSequence = loadingSequence ) @@ -195,4 +183,55 @@ open class TruckService( return "Import Excel success"; } + open fun findAllByShopId(shopId: Long): List { + return truckRepository.findAllByShopId(shopId) + } + + @Transactional + open fun updateTruckLaneByTruckLanceCode(request: SaveTruckLane): List { + + val updateTruckLance = truckRepository.findById(request.id).orElseThrow() + ?: throw IllegalArgumentException("Truck not found with truckLanceCode: $request.truckLanceCode") + //println(updateTruckLance,"before") + updateTruckLance.truckLanceCode = request.truckLanceCode + updateTruckLance.loadingSequence = request.loadingSequence.toInt() + updateTruckLance.districtReference = request.districtReference.toInt() + updateTruckLance.departureTime = request.departureTime + updateTruckLance.storeId = request.storeId.toInt() + + val savedTruck = truckRepository.save(updateTruckLance) + //print(updateTruckLance,"after") + return listOf(savedTruck) + } + + + @Transactional + open fun deleteById(id: Long): String { + truckRepository.deleteById(id) + return "Truck deleted successfully with id: $id" + } + + @Transactional + open fun createTruck(request: SaveTruckRequest): Truck { + // Always create a new truck, ignore id if provided + val truck = Truck() + val shop = shopRepository.findById(request.shopId).orElse(null) + if (shop == null) { + throw IllegalArgumentException("Shop not found with id: ${request.shopId}") + } + + truck.apply { + this.storeId = request.store_id + this.truckLanceCode = request.truckLanceCode + this.departureTime = request.departureTime + this.shop = shop + this.shopName = request.shopName + this.shopCode = request.shopCode + this.loadingSequence = request.loadingSequence + this.districtReference = request.districtReference + } + + return truckRepository.save(truck) + } + } \ No newline at end of file diff --git a/src/main/java/com/ffii/fpsms/modules/pickOrder/web/SaveTruckRequest.kt b/src/main/java/com/ffii/fpsms/modules/pickOrder/web/SaveTruckRequest.kt new file mode 100644 index 0000000..05cd589 --- /dev/null +++ b/src/main/java/com/ffii/fpsms/modules/pickOrder/web/SaveTruckRequest.kt @@ -0,0 +1,24 @@ +package com.ffii.fpsms.modules.pickOrder.web.models +import java.time.LocalTime +data class SaveTruckRequest( + val id: Long? = null, + val store_id: Int, + val truckLanceCode: String, + val departureTime: LocalTime, + val shopId: Long, + val shopName: String, + val shopCode: String, + val loadingSequence: Int, + val districtReference: Int? = null, +) +data class SaveTruckLane( + val id: Long, + val truckLanceCode: String, + val departureTime: LocalTime, + val loadingSequence: Long, + val districtReference: Long, + val storeId: Int +) +data class deleteTruckLane( + val id: Long +) 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 2433cc7..ab413d4 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 @@ -1,6 +1,7 @@ package com.ffii.fpsms.modules.pickOrder.web import com.ffii.fpsms.modules.master.web.models.MessageResponse +import com.ffii.fpsms.modules.pickOrder.entity.Truck import org.springframework.web.bind.ServletRequestBindingException import jakarta.servlet.http.HttpServletRequest import org.apache.poi.ss.usermodel.Workbook @@ -12,6 +13,9 @@ import org.springframework.web.multipart.MultipartHttpServletRequest import com.ffii.fpsms.modules.pickOrder.web.models.SaveTruckRequest 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 jakarta.validation.Valid @RestController @RequestMapping("/truck") @@ -45,6 +49,33 @@ class TruckController( ) } } + + @PostMapping("/create") + fun createTruck(@Valid @RequestBody request: SaveTruckRequest): MessageResponse { + try { + val truck = truckService.createTruck(request) + return MessageResponse( + id = truck.id, + name = truck.shopName, + code = truck.truckLanceCode, + type = "truck", + message = "Truck created 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("/importExcel") @Throws(ServletRequestBindingException::class) fun importExcel(request: HttpServletRequest): ResponseEntity<*> { @@ -82,4 +113,63 @@ class TruckController( ) } -} \ No newline at end of file + @GetMapping("/findTruckLane/{shopId}") + fun findAllByShopId(@PathVariable shopId: Long): List { + return truckService.findAllByShopId(shopId); + } + + @PostMapping("/updateTruckLane") + fun updateTruckLane(@Valid @RequestBody request: SaveTruckLane): MessageResponse { + try { + val trucks = truckService.updateTruckLaneByTruckLanceCode( + request + ) + val truck = trucks.firstOrNull() + return MessageResponse( + id = truck?.id, + name = truck?.shopName, + code = truck?.truckLanceCode, + type = "truck", + message = if (truck != null) "Truck lane updated successfully" else "Truck lane not found", + 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("/deleteTruckLane") + fun deleteTruckLane(@Valid @RequestBody request: deleteTruckLane): MessageResponse { + try { + val result = truckService.deleteById(request.id) + return MessageResponse( + id = request.id, + name = null, + code = null, + type = "truck", + message = result, + errorPosition = null, + entity = null + ) + } catch (e: Exception) { + return MessageResponse( + id = null, + name = null, + code = null, + type = "truck", + message = "Error: ${e.message}", + errorPosition = null, + entity = null + ) + } + } +} 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 a2f8aa2..05cd589 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 @@ -9,4 +9,16 @@ data class SaveTruckRequest( val shopName: String, val shopCode: String, val loadingSequence: Int, + val districtReference: Int? = null, +) +data class SaveTruckLane( + val id: Long, + val truckLanceCode: String, + val departureTime: LocalTime, + val loadingSequence: Long, + val districtReference: Long, + val storeId: Int +) +data class deleteTruckLane( + val id: Long )