|
- package com.ffii.fpsms.m18.service
-
- import com.ffii.core.utils.JwtTokenUtil
- import com.ffii.fpsms.api.service.ApiCallerService
- import com.ffii.fpsms.m18.M18Config
- import com.ffii.fpsms.m18.enums.M18DataLogStatus
- import com.ffii.fpsms.m18.model.*
- import com.ffii.fpsms.m18.utils.CommonUtils
- import com.ffii.fpsms.m18.web.models.M18TestPoRequest
- import com.ffii.fpsms.modules.master.service.ItemUomService
- import com.ffii.fpsms.modules.master.service.ItemsService
- import com.ffii.fpsms.modules.master.service.ShopService
- import com.ffii.fpsms.modules.purchaseOrder.enums.PurchaseOrderLineStatus
- import com.ffii.fpsms.modules.purchaseOrder.enums.PurchaseOrderStatus
- import com.ffii.fpsms.modules.purchaseOrder.enums.PurchaseOrderType
- import com.ffii.fpsms.modules.purchaseOrder.service.PurchaseOrderLineService
- import com.ffii.fpsms.modules.purchaseOrder.service.PurchaseOrderService
- import com.ffii.fpsms.modules.purchaseOrder.web.model.SavePurchaseOrderLineRequest
- import com.ffii.fpsms.modules.purchaseOrder.web.model.SavePurchaseOrderRequest
- import org.slf4j.Logger
- import org.slf4j.LoggerFactory
- import org.springframework.stereotype.Service
- import java.time.LocalDateTime
- import kotlin.reflect.full.memberProperties
-
- @Service
- open class M18PurchaseOrderService(
- val m18Config: M18Config,
- val apiCallerService: ApiCallerService,
- val m18DataLogService: M18DataLogService,
- val purchaseOrderService: PurchaseOrderService,
- val purchaseOrderLineService: PurchaseOrderLineService,
- val itemsService: ItemsService,
- val shopService: ShopService,
- val itemUomService: ItemUomService,
- ) {
- val commonUtils = CommonUtils()
- val logger: Logger = LoggerFactory.getLogger(JwtTokenUtil::class.java)
-
- val lastModifyDateStart = "2025-05-14 14:00:00"
- val lastModifyDateEnd = "2025-05-14 14:30:00"
- // val lastModifyDateConds =
- // "lastModifyDate=largerOrEqual=${lastModifyDateStart}=and=lastModifyDate=lessOrEqual=${lastModifyDateEnd}"
- // val lastModifyDate = LocalDateTime.now().minusMinutes(30)
- // val commonConds =
- // "(beId=equal=${m18Config.BEID_PF}=or=beId=equal=${m18Config.BEID_PP}=or=beId=equal=${m18Config.BEID_TOA})=and=lastModifyDate=largerOrEqual=${lastModifyDate}"
-
- // M18 API
- val M18_LOAD_PURCHASE_ORDER_API = "/root/api/read/po"
- val M18_FETCH_PURCHASE_ORDER_LIST_API = "/search/search"
-
- // Include material po, shop po, oem po
- open fun getPurchaseOrdersWithType(request: M18TestPoRequest): M18PurchaseOrderListResponseWithType? {
- val purchaseOrders = M18PurchaseOrderListResponseWithType(mutableListOf())
- val lastModifyDateConds =
- "lastModifyDate=largerOrEqual=${request.modifiedDateFrom ?: lastModifyDateStart}=and=lastModifyDate=lessOrEqual=${request.modifiedDateTo ?: lastModifyDateEnd}"
- // Material PO
- val materialPoBuyers =
- commonUtils.listToString(listOf(m18Config.BEID_PP, m18Config.BEID_PF), "beId=equal=", "=or=")
- val materialPoSupplierNot = commonUtils.listToString(
- shopService.findM18VendorIdsByCodeRegexp(m18Config.MATERIAL_PO_SUPPLIER_NOT),
- "venId=unequal=",
- "=or="
- )
- val materialPoConds = "(${materialPoBuyers})=and=(${materialPoSupplierNot})=and=(${lastModifyDateConds})"
- println("materialPoConds: ${materialPoConds}")
- val materialPoParams = M18PurchaseOrderListRequest(
- params = null,
- conds = materialPoConds
- )
-
- try {
- purchaseOrders.valuesWithType += Pair(
- PurchaseOrderType.MATERIAL,
- apiCallerService.get<M18PurchaseOrderListResponse, M18PurchaseOrderListRequest>(
- M18_FETCH_PURCHASE_ORDER_LIST_API,
- materialPoParams
- ).block()
- )
- } catch (e: Exception) {
- logger.error("(Getting Material Po list) Error on Function - ${e.stackTrace}")
- logger.error(e.message)
- }
-
- // Shop PO
- val shopPoBuyers = commonUtils.listToString(listOf(m18Config.BEID_TOA), "beId=equal=", "=or=")
- val shopPoSupplier = commonUtils.listToString(
- shopService.findM18VendorIdsByCodeRegexp(m18Config.SHOP_PO_SUPPLIER),
- "venId=equal=",
- "=or="
- )
- val shopPoConds = "(${shopPoBuyers})=and=(${shopPoSupplier})=and=(${lastModifyDateConds})"
- println("shopPoConds: ${shopPoConds}")
- val shopPoParams = M18PurchaseOrderListRequest(
- params = null,
- conds = shopPoConds
- )
-
- try {
- purchaseOrders.valuesWithType += Pair(
- PurchaseOrderType.SHOP, apiCallerService.get<M18PurchaseOrderListResponse, M18PurchaseOrderListRequest>(
- M18_FETCH_PURCHASE_ORDER_LIST_API,
- shopPoParams
- ).block()
- )
- } catch (e: Exception) {
- logger.error("(Getting Shop Po list) Error on Function - ${e.stackTrace}")
- logger.error(e.message)
- }
-
- // OEM PO
- /* val oemPoBuyers = commonUtils.listToString(listOf(m18Config.BEID_PF, m18Config.BEID_PP), "beId=equal=", "=or=")
- val oemPoSupplier = commonUtils.listToString(
- shopService.findM18VendorIdsByCodeRegexp(m18Config.OEM_PO_SUPPLIER),
- "venId=equal=",
- "=or="
- )
- val oemPoConds = "(${oemPoBuyers})=and=(${oemPoSupplier})=and=(${lastModifyDateConds})"
- println("oemPoConds: ${oemPoConds}")
- val oemPoParams = M18PurchaseOrderListRequest(
- params = null,
- conds = oemPoConds
- )
-
- try {
- purchaseOrders.valuesWithType += Pair(
- PurchaseOrderType.OEM, apiCallerService.get<M18PurchaseOrderListResponse, M18PurchaseOrderListRequest>(
- M18_FETCH_PURCHASE_ORDER_LIST_API,
- oemPoParams
- ).block()
- )
- } catch (e: Exception) {
- logger.error("(Getting OEM Po list) Error on Function - ${e.stackTrace}")
- logger.error(e.message)
- } */
-
- return purchaseOrders
- }
-
- open fun getPurchaseOrder(id: Long): M18PurchaseOrderResponse? {
- val purchaseOrderParams = M18PurchaseOrderRequest(
- id = id
- )
-
- var purchaseOrder: M18PurchaseOrderResponse? = null
-
- try {
- purchaseOrder = apiCallerService.get<M18PurchaseOrderResponse, M18PurchaseOrderRequest>(
- M18_LOAD_PURCHASE_ORDER_API,
- purchaseOrderParams
- ).block()
- } catch (e: Exception) {
- logger.error("(Getting Po Detail) Error on Function - ${e.stackTrace}")
- logger.error(e.message)
- }
-
- return purchaseOrder
- }
-
- open fun savePurchaseOrders(request: M18TestPoRequest) {
- logger.info("--------------------------------------------Start - Saving M18 Purchase Order--------------------------------------------")
- val purchaseOrdersWithType = getPurchaseOrdersWithType(request)
- val examplePurchaseOrders = listOf<Long>(4764034L)
-
- val successList = mutableListOf<Long>()
- val successDetailList = mutableListOf<Long>()
- val failList = mutableListOf<Long>()
- val failDetailList = mutableListOf<Long>()
-
- val poRefType = "Purchase Order"
- val poLineRefType = "Purchase Order Line"
-
- if (purchaseOrdersWithType != null) {
- // Loop for Purchase Orders (values)
- purchaseOrdersWithType.valuesWithType.forEach { purchaseOrderWithType ->
- val type = purchaseOrderWithType.first
- // if success
- val purchaseOrdersValues = purchaseOrderWithType.second?.values
- // if fail
- val purchaseOrdersMessages = purchaseOrderWithType.second?.messages
-
- if (purchaseOrdersValues != null) {
- purchaseOrdersValues.forEach { purchaseOrder ->
- val purchaseOrderDetail = getPurchaseOrder(purchaseOrder.id)
-
- var purchaseOrderId: Long? = null //FP-MTMS
-
- // Process for Purchase Order (mainpo)
- // Assume only one PO in the PO (search by PO ID)
- val mainpo = purchaseOrderDetail?.data?.mainpo?.get(0)
- val pot = purchaseOrderDetail?.data?.pot
- val purchaseOrderLineMessage = purchaseOrderDetail?.messages
-
- // purchase_order + m18_data_log table
- if (mainpo != null) {
- // Find the latest m18 data log by m18 id & type
- logger.info("${poRefType}: Finding For Latest M18 Data Log...")
- val latestPurchaseOrderLog =
- m18DataLogService.findLatestM18DataLogWithSuccess(purchaseOrder.id, poRefType)
-
- logger.info(latestPurchaseOrderLog.toString())
- // Save to m18_data_log table
- logger.info("${poRefType}: Saving for M18 Data Log...")
- val mainpoJson =
- mainpo::class.memberProperties.associate { prop -> prop.name to prop.getter.call(mainpo) }
- .toMutableMap()
-
- val saveM18PurchaseOrderLogRequest = SaveM18DataLogRequest(
- id = null,
- refType = poRefType,
- m18Id = purchaseOrder.id,
- m18LastModifyDate = commonUtils.timestampToLocalDateTime(mainpo.lastModifyDate),
- // dataLog = mainpoJson,
- statusEnum = M18DataLogStatus.NOT_PROCESS
- )
-
- val saveM18PurchaseOrderLog =
- m18DataLogService.saveM18DataLog(saveM18PurchaseOrderLogRequest)
- // logger.info("${poRefType}: Saved M18 Data Log. ID: ${saveM18PurchaseOrderLog.id}")
-
- try {
- // Find the purchase_order if exist
- logger.info("${poRefType}: Finding exising purchase order...")
- val existingPurchaseOrder =
- latestPurchaseOrderLog?.id?.let { purchaseOrderService.findByM18DataLogId(it) }
- logger.info("${poRefType}: Exising purchase order ID: ${existingPurchaseOrder?.id}")
-
- // Save to purchase_order table
- logger.info("${poRefType}: Saving purchase order...")
- val savePurchaseOrderRequest = SavePurchaseOrderRequest(
- id = existingPurchaseOrder?.id,
- code = mainpo.code,
- m18SupplierId = mainpo.venId,
- m18ShopId = mainpo.virDeptId,
- m18CurrencyId = mainpo.curId,
- orderDate = commonUtils.timestampToLocalDateTime(mainpo.tDate),
- estimatedArrivalDate = commonUtils.timestampToLocalDateTime(mainpo.dDate),
- completeDate = null,
- status = PurchaseOrderStatus.PENDING.value,
- type = type.value,
- m18DataLogId = saveM18PurchaseOrderLog.id,
- )
-
- val savePurchaseOrderResponse =
- purchaseOrderService.savePurchaseOrder(savePurchaseOrderRequest)
- purchaseOrderId = savePurchaseOrderResponse.id
-
- // Update m18_data_log with success
- val successSaveM18PurchaseOrderLogRequest = SaveM18DataLogRequest(
- id = saveM18PurchaseOrderLog.id,
- dataLog = mainpoJson,
- statusEnum = M18DataLogStatus.SUCCESS
- )
-
- m18DataLogService.saveM18DataLog(successSaveM18PurchaseOrderLogRequest)
-
- // log success info
- successList.add(purchaseOrder.id)
- logger.info("${poRefType}: Saved purchase order. ID: ${savePurchaseOrderResponse.id} | M18 ${poRefType} ID: ${purchaseOrder.id}")
-
- } catch (e: Exception) {
- failList.add(purchaseOrder.id)
- logger.error("${poRefType}: Saving Failure!")
- logger.error("Error on Function - ${e.stackTrace} | Type: ${poRefType} | M18 ID: ${purchaseOrder.id} | Different? ${mainpo.id}")
- logger.error(e.message)
-
- val errorSaveM18PurchaseOrderLogRequest = SaveM18DataLogRequest(
- id = saveM18PurchaseOrderLog.id,
- dataLog = mutableMapOf(Pair("Exception Message", e.message)),
- statusEnum = M18DataLogStatus.FAIL
- )
-
- m18DataLogService.saveM18DataLog(errorSaveM18PurchaseOrderLogRequest)
- logger.error("${poRefType}: M18 Data Log Updated! Please see the error. ID: ${saveM18PurchaseOrderLogRequest.id}")
- }
-
- // purchase_order_line + m18_data_log
- // TODO: check deleted po line?
- if (pot != null) {
- // Loop for Purchase Order Lines (pot)
- pot.forEach { line ->
-
- // Find the latest m18 data log by m18 id & type
- logger.info("${poLineRefType}: Finding For Latest M18 Data Log...")
- val latestPurchaseOrderLineLog =
- m18DataLogService.findLatestM18DataLogWithSuccess(line.id, poLineRefType)
- // logger.info("${poLineRefType}: Latest M18 Data Log ID: ${latestPurchaseOrderLineLog?.id}")
-
- // Save to m18_data_log table
- logger.info("${poLineRefType}: Saving for M18 Data Log...")
- val lineJson =
- line::class.memberProperties.associate { prop ->
- prop.name to prop.getter.call(
- line
- )
- }
- .toMutableMap()
- val saveM18PurchaseOrderLineLogRequest = SaveM18DataLogRequest(
- id = null,
- refType = poLineRefType,
- m18Id = line.id,
- m18LastModifyDate = commonUtils.timestampToLocalDateTime(mainpo.lastModifyDate),
- // dataLog = lineJson,
- statusEnum = M18DataLogStatus.NOT_PROCESS
- )
-
- val saveM18PurchaseOrderLineLog =
- m18DataLogService.saveM18DataLog(saveM18PurchaseOrderLineLogRequest)
-
- // logger.info("${poLineRefType}: Saved M18 Data Log. ID: ${saveM18PurchaseOrderLineLog.id}")
- logger.info("${poLineRefType}: Finding item...")
- val item = itemsService.findByM18Id(line.proId)
- logger.info("${poLineRefType}: Item ID: ${item?.id} | M18 Item ID: ${line.proId}")
-
- try {
- // Find the purchase_order_line if exist
- logger.info("${poLineRefType}: Finding exising purchase order line...")
- val existingPurchaseOrderLine = latestPurchaseOrderLineLog?.id?.let {
- purchaseOrderLineService.findPurchaseOrderLineByM18Id(it)
- }
- logger.info("${poLineRefType}: Exising purchase order line ID: ${existingPurchaseOrderLine?.id}")
-
- // Save to purchase_order_line table
- logger.info("${poLineRefType}: Saving purchase order line...")
- val itemUom = item?.id?.let { itemUomService.findPurchaseUnitByItemId(it) }
- val savePurchaseOrderLineRequest = SavePurchaseOrderLineRequest(
- id = existingPurchaseOrderLine?.id,
- itemId = item?.id,
- uomId = itemUom?.uom?.id,
- purchaseOrderId = purchaseOrderId,
- qty = line.qty,
- price = line.amt,
- // m18CurrencyId = mainpo.curId,
- status = existingPurchaseOrderLine?.status?.value
- ?: PurchaseOrderLineStatus.PENDING.value,
- m18DataLogId = saveM18PurchaseOrderLineLog.id,
- )
-
- val savePurchaseOrderLineResponse =
- purchaseOrderLineService.savePurchaseOrderLine(savePurchaseOrderLineRequest)
-
- // Update m18_data_log with success
- val successSaveM18PurchaseOrderLineLogRequest = SaveM18DataLogRequest(
- id = saveM18PurchaseOrderLineLog.id,
- dataLog = lineJson,
- statusEnum = M18DataLogStatus.SUCCESS
- )
-
- m18DataLogService.saveM18DataLog(successSaveM18PurchaseOrderLineLogRequest)
-
- // log success info
- successDetailList.add(line.id)
- logger.info("${poLineRefType}: Purchase order ID: ${purchaseOrderId} | M18 ID: ${purchaseOrder.id}")
- logger.info("${poLineRefType}: Saved purchase order line. ID: ${savePurchaseOrderLineResponse.id} | M18 Line ID: ${line.id}")
- } catch (e: Exception) {
- failDetailList.add(line.id)
- logger.error("${poLineRefType}: Saving Failure!")
- logger.error("Error on Function - ${e.stackTrace} | Type: ${poLineRefType} | M18 ID: ${line.id}")
- logger.error(e.message)
-
- val errorSaveM18PurchaseOrderLineLogRequest = SaveM18DataLogRequest(
- id = saveM18PurchaseOrderLineLog.id,
- dataLog = mutableMapOf(Pair("Exception Message", e.message)),
- statusEnum = M18DataLogStatus.FAIL
- )
-
- m18DataLogService.saveM18DataLog(errorSaveM18PurchaseOrderLineLogRequest)
- logger.error("${poLineRefType}: M18 Data Log Updated! Please see the error. ID: ${saveM18PurchaseOrderLineLog.id}")
- }
- }
- } else {
- // pot
- logger.error("${poLineRefType}: Saving Failure!")
- val saveM18PurchaseOrderLineLogRequest = SaveM18DataLogRequest(
- id = null,
- refType = "${poLineRefType}",
- m18Id = purchaseOrder.id,
- m18LastModifyDate = commonUtils.timestampToLocalDateTime(mainpo.lastModifyDate),
- // dataLog = mutableMapOf(Pair("Error Message", "${poLineRefType} is null")),
- dataLog = mutableMapOf(
- Pair(
- "${poLineRefType} Error Message",
- "pot is null"
- ),
- Pair(
- "${poLineRefType} Error Code",
- purchaseOrderLineMessage?.get(0)?.msgCode ?: "No Msg Code from M18"
- ),
- Pair(
- "${poLineRefType} Error Detail",
- purchaseOrderLineMessage?.get(0)?.msgDetail ?: "No Msg Detail from M18"
- ),
- ),
- statusEnum = M18DataLogStatus.FAIL
- )
-
- val errorLog = m18DataLogService.saveM18DataLog(saveM18PurchaseOrderLineLogRequest)
- logger.error("${poLineRefType}: M18 Data Log Updated! Please see the error. ID: ${errorLog.id}")
- }
- } else {
- // mainpo
- failList.add(purchaseOrder.id)
- logger.error("${poRefType}: Saving Failure!")
- val saveM18DataLogRequest = SaveM18DataLogRequest(
- id = null,
- refType = "${poRefType}",
- m18Id = purchaseOrder.id,
- // m18LastModifyDate = if(mainpo?.lastModifyDate != null) commonUtils.instantToLocalDateTime(mainpo.lastModifyDate) else LocalDateTime.now(),
- m18LastModifyDate = LocalDateTime.now(),
- dataLog = mutableMapOf(
- Pair(
- "${poRefType} Error",
- "mainpo is null"
- ),
- Pair(
- "${poRefType} Error Code",
- purchaseOrdersMessages?.get(0)?.msgCode ?: "No Msg Code from M18"
- ),
- Pair(
- "${poRefType} Error Detail",
- purchaseOrdersMessages?.get(0)?.msgDetail ?: "No Msg Detail from M18"
- ),
- ),
- statusEnum = M18DataLogStatus.FAIL
- )
-
- val errorLog = m18DataLogService.saveM18DataLog(saveM18DataLogRequest)
- logger.error("${poLineRefType}: M18 Data Log Updated! Please see the error. ID: ${errorLog.id}")
- }
- }
- } else {
- logger.error("${poRefType} List is null. May occur errors.")
- }
- }
- } else {
- logger.error("${poRefType} List is null. May occur errors.")
- }
-
- // End of save. Check result
- logger.info("Total Success (${poRefType}) (${successList.size}): $successList")
- // if (failList.size > 0) {
- logger.error("Total Fail (${poRefType}) (${failList.size}): $failList")
- // }
-
- logger.info("Total Success (${poLineRefType}) (${successDetailList.size}): $successDetailList")
- // if (failDetailList.size > 0) {
- logger.error("Total Fail (${poLineRefType}) (${failDetailList.size}): $failDetailList")
- // }
- logger.info("--------------------------------------------End - Saving M18 Purchase Order--------------------------------------------")
- }
- }
|