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.model.* import com.ffii.fpsms.m18.utils.CommonUtils 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.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.LocalDate 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 dateTimeConverter = CommonUtils() val logger: Logger = LoggerFactory.getLogger(JwtTokenUtil::class.java) val lastModifyDate = LocalDate.now().minusDays(1) 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" open fun getPurchaseOrders(): M18PurchaseOrderListResponse? { val purchaseOrdersParams = M18PurchaseOrderListRequest( params = null, conds = commonConds ) var purchaseOrders: M18PurchaseOrderListResponse? = null try { purchaseOrders = apiCallerService.get( M18_FETCH_PURCHASE_ORDER_LIST_API, purchaseOrdersParams ).block() } catch (e: Exception) { logger.error("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( M18_LOAD_PURCHASE_ORDER_API, purchaseOrderParams ).block() } catch (e: Exception) { logger.error("Error on Function - ${e.stackTrace}") logger.error(e.message) } return purchaseOrder } open fun savePurchaseOrders() { val purchaseOrders = getPurchaseOrders() val examplePurchaseOrders = listOf(4764034L) val successList = mutableListOf() val successDetailList = mutableListOf() val failList = mutableListOf() val failDetailList = mutableListOf() if (purchaseOrders != null) { // Loop for Purchase Orders (values) purchaseOrders.values.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 // purchase_order + m18_data_log table if (mainPo != null) { val poRefType = "Purchase Order" // Find the latest m18 data log by m18 id & type val latestM18DataLog = m18DataLogService.findLatestM18DataLog(purchaseOrder.id, poRefType) // Save to m18_data_log table 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 = dateTimeConverter.InstantToLocalDateTime(mainPo.lastModifyDate), dataLog = mainPoJson, status = true ) val saveM18PurchaseOrderLog = m18DataLogService.saveM18DataLog(saveM18PurchaseOrderLogRequest) try { // Find the purchase_order if exist val existingPurchaseOrder = latestM18DataLog?.id?.let { purchaseOrderService.findPurchaseOrderByM18Id(it) } // Save to purchase_order table val supplierId = shopService.findByM18Id(mainPo.venId)?.id val savePurchaseOrderRequest = SavePurchaseOrderRequest( id = existingPurchaseOrder?.id, code = mainPo.code, supplierId = supplierId, orderDate = dateTimeConverter.InstantToLocalDateTime(mainPo.tDate), estimatedArrivalDate = dateTimeConverter.InstantToLocalDateTime(mainPo.dDate), completeDate = null, status = PurchaseOrderStatus.PENDING.value, m18DataLogId = saveM18PurchaseOrderLog.id, ) val savePurchaseOrderResponse = purchaseOrderService.savePurchaseOrder(savePurchaseOrderRequest) purchaseOrderId = savePurchaseOrderResponse.id successList.add(purchaseOrder.id) } catch (e: Exception) { failList.add(purchaseOrder.id) logger.error("Error on Function - ${e.stackTrace} | Type: Purchase Order | M18 ID: ${purchaseOrder.id} | Different? ${mainPo.id}") logger.error(e.message) val errorSaveM18PurchaseOrderLogRequest = SaveM18DataLogRequest( id = saveM18PurchaseOrderLogRequest.id, refType = "Purchase Order", m18Id = purchaseOrder.id, m18LastModifyDate = dateTimeConverter.InstantToLocalDateTime(mainPo.lastModifyDate), dataLog = mainPoJson, status = false ) m18DataLogService.saveM18DataLog(errorSaveM18PurchaseOrderLogRequest) } // purchase_order_line + m18_data_log if (pot != null) { // Loop for Purchase Order Lines (pot) pot.forEach { line -> val poLineRefType = "Purchase Order Line" // Find the latest m18 data log by m18 id & type val latestM18DataLog = m18DataLogService.findLatestM18DataLog(line.id, poLineRefType) // Save to m18_data_log table 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 = dateTimeConverter.InstantToLocalDateTime(mainPo.lastModifyDate), dataLog = lineJson, status = true ) val saveM18PurchaseOrderLineLog = m18DataLogService.saveM18DataLog(saveM18PurchaseOrderLineLogRequest) val item = itemsService.findByM18Id(line.id) logger.info("Item ID: ${item?.id}") try { // Find the purchase_order_line if exist val existingPurchaseOrderLine = latestM18DataLog?.id?.let { purchaseOrderLineService.findPurchaseOrderLineByM18Id(it) } // Save to purchase_order_line table val savePurchaseOrderLineRequest = SavePurchaseOrderLineRequest( id = existingPurchaseOrderLine?.id, itemId = item?.id, uomId = null, purchaseOrderId = purchaseOrderId, qty = line.qty, price = line.amt, priceUnit = null, status = existingPurchaseOrderLine?.status?.value ?: PurchaseOrderLineStatus.PENDING.value, m18DataLogId = saveM18PurchaseOrderLineLog.id, ) purchaseOrderLineService.savePurchaseOrderLine(savePurchaseOrderLineRequest) } catch (e: Exception) { failDetailList.add(line.id) logger.error("Error on Function - ${e.stackTrace} | Type: Purchase Order Line | M18 ID: ${line.id}") logger.error(e.message) val errorSaveM18PurchaseOrderLineLogRequest = SaveM18DataLogRequest( id = saveM18PurchaseOrderLineLog.id, refType = "Purchase Order", m18Id = line.id, m18LastModifyDate = dateTimeConverter.InstantToLocalDateTime(mainPo.lastModifyDate), dataLog = lineJson, status = false ) m18DataLogService.saveM18DataLog(errorSaveM18PurchaseOrderLineLogRequest) } } } else { val saveM18PurchaseOrderLineLogRequest = SaveM18DataLogRequest( id = null, refType = "Purchase Order Line", m18Id = purchaseOrder.id, m18LastModifyDate = dateTimeConverter.InstantToLocalDateTime(mainPo.lastModifyDate), dataLog = mutableMapOf(Pair("Error Message", "Purchase Order Line is null")), status = false ) m18DataLogService.saveM18DataLog(saveM18PurchaseOrderLineLogRequest) } } else { val saveM18DataLogRequest = SaveM18DataLogRequest( id = null, refType = "Purchase Order", m18Id = purchaseOrder.id, // m18LastModifyDate = if(mainPo?.lastModifyDate != null) dateTimeConverter.InstantToLocalDateTime(mainPo.lastModifyDate) else LocalDateTime.now(), m18LastModifyDate = LocalDateTime.now(), dataLog = mutableMapOf(Pair("Error Message", "Purchase Order is null")), status = false ) m18DataLogService.saveM18DataLog(saveM18DataLogRequest) } } } else { logger.error("Purchase Order List is null. May occur errors.") } // End of save. Check result logger.info("Total Success (Purchase Order) (${successList.size}): $successList") if (failList.size > 0) { logger.error("Total Fail (Purchase Order) (${failList.size}): $failList") } logger.info("Total Success (Purchase Order Line) (${successDetailList.size}): $successDetailList") if (failDetailList.size > 0) { logger.error("Total Fail (Purchase Order Line) (${failDetailList.size}): $failDetailList") } } }