| @@ -0,0 +1,412 @@ | |||
| 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 | |||
| ) | |||
| 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, | |||
| ) | |||
| 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--------------------------------------------") | |||
| } | |||
| } | |||
| @@ -6,6 +6,7 @@ import com.ffii.fpsms.m18.M18Config | |||
| import com.ffii.fpsms.m18.model.* | |||
| import com.ffii.fpsms.m18.utils.CommonUtils | |||
| import com.ffii.fpsms.m18.web.models.M18TestMasterDateRequest | |||
| import com.ffii.fpsms.modules.master.entity.Items | |||
| import com.ffii.fpsms.modules.master.entity.UomConversion | |||
| import com.ffii.fpsms.modules.master.enums.ShopType | |||
| import com.ffii.fpsms.modules.master.service.* | |||
| @@ -137,6 +138,82 @@ open class M18MasterDataService( | |||
| ) | |||
| } | |||
| open fun saveProduct(id: Long): MessageResponse? { | |||
| try { | |||
| val itemDetail = getProduct(id) | |||
| val pro = itemDetail?.data?.pro?.get(0) | |||
| val price = itemDetail?.data?.price | |||
| if (itemDetail != null && pro != null) { | |||
| val existingItem = itemsService.findByM18Id(id) | |||
| val saveItemRequest = NewItemRequest( | |||
| code = pro.code, | |||
| name = pro.desc, | |||
| // type = if (pro.seriesId == m18Config.SERIESID_PF) ProductType.MATERIAL | |||
| // else ItemType.PRODUCT, | |||
| type = ItemType.MATERIAL, | |||
| id = existingItem?.id, | |||
| description = pro.desc, | |||
| remarks = null, | |||
| shelfLife = null, | |||
| countryOfOrigin = null, | |||
| maxQty = null, | |||
| m18Id = id, | |||
| m18LastModifyDate = commonUtils.timestampToLocalDateTime(pro.lastModifyDate) | |||
| ) | |||
| val savedItem = itemsService.saveItem(saveItemRequest) | |||
| logger.info("Processing item uom...") | |||
| // Find the item uom that ready to delete (not in m18) | |||
| val existingItemUoms = savedItem.id?.let { itemUomService.findAllByItemsId(it) } | |||
| val m18ItemUomIds = price?.map { it.id } ?: listOf() | |||
| // Delete the item uom | |||
| logger.info("Deleting item uom...") | |||
| // logger.info("Item Uom: ${existingItemUoms?.map { it.m18Id }}") | |||
| // logger.info("M18: ${m18ItemUomIds}") | |||
| existingItemUoms?.filter { it.m18Id !in m18ItemUomIds }?.mapNotNull { it.id } | |||
| ?.let { itemUomService.deleteItemUoms(it) } | |||
| // Update the item uom | |||
| logger.info("Updating item uom...") | |||
| price?.forEach { | |||
| val itemUomRequest = ItemUomRequest( | |||
| m18UomId = it.unitId, | |||
| itemId = savedItem.id, | |||
| baseUnit = it.basicUnit, | |||
| stockUnit = it.stkUnit, | |||
| pickingUnit = it.pickUnit, | |||
| salesUnit = it.saleUnit, | |||
| purchaseUnit = it.purUnit, | |||
| price = null, | |||
| currencyId = null, | |||
| m18Id = it.id, | |||
| m18LastModifyDate = commonUtils.timestampToLocalDateTime(pro.lastModifyDate), | |||
| ratioD = it.ratioD, | |||
| ratioN = it.ratioN, | |||
| deleted = it.expired | |||
| ) | |||
| // logger.info("saved item id: ${savedItem.id}") | |||
| itemUomService.saveItemUom(itemUomRequest) | |||
| } | |||
| logger.info("Success (M18 Item): ${id} | ${pro.code} | ${pro.desc}") | |||
| return savedItem | |||
| } else { | |||
| logger.error("Fail Message: ${itemDetail?.messages?.get(0)?.msgDetail}") | |||
| logger.error("Fail: Item ID - ${id} Not Found") | |||
| return null | |||
| } | |||
| } catch (e: Exception) { | |||
| logger.error("Exception") | |||
| logger.error("Fail Message: ${e.message}") | |||
| logger.error("Fail: Item ID - ${id}") | |||
| return null | |||
| } | |||
| } | |||
| open fun saveProducts(request: M18TestMasterDateRequest) { | |||
| logger.info("--------------------------------------------Start - Saving M18 Products / Materials--------------------------------------------") | |||
| val items = getProducts(request) | |||
| @@ -7,6 +7,8 @@ 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.deliveryOrder.service.DeliveryOrderLineService | |||
| import com.ffii.fpsms.modules.deliveryOrder.service.DeliveryOrderService | |||
| import com.ffii.fpsms.modules.master.service.ItemUomService | |||
| import com.ffii.fpsms.modules.master.service.ItemsService | |||
| import com.ffii.fpsms.modules.master.service.ShopService | |||
| @@ -30,9 +32,12 @@ open class M18PurchaseOrderService( | |||
| val m18DataLogService: M18DataLogService, | |||
| val purchaseOrderService: PurchaseOrderService, | |||
| val purchaseOrderLineService: PurchaseOrderLineService, | |||
| 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) | |||
| @@ -49,7 +54,7 @@ open class M18PurchaseOrderService( | |||
| 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 | |||
| // Include material po, oem po | |||
| open fun getPurchaseOrdersWithType(request: M18TestPoRequest): M18PurchaseOrderListResponseWithType? { | |||
| val purchaseOrders = M18PurchaseOrderListResponseWithType(mutableListOf()) | |||
| val lastModifyDateConds = | |||
| @@ -83,7 +88,7 @@ open class M18PurchaseOrderService( | |||
| } | |||
| // Shop PO | |||
| val shopPoBuyers = commonUtils.listToString(listOf(m18Config.BEID_TOA), "beId=equal=", "=or=") | |||
| /* val shopPoBuyers = commonUtils.listToString(listOf(m18Config.BEID_TOA), "beId=equal=", "=or=") | |||
| val shopPoSupplier = commonUtils.listToString( | |||
| shopService.findM18VendorIdsByCodeRegexp(m18Config.SHOP_PO_SUPPLIER), | |||
| "venId=equal=", | |||
| @@ -106,7 +111,7 @@ open class M18PurchaseOrderService( | |||
| } 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=") | |||
| @@ -310,7 +315,13 @@ open class M18PurchaseOrderService( | |||
| // 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}") | |||
| var itemId: Long? = null | |||
| if (item == null) { | |||
| itemId = m18MasterDataService.saveProduct(line.proId)?.id | |||
| } else { | |||
| itemId = item.id | |||
| } | |||
| logger.info("${poLineRefType}: Item ID: ${itemId} | M18 Item ID: ${line.proId}") | |||
| try { | |||
| // Find the purchase_order_line if exist | |||
| @@ -322,10 +333,10 @@ open class M18PurchaseOrderService( | |||
| // Save to purchase_order_line table | |||
| logger.info("${poLineRefType}: Saving purchase order line...") | |||
| val itemUom = item?.id?.let { itemUomService.findPurchaseUnitByItemId(it) } | |||
| val itemUom = itemId?.let { itemUomService.findPurchaseUnitByItemId(it) } | |||
| val savePurchaseOrderLineRequest = SavePurchaseOrderLineRequest( | |||
| id = existingPurchaseOrderLine?.id, | |||
| itemId = item?.id, | |||
| itemId = itemId, | |||
| uomId = itemUom?.uom?.id, | |||
| purchaseOrderId = purchaseOrderId, | |||
| qty = line.qty, | |||
| @@ -2,9 +2,11 @@ package com.ffii.fpsms.m18.web | |||
| import com.ffii.core.utils.JwtTokenUtil | |||
| import com.ffii.fpsms.m18.M18Config | |||
| import com.ffii.fpsms.m18.service.M18DeliveryOrderService | |||
| import com.ffii.fpsms.m18.service.M18MasterDataService | |||
| import com.ffii.fpsms.m18.service.M18PurchaseOrderService | |||
| import com.ffii.fpsms.m18.service.M18PurchaseQuotationService | |||
| import com.ffii.fpsms.m18.web.models.M18TestDoRequest | |||
| import com.ffii.fpsms.m18.web.models.M18TestMasterDateRequest | |||
| import com.ffii.fpsms.m18.web.models.M18TestPoRequest | |||
| import com.ffii.fpsms.m18.web.models.M18TestPqRequest | |||
| @@ -18,12 +20,7 @@ import com.ffii.fpsms.modules.master.service.ShopService | |||
| import jakarta.validation.Valid | |||
| import org.slf4j.Logger | |||
| import org.slf4j.LoggerFactory | |||
| import org.springframework.web.bind.annotation.GetMapping | |||
| import org.springframework.web.bind.annotation.PostMapping | |||
| import org.springframework.web.bind.annotation.RequestBody | |||
| import org.springframework.web.bind.annotation.RequestMapping | |||
| import org.springframework.web.bind.annotation.RequestParam | |||
| import org.springframework.web.bind.annotation.RestController | |||
| import org.springframework.web.bind.annotation.* | |||
| @RestController | |||
| @@ -37,6 +34,7 @@ class M18TestController ( | |||
| private val m18Config: M18Config, | |||
| private val itemUomService: ItemUomService, | |||
| private val m18PurchaseQuotationService: M18PurchaseQuotationService, | |||
| private val m18DeliveryOrderService: M18DeliveryOrderService, | |||
| ) { | |||
| var logger: Logger = LoggerFactory.getLogger(JwtTokenUtil::class.java) | |||
| @@ -95,6 +93,12 @@ class M18TestController ( | |||
| m18MasterDataService.saveProducts(request) | |||
| } | |||
| @GetMapping("/product/{id}") | |||
| fun m18Product(@PathVariable id: Long) { | |||
| logger.info("Access token: ${m18Config.ACCESS_TOKEN}") | |||
| m18MasterDataService.saveProduct(id) | |||
| } | |||
| @PostMapping("/vendor") | |||
| fun m18Vendor(@Valid @RequestBody request: M18TestMasterDateRequest) { | |||
| logger.info("Access token: ${m18Config.ACCESS_TOKEN}") | |||
| @@ -132,6 +136,13 @@ class M18TestController ( | |||
| m18PurchaseOrderService.savePurchaseOrders(request) | |||
| } | |||
| // --------------------------------------------- Purchase Order --------------------------------------------- /// | |||
| @PostMapping("/do") | |||
| fun m18DO(@Valid @RequestBody request: M18TestDoRequest) { | |||
| logger.info("Access token: ${m18Config.ACCESS_TOKEN}") | |||
| m18DeliveryOrderService.saveDeliveryOrders(request) | |||
| } | |||
| // --------------------------------------------- Purchase Quotation --------------------------------------------- /// | |||
| @PostMapping("/pq") | |||
| fun m18PQ(@Valid @RequestBody request: M18TestPqRequest) { | |||
| @@ -5,6 +5,11 @@ data class M18TestPoRequest( | |||
| val modifiedDateTo: String?, | |||
| ) | |||
| data class M18TestDoRequest( | |||
| val modifiedDateFrom: String?, | |||
| val modifiedDateTo: String?, | |||
| ) | |||
| data class M18TestPqRequest( | |||
| val modifiedDateFrom: String? = null, | |||
| val modifiedDateTo: String? = null, | |||
| @@ -3,6 +3,9 @@ package com.ffii.fpsms.modules.deliveryOrder.entity | |||
| import com.fasterxml.jackson.annotation.JsonBackReference | |||
| import com.ffii.core.entity.BaseEntity | |||
| import com.ffii.fpsms.m18.entity.M18DataLog | |||
| import com.ffii.fpsms.modules.deliveryOrder.enums.DeliveryOrderLineStatus | |||
| import com.ffii.fpsms.modules.deliveryOrder.enums.DeliveryOrderLineStatusConverter | |||
| import com.ffii.fpsms.modules.deliveryOrder.enums.DeliveryOrderStatusConverter | |||
| import com.ffii.fpsms.modules.master.entity.Items | |||
| import com.ffii.fpsms.modules.master.entity.UomConversion | |||
| import com.ffii.fpsms.modules.purchaseOrder.entity.PurchaseOrderLine | |||
| @@ -35,10 +38,10 @@ open class DeliveryOrderLine: BaseEntity<Long>() { | |||
| @Column(name = "price", precision = 14, scale = 2) | |||
| open var price: BigDecimal? = null | |||
| @Size(max = 30) | |||
| @NotNull | |||
| @Column(name = "status", nullable = false, length = 30) | |||
| open var status: String? = null | |||
| @Convert(converter = DeliveryOrderLineStatusConverter::class) | |||
| open var status: DeliveryOrderLineStatus? = null | |||
| @NotNull | |||
| @ManyToOne | |||
| @@ -2,7 +2,9 @@ package com.ffii.fpsms.modules.deliveryOrder.entity | |||
| import com.ffii.core.support.AbstractRepository | |||
| import org.springframework.stereotype.Repository | |||
| import java.io.Serializable | |||
| @Repository | |||
| interface DeliveryOrderLineRepository : AbstractRepository<DeliveryOrderLine, Long> { | |||
| fun findByM18DataLogIdAndDeletedIsFalse(m18datalogId: Serializable): DeliveryOrderLine? | |||
| } | |||
| @@ -0,0 +1,7 @@ | |||
| package com.ffii.fpsms.modules.deliveryOrder.enums | |||
| enum class DeliveryOrderLineStatus(val value: String) { | |||
| PENDING("pending"), | |||
| PICKING("picking"), | |||
| COMPLETED("completed"); | |||
| } | |||
| @@ -0,0 +1,18 @@ | |||
| package com.ffii.fpsms.modules.deliveryOrder.enums | |||
| import jakarta.persistence.AttributeConverter | |||
| import jakarta.persistence.Converter | |||
| // Delivery Order Line Status | |||
| @Converter(autoApply = true) | |||
| class DeliveryOrderLineStatusConverter : AttributeConverter<DeliveryOrderLineStatus, String>{ | |||
| override fun convertToDatabaseColumn(status: DeliveryOrderLineStatus?): String? { | |||
| return status?.value | |||
| } | |||
| override fun convertToEntityAttribute(value: String?): DeliveryOrderLineStatus? { | |||
| return value?.let { v -> | |||
| DeliveryOrderLineStatus.entries.find { it.value == v } | |||
| } | |||
| } | |||
| } | |||
| @@ -0,0 +1,64 @@ | |||
| package com.ffii.fpsms.modules.deliveryOrder.service | |||
| import com.ffii.fpsms.m18.entity.M18DataLogRepository | |||
| import com.ffii.fpsms.modules.deliveryOrder.entity.DeliveryOrderLine | |||
| import com.ffii.fpsms.modules.deliveryOrder.entity.DeliveryOrderLineRepository | |||
| import com.ffii.fpsms.modules.deliveryOrder.entity.DeliveryOrderRepository | |||
| import com.ffii.fpsms.modules.deliveryOrder.enums.DeliveryOrderLineStatus | |||
| import com.ffii.fpsms.modules.deliveryOrder.web.models.SaveDeliveryOrderLineRequest | |||
| import com.ffii.fpsms.modules.deliveryOrder.web.models.SaveDeliveryOrderLineResponse | |||
| import com.ffii.fpsms.modules.master.entity.ItemsRepository | |||
| import com.ffii.fpsms.modules.master.service.UomConversionService | |||
| import org.springframework.stereotype.Service | |||
| import kotlin.jvm.optionals.getOrDefault | |||
| import kotlin.jvm.optionals.getOrNull | |||
| @Service | |||
| open class DeliveryOrderLineService( | |||
| private val deliveryOrderService: DeliveryOrderService, | |||
| private val deliveryOrderRepository: DeliveryOrderRepository, | |||
| private val deliveryOrderLineRepository: DeliveryOrderLineRepository, | |||
| private val itemsRepository: ItemsRepository, | |||
| private val m18DataLogRepository: M18DataLogRepository, | |||
| private val uomConversionService: UomConversionService, | |||
| ) { | |||
| open fun findDeliveryOrderLineByM18Id(m18DataLogId: Long): DeliveryOrderLine? { | |||
| return deliveryOrderLineRepository.findByM18DataLogIdAndDeletedIsFalse(m18DataLogId) | |||
| } | |||
| open fun saveDeliveryOrderLine(request: SaveDeliveryOrderLineRequest): SaveDeliveryOrderLineResponse { | |||
| val deliveryOrderLine = request.id?.let { | |||
| deliveryOrderLineRepository.findById(it).getOrDefault( | |||
| DeliveryOrderLine() | |||
| ) | |||
| } ?: DeliveryOrderLine(); | |||
| val item = request.itemId?.let { itemsRepository.findById(it).getOrNull() } | |||
| val deliveryOrder = request.deliveryOrderId?.let { deliveryOrderRepository.findById(it).getOrNull() } | |||
| val status = request.status?.let { status -> DeliveryOrderLineStatus.entries.find { it.value == status } } | |||
| val m18DataLog = request.m18DataLogId?.let { m18DataLogRepository.findById(it).getOrNull() } | |||
| val uom = request.uomId?.let { uomConversionService.find(it).getOrNull() } | |||
| deliveryOrderLine.apply { | |||
| this.item = item | |||
| itemNo = item?.code | |||
| this.deliveryOrder = deliveryOrder | |||
| qty = request.qty | |||
| price = request.price | |||
| this.uom = uom | |||
| this.status = status | |||
| this.m18DataLog = m18DataLog ?: this.m18DataLog | |||
| } | |||
| val savedDeliveryOrderLine = deliveryOrderLineRepository.saveAndFlush(deliveryOrderLine).let { | |||
| SaveDeliveryOrderLineResponse( | |||
| id = it.id, | |||
| itemNo = it.itemNo, | |||
| qty = it.qty, | |||
| price = it.price, | |||
| status = it.status?.value | |||
| ) | |||
| } | |||
| return savedDeliveryOrderLine | |||
| } | |||
| } | |||
| @@ -0,0 +1,14 @@ | |||
| package com.ffii.fpsms.modules.deliveryOrder.web.models | |||
| import java.math.BigDecimal | |||
| data class SaveDeliveryOrderLineRequest( | |||
| val id: Long?, | |||
| val itemId: Long?, | |||
| val uomId: Long?, | |||
| val deliveryOrderId: Long?, | |||
| val qty: BigDecimal?, | |||
| val price: BigDecimal?, | |||
| val status: String?, | |||
| val m18DataLogId: Long?, | |||
| ) | |||
| @@ -0,0 +1,11 @@ | |||
| package com.ffii.fpsms.modules.deliveryOrder.web.models | |||
| import java.math.BigDecimal | |||
| data class SaveDeliveryOrderLineResponse( | |||
| val id: Long?, | |||
| val itemNo: String?, | |||
| val qty: BigDecimal?, | |||
| val price: BigDecimal?, | |||
| val status: String?, | |||
| ) | |||
| @@ -17,6 +17,8 @@ interface ItemUomRespository : AbstractRepository<ItemUom, Long> { | |||
| fun findByItemIdAndPurchaseUnitIsTrueAndDeletedIsFalse(itemId: Serializable): ItemUom? | |||
| fun findByItemIdAndSalesUnitIsTrueAndDeletedIsFalse(itemId: Serializable): ItemUom? | |||
| fun findByItemM18IdAndPurchaseUnitIsTrueAndDeletedIsFalse(itemM18Id: Long): ItemUom? | |||
| fun findBaseUnitByItemIdAndBaseUnitIsTrueAndDeletedIsFalse(itemId: Long): ItemUom? | |||
| } | |||
| @@ -31,6 +31,10 @@ open class ItemUomService( | |||
| return itemUomRespository.findByItemIdAndPurchaseUnitIsTrueAndDeletedIsFalse(itemId) | |||
| } | |||
| open fun findSalesUnitByItemId(itemId: Long): ItemUom? { | |||
| return itemUomRespository.findByItemIdAndSalesUnitIsTrueAndDeletedIsFalse(itemId) | |||
| } | |||
| open fun findPurchaseUnitByM18ItemId(m18ItemId: Long): ItemUom? { | |||
| return itemUomRespository.findByItemM18IdAndPurchaseUnitIsTrueAndDeletedIsFalse(m18ItemId) | |||
| } | |||