diff --git a/src/main/java/com/ffii/fpsms/modules/stock/entity/InventoryRepository.kt b/src/main/java/com/ffii/fpsms/modules/stock/entity/InventoryRepository.kt index a439b31..45fb4c0 100644 --- a/src/main/java/com/ffii/fpsms/modules/stock/entity/InventoryRepository.kt +++ b/src/main/java/com/ffii/fpsms/modules/stock/entity/InventoryRepository.kt @@ -46,6 +46,56 @@ interface InventoryRepository: AbstractRepository { pageable: Pageable ): Page + /** + * Inventory search page only: no baseUnit/uomId match required; + * one row per item = latest inventory id (no larger id for same item). + */ + @Query( + """ + SELECT i FROM Inventory i + WHERE (:code IS NULL OR :code = '' OR LOWER(i.item.code) LIKE LOWER(CONCAT('%', :code, '%'))) + AND (:name IS NULL OR :name = '' OR LOWER(i.item.name) LIKE LOWER(CONCAT('%', :name, '%'))) + AND (:type IS NULL OR :type = '' OR i.item.type = :type) + AND i.deleted = false + AND NOT EXISTS ( + SELECT 1 FROM Inventory i2 + WHERE i2.item.id = i.item.id + AND i2.deleted = false + AND i2.id > i.id + ) + """ + ) + fun findLatestInventoryInfoByItemCodeContainsAndItemNameContainsAndItemTypeAndDeletedIsFalse( + code: String, + name: String, + type: String, + pageable: Pageable, + ): Page + + @Query( + """ + SELECT i FROM Inventory i + WHERE (:code IS NULL OR :code = '' OR LOWER(i.item.code) LIKE LOWER(CONCAT('%', :code, '%'))) + AND (:name IS NULL OR :name = '' OR LOWER(i.item.name) LIKE LOWER(CONCAT('%', :name, '%'))) + AND (:type IS NULL OR :type = '' OR i.item.type = :type) + AND i.item.id IN :itemIds + AND i.deleted = false + AND NOT EXISTS ( + SELECT 1 FROM Inventory i2 + WHERE i2.item.id = i.item.id + AND i2.deleted = false + AND i2.id > i.id + ) + """ + ) + fun findLatestInventoryInfoByItemCodeContainsAndItemNameContainsAndItemTypeAndItemIdInAndDeletedIsFalse( + code: String, + name: String, + type: String, + itemIds: List, + pageable: Pageable, + ): Page + fun findInventoryInfoByItemIdInAndDeletedIsFalse(itemIds: List): List fun findInventoryInfoByItemInAndDeletedIsFalse(items: List): List 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 407c6a5..eb803fe 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 @@ -88,6 +88,43 @@ open class InventoryService( return RecordsRes(records, total.toInt()); } + /** + * Inventory search page only: no baseUnit/uomId filter; + * one inventory row per item (MAX id). Shared getRecordByPage is unchanged. + */ + open fun searchInventoriesByLatestInventory( + request: SearchInventoryRequest, + ): 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 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()) + } + 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 143d339..3198dcc 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 @@ -4,12 +4,7 @@ import com.ffii.core.response.RecordsRes import com.ffii.fpsms.modules.stock.entity.projection.InventoryInfo import com.ffii.fpsms.modules.stock.service.InventoryService import com.ffii.fpsms.modules.stock.web.model.SearchInventoryRequest -import org.springframework.core.io.ByteArrayResource -import org.springframework.core.io.Resource -import org.springframework.http.HttpHeaders -import org.springframework.http.ResponseEntity import org.springframework.web.bind.annotation.* -import java.time.LocalDate @RestController @RequestMapping("/inventory") @@ -26,14 +21,16 @@ class InventoryController( return inventoryService.allInventoriesByPage(request); } + /** Inventory search page only: latest inventory row per item, no baseUnit/uomId filter. */ + @GetMapping("/searchLatest/getRecordByPage") + fun searchInventoriesByLatestInventory( + @ModelAttribute request: SearchInventoryRequest, + ): RecordsRes { + return inventoryService.searchInventoriesByLatestInventory(request) + } + @PostMapping("/import-bom") fun importInventory() { val reportResult = inventoryService.importInventoryExcel() -// val filename = "bom_excel_issue_log_${LocalDate.now()}.xlsx" - -// return ResponseEntity.ok() -// .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"$filename\"") -// .header(HttpHeaders.CONTENT_TYPE, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") -// .body(ByteArrayResource(reportResult)) } -} \ No newline at end of file +}