From 0e0f311f806cf3c4ec6b8badaf245697bfc58278 Mon Sep 17 00:00:00 2001 From: "CANCERYS\\kw093" Date: Wed, 23 Sep 2026 13:12:33 +0800 Subject: [PATCH] po/do/jo settings --- .../service/DoFloorSupplierSettingsService.kt | 62 +++++++++++++++ .../service/DoWorkbenchMainService.kt | 56 +++++++++++-- .../service/JoWorkbenchMainService.kt | 8 +- .../service/JoWorkbenchPickConstants.kt | 4 +- .../ConsumableWorkbenchPickConstants.kt | 10 +-- .../service/PickOrderWorkbenchService.kt | 7 +- .../stock/service/SuggestedPickLotService.kt | 7 +- .../SuggestedPickLotWorkbenchService.kt | 15 ++-- .../20260922_auto_putaway/01_setting.sql | 79 +++++++++++++++++++ .../01_setting.sql | 30 +++++++ .../01_setting.sql | 8 ++ .../01_setting.sql | 28 +++++++ .../01_setting.sql | 29 +++++++ 13 files changed, 310 insertions(+), 33 deletions(-) create mode 100644 src/main/resources/db/changelog/changes/20260922_auto_putaway/01_setting.sql create mode 100644 src/main/resources/db/changelog/changes/20260922_auto_putaway_rules/01_setting.sql create mode 100644 src/main/resources/db/changelog/changes/20260922_auto_putaway_rules_drop_jo_fa/01_setting.sql create mode 100644 src/main/resources/db/changelog/changes/20260922_pick_exclude_print_mode/01_setting.sql create mode 100644 src/main/resources/db/changelog/changes/20260922_pick_exclude_warehouses/01_setting.sql diff --git a/src/main/java/com/ffii/fpsms/modules/deliveryOrder/service/DoFloorSupplierSettingsService.kt b/src/main/java/com/ffii/fpsms/modules/deliveryOrder/service/DoFloorSupplierSettingsService.kt index 76f0acfb..ba4b6a1a 100644 --- a/src/main/java/com/ffii/fpsms/modules/deliveryOrder/service/DoFloorSupplierSettingsService.kt +++ b/src/main/java/com/ffii/fpsms/modules/deliveryOrder/service/DoFloorSupplierSettingsService.kt @@ -1,5 +1,6 @@ package com.ffii.fpsms.modules.deliveryOrder.service +import com.ffii.fpsms.modules.jobOrder.service.JoWorkbenchPickConstants import com.ffii.fpsms.modules.settings.entity.SettingsRepository import org.springframework.stereotype.Service import java.util.Locale @@ -12,9 +13,22 @@ open class DoFloorSupplierSettingsService( companion object { private const val SETTING_DO_FLOOR_SUPPLIERS_2F = "DO.floor.suppliers.2F" private const val SETTING_DO_FLOOR_SUPPLIERS_4F = "DO.floor.suppliers.4F" + const val SETTING_DO_PICK_EXCLUDE_WAREHOUSES = "DO.pick.excludeWarehouses" + const val SETTING_JO_PICK_EXCLUDE_WAREHOUSES = "JO.pick.excludeWarehouses" + const val SETTING_DO_PICK_EXCLUDE_PRINT_MODE = "DO.pick.excludePrintMode" + const val SETTING_JO_PICK_EXCLUDE_PRINT_MODE = "JO.pick.excludePrintMode" + const val PRINT_MODE_HIDE_LIST = "hideList" + const val PRINT_MODE_HIDE_QR = "hideQr" + + /** Saved when the list is cleared. Settings update rejects a blank value. */ + const val EMPTY_CODE_LIST_MARKER = "-" private val DEFAULT_SUPPLIERS_2F = listOf("P07", "P06D", "P06Y") private val DEFAULT_SUPPLIERS_4F = listOf("P06B") + private val DEFAULT_DO_PICK_EXCLUDE_WAREHOUSES = listOf( + "2F-W202-01-00", + "2F-W200-#A-00", + ) } open fun supplierCodesFromSetting(settingName: String, defaultList: List): List { @@ -32,6 +46,54 @@ open class DoFloorSupplierSettingsService( return suppliers2F to suppliers4F } + /** DO pick / workbench default: lots in these warehouses are not suggested. */ + open fun loadDoPickExcludeWarehouseCodes(): Set = + warehouseCodesFromSettingOrDefault( + SETTING_DO_PICK_EXCLUDE_WAREHOUSES, + DEFAULT_DO_PICK_EXCLUDE_WAREHOUSES, + ) + + /** JO workbench (and consumable user 246): lots in these warehouses are not suggested. */ + open fun loadJoPickExcludeWarehouseCodes(): Set = + warehouseCodesFromSettingOrDefault( + SETTING_JO_PICK_EXCLUDE_WAREHOUSES, + JoWorkbenchPickConstants.DEFAULT_EXCLUDE_WAREHOUSE_CODES.toList(), + ) + + /** + * hideList: excluded warehouses are omitted from the print list, and scanning their physical QR does not pass. + * hideQr: they stay on the list without a QR, and scanning the physical QR still passes. + * Missing row is hideList. + */ + open fun loadDoPickExcludePrintMode(): String = printModeFromSetting(SETTING_DO_PICK_EXCLUDE_PRINT_MODE) + + open fun loadJoPickExcludePrintMode(): String = printModeFromSetting(SETTING_JO_PICK_EXCLUDE_PRINT_MODE) + + open fun rejectsScanOfExcludedWarehouse(printMode: String): Boolean = + printMode != PRINT_MODE_HIDE_QR + + private fun printModeFromSetting(settingName: String): String { + val raw = settingsRepository.findByName(settingName).map { it.value }.orElse(null)?.trim().orEmpty() + return if (raw == PRINT_MODE_HIDE_QR) PRINT_MODE_HIDE_QR else PRINT_MODE_HIDE_LIST + } + + /** + * Missing row uses [defaultList]. + * A saved blank value or [EMPTY_CODE_LIST_MARKER] means exclude nothing. + */ + open fun warehouseCodesFromSettingOrDefault(settingName: String, defaultList: List): Set { + val row = settingsRepository.findByName(settingName) + if (row.isEmpty) { + return defaultList.map { it.trim().uppercase(Locale.ROOT) }.filter { it.isNotEmpty() }.toSet() + } + val raw = row.get().value?.trim().orEmpty() + if (raw.isEmpty() || raw == EMPTY_CODE_LIST_MARKER) return emptySet() + return raw.split(",") + .map { it.trim().uppercase(Locale.ROOT) } + .filter { it.isNotEmpty() && it != EMPTY_CODE_LIST_MARKER } + .toSet() + } + open fun allowedSupplierCodesForFloor(floor: String?): List { val f = floor?.trim()?.uppercase(Locale.ROOT).orEmpty() val (codes2F, codes4F) = loadDoFloorSupplierLists() diff --git a/src/main/java/com/ffii/fpsms/modules/deliveryOrder/service/DoWorkbenchMainService.kt b/src/main/java/com/ffii/fpsms/modules/deliveryOrder/service/DoWorkbenchMainService.kt index e1563c53..66e874df 100644 --- a/src/main/java/com/ffii/fpsms/modules/deliveryOrder/service/DoWorkbenchMainService.kt +++ b/src/main/java/com/ffii/fpsms/modules/deliveryOrder/service/DoWorkbenchMainService.kt @@ -63,7 +63,6 @@ import com.ffii.fpsms.modules.deliveryOrder.web.models.ReleasedDoPickOrderListIt import com.ffii.fpsms.modules.deliveryOrder.web.models.WorkbenchTicketReleaseTableResponse import com.ffii.fpsms.modules.user.service.UserService import com.ffii.fpsms.modules.jobOrder.entity.JoPickOrderRepository -import com.ffii.fpsms.modules.jobOrder.service.JoWorkbenchPickConstants import com.ffii.fpsms.modules.pickOrder.entity.TruckRepository import kotlin.system.measureTimeMillis import org.slf4j.LoggerFactory @@ -246,9 +245,9 @@ open class DoWorkbenchMainService( /** * FP-MTMS Version Checklist | Functions Ref. No. 38 | v1.0.2 | 2026-08-13 * Warehouse exclude list for workbench **re-suggest** after scan-pick (shortfall / lot split). - * - JO: same list as assign ([JoWorkbenchPickConstants.DEFAULT_EXCLUDE_WAREHOUSE_CODES]). + * - JO: setting `JO.pick.excludeWarehouses` (fallback is JoWorkbenchPickConstants when the row is missing). * - Consumable: hardcoded user [ConsumableWorkbenchPickConstants.HARDCODED_EXCLUDE_USER_ID] → JO list; else empty (no limit). - * - DO / other: pass through request (`null` → service default excludes). + * - DO / other: pass through request (`null` → `DO.pick.excludeWarehouses`). */ private fun workbenchResuggestExcludeWarehouseCodes( pickOrderId: Long?, @@ -259,14 +258,49 @@ open class DoWorkbenchMainService( val resolvedType = poType ?: pickOrderId?.let { pickOrderRepository.findById(it).orElse(null)?.type } if (resolvedType == PickOrderType.JOB_ORDER) { - return JoWorkbenchPickConstants.DEFAULT_EXCLUDE_WAREHOUSE_CODES.toList() + return doFloorSupplierSettingsService.loadJoPickExcludeWarehouseCodes().toList() } if (resolvedType == PickOrderType.Consumable && userId != null) { - return ConsumableWorkbenchPickConstants.resolveExcludeWarehouseCodes(userId) + return ConsumableWorkbenchPickConstants.resolveExcludeWarehouseCodes( + userId, + doFloorSupplierSettingsService.loadJoPickExcludeWarehouseCodes(), + ) } return requestExcludeWarehouseCodes } + /** + * hideList: a lot in an excluded warehouse is not on the print list, and scanning its physical QR does not pass. + * hideQr: the lot stays on the list without a printed QR, and scanning the physical QR still passes. + */ + private fun rejectScanWhenWarehouseHiddenFromList( + pickOrderType: PickOrderType?, + userId: Long?, + warehouseCode: String?, + ): String? { + val code = warehouseCode?.trim()?.uppercase(Locale.ROOT).orEmpty() + if (code.isEmpty()) return null + val joCodes = doFloorSupplierSettingsService.loadJoPickExcludeWarehouseCodes() + val (codes, printMode) = when (pickOrderType) { + PickOrderType.JOB_ORDER -> joCodes to doFloorSupplierSettingsService.loadJoPickExcludePrintMode() + PickOrderType.Consumable -> { + val limited = if (userId == null) { + emptySet() + } else { + ConsumableWorkbenchPickConstants.resolveExcludeWarehouseCodes(userId, joCodes) + .map { it.uppercase(Locale.ROOT) } + .toSet() + } + limited to doFloorSupplierSettingsService.loadJoPickExcludePrintMode() + } + else -> doFloorSupplierSettingsService.loadDoPickExcludeWarehouseCodes() to + doFloorSupplierSettingsService.loadDoPickExcludePrintMode() + } + if (code !in codes) return null + if (!doFloorSupplierSettingsService.rejectsScanOfExcludedWarehouse(printMode)) return null + return "此儲位不在揀貨清單,掃到實物 QR 也不可以揀。" + } + /** * FP-MTMS Version Checklist | Functions Ref. No. 38 | v1.0.2 | 2026-08-13 * Workbench scan-pick (DO FG): @@ -450,6 +484,18 @@ open class DoWorkbenchMainService( println("Scanned lot does not match pick line item") } + val hiddenWarehouseReject = rejectScanWhenWarehouseHiddenFromList( + pickOrderType = pol.pickOrder?.type, + userId = request.userId, + warehouseCode = scannedIll.warehouse?.code, + ) + if (hiddenWarehouseReject != null) { + return MessageResponse( + id = sol.id, name = "scan_pick", code = "INVALID", type = "workbench_scan_pick", + message = hiddenWarehouseReject, errorPosition = null, entity = null, + ) + } + sol.inventoryLotLine = scannedIll val required = pol.qty ?: BigDecimal.ZERO diff --git a/src/main/java/com/ffii/fpsms/modules/jobOrder/service/JoWorkbenchMainService.kt b/src/main/java/com/ffii/fpsms/modules/jobOrder/service/JoWorkbenchMainService.kt index a2ef1724..5715b817 100644 --- a/src/main/java/com/ffii/fpsms/modules/jobOrder/service/JoWorkbenchMainService.kt +++ b/src/main/java/com/ffii/fpsms/modules/jobOrder/service/JoWorkbenchMainService.kt @@ -1,5 +1,6 @@ package com.ffii.fpsms.modules.jobOrder.service +import com.ffii.fpsms.modules.deliveryOrder.service.DoFloorSupplierSettingsService import com.ffii.fpsms.modules.jobOrder.entity.JoPickOrderRepository import com.ffii.fpsms.modules.jobOrder.entity.JobOrderRepository import com.ffii.fpsms.modules.jobOrder.enums.JobOrderStatus @@ -50,9 +51,8 @@ open class JoWorkbenchMainService( private val stockOutRepository: StockOutRepository, private val suggestedPickLotWorkbenchService: SuggestedPickLotWorkbenchService, private val stockOutLineWorkbenchService: StockOutLineWorkbenchService, + private val doFloorSupplierSettingsService: DoFloorSupplierSettingsService, ) { - private val workbenchDefaultExcludeWarehouseCodes: Set = - JoWorkbenchPickConstants.DEFAULT_EXCLUDE_WAREHOUSE_CODES private fun debugPrintSuggestionNullReasons(pickOrderId: Long) { val pickOrder = pickOrderRepository.findById(pickOrderId).orElse(null) ?: return @@ -80,7 +80,7 @@ open class JoWorkbenchMainService( val notExpired = availableStatus.filter { it.inventoryLot?.expiryDate?.isBefore(today) != true } val notExcluded = notExpired.filter { lot -> val code = lot.warehouse?.code?.trim()?.uppercase(Locale.ROOT) - code.isNullOrEmpty() || code !in workbenchDefaultExcludeWarehouseCodes + code.isNullOrEmpty() || code !in doFloorSupplierSettingsService.loadJoPickExcludeWarehouseCodes() } val positiveQty = notExcluded.filter { lot -> val inQ = lot.inQty ?: BigDecimal.ZERO @@ -539,7 +539,7 @@ open class JoWorkbenchMainService( suggestedPickLotWorkbenchService.primeNextSingleLotSuggestionsForPickOrder( pickOrderId = pickOrderId, storeId = null, - excludeWarehouseCodes = workbenchDefaultExcludeWarehouseCodes.toList() + excludeWarehouseCodes = doFloorSupplierSettingsService.loadJoPickExcludeWarehouseCodes().toList() ) stockOutLineWorkbenchService.ensureStockOutLinesForPickOrderNoHold(pickOrderId, userId) val splAfter = loadSplDebugRowsByPol(pickOrderId) diff --git a/src/main/java/com/ffii/fpsms/modules/jobOrder/service/JoWorkbenchPickConstants.kt b/src/main/java/com/ffii/fpsms/modules/jobOrder/service/JoWorkbenchPickConstants.kt index 727c54a0..81c789b7 100644 --- a/src/main/java/com/ffii/fpsms/modules/jobOrder/service/JoWorkbenchPickConstants.kt +++ b/src/main/java/com/ffii/fpsms/modules/jobOrder/service/JoWorkbenchPickConstants.kt @@ -3,8 +3,8 @@ package com.ffii.fpsms.modules.jobOrder.service /** * JO workbench pick constants. * - * [DEFAULT_EXCLUDE_WAREHOUSE_CODES] applies on **assign / first prime** ([JoWorkbenchMainService]) - * and on **scan-pick re-suggest** ([com.ffii.fpsms.modules.deliveryOrder.service.DoWorkbenchMainService]). + * [DEFAULT_EXCLUDE_WAREHOUSE_CODES] is the fallback when setting `JO.pick.excludeWarehouses` is missing. + * Assign / first prime and scan-pick re-suggest read the setting at runtime. * JO re-suggest keeps [storeId] null (same as assign); it does not use DO floor store resolution. */ object JoWorkbenchPickConstants { diff --git a/src/main/java/com/ffii/fpsms/modules/pickOrder/service/ConsumableWorkbenchPickConstants.kt b/src/main/java/com/ffii/fpsms/modules/pickOrder/service/ConsumableWorkbenchPickConstants.kt index caaadd87..a2b7f6df 100644 --- a/src/main/java/com/ffii/fpsms/modules/pickOrder/service/ConsumableWorkbenchPickConstants.kt +++ b/src/main/java/com/ffii/fpsms/modules/pickOrder/service/ConsumableWorkbenchPickConstants.kt @@ -1,21 +1,19 @@ package com.ffii.fpsms.modules.pickOrder.service -import com.ffii.fpsms.modules.jobOrder.service.JoWorkbenchPickConstants - /** * Temporary consumable workbench exclude list until per-user DB config (Scheme A) lands. * - * - [HARDCODED_EXCLUDE_USER_ID] → same warehouses as JO ([JoWorkbenchPickConstants]). + * - [HARDCODED_EXCLUDE_USER_ID] → the JO exclude list passed in (setting `JO.pick.excludeWarehouses`). * - All other users → empty list (no warehouse limit). Do not return null: - * [SuggestedPickLotWorkbenchService] treats null as DO default 2F excludes. + * [com.ffii.fpsms.modules.stock.service.SuggestedPickLotWorkbenchService] treats null as the DO exclude setting. * Consumable re-suggest keeps storeId null (same as first prime / JO); it does not use DO floor store resolution. */ object ConsumableWorkbenchPickConstants { const val HARDCODED_EXCLUDE_USER_ID: Long = 246L /** FP-MTMS Version Checklist | Functions Ref. No. 66 | v1.0.0 | 2026-08-13 */ - fun resolveExcludeWarehouseCodes(userId: Long): List { + fun resolveExcludeWarehouseCodes(userId: Long, joExcludeWarehouseCodes: Collection): List { if (userId != HARDCODED_EXCLUDE_USER_ID) return emptyList() - return JoWorkbenchPickConstants.DEFAULT_EXCLUDE_WAREHOUSE_CODES.toList() + return joExcludeWarehouseCodes.map { it.trim() }.filter { it.isNotEmpty() } } } diff --git a/src/main/java/com/ffii/fpsms/modules/pickOrder/service/PickOrderWorkbenchService.kt b/src/main/java/com/ffii/fpsms/modules/pickOrder/service/PickOrderWorkbenchService.kt index 6cc90c60..9b161280 100644 --- a/src/main/java/com/ffii/fpsms/modules/pickOrder/service/PickOrderWorkbenchService.kt +++ b/src/main/java/com/ffii/fpsms/modules/pickOrder/service/PickOrderWorkbenchService.kt @@ -1,6 +1,7 @@ package com.ffii.fpsms.modules.pickOrder.service import com.ffii.core.support.JdbcDao +import com.ffii.fpsms.modules.deliveryOrder.service.DoFloorSupplierSettingsService import com.ffii.fpsms.modules.master.web.models.MessageResponse import com.ffii.fpsms.modules.pickOrder.entity.PickOrderLineRepository import com.ffii.fpsms.modules.pickOrder.entity.PickOrderRepository @@ -23,6 +24,7 @@ open class PickOrderWorkbenchService( private val userService: UserService, private val suggestedPickLotWorkbenchService: SuggestedPickLotWorkbenchService, private val stockOutLineWorkbenchService: StockOutLineWorkbenchService, + private val doFloorSupplierSettingsService: DoFloorSupplierSettingsService, ) { private fun toBigDecimal(v: Any?): BigDecimal? = when (v) { null -> null @@ -447,7 +449,10 @@ open class PickOrderWorkbenchService( val excludeWarehouseCodes = if (pickOrder.type == PickOrderType.Consumable) { - ConsumableWorkbenchPickConstants.resolveExcludeWarehouseCodes(userId) + ConsumableWorkbenchPickConstants.resolveExcludeWarehouseCodes( + userId, + doFloorSupplierSettingsService.loadJoPickExcludeWarehouseCodes(), + ) } else { null } 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 507b100a..cb71568c 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 @@ -106,10 +106,7 @@ open class SuggestedPickLotService( val suggestedList: MutableList = mutableListOf() val holdQtyMap: MutableMap = request.holdQtyMap - val excludedWarehouseCodes = setOf( - "2F-W202-01-00", - "2F-W200-#A-00", - ) + val excludedWarehouseCodes = doFloorSupplierSettingsService.loadDoPickExcludeWarehouseCodes() val availableInventoryLotLines = inventoryLotLineService .allInventoryLotLinesByItemIdIn(itemIds) .filter { it.status == InventoryLotLineStatus.AVAILABLE.value } @@ -173,7 +170,7 @@ open class SuggestedPickLotService( val warehouseStoreId=inventoryLotLine?.warehouse?.store_id // 3F filter only applies to delivery order release; no limit for job order, AssignAndRelease, etc. val isDeliveryOrderPick = line.pickOrder?.type?.value == "do" - val warehouseCodeForExclusion = inventoryLotLine?.warehouse?.code + val warehouseCodeForExclusion = inventoryLotLine?.warehouse?.code?.trim()?.uppercase(java.util.Locale.ROOT) if (isDeliveryOrderPick && warehouseCodeForExclusion != null && excludedWarehouseCodes.contains(warehouseCodeForExclusion) diff --git a/src/main/java/com/ffii/fpsms/modules/stock/service/SuggestedPickLotWorkbenchService.kt b/src/main/java/com/ffii/fpsms/modules/stock/service/SuggestedPickLotWorkbenchService.kt index 50f02a6c..2eb5e4e4 100644 --- a/src/main/java/com/ffii/fpsms/modules/stock/service/SuggestedPickLotWorkbenchService.kt +++ b/src/main/java/com/ffii/fpsms/modules/stock/service/SuggestedPickLotWorkbenchService.kt @@ -1,5 +1,6 @@ package com.ffii.fpsms.modules.stock.service +import com.ffii.fpsms.modules.deliveryOrder.service.DoFloorSupplierSettingsService import com.ffii.fpsms.modules.pickOrder.entity.PickOrderLine import com.ffii.fpsms.modules.pickOrder.entity.PickOrderLineRepository import com.ffii.fpsms.modules.stock.entity.InventoryLotLine @@ -29,6 +30,7 @@ open class SuggestedPickLotWorkbenchService( private val inventoryLotLineRepository: InventoryLotLineRepository, private val stockOutLIneRepository: StockOutLIneRepository, private val suggestPickLotRepository: SuggestPickLotRepository, + private val doFloorSupplierSettingsService: DoFloorSupplierSettingsService, ) { private val log = LoggerFactory.getLogger(SuggestedPickLotWorkbenchService::class.java) @@ -126,16 +128,9 @@ open class SuggestedPickLotWorkbenchService( } /** - * Backend-default avoid warehouse list for workbench suggestions. - * - Case-insensitive match against `warehouse.code`. - * - When request.excludeWarehouseCodes is provided, it overrides this default. - * - * Keep it empty if you don't need any default excludes. + * DO workbench default exclude list comes from settings (`DO.pick.excludeWarehouses`). + * When request.excludeWarehouseCodes is provided, it overrides that list. */ - private val defaultExcludeWarehouseCodes: Set = setOf( - "2F-W202-01-00", - "2F-W200-#A-00", -) private fun normalizeStoreId(raw: String?): String? { val s = raw?.trim()?.uppercase() ?: return null if (s.isEmpty()) return null @@ -149,7 +144,7 @@ open class SuggestedPickLotWorkbenchService( } private fun effectiveExcludeWarehouseCodes(raw: List?): Set { - if (raw == null) return defaultExcludeWarehouseCodes + if (raw == null) return doFloorSupplierSettingsService.loadDoPickExcludeWarehouseCodes() val normalized = raw .map { it.trim() } .filter { it.isNotEmpty() } diff --git a/src/main/resources/db/changelog/changes/20260922_auto_putaway/01_setting.sql b/src/main/resources/db/changelog/changes/20260922_auto_putaway/01_setting.sql new file mode 100644 index 00000000..7845039c --- /dev/null +++ b/src/main/resources/db/changelog/changes/20260922_auto_putaway/01_setting.sql @@ -0,0 +1,79 @@ +--liquibase formatted sql +--changeset fpsms:20260922_auto_putaway + +-- QC accept auto put-away. Warehouse 2F-W200-#A-00 is warehouse id 1141. +-- Item keyword FA matches item codes that contain FA. +-- JO also auto put-away when BOM description is WIP or FG. +-- "-" means that list is empty (condition off, or no fallback warehouse). + +INSERT INTO `settings` (`name`, `value`, `category`, `type`) +SELECT v.name, v.value, v.category, v.type +FROM ( + SELECT 'PO.autoPutAway.warehouse' AS name, + '2F-W200-#A-00' AS value, + 'PICK_RULES' AS category, + 'string' AS type +) v +WHERE NOT EXISTS ( + SELECT 1 FROM `settings` s WHERE s.name = 'PO.autoPutAway.warehouse' +); + +INSERT INTO `settings` (`name`, `value`, `category`, `type`) +SELECT v.name, v.value, v.category, v.type +FROM ( + SELECT 'PO.autoPutAway.itemKeywords' AS name, + 'FA' AS value, + 'PICK_RULES' AS category, + 'string' AS type +) v +WHERE NOT EXISTS ( + SELECT 1 FROM `settings` s WHERE s.name = 'PO.autoPutAway.itemKeywords' +); + +INSERT INTO `settings` (`name`, `value`, `category`, `type`) +SELECT v.name, v.value, v.category, v.type +FROM ( + SELECT 'PO.autoPutAway.bomTypes' AS name, + '-' AS value, + 'PICK_RULES' AS category, + 'string' AS type +) v +WHERE NOT EXISTS ( + SELECT 1 FROM `settings` s WHERE s.name = 'PO.autoPutAway.bomTypes' +); + +INSERT INTO `settings` (`name`, `value`, `category`, `type`) +SELECT v.name, v.value, v.category, v.type +FROM ( + SELECT 'JO.autoPutAway.warehouse' AS name, + '2F-W200-#A-00' AS value, + 'PICK_RULES' AS category, + 'string' AS type +) v +WHERE NOT EXISTS ( + SELECT 1 FROM `settings` s WHERE s.name = 'JO.autoPutAway.warehouse' +); + +INSERT INTO `settings` (`name`, `value`, `category`, `type`) +SELECT v.name, v.value, v.category, v.type +FROM ( + SELECT 'JO.autoPutAway.itemKeywords' AS name, + 'FA' AS value, + 'PICK_RULES' AS category, + 'string' AS type +) v +WHERE NOT EXISTS ( + SELECT 1 FROM `settings` s WHERE s.name = 'JO.autoPutAway.itemKeywords' +); + +INSERT INTO `settings` (`name`, `value`, `category`, `type`) +SELECT v.name, v.value, v.category, v.type +FROM ( + SELECT 'JO.autoPutAway.bomTypes' AS name, + 'WIP,FG' AS value, + 'PICK_RULES' AS category, + 'string' AS type +) v +WHERE NOT EXISTS ( + SELECT 1 FROM `settings` s WHERE s.name = 'JO.autoPutAway.bomTypes' +); diff --git a/src/main/resources/db/changelog/changes/20260922_auto_putaway_rules/01_setting.sql b/src/main/resources/db/changelog/changes/20260922_auto_putaway_rules/01_setting.sql new file mode 100644 index 00000000..91ef3629 --- /dev/null +++ b/src/main/resources/db/changelog/changes/20260922_auto_putaway_rules/01_setting.sql @@ -0,0 +1,30 @@ +--liquibase formatted sql +--changeset fpsms:20260922_auto_putaway_rules + +-- Multiple auto put-away rules. Empty itemKeywords means every item. +-- locationMode itemLocation uses the item location code. warehouse uses warehouseCode. +-- First matching rule wins. whitelist puts away. blacklist does not. + +INSERT INTO `settings` (`name`, `value`, `category`, `type`) +SELECT v.name, v.value, v.category, v.type +FROM ( + SELECT 'PO.autoPutAway.rules' AS name, + '[{"itemKeywords":"FA","bomTypes":"","locationMode":"warehouse","warehouseCode":"2F-W200-#A-00","listMode":"whitelist"}]' AS value, + 'PICK_RULES' AS category, + 'string' AS type +) v +WHERE NOT EXISTS ( + SELECT 1 FROM `settings` s WHERE s.name = 'PO.autoPutAway.rules' +); + +INSERT INTO `settings` (`name`, `value`, `category`, `type`) +SELECT v.name, v.value, v.category, v.type +FROM ( + SELECT 'JO.autoPutAway.rules' AS name, + '[{"itemKeywords":"","bomTypes":"FG","locationMode":"itemLocation","warehouseCode":"2F-W200-#A-00","listMode":"whitelist"},{"itemKeywords":"","bomTypes":"WIP","locationMode":"warehouse","warehouseCode":"2F-W200-#A-00","listMode":"whitelist"}]' AS value, + 'PICK_RULES' AS category, + 'string' AS type +) v +WHERE NOT EXISTS ( + SELECT 1 FROM `settings` s WHERE s.name = 'JO.autoPutAway.rules' +); diff --git a/src/main/resources/db/changelog/changes/20260922_auto_putaway_rules_drop_jo_fa/01_setting.sql b/src/main/resources/db/changelog/changes/20260922_auto_putaway_rules_drop_jo_fa/01_setting.sql new file mode 100644 index 00000000..3d7839bc --- /dev/null +++ b/src/main/resources/db/changelog/changes/20260922_auto_putaway_rules_drop_jo_fa/01_setting.sql @@ -0,0 +1,8 @@ +--liquibase formatted sql +--changeset fpsms:20260922_auto_putaway_rules_drop_jo_fa + +-- Job order auto put-away does not include an item-code FA rule. +UPDATE `settings` +SET `value` = '[{"itemKeywords":"","bomTypes":"FG","locationMode":"itemLocation","warehouseCode":"2F-W200-#A-00","listMode":"whitelist"},{"itemKeywords":"","bomTypes":"WIP","locationMode":"warehouse","warehouseCode":"2F-W200-#A-00","listMode":"whitelist"}]' +WHERE `name` = 'JO.autoPutAway.rules' + AND `value` = '[{"itemKeywords":"","bomTypes":"FG","locationMode":"itemLocation","warehouseCode":"2F-W200-#A-00","listMode":"whitelist"},{"itemKeywords":"","bomTypes":"WIP","locationMode":"warehouse","warehouseCode":"2F-W200-#A-00","listMode":"whitelist"},{"itemKeywords":"FA","bomTypes":"","locationMode":"warehouse","warehouseCode":"2F-W200-#A-00","listMode":"whitelist"}]'; diff --git a/src/main/resources/db/changelog/changes/20260922_pick_exclude_print_mode/01_setting.sql b/src/main/resources/db/changelog/changes/20260922_pick_exclude_print_mode/01_setting.sql new file mode 100644 index 00000000..5c139fcd --- /dev/null +++ b/src/main/resources/db/changelog/changes/20260922_pick_exclude_print_mode/01_setting.sql @@ -0,0 +1,28 @@ +--liquibase formatted sql +--changeset fpsms:20260922_pick_exclude_print_mode + +-- hideList: print modal omits these warehouses. hideQr: list them but hide QR. + +INSERT INTO `settings` (`name`, `value`, `category`, `type`) +SELECT v.name, v.value, v.category, v.type +FROM ( + SELECT 'DO.pick.excludePrintMode' AS name, + 'hideList' AS value, + 'PICK_RULES' AS category, + 'string' AS type +) v +WHERE NOT EXISTS ( + SELECT 1 FROM `settings` s WHERE s.name = 'DO.pick.excludePrintMode' +); + +INSERT INTO `settings` (`name`, `value`, `category`, `type`) +SELECT v.name, v.value, v.category, v.type +FROM ( + SELECT 'JO.pick.excludePrintMode' AS name, + 'hideList' AS value, + 'PICK_RULES' AS category, + 'string' AS type +) v +WHERE NOT EXISTS ( + SELECT 1 FROM `settings` s WHERE s.name = 'JO.pick.excludePrintMode' +); diff --git a/src/main/resources/db/changelog/changes/20260922_pick_exclude_warehouses/01_setting.sql b/src/main/resources/db/changelog/changes/20260922_pick_exclude_warehouses/01_setting.sql new file mode 100644 index 00000000..ab846dbf --- /dev/null +++ b/src/main/resources/db/changelog/changes/20260922_pick_exclude_warehouses/01_setting.sql @@ -0,0 +1,29 @@ +--liquibase formatted sql +--changeset fpsms:20260922_pick_exclude_warehouses + +-- DO / JO pick exclude warehouse codes (comma-separated). "-" means exclude nothing. +-- Missing row falls back to the same defaults in DoFloorSupplierSettingsService. + +INSERT INTO `settings` (`name`, `value`, `category`, `type`) +SELECT v.name, v.value, v.category, v.type +FROM ( + SELECT 'DO.pick.excludeWarehouses' AS name, + '2F-W202-01-00,2F-W200-#A-00' AS value, + 'PICK_RULES' AS category, + 'string' AS type +) v +WHERE NOT EXISTS ( + SELECT 1 FROM `settings` s WHERE s.name = 'DO.pick.excludeWarehouses' +); + +INSERT INTO `settings` (`name`, `value`, `category`, `type`) +SELECT v.name, v.value, v.category, v.type +FROM ( + SELECT 'JO.pick.excludeWarehouses' AS name, + '4F-W402-01-00,4F-W402-02-00,4F-W402-03-00,4F-W402-04-00,4F-W402-05-00,4F-W402-#A-00,4F-W402-#B-00,4F-W402-#C-00,4F-W402-#D-00,4F-W402-#E-00,4F-W402-#F-00,4F-W402-#G-00,4F-W402-#H-00,4F-W402-#I-00,4F-W402-#J-00,4F-W402-#K-00,4F-W402-#L-00,4F-W402-#M-00,4F-W402-#N-00,4F-W402-#O-00,4F-W402-#P-00,4F-W402-#Q-00,4F-W402-#R-00,4F-W402-#S-00' AS value, + 'PICK_RULES' AS category, + 'string' AS type +) v +WHERE NOT EXISTS ( + SELECT 1 FROM `settings` s WHERE s.name = 'JO.pick.excludeWarehouses' +);