diff --git a/src/main/java/com/ffii/fpsms/modules/jobOrder/entity/JobOrder.kt b/src/main/java/com/ffii/fpsms/modules/jobOrder/entity/JobOrder.kt index 5511fed..5314502 100644 --- a/src/main/java/com/ffii/fpsms/modules/jobOrder/entity/JobOrder.kt +++ b/src/main/java/com/ffii/fpsms/modules/jobOrder/entity/JobOrder.kt @@ -6,6 +6,7 @@ import com.ffii.fpsms.modules.jobOrder.enums.JobOrderStatus import com.ffii.fpsms.modules.jobOrder.enums.JobOrderStatusConverter import com.ffii.fpsms.modules.master.entity.Bom import com.ffii.fpsms.modules.master.entity.ProductionScheduleLine +import com.ffii.fpsms.modules.stock.entity.StockInLine import com.ffii.fpsms.modules.user.entity.User import jakarta.persistence.* import jakarta.validation.constraints.NotNull @@ -46,8 +47,8 @@ open class JobOrder : BaseEntity() { // @Size(max = 100) @NotNull - @Column(name = "status", nullable = false, length = 100) @Convert(converter = JobOrderStatusConverter::class) + @Column(name = "status", nullable = false, length = 100) open var status: JobOrderStatus? = null @Size(max = 500) @@ -71,4 +72,8 @@ open class JobOrder : BaseEntity() { @JsonManagedReference @OneToMany(mappedBy = "jobOrder", cascade = [CascadeType.ALL], orphanRemoval = true) open var jobms: MutableList = mutableListOf() + + @JsonManagedReference + @OneToMany(mappedBy = "jobOrder", cascade = [CascadeType.ALL], orphanRemoval = true) + open var stockInLines: MutableList = mutableListOf() } \ No newline at end of file diff --git a/src/main/java/com/ffii/fpsms/modules/jobOrder/entity/projections/JobOrderInfo.kt b/src/main/java/com/ffii/fpsms/modules/jobOrder/entity/projections/JobOrderInfo.kt index 562c8a7..384dcc2 100644 --- a/src/main/java/com/ffii/fpsms/modules/jobOrder/entity/projections/JobOrderInfo.kt +++ b/src/main/java/com/ffii/fpsms/modules/jobOrder/entity/projections/JobOrderInfo.kt @@ -1,5 +1,6 @@ package com.ffii.fpsms.modules.jobOrder.entity.projections +import com.ffii.fpsms.modules.master.entity.* import org.springframework.beans.factory.annotation.Value import java.math.BigDecimal @@ -10,14 +11,30 @@ interface JobOrderInfo { @get:Value("#{target.bom.item.code}") val itemCode: String; + @get:Value("#{target.bom.item.name}") + val itemName: String; @get:Value("#{target.bom.name}") val name: String; val reqQty: BigDecimal; - @get:Value("#{target.bom.item.itemUoms.^[salesUnit == true && deleted == false]?.uom.udfudesc}") - val uom: String; + @get:Value("#{target.bom.item}") + val item: JobOrderItemInfo; -@get:Value("#{target.status.value}") + // TODO pack below as StockInLineInfo + @get:Value("#{target.stockInLines?.size() > 0 ? target.stockInLines[0].id : null}") + val stockInLineId: Long?; + + @get:Value("#{target.stockInLines?.size() > 0 ? target.stockInLines[0].status : null}") + val stockInLineStatus: String?; + + @get:Value("#{target.stockInLines?.size() > 0 ? target.stockInLines[0].escalationLog.^[status.value == 'pending']?.handler?.id : null}") + val silHandlerId: Long?; + +// @get:Value("#{target.bom.item.itemUoms.^[salesUnit == true && deleted == false]?.uom}") +//// @get:Value("#{target.bom.item.itemUoms.^[salesUnit == true && deleted == false]?.uom.udfudesc}") +// val uom: UomConversion; + + @get:Value("#{target.status.value}") val status: String; } @@ -27,6 +44,7 @@ interface JobOrderDetailWithJsonString { val code: String?; val itemCode: String?; val name: String?; + val itemId: Long?; val reqQty: BigDecimal?; val uom: String?; val shortUom: String?; @@ -34,6 +52,32 @@ interface JobOrderDetailWithJsonString { val status: String?; } +//interface JobOrderResult { +// val id: Long; +// val code: String?; +// @get:Value("#{target.status.value}") +// val status: String; +// @get:Value("#{target.bom.item}") +// val item: Items; +// val reqQty: BigDecimal; +// @get:Value("#{target.bom.item.itemUoms.^[salesUnit == true && deleted == false]?.uom}") +// val uom: UomConversion?; +//} + +interface JobOrderItemInfo{ + val id: Long + val name: String + val code: String + val description: String? + val remarks: String? + val type: String? + val shelfLife: Double? + val countryOfOrigin: String? + val maxQty: Double? + @get:Value("#{target.itemUoms.^[salesUnit == true && deleted == false]?.uom}") + val uom: UomConversion? +} + data class JobOrderDetail( val id: Long?, val code: String?, diff --git a/src/main/java/com/ffii/fpsms/modules/jobOrder/service/JobOrderService.kt b/src/main/java/com/ffii/fpsms/modules/jobOrder/service/JobOrderService.kt index e3ecb80..eb72933 100644 --- a/src/main/java/com/ffii/fpsms/modules/jobOrder/service/JobOrderService.kt +++ b/src/main/java/com/ffii/fpsms/modules/jobOrder/service/JobOrderService.kt @@ -1,5 +1,6 @@ package com.ffii.fpsms.modules.jobOrder.service +import com.ffii.core.exception.BadRequestException import com.ffii.core.response.RecordsRes import com.ffii.core.utils.GsonUtils import com.ffii.core.utils.PdfUtils @@ -10,9 +11,6 @@ import com.ffii.fpsms.modules.jobOrder.entity.projections.JobOrderDetail import com.ffii.fpsms.modules.jobOrder.entity.projections.JobOrderDetailPickLine import com.ffii.fpsms.modules.jobOrder.entity.projections.JobOrderInfo import com.ffii.fpsms.modules.jobOrder.enums.JobOrderStatus -import com.ffii.fpsms.modules.jobOrder.web.model.CreateJobOrderRequest -import com.ffii.fpsms.modules.jobOrder.web.model.JobOrderCommonActionRequest -import com.ffii.fpsms.modules.jobOrder.web.model.SearchJobOrderInfoRequest import com.ffii.fpsms.modules.master.entity.ProductionScheduleLineRepository import com.ffii.fpsms.modules.master.service.BomService import com.ffii.fpsms.modules.master.web.models.MessageResponse @@ -32,6 +30,7 @@ import java.time.format.DateTimeFormatter import kotlin.jvm.optionals.getOrNull import com.ffii.fpsms.modules.jobOrder.service.JoPickOrderService +import com.ffii.fpsms.modules.jobOrder.web.model.* import com.ffii.fpsms.modules.jobOrder.web.model.ExportPickRecordRequest import com.ffii.fpsms.modules.jobOrder.web.model.PrintPickRecordRequest import com.ffii.fpsms.modules.master.service.PrinterService @@ -78,7 +77,7 @@ open class JobOrderService( val response = jobOrderRepository.findJobOrderInfoByCodeContainsAndBomNameContainsAndDeletedIsFalseOrderByIdDesc( code = request.code ?: "", - bomName = request.name ?: "", + bomName = request.itemName ?: "", pageable = pageable ) @@ -177,6 +176,35 @@ open class JobOrderService( ) } + @Transactional(rollbackFor = [Exception::class]) + open fun updateJobOrder(request: JobOrderUpdateRequest): MessageResponse { + val jo = request.id.let { jobOrderRepository.findById(it).getOrNull() } ?: throw NoSuchElementException() + val newStatus: JobOrderStatus = when (request.status) { //TODO: improve if can + "pending" -> { JobOrderStatus.PENDING } + "processing" -> { JobOrderStatus.PROCESSING } + "planning" -> { JobOrderStatus.PLANNING } + "storing" -> { JobOrderStatus.STORING } + "completed" -> { JobOrderStatus.COMPLETED } + "packaging" -> { JobOrderStatus.PACKAGING } + else -> { throw BadRequestException() } + } + + jo.apply { + status = newStatus + } + val savedJo = jobOrderRepository.save(jo) + + return MessageResponse( + id = savedJo.id, + code = savedJo.code, + name = savedJo.bom?.name, + type = null, + message = "Job Order status updated to " + savedJo.status, + errorPosition = null, + entity = mapOf("status" to jo.status?.value) + ) + } + @Transactional(rollbackFor = [Exception::class]) open fun releaseJobOrder(request: JobOrderCommonActionRequest): MessageResponse { val jo = request.id.let { jobOrderRepository.findById(it).getOrNull() } ?: throw NoSuchElementException() diff --git a/src/main/java/com/ffii/fpsms/modules/jobOrder/web/JobOrderController.kt b/src/main/java/com/ffii/fpsms/modules/jobOrder/web/JobOrderController.kt index 24422ee..68de062 100644 --- a/src/main/java/com/ffii/fpsms/modules/jobOrder/web/JobOrderController.kt +++ b/src/main/java/com/ffii/fpsms/modules/jobOrder/web/JobOrderController.kt @@ -19,6 +19,7 @@ import org.springframework.web.bind.annotation.RequestBody import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.RestController import com.ffii.fpsms.modules.jobOrder.service.JoPickOrderService +import com.ffii.fpsms.modules.jobOrder.web.model.* import com.ffii.fpsms.modules.jobOrder.web.model.ExportPickRecordRequest import com.ffii.fpsms.modules.jobOrder.web.model.PrintPickRecordRequest import com.ffii.fpsms.modules.jobOrder.web.model.SecondScanSubmitRequest @@ -56,6 +57,11 @@ class JobOrderController( return jobOrderService.jobOrderDetailByCode(code); } + @PostMapping("/update") + fun updateJobOrder(@Valid @RequestBody request: JobOrderUpdateRequest): MessageResponse { + return jobOrderService.updateJobOrder(request) + } + @PostMapping("/release") fun releaseJobOrder(@Valid @RequestBody request: JobOrderCommonActionRequest): MessageResponse { return jobOrderService.releaseJobOrder(request) diff --git a/src/main/java/com/ffii/fpsms/modules/jobOrder/web/model/JobOrderActionRequest.kt b/src/main/java/com/ffii/fpsms/modules/jobOrder/web/model/JobOrderActionRequest.kt index 217d306..775cd9b 100644 --- a/src/main/java/com/ffii/fpsms/modules/jobOrder/web/model/JobOrderActionRequest.kt +++ b/src/main/java/com/ffii/fpsms/modules/jobOrder/web/model/JobOrderActionRequest.kt @@ -2,4 +2,9 @@ package com.ffii.fpsms.modules.jobOrder.web.model data class JobOrderCommonActionRequest( val id: Long, +) + +data class JobOrderUpdateRequest( + val id: Long, + val status: String, ) \ No newline at end of file diff --git a/src/main/java/com/ffii/fpsms/modules/jobOrder/web/model/SearchJobOrderInfoRequest.kt b/src/main/java/com/ffii/fpsms/modules/jobOrder/web/model/SearchJobOrderInfoRequest.kt index c3c05cb..0a944cf 100644 --- a/src/main/java/com/ffii/fpsms/modules/jobOrder/web/model/SearchJobOrderInfoRequest.kt +++ b/src/main/java/com/ffii/fpsms/modules/jobOrder/web/model/SearchJobOrderInfoRequest.kt @@ -2,7 +2,7 @@ package com.ffii.fpsms.modules.jobOrder.web.model data class SearchJobOrderInfoRequest( val code: String?, - val name: String?, + val itemName: String?, val pageSize: Int?, val pageNum: Int?, ) diff --git a/src/main/java/com/ffii/fpsms/modules/master/entity/Items.kt b/src/main/java/com/ffii/fpsms/modules/master/entity/Items.kt index 95e9bcd..51a525a 100644 --- a/src/main/java/com/ffii/fpsms/modules/master/entity/Items.kt +++ b/src/main/java/com/ffii/fpsms/modules/master/entity/Items.kt @@ -60,6 +60,7 @@ open class Items : BaseEntity() { open var category: ItemCategory? = null @ManyToOne + @JsonManagedReference @JoinColumn(name = "qcCategoryId") open var qcCategory: QcCategory? = null } \ No newline at end of file diff --git a/src/main/java/com/ffii/fpsms/modules/purchaseOrder/service/PurchaseOrderService.kt b/src/main/java/com/ffii/fpsms/modules/purchaseOrder/service/PurchaseOrderService.kt index 309cf79..a805538 100644 --- a/src/main/java/com/ffii/fpsms/modules/purchaseOrder/service/PurchaseOrderService.kt +++ b/src/main/java/com/ffii/fpsms/modules/purchaseOrder/service/PurchaseOrderService.kt @@ -241,8 +241,8 @@ open class PurchaseOrderService( qty = thisPol.qty!!, // processed = inLine.filter{ it.status == StockInLineStatus.COMPLETE.status}.sumOf { it.acceptedQty }, processed = inLine - .filter { line -> line.putAwayLines.any { it.qty?.let { qty -> qty > BigDecimal.ZERO } == true } } - .sumOf { line -> line.putAwayLines.sumOf { it.qty?.takeIf { qty -> qty > BigDecimal.ZERO } ?: BigDecimal.ZERO } }, + .filter { line -> line.putAwayLines?.any { it.qty?.let { qty -> qty > BigDecimal.ZERO } == true } ?: false } + .sumOf { line -> line.putAwayLines?.sumOf { it.qty?.takeIf { qty -> qty > BigDecimal.ZERO } ?: BigDecimal.ZERO } ?: BigDecimal.ZERO}, receivedQty = thisPol.stockInLines.sumOf { it.acceptedQty ?: BigDecimal.ZERO }, uom = thisPol.uom!!, price = thisPol.price!!, diff --git a/src/main/java/com/ffii/fpsms/modules/stock/entity/StockInLine.kt b/src/main/java/com/ffii/fpsms/modules/stock/entity/StockInLine.kt index f70d3be..68237cd 100644 --- a/src/main/java/com/ffii/fpsms/modules/stock/entity/StockInLine.kt +++ b/src/main/java/com/ffii/fpsms/modules/stock/entity/StockInLine.kt @@ -3,6 +3,7 @@ package com.ffii.fpsms.modules.stock.entity import com.fasterxml.jackson.annotation.JsonBackReference import com.fasterxml.jackson.annotation.JsonManagedReference import com.ffii.core.entity.BaseEntity +import com.ffii.fpsms.modules.jobOrder.entity.JobOrder import com.ffii.fpsms.modules.master.entity.Items import com.ffii.fpsms.modules.purchaseOrder.entity.PurchaseOrder import com.ffii.fpsms.modules.purchaseOrder.entity.PurchaseOrderLine @@ -37,6 +38,11 @@ open class StockInLine : BaseEntity() { @JoinColumn(name = "purchaseOrderLineId") open var purchaseOrderLine: PurchaseOrderLine? = null + @JsonBackReference + @ManyToOne + @JoinColumn(name = "jobOrderId") + open var jobOrder: JobOrder? = null + @ManyToOne @JoinColumn(name = "stockTakeLineId") open var stockTakeLine: StockTakeLine? = null diff --git a/src/main/java/com/ffii/fpsms/modules/stock/entity/projection/StockInLineInfo.kt b/src/main/java/com/ffii/fpsms/modules/stock/entity/projection/StockInLineInfo.kt index 38d1851..cf6bb1d 100644 --- a/src/main/java/com/ffii/fpsms/modules/stock/entity/projection/StockInLineInfo.kt +++ b/src/main/java/com/ffii/fpsms/modules/stock/entity/projection/StockInLineInfo.kt @@ -20,10 +20,12 @@ interface StockInLineInfo { val purchaseOrderLineId: Long? @get:Value("#{target.purchaseOrder?.id}") val purchaseOrderId: Long? + @get:Value("#{target.jobOrder?.id}") + val jobOrderId: Long? val demandQty: BigDecimal? val acceptedQty: BigDecimal @get:Value("#{target.purchaseOrderLine?.qty}") - val qty: BigDecimal + val qty: BigDecimal? val price: BigDecimal? val priceUnit: BigDecimal? @get:Value("#{target.item?.shelfLife}") @@ -36,19 +38,21 @@ interface StockInLineInfo { var productLotNo: String? @get:Value("#{target.stockIn?.supplier?.name}") val supplier: String? - @get:Value("#{target.purchaseOrderLine?.uom ?: target.stockTakeLine?.uom}") - val uom: UomConversion + @get:Value("#{target.item?.itemUoms.^[salesUnit == true && deleted == false]?.uom}") //TODO review + val uom: UomConversion? @get:Value("#{target.stockIn?.purchaseOrder?.code}") val poCode: String? + @get:Value("#{target.jobOrder?.code}") + val joCode: String? @get:Value("#{target.item?.type}") - val itemType: String - val dnNo: String -// val dnDate: LocalDateTime? + val itemType: String? + val dnNo: String? + // val dnDate: LocalDateTime? // val qcDecision: LocalDateTime? @get:Value("#{target.escalationLog.^[status.value == 'pending']?.handler?.id}") val handlerId: Long? @get:Value("#{target.inventoryLot?.inventoryLotLines ?: new java.util.ArrayList()}") - val putAwayLines: List; + val putAwayLines: List? } interface PutAwayLineForSil { diff --git a/src/main/java/com/ffii/fpsms/modules/stock/service/InventoryLotLineService.kt b/src/main/java/com/ffii/fpsms/modules/stock/service/InventoryLotLineService.kt index e1111a0..1e984ed 100644 --- a/src/main/java/com/ffii/fpsms/modules/stock/service/InventoryLotLineService.kt +++ b/src/main/java/com/ffii/fpsms/modules/stock/service/InventoryLotLineService.kt @@ -104,7 +104,7 @@ open class InventoryLotLineService( open fun updateInventoryLotLineStatus(request: UpdateInventoryLotLineStatusRequest): MessageResponse { // Get the existing inventory lot line val existingLotLine = inventoryLotLineRepository.findById(request.inventoryLotLineId).orElseThrow() - + // Create update request with existing data and new status val updateRequest = SaveInventoryLotLineRequest( id = existingLotLine.id, @@ -118,12 +118,12 @@ open class InventoryLotLineService( status = request.status, remarks = existingLotLine.remarks ) - + val updatedLotLine = saveInventoryLotLine(updateRequest) - + // ✅ ADD THIS: Update inventory table after lot line status change updateInventoryTable(updatedLotLine) - + return MessageResponse( id = updatedLotLine.id, name = updatedLotLine.id.toString(), @@ -143,27 +143,27 @@ open class InventoryLotLineService( println("Cannot update inventory table: itemId is null for lot line ${inventoryLotLine.id}") return } - + // Calculate onHoldQty (sum of holdQty from available lots only) val onHoldQty = inventoryLotLineRepository.findAllByInventoryLotItemIdAndStatus(itemId, InventoryLotLineStatus.AVAILABLE.value) .sumOf { it.holdQty ?: BigDecimal.ZERO } - + // Calculate unavailableQty (sum of inQty from unavailable lots only) val unavailableQty = inventoryLotLineRepository.findAllByInventoryLotItemIdAndStatus(itemId, InventoryLotLineStatus.UNAVAILABLE.value) - .sumOf { + .sumOf { val inQty = it.inQty ?: BigDecimal.ZERO val outQty = it.outQty ?: BigDecimal.ZERO val remainingQty = inQty.minus(outQty) remainingQty } - + // Update the inventory table val inventory = inventoryRepository.findByItemId(itemId).orElse(null) if (inventory != null) { inventory.onHoldQty = onHoldQty inventory.unavailableQty = unavailableQty inventoryRepository.save(inventory) - + println("Updated inventory for item $itemId: onHoldQty=$onHoldQty, unavailableQty=$unavailableQty") } else { println("Inventory not found for item $itemId") @@ -200,11 +200,11 @@ open class InventoryLotLineService( field["itemName"] = info.itemName ?: "N/A" field["itemNo"] = info.itemNo field["poCode"] = info.poCode ?: "N/A" - field["itemType"] = info.itemType + field["itemType"] = info.itemType ?: "N/A" field["acceptedQty"] = info.acceptedQty.toString() - field["uom"] = (info.uom.udfudesc ?: "N/A").toString() - field["productionDate"] = info.productionDate?.format(DateTimeFormatter.ISO_LOCAL_DATE) ?: "N/A" - field["expiryDate"] = info.expiryDate?.format(DateTimeFormatter.ISO_LOCAL_DATE) ?: "N/A" + field["uom"] = info.uom?.udfudesc.toString() ?: "N/A" + field["productionDate"] = info.productionDate?.format(DateTimeFormatter.ISO_LOCAL_DATE) ?: "" + field["expiryDate"] = info.expiryDate?.format(DateTimeFormatter.ISO_LOCAL_DATE) ?: "" field["lotNo"] = info.lotNo!! field["supplier"] = info.supplier ?: "N/A" val image = QrCodeUtil.generateQRCodeImage(qrCodeContent) @@ -224,11 +224,11 @@ open class InventoryLotLineService( open fun updateInventoryLotLineQuantities(request: UpdateInventoryLotLineQuantitiesRequest): MessageResponse { try { val inventoryLotLine = inventoryLotLineRepository.findById(request.inventoryLotLineId).orElseThrow() - + // Handle quantity updates based on operation var newHoldQty = inventoryLotLine.holdQty ?: BigDecimal.ZERO var newOutQty = inventoryLotLine.outQty ?: BigDecimal.ZERO - + when (request.operation) { "pick" -> { // Move from hold_qty to out_qty @@ -244,12 +244,12 @@ open fun updateInventoryLotLineQuantities(request: UpdateInventoryLotLineQuantit throw IllegalArgumentException("Unknown operation: ${request.operation}") } } - + // Validate quantities if (newHoldQty < BigDecimal.ZERO || newOutQty < BigDecimal.ZERO) { throw IllegalArgumentException("Invalid quantities: holdQty=$newHoldQty, outQty=$newOutQty") } - + val updateRequest = SaveInventoryLotLineRequest( id = inventoryLotLine.id, inventoryLotId = inventoryLotLine.inventoryLot?.id, @@ -261,9 +261,9 @@ open fun updateInventoryLotLineQuantities(request: UpdateInventoryLotLineQuantit status = inventoryLotLine.status?.value, // Keep existing status remarks = inventoryLotLine.remarks ) - + val updatedInventoryLotLine = saveInventoryLotLine(updateRequest) - + return MessageResponse( id = updatedInventoryLotLine.id, name = "Inventory lot line quantities updated", diff --git a/src/main/java/com/ffii/fpsms/modules/stock/service/StockInLineService.kt b/src/main/java/com/ffii/fpsms/modules/stock/service/StockInLineService.kt index 0492287..bc4381f 100644 --- a/src/main/java/com/ffii/fpsms/modules/stock/service/StockInLineService.kt +++ b/src/main/java/com/ffii/fpsms/modules/stock/service/StockInLineService.kt @@ -23,6 +23,8 @@ import java.time.LocalDate import java.time.LocalDateTime import com.ffii.core.utils.PdfUtils; import com.ffii.core.utils.ZebraPrinterUtil +import com.ffii.fpsms.modules.jobOrder.entity.JobOrderRepository +import com.ffii.fpsms.modules.jobOrder.enums.JobOrderStatus import com.ffii.fpsms.modules.master.entity.ItemUomRespository import com.ffii.fpsms.modules.master.entity.WarehouseRepository import com.ffii.fpsms.modules.master.service.PrinterService @@ -61,6 +63,7 @@ open class StockInLineService( private val stockInService: StockInService, private val stockInRepository: StockInRepository, private val stockInLineRepository: StockInLineRepository, + private val jobOrderRepository: JobOrderRepository, private val inventoryLotRepository: InventoryLotRepository, private val inventoryLotLineRepository: InventoryLotLineRepository, private val itemRepository: ItemsRepository, @@ -86,6 +89,9 @@ open class StockInLineService( val stl = if (request.stockTakeLineId != null) request.stockTakeLineId?.let { stockTakeLineRepository.findById(it).getOrNull() } else null + val jo = if (request.jobOrderId != null) + request.jobOrderId?.let { jobOrderRepository.findById(it).getOrNull() } + else null var stockIn = if (request.stockInId != null) request.stockInId?.let { stockInRepository.findByIdAndDeletedFalse(it) } else if (pol != null) pol.purchaseOrder?.id?.let { stockInRepository.findByPurchaseOrderIdAndDeletedFalse(it) } @@ -97,6 +103,7 @@ open class StockInLineService( // stockIn = stockInService.create(SaveStockInRequest(purchaseOrderId = request.purchaseOrderId)).entity as StockIn // var stockIn = stockInRepository.findByPurchaseOrderIdAndDeletedFalse(request.purchaseOrderId) } + val item = itemRepository.findById(request.itemId).orElseThrow() // If request contains valid POL if (pol != null) { @@ -128,6 +135,13 @@ open class StockInLineService( } } + // If request contains valid job order id + if (jo != null) { + stockInLine.apply { + this.jobOrder = jo + } + } + // val allStockInLine = stockInLineRepository.findAllStockInLineInfoByStockInIdAndDeletedFalse(stockIn.id!!) // if (pol.qty!! < request.acceptedQty) { // throw BadRequestException() @@ -401,6 +415,14 @@ open class StockInLineService( StockInLineStatus.COMPLETE.status else StockInLineStatus.PARTIALLY_COMPLETE.status // this.inventoryLotLine = savedInventoryLotLine } + // Update JO Status + if (stockInLine.jobOrder != null) { //TODO Improve + val jo = stockInLine.jobOrder + jo?.apply { + status = JobOrderStatus.COMPLETED + } + jobOrderRepository.save(jo!!) + } } } else if (request.status == StockInLineStatus.PENDING.status || request.status == StockInLineStatus.ESCALATED.status) { var escLogId : Long? = 0L; @@ -496,11 +518,11 @@ open class StockInLineService( field["itemName"] = info.itemName ?: "N/A" field["itemNo"] = info.itemNo field["poCode"] = info.poCode ?: "N/A" - field["itemType"] = info.itemType + field["itemType"] = info.itemType ?: "N/A" field["acceptedQty"] = info.acceptedQty.toString() - field["uom"] = (info.uom.udfudesc ?: "N/A").toString() - field["productionDate"] = info.productionDate?.format(DateTimeFormatter.ISO_LOCAL_DATE) ?: "N/A" - field["expiryDate"] = info.expiryDate?.format(DateTimeFormatter.ISO_LOCAL_DATE) ?: "N/A" + field["uom"] = info.uom?.udfudesc.toString() ?: "N/A" + field["productionDate"] = info.productionDate?.format(DateTimeFormatter.ISO_LOCAL_DATE) ?: "" + field["expiryDate"] = info.expiryDate?.format(DateTimeFormatter.ISO_LOCAL_DATE) ?: "" field["lotNo"] = info.lotNo ?: "N/A" field["supplier"] = info.supplier ?: "N/A" val image = QrCodeUtil.generateQRCodeImage(qrCodeContent) @@ -508,11 +530,11 @@ open class StockInLineService( fields.add(field) } val params: MutableMap = mutableMapOf( - "poCode" to (qrCodeInfo[0].poCode ?: "N/A") + "poCode" to (qrCodeInfo[0].poCode ?: "N/A") //TODO change to JO code for JO ) return mapOf( "report" to PdfUtils.fillReport(poLabel,fields, params), - "fileName" to (qrCodeInfo[0].poCode ?: qrCodeInfo[0].lotNo ?: "N/A") + "fileName" to (qrCodeInfo[0].poCode ?: qrCodeInfo[0].joCode ?: qrCodeInfo[0].lotNo).toString() ); } diff --git a/src/main/java/com/ffii/fpsms/modules/stock/web/model/SaveStockInRequest.kt b/src/main/java/com/ffii/fpsms/modules/stock/web/model/SaveStockInRequest.kt index 4ba6bd4..8c43d6f 100644 --- a/src/main/java/com/ffii/fpsms/modules/stock/web/model/SaveStockInRequest.kt +++ b/src/main/java/com/ffii/fpsms/modules/stock/web/model/SaveStockInRequest.kt @@ -45,6 +45,7 @@ data class SaveStockInLineRequest( var itemId: Long, var purchaseOrderId: Long? = null, var purchaseOrderLineId: Long? = null, + var jobOrderId: Long? = null, var acceptedQty: BigDecimal, var acceptQty: BigDecimal?, var acceptedWeight: BigDecimal? = null, diff --git a/src/main/resources/db/changelog/changes/20250929_01_kelvin/01_update_stock_in_line.sql b/src/main/resources/db/changelog/changes/20250929_01_kelvin/01_update_stock_in_line.sql new file mode 100644 index 0000000..3281af8 --- /dev/null +++ b/src/main/resources/db/changelog/changes/20250929_01_kelvin/01_update_stock_in_line.sql @@ -0,0 +1,4 @@ +-- liquibase formatted sql +-- changeset kelvin:update stock in line table +ALTER TABLE `stock_in_line` +ADD COLUMN `jobOrderId` INT NULL DEFAULT NULL AFTER `stockTakeLineId`;