|
|
|
@@ -45,6 +45,7 @@ import java.time.LocalDate |
|
|
|
import com.ffii.fpsms.modules.stock.entity.InventoryLotLine |
|
|
|
import java.math.RoundingMode |
|
|
|
import com.ffii.fpsms.modules.stock.entity.StockTake |
|
|
|
import com.ffii.fpsms.modules.master.entity.ItemsRepository |
|
|
|
@Service |
|
|
|
class StockTakeRecordService( |
|
|
|
val stockTakeRepository: StockTakeRepository, |
|
|
|
@@ -61,7 +62,8 @@ class StockTakeRecordService( |
|
|
|
val inventoryLotRepository: InventoryLotRepository, |
|
|
|
val stockLedgerRepository: StockLedgerRepository, |
|
|
|
val inventoryRepository: InventoryRepository, |
|
|
|
val uomConversionRepository: UomConversionRepository |
|
|
|
val uomConversionRepository: UomConversionRepository, |
|
|
|
val itemsRepository: ItemsRepository |
|
|
|
|
|
|
|
) { |
|
|
|
private val logger: Logger = LoggerFactory.getLogger(StockTakeRecordService::class.java) |
|
|
|
@@ -90,6 +92,18 @@ class StockTakeRecordService( |
|
|
|
/** |
|
|
|
* 逗號分隔多個關鍵字,任一包含於 [StockTakeRecord.itemCode] 即保留(不分大小寫)。 |
|
|
|
*/ |
|
|
|
private fun filterStockTakeRecordsByItemKeyword( |
|
|
|
records: List<StockTakeRecord>, |
|
|
|
itemKeyword: String? |
|
|
|
): List<StockTakeRecord> { |
|
|
|
if (itemKeyword.isNullOrBlank()) return records |
|
|
|
val parts = itemKeyword.split(",").map { it.trim() }.filter { it.isNotEmpty() } |
|
|
|
if (parts.isEmpty()) return records |
|
|
|
return records.filter { rec -> |
|
|
|
val code = rec.itemCode ?: "" |
|
|
|
parts.any { part -> code.contains(part, ignoreCase = true) } |
|
|
|
} |
|
|
|
} |
|
|
|
private fun filterStockTakeRecordsByItemCode( |
|
|
|
records: List<StockTakeRecord>, |
|
|
|
itemCode: String? |
|
|
|
@@ -154,7 +168,18 @@ class StockTakeRecordService( |
|
|
|
parts.any { part -> name.contains(part, ignoreCase = true) } |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
private fun filterStockTakeRecordsByWarehouseCode( |
|
|
|
records: List<StockTakeRecord>, |
|
|
|
warehouseCodeKeyword: String? |
|
|
|
): List<StockTakeRecord> { |
|
|
|
if (warehouseCodeKeyword.isNullOrBlank()) return records |
|
|
|
val parts = warehouseCodeKeyword.split(",").map { it.trim() }.filter { it.isNotEmpty() } |
|
|
|
if (parts.isEmpty()) return records |
|
|
|
return records.filter { rec -> |
|
|
|
val code = rec.warehouse?.code ?: "" |
|
|
|
parts.any { part -> code.contains(part, ignoreCase = true) } |
|
|
|
} |
|
|
|
} |
|
|
|
private fun filterInventoryLotDetailsBySectionDescription( |
|
|
|
responses: List<InventoryLotDetailResponse>, |
|
|
|
sectionDescription: String? |
|
|
|
@@ -164,7 +189,35 @@ class StockTakeRecordService( |
|
|
|
r.stockTakeSectionDescription?.equals(sectionDescription, ignoreCase = true) == true |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
private fun filterInventoryLotDetailsByItemKeyword( |
|
|
|
responses: List<InventoryLotDetailResponse>, |
|
|
|
itemKeyword: String? |
|
|
|
): List<InventoryLotDetailResponse> { |
|
|
|
if (itemKeyword.isNullOrBlank()) return responses |
|
|
|
val parts = itemKeyword.split(",").map { it.trim() }.filter { it.isNotEmpty() } |
|
|
|
if (parts.isEmpty()) return responses |
|
|
|
|
|
|
|
return responses.filter { r -> |
|
|
|
val code = r.itemCode ?: "" |
|
|
|
val name = r.itemName ?: "" |
|
|
|
parts.any { part -> |
|
|
|
code.contains(part, ignoreCase = true) || name.contains(part, ignoreCase = true) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
private fun filterInventoryLotDetailsByWarehouseKeyword( |
|
|
|
responses: List<InventoryLotDetailResponse>, |
|
|
|
warehouseKeyword: String? |
|
|
|
): List<InventoryLotDetailResponse> { |
|
|
|
if (warehouseKeyword.isNullOrBlank()) return responses |
|
|
|
val parts = warehouseKeyword.split(",").map { it.trim() }.filter { it.isNotEmpty() } |
|
|
|
if (parts.isEmpty()) return responses |
|
|
|
|
|
|
|
return responses.filter { r -> |
|
|
|
val code = r.warehouseCode ?: "" |
|
|
|
parts.any { part -> code.contains(part, ignoreCase = true) } |
|
|
|
} |
|
|
|
} |
|
|
|
private fun filterInventoryLotDetailsByStockTakeSections( |
|
|
|
responses: List<InventoryLotDetailResponse>, |
|
|
|
stockTakeSections: String? |
|
|
|
@@ -333,13 +386,13 @@ class StockTakeRecordService( |
|
|
|
pageNum: Int = 0, |
|
|
|
pageSize: Int = 100, |
|
|
|
approvalView: String? = null, |
|
|
|
itemCode: String? = null, |
|
|
|
itemName: String? = null, |
|
|
|
itemKeyword: String? = null, |
|
|
|
sectionDescription: String? = null, |
|
|
|
stockTakeSections: String? = null |
|
|
|
stockTakeSections: String? = null, |
|
|
|
warehouseKeyword: String? = null |
|
|
|
): RecordsRes<InventoryLotDetailResponse> { |
|
|
|
|
|
|
|
println("getApproverInventoryLotDetailsAll called with stockTakeId: $stockTakeId, pageNum: $pageNum, pageSize: $pageSize, itemCode: $itemCode, itemName: $itemName, sectionDescription: $sectionDescription, stockTakeSections: $stockTakeSections") |
|
|
|
println("getApproverInventoryLotDetailsAll called with stockTakeId: $stockTakeId, pageNum: $pageNum, pageSize: $pageSize, itemKeyword: $itemKeyword, sectionDescription: $sectionDescription, stockTakeSections: $stockTakeSections, warehouseKeyword: $warehouseKeyword") |
|
|
|
|
|
|
|
// 3. 如果传了 stockTakeId,就把「同一轮」的所有 stockTake 找出来(stockTakeRoundId,舊資料則 planStart) |
|
|
|
// stockTakeId != null 时,优先用 stocktakerecord.stockTakeRoundId 取整轮记录(更快) |
|
|
|
@@ -363,10 +416,30 @@ class StockTakeRecordService( |
|
|
|
emptySet<Long>() to emptyList() |
|
|
|
} |
|
|
|
var roundStockTakeRecords = roundStockTakeRecordsRaw |
|
|
|
val parts = itemKeyword |
|
|
|
?.split(",") |
|
|
|
?.map { it.trim() } |
|
|
|
?.filter { it.isNotEmpty() } |
|
|
|
.orEmpty() |
|
|
|
if (parts.isNotEmpty()) { |
|
|
|
val allowedItemIds = parts |
|
|
|
.flatMap { kw -> itemsRepository.findIdsByCodeOrNameContains(kw) } |
|
|
|
.distinct() |
|
|
|
.toSet() |
|
|
|
if (allowedItemIds.isEmpty()) { |
|
|
|
return RecordsRes(emptyList(), 0) |
|
|
|
} |
|
|
|
roundStockTakeRecords = roundStockTakeRecords.filter { rec -> |
|
|
|
val itemId = rec.itemId |
|
|
|
itemId != null && allowedItemIds.contains(itemId) |
|
|
|
} |
|
|
|
} |
|
|
|
roundStockTakeRecords = filterStockTakeRecordsBySectionDescription(roundStockTakeRecords, sectionDescription) |
|
|
|
roundStockTakeRecords = filterStockTakeRecordsByStockTakeSections(roundStockTakeRecords, stockTakeSections) |
|
|
|
roundStockTakeRecords = filterStockTakeRecordsByItemCode(roundStockTakeRecords, itemCode) |
|
|
|
roundStockTakeRecords = filterStockTakeRecordsByItemName(roundStockTakeRecords, itemName) |
|
|
|
// roundStockTakeRecords = filterStockTakeRecordsByItemCode(roundStockTakeRecords, itemCode) |
|
|
|
//roundStockTakeRecords = filterStockTakeRecordsByItemName(roundStockTakeRecords, itemName) |
|
|
|
//roundStockTakeRecords = filterStockTakeRecordsByItemKeyword(roundStockTakeRecords, itemKeyword) |
|
|
|
roundStockTakeRecords = filterStockTakeRecordsByWarehouseCode(roundStockTakeRecords, warehouseKeyword) |
|
|
|
if (stockTakeId != null && roundStockTakeRecords.isEmpty()) { |
|
|
|
return RecordsRes(emptyList(), 0) |
|
|
|
} |
|
|
|
@@ -470,6 +543,7 @@ class StockTakeRecordService( |
|
|
|
warehouseSlot = warehouse?.slot, |
|
|
|
warehouseArea = warehouse?.area, |
|
|
|
warehouse = warehouse?.warehouse, |
|
|
|
storeId = warehouse?.store_id, |
|
|
|
varianceQty = stockTakeRecord?.varianceQty, |
|
|
|
stockTakeRecordId = stockTakeRecord?.id, |
|
|
|
stockTakeRecordStatus = stockTakeRecord?.status, |
|
|
|
@@ -517,8 +591,10 @@ class StockTakeRecordService( |
|
|
|
var list = approvalFilteredResults |
|
|
|
list = filterInventoryLotDetailsBySectionDescription(list, sectionDescription) |
|
|
|
list = filterInventoryLotDetailsByStockTakeSections(list, stockTakeSections) |
|
|
|
list = filterInventoryLotDetailsByItemCode(list, itemCode) |
|
|
|
list = filterInventoryLotDetailsByItemName(list, itemName) |
|
|
|
//list = filterInventoryLotDetailsByItemCode(list, itemCode) |
|
|
|
//list = filterInventoryLotDetailsByItemName(list, itemName) |
|
|
|
list = filterInventoryLotDetailsByItemKeyword(list, itemKeyword) |
|
|
|
list = filterInventoryLotDetailsByWarehouseKeyword(list, warehouseKeyword) |
|
|
|
list |
|
|
|
} else { |
|
|
|
approvalFilteredResults |
|
|
|
@@ -707,6 +783,7 @@ class StockTakeRecordService( |
|
|
|
warehouseCode = warehouse?.code, |
|
|
|
warehouseName = warehouse?.name, |
|
|
|
status = ill.status?.name, |
|
|
|
storeId = warehouse?.store_id, |
|
|
|
stockTakeRecordStatus = null, |
|
|
|
stockTakeRecordId = null, |
|
|
|
firstStockTakeQty = null, |
|
|
|
@@ -788,6 +865,7 @@ class StockTakeRecordService( |
|
|
|
itemName = item?.name, |
|
|
|
lotNo = inventoryLot?.lotNo, |
|
|
|
expiryDate = inventoryLot?.expiryDate, |
|
|
|
storeId = warehouse?.store_id, |
|
|
|
productionDate = inventoryLot?.productionDate, |
|
|
|
stockInDate = inventoryLot?.stockInDate, |
|
|
|
inQty = ill.inQty, |
|
|
|
@@ -797,10 +875,11 @@ class StockTakeRecordService( |
|
|
|
availableQty = availableQty, |
|
|
|
uom = ill.stockUom?.uom?.udfudesc, |
|
|
|
warehouseCode = warehouse?.code, |
|
|
|
warehouseArea = warehouse?.area, |
|
|
|
warehouseName = warehouse?.name, |
|
|
|
status = ill.status?.name, |
|
|
|
warehouseSlot = warehouse?.slot, |
|
|
|
warehouseArea = warehouse?.area, |
|
|
|
|
|
|
|
warehouse = warehouse?.warehouse, |
|
|
|
varianceQty = stockTakeRecord?.varianceQty, |
|
|
|
stockTakeRecordId = stockTakeRecord?.id, |
|
|
|
@@ -1810,6 +1889,7 @@ open fun getInventoryLotDetailsByStockTakeSectionNotMatch( |
|
|
|
warehouseSlot = warehouse?.slot, |
|
|
|
warehouseArea = warehouse?.area, |
|
|
|
warehouse = warehouse?.warehouse, |
|
|
|
storeId = warehouse?.store_id, |
|
|
|
varianceQty = stockTakeRecord.varianceQty, |
|
|
|
stockTakeRecordId = stockTakeRecord.id, |
|
|
|
stockTakeRecordStatus = stockTakeRecord.status, |
|
|
|
|