| @@ -1770,7 +1770,7 @@ private fun normalizeFloor(raw: String): String { | |||||
| val num = cleaned.replace(Regex("[^0-9]"), "") | val num = cleaned.replace(Regex("[^0-9]"), "") | ||||
| return if (num.isNotEmpty()) "${num}F" else cleaned | return if (num.isNotEmpty()) "${num}F" else cleaned | ||||
| } | } | ||||
| open fun getAllJoPickOrders(isDrink: Boolean?, floor: String?): List<AllJoPickOrderResponse> { | |||||
| open fun getAllJoPickOrders(bomType: String?, floor: String?): List<AllJoPickOrderResponse> { | |||||
| println("=== getAllJoPickOrders ===") | println("=== getAllJoPickOrders ===") | ||||
| return try { | return try { | ||||
| @@ -1879,8 +1879,12 @@ open fun getAllJoPickOrders(isDrink: Boolean?, floor: String?): List<AllJoPickOr | |||||
| val bom = jobOrder.bom | val bom = jobOrder.bom | ||||
| // 按 isDrink 过滤:null 表示不过滤(全部) | |||||
| if (isDrink != null && bom?.isDrink != isDrink) return@mapNotNull null | |||||
| // 按 bom.type 过滤:null / blank 表示不过滤(全部) | |||||
| val normalizedType = bomType?.trim()?.lowercase()?.takeIf { it.isNotBlank() } | |||||
| if (normalizedType != null) { | |||||
| val currentType = bom?.type?.trim()?.lowercase() | |||||
| if (currentType != normalizedType) return@mapNotNull null | |||||
| } | |||||
| println("BOM found: ${bom?.id}") | println("BOM found: ${bom?.id}") | ||||
| val item = bom?.item | val item = bom?.item | ||||
| @@ -243,12 +243,12 @@ fun recordSecondScanIssue( | |||||
| } | } | ||||
| @GetMapping("/AllJoPickOrder") | @GetMapping("/AllJoPickOrder") | ||||
| fun getAllJoPickOrder( | fun getAllJoPickOrder( | ||||
| @RequestParam(required = false) isDrink: Boolean?, | |||||
| @RequestParam(name = "type", required = false) bomType: String?, | |||||
| // Single floor, e.g. "2F"/"3F"/"4F". When provided, backend returns job pick orders | // Single floor, e.g. "2F"/"3F"/"4F". When provided, backend returns job pick orders | ||||
| // that still have unpicked lines on that floor OR any "no lot" remaining lines. | // that still have unpicked lines on that floor OR any "no lot" remaining lines. | ||||
| @RequestParam(required = false) floor: String? | @RequestParam(required = false) floor: String? | ||||
| ): List<AllJoPickOrderResponse> { | ): List<AllJoPickOrderResponse> { | ||||
| return joPickOrderService.getAllJoPickOrders(isDrink, floor) | |||||
| return joPickOrderService.getAllJoPickOrders(bomType, floor) | |||||
| } | } | ||||
| @GetMapping("/all-lots-hierarchical-by-pick-order/{pickOrderId}") | @GetMapping("/all-lots-hierarchical-by-pick-order/{pickOrderId}") | ||||
| @@ -28,6 +28,8 @@ open class Bom : BaseEntity<Long>() { | |||||
| @Column | @Column | ||||
| open var allergicSubstances: Int? = null | open var allergicSubstances: Int? = null | ||||
| @Column | |||||
| open var type: String? = null | |||||
| @Column | @Column | ||||
| open var timeSequence: Int? = null | open var timeSequence: Int? = null | ||||
| @Column | @Column | ||||
| @@ -1407,11 +1407,15 @@ open class ProductProcessService( | |||||
| ) | ) | ||||
| } | } | ||||
| open fun getAllJoborderProductProcessInfo(isDrink: Boolean?): List<AllJoborderProductProcessInfoResponse> { | |||||
| open fun getAllJoborderProductProcessInfo(bomType: String?): List<AllJoborderProductProcessInfoResponse> { | |||||
| val productProcesses = productProcessRepository.findAllByDeletedIsFalse() | val productProcesses = productProcessRepository.findAllByDeletedIsFalse() | ||||
| val productProcessIds = productProcesses.map { it.id } | |||||
| val normalizedType = bomType?.trim()?.lowercase()?.takeIf { it.isNotBlank() } | |||||
| val filteredProductProcesses = productProcesses.filter { process -> | |||||
| if (normalizedType == null) return@filter true | |||||
| process.bom?.type?.trim()?.lowercase() == normalizedType | |||||
| } | |||||
| return productProcesses.map { productProcesses -> | |||||
| return filteredProductProcesses.map { productProcesses -> | |||||
| val productProcessLines = productProcessLineRepository.findByProductProcess_Id(productProcesses.id ?: 0L) | val productProcessLines = productProcessLineRepository.findByProductProcess_Id(productProcesses.id ?: 0L) | ||||
| val jobOrder = jobOrderRepository.findById(productProcesses.jobOrder?.id ?: 0L).orElse(null) | val jobOrder = jobOrderRepository.findById(productProcesses.jobOrder?.id ?: 0L).orElse(null) | ||||
| val FinishedProductProcessLineCount = | val FinishedProductProcessLineCount = | ||||
| @@ -1478,9 +1482,6 @@ open class ProductProcessService( | |||||
| ) | ) | ||||
| }.filter { response -> | }.filter { response -> | ||||
| // 过滤掉已完成上架的 job order | // 过滤掉已完成上架的 job order | ||||
| if (isDrink != null && response.isDrink != isDrink) { | |||||
| return@filter false | |||||
| } | |||||
| val jobOrder = jobOrderRepository.findById(response.jobOrderId ?: 0L).orElse(null) | val jobOrder = jobOrderRepository.findById(response.jobOrderId ?: 0L).orElse(null) | ||||
| val stockInLineStatus = jobOrder?.stockInLines?.firstOrNull()?.status | val stockInLineStatus = jobOrder?.stockInLines?.firstOrNull()?.status | ||||
| stockInLineStatus != "completed" | stockInLineStatus != "completed" | ||||
| @@ -1504,7 +1505,7 @@ open class ProductProcessService( | |||||
| jobOrderCode: String?, | jobOrderCode: String?, | ||||
| bomIds: List<Long>?, | bomIds: List<Long>?, | ||||
| qcReady: Boolean?, | qcReady: Boolean?, | ||||
| isDrink: Boolean?, | |||||
| bomType: String?, | |||||
| page: Int, | page: Int, | ||||
| size: Int | size: Int | ||||
| ): JobOrderProductProcessPageResponse { | ): JobOrderProductProcessPageResponse { | ||||
| @@ -1514,7 +1515,7 @@ open class ProductProcessService( | |||||
| val trimmedItemCode = itemCode?.trim()?.takeIf { it.isNotBlank() } | val trimmedItemCode = itemCode?.trim()?.takeIf { it.isNotBlank() } | ||||
| val trimmedJobOrderCode = jobOrderCode?.trim()?.takeIf { it.isNotBlank() } | val trimmedJobOrderCode = jobOrderCode?.trim()?.takeIf { it.isNotBlank() } | ||||
| // 1) 找出候选 jobOrder:用 date/itemCode/jobOrderCode/bomIds/isDrink 先把数据缩小到今天等范围 | |||||
| // 1) 找出候选 jobOrder:用 date/itemCode/jobOrderCode/bomIds/type 先把数据缩小到今天等范围 | |||||
| val candidateProcesses = if (date != null) { | val candidateProcesses = if (date != null) { | ||||
| productProcessRepository.findAllByDeletedIsFalseAndDate(date) | productProcessRepository.findAllByDeletedIsFalseAndDate(date) | ||||
| } else { | } else { | ||||
| @@ -1523,9 +1524,10 @@ open class ProductProcessService( | |||||
| val filteredCandidateProcesses = candidateProcesses.filter { p -> | val filteredCandidateProcesses = candidateProcesses.filter { p -> | ||||
| if (p.jobOrder?.isHidden == true) return@filter false | if (p.jobOrder?.isHidden == true) return@filter false | ||||
| if (isDrink != null) { | |||||
| val bomIsDrink = p.bom?.isDrink | |||||
| if (bomIsDrink != isDrink) return@filter false | |||||
| val normalizedType = bomType?.trim()?.lowercase()?.takeIf { it.isNotBlank() } | |||||
| if (normalizedType != null) { | |||||
| val currentType = p.bom?.type?.trim()?.lowercase() | |||||
| if (currentType != normalizedType) return@filter false | |||||
| } | } | ||||
| if (trimmedItemCode != null) { | if (trimmedItemCode != null) { | ||||
| val code = p.item?.code | val code = p.item?.code | ||||
| @@ -194,9 +194,9 @@ class ProductProcessController( | |||||
| @GetMapping("/Demo/Process/all") | @GetMapping("/Demo/Process/all") | ||||
| fun demoprocessall( | fun demoprocessall( | ||||
| @RequestParam(required = false) isDrink: Boolean? | |||||
| @RequestParam(name = "type", required = false) bomType: String? | |||||
| ): List<AllJoborderProductProcessInfoResponse> { | ): List<AllJoborderProductProcessInfoResponse> { | ||||
| return productProcessService.getAllJoborderProductProcessInfo(isDrink) | |||||
| return productProcessService.getAllJoborderProductProcessInfo(bomType) | |||||
| } | } | ||||
| @GetMapping("/Demo/Process/search") | @GetMapping("/Demo/Process/search") | ||||
| @@ -206,7 +206,7 @@ class ProductProcessController( | |||||
| @RequestParam(required = false) jobOrderCode: String?, | @RequestParam(required = false) jobOrderCode: String?, | ||||
| @RequestParam(required = false) bomIds: String?, | @RequestParam(required = false) bomIds: String?, | ||||
| @RequestParam(required = false) qcReady: Boolean?, | @RequestParam(required = false) qcReady: Boolean?, | ||||
| @RequestParam(required = false) isDrink: Boolean?, | |||||
| @RequestParam(name = "type", required = false) bomType: String?, | |||||
| @RequestParam(defaultValue = "0") page: Int, | @RequestParam(defaultValue = "0") page: Int, | ||||
| @RequestParam(defaultValue = "50") size: Int | @RequestParam(defaultValue = "50") size: Int | ||||
| ): JobOrderProductProcessPageResponse { | ): JobOrderProductProcessPageResponse { | ||||
| @@ -225,7 +225,7 @@ class ProductProcessController( | |||||
| jobOrderCode = jobOrderCode, | jobOrderCode = jobOrderCode, | ||||
| bomIds = parsedBomIds, | bomIds = parsedBomIds, | ||||
| qcReady = qcReady, | qcReady = qcReady, | ||||
| isDrink = isDrink, | |||||
| bomType = bomType, | |||||
| page = page, | page = page, | ||||
| size = size | size = size | ||||
| ) | ) | ||||
| @@ -0,0 +1,9 @@ | |||||
| -- liquibase formatted sql | |||||
| -- changeset Enson:alter_bom_type | |||||
| -- preconditions onFail:MARK_RAN | |||||
| -- precondition-sql-check expectedResult:0 SELECT COUNT(*) FROM information_schema.columns WHERE table_schema='fpsmsdb' AND table_name='bom' AND column_name='type' | |||||
| ALTER TABLE `fpsmsdb`.`bom` | |||||
| Add COLUMN `type` varchar(255); | |||||
| @@ -0,0 +1,15 @@ | |||||
| -- liquibase formatted sql | |||||
| -- changeset Enson:update_bom_type_by_code_and_isDrink_20260408 | |||||
| UPDATE `fpsmsdb`.`bom` | |||||
| SET `type` = CASE | |||||
| WHEN isDrink = 1 THEN 'Drink' | |||||
| WHEN code IN ( | |||||
| 'PP2255','PP2257','PP2258','PP2259','PP2261','PP2263','PP2264','PP2266', | |||||
| 'PP2270','PP2275','PP2280','PP2281','PP2283', | |||||
| 'PP2291','PP2295','PP2296','PP2297','PP2299','PP2302','PP2303','PP2304', | |||||
| 'PP2305','PP2339','PP2340' | |||||
| ) THEN 'Powder_Mixture' | |||||
| ELSE 'Other' | |||||
| END | |||||
| WHERE `type` IS NULL OR `type` = ''; | |||||