diff --git a/src/main/java/com/ffii/fpsms/modules/master/entity/WarehouseRepository.kt b/src/main/java/com/ffii/fpsms/modules/master/entity/WarehouseRepository.kt index d3ac33b..45c1ed6 100644 --- a/src/main/java/com/ffii/fpsms/modules/master/entity/WarehouseRepository.kt +++ b/src/main/java/com/ffii/fpsms/modules/master/entity/WarehouseRepository.kt @@ -5,7 +5,6 @@ import com.ffii.fpsms.modules.master.entity.projections.WarehouseCombo import org.springframework.data.domain.Page import org.springframework.data.domain.Pageable import org.springframework.data.jpa.repository.Query -import org.springframework.data.repository.query.Param import org.springframework.stereotype.Repository import java.io.Serializable @@ -23,22 +22,6 @@ interface WarehouseRepository : AbstractRepository { fun findAllByIdIn(ids: List): List; fun findAllByCodeAndDeletedIsFalse(code: String): List - /** FP-MTMS Version Checklist | Functions Ref. No. 19 | v1.0.1 | 2026-09-10 */ - @Query( - """ - SELECT w FROM Warehouse w - WHERE w.deleted = false - AND (:storeId IS NULL OR :storeId = '' OR w.store_id = :storeId) - AND (:warehouse IS NULL OR :warehouse = '' OR w.warehouse = :warehouse) - AND (:area IS NULL OR :area = '' OR w.area = :area) - """ - ) - fun findByLocationFilters( - @Param("storeId") storeId: String?, - @Param("warehouse") warehouse: String?, - @Param("area") area: String?, - ): List - @Query( """ SELECT COUNT(w) FROM Warehouse w diff --git a/src/main/java/com/ffii/fpsms/modules/stock/entity/InventoryLotLineRepository.kt b/src/main/java/com/ffii/fpsms/modules/stock/entity/InventoryLotLineRepository.kt index c854c08..7b5ff3e 100644 --- a/src/main/java/com/ffii/fpsms/modules/stock/entity/InventoryLotLineRepository.kt +++ b/src/main/java/com/ffii/fpsms/modules/stock/entity/InventoryLotLineRepository.kt @@ -3,7 +3,6 @@ package com.ffii.fpsms.modules.stock.entity import com.ffii.core.support.AbstractRepository import com.ffii.fpsms.modules.stock.entity.projection.CurrentInventoryItemInfo import com.ffii.fpsms.modules.stock.entity.projection.InventoryLotLineInfo -import com.ffii.fpsms.modules.stock.entity.projection.InventoryStockUomSearchRow import org.springframework.data.domain.Page import org.springframework.data.domain.Pageable import org.springframework.data.jpa.repository.Modifying @@ -57,116 +56,8 @@ WHERE ill.id = :id fun findInventoryLotLineInfoByInventoryLotItemIdIn(ids: List): List - @Query( - """ - SELECT ill FROM InventoryLotLine ill - WHERE (:id IS NULL OR ill.inventoryLot.item.id = :id) - AND (:uomId IS NULL OR ill.stockUom.uom.id = :uomId) - ORDER BY ill.id DESC - """ - ) - /** FP-MTMS Version Checklist | Functions Ref. No. 80 | v1.0.0 | 2026-09-10 */ - fun findInventoryLotLineInfoByItemId( - @Param("id") id: Long?, - @Param("uomId") uomId: Long?, - pageable: Pageable, - ): Page - - @Query( - """ - SELECT DISTINCT ill.inventoryLot.item.id - FROM InventoryLotLine ill - WHERE ill.deleted = false - AND ill.status = :status - AND ill.warehouse.id IN :warehouseIds - """ - ) - fun findDistinctItemIdsByWarehouseIdsAndStatus( - @Param("warehouseIds") warehouseIds: List, - @Param("status") status: InventoryLotLineStatus, - ): List - - @Query( - """ - SELECT ill FROM InventoryLotLine ill - WHERE (:id IS NULL OR ill.inventoryLot.item.id = :id) - AND ill.warehouse.id IN :warehouseIds - AND (:uomId IS NULL OR ill.stockUom.uom.id = :uomId) - ORDER BY ill.id DESC - """ - ) - /** FP-MTMS Version Checklist | Functions Ref. No. 80 | v1.0.0 | 2026-09-10 */ - fun findInventoryLotLineInfoByItemIdAndWarehouseIdIn( - @Param("id") id: Long?, - @Param("warehouseIds") warehouseIds: List, - @Param("uomId") uomId: Long?, - pageable: Pageable, - ): Page - - @Query( - value = """ - SELECT - MAX(CAST(ill.id AS long)) AS id, - CAST(item.id AS long) AS itemId, - item.code AS itemCode, - item.name AS itemName, - item.type AS itemType, - SUM(COALESCE(ill.inQty, 0)) AS onHandQty, - SUM(COALESCE(ill.holdQty, 0)) AS onHoldQty, - SUM(COALESCE(ill.inQty, 0) - COALESCE(ill.outQty, 0) - COALESCE(ill.holdQty, 0)) AS availableQty, - CAST(uom.id AS long) AS uomId, - uom.code AS uomCode, - uom.udfudesc AS uomUdfudesc, - uom.udfShortDesc AS uomShortDesc, - SUM(COALESCE(ill.inQty, 0) - COALESCE(ill.outQty, 0) - COALESCE(ill.holdQty, 0)) AS qtyPerSmallestUnit, - MAX(item.latestMarketUnitPrice) AS latestMarketUnitPrice, - MAX(item.latestMupUpdatedDate) AS latestMupUpdatedDate - FROM InventoryLotLine ill - JOIN ill.inventoryLot il - JOIN il.item item - JOIN ill.stockUom su - JOIN su.uom uom - WHERE ill.deleted = false - AND il.deleted = false - AND item.deleted = false - AND ill.status = :status - AND (:code IS NULL OR :code = '' OR LOWER(item.code) LIKE LOWER(CONCAT('%', :code, '%'))) - AND (:name IS NULL OR :name = '' OR LOWER(item.name) LIKE LOWER(CONCAT('%', :name, '%'))) - AND (:type IS NULL OR :type = '' OR item.type = :type) - AND (:hasWarehouseFilter = false OR ill.warehouse.id IN :warehouseIds) - AND (:lotNo IS NULL OR :lotNo = '' OR il.lotNo = :lotNo) - GROUP BY item.id, item.code, item.name, item.type, uom.id, uom.code, uom.udfudesc, uom.udfShortDesc - ORDER BY item.code ASC, uom.udfudesc ASC - """, - countQuery = """ - SELECT COUNT(DISTINCT CONCAT(CAST(item.id AS string), ':', CAST(uom.id AS string))) - FROM InventoryLotLine ill - JOIN ill.inventoryLot il - JOIN il.item item - JOIN ill.stockUom su - JOIN su.uom uom - WHERE ill.deleted = false - AND il.deleted = false - AND item.deleted = false - AND ill.status = :status - AND (:code IS NULL OR :code = '' OR LOWER(item.code) LIKE LOWER(CONCAT('%', :code, '%'))) - AND (:name IS NULL OR :name = '' OR LOWER(item.name) LIKE LOWER(CONCAT('%', :name, '%'))) - AND (:type IS NULL OR :type = '' OR item.type = :type) - AND (:hasWarehouseFilter = false OR ill.warehouse.id IN :warehouseIds) - AND (:lotNo IS NULL OR :lotNo = '' OR il.lotNo = :lotNo) - """, - ) - /** FP-MTMS Version Checklist | Functions Ref. No. 19 | v1.0.1 | 2026-09-10 */ - fun searchInventoryGroupedByStockUom( - @Param("code") code: String, - @Param("name") name: String, - @Param("type") type: String, - @Param("status") status: InventoryLotLineStatus, - @Param("hasWarehouseFilter") hasWarehouseFilter: Boolean, - @Param("warehouseIds") warehouseIds: List, - @Param("lotNo") lotNo: String?, - pageable: Pageable, - ): Page + @Query("select ill from InventoryLotLine ill where :id is null or ill.inventoryLot.item.id = :id order by ill.id desc") + fun findInventoryLotLineInfoByItemId(id: Long?, pageable: Pageable): Page @Query(""" SELECT ill FROM InventoryLotLine ill diff --git a/src/main/java/com/ffii/fpsms/modules/stock/entity/projection/InventoryStockUomSearchRow.kt b/src/main/java/com/ffii/fpsms/modules/stock/entity/projection/InventoryStockUomSearchRow.kt deleted file mode 100644 index e48f4af..0000000 --- a/src/main/java/com/ffii/fpsms/modules/stock/entity/projection/InventoryStockUomSearchRow.kt +++ /dev/null @@ -1,30 +0,0 @@ -package com.ffii.fpsms.modules.stock.entity.projection - -import java.math.BigDecimal -import java.time.LocalDateTime - -/** - * Inventory search page: one row per item + lot-line stock UoM. - */ -interface InventoryStockUomSearchRow { - val id: Long? - val itemId: Long? - val itemCode: String? - val itemName: String? - val itemType: String? - val onHandQty: BigDecimal? - val onHoldQty: BigDecimal? - val unavailableQty: BigDecimal? - val availableQty: BigDecimal? - val uomId: Long? - val uomCode: String? - val uomUdfudesc: String? - val uomShortDesc: String? - val qtyPerSmallestUnit: BigDecimal? - val baseUom: String? - val price: BigDecimal? - val currencyName: String? - val status: String? - val latestMarketUnitPrice: Double? - val latestMupUpdatedDate: LocalDateTime? -} 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 c47f2fd..78494b9 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 @@ -76,15 +76,9 @@ open class InventoryLotLineService( return inventoryLotLineRepository.findInventoryLotLineInfoByInventoryLotItemIdIn(itemIds) } - /** FP-MTMS Version Checklist | Functions Ref. No. 80 | v1.0.0 | 2026-09-10 */ open fun allInventoryLotLinesByPage(request: SearchInventoryLotLineInfoRequest): RecordsRes { val pageable = PageRequest.of(request.pageNum ?: 0, request.pageSize ?: 10); - val warehouseIds = resolveWarehouseIds(request.storeId, request.warehouse, request.area) - if (warehouseIds != null && warehouseIds.isEmpty()) { - return RecordsRes(emptyList(), 0) - } - val response = if (request.stockIssueBadItem == true) { inventoryLotLineRepository.findStockIssueBadItemLotLinesByItemId( request.itemId, @@ -92,15 +86,8 @@ open class InventoryLotLineService( listOf(InventoryLotLineStatus.AVAILABLE, InventoryLotLineStatus.UNAVAILABLE), pageable, ) - } else if (warehouseIds != null) { - inventoryLotLineRepository.findInventoryLotLineInfoByItemIdAndWarehouseIdIn( - request.itemId, - warehouseIds, - request.uomId, - pageable, - ) } else { - inventoryLotLineRepository.findInventoryLotLineInfoByItemId(request.itemId, request.uomId, pageable) + inventoryLotLineRepository.findInventoryLotLineInfoByItemId(request.itemId, pageable) } val records = response.content @@ -108,28 +95,6 @@ open class InventoryLotLineService( return RecordsRes(records, total.toInt()); } - /** - * FP-MTMS Version Checklist | Functions Ref. No. 80 | v1.0.0 | 2026-09-10 - * Returns null when no location filter is set. - */ - private fun resolveWarehouseIds( - storeId: String?, - warehouse: String?, - area: String?, - ): List? { - val trimmedStoreId = storeId?.trim()?.takeIf { it.isNotEmpty() } - val trimmedWarehouse = warehouse?.trim()?.takeIf { it.isNotEmpty() } - val trimmedArea = area?.trim()?.takeIf { it.isNotEmpty() } - if (trimmedStoreId == null && trimmedWarehouse == null && trimmedArea == null) { - return null - } - return warehouseRepository.findByLocationFilters( - trimmedStoreId, - trimmedWarehouse, - trimmedArea, - ).mapNotNull { it.id } - } - open fun searchStockIssueBadItemLotLines( request: SearchStockIssueBadItemLotLineRequest, ): RecordsRes { diff --git a/src/main/java/com/ffii/fpsms/modules/stock/service/InventoryService.kt b/src/main/java/com/ffii/fpsms/modules/stock/service/InventoryService.kt index da108a7..d909d74 100644 --- a/src/main/java/com/ffii/fpsms/modules/stock/service/InventoryService.kt +++ b/src/main/java/com/ffii/fpsms/modules/stock/service/InventoryService.kt @@ -17,7 +17,6 @@ import com.ffii.fpsms.modules.purchaseOrder.enums.PurchaseOrderType import com.ffii.fpsms.modules.stock.entity.* import com.ffii.fpsms.modules.stock.entity.enum.InventoryLotLineStatus import com.ffii.fpsms.modules.stock.entity.projection.InventoryInfo -import com.ffii.fpsms.modules.stock.entity.projection.InventoryStockUomSearchRow import com.ffii.fpsms.modules.stock.web.model.SearchInventoryRequest import org.apache.poi.ss.usermodel.Sheet import org.apache.poi.ss.usermodel.Workbook @@ -90,56 +89,43 @@ open class InventoryService( } /** - * FP-MTMS Version Checklist | Functions Ref. No. 19 | v1.0.1 | 2026-09-10 - * Inventory search page: one row per item + lot-line stock UoM. + * FP-MTMS Version Checklist | Functions Ref. No. 19 | v1.0.0 | 2026-07-17 + * Inventory search page only: no baseUnit/uomId filter; + * one inventory row per item (latest id). Shared getRecordByPage is unchanged. */ open fun searchInventoriesByLatestInventory( request: SearchInventoryRequest, - ): RecordsRes { + ): RecordsRes { val pageable = PageRequest.of(request.pageNum ?: 0, request.pageSize ?: 10) val code = request.code?.trim().orEmpty() val name = request.name?.trim().orEmpty() val type = request.type?.trim().orEmpty() val lotNo = request.lotNo?.trim()?.takeIf { it.isNotEmpty() } - val warehouseIds = resolveWarehouseIds(request.storeId, request.warehouse, request.area) - if (warehouseIds != null && warehouseIds.isEmpty()) { - return RecordsRes(emptyList(), 0) - } - val hasWarehouseFilter = warehouseIds != null - val response = inventoryLotLineRepository.searchInventoryGroupedByStockUom( - code = code, - name = name, - type = type, - status = InventoryLotLineStatus.AVAILABLE, - hasWarehouseFilter = hasWarehouseFilter, - warehouseIds = warehouseIds ?: listOf(-1L), - lotNo = lotNo, - pageable = pageable, - ) + val response = if (lotNo != null) { + val itemIds = inventoryLotLineRepository.findDistinctItemIdsByLotNo(lotNo) + if (itemIds.isEmpty()) { + return RecordsRes(emptyList(), 0) + } + inventoryRepository.findLatestInventoryInfoByItemCodeContainsAndItemNameContainsAndItemTypeAndItemIdInAndDeletedIsFalse( + code = code, + name = name, + type = type, + itemIds = itemIds, + pageable = pageable, + ) + } else { + inventoryRepository.findLatestInventoryInfoByItemCodeContainsAndItemNameContainsAndItemTypeAndDeletedIsFalse( + code = code, + name = name, + type = type, + pageable = pageable, + ) + } return RecordsRes(response.content, response.totalElements.toInt()) } - /** FP-MTMS Version Checklist | Functions Ref. No. 19 | v1.0.1 | 2026-09-10 */ - private fun resolveWarehouseIds( - storeId: String?, - warehouse: String?, - area: String?, - ): List? { - val trimmedStoreId = storeId?.trim()?.takeIf { it.isNotEmpty() } - val trimmedWarehouse = warehouse?.trim()?.takeIf { it.isNotEmpty() } - val trimmedArea = area?.trim()?.takeIf { it.isNotEmpty() } - if (trimmedStoreId == null && trimmedWarehouse == null && trimmedArea == null) { - return null - } - return warehouseRepository.findByLocationFilters( - trimmedStoreId, - trimmedWarehouse, - trimmedArea, - ).mapNotNull { it.id } - } - open fun allInventoriesByItems(items: List): List{ return inventoryRepository.findInventoryInfoByItemInAndDeletedIsFalse(items); } diff --git a/src/main/java/com/ffii/fpsms/modules/stock/web/InventoryController.kt b/src/main/java/com/ffii/fpsms/modules/stock/web/InventoryController.kt index c868176..20cf216 100644 --- a/src/main/java/com/ffii/fpsms/modules/stock/web/InventoryController.kt +++ b/src/main/java/com/ffii/fpsms/modules/stock/web/InventoryController.kt @@ -2,7 +2,6 @@ package com.ffii.fpsms.modules.stock.web import com.ffii.core.response.RecordsRes import com.ffii.fpsms.modules.stock.entity.projection.InventoryInfo -import com.ffii.fpsms.modules.stock.entity.projection.InventoryStockUomSearchRow import com.ffii.fpsms.modules.stock.service.InventoryService import com.ffii.fpsms.modules.stock.web.model.SearchInventoryRequest import org.springframework.web.bind.annotation.* @@ -23,13 +22,13 @@ class InventoryController( } /** - * FP-MTMS Version Checklist | Functions Ref. No. 19 | v1.0.1 | 2026-09-10 - * Inventory search page: one row per item + lot-line stock UoM, with optional location filters. + * FP-MTMS Version Checklist | Functions Ref. No. 19 | v1.0.0 | 2026-07-17 + * Inventory search page only: latest inventory row per item, no baseUnit/uomId filter. */ @GetMapping("/searchLatest/getRecordByPage") fun searchInventoriesByLatestInventory( @ModelAttribute request: SearchInventoryRequest, - ): RecordsRes { + ): RecordsRes { return inventoryService.searchInventoriesByLatestInventory(request) } diff --git a/src/main/java/com/ffii/fpsms/modules/stock/web/model/SearchInventoryLotLineInfoRequest.kt b/src/main/java/com/ffii/fpsms/modules/stock/web/model/SearchInventoryLotLineInfoRequest.kt index edf1b75..53d7327 100644 --- a/src/main/java/com/ffii/fpsms/modules/stock/web/model/SearchInventoryLotLineInfoRequest.kt +++ b/src/main/java/com/ffii/fpsms/modules/stock/web/model/SearchInventoryLotLineInfoRequest.kt @@ -2,15 +2,8 @@ package com.ffii.fpsms.modules.stock.web.model data class SearchInventoryLotLineInfoRequest( val itemId: Long? = null, - val uomId: Long? = null, val pageSize: Int?, val pageNum: Int?, /** When true: non-expired lots with inQty > outQty; includes available and unavailable status. */ val stockIssueBadItem: Boolean? = false, - /** Floor / store, e.g. 2F. Used by inventory location search. */ - val storeId: String? = null, - /** Warehouse zone, e.g. W201. */ - val warehouse: String? = null, - /** Area, e.g. #R. */ - val area: String? = null, ) diff --git a/src/main/java/com/ffii/fpsms/modules/stock/web/model/SearchInventoryRequest.kt b/src/main/java/com/ffii/fpsms/modules/stock/web/model/SearchInventoryRequest.kt index 7e3cbc2..c40dcb4 100644 --- a/src/main/java/com/ffii/fpsms/modules/stock/web/model/SearchInventoryRequest.kt +++ b/src/main/java/com/ffii/fpsms/modules/stock/web/model/SearchInventoryRequest.kt @@ -5,12 +5,6 @@ data class SearchInventoryRequest( val name: String, val type: String, val lotNo: String? = null, - /** Floor / store, e.g. 2F. Used by inventory location search. */ - val storeId: String? = null, - /** Warehouse zone, e.g. W201. */ - val warehouse: String? = null, - /** Area, e.g. #R. */ - val area: String? = null, val pageNum: Int?, val pageSize: Int? )