From 7fe4fd11bf3e49cf60ad908a50ffe51056f4955b Mon Sep 17 00:00:00 2001 From: "MSI\\derek" Date: Thu, 26 Jun 2025 18:36:36 +0800 Subject: [PATCH] update --- .../service/ProductionScheduleService.kt | 1 + .../pickOrder/service/PickOrderService.kt | 71 ++++++++++++++++--- .../pickOrder/web/PickOrderController.kt | 38 +++++++++- .../entity/projection/InventoryLotLineInfo.kt | 1 + .../stock/service/SuggestedPickLotService.kt | 2 +- .../stock/web/InventoryLotLineController.kt | 22 +++++- .../modules/stock/web/model/LotLineInfo.kt | 10 +++ .../modules/user/web/UserController.java | 16 +++++ 8 files changed, 148 insertions(+), 13 deletions(-) create mode 100644 src/main/java/com/ffii/fpsms/modules/stock/web/model/LotLineInfo.kt diff --git a/src/main/java/com/ffii/fpsms/modules/master/service/ProductionScheduleService.kt b/src/main/java/com/ffii/fpsms/modules/master/service/ProductionScheduleService.kt index 65b533a..59602a4 100644 --- a/src/main/java/com/ffii/fpsms/modules/master/service/ProductionScheduleService.kt +++ b/src/main/java/com/ffii/fpsms/modules/master/service/ProductionScheduleService.kt @@ -207,6 +207,7 @@ open class ProductionScheduleService( val resultList = jdbcDao.queryForList(sql.toString(), args, ); + //TODO: From Global config val DARK_MAX_VALUE = 1; val FLOAT_MAX_VALUE = 5; val DENSE_MAX_VALUE = 5; diff --git a/src/main/java/com/ffii/fpsms/modules/pickOrder/service/PickOrderService.kt b/src/main/java/com/ffii/fpsms/modules/pickOrder/service/PickOrderService.kt index dbd5d1c..acf7ebd 100644 --- a/src/main/java/com/ffii/fpsms/modules/pickOrder/service/PickOrderService.kt +++ b/src/main/java/com/ffii/fpsms/modules/pickOrder/service/PickOrderService.kt @@ -1,6 +1,7 @@ package com.ffii.fpsms.modules.pickOrder.service import com.ffii.core.response.RecordsRes +import com.ffii.core.support.JdbcDao import com.ffii.fpsms.modules.common.SecurityUtils import com.ffii.fpsms.modules.pickOrder.entity.PickOrderRepository import com.ffii.fpsms.modules.pickOrder.entity.projection.PickOrderInfo @@ -12,8 +13,11 @@ import com.ffii.fpsms.modules.stock.service.InventoryService import com.ffii.fpsms.modules.stock.service.StockOutLineService import com.ffii.fpsms.modules.stock.service.SuggestedPickLotService import com.ffii.fpsms.modules.stock.web.model.SuggestedPickLotForPoRequest +import com.ffii.fpsms.modules.user.entity.UserRepository import com.ffii.fpsms.modules.user.service.UserService import org.springframework.data.domain.PageRequest +import org.springframework.http.HttpStatus +import org.springframework.http.ResponseEntity import org.springframework.stereotype.Service import org.springframework.transaction.annotation.Transactional import java.io.Serializable @@ -25,10 +29,12 @@ import kotlin.jvm.optionals.getOrNull @Service open class PickOrderService( + private val jdbcDao: JdbcDao, val pickOrderRepository: PickOrderRepository, val stockOutLineService: StockOutLineService, val suggestedPickLotService: SuggestedPickLotService, - val userService: UserService, private val inventoryLotLineRepository: InventoryLotLineRepository, + val userService: UserService, + private val inventoryLotLineRepository: InventoryLotLineRepository, val inventoryService: InventoryService, ) { open fun localDateTimeParse(dateTime: String?, pattern: String? = "YYYY-MM-DD hh:mm:ss"): LocalDateTime? { @@ -62,6 +68,25 @@ open class PickOrderService( return RecordsRes(records, total.toInt()) } + open fun getConsoPickOrderList(args: MutableMap): List> { + val sql = StringBuilder( "select" + + " po.consoCode, " + + " po.releasedDate, " + + " po.status, " + + " po.assignTo " + + " from pick_order po " + + " where po.deleted = false " + + " and po.consoCode is not null " + ) + if (args.containsKey("consoCode")){ + sql.append(" AND po.consoCode like :consoCode "); + } + if (args.containsKey("status")){ + sql.append(" AND po.status = :status "); + } + sql.append(" group by po.consoCode, po.releasedDate, po.status, po.assignTo ") + return jdbcDao.queryForList(sql.toString(), args); + } // Consolidating Pick Orders open fun assignConsoCode(): String { val suffixFormat = "%03d" @@ -91,12 +116,14 @@ open class PickOrderService( it.consoCode = newConsoCode it.status = PickOrderStatus.CONSOLIDATED } + println(newConsoCode) + println(pickOrders) - val updatedPickOrders = pickOrderRepository.saveAll(pickOrders) - val updatedPickOrderInfos = updatedPickOrders.map { po -> po.id as Serializable } + val savedPickOrders = pickOrderRepository.saveAll(pickOrders) + val savedPickOrderInfos = savedPickOrders.map { po -> po.id as Serializable } .let { pickOrderRepository.findPickOrderInfoByIdIn(it) } - return updatedPickOrderInfos + return savedPickOrderInfos } open fun deconsoPickOrders(request: ConsoPickOrderRequest): List { @@ -113,6 +140,32 @@ open class PickOrderService( return updatedPickOrderInfos } + open fun getPickOrderLine(args: MutableMap): List> { + if (!args.containsKey("consoCode") || args["consoCode"] == null) { + throw IllegalArgumentException("consoCode must not be null") + } + val sql = StringBuilder("select" + + " pol.id, " + + " i.name as itemName, " + + " pol.qty as qty, " + + " max(uc.code) as uom, " + + " group_concat(w.name) as warehouse, " + + " group_concat(il.lotNo) as suggestedLotNo " + + " from pick_order po " + + " left join pick_order_line pol on pol.poId = po.id " + + " left join items i on i.id = pol.itemId " + + " left join suggested_pick_lot spl on spl.pickOrderLineId = pol.id " + + " left join inventory_lot_line ill on ill.id = spl.suggestedLotLineId " + + " left join warehouse w on w.id = ill.warehouseId " + + " left join inventory_lot il on il.id = ill.inventoryLotId " + + " left join uom_conversion uc on uc.id = pol.uomId " + + " where po.deleted = false " + + " and po.consoCode = :consoCode " + + " group by pol.id, i.name, pol.qty " + ) + return jdbcDao.queryForList(sql.toString(), args); + } + // TODO: Add actual pick lots open fun consoPickOrderDetail(consoCode: String): ConsoPickOrderResponse { val zero = BigDecimal.ZERO @@ -128,7 +181,6 @@ open class PickOrderService( // Mapping: PickOrder -> PickOrderInConso val finalPos = pos.map { po -> val pols = po.pickOrderLines - // Suggestions for Pick Order Line // val suggestions = suggestedPickLotService.suggestionForPickOrderLines(pols) @@ -253,7 +305,7 @@ open class PickOrderService( open fun releaseConsoPickOrderInfo(consoCode: String): ReleasePickOrderInfoResponse { val zero = BigDecimal.ZERO val pos = pickOrderRepository.findAllByConsoCodeAndStatus(consoCode, PickOrderStatus.CONSOLIDATED) - + println(pos) // Get Inventory Data val requiredItems = pos .flatMap { it.pickOrderLines } @@ -263,8 +315,10 @@ open class PickOrderService( override val id: Long? = value[0].item?.id override val code: String? = value[0].item?.code override val name: String? = value[0].item?.name + override val uomDesc: String? = value[0].uom?.udfudesc override var availableQty: BigDecimal? = zero override val requiredQty: BigDecimal = value.sumOf { it.qty ?: zero } + } } // itemId - requiredQty @@ -322,15 +376,15 @@ open class PickOrderService( } @Transactional(rollbackFor = [java.lang.Exception::class]) - open fun releaseConsoPickOrderAction(request: ReleaseConsoPickOrderRequest) { + open fun releaseConsoPickOrderAction(request: ReleaseConsoPickOrderRequest): ResponseEntity { val releasedBy = SecurityUtils.getUser().getOrNull() val assignTo = request.assignTo?.let { userService.find(it) }?.getOrNull() val pos = pickOrderRepository.findAllByConsoCodeAndStatus(request.consoCode, PickOrderStatus.CONSOLIDATED) pos.forEach { it.apply { this.releasedBy = releasedBy - this.assignTo = assignTo status = PickOrderStatus.RELEASED + this.assignTo = assignTo } } @@ -339,5 +393,6 @@ open class PickOrderService( suggestedPickLotService.saveAll(suggestions.suggestedList) pickOrderRepository.saveAll(pos) + return ResponseEntity("success", HttpStatus.OK) } } \ No newline at end of file diff --git a/src/main/java/com/ffii/fpsms/modules/pickOrder/web/PickOrderController.kt b/src/main/java/com/ffii/fpsms/modules/pickOrder/web/PickOrderController.kt index 901cdb2..85ea941 100644 --- a/src/main/java/com/ffii/fpsms/modules/pickOrder/web/PickOrderController.kt +++ b/src/main/java/com/ffii/fpsms/modules/pickOrder/web/PickOrderController.kt @@ -1,14 +1,22 @@ package com.ffii.fpsms.modules.pickOrder.web import com.ffii.core.response.RecordsRes +import com.ffii.core.utils.CriteriaArgsBuilder +import com.ffii.core.utils.PagingUtils import com.ffii.fpsms.modules.pickOrder.entity.PickOrderRepository import com.ffii.fpsms.modules.pickOrder.entity.projection.PickOrderInfo import com.ffii.fpsms.modules.pickOrder.service.PickOrderService import com.ffii.fpsms.modules.pickOrder.web.models.* +import com.ffii.fpsms.modules.pickOrder.web.models.ConsoPickOrderRequest +import com.ffii.fpsms.modules.pickOrder.web.models.ConsoPickOrderResponse +import com.ffii.fpsms.modules.pickOrder.web.models.ReleaseConsoPickOrderRequest +import com.ffii.fpsms.modules.pickOrder.web.models.SearchPickOrderRequest +import jakarta.servlet.http.HttpServletRequest import jakarta.validation.Valid import org.springframework.data.domain.Page import org.springframework.data.domain.PageRequest import org.springframework.data.domain.Pageable +import org.springframework.http.ResponseEntity import org.springframework.web.bind.annotation.GetMapping import org.springframework.web.bind.annotation.ModelAttribute import org.springframework.web.bind.annotation.PathVariable @@ -36,6 +44,30 @@ class PickOrderController( fun allPickOrdersByPage(@ModelAttribute request: SearchPickOrderRequest): RecordsRes { return pickOrderService.allPickOrdersByPage(request); } + @GetMapping("/getRecordByPage-conso") + fun allConsoPickOrdersByPage(request: HttpServletRequest): RecordsRes> { + val criteriaArgs = CriteriaArgsBuilder.withRequest(request) + .addStringLike("consoCode") + .addString("status") + .build() + val pageSize = request.getParameter("pageSize")?.toIntOrNull() ?: 10 // Default to 10 if not provided + val pageNum = request.getParameter("pageNum")?.toIntOrNull() ?: 1 // Default to 1 if not provided + val fullList = pickOrderService.getConsoPickOrderList(criteriaArgs) + val paginatedList = PagingUtils.getPaginatedList(fullList,pageSize, pageNum) + return RecordsRes(paginatedList, fullList.size) + } + + @GetMapping("/get-pickorder-line-byPage") + fun getPickOrderLine(request: HttpServletRequest): RecordsRes> { + val criteriaArgs = CriteriaArgsBuilder.withRequest(request) + .addString("consoCode") + .build() + val pageSize = request.getParameter("pageSize")?.toIntOrNull() ?: 10 // Default to 10 if not provided + val pageNum = request.getParameter("pageNum")?.toIntOrNull() ?: 1 // Default to 1 if not provided + val fullList = pickOrderService.getPickOrderLine(criteriaArgs) + val paginatedList = PagingUtils.getPaginatedList(fullList,pageSize, pageNum) + return RecordsRes(paginatedList, fullList.size) + } // Consolidating Pick Orders @PostMapping("/conso") @@ -54,13 +86,13 @@ class PickOrderController( } // Release Pick Order - @GetMapping("/releaseConso/{consoCode}") + @GetMapping("/pre-release-info/{consoCode}") fun releaseConsoPickOrderInfo(@PathVariable consoCode: String): ReleasePickOrderInfoResponse { return pickOrderService.releaseConsoPickOrderInfo(consoCode); } @PostMapping("/releaseConso") - fun releaseConsoPickOrderAction(@Valid @RequestBody request: ReleaseConsoPickOrderRequest) { - pickOrderService.releaseConsoPickOrderAction(request) + fun releaseConsoPickOrderAction(@Valid @RequestBody request: ReleaseConsoPickOrderRequest): ResponseEntity { + return pickOrderService.releaseConsoPickOrderAction(request) } } \ No newline at end of file diff --git a/src/main/java/com/ffii/fpsms/modules/stock/entity/projection/InventoryLotLineInfo.kt b/src/main/java/com/ffii/fpsms/modules/stock/entity/projection/InventoryLotLineInfo.kt index 0ca9fc0..c1314a6 100644 --- a/src/main/java/com/ffii/fpsms/modules/stock/entity/projection/InventoryLotLineInfo.kt +++ b/src/main/java/com/ffii/fpsms/modules/stock/entity/projection/InventoryLotLineInfo.kt @@ -43,6 +43,7 @@ interface CurrentInventoryItemInfo { val id: Long? // item id val code: String? val name: String? + val uomDesc: String? val availableQty: BigDecimal? val requiredQty: BigDecimal? } \ No newline at end of file diff --git a/src/main/java/com/ffii/fpsms/modules/stock/service/SuggestedPickLotService.kt b/src/main/java/com/ffii/fpsms/modules/stock/service/SuggestedPickLotService.kt index 9298222..f7d348d 100644 --- a/src/main/java/com/ffii/fpsms/modules/stock/service/SuggestedPickLotService.kt +++ b/src/main/java/com/ffii/fpsms/modules/stock/service/SuggestedPickLotService.kt @@ -69,8 +69,8 @@ open class SuggestedPickLotService( // get current inventory lot line qty & grouped by item Id val availableInventoryLotLines = inventoryLotLineService .allInventoryLotLinesByItemIdIn(itemIds) - .filter { (it.inQty ?: zero).minus(it.outQty ?: zero).minus(it.holdQty ?: zero) > zero } .filter { it.status == InventoryLotLineStatus.AVAILABLE.value } + .filter { (it.inQty ?: zero).minus(it.outQty ?: zero).minus(it.holdQty ?: zero) > zero } .sortedBy { it.expiryDate } .groupBy { it.item?.id } diff --git a/src/main/java/com/ffii/fpsms/modules/stock/web/InventoryLotLineController.kt b/src/main/java/com/ffii/fpsms/modules/stock/web/InventoryLotLineController.kt index 2634c8c..d9f3b53 100644 --- a/src/main/java/com/ffii/fpsms/modules/stock/web/InventoryLotLineController.kt +++ b/src/main/java/com/ffii/fpsms/modules/stock/web/InventoryLotLineController.kt @@ -2,18 +2,23 @@ package com.ffii.fpsms.modules.stock.web import com.ffii.fpsms.modules.pickOrder.web.models.ConsoPickOrderRequest import com.ffii.fpsms.modules.stock.entity.InventoryLotLineRepository +import com.ffii.fpsms.modules.stock.entity.StockInLineRepository +import com.ffii.fpsms.modules.stock.web.model.LotLineInfo import jakarta.validation.Valid import org.springframework.web.bind.annotation.GetMapping +import org.springframework.web.bind.annotation.PathVariable import org.springframework.web.bind.annotation.PostMapping import org.springframework.web.bind.annotation.RequestBody import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.RequestParam import org.springframework.web.bind.annotation.RestController +import java.math.BigDecimal @RequestMapping("/inventoryLotLine") @RestController class InventoryLotLineController ( - private val inventoryLotLineRepository: InventoryLotLineRepository + private val inventoryLotLineRepository: InventoryLotLineRepository, + private val stockInLineRepository: StockInLineRepository, ){ // @PostMapping("/test") @@ -24,4 +29,19 @@ class InventoryLotLineController ( fun test(@Valid @RequestBody request: ConsoPickOrderRequest): Any { return inventoryLotLineRepository.findCurrentInventoryByItems(request.ids) } + + @GetMapping("/lot-detail/{stockInLineId}") + fun getLotDetail(@Valid @PathVariable stockInLineId: Long): LotLineInfo { + val stockInLine = stockInLineRepository.findById(stockInLineId).orElseThrow() + val inventoryLotLine = stockInLine.inventoryLotLine!! + val zero = BigDecimal.ZERO + return LotLineInfo( + inventoryLotLineId = inventoryLotLine.id!!, + lotNo = stockInLine.lotNo!!, + remainingQty = (inventoryLotLine.inQty ?: zero) + .minus(inventoryLotLine.outQty ?: zero) + .minus(inventoryLotLine.holdQty ?: zero), + uom = inventoryLotLine.stockUom!!.uom!!.udfudesc!! + ) + } } \ No newline at end of file diff --git a/src/main/java/com/ffii/fpsms/modules/stock/web/model/LotLineInfo.kt b/src/main/java/com/ffii/fpsms/modules/stock/web/model/LotLineInfo.kt new file mode 100644 index 0000000..65335fd --- /dev/null +++ b/src/main/java/com/ffii/fpsms/modules/stock/web/model/LotLineInfo.kt @@ -0,0 +1,10 @@ +package com.ffii.fpsms.modules.stock.web.model + +import java.math.BigDecimal + +data class LotLineInfo( + val inventoryLotLineId: Long, + val lotNo: String, + val remainingQty: BigDecimal, + val uom: String +) diff --git a/src/main/java/com/ffii/fpsms/modules/user/web/UserController.java b/src/main/java/com/ffii/fpsms/modules/user/web/UserController.java index 526d8bf..4f0a038 100644 --- a/src/main/java/com/ffii/fpsms/modules/user/web/UserController.java +++ b/src/main/java/com/ffii/fpsms/modules/user/web/UserController.java @@ -1,11 +1,14 @@ package com.ffii.fpsms.modules.user.web; import java.io.UnsupportedEncodingException; +import java.util.HashMap; import java.util.List; +import java.util.Map; import com.ffii.fpsms.modules.user.service.pojo.UserRecord; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.hibernate.mapping.Any; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.access.prepost.PreAuthorize; @@ -69,6 +72,19 @@ public class UserController{ return ResponseEntity.ok(userService.search(req)); } + @GetMapping("/name-list") + public ResponseEntity>> namelist() { + SearchUserReq req = new SearchUserReq(); + List> namelist = userService.search(req).stream() + .map(user -> { + Map map = new HashMap<>(); + map.put("id", user.getId()); + map.put("name", user.getName()); + return map; + }) + .toList(); + return ResponseEntity.ok(namelist); + } // @Operation(summary = "load user data", responses = { @ApiResponse(responseCode = "200"), // @ApiResponse(responseCode = "404", content = @Content) }) @GetMapping("/{id}")