@@ -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.model.* | ||||
import com.ffii.fpsms.m18.utils.CommonUtils | import com.ffii.fpsms.m18.utils.CommonUtils | ||||
import com.ffii.fpsms.m18.web.models.M18TestMasterDateRequest | 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.entity.UomConversion | ||||
import com.ffii.fpsms.modules.master.enums.ShopType | import com.ffii.fpsms.modules.master.enums.ShopType | ||||
import com.ffii.fpsms.modules.master.service.* | 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) { | open fun saveProducts(request: M18TestMasterDateRequest) { | ||||
logger.info("--------------------------------------------Start - Saving M18 Products / Materials--------------------------------------------") | logger.info("--------------------------------------------Start - Saving M18 Products / Materials--------------------------------------------") | ||||
val items = getProducts(request) | 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.model.* | ||||
import com.ffii.fpsms.m18.utils.CommonUtils | import com.ffii.fpsms.m18.utils.CommonUtils | ||||
import com.ffii.fpsms.m18.web.models.M18TestPoRequest | 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.ItemUomService | ||||
import com.ffii.fpsms.modules.master.service.ItemsService | import com.ffii.fpsms.modules.master.service.ItemsService | ||||
import com.ffii.fpsms.modules.master.service.ShopService | import com.ffii.fpsms.modules.master.service.ShopService | ||||
@@ -30,9 +32,12 @@ open class M18PurchaseOrderService( | |||||
val m18DataLogService: M18DataLogService, | val m18DataLogService: M18DataLogService, | ||||
val purchaseOrderService: PurchaseOrderService, | val purchaseOrderService: PurchaseOrderService, | ||||
val purchaseOrderLineService: PurchaseOrderLineService, | val purchaseOrderLineService: PurchaseOrderLineService, | ||||
val deliveryOrderService: DeliveryOrderService, | |||||
val deliveryOrderLineService: DeliveryOrderLineService, | |||||
val itemsService: ItemsService, | val itemsService: ItemsService, | ||||
val shopService: ShopService, | val shopService: ShopService, | ||||
val itemUomService: ItemUomService, | val itemUomService: ItemUomService, | ||||
val m18MasterDataService: M18MasterDataService | |||||
) { | ) { | ||||
val commonUtils = CommonUtils() | val commonUtils = CommonUtils() | ||||
val logger: Logger = LoggerFactory.getLogger(JwtTokenUtil::class.java) | 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_LOAD_PURCHASE_ORDER_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, shop po, oem po | |||||
// Include material po, oem po | |||||
open fun getPurchaseOrdersWithType(request: M18TestPoRequest): M18PurchaseOrderListResponseWithType? { | open fun getPurchaseOrdersWithType(request: M18TestPoRequest): M18PurchaseOrderListResponseWithType? { | ||||
val purchaseOrders = M18PurchaseOrderListResponseWithType(mutableListOf()) | val purchaseOrders = M18PurchaseOrderListResponseWithType(mutableListOf()) | ||||
val lastModifyDateConds = | val lastModifyDateConds = | ||||
@@ -83,7 +88,7 @@ open class M18PurchaseOrderService( | |||||
} | } | ||||
// Shop PO | // 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( | val shopPoSupplier = commonUtils.listToString( | ||||
shopService.findM18VendorIdsByCodeRegexp(m18Config.SHOP_PO_SUPPLIER), | shopService.findM18VendorIdsByCodeRegexp(m18Config.SHOP_PO_SUPPLIER), | ||||
"venId=equal=", | "venId=equal=", | ||||
@@ -106,7 +111,7 @@ open class M18PurchaseOrderService( | |||||
} catch (e: Exception) { | } catch (e: Exception) { | ||||
logger.error("(Getting Shop Po list) Error on Function - ${e.stackTrace}") | logger.error("(Getting Shop Po list) Error on Function - ${e.stackTrace}") | ||||
logger.error(e.message) | logger.error(e.message) | ||||
} | |||||
} */ | |||||
// OEM PO | // OEM PO | ||||
/* val oemPoBuyers = commonUtils.listToString(listOf(m18Config.BEID_PF, m18Config.BEID_PP), "beId=equal=", "=or=") | /* 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}: 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) | ||||
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 { | try { | ||||
// Find the purchase_order_line if exist | // Find the purchase_order_line if exist | ||||
@@ -322,10 +333,10 @@ 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 = item?.id?.let { itemUomService.findPurchaseUnitByItemId(it) } | |||||
val itemUom = itemId?.let { itemUomService.findPurchaseUnitByItemId(it) } | |||||
val savePurchaseOrderLineRequest = SavePurchaseOrderLineRequest( | val savePurchaseOrderLineRequest = SavePurchaseOrderLineRequest( | ||||
id = existingPurchaseOrderLine?.id, | id = existingPurchaseOrderLine?.id, | ||||
itemId = item?.id, | |||||
itemId = itemId, | |||||
uomId = itemUom?.uom?.id, | uomId = itemUom?.uom?.id, | ||||
purchaseOrderId = purchaseOrderId, | purchaseOrderId = purchaseOrderId, | ||||
qty = line.qty, | qty = line.qty, | ||||
@@ -2,9 +2,11 @@ package com.ffii.fpsms.m18.web | |||||
import com.ffii.core.utils.JwtTokenUtil | import com.ffii.core.utils.JwtTokenUtil | ||||
import com.ffii.fpsms.m18.M18Config | 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.M18MasterDataService | ||||
import com.ffii.fpsms.m18.service.M18PurchaseOrderService | import com.ffii.fpsms.m18.service.M18PurchaseOrderService | ||||
import com.ffii.fpsms.m18.service.M18PurchaseQuotationService | 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.M18TestMasterDateRequest | ||||
import com.ffii.fpsms.m18.web.models.M18TestPoRequest | import com.ffii.fpsms.m18.web.models.M18TestPoRequest | ||||
import com.ffii.fpsms.m18.web.models.M18TestPqRequest | 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 jakarta.validation.Valid | ||||
import org.slf4j.Logger | import org.slf4j.Logger | ||||
import org.slf4j.LoggerFactory | 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 | @RestController | ||||
@@ -37,6 +34,7 @@ class M18TestController ( | |||||
private val m18Config: M18Config, | private val m18Config: M18Config, | ||||
private val itemUomService: ItemUomService, | private val itemUomService: ItemUomService, | ||||
private val m18PurchaseQuotationService: M18PurchaseQuotationService, | private val m18PurchaseQuotationService: M18PurchaseQuotationService, | ||||
private val m18DeliveryOrderService: M18DeliveryOrderService, | |||||
) { | ) { | ||||
var logger: Logger = LoggerFactory.getLogger(JwtTokenUtil::class.java) | var logger: Logger = LoggerFactory.getLogger(JwtTokenUtil::class.java) | ||||
@@ -95,6 +93,12 @@ class M18TestController ( | |||||
m18MasterDataService.saveProducts(request) | m18MasterDataService.saveProducts(request) | ||||
} | } | ||||
@GetMapping("/product/{id}") | |||||
fun m18Product(@PathVariable id: Long) { | |||||
logger.info("Access token: ${m18Config.ACCESS_TOKEN}") | |||||
m18MasterDataService.saveProduct(id) | |||||
} | |||||
@PostMapping("/vendor") | @PostMapping("/vendor") | ||||
fun m18Vendor(@Valid @RequestBody request: M18TestMasterDateRequest) { | fun m18Vendor(@Valid @RequestBody request: M18TestMasterDateRequest) { | ||||
logger.info("Access token: ${m18Config.ACCESS_TOKEN}") | logger.info("Access token: ${m18Config.ACCESS_TOKEN}") | ||||
@@ -132,6 +136,13 @@ class M18TestController ( | |||||
m18PurchaseOrderService.savePurchaseOrders(request) | 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 --------------------------------------------- /// | // --------------------------------------------- Purchase Quotation --------------------------------------------- /// | ||||
@PostMapping("/pq") | @PostMapping("/pq") | ||||
fun m18PQ(@Valid @RequestBody request: M18TestPqRequest) { | fun m18PQ(@Valid @RequestBody request: M18TestPqRequest) { | ||||
@@ -5,6 +5,11 @@ data class M18TestPoRequest( | |||||
val modifiedDateTo: String?, | val modifiedDateTo: String?, | ||||
) | ) | ||||
data class M18TestDoRequest( | |||||
val modifiedDateFrom: String?, | |||||
val modifiedDateTo: String?, | |||||
) | |||||
data class M18TestPqRequest( | data class M18TestPqRequest( | ||||
val modifiedDateFrom: String? = null, | val modifiedDateFrom: String? = null, | ||||
val modifiedDateTo: 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.fasterxml.jackson.annotation.JsonBackReference | ||||
import com.ffii.core.entity.BaseEntity | import com.ffii.core.entity.BaseEntity | ||||
import com.ffii.fpsms.m18.entity.M18DataLog | 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.Items | ||||
import com.ffii.fpsms.modules.master.entity.UomConversion | import com.ffii.fpsms.modules.master.entity.UomConversion | ||||
import com.ffii.fpsms.modules.purchaseOrder.entity.PurchaseOrderLine | import com.ffii.fpsms.modules.purchaseOrder.entity.PurchaseOrderLine | ||||
@@ -35,10 +38,10 @@ open class DeliveryOrderLine: BaseEntity<Long>() { | |||||
@Column(name = "price", precision = 14, scale = 2) | @Column(name = "price", precision = 14, scale = 2) | ||||
open var price: BigDecimal? = null | open var price: BigDecimal? = null | ||||
@Size(max = 30) | |||||
@NotNull | @NotNull | ||||
@Column(name = "status", nullable = false, length = 30) | @Column(name = "status", nullable = false, length = 30) | ||||
open var status: String? = null | |||||
@Convert(converter = DeliveryOrderLineStatusConverter::class) | |||||
open var status: DeliveryOrderLineStatus? = null | |||||
@NotNull | @NotNull | ||||
@ManyToOne | @ManyToOne | ||||
@@ -2,7 +2,9 @@ package com.ffii.fpsms.modules.deliveryOrder.entity | |||||
import com.ffii.core.support.AbstractRepository | import com.ffii.core.support.AbstractRepository | ||||
import org.springframework.stereotype.Repository | import org.springframework.stereotype.Repository | ||||
import java.io.Serializable | |||||
@Repository | @Repository | ||||
interface DeliveryOrderLineRepository : AbstractRepository<DeliveryOrderLine, Long> { | 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 findByItemIdAndPurchaseUnitIsTrueAndDeletedIsFalse(itemId: Serializable): ItemUom? | ||||
fun findByItemIdAndSalesUnitIsTrueAndDeletedIsFalse(itemId: Serializable): ItemUom? | |||||
fun findByItemM18IdAndPurchaseUnitIsTrueAndDeletedIsFalse(itemM18Id: Long): ItemUom? | fun findByItemM18IdAndPurchaseUnitIsTrueAndDeletedIsFalse(itemM18Id: Long): ItemUom? | ||||
fun findBaseUnitByItemIdAndBaseUnitIsTrueAndDeletedIsFalse(itemId: Long): ItemUom? | fun findBaseUnitByItemIdAndBaseUnitIsTrueAndDeletedIsFalse(itemId: Long): ItemUom? | ||||
} | } |
@@ -31,6 +31,10 @@ open class ItemUomService( | |||||
return itemUomRespository.findByItemIdAndPurchaseUnitIsTrueAndDeletedIsFalse(itemId) | return itemUomRespository.findByItemIdAndPurchaseUnitIsTrueAndDeletedIsFalse(itemId) | ||||
} | } | ||||
open fun findSalesUnitByItemId(itemId: Long): ItemUom? { | |||||
return itemUomRespository.findByItemIdAndSalesUnitIsTrueAndDeletedIsFalse(itemId) | |||||
} | |||||
open fun findPurchaseUnitByM18ItemId(m18ItemId: Long): ItemUom? { | open fun findPurchaseUnitByM18ItemId(m18ItemId: Long): ItemUom? { | ||||
return itemUomRespository.findByItemM18IdAndPurchaseUnitIsTrueAndDeletedIsFalse(m18ItemId) | return itemUomRespository.findByItemM18IdAndPurchaseUnitIsTrueAndDeletedIsFalse(m18ItemId) | ||||
} | } | ||||