Non puoi selezionare più di 25 argomenti Gli argomenti devono iniziare con una lettera o un numero, possono includere trattini ('-') e possono essere lunghi fino a 35 caratteri.
 
 
 
 
 

465 righe
26 KiB

  1. package com.ffii.fpsms.m18.service
  2. import com.ffii.core.utils.JwtTokenUtil
  3. import com.ffii.fpsms.api.service.ApiCallerService
  4. import com.ffii.fpsms.m18.M18Config
  5. import com.ffii.fpsms.m18.enums.M18DataLogStatus
  6. import com.ffii.fpsms.m18.model.*
  7. import com.ffii.fpsms.m18.utils.CommonUtils
  8. import com.ffii.fpsms.m18.web.models.M18TestPoRequest
  9. import com.ffii.fpsms.modules.deliveryOrder.service.DeliveryOrderLineService
  10. import com.ffii.fpsms.modules.deliveryOrder.service.DeliveryOrderService
  11. import com.ffii.fpsms.modules.master.service.ItemUomService
  12. import com.ffii.fpsms.modules.master.service.ItemsService
  13. import com.ffii.fpsms.modules.master.service.ShopService
  14. import com.ffii.fpsms.modules.purchaseOrder.enums.PurchaseOrderLineStatus
  15. import com.ffii.fpsms.modules.purchaseOrder.enums.PurchaseOrderStatus
  16. import com.ffii.fpsms.modules.purchaseOrder.enums.PurchaseOrderType
  17. import com.ffii.fpsms.modules.purchaseOrder.service.PurchaseOrderLineService
  18. import com.ffii.fpsms.modules.purchaseOrder.service.PurchaseOrderService
  19. import com.ffii.fpsms.modules.purchaseOrder.web.model.SavePurchaseOrderLineRequest
  20. import com.ffii.fpsms.modules.purchaseOrder.web.model.SavePurchaseOrderRequest
  21. import org.slf4j.Logger
  22. import org.slf4j.LoggerFactory
  23. import org.springframework.stereotype.Service
  24. import java.time.LocalDateTime
  25. import kotlin.reflect.full.memberProperties
  26. @Service
  27. open class M18PurchaseOrderService(
  28. val m18Config: M18Config,
  29. val apiCallerService: ApiCallerService,
  30. val m18DataLogService: M18DataLogService,
  31. val purchaseOrderService: PurchaseOrderService,
  32. val purchaseOrderLineService: PurchaseOrderLineService,
  33. val deliveryOrderService: DeliveryOrderService,
  34. val deliveryOrderLineService: DeliveryOrderLineService,
  35. val itemsService: ItemsService,
  36. val shopService: ShopService,
  37. val itemUomService: ItemUomService,
  38. val m18MasterDataService: M18MasterDataService
  39. ) {
  40. val commonUtils = CommonUtils()
  41. val logger: Logger = LoggerFactory.getLogger(JwtTokenUtil::class.java)
  42. val lastModifyDateStart = "2025-05-14 14:00:00"
  43. val lastModifyDateEnd = "2025-05-14 14:30:00"
  44. // val lastModifyDateConds =
  45. // "lastModifyDate=largerOrEqual=${lastModifyDateStart}=and=lastModifyDate=lessOrEqual=${lastModifyDateEnd}"
  46. // val lastModifyDate = LocalDateTime.now().minusMinutes(30)
  47. // val commonConds =
  48. // "(beId=equal=${m18Config.BEID_PF}=or=beId=equal=${m18Config.BEID_PP}=or=beId=equal=${m18Config.BEID_TOA})=and=lastModifyDate=largerOrEqual=${lastModifyDate}"
  49. // M18 API
  50. val M18_LOAD_PURCHASE_ORDER_API = "/root/api/read/po"
  51. val M18_FETCH_PURCHASE_ORDER_LIST_API = "/search/search"
  52. // Include material po, oem po
  53. open fun getPurchaseOrdersWithType(request: M18TestPoRequest): M18PurchaseOrderListResponseWithType? {
  54. val purchaseOrders = M18PurchaseOrderListResponseWithType(mutableListOf())
  55. val lastModifyDateConds =
  56. "lastModifyDate=largerOrEqual=${request.modifiedDateFrom ?: lastModifyDateStart}=and=lastModifyDate=lessOrEqual=${request.modifiedDateTo ?: lastModifyDateEnd}"
  57. // Material PO
  58. val materialPoBuyers =
  59. commonUtils.listToString(listOf(m18Config.BEID_PP, m18Config.BEID_PF), "beId=equal=", "=or=")
  60. val materialPoSupplierNot = commonUtils.listToString(
  61. shopService.findM18VendorIdsByCodeRegexp(m18Config.MATERIAL_PO_SUPPLIER_NOT),
  62. "venId=unequal=",
  63. "=or="
  64. )
  65. val materialPoConds = "(${materialPoBuyers})=and=(${materialPoSupplierNot})=and=(${lastModifyDateConds})"
  66. println("materialPoConds: ${materialPoConds}")
  67. val materialPoParams = M18PurchaseOrderListRequest(
  68. params = null,
  69. conds = materialPoConds
  70. )
  71. try {
  72. purchaseOrders.valuesWithType += Pair(
  73. PurchaseOrderType.MATERIAL,
  74. apiCallerService.get<M18PurchaseOrderListResponse, M18PurchaseOrderListRequest>(
  75. M18_FETCH_PURCHASE_ORDER_LIST_API,
  76. materialPoParams
  77. ).block()
  78. )
  79. } catch (e: Exception) {
  80. logger.error("(Getting Material Po list) Error on Function - ${e.stackTrace}")
  81. logger.error(e.message)
  82. }
  83. // Shop PO
  84. /* val shopPoBuyers = commonUtils.listToString(listOf(m18Config.BEID_TOA), "beId=equal=", "=or=")
  85. val shopPoSupplier = commonUtils.listToString(
  86. shopService.findM18VendorIdsByCodeRegexp(m18Config.SHOP_PO_SUPPLIER),
  87. "venId=equal=",
  88. "=or="
  89. )
  90. val shopPoConds = "(${shopPoBuyers})=and=(${shopPoSupplier})=and=(${lastModifyDateConds})"
  91. println("shopPoConds: ${shopPoConds}")
  92. val shopPoParams = M18PurchaseOrderListRequest(
  93. params = null,
  94. conds = shopPoConds
  95. )
  96. try {
  97. purchaseOrders.valuesWithType += Pair(
  98. PurchaseOrderType.SHOP, apiCallerService.get<M18PurchaseOrderListResponse, M18PurchaseOrderListRequest>(
  99. M18_FETCH_PURCHASE_ORDER_LIST_API,
  100. shopPoParams
  101. ).block()
  102. )
  103. } catch (e: Exception) {
  104. logger.error("(Getting Shop Po list) Error on Function - ${e.stackTrace}")
  105. logger.error(e.message)
  106. } */
  107. // OEM PO
  108. /* val oemPoBuyers = commonUtils.listToString(listOf(m18Config.BEID_PF, m18Config.BEID_PP), "beId=equal=", "=or=")
  109. val oemPoSupplier = commonUtils.listToString(
  110. shopService.findM18VendorIdsByCodeRegexp(m18Config.OEM_PO_SUPPLIER),
  111. "venId=equal=",
  112. "=or="
  113. )
  114. val oemPoConds = "(${oemPoBuyers})=and=(${oemPoSupplier})=and=(${lastModifyDateConds})"
  115. println("oemPoConds: ${oemPoConds}")
  116. val oemPoParams = M18PurchaseOrderListRequest(
  117. params = null,
  118. conds = oemPoConds
  119. )
  120. try {
  121. purchaseOrders.valuesWithType += Pair(
  122. PurchaseOrderType.OEM, apiCallerService.get<M18PurchaseOrderListResponse, M18PurchaseOrderListRequest>(
  123. M18_FETCH_PURCHASE_ORDER_LIST_API,
  124. oemPoParams
  125. ).block()
  126. )
  127. } catch (e: Exception) {
  128. logger.error("(Getting OEM Po list) Error on Function - ${e.stackTrace}")
  129. logger.error(e.message)
  130. } */
  131. return purchaseOrders
  132. }
  133. open fun getPurchaseOrder(id: Long): M18PurchaseOrderResponse? {
  134. val purchaseOrderParams = M18PurchaseOrderRequest(
  135. id = id
  136. )
  137. var purchaseOrder: M18PurchaseOrderResponse? = null
  138. try {
  139. purchaseOrder = apiCallerService.get<M18PurchaseOrderResponse, M18PurchaseOrderRequest>(
  140. M18_LOAD_PURCHASE_ORDER_API,
  141. purchaseOrderParams
  142. ).block()
  143. } catch (e: Exception) {
  144. logger.error("(Getting Po Detail) Error on Function - ${e.stackTrace}")
  145. logger.error(e.message)
  146. }
  147. return purchaseOrder
  148. }
  149. open fun savePurchaseOrders(request: M18TestPoRequest) {
  150. logger.info("--------------------------------------------Start - Saving M18 Purchase Order--------------------------------------------")
  151. val purchaseOrdersWithType = getPurchaseOrdersWithType(request)
  152. val examplePurchaseOrders = listOf<Long>(4764034L)
  153. val successList = mutableListOf<Long>()
  154. val successDetailList = mutableListOf<Long>()
  155. val failList = mutableListOf<Long>()
  156. val failDetailList = mutableListOf<Long>()
  157. val poRefType = "Purchase Order"
  158. val poLineRefType = "Purchase Order Line"
  159. if (purchaseOrdersWithType != null) {
  160. // Loop for Purchase Orders (values)
  161. purchaseOrdersWithType.valuesWithType.forEach { purchaseOrderWithType ->
  162. val type = purchaseOrderWithType.first
  163. // if success
  164. val purchaseOrdersValues = purchaseOrderWithType.second?.values
  165. // if fail
  166. val purchaseOrdersMessages = purchaseOrderWithType.second?.messages
  167. if (purchaseOrdersValues != null) {
  168. purchaseOrdersValues.forEach { purchaseOrder ->
  169. val purchaseOrderDetail = getPurchaseOrder(purchaseOrder.id)
  170. var purchaseOrderId: Long? = null //FP-MTMS
  171. // Process for Purchase Order (mainpo)
  172. // Assume only one PO in the PO (search by PO ID)
  173. val mainpo = purchaseOrderDetail?.data?.mainpo?.get(0)
  174. val pot = purchaseOrderDetail?.data?.pot
  175. val purchaseOrderLineMessage = purchaseOrderDetail?.messages
  176. // purchase_order + m18_data_log table
  177. if (mainpo != null) {
  178. // Find the latest m18 data log by m18 id & type
  179. logger.info("${poRefType}: Finding For Latest M18 Data Log...")
  180. val latestPurchaseOrderLog =
  181. m18DataLogService.findLatestM18DataLogWithSuccess(purchaseOrder.id, poRefType)
  182. logger.info(latestPurchaseOrderLog.toString())
  183. // Save to m18_data_log table
  184. logger.info("${poRefType}: Saving for M18 Data Log...")
  185. val mainpoJson =
  186. mainpo::class.memberProperties.associate { prop -> prop.name to prop.getter.call(mainpo) }
  187. .toMutableMap()
  188. val saveM18PurchaseOrderLogRequest = SaveM18DataLogRequest(
  189. id = null,
  190. refType = poRefType,
  191. m18Id = purchaseOrder.id,
  192. m18LastModifyDate = commonUtils.timestampToLocalDateTime(mainpo.lastModifyDate),
  193. // dataLog = mainpoJson,
  194. statusEnum = M18DataLogStatus.NOT_PROCESS
  195. )
  196. val saveM18PurchaseOrderLog =
  197. m18DataLogService.saveM18DataLog(saveM18PurchaseOrderLogRequest)
  198. // logger.info("${poRefType}: Saved M18 Data Log. ID: ${saveM18PurchaseOrderLog.id}")
  199. try {
  200. // Find the purchase_order if exist
  201. logger.info("${poRefType}: Finding exising purchase order...")
  202. val existingPurchaseOrder =
  203. latestPurchaseOrderLog?.id?.let { purchaseOrderService.findByM18DataLogId(it) }
  204. logger.info("${poRefType}: Exising purchase order ID: ${existingPurchaseOrder?.id}")
  205. // Save to purchase_order table
  206. logger.info("${poRefType}: Saving purchase order...")
  207. val savePurchaseOrderRequest = SavePurchaseOrderRequest(
  208. id = existingPurchaseOrder?.id,
  209. code = mainpo.code,
  210. m18SupplierId = mainpo.venId,
  211. m18ShopId = mainpo.virDeptId,
  212. m18CurrencyId = mainpo.curId,
  213. orderDate = commonUtils.timestampToLocalDateTime(mainpo.tDate),
  214. estimatedArrivalDate = commonUtils.timestampToLocalDateTime(mainpo.dDate),
  215. completeDate = null,
  216. status = PurchaseOrderStatus.PENDING.value,
  217. type = type.value,
  218. m18DataLogId = saveM18PurchaseOrderLog.id,
  219. m18BeId = mainpo.beId
  220. )
  221. val savePurchaseOrderResponse =
  222. purchaseOrderService.savePurchaseOrder(savePurchaseOrderRequest)
  223. purchaseOrderId = savePurchaseOrderResponse.id
  224. // Update m18_data_log with success
  225. val successSaveM18PurchaseOrderLogRequest = SaveM18DataLogRequest(
  226. id = saveM18PurchaseOrderLog.id,
  227. dataLog = mainpoJson,
  228. statusEnum = M18DataLogStatus.SUCCESS
  229. )
  230. m18DataLogService.saveM18DataLog(successSaveM18PurchaseOrderLogRequest)
  231. // log success info
  232. successList.add(purchaseOrder.id)
  233. logger.info("${poRefType}: Saved purchase order. ID: ${savePurchaseOrderResponse.id} | M18 ${poRefType} ID: ${purchaseOrder.id}")
  234. } catch (e: Exception) {
  235. failList.add(purchaseOrder.id)
  236. logger.error("${poRefType}: Saving Failure!")
  237. logger.error("Error on Function - ${e.stackTrace} | Type: ${poRefType} | M18 ID: ${purchaseOrder.id} | Different? ${mainpo.id}")
  238. logger.error(e.message)
  239. val errorSaveM18PurchaseOrderLogRequest = SaveM18DataLogRequest(
  240. id = saveM18PurchaseOrderLog.id,
  241. dataLog = mutableMapOf(Pair("Exception Message", e.message)),
  242. statusEnum = M18DataLogStatus.FAIL
  243. )
  244. m18DataLogService.saveM18DataLog(errorSaveM18PurchaseOrderLogRequest)
  245. logger.error("${poRefType}: M18 Data Log Updated! Please see the error. ID: ${saveM18PurchaseOrderLogRequest.id}")
  246. }
  247. // purchase_order_line + m18_data_log
  248. // TODO: check deleted po line?
  249. if (pot != null) {
  250. // Loop for Purchase Order Lines (pot)
  251. pot.forEach { line ->
  252. // Find the latest m18 data log by m18 id & type
  253. logger.info("${poLineRefType}: Finding For Latest M18 Data Log...")
  254. val latestPurchaseOrderLineLog =
  255. m18DataLogService.findLatestM18DataLogWithSuccess(line.id, poLineRefType)
  256. // logger.info("${poLineRefType}: Latest M18 Data Log ID: ${latestPurchaseOrderLineLog?.id}")
  257. // Save to m18_data_log table
  258. logger.info("${poLineRefType}: Saving for M18 Data Log...")
  259. val lineJson =
  260. line::class.memberProperties.associate { prop ->
  261. prop.name to prop.getter.call(
  262. line
  263. )
  264. }
  265. .toMutableMap()
  266. val saveM18PurchaseOrderLineLogRequest = SaveM18DataLogRequest(
  267. id = null,
  268. refType = poLineRefType,
  269. m18Id = line.id,
  270. m18LastModifyDate = commonUtils.timestampToLocalDateTime(mainpo.lastModifyDate),
  271. // dataLog = lineJson,
  272. statusEnum = M18DataLogStatus.NOT_PROCESS
  273. )
  274. val saveM18PurchaseOrderLineLog =
  275. m18DataLogService.saveM18DataLog(saveM18PurchaseOrderLineLogRequest)
  276. // logger.info("${poLineRefType}: Saved M18 Data Log. ID: ${saveM18PurchaseOrderLineLog.id}")
  277. logger.info("${poLineRefType}: Finding item...")
  278. val item = itemsService.findByM18Id(line.proId)
  279. var itemId: Long? = null
  280. if (item == null) {
  281. itemId = m18MasterDataService.saveProduct(line.proId)?.id
  282. } else {
  283. itemId = item.id
  284. }
  285. logger.info("${poLineRefType}: Item ID: ${itemId} | M18 Item ID: ${line.proId}")
  286. try {
  287. // Find the purchase_order_line if exist
  288. logger.info("${poLineRefType}: Finding exising purchase order line...")
  289. val existingPurchaseOrderLine = latestPurchaseOrderLineLog?.id?.let {
  290. purchaseOrderLineService.findPurchaseOrderLineByM18Id(it)
  291. }
  292. logger.info("${poLineRefType}: Exising purchase order line ID: ${existingPurchaseOrderLine?.id}")
  293. // Save to purchase_order_line table
  294. logger.info("${poLineRefType}: Saving purchase order line...")
  295. val itemUom = itemId?.let { itemUomService.findPurchaseUnitByItemId(it) }
  296. val savePurchaseOrderLineRequest = SavePurchaseOrderLineRequest(
  297. id = existingPurchaseOrderLine?.id,
  298. itemId = itemId,
  299. uomId = itemUom?.uom?.id,
  300. purchaseOrderId = purchaseOrderId,
  301. qty = line.qty,
  302. price = line.amt,
  303. // m18CurrencyId = mainpo.curId,
  304. status = existingPurchaseOrderLine?.status?.value
  305. ?: PurchaseOrderLineStatus.PENDING.value,
  306. m18DataLogId = saveM18PurchaseOrderLineLog.id,
  307. m18Discount = line.disc,
  308. m18Lot = line.lot
  309. )
  310. val savePurchaseOrderLineResponse =
  311. purchaseOrderLineService.savePurchaseOrderLine(savePurchaseOrderLineRequest)
  312. // Update m18_data_log with success
  313. val successSaveM18PurchaseOrderLineLogRequest = SaveM18DataLogRequest(
  314. id = saveM18PurchaseOrderLineLog.id,
  315. dataLog = lineJson,
  316. statusEnum = M18DataLogStatus.SUCCESS
  317. )
  318. m18DataLogService.saveM18DataLog(successSaveM18PurchaseOrderLineLogRequest)
  319. // log success info
  320. successDetailList.add(line.id)
  321. logger.info("${poLineRefType}: Purchase order ID: ${purchaseOrderId} | M18 ID: ${purchaseOrder.id}")
  322. logger.info("${poLineRefType}: Saved purchase order line. ID: ${savePurchaseOrderLineResponse.id} | M18 Line ID: ${line.id}")
  323. } catch (e: Exception) {
  324. failDetailList.add(line.id)
  325. logger.error("${poLineRefType}: Saving Failure!")
  326. logger.error("Error on Function - ${e.stackTrace} | Type: ${poLineRefType} | M18 ID: ${line.id}")
  327. logger.error(e.message)
  328. val errorSaveM18PurchaseOrderLineLogRequest = SaveM18DataLogRequest(
  329. id = saveM18PurchaseOrderLineLog.id,
  330. dataLog = mutableMapOf(Pair("Exception Message", e.message)),
  331. statusEnum = M18DataLogStatus.FAIL
  332. )
  333. m18DataLogService.saveM18DataLog(errorSaveM18PurchaseOrderLineLogRequest)
  334. logger.error("${poLineRefType}: M18 Data Log Updated! Please see the error. ID: ${saveM18PurchaseOrderLineLog.id}")
  335. }
  336. }
  337. } else {
  338. // pot
  339. logger.error("${poLineRefType}: Saving Failure!")
  340. val saveM18PurchaseOrderLineLogRequest = SaveM18DataLogRequest(
  341. id = null,
  342. refType = "${poLineRefType}",
  343. m18Id = purchaseOrder.id,
  344. m18LastModifyDate = commonUtils.timestampToLocalDateTime(mainpo.lastModifyDate),
  345. // dataLog = mutableMapOf(Pair("Error Message", "${poLineRefType} is null")),
  346. dataLog = mutableMapOf(
  347. Pair(
  348. "${poLineRefType} Error Message",
  349. "pot is null"
  350. ),
  351. Pair(
  352. "${poLineRefType} Error Code",
  353. purchaseOrderLineMessage?.get(0)?.msgCode ?: "No Msg Code from M18"
  354. ),
  355. Pair(
  356. "${poLineRefType} Error Detail",
  357. purchaseOrderLineMessage?.get(0)?.msgDetail ?: "No Msg Detail from M18"
  358. ),
  359. ),
  360. statusEnum = M18DataLogStatus.FAIL
  361. )
  362. val errorLog = m18DataLogService.saveM18DataLog(saveM18PurchaseOrderLineLogRequest)
  363. logger.error("${poLineRefType}: M18 Data Log Updated! Please see the error. ID: ${errorLog.id}")
  364. }
  365. } else {
  366. // mainpo
  367. failList.add(purchaseOrder.id)
  368. logger.error("${poRefType}: Saving Failure!")
  369. val saveM18DataLogRequest = SaveM18DataLogRequest(
  370. id = null,
  371. refType = "${poRefType}",
  372. m18Id = purchaseOrder.id,
  373. // m18LastModifyDate = if(mainpo?.lastModifyDate != null) commonUtils.instantToLocalDateTime(mainpo.lastModifyDate) else LocalDateTime.now(),
  374. m18LastModifyDate = LocalDateTime.now(),
  375. dataLog = mutableMapOf(
  376. Pair(
  377. "${poRefType} Error",
  378. "mainpo is null"
  379. ),
  380. Pair(
  381. "${poRefType} Error Code",
  382. purchaseOrdersMessages?.get(0)?.msgCode ?: "No Msg Code from M18"
  383. ),
  384. Pair(
  385. "${poRefType} Error Detail",
  386. purchaseOrdersMessages?.get(0)?.msgDetail ?: "No Msg Detail from M18"
  387. ),
  388. ),
  389. statusEnum = M18DataLogStatus.FAIL
  390. )
  391. val errorLog = m18DataLogService.saveM18DataLog(saveM18DataLogRequest)
  392. logger.error("${poLineRefType}: M18 Data Log Updated! Please see the error. ID: ${errorLog.id}")
  393. }
  394. }
  395. } else {
  396. logger.error("${poRefType} List is null. May occur errors.")
  397. }
  398. }
  399. } else {
  400. logger.error("${poRefType} List is null. May occur errors.")
  401. }
  402. // End of save. Check result
  403. logger.info("Total Success (${poRefType}) (${successList.size}): $successList")
  404. // if (failList.size > 0) {
  405. logger.error("Total Fail (${poRefType}) (${failList.size}): $failList")
  406. // }
  407. logger.info("Total Success (${poLineRefType}) (${successDetailList.size}): $successDetailList")
  408. // if (failDetailList.size > 0) {
  409. logger.error("Total Fail (${poLineRefType}) (${failDetailList.size}): $failDetailList")
  410. // }
  411. logger.info("--------------------------------------------End - Saving M18 Purchase Order--------------------------------------------")
  412. }
  413. }