|
- 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.M18TestDoRequest
- import com.ffii.fpsms.m18.web.models.M18TestPoRequest
- import com.ffii.fpsms.modules.deliveryOrder.enums.DeliveryOrderLineStatus
- import com.ffii.fpsms.modules.deliveryOrder.enums.DeliveryOrderStatus
- import com.ffii.fpsms.modules.deliveryOrder.service.DeliveryOrderLineService
- import com.ffii.fpsms.modules.deliveryOrder.service.DeliveryOrderService
- import com.ffii.fpsms.modules.deliveryOrder.web.models.SaveDeliveryOrderLineRequest
- import com.ffii.fpsms.modules.deliveryOrder.web.models.SaveDeliveryOrderRequest
- import com.ffii.fpsms.modules.master.entity.Items
- 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.PurchaseOrderType
- 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 M18DeliveryOrderService(
- val m18Config: M18Config,
- val apiCallerService: ApiCallerService,
- val m18DataLogService: M18DataLogService,
- val deliveryOrderService: DeliveryOrderService,
- val deliveryOrderLineService: DeliveryOrderLineService,
- val itemsService: ItemsService,
- val shopService: ShopService,
- val itemUomService: ItemUomService,
- val m18MasterDataService: M18MasterDataService,
- ) {
- 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
- // Sharing same API with po
- val M18_LOAD_PURCHASE_ORDER_API = "/root/api/read/po"
- val M18_FETCH_PURCHASE_ORDER_LIST_API = "/search/search"
-
- // Include shop po
- open fun getDeliveryOrdersWithType(request: M18TestDoRequest): M18PurchaseOrderListResponseWithType? {
- val deliveryOrders = M18PurchaseOrderListResponseWithType(mutableListOf())
- val lastModifyDateConds =
- "lastModifyDate=largerOrEqual=${request.modifiedDateFrom ?: lastModifyDateStart}=and=lastModifyDate=lessOrEqual=${request.modifiedDateTo ?: lastModifyDateEnd}"
-
- // 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 {
- deliveryOrders.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)
- }
-
- return deliveryOrders
- }
-
- open fun getDeliveryOrder(id: Long): M18PurchaseOrderResponse? {
- val deliveryOrderParams = M18PurchaseOrderRequest(
- id = id
- )
-
- var deliveryOrder: M18PurchaseOrderResponse? = null
-
- try {
- deliveryOrder = apiCallerService.get<M18PurchaseOrderResponse, M18PurchaseOrderRequest>(
- M18_LOAD_PURCHASE_ORDER_API,
- deliveryOrderParams
- ).block()
- } catch (e: Exception) {
- logger.error("(Getting Po Detail) Error on Function - ${e.stackTrace}")
- logger.error(e.message)
- }
-
- return deliveryOrder
- }
-
- open fun saveDeliveryOrders(request: M18TestDoRequest) {
- logger.info("--------------------------------------------Start - Saving M18 Delivery Order--------------------------------------------")
- val deliveryOrdersWithType = getDeliveryOrdersWithType(request)
-
- val successList = mutableListOf<Long>()
- val successDetailList = mutableListOf<Long>()
- val failList = mutableListOf<Long>()
- val failDetailList = mutableListOf<Long>()
- val failItemDetailList = mutableListOf<Long>()
-
- val doRefType = "Delivery Order"
- val doLineRefType = "Delivery Order Line"
-
- if (deliveryOrdersWithType != null) {
- // Loop for Delivery Orders (values)
- deliveryOrdersWithType.valuesWithType.forEach { deliveryOrderWithType ->
- val type = deliveryOrderWithType.first
- // if success
- val deliveryOrdersValues = deliveryOrderWithType.second?.values
- // if fail
- val deliveryOrdersMessages = deliveryOrderWithType.second?.messages
-
- if (deliveryOrdersValues != null) {
- deliveryOrdersValues.forEach { deliveryOrder ->
- val deliveryOrderDetail = getDeliveryOrder(deliveryOrder.id)
-
- var deliveryOrderId: Long? = null //FP-MTMS
-
- // Process for Delivery Order (mainpo)
- // Assume only one DO in the DO (search by DO ID)
- val mainpo = deliveryOrderDetail?.data?.mainpo?.get(0)
- val pot = deliveryOrderDetail?.data?.pot
- val deliveryOrderLineMessage = deliveryOrderDetail?.messages
-
- // delivery_order + m18_data_log table
- if (mainpo != null) {
- // Find the latest m18 data log by m18 id & type
- logger.info("${doRefType}: Finding For Latest M18 Data Log...")
- val latestDeliveryOrderLog =
- m18DataLogService.findLatestM18DataLogWithSuccess(deliveryOrder.id, doRefType)
-
- logger.info(latestDeliveryOrderLog.toString())
- // Save to m18_data_log table
- logger.info("${doRefType}: Saving for M18 Data Log...")
- val mainpoJson =
- mainpo::class.memberProperties.associate { prop -> prop.name to prop.getter.call(mainpo) }
- .toMutableMap()
-
- val saveM18DeliveryOrderLogRequest = SaveM18DataLogRequest(
- id = null,
- refType = doRefType,
- m18Id = deliveryOrder.id,
- m18LastModifyDate = commonUtils.timestampToLocalDateTime(mainpo.lastModifyDate),
- // dataLog = mainpoJson,
- statusEnum = M18DataLogStatus.NOT_PROCESS
- )
-
- val saveM18DeliveryOrderLog =
- m18DataLogService.saveM18DataLog(saveM18DeliveryOrderLogRequest)
- // logger.info("${doRefType}: Saved M18 Data Log. ID: ${saveM18DeliveryOrderLog.id}")
-
- try {
- // Find the delivery_order if exist
- logger.info("${doRefType}: Finding exising delivery order...")
- val existingDeliveryOrder =
- latestDeliveryOrderLog?.id?.let { deliveryOrderService.findByM18DataLogId(it) }
- logger.info("${doRefType}: Exising delivery order ID: ${existingDeliveryOrder?.id}")
-
- // Save to delivery_order table
- logger.info("${doRefType}: Saving delivery order...")
- val saveDeliveryOrderRequest = SaveDeliveryOrderRequest(
- id = existingDeliveryOrder?.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 = DeliveryOrderStatus.PENDING.value,
- type = type.value,
- m18DataLogId = saveM18DeliveryOrderLog.id,
- handlerId = null,
- m18BeId = mainpo.beId
- )
-
- val saveDeliveryOrderResponse =
- deliveryOrderService.saveDeliveryOrder(saveDeliveryOrderRequest)
- deliveryOrderId = saveDeliveryOrderResponse.id
-
- // Update m18_data_log with success
- val successSaveM18DeliveryOrderLogRequest = SaveM18DataLogRequest(
- id = saveM18DeliveryOrderLog.id,
- dataLog = mainpoJson,
- statusEnum = M18DataLogStatus.SUCCESS
- )
-
- m18DataLogService.saveM18DataLog(successSaveM18DeliveryOrderLogRequest)
-
- // log success info
- successList.add(deliveryOrder.id)
- logger.info("${doRefType}: Saved delivery order. ID: ${saveDeliveryOrderResponse.id} | M18 ${doRefType} ID: ${deliveryOrder.id}")
-
- } catch (e: Exception) {
- failList.add(deliveryOrder.id)
- logger.error("${doRefType}: Saving Failure!")
- logger.error("Error on Function - ${e.stackTrace} | Type: ${doRefType} | M18 ID: ${deliveryOrder.id} | Different? ${mainpo.id}")
- logger.error(e.message)
-
- val errorSaveM18DeliveryOrderLogRequest = SaveM18DataLogRequest(
- id = saveM18DeliveryOrderLog.id,
- dataLog = mutableMapOf(Pair("Exception Message", e.message)),
- statusEnum = M18DataLogStatus.FAIL
- )
-
- m18DataLogService.saveM18DataLog(errorSaveM18DeliveryOrderLogRequest)
- logger.error("${doRefType}: M18 Data Log Updated! Please see the error. ID: ${saveM18DeliveryOrderLogRequest.id}")
- }
-
- // delivery_order_line + m18_data_log
- // TODO: check deleted po line?
- if (pot != null) {
- // Loop for Delivery Order Lines (pot)
- pot.forEach { line ->
-
- // Find the latest m18 data log by m18 id & type
- logger.info("${doLineRefType}: Finding For Latest M18 Data Log...")
- val latestDeliveryOrderLineLog =
- m18DataLogService.findLatestM18DataLogWithSuccess(line.id, doLineRefType)
- // logger.info("${doLineRefType}: Latest M18 Data Log ID: ${latestDeliveryOrderLineLog?.id}")
-
- // Save to m18_data_log table
- logger.info("${doLineRefType}: Saving for M18 Data Log...")
- val lineJson =
- line::class.memberProperties.associate { prop ->
- prop.name to prop.getter.call(
- line
- )
- }
- .toMutableMap()
- val saveM18DeliveryOrderLineLogRequest = SaveM18DataLogRequest(
- id = null,
- refType = doLineRefType,
- m18Id = line.id,
- m18LastModifyDate = commonUtils.timestampToLocalDateTime(mainpo.lastModifyDate),
- // dataLog = lineJson,
- statusEnum = M18DataLogStatus.NOT_PROCESS
- )
-
- val saveM18DeliveryOrderLineLog =
- m18DataLogService.saveM18DataLog(saveM18DeliveryOrderLineLogRequest)
-
- // logger.info("${doLineRefType}: Saved M18 Data Log. ID: ${saveM18DeliveryOrderLineLog.id}")
- logger.info("${doLineRefType}: Finding item...")
- val item = itemsService.findByM18Id(line.proId)
- var itemId: Long? = null
- if (item == null) {
- itemId = m18MasterDataService.saveProduct(line.proId)?.id
- } else {
- itemId = item.id
- }
-
- logger.info("${doLineRefType}: Item ID: ${itemId} | M18 Item ID: ${line.proId}")
-
- try {
- // Find the delivery_order_line if exist
- logger.info("${doLineRefType}: Finding exising delivery order line...")
- val existingDeliveryOrderLine = latestDeliveryOrderLineLog?.id?.let {
- deliveryOrderLineService.findDeliveryOrderLineByM18Id(it)
- }
- logger.info("${doLineRefType}: Exising delivery order line ID: ${existingDeliveryOrderLine?.id}")
-
- // Save to delivery_order_line table
- logger.info("${doLineRefType}: Saving delivery order line...")
- val itemUom = itemId?.let { itemUomService.findSalesUnitByItemId(it) }
- val saveDeliveryOrderLineRequest = SaveDeliveryOrderLineRequest(
- id = existingDeliveryOrderLine?.id,
- itemId = itemId,
- uomId = itemUom?.uom?.id,
- deliveryOrderId = deliveryOrderId,
- qty = line.qty,
- price = line.amt,
- // m18CurrencyId = mainpo.curId,
- status = existingDeliveryOrderLine?.status?.value
- ?: DeliveryOrderLineStatus.PENDING.value,
- m18DataLogId = saveM18DeliveryOrderLineLog.id,
- m18Discount = line.disc,
- m18Lot = line.lot
- )
-
- val saveDeliveryOrderLineResponse =
- deliveryOrderLineService.saveDeliveryOrderLine(saveDeliveryOrderLineRequest)
-
- // Update m18_data_log with success
- val successSaveM18DeliveryOrderLineLogRequest = SaveM18DataLogRequest(
- id = saveM18DeliveryOrderLineLog.id,
- dataLog = lineJson,
- statusEnum = M18DataLogStatus.SUCCESS
- )
-
- m18DataLogService.saveM18DataLog(successSaveM18DeliveryOrderLineLogRequest)
-
- // log success info
- successDetailList.add(line.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}")
- } catch (e: Exception) {
- failDetailList.add(line.id)
- failItemDetailList.add(line.proId)
- logger.error("${doLineRefType}: Saving Failure!")
- logger.error("Error on Function - ${e.stackTrace} | Type: ${doLineRefType} | M18 ID: ${line.id}")
- logger.error(e.message)
-
- val errorSaveM18DeliveryOrderLineLogRequest = SaveM18DataLogRequest(
- id = saveM18DeliveryOrderLineLog.id,
- dataLog = mutableMapOf(Pair("Exception Message", e.message)),
- statusEnum = M18DataLogStatus.FAIL
- )
-
- m18DataLogService.saveM18DataLog(errorSaveM18DeliveryOrderLineLogRequest)
- logger.error("${doLineRefType}: M18 Data Log Updated! Please see the error. ID: ${saveM18DeliveryOrderLineLog.id}")
- }
- }
- } else {
- // pot
- logger.error("${doLineRefType}: Saving Failure!")
- val saveM18DeliveryOrderLineLogRequest = SaveM18DataLogRequest(
- id = null,
- refType = "${doLineRefType}",
- m18Id = deliveryOrder.id,
- m18LastModifyDate = commonUtils.timestampToLocalDateTime(mainpo.lastModifyDate),
- // dataLog = mutableMapOf(Pair("Error Message", "${doLineRefType} is null")),
- dataLog = mutableMapOf(
- Pair(
- "${doLineRefType} Error Message",
- "pot is null"
- ),
- Pair(
- "${doLineRefType} Error Code",
- deliveryOrderLineMessage?.get(0)?.msgCode ?: "No Msg Code from M18"
- ),
- Pair(
- "${doLineRefType} Error Detail",
- deliveryOrderLineMessage?.get(0)?.msgDetail ?: "No Msg Detail from M18"
- ),
- ),
- statusEnum = M18DataLogStatus.FAIL
- )
-
- val errorLog = m18DataLogService.saveM18DataLog(saveM18DeliveryOrderLineLogRequest)
- logger.error("${doLineRefType}: M18 Data Log Updated! Please see the error. ID: ${errorLog.id}")
- }
- } else {
- // mainpo
- failList.add(deliveryOrder.id)
- logger.error("${doRefType}: Saving Failure!")
- val saveM18DataLogRequest = SaveM18DataLogRequest(
- id = null,
- refType = "${doRefType}",
- m18Id = deliveryOrder.id,
- // m18LastModifyDate = if(mainpo?.lastModifyDate != null) commonUtils.instantToLocalDateTime(mainpo.lastModifyDate) else LocalDateTime.now(),
- m18LastModifyDate = LocalDateTime.now(),
- dataLog = mutableMapOf(
- Pair(
- "${doRefType} Error",
- "mainpo is null"
- ),
- Pair(
- "${doRefType} Error Code",
- deliveryOrdersMessages?.get(0)?.msgCode ?: "No Msg Code from M18"
- ),
- Pair(
- "${doRefType} Error Detail",
- deliveryOrdersMessages?.get(0)?.msgDetail ?: "No Msg Detail from M18"
- ),
- ),
- statusEnum = M18DataLogStatus.FAIL
- )
-
- val errorLog = m18DataLogService.saveM18DataLog(saveM18DataLogRequest)
- logger.error("${doLineRefType}: M18 Data Log Updated! Please see the error. ID: ${errorLog.id}")
- }
- }
- } else {
- logger.error("${doRefType} List is null. May occur errors.")
- }
- }
- } else {
- logger.error("${doRefType} List is null. May occur errors.")
- }
-
- // End of save. Check result
- logger.info("Total Success (${doRefType}) (${successList.size}): $successList")
- // if (failList.size > 0) {
- logger.error("Total Fail (${doRefType}) (${failList.size}): $failList")
- // }
-
- logger.info("Total Success (${doLineRefType}) (${successDetailList.size}): $successDetailList")
- // if (failDetailList.size > 0) {
- logger.error("Total Fail (${doLineRefType}) (${failDetailList.size}): $failDetailList")
- logger.error("Total Fail M18 Items (${doLineRefType}) (${failItemDetailList.distinct().size}): ${failItemDetailList.distinct()}")
- // }
- logger.info("--------------------------------------------End - Saving M18 Delivery Order--------------------------------------------")
- }
- }
|