@@ -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) | |||
} | |||