| @@ -44,7 +44,7 @@ interface JobOrderRepository : AbstractRepository<JobOrder, Long> { | |||||
| bi.code as itemCode, | bi.code as itemCode, | ||||
| b.name, | b.name, | ||||
| jo.reqQty, | jo.reqQty, | ||||
| -- b.outputQtyUom, | |||||
| b.outputQtyUom as unit, | |||||
| uc2.udfudesc as uom, | uc2.udfudesc as uom, | ||||
| COALESCE(uc2.udfShortDesc, uc2.udfudesc) as shortUom, | COALESCE(uc2.udfShortDesc, uc2.udfudesc) as shortUom, | ||||
| json_arrayagg( | json_arrayagg( | ||||
| @@ -84,6 +84,7 @@ interface JobOrderRepository : AbstractRepository<JobOrder, Long> { | |||||
| jo.code, | jo.code, | ||||
| b.name, | b.name, | ||||
| jo.reqQty, | jo.reqQty, | ||||
| b.outputQtyUom as unit, | |||||
| uc2.udfudesc as uom, | uc2.udfudesc as uom, | ||||
| json_arrayagg( | json_arrayagg( | ||||
| json_object( | json_object( | ||||
| @@ -1123,6 +1123,16 @@ open fun getCompletedJobOrderPickOrderLotDetails(pickOrderId: Long): List<Map<St | |||||
| -- Job Order Information | -- Job Order Information | ||||
| jo.id as jobOrderId, | jo.id as jobOrderId, | ||||
| jo.code as jobOrderCode, | jo.code as jobOrderCode, | ||||
| DATE_FORMAT(jo.planStart, '%Y/%m/%d') as jobOrderPlanStart, | |||||
| jo.reqQty as jobOrderReqQty, | |||||
| -- Finished Goods Information | |||||
| fg.code as fgCode, | |||||
| fg.name as fgName, | |||||
| b.outputQtyUom as unit, | |||||
| uc_fg.udfudesc as uomConversionDesc, | |||||
| -- Pick Order Line Information | -- Pick Order Line Information | ||||
| pol.id as pickOrderLineId, | pol.id as pickOrderLineId, | ||||
| @@ -1212,6 +1222,8 @@ open fun getCompletedJobOrderPickOrderLotDetails(pickOrderId: Long): List<Map<St | |||||
| FROM fpsmsdb.pick_order po | FROM fpsmsdb.pick_order po | ||||
| JOIN fpsmsdb.job_order jo ON jo.id = po.joId | JOIN fpsmsdb.job_order jo ON jo.id = po.joId | ||||
| LEFT JOIN fpsmsdb.bom b ON b.id = jo.bomId | |||||
| LEFT JOIN fpsmsdb.items fg ON fg.id = b.itemId | |||||
| JOIN fpsmsdb.pick_order_line pol ON pol.poId = po.id | JOIN fpsmsdb.pick_order_line pol ON pol.poId = po.id | ||||
| JOIN fpsmsdb.items i ON i.id = pol.itemId | JOIN fpsmsdb.items i ON i.id = pol.itemId | ||||
| LEFT JOIN fpsmsdb.uom_conversion uc ON uc.id = pol.uomId | LEFT JOIN fpsmsdb.uom_conversion uc ON uc.id = pol.uomId | ||||
| @@ -1222,6 +1234,8 @@ open fun getCompletedJobOrderPickOrderLotDetails(pickOrderId: Long): List<Map<St | |||||
| LEFT JOIN fpsmsdb.warehouse w ON w.id = ill.warehouseId | LEFT JOIN fpsmsdb.warehouse w ON w.id = ill.warehouseId | ||||
| LEFT JOIN fpsmsdb.stock_out_line sol ON sol.pickOrderLineId = pol.id AND sol.inventoryLotLineId = ill.id AND sol.deleted = false | LEFT JOIN fpsmsdb.stock_out_line sol ON sol.pickOrderLineId = pol.id AND sol.inventoryLotLineId = ill.id AND sol.deleted = false | ||||
| LEFT JOIN fpsmsdb.jo_pick_order jpo ON jpo.pick_order_id = po.id AND jpo.item_id = pol.itemId | LEFT JOIN fpsmsdb.jo_pick_order jpo ON jpo.pick_order_id = po.id AND jpo.item_id = pol.itemId | ||||
| LEFT JOIN fpsmsdb.item_uom iu ON iu.itemId = b.itemId | |||||
| LEFT JOIN fpsmsdb.uom_conversion uc_fg ON uc_fg.id = iu.uomId AND iu.stockunit = 1 | |||||
| WHERE po.deleted = false | WHERE po.deleted = false | ||||
| AND po.id = :pickOrderId | AND po.id = :pickOrderId | ||||
| AND pol.deleted = false | AND pol.deleted = false | ||||
| @@ -2,6 +2,7 @@ package com.ffii.fpsms.modules.jobOrder.service | |||||
| import com.ffii.core.response.RecordsRes | import com.ffii.core.response.RecordsRes | ||||
| import com.ffii.core.utils.GsonUtils | import com.ffii.core.utils.GsonUtils | ||||
| import com.ffii.core.utils.PdfUtils | |||||
| import com.ffii.fpsms.modules.common.SecurityUtils | import com.ffii.fpsms.modules.common.SecurityUtils | ||||
| import com.ffii.fpsms.modules.jobOrder.entity.JobOrder | import com.ffii.fpsms.modules.jobOrder.entity.JobOrder | ||||
| import com.ffii.fpsms.modules.jobOrder.entity.JobOrderRepository | import com.ffii.fpsms.modules.jobOrder.entity.JobOrderRepository | ||||
| @@ -31,6 +32,8 @@ import java.time.format.DateTimeFormatter | |||||
| import kotlin.jvm.optionals.getOrNull | import kotlin.jvm.optionals.getOrNull | ||||
| import com.ffii.fpsms.modules.jobOrder.service.JoPickOrderService | import com.ffii.fpsms.modules.jobOrder.service.JoPickOrderService | ||||
| import com.ffii.fpsms.modules.jobOrder.web.model.ExportPickRecordRequest | |||||
| import com.ffii.fpsms.modules.jobOrder.web.model.PrintPickRecordRequest | |||||
| import com.ffii.fpsms.modules.pickOrder.entity.PickOrderRepository | import com.ffii.fpsms.modules.pickOrder.entity.PickOrderRepository | ||||
| import com.ffii.fpsms.modules.pickOrder.entity.PickOrderLineRepository | import com.ffii.fpsms.modules.pickOrder.entity.PickOrderLineRepository | ||||
| import com.ffii.fpsms.modules.stock.service.SuggestedPickLotService | import com.ffii.fpsms.modules.stock.service.SuggestedPickLotService | ||||
| @@ -42,6 +45,12 @@ import com.ffii.fpsms.modules.stock.entity.StockOutLine | |||||
| import com.ffii.fpsms.modules.stock.web.model.StockOutStatus | import com.ffii.fpsms.modules.stock.web.model.StockOutStatus | ||||
| import com.ffii.fpsms.modules.stock.web.model.StockOutLineStatus | import com.ffii.fpsms.modules.stock.web.model.StockOutLineStatus | ||||
| import com.ffii.fpsms.modules.stock.web.model.SuggestedPickLotForPolRequest | import com.ffii.fpsms.modules.stock.web.model.SuggestedPickLotForPolRequest | ||||
| import net.sf.jasperreports.engine.JasperCompileManager | |||||
| import org.springframework.core.io.ClassPathResource | |||||
| import java.io.FileNotFoundException | |||||
| import java.io.IOException | |||||
| @Service | @Service | ||||
| open class JobOrderService( | open class JobOrderService( | ||||
| val jobOrderRepository: JobOrderRepository, | val jobOrderRepository: JobOrderRepository, | ||||
| @@ -55,8 +64,10 @@ open class JobOrderService( | |||||
| val suggestedPickLotService: SuggestedPickLotService, | val suggestedPickLotService: SuggestedPickLotService, | ||||
| val inventoryLotLineRepository: InventoryLotLineRepository, | val inventoryLotLineRepository: InventoryLotLineRepository, | ||||
| val stockOutRepository: StockOutRepository, | val stockOutRepository: StockOutRepository, | ||||
| val stockOutLineRepository: StockOutLIneRepository | |||||
| val stockOutLineRepository: StockOutLIneRepository, | |||||
| ) { | ) { | ||||
| open fun allJobOrdersByPage(request: SearchJobOrderInfoRequest): RecordsRes<JobOrderInfo> { | open fun allJobOrdersByPage(request: SearchJobOrderInfoRequest): RecordsRes<JobOrderInfo> { | ||||
| val pageable = PageRequest.of(request.pageNum ?: 0, request.pageSize ?: 10); | val pageable = PageRequest.of(request.pageNum ?: 0, request.pageSize ?: 10); | ||||
| @@ -289,4 +300,68 @@ open class JobOrderService( | |||||
| entity = mapOf("status" to jo.status?.value) | entity = mapOf("status" to jo.status?.value) | ||||
| ) | ) | ||||
| } | } | ||||
| //Pick Record | |||||
| @Throws(IOException::class) | |||||
| @Transactional | |||||
| open fun exportPickRecord(request: ExportPickRecordRequest): Map<String, Any> { | |||||
| val PICKRECORD_PDF = "PickRecord/PickRecordPDF.jrxml" | |||||
| val resource = ClassPathResource(PICKRECORD_PDF) | |||||
| if(!resource.exists()){ | |||||
| throw FileNotFoundException("Report file not found: $PICKRECORD_PDF") | |||||
| } | |||||
| val inputStream = resource.inputStream | |||||
| val pickRecord = JasperCompileManager.compileReport(inputStream) | |||||
| val pickRecordInfo = joPickOrderService.getCompletedJobOrderPickOrderLotDetails(request.jobOrderIds).toMutableList() | |||||
| val fields = mutableListOf<MutableMap<String, Any>>() | |||||
| val params = mutableMapOf<String, Any>() | |||||
| val sortedPickRecordInfo = pickRecordInfo.sortedBy { info -> | |||||
| (info["routerIndex"] as? Int) ?: Int.MAX_VALUE | |||||
| } | |||||
| sortedPickRecordInfo.forEachIndexed { index, info -> | |||||
| val field = mutableMapOf<String, Any>() | |||||
| val itemName = info["itemName"] as? String?: "N/A" | |||||
| val itemCode = info["itemCode"] as? String?: "N/A" | |||||
| val lotNo = info["lotNo"] as? String?: "N/A" | |||||
| val uomShortDesc = info["uomShortDesc"] as? String?: "N/A" | |||||
| val uomDesc = info["uomDesc"] as? String?: "N/A" | |||||
| val route = info["routerRoute"] as? String?: "N/A" | |||||
| val actualPickQty = info["actualPickQty"] as? BigDecimal?: "N/A" | |||||
| field["sequenceNumber"] = (index + 1).toString() | |||||
| field["itemName"] = itemName | |||||
| field["itemNo"] = itemCode | |||||
| field["lotNo"] = lotNo | |||||
| field["shortName"] = uomShortDesc | |||||
| field["uom"] = uomDesc | |||||
| field["route"] = route | |||||
| field["qty"] = actualPickQty.toString() | |||||
| fields.add(field) | |||||
| } | |||||
| params["JobOrderCode"] = pickRecordInfo.firstOrNull()?.get("jobOrderCode") as? String ?: "N/A" | |||||
| params["ProductionDate"] = pickRecordInfo.firstOrNull()?.get("jobOrderPlanStart") as? String ?: "N/A" | |||||
| val reqQty = pickRecordInfo.firstOrNull()?.get("jobOrderReqQty") as? BigDecimal | |||||
| params["RequiredQuantity"] = reqQty?.toString() ?: "N/A" | |||||
| params["FGCode"] = pickRecordInfo.firstOrNull()?.get("fgCode") as? String ?: "N/A" | |||||
| params["FGName"] = pickRecordInfo.firstOrNull()?.get("fgName") as? String ?: "N/A" | |||||
| params["unit"] = pickRecordInfo.firstOrNull()?.get("unit") as? String ?: "N/A" | |||||
| return mapOf( | |||||
| "report" to PdfUtils.fillReport(pickRecord, fields, params), | |||||
| "filename" to "123" | |||||
| ) | |||||
| } | |||||
| @Transactional | |||||
| open fun printPickRecord(request: PrintPickRecordRequest){ | |||||
| } | |||||
| } | } | ||||
| @@ -19,8 +19,18 @@ import org.springframework.web.bind.annotation.RequestBody | |||||
| import org.springframework.web.bind.annotation.RequestMapping | import org.springframework.web.bind.annotation.RequestMapping | ||||
| import org.springframework.web.bind.annotation.RestController | import org.springframework.web.bind.annotation.RestController | ||||
| import com.ffii.fpsms.modules.jobOrder.service.JoPickOrderService | import com.ffii.fpsms.modules.jobOrder.service.JoPickOrderService | ||||
| import com.ffii.fpsms.modules.jobOrder.web.model.ExportPickRecordRequest | |||||
| import com.ffii.fpsms.modules.jobOrder.web.model.SecondScanSubmitRequest | import com.ffii.fpsms.modules.jobOrder.web.model.SecondScanSubmitRequest | ||||
| import com.ffii.fpsms.modules.jobOrder.web.model.SecondScanIssueRequest | import com.ffii.fpsms.modules.jobOrder.web.model.SecondScanIssueRequest | ||||
| import jakarta.servlet.http.HttpServletResponse | |||||
| import net.sf.jasperreports.engine.JasperExportManager | |||||
| import net.sf.jasperreports.engine.JasperPrint | |||||
| import org.aspectj.weaver.tools.UnsupportedPointcutPrimitiveException | |||||
| import org.springframework.context.NoSuchMessageException | |||||
| import java.io.OutputStream | |||||
| import java.io.UnsupportedEncodingException | |||||
| import java.text.ParseException | |||||
| @RestController | @RestController | ||||
| @RequestMapping("/jo") | @RequestMapping("/jo") | ||||
| class JobOrderController( | class JobOrderController( | ||||
| @@ -148,6 +158,18 @@ class JobOrderController( | |||||
| fun getCompletedJobOrderPickOrderLotDetails(@PathVariable pickOrderId: Long): List<Map<String, Any?>> { | fun getCompletedJobOrderPickOrderLotDetails(@PathVariable pickOrderId: Long): List<Map<String, Any?>> { | ||||
| return joPickOrderService.getCompletedJobOrderPickOrderLotDetails(pickOrderId) | return joPickOrderService.getCompletedJobOrderPickOrderLotDetails(pickOrderId) | ||||
| } | } | ||||
| @PostMapping("/PickRecord") | |||||
| @Throws(UnsupportedEncodingException::class, NoSuchMessageException::class, ParseException::class, Exception::class) | |||||
| fun printPickRecord(@Valid @RequestBody request: ExportPickRecordRequest, response: HttpServletResponse){ | |||||
| response.characterEncoding = "utf-8" | |||||
| response.contentType = "application/pdf" | |||||
| val out: OutputStream = response.outputStream | |||||
| val pdf = jobOrderService.exportPickRecord(request) | |||||
| val jasperPrint = pdf["report"] as JasperPrint | |||||
| response.addHeader("filename", "${pdf["filename"]}.pdf") | |||||
| out.write(JasperExportManager.exportReportToPdf(jasperPrint)) | |||||
| } | |||||
| @GetMapping("/completed-job-order-pick-orders-only/{userId}") | @GetMapping("/completed-job-order-pick-orders-only/{userId}") | ||||
| fun getCompletedJobOrderPickOrders(@PathVariable userId: Long): List<Map<String, Any?>> { | fun getCompletedJobOrderPickOrders(@PathVariable userId: Long): List<Map<String, Any?>> { | ||||
| return joPickOrderService.getCompletedJobOrderPickOrders(userId) | return joPickOrderService.getCompletedJobOrderPickOrders(userId) | ||||
| @@ -157,4 +179,4 @@ class JobOrderController( | |||||
| fun getCompletedJobOrderPickOrderLotDetailsForCompletedPick(@PathVariable pickOrderId: Long): List<Map<String, Any?>> { | fun getCompletedJobOrderPickOrderLotDetailsForCompletedPick(@PathVariable pickOrderId: Long): List<Map<String, Any?>> { | ||||
| return joPickOrderService.getCompletedJobOrderPickOrderLotDetailsForCompletedPick(pickOrderId) | return joPickOrderService.getCompletedJobOrderPickOrderLotDetailsForCompletedPick(pickOrderId) | ||||
| } | } | ||||
| } | |||||
| } | |||||
| @@ -0,0 +1,5 @@ | |||||
| package com.ffii.fpsms.modules.jobOrder.web.model | |||||
| data class ExportPickRecordRequest ( | |||||
| val jobOrderIds: Long, | |||||
| ) | |||||
| @@ -0,0 +1,4 @@ | |||||
| package com.ffii.fpsms.modules.jobOrder.web.model | |||||
| class PrintPickRecordRequest { | |||||
| } | |||||