From ea0d9c1badfcbd94ceb7ca0259eff1ea7a7a91bc Mon Sep 17 00:00:00 2001 From: Fai Luk Date: Sat, 31 Jan 2026 14:13:40 +0800 Subject: [PATCH] try to use a different account in production to syn m18 --- .../m18/service/M18DeliveryOrderService.kt | 38 +++++++++++++------ .../fpsms/m18/service/M18MasterDataService.kt | 34 ++++++++++------- .../ffii/fpsms/m18/web/M18TestController.kt | 16 ++++---- src/main/resources/application-prod.yml | 37 ++++++++++++++++++ 4 files changed, 93 insertions(+), 32 deletions(-) create mode 100644 src/main/resources/application-prod.yml diff --git a/src/main/java/com/ffii/fpsms/m18/service/M18DeliveryOrderService.kt b/src/main/java/com/ffii/fpsms/m18/service/M18DeliveryOrderService.kt index 34e96cc..a52e1f7 100644 --- a/src/main/java/com/ffii/fpsms/m18/service/M18DeliveryOrderService.kt +++ b/src/main/java/com/ffii/fpsms/m18/service/M18DeliveryOrderService.kt @@ -14,6 +14,7 @@ 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.ItemUom import com.ffii.fpsms.modules.master.service.ItemUomService import com.ffii.fpsms.modules.master.service.ItemsService import com.ffii.fpsms.modules.master.service.ShopService @@ -106,7 +107,7 @@ open class M18DeliveryOrderService( shopPoConds += "=and=(${dDateEqualConds})" } - println("shopPoConds: ${shopPoConds}") + logger.info("shopPoConds: ${shopPoConds}") val shopPoParams = M18PurchaseOrderListRequest( params = null, @@ -159,6 +160,9 @@ open class M18DeliveryOrderService( val failList = mutableListOf() val failDetailList = mutableListOf() val failItemDetailList = mutableListOf() + val uomByM18IdCache = mutableMapOf() + val itemIdCache = mutableMapOf() + val stockUomIdCache = mutableMapOf, Long?>() val doRefType = "Delivery Order" val doLineRefType = "Delivery Order Line" @@ -191,7 +195,7 @@ open class M18DeliveryOrderService( // logger.info("${doRefType}: Finding For Latest M18 Data Log...") val latestDeliveryOrderLog = m18DataLogService.findLatestM18DataLogWithSuccess(deliveryOrder.id, doRefType) - logger.info(latestDeliveryOrderLog.toString()) + //logger.info(latestDeliveryOrderLog.toString()) // Save to m18_data_log table // logger.info("${doRefType}: Saving for M18 Data Log...") val mainpoJson = @@ -305,14 +309,23 @@ open class M18DeliveryOrderService( // 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 + val itemId: Long? = itemIdCache.getOrPut(line.proId) { + val item = itemsService.findByM18Id(line.proId) + if (item == null) { + m18MasterDataService.saveProduct(line.proId)?.id + } else { + item.id + } } + val stockUomId: Long? = if (itemId != null) { + val key = line.proId to line.unitId // safe key + stockUomIdCache.getOrPut(key) { + val uom = itemUomService.findByM18Id(line.unitId) + itemUomService.findStockUnitByItemId(itemId)?.uom?.id + } + } else null + // logger.info("${doLineRefType}: Item ID: ${itemId} | M18 Item ID: ${line.proId}") try { @@ -325,12 +338,15 @@ open class M18DeliveryOrderService( // Save to delivery_order_line table // logger.info("${doLineRefType}: Saving delivery order line...") - val itemUom = itemUomService.findByM18Id(line.unitId) + val itemUom = uomByM18IdCache.getOrPut(line.unitId) { + itemUomService.findByM18Id(line.unitId) + } + val saveDeliveryOrderLineRequest = SaveDeliveryOrderLineRequest( id = existingDeliveryOrderLine?.id, itemId = itemId, uomIdM18 = itemUom?.uom?.id, - uomId= itemUomService.findStockUnitByItemId(itemId?: 0)?.uom?.id, + uomId= stockUomId, deliveryOrderId = deliveryOrderId, qtyM18 = line.qty, qty = itemUomService.convertQtyToStockQty(itemId?:0, itemUom?.uom?.id?: 0, line.qty), @@ -359,7 +375,7 @@ open class M18DeliveryOrderService( // 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} | Delivery order ID: ${deliveryOrderId} | M18 ID: ${deliveryOrder.id}") + //logger.info("${doLineRefType}: Saved delivery order line. ID: ${saveDeliveryOrderLineResponse.id} | M18 Line ID: ${line.id} | Delivery order ID: ${deliveryOrderId} | M18 ID: ${deliveryOrder.id}") } catch (e: SQLException) { failDetailList.add(line.id) failItemDetailList.add(line.proId) diff --git a/src/main/java/com/ffii/fpsms/m18/service/M18MasterDataService.kt b/src/main/java/com/ffii/fpsms/m18/service/M18MasterDataService.kt index f23f151..c65d5bf 100644 --- a/src/main/java/com/ffii/fpsms/m18/service/M18MasterDataService.kt +++ b/src/main/java/com/ffii/fpsms/m18/service/M18MasterDataService.kt @@ -17,6 +17,7 @@ import java.math.BigDecimal import java.time.LocalDateTime import java.time.format.DateTimeFormatter import com.ffii.fpsms.m18.model.SyncResult +import com.ffii.fpsms.modules.master.entity.Items import java.time.Instant import java.time.LocalDate import java.time.ZoneId @@ -233,30 +234,38 @@ open class M18MasterDataService( } } - open fun saveProducts(request: M18CommonRequest) : SyncResult{ + open fun saveProducts(request: M18CommonRequest): SyncResult { logger.info("--------------------------------------------Start - Saving M18 Products / Materials--------------------------------------------") + val items = getProducts(request) val exampleProducts = listOf(10946L, 3825L) + // ── New: cache for findByM18Id ───────────────────────────────────────── + // M18 item.id → internal Item entity (or just the id if you only need id) + val itemCache = mutableMapOf() + val successList = mutableListOf() val failList = mutableListOf() val values = items?.values?.sortedBy { it.id } if (values != null) { values.forEach { item -> -// if (item.id in exampleProducts) { + // if (item.id in exampleProducts) { // keep your debug filter if needed + try { val itemDetail = getProduct(item.id) val pro = itemDetail?.data?.pro?.get(0) val price = itemDetail?.data?.price if (itemDetail != null && pro != null) { - val existingItem = itemsService.findByM18Id(item.id) + // ── Use cache instead of direct call ──────────────────────── + val existingItem = itemCache.getOrPut(item.id) { + itemsService.findByM18Id(item.id) + } + val saveItemRequest = NewItemRequest( code = pro.code, name = pro.desc, -// type = if (pro.seriesId == m18Config.SERIESID_PF) ProductType.MATERIAL -// else ItemType.PRODUCT, type = when (pro.udfProducttype) { M18ItemType.CONSUMABLES.type -> ItemType.CONSUMABLES.type M18ItemType.NONCONSUMABLES.type -> ItemType.NONCONSUMABLES.type @@ -287,18 +296,19 @@ open class M18MasterDataService( val savedItem = itemsService.saveItem(saveItemRequest) logger.info("Processing item uom...") - // Find the item uom that ready to delete (not in m18) + + // Optional: cache findAllByItemsId if you think it might be called multiple times + // (usually not needed here because each savedItem.id is unique) val existingItemUoms = savedItem.id?.let { itemUomService.findAllByItemsId(it) } + val m18ItemUomIds = price?.map { it.id } ?: listOf() - // Delete the item uom + // Delete old UOMs not present in M18 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 + // Update / create UOMs from M18 logger.info("Updating item uom...") price?.forEach { val endMillis = it.endDate @@ -319,11 +329,9 @@ open class M18MasterDataService( m18LastModifyDate = commonUtils.timestampToLocalDateTime(pro.lastModifyDate), ratioD = it.ratioD, ratioN = it.ratioN, - //deleted = it.expired deleted = endInstant.isBefore(now) ) -// logger.info("saved item id: ${savedItem.id}") itemUomService.saveItemUom(itemUomRequest) } @@ -340,13 +348,13 @@ open class M18MasterDataService( logger.error("Fail Message: ${e.message}") logger.error("Fail Count ${failList.size}: Item ID - ${item.id}") } + // } // end of exampleProducts filter } } else { logger.error("Items List is null. May occur errors.") } logger.info("Total Success (${successList.size})") - if (failList.size > 0) { logger.error("Total Fail (${failList.size}): $failList") } diff --git a/src/main/java/com/ffii/fpsms/m18/web/M18TestController.kt b/src/main/java/com/ffii/fpsms/m18/web/M18TestController.kt index 74e7768..668ef7a 100644 --- a/src/main/java/com/ffii/fpsms/m18/web/M18TestController.kt +++ b/src/main/java/com/ffii/fpsms/m18/web/M18TestController.kt @@ -106,51 +106,51 @@ class M18TestController ( @GetMapping("/product/{id}") fun m18Product(@PathVariable id: Long) { - logger.info("Access token: ${m18Config.ACCESS_TOKEN}") + //logger.info("Access token: ${m18Config.ACCESS_TOKEN}") m18MasterDataService.saveProduct(id) } @PostMapping("/vendor") fun m18Vendor(@Valid @RequestBody request: M18CommonRequest) { - logger.info("Access token: ${m18Config.ACCESS_TOKEN}") + //logger.info("Access token: ${m18Config.ACCESS_TOKEN}") m18MasterDataService.saveVendors(request) } @PostMapping("/unit") fun m18Unit(@Valid @RequestBody request: M18CommonRequest) { - logger.info("Access token: ${m18Config.ACCESS_TOKEN}") + //logger.info("Access token: ${m18Config.ACCESS_TOKEN}") m18MasterDataService.saveUnits(request) } @PostMapping("/currency") fun m18Currency(@Valid @RequestBody request: M18CommonRequest) { - logger.info("Access token: ${m18Config.ACCESS_TOKEN}") + //logger.info("Access token: ${m18Config.ACCESS_TOKEN}") m18MasterDataService.saveCurrencies(request) } @PostMapping("/bom") fun m18Bom(@Valid @RequestBody request: M18CommonRequest) { - logger.info("Access token: ${m18Config.ACCESS_TOKEN}") + //logger.info("Access token: ${m18Config.ACCESS_TOKEN}") m18MasterDataService.saveBoms(request) } @PostMapping("/businessUnit") fun m18BusinessUnit(@Valid @RequestBody request: M18CommonRequest) { - logger.info("Access token: ${m18Config.ACCESS_TOKEN}") + //logger.info("Access token: ${m18Config.ACCESS_TOKEN}") m18MasterDataService.saveBusinessUnits(request) } // --------------------------------------------- Purchase Order --------------------------------------------- /// @PostMapping("/po") fun m18PO(@Valid @RequestBody request: M18CommonRequest) { - logger.info("Access token: ${m18Config.ACCESS_TOKEN}") + //logger.info("Access token: ${m18Config.ACCESS_TOKEN}") m18PurchaseOrderService.savePurchaseOrders(request) } // --------------------------------------------- Delivery Order --------------------------------------------- /// @PostMapping("/do") fun m18DO(@Valid @RequestBody request: M18CommonRequest) { - logger.info("Access token: ${m18Config.ACCESS_TOKEN}") + //logger.info("Access token: ${m18Config.ACCESS_TOKEN}") m18DeliveryOrderService.saveDeliveryOrders(request) } diff --git a/src/main/resources/application-prod.yml b/src/main/resources/application-prod.yml new file mode 100644 index 0000000..b76f462 --- /dev/null +++ b/src/main/resources/application-prod.yml @@ -0,0 +1,37 @@ +spring: + datasource: + jdbc-url: jdbc:mysql://127.0.0.1:3306/fpsmsdb?useUnicode=true&characterEncoding=UTF8&serverTimezone=GMT%2B8 + username: root + password: secret + +m18: + config: + grant-type: password + client-id: M2Y1OGYxMmQtZDRiOS00OTA4LTgyNTktZDRkNzEzNWVkMzRm + client-secret: N2IzMjY5ZTEtZDIyYy00M2FlLWJhZjktZWU0ODBhYzAyNDA3 + username: MTMS2 + password: ea5bfbd761dd1b97bc08354d66169155f11ddaf1 + base-url: https://toa.m18saas.com/jsf/rfws + base-url-uat: https://toauat.m18saas.com/jsf/rfws + base-password: 1648414877 + supplier: + shop-po: P06, P07 + oem-po: T62 + supplier-not: + material-po: P06, P07 + beId: + toa: 1 + pf: 27 + pp: 29 + seriesId: + pp: 26 + pf: 33 + fa: 2 + fb: 3 + fc: 4 + fd: 5 + ff: 6 + sc: 27 + se: 28 + sf: 70 + sr: 29 \ No newline at end of file