選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。
 
 
 
 
 

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