diff --git a/src/main/java/com/ffii/fpsms/modules/master/service/ItemUomService.kt b/src/main/java/com/ffii/fpsms/modules/master/service/ItemUomService.kt index e8ecaf1..06f9fd9 100644 --- a/src/main/java/com/ffii/fpsms/modules/master/service/ItemUomService.kt +++ b/src/main/java/com/ffii/fpsms/modules/master/service/ItemUomService.kt @@ -97,6 +97,29 @@ open class ItemUomService( return stockQty.setScale(0, RoundingMode.UP) } + /** + * Convert purchase qty -> stock qty (PO display / acceptedQty calculation) + * with round-down to integer stock qty. + */ + open fun convertPurchaseQtyToStockQtyRoundDown(itemId: Long, purchaseQty: BigDecimal): BigDecimal { + val purchaseUnit = findPurchaseUnitByItemId(itemId) ?: return purchaseQty + val stockUnit = findStockUnitByItemId(itemId) ?: return purchaseQty + val one = BigDecimal.ONE + + // Use high precision for intermediate steps, and round down only at the end. + val calcScale = 10 + + val baseQty = purchaseQty + .multiply(purchaseUnit.ratioN ?: one) + .divide(purchaseUnit.ratioD ?: one, calcScale, RoundingMode.HALF_UP) + + val stockQty = baseQty + .multiply(stockUnit.ratioD ?: one) + .divide(stockUnit.ratioN ?: one, calcScale, RoundingMode.HALF_UP) + + return stockQty.setScale(0, RoundingMode.DOWN) + } + /** Inverse of convertPurchaseQtyToStockQty: stock qty -> purchase qty (for PO-origin StockInLine display). */ open fun convertStockQtyToPurchaseQty(itemId: Long, stockQty: BigDecimal): BigDecimal { val purchaseUnit = findPurchaseUnitByItemId(itemId) ?: return stockQty diff --git a/src/main/java/com/ffii/fpsms/modules/report/service/ItemQcFailReportService.kt b/src/main/java/com/ffii/fpsms/modules/report/service/ItemQcFailReportService.kt index ac7bbd4..ff49878 100644 --- a/src/main/java/com/ffii/fpsms/modules/report/service/ItemQcFailReportService.kt +++ b/src/main/java/com/ffii/fpsms/modules/report/service/ItemQcFailReportService.kt @@ -143,13 +143,7 @@ open class ItemQcFailReportService( COALESCE(qi.code, '') """.trimIndent() val result = jdbcDao.queryForList(sql, args) - println("qcTemplate: ${result[0]["qcTemplate"]}") - println("qcDefectCriteria: ${result[0]["qcDefectCriteria"]}") - println("lotQty: ${result[0]["lotQty"]}") - println("defectQty: ${result[0]["defectQty"]}") - println("refData: ${result[0]["refData"]}") - println("remark: ${result[0]["remark"]}") - println("orderRefNo: ${result[0]["orderRefNo"]}") + return result } diff --git a/src/main/java/com/ffii/fpsms/modules/stock/entity/projection/StockInLineInfo.kt b/src/main/java/com/ffii/fpsms/modules/stock/entity/projection/StockInLineInfo.kt index 40671be..2aff3bd 100644 --- a/src/main/java/com/ffii/fpsms/modules/stock/entity/projection/StockInLineInfo.kt +++ b/src/main/java/com/ffii/fpsms/modules/stock/entity/projection/StockInLineInfo.kt @@ -28,7 +28,7 @@ interface StockInLineInfo { val receivedQty: BigDecimal? val demandQty: BigDecimal? val acceptedQty: BigDecimal - @get:Value("#{target.purchaseOrderLine != null && target.item != null && target.acceptedQty != null ? @itemUomService.convertStockQtyToPurchaseQty(target.item.id, target.acceptedQty) : null}") + @get:Value("#{target.acceptedQtyM18 != null ? new java.math.BigDecimal(target.acceptedQtyM18) : null}") val purchaseAcceptedQty: BigDecimal? @get:Value("#{target.purchaseOrderLine?.qty}") val qty: BigDecimal? diff --git a/src/main/java/com/ffii/fpsms/modules/stock/service/StockInLineService.kt b/src/main/java/com/ffii/fpsms/modules/stock/service/StockInLineService.kt index 038136a..4419cf2 100644 --- a/src/main/java/com/ffii/fpsms/modules/stock/service/StockInLineService.kt +++ b/src/main/java/com/ffii/fpsms/modules/stock/service/StockInLineService.kt @@ -245,11 +245,18 @@ open class StockInLineService( this.item = item itemNo = item.code this.stockIn = stockIn - // PO-origin: store in stock qty; others: store as received - acceptedQty = if (pol != null && item.id != null) { - itemUomService.convertPurchaseQtyToStockQty(item.id!!, request.acceptedQty ?: BigDecimal.ZERO) + // PO-origin: + // 1) store user-input qty in acceptedQtyM18 (purchase unit) + // 2) calculate stock acceptedQty with round-down + if (pol != null && item.id != null) { + acceptedQtyM18 = request.acceptedQty.toInt() + acceptedQty = itemUomService.convertPurchaseQtyToStockQtyRoundDown( + item.id!!, + request.acceptedQty + ) } else { - request.acceptedQty + // Non-PO flows: keep legacy behavior + acceptedQty = request.acceptedQty } // Set demandQty based on source if (jo != null && jo?.bom != null) {