@@ -54,6 +54,7 @@ open class M18PurchaseOrderService(
// M18 API
// M18 API
val M18_LOAD_PURCHASE_ORDER_API = "/root/api/read/po"
val M18_LOAD_PURCHASE_ORDER_API = "/root/api/read/po"
val M18_LOAD_PURCHASE_ORDER_BY_CODE_API = "/root/api/read/po"
val M18_FETCH_PURCHASE_ORDER_LIST_API = "/search/search"
val M18_FETCH_PURCHASE_ORDER_LIST_API = "/search/search"
// Include material po, oem po
// Include material po, oem po
@@ -204,16 +205,82 @@ open class M18PurchaseOrderService(
return purchaseOrder
return purchaseOrder
}
}
open fun getPurchaseOrderByCode(code: String): M18PurchaseOrderResponse? {
var purchaseOrder: M18PurchaseOrderResponse? = null
try {
purchaseOrder = apiCallerService.get<M18PurchaseOrderResponse>(
M18_LOAD_PURCHASE_ORDER_BY_CODE_API,
mapOf("code" to code)
).block()
} catch (e: Exception) {
logger.error("(Getting Po Detail By Code) Error on Function - ${e.stackTrace}")
logger.error(e.message)
}
return purchaseOrder
}
private fun resolvePoTypeByBeId(beId: Long?): PurchaseOrderType {
return if (beId?.toString() == m18Config.BEID_TOA) PurchaseOrderType.SHOP else PurchaseOrderType.MATERIAL
}
open fun savePurchaseOrderByCode(code: String): SyncResult {
// Follow the scheduler's original approach:
// 1) use /search/search to find the PO id by code
// 2) then sync by PO id (this reuses the same create/update logic)
val searchRequest = M18PurchaseOrderListRequest(
stSearch = "po",
params = null,
conds = "(code=equal=$code)"
)
val poListResponse = try {
apiCallerService.get<M18PurchaseOrderListResponse, M18PurchaseOrderListRequest>(
M18_FETCH_PURCHASE_ORDER_LIST_API,
searchRequest
).block()
} catch (e: Exception) {
logger.error("(Getting Po List By Code) Error on Function - ${e.stackTrace}")
logger.error(e.message)
null
}
val poValues = poListResponse?.values
if (poValues.isNullOrEmpty()) {
return SyncResult(
totalProcessed = 1,
totalSuccess = 0,
totalFail = 1,
query = "code=equal=$code"
)
}
val request = M18PurchaseOrderListResponseWithType(
valuesWithType = mutableListOf(Pair(PurchaseOrderType.MATERIAL, poListResponse)),
query = "code=equal=$code"
)
return savePurchaseOrdersWithPreparedList(purchaseOrdersWithType = request)
}
open fun savePurchaseOrders(request: M18CommonRequest) : SyncResult{
open fun savePurchaseOrders(request: M18CommonRequest) : SyncResult{
logger.info("--------------------------------------------Start - Saving M18 Purchase Order--------------------------------------------")
val purchaseOrdersWithType = getPurchaseOrdersWithType(request)
val purchaseOrdersWithType = getPurchaseOrdersWithType(request)
val examplePurchaseOrders = listOf<Long>(4764034L)
return savePurchaseOrdersWithPreparedList(
purchaseOrdersWithType = purchaseOrdersWithType,
preloadPurchaseOrderDetails = null
)
}
private fun savePurchaseOrdersWithPreparedList(
purchaseOrdersWithType: M18PurchaseOrderListResponseWithType?,
preloadPurchaseOrderDetails: Map<Long, M18PurchaseOrderResponse?>? = null
): SyncResult {
logger.info("--------------------------------------------Start - Saving M18 Purchase Order--------------------------------------------")
val successList = mutableListOf<Long>()
val successList = mutableListOf<Long>()
val successDetailList = mutableListOf<Long>()
val successDetailList = mutableListOf<Long>()
val failList = mutableListOf<Long>()
val failList = mutableListOf<Long>()
val failDetailList = mutableListOf<Long>()
val failDetailList = mutableListOf<Long>()
val affectedItemIds = mutableSetOf<Long>()
val affectedItemIds = mutableSetOf<Long>()
val uomByM18IdCache = mutableMapOf<Long, com.ffii.fpsms.modules.master.entity.ItemUom?>()
val poRefType = "Purchase Order"
val poRefType = "Purchase Order"
val poLineRefType = "Purchase Order Line"
val poLineRefType = "Purchase Order Line"
@@ -221,7 +288,6 @@ open class M18PurchaseOrderService(
if (purchaseOrdersWithType != null) {
if (purchaseOrdersWithType != null) {
// Loop for Purchase Orders (values)
// Loop for Purchase Orders (values)
purchaseOrdersWithType.valuesWithType.forEach { purchaseOrderWithType ->
purchaseOrdersWithType.valuesWithType.forEach { purchaseOrderWithType ->
val type = purchaseOrderWithType.first
// if success
// if success
val purchaseOrdersValues = purchaseOrderWithType.second?.values
val purchaseOrdersValues = purchaseOrderWithType.second?.values
// if fail
// if fail
@@ -229,7 +295,8 @@ open class M18PurchaseOrderService(
if (purchaseOrdersValues != null) {
if (purchaseOrdersValues != null) {
purchaseOrdersValues.forEach { purchaseOrder ->
purchaseOrdersValues.forEach { purchaseOrder ->
val purchaseOrderDetail = getPurchaseOrder(purchaseOrder.id)
val purchaseOrderDetail =
preloadPurchaseOrderDetails?.get(purchaseOrder.id) ?: getPurchaseOrder(purchaseOrder.id)
var purchaseOrderId: Long? = null //FP-MTMS
var purchaseOrderId: Long? = null //FP-MTMS
@@ -242,10 +309,11 @@ open class M18PurchaseOrderService(
// purchase_order + m18_data_log table
// purchase_order + m18_data_log table
if (mainpo != null) {
if (mainpo != null) {
val m18PurchaseOrderId = mainpo.id
// Find the latest m18 data log by m18 id & type
// Find the latest m18 data log by m18 id & type
// logger.info("${poRefType}: Finding For Latest M18 Data Log...")
// logger.info("${poRefType}: Finding For Latest M18 Data Log...")
val latestPurchaseOrderLog =
val latestPurchaseOrderLog =
m18DataLogService.findLatestM18DataLogWithSuccess(purchaseOrder.i d, poRefType)
m18DataLogService.findLatestM18DataLogWithSuccess(m18PurchaseOrderI d, poRefType)
// logger.info(latestPurchaseOrderLog.toString())
// logger.info(latestPurchaseOrderLog.toString())
// Save to m18_data_log table
// Save to m18_data_log table
@@ -257,7 +325,7 @@ open class M18PurchaseOrderService(
val saveM18PurchaseOrderLogRequest = SaveM18DataLogRequest(
val saveM18PurchaseOrderLogRequest = SaveM18DataLogRequest(
id = null,
id = null,
refType = poRefType,
refType = poRefType,
m18Id = purchaseOrder.i d,
m18Id = m18PurchaseOrderI d,
m18LastModifyDate = commonUtils.timestampToLocalDateTime(mainpo.lastModifyDate),
m18LastModifyDate = commonUtils.timestampToLocalDateTime(mainpo.lastModifyDate),
// dataLog = mainpoJson,
// dataLog = mainpoJson,
statusEnum = M18DataLogStatus.NOT_PROCESS
statusEnum = M18DataLogStatus.NOT_PROCESS
@@ -286,7 +354,7 @@ open class M18PurchaseOrderService(
estimatedArrivalDate = commonUtils.timestampToLocalDateTime(mainpo.dDate),
estimatedArrivalDate = commonUtils.timestampToLocalDateTime(mainpo.dDate),
completeDate = null,
completeDate = null,
status = PurchaseOrderStatus.PENDING.value,
status = PurchaseOrderStatus.PENDING.value,
type = type .value,
type = resolvePoTypeByBeId(mainpo.beId) .value,
m18DataLogId = saveM18PurchaseOrderLog.id,
m18DataLogId = saveM18PurchaseOrderLog.id,
m18BeId = mainpo.beId
m18BeId = mainpo.beId
)
)
@@ -305,13 +373,13 @@ open class M18PurchaseOrderService(
m18DataLogService.saveM18DataLog(successSaveM18PurchaseOrderLogRequest)
m18DataLogService.saveM18DataLog(successSaveM18PurchaseOrderLogRequest)
// log success info
// log success info
successList.add(purchaseOrder.i d)
logger.info("${poRefType}: Saved purchase order. ID: ${savePurchaseOrderResponse.id} | M18 ${poRefType} ID: ${purchaseOrder.i d}")
successList.add(m18PurchaseOrderI d)
logger.info("${poRefType}: Saved purchase order. ID: ${savePurchaseOrderResponse.id} | M18 ${poRefType} ID: ${m18PurchaseOrderI d}")
} catch (e: Exception) {
} catch (e: Exception) {
failList.add(purchaseOrder.i d)
failList.add(m18PurchaseOrderI d)
// logger.error("${poRefType}: Saving Failure!")
// logger.error("${poRefType}: Saving Failure!")
logger.error("Error on Function - ${e.stackTrace} | Type: ${poRefType} | M18 ID: ${purchaseOrder.i d} | Different? ${mainpo.id}")
logger.error("Error on Function - ${e.stackTrace} | Type: ${poRefType} | M18 ID: ${m18PurchaseOrderI d} | Different? ${mainpo.id}")
logger.error(e.message)
logger.error(e.message)
val errorSaveM18PurchaseOrderLogRequest = SaveM18DataLogRequest(
val errorSaveM18PurchaseOrderLogRequest = SaveM18DataLogRequest(
@@ -359,11 +427,10 @@ open class M18PurchaseOrderService(
// logger.info("${poLineRefType}: Saved M18 Data Log. ID: ${saveM18PurchaseOrderLineLog.id}")
// logger.info("${poLineRefType}: Saved M18 Data Log. ID: ${saveM18PurchaseOrderLineLog.id}")
// logger.info("${poLineRefType}: Finding item...")
// logger.info("${poLineRefType}: Finding item...")
val item = itemsService.findByM18Id(line.proId)
val item = itemsService.findByM18Id(line.proId)
var itemId: Long? = null
if (item == null) {
itemId = m18MasterDataService.saveProduct(line.proId)?.id
val itemId: Long? = if (item == null) {
m18MasterDataService.saveProduct(line.proId)?.id
} else {
} else {
itemId = item .id
item.id
}
}
logger.info("${poLineRefType}: Item ID: ${itemId} | M18 Item ID: ${line.proId}")
logger.info("${poLineRefType}: Item ID: ${itemId} | M18 Item ID: ${line.proId}")
@@ -377,13 +444,26 @@ open class M18PurchaseOrderService(
// Save to purchase_order_line table
// Save to purchase_order_line table
// logger.info("${poLineRefType}: Saving purchase order line...")
// logger.info("${poLineRefType}: Saving purchase order line...")
val itemUom = itemId?.let { itemUomService.findPurchaseUnitByItemId(it) }
val purchaseItemUom = itemId?.let { itemUomService.findPurchaseUnitByItemId(it) }
val m18ItemUom = uomByM18IdCache.getOrPut(line.unitId) {
itemUomService.findByM18Id(line.unitId)
}
val qtyM18 = line.qty
val sourceUomId = m18ItemUom?.uom?.id
// qtyM18 is the original qty in M18 line uom.
// System PO line.qty must be qty in purchase unit.
val convertedQty = if (itemId != null && sourceUomId != null) {
itemUomService.convertQtyToPurchaseQty(itemId, sourceUomId, qtyM18)
} else {
qtyM18
}
val savePurchaseOrderLineRequest = SavePurchaseOrderLineRequest(
val savePurchaseOrderLineRequest = SavePurchaseOrderLineRequest(
id = existingPurchaseOrderLine?.id,
id = existingPurchaseOrderLine?.id,
itemId = itemId,
itemId = itemId,
uomId = itemUom?.uom?.id,
uomId = purchaseI temUom?.uom?.id,
purchaseOrderId = purchaseOrderId,
purchaseOrderId = purchaseOrderId,
qty = line.qty,
qty = convertedQty,
qtyM18 = qtyM18,
up = line.up,
up = line.up,
price = line.amt,
price = line.amt,
// m18CurrencyId = mainpo.curId,
// m18CurrencyId = mainpo.curId,
@@ -391,7 +471,8 @@ open class M18PurchaseOrderService(
?: PurchaseOrderLineStatus.PENDING.value,
?: PurchaseOrderLineStatus.PENDING.value,
m18DataLogId = saveM18PurchaseOrderLineLog.id,
m18DataLogId = saveM18PurchaseOrderLineLog.id,
m18Discount = line.disc,
m18Discount = line.disc,
m18Lot = line.lot
m18Lot = line.lot,
uomIdM18 = sourceUomId
)
)
val savePurchaseOrderLineResponse =
val savePurchaseOrderLineResponse =
@@ -443,7 +524,7 @@ open class M18PurchaseOrderService(
val saveM18PurchaseOrderLineLogRequest = SaveM18DataLogRequest(
val saveM18PurchaseOrderLineLogRequest = SaveM18DataLogRequest(
id = null,
id = null,
refType = "${poLineRefType}",
refType = "${poLineRefType}",
m18Id = purchaseOrder.i d,
m18Id = m18PurchaseOrderI d,
m18LastModifyDate = commonUtils.timestampToLocalDateTime(mainpo.lastModifyDate),
m18LastModifyDate = commonUtils.timestampToLocalDateTime(mainpo.lastModifyDate),
// dataLog = mutableMapOf(Pair("Error Message", "${poLineRefType} is null")),
// dataLog = mutableMapOf(Pair("Error Message", "${poLineRefType} is null")),
dataLog = mutableMapOf(
dataLog = mutableMapOf(