| @@ -17,10 +17,12 @@ import com.ffii.fpsms.modules.deliveryOrder.web.models.SaveDeliveryOrderRequest | |||||
| import com.ffii.fpsms.modules.master.service.ItemUomService | import com.ffii.fpsms.modules.master.service.ItemUomService | ||||
| import com.ffii.fpsms.modules.master.service.ItemsService | import com.ffii.fpsms.modules.master.service.ItemsService | ||||
| import com.ffii.fpsms.modules.master.service.ShopService | import com.ffii.fpsms.modules.master.service.ShopService | ||||
| import com.ffii.fpsms.modules.master.web.models.ConvertUomByItemRequest | |||||
| import com.ffii.fpsms.modules.purchaseOrder.enums.PurchaseOrderType | import com.ffii.fpsms.modules.purchaseOrder.enums.PurchaseOrderType | ||||
| import org.slf4j.Logger | import org.slf4j.Logger | ||||
| import org.slf4j.LoggerFactory | import org.slf4j.LoggerFactory | ||||
| import org.springframework.stereotype.Service | import org.springframework.stereotype.Service | ||||
| import java.sql.SQLException | |||||
| import java.time.LocalDateTime | import java.time.LocalDateTime | ||||
| import java.time.format.DateTimeFormatter | import java.time.format.DateTimeFormatter | ||||
| import kotlin.reflect.full.memberProperties | import kotlin.reflect.full.memberProperties | ||||
| @@ -232,7 +234,7 @@ open class M18DeliveryOrderService( | |||||
| m18DataLogId = saveM18DeliveryOrderLog.id, | m18DataLogId = saveM18DeliveryOrderLog.id, | ||||
| handlerId = null, | handlerId = null, | ||||
| m18BeId = mainpo.beId, | m18BeId = mainpo.beId, | ||||
| deleted = mainpo.udfIsVoid == "false" | |||||
| deleted = (mainpo.udfIsVoid == "true") ?: false | |||||
| ) | ) | ||||
| val saveDeliveryOrderResponse = | val saveDeliveryOrderResponse = | ||||
| @@ -323,13 +325,15 @@ open class M18DeliveryOrderService( | |||||
| // Save to delivery_order_line table | // Save to delivery_order_line table | ||||
| // logger.info("${doLineRefType}: Saving delivery order line...") | // logger.info("${doLineRefType}: Saving delivery order line...") | ||||
| val itemUom = itemId?.let { itemUomService.findStockUnitByItemId(it) } | |||||
| val itemUom = itemUomService.findByM18Id(line.unitId) | |||||
| val saveDeliveryOrderLineRequest = SaveDeliveryOrderLineRequest( | val saveDeliveryOrderLineRequest = SaveDeliveryOrderLineRequest( | ||||
| id = existingDeliveryOrderLine?.id, | id = existingDeliveryOrderLine?.id, | ||||
| itemId = itemId, | itemId = itemId, | ||||
| uomId = itemUom?.uom?.id, | |||||
| uomIdM18 = itemUom?.uom?.id, | |||||
| uomId= itemUomService.findStockUnitByItemId(itemId?: 0)?.uom?.id, | |||||
| deliveryOrderId = deliveryOrderId, | deliveryOrderId = deliveryOrderId, | ||||
| qty = line.qty, | |||||
| qtyM18 = line.qty, | |||||
| qty = itemUomService.convertQtyToStockQty(itemId?:0, itemUom?.uom?.id?: 0, line.qty), | |||||
| up = line.up, | up = line.up, | ||||
| price = line.amt, | price = line.amt, | ||||
| // m18CurrencyId = mainpo.curId, | // m18CurrencyId = mainpo.curId, | ||||
| @@ -356,7 +360,7 @@ open class M18DeliveryOrderService( | |||||
| successDetailList.add(line.id) | successDetailList.add(line.id) | ||||
| // logger.info("${doLineRefType}: Delivery order ID: ${deliveryOrderId} | M18 ID: ${deliveryOrder.id}") | // logger.info("${doLineRefType}: Delivery order ID: ${deliveryOrderId} | M18 ID: ${deliveryOrder.id}") | ||||
| logger.info("${doLineRefType}: Saved delivery order line. ID: ${saveDeliveryOrderLineResponse.id} | M18 Line ID: ${line.id} | Delivery order ID: ${deliveryOrderId} | M18 ID: ${deliveryOrder.id}") | logger.info("${doLineRefType}: Saved delivery order line. ID: ${saveDeliveryOrderLineResponse.id} | M18 Line ID: ${line.id} | Delivery order ID: ${deliveryOrderId} | M18 ID: ${deliveryOrder.id}") | ||||
| } catch (e: Exception) { | |||||
| } catch (e: SQLException) { | |||||
| failDetailList.add(line.id) | failDetailList.add(line.id) | ||||
| failItemDetailList.add(line.proId) | failItemDetailList.add(line.proId) | ||||
| // logger.error("${doLineRefType}: Saving Failure!") | // logger.error("${doLineRefType}: Saving Failure!") | ||||
| @@ -31,6 +31,9 @@ open class DeliveryOrderLine: BaseEntity<Long>() { | |||||
| @Column(name = "qty", precision = 14, scale = 2) | @Column(name = "qty", precision = 14, scale = 2) | ||||
| open var qty: BigDecimal? = null | open var qty: BigDecimal? = null | ||||
| @Column(name = "qtyM18", precision = 14, scale = 2) | |||||
| open var qtyM18: BigDecimal? = null | |||||
| @Column(name = "up", precision = 14, scale = 2) | @Column(name = "up", precision = 14, scale = 2) | ||||
| open var up: BigDecimal? = null | open var up: BigDecimal? = null | ||||
| @@ -38,6 +41,10 @@ open class DeliveryOrderLine: BaseEntity<Long>() { | |||||
| @JoinColumn(name = "uomId") | @JoinColumn(name = "uomId") | ||||
| open var uom: UomConversion? = null | open var uom: UomConversion? = null | ||||
| @ManyToOne | |||||
| @JoinColumn(name = "uomIdM18") | |||||
| open var uomM18: UomConversion? = null | |||||
| @Column(name = "price", precision = 14, scale = 2) | @Column(name = "price", precision = 14, scale = 2) | ||||
| open var price: BigDecimal? = null | open var price: BigDecimal? = null | ||||
| @@ -37,15 +37,18 @@ open class DeliveryOrderLineService( | |||||
| val status = request.status?.let { status -> DeliveryOrderLineStatus.entries.find { it.value == status } } | val status = request.status?.let { status -> DeliveryOrderLineStatus.entries.find { it.value == status } } | ||||
| val m18DataLog = request.m18DataLogId?.let { m18DataLogRepository.findById(it).getOrNull() } | val m18DataLog = request.m18DataLogId?.let { m18DataLogRepository.findById(it).getOrNull() } | ||||
| val uom = request.uomId?.let { uomConversionService.find(it).getOrNull() } | val uom = request.uomId?.let { uomConversionService.find(it).getOrNull() } | ||||
| val uomM18 = request.uomIdM18?.let { uomConversionService.find(it).getOrNull() } | |||||
| deliveryOrderLine.apply { | deliveryOrderLine.apply { | ||||
| this.item = item | this.item = item | ||||
| itemNo = item?.code | itemNo = item?.code | ||||
| this.deliveryOrder = deliveryOrder | this.deliveryOrder = deliveryOrder | ||||
| qty = request.qty | qty = request.qty | ||||
| qtyM18 = request.qtyM18 | |||||
| up = request.up | up = request.up | ||||
| price = request.price | price = request.price | ||||
| this.uom = uom | this.uom = uom | ||||
| this.uomM18 = uomM18 | |||||
| this.status = status | this.status = status | ||||
| this.m18DataLog = m18DataLog ?: this.m18DataLog | this.m18DataLog = m18DataLog ?: this.m18DataLog | ||||
| m18Discount = request.m18Discount | m18Discount = request.m18Discount | ||||
| @@ -57,6 +60,7 @@ open class DeliveryOrderLineService( | |||||
| id = it.id, | id = it.id, | ||||
| itemNo = it.itemNo, | itemNo = it.itemNo, | ||||
| qty = it.qty, | qty = it.qty, | ||||
| qtyM18 = it.qtyM18, | |||||
| price = it.price, | price = it.price, | ||||
| status = it.status?.value | status = it.status?.value | ||||
| ) | ) | ||||
| @@ -502,6 +502,7 @@ open class DeliveryOrderService( | |||||
| this.m18DataLog = m18DataLog | this.m18DataLog = m18DataLog | ||||
| this.handler = handler | this.handler = handler | ||||
| m18BeId = request.m18BeId | m18BeId = request.m18BeId | ||||
| this.deleted = request.deleted | |||||
| } | } | ||||
| val savedDeliveryOrder = deliveryOrderRepository.saveAndFlush(deliveryOrder).let { | val savedDeliveryOrder = deliveryOrderRepository.saveAndFlush(deliveryOrder).let { | ||||
| @@ -6,8 +6,10 @@ data class SaveDeliveryOrderLineRequest( | |||||
| val id: Long?, | val id: Long?, | ||||
| val itemId: Long?, | val itemId: Long?, | ||||
| val uomId: Long?, | val uomId: Long?, | ||||
| val uomIdM18: Long?, | |||||
| val deliveryOrderId: Long?, | val deliveryOrderId: Long?, | ||||
| val qty: BigDecimal?, | val qty: BigDecimal?, | ||||
| val qtyM18: BigDecimal?, | |||||
| val up: BigDecimal?, | val up: BigDecimal?, | ||||
| val price: BigDecimal?, | val price: BigDecimal?, | ||||
| val status: String?, | val status: String?, | ||||
| @@ -1,11 +1,13 @@ | |||||
| package com.ffii.fpsms.modules.deliveryOrder.web.models | package com.ffii.fpsms.modules.deliveryOrder.web.models | ||||
| import com.ffii.fpsms.modules.master.entity.ItemUom | |||||
| import java.math.BigDecimal | import java.math.BigDecimal | ||||
| data class SaveDeliveryOrderLineResponse( | data class SaveDeliveryOrderLineResponse( | ||||
| val id: Long?, | val id: Long?, | ||||
| val itemNo: String?, | val itemNo: String?, | ||||
| val qty: BigDecimal?, | val qty: BigDecimal?, | ||||
| val qtyM18: BigDecimal?, | |||||
| val price: BigDecimal?, | val price: BigDecimal?, | ||||
| val status: String?, | val status: String?, | ||||
| ) | ) | ||||
| @@ -4,7 +4,7 @@ import java.time.LocalDateTime | |||||
| data class SaveDeliveryOrderResponse( | data class SaveDeliveryOrderResponse( | ||||
| val id: Long?, | val id: Long?, | ||||
| val deleted: Boolean?, | |||||
| //val deleted: Boolean?=false, | |||||
| val code: String?, | val code: String?, | ||||
| val supplierCode: String?, | val supplierCode: String?, | ||||
| val shopCode: String?, | val shopCode: String?, | ||||
| @@ -25,5 +25,5 @@ interface ItemUomRespository : AbstractRepository<ItemUom, Long> { | |||||
| fun findByItemM18IdAndPurchaseUnitIsTrueAndDeletedIsFalse(itemM18Id: Long): ItemUom? | fun findByItemM18IdAndPurchaseUnitIsTrueAndDeletedIsFalse(itemM18Id: Long): ItemUom? | ||||
| fun findBaseUnitByItemIdAndStockUnitIsTrueAndDeletedIsFalse(itemId: Long): ItemUom? | fun findBaseUnitByItemIdAndStockUnitIsTrueAndDeletedIsFalse(itemId: Long): ItemUom? | ||||
| fun findByItemIdAndUomIdAndDeletedIsFalse(itemId: Long, uomId: Long): ItemUom? | |||||
| fun findFirstByItemIdAndUomIdAndDeletedIsFalse(itemId: Long, uomId: Long): ItemUom? | |||||
| } | } | ||||
| @@ -40,6 +40,10 @@ open class ItemUomService( | |||||
| return itemUomRespository.findByItemIdAndStockUnitIsTrueAndDeletedIsFalse(itemId) | return itemUomRespository.findByItemIdAndStockUnitIsTrueAndDeletedIsFalse(itemId) | ||||
| } | } | ||||
| open fun findFirstByItemIdAndUomId(itemId: Long, uomId: Long): ItemUom? { | |||||
| return itemUomRespository.findFirstByItemIdAndUomIdAndDeletedIsFalse(itemId, uomId) | |||||
| } | |||||
| open fun findPurchaseUnitByM18ItemId(m18ItemId: Long): ItemUom? { | open fun findPurchaseUnitByM18ItemId(m18ItemId: Long): ItemUom? { | ||||
| return itemUomRespository.findByItemM18IdAndPurchaseUnitIsTrueAndDeletedIsFalse(m18ItemId) | return itemUomRespository.findByItemM18IdAndPurchaseUnitIsTrueAndDeletedIsFalse(m18ItemId) | ||||
| } | } | ||||
| @@ -74,6 +78,18 @@ open class ItemUomService( | |||||
| return stockQty; | return stockQty; | ||||
| } | } | ||||
| open fun convertQtyToStockQty(itemId: Long, uomId: Long, sourceQty: BigDecimal): BigDecimal { | |||||
| val itemUom = findFirstByItemIdAndUomId(itemId, uomId) | |||||
| val stockUnit = findStockUnitByItemId(itemId) ?: return BigDecimal.ZERO; | |||||
| val one = BigDecimal.ONE; | |||||
| val baseQty = sourceQty.multiply(itemUom?.ratioN ?: one).divide(itemUom?.ratioD ?: one, 2, RoundingMode.UP) | |||||
| val stockQty = baseQty.multiply(stockUnit.ratioD ?: one).divide(stockUnit.ratioN ?: one, 2, RoundingMode.UP) | |||||
| return stockQty; | |||||
| } | |||||
| // See if need to update the response | // See if need to update the response | ||||
| open fun saveItemUom(request: ItemUomRequest): ItemUom { | open fun saveItemUom(request: ItemUomRequest): ItemUom { | ||||
| val itemUom = request.m18Id?.let { findByM18Id(it) } ?: request.id?.let { findById(it) } ?: ItemUom() | val itemUom = request.m18Id?.let { findByM18Id(it) } ?: request.id?.let { findById(it) } ?: ItemUom() | ||||
| @@ -157,7 +173,7 @@ open class ItemUomService( | |||||
| } | } | ||||
| } | } | ||||
| // Find source ItemUom by itemId and uomId | // Find source ItemUom by itemId and uomId | ||||
| val sourceItemUom = itemUomRespository.findByItemIdAndUomIdAndDeletedIsFalse(request.itemId, request.uomId) | |||||
| val sourceItemUom = itemUomRespository.findFirstByItemIdAndUomIdAndDeletedIsFalse(request.itemId, request.uomId) | |||||
| ?: throw IllegalArgumentException("Source ItemUom not found for itemId=${request.itemId}, uomId=${request.uomId}") | ?: throw IllegalArgumentException("Source ItemUom not found for itemId=${request.itemId}, uomId=${request.uomId}") | ||||
| // Find target ItemUom by itemId and targetUnit | // Find target ItemUom by itemId and targetUnit | ||||
| @@ -700,7 +700,7 @@ val sufficientStockQty = bomMaterials | |||||
| val baseReqQtyResult = if (reqUomId > 0) { | val baseReqQtyResult = if (reqUomId > 0) { | ||||
| try { | try { | ||||
| // First check if ItemUom exists for this item and UomConversion | // First check if ItemUom exists for this item and UomConversion | ||||
| val sourceItemUom = itemUomRepository.findByItemIdAndUomIdAndDeletedIsFalse(itemId, reqUomId) | |||||
| val sourceItemUom = itemUomRepository.findFirstByItemIdAndUomIdAndDeletedIsFalse(itemId, reqUomId) | |||||
| val targetItemUom = itemUomService.findBaseUnitByItemId(itemId) | val targetItemUom = itemUomService.findBaseUnitByItemId(itemId) | ||||
| println("Converting reqQty: ${line.reqQty} from UOM id=$reqUomId to baseUnit") | println("Converting reqQty: ${line.reqQty} from UOM id=$reqUomId to baseUnit") | ||||
| @@ -752,7 +752,7 @@ val sufficientStockQty = bomMaterials | |||||
| val baseStockQtyResult = if (stockUomId != null && stockUomId > 0) { | val baseStockQtyResult = if (stockUomId != null && stockUomId > 0) { | ||||
| try { | try { | ||||
| // Get source and target ItemUom to show ratioN/ratioD | // Get source and target ItemUom to show ratioN/ratioD | ||||
| val sourceItemUom = itemUomRepository.findByItemIdAndUomIdAndDeletedIsFalse(itemId, stockUomId) | |||||
| val sourceItemUom = itemUomRepository.findFirstByItemIdAndUomIdAndDeletedIsFalse(itemId, stockUomId) | |||||
| val targetItemUom = itemUomService.findBaseUnitByItemId(itemId) | val targetItemUom = itemUomService.findBaseUnitByItemId(itemId) | ||||
| println("Converting stockQty: $stockQtyValue from UOM id=$stockUomId to baseUnit") | println("Converting stockQty: $stockQtyValue from UOM id=$stockUomId to baseUnit") | ||||
| @@ -825,7 +825,7 @@ val sufficientStockQty = bomMaterials | |||||
| if (baseReqQtyForStock != null) { | if (baseReqQtyForStock != null) { | ||||
| // Now convert from baseUnit to stockUomId | // Now convert from baseUnit to stockUomId | ||||
| val sourceItemUom = itemUomService.findBaseUnitByItemId(itemId) | val sourceItemUom = itemUomService.findBaseUnitByItemId(itemId) | ||||
| val targetItemUom = itemUomRepository.findByItemIdAndUomIdAndDeletedIsFalse(itemId, stockUomId) | |||||
| val targetItemUom = itemUomRepository.findFirstByItemIdAndUomIdAndDeletedIsFalse(itemId, stockUomId) | |||||
| if (sourceItemUom != null && targetItemUom != null) { | if (sourceItemUom != null && targetItemUom != null) { | ||||
| val sourceRatioN = sourceItemUom.ratioN ?: BigDecimal.ONE | val sourceRatioN = sourceItemUom.ratioN ?: BigDecimal.ONE | ||||
| @@ -0,0 +1,7 @@ | |||||
| --liquibase formatted sql | |||||
| --changeset author:vin m18 | |||||
| ALTER TABLE `fpsmsdb`.`delivery_order_line` | |||||
| ADD COLUMN `qtyM18` DECIMAL(14,2) NULL AFTER `qty`, | |||||
| ADD COLUMN `delivery_order_linecol` VARCHAR(45) NULL AFTER `qtyM18`, | |||||
| ADD COLUMN `uomIdM18` INT NULL AFTER `uomId`; | |||||