You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

415 line
24 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.M18TestDoRequest
  9. import com.ffii.fpsms.m18.web.models.M18TestPoRequest
  10. import com.ffii.fpsms.modules.deliveryOrder.enums.DeliveryOrderLineStatus
  11. import com.ffii.fpsms.modules.deliveryOrder.enums.DeliveryOrderStatus
  12. import com.ffii.fpsms.modules.deliveryOrder.service.DeliveryOrderLineService
  13. import com.ffii.fpsms.modules.deliveryOrder.service.DeliveryOrderService
  14. import com.ffii.fpsms.modules.deliveryOrder.web.models.SaveDeliveryOrderLineRequest
  15. import com.ffii.fpsms.modules.deliveryOrder.web.models.SaveDeliveryOrderRequest
  16. import com.ffii.fpsms.modules.master.entity.Items
  17. import com.ffii.fpsms.modules.master.service.ItemUomService
  18. import com.ffii.fpsms.modules.master.service.ItemsService
  19. import com.ffii.fpsms.modules.master.service.ShopService
  20. import com.ffii.fpsms.modules.purchaseOrder.enums.PurchaseOrderType
  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 M18DeliveryOrderService(
  28. val m18Config: M18Config,
  29. val apiCallerService: ApiCallerService,
  30. val m18DataLogService: M18DataLogService,
  31. val deliveryOrderService: DeliveryOrderService,
  32. val deliveryOrderLineService: DeliveryOrderLineService,
  33. val itemsService: ItemsService,
  34. val shopService: ShopService,
  35. val itemUomService: ItemUomService,
  36. val m18MasterDataService: M18MasterDataService,
  37. ) {
  38. val commonUtils = CommonUtils()
  39. val logger: Logger = LoggerFactory.getLogger(JwtTokenUtil::class.java)
  40. val lastModifyDateStart = "2025-05-14 14:00:00"
  41. val lastModifyDateEnd = "2025-05-14 14:30:00"
  42. // val lastModifyDateConds =
  43. // "lastModifyDate=largerOrEqual=${lastModifyDateStart}=and=lastModifyDate=lessOrEqual=${lastModifyDateEnd}"
  44. // val lastModifyDate = LocalDateTime.now().minusMinutes(30)
  45. // val commonConds =
  46. // "(beId=equal=${m18Config.BEID_PF}=or=beId=equal=${m18Config.BEID_PP}=or=beId=equal=${m18Config.BEID_TOA})=and=lastModifyDate=largerOrEqual=${lastModifyDate}"
  47. // M18 API
  48. // Sharing same API with po
  49. val M18_LOAD_PURCHASE_ORDER_API = "/root/api/read/po"
  50. val M18_FETCH_PURCHASE_ORDER_LIST_API = "/search/search"
  51. // Include shop po
  52. open fun getDeliveryOrdersWithType(request: M18TestDoRequest): M18PurchaseOrderListResponseWithType? {
  53. val deliveryOrders = M18PurchaseOrderListResponseWithType(mutableListOf())
  54. val lastModifyDateConds =
  55. "lastModifyDate=largerOrEqual=${request.modifiedDateFrom ?: lastModifyDateStart}=and=lastModifyDate=lessOrEqual=${request.modifiedDateTo ?: lastModifyDateEnd}"
  56. // Shop PO
  57. val shopPoBuyers = commonUtils.listToString(listOf(m18Config.BEID_TOA), "beId=equal=", "=or=")
  58. val shopPoSupplier = commonUtils.listToString(
  59. shopService.findM18VendorIdsByCodeRegexp(m18Config.SHOP_PO_SUPPLIER),
  60. "venId=equal=",
  61. "=or="
  62. )
  63. val shopPoConds = "(${shopPoBuyers})=and=(${shopPoSupplier})=and=(${lastModifyDateConds})"
  64. println("shopPoConds: ${shopPoConds}")
  65. val shopPoParams = M18PurchaseOrderListRequest(
  66. params = null,
  67. conds = shopPoConds
  68. )
  69. try {
  70. deliveryOrders.valuesWithType += Pair(
  71. PurchaseOrderType.SHOP, apiCallerService.get<M18PurchaseOrderListResponse, M18PurchaseOrderListRequest>(
  72. M18_FETCH_PURCHASE_ORDER_LIST_API,
  73. shopPoParams
  74. ).block()
  75. )
  76. } catch (e: Exception) {
  77. logger.error("(Getting Shop Po list) Error on Function - ${e.stackTrace}")
  78. logger.error(e.message)
  79. }
  80. return deliveryOrders
  81. }
  82. open fun getDeliveryOrder(id: Long): M18PurchaseOrderResponse? {
  83. val deliveryOrderParams = M18PurchaseOrderRequest(
  84. id = id
  85. )
  86. var deliveryOrder: M18PurchaseOrderResponse? = null
  87. try {
  88. deliveryOrder = apiCallerService.get<M18PurchaseOrderResponse, M18PurchaseOrderRequest>(
  89. M18_LOAD_PURCHASE_ORDER_API,
  90. deliveryOrderParams
  91. ).block()
  92. } catch (e: Exception) {
  93. logger.error("(Getting Po Detail) Error on Function - ${e.stackTrace}")
  94. logger.error(e.message)
  95. }
  96. return deliveryOrder
  97. }
  98. open fun saveDeliveryOrders(request: M18TestDoRequest) {
  99. logger.info("--------------------------------------------Start - Saving M18 Delivery Order--------------------------------------------")
  100. val deliveryOrdersWithType = getDeliveryOrdersWithType(request)
  101. val successList = mutableListOf<Long>()
  102. val successDetailList = mutableListOf<Long>()
  103. val failList = mutableListOf<Long>()
  104. val failDetailList = mutableListOf<Long>()
  105. val failItemDetailList = mutableListOf<Long>()
  106. val doRefType = "Delivery Order"
  107. val doLineRefType = "Delivery Order Line"
  108. if (deliveryOrdersWithType != null) {
  109. // Loop for Delivery Orders (values)
  110. deliveryOrdersWithType.valuesWithType.forEach { deliveryOrderWithType ->
  111. val type = deliveryOrderWithType.first
  112. // if success
  113. val deliveryOrdersValues = deliveryOrderWithType.second?.values
  114. // if fail
  115. val deliveryOrdersMessages = deliveryOrderWithType.second?.messages
  116. if (deliveryOrdersValues != null) {
  117. deliveryOrdersValues.forEach { deliveryOrder ->
  118. val deliveryOrderDetail = getDeliveryOrder(deliveryOrder.id)
  119. var deliveryOrderId: Long? = null //FP-MTMS
  120. // Process for Delivery Order (mainpo)
  121. // Assume only one DO in the DO (search by DO ID)
  122. val mainpo = deliveryOrderDetail?.data?.mainpo?.get(0)
  123. val pot = deliveryOrderDetail?.data?.pot
  124. val deliveryOrderLineMessage = deliveryOrderDetail?.messages
  125. // delivery_order + m18_data_log table
  126. if (mainpo != null) {
  127. // Find the latest m18 data log by m18 id & type
  128. logger.info("${doRefType}: Finding For Latest M18 Data Log...")
  129. val latestDeliveryOrderLog =
  130. m18DataLogService.findLatestM18DataLogWithSuccess(deliveryOrder.id, doRefType)
  131. logger.info(latestDeliveryOrderLog.toString())
  132. // Save to m18_data_log table
  133. logger.info("${doRefType}: Saving for M18 Data Log...")
  134. val mainpoJson =
  135. mainpo::class.memberProperties.associate { prop -> prop.name to prop.getter.call(mainpo) }
  136. .toMutableMap()
  137. val saveM18DeliveryOrderLogRequest = SaveM18DataLogRequest(
  138. id = null,
  139. refType = doRefType,
  140. m18Id = deliveryOrder.id,
  141. m18LastModifyDate = commonUtils.timestampToLocalDateTime(mainpo.lastModifyDate),
  142. // dataLog = mainpoJson,
  143. statusEnum = M18DataLogStatus.NOT_PROCESS
  144. )
  145. val saveM18DeliveryOrderLog =
  146. m18DataLogService.saveM18DataLog(saveM18DeliveryOrderLogRequest)
  147. // logger.info("${doRefType}: Saved M18 Data Log. ID: ${saveM18DeliveryOrderLog.id}")
  148. try {
  149. // Find the delivery_order if exist
  150. logger.info("${doRefType}: Finding exising delivery order...")
  151. val existingDeliveryOrder =
  152. latestDeliveryOrderLog?.id?.let { deliveryOrderService.findByM18DataLogId(it) }
  153. logger.info("${doRefType}: Exising delivery order ID: ${existingDeliveryOrder?.id}")
  154. // Save to delivery_order table
  155. logger.info("${doRefType}: Saving delivery order...")
  156. val saveDeliveryOrderRequest = SaveDeliveryOrderRequest(
  157. id = existingDeliveryOrder?.id,
  158. code = mainpo.code,
  159. m18SupplierId = mainpo.venId,
  160. m18ShopId = mainpo.virDeptId,
  161. m18CurrencyId = mainpo.curId,
  162. orderDate = commonUtils.timestampToLocalDateTime(mainpo.tDate),
  163. estimatedArrivalDate = commonUtils.timestampToLocalDateTime(mainpo.dDate),
  164. completeDate = null,
  165. status = DeliveryOrderStatus.PENDING.value,
  166. type = type.value,
  167. m18DataLogId = saveM18DeliveryOrderLog.id,
  168. handlerId = null,
  169. m18BeId = mainpo.beId
  170. )
  171. val saveDeliveryOrderResponse =
  172. deliveryOrderService.saveDeliveryOrder(saveDeliveryOrderRequest)
  173. deliveryOrderId = saveDeliveryOrderResponse.id
  174. // Update m18_data_log with success
  175. val successSaveM18DeliveryOrderLogRequest = SaveM18DataLogRequest(
  176. id = saveM18DeliveryOrderLog.id,
  177. dataLog = mainpoJson,
  178. statusEnum = M18DataLogStatus.SUCCESS
  179. )
  180. m18DataLogService.saveM18DataLog(successSaveM18DeliveryOrderLogRequest)
  181. // log success info
  182. successList.add(deliveryOrder.id)
  183. logger.info("${doRefType}: Saved delivery order. ID: ${saveDeliveryOrderResponse.id} | M18 ${doRefType} ID: ${deliveryOrder.id}")
  184. } catch (e: Exception) {
  185. failList.add(deliveryOrder.id)
  186. logger.error("${doRefType}: Saving Failure!")
  187. logger.error("Error on Function - ${e.stackTrace} | Type: ${doRefType} | M18 ID: ${deliveryOrder.id} | Different? ${mainpo.id}")
  188. logger.error(e.message)
  189. val errorSaveM18DeliveryOrderLogRequest = SaveM18DataLogRequest(
  190. id = saveM18DeliveryOrderLog.id,
  191. dataLog = mutableMapOf(Pair("Exception Message", e.message)),
  192. statusEnum = M18DataLogStatus.FAIL
  193. )
  194. m18DataLogService.saveM18DataLog(errorSaveM18DeliveryOrderLogRequest)
  195. logger.error("${doRefType}: M18 Data Log Updated! Please see the error. ID: ${saveM18DeliveryOrderLogRequest.id}")
  196. }
  197. // delivery_order_line + m18_data_log
  198. // TODO: check deleted po line?
  199. if (pot != null) {
  200. // Loop for Delivery Order Lines (pot)
  201. pot.forEach { line ->
  202. // Find the latest m18 data log by m18 id & type
  203. logger.info("${doLineRefType}: Finding For Latest M18 Data Log...")
  204. val latestDeliveryOrderLineLog =
  205. m18DataLogService.findLatestM18DataLogWithSuccess(line.id, doLineRefType)
  206. // logger.info("${doLineRefType}: Latest M18 Data Log ID: ${latestDeliveryOrderLineLog?.id}")
  207. // Save to m18_data_log table
  208. logger.info("${doLineRefType}: Saving for M18 Data Log...")
  209. val lineJson =
  210. line::class.memberProperties.associate { prop ->
  211. prop.name to prop.getter.call(
  212. line
  213. )
  214. }
  215. .toMutableMap()
  216. val saveM18DeliveryOrderLineLogRequest = SaveM18DataLogRequest(
  217. id = null,
  218. refType = doLineRefType,
  219. m18Id = line.id,
  220. m18LastModifyDate = commonUtils.timestampToLocalDateTime(mainpo.lastModifyDate),
  221. // dataLog = lineJson,
  222. statusEnum = M18DataLogStatus.NOT_PROCESS
  223. )
  224. val saveM18DeliveryOrderLineLog =
  225. m18DataLogService.saveM18DataLog(saveM18DeliveryOrderLineLogRequest)
  226. // logger.info("${doLineRefType}: Saved M18 Data Log. ID: ${saveM18DeliveryOrderLineLog.id}")
  227. logger.info("${doLineRefType}: Finding item...")
  228. val item = itemsService.findByM18Id(line.proId)
  229. var itemId: Long? = null
  230. if (item == null) {
  231. itemId = m18MasterDataService.saveProduct(line.proId)?.id
  232. } else {
  233. itemId = item.id
  234. }
  235. logger.info("${doLineRefType}: Item ID: ${itemId} | M18 Item ID: ${line.proId}")
  236. try {
  237. // Find the delivery_order_line if exist
  238. logger.info("${doLineRefType}: Finding exising delivery order line...")
  239. val existingDeliveryOrderLine = latestDeliveryOrderLineLog?.id?.let {
  240. deliveryOrderLineService.findDeliveryOrderLineByM18Id(it)
  241. }
  242. logger.info("${doLineRefType}: Exising delivery order line ID: ${existingDeliveryOrderLine?.id}")
  243. // Save to delivery_order_line table
  244. logger.info("${doLineRefType}: Saving delivery order line...")
  245. val itemUom = itemId?.let { itemUomService.findSalesUnitByItemId(it) }
  246. val saveDeliveryOrderLineRequest = SaveDeliveryOrderLineRequest(
  247. id = existingDeliveryOrderLine?.id,
  248. itemId = itemId,
  249. uomId = itemUom?.uom?.id,
  250. deliveryOrderId = deliveryOrderId,
  251. qty = line.qty,
  252. price = line.amt,
  253. // m18CurrencyId = mainpo.curId,
  254. status = existingDeliveryOrderLine?.status?.value
  255. ?: DeliveryOrderLineStatus.PENDING.value,
  256. m18DataLogId = saveM18DeliveryOrderLineLog.id,
  257. m18Discount = line.disc,
  258. m18Lot = line.lot
  259. )
  260. val saveDeliveryOrderLineResponse =
  261. deliveryOrderLineService.saveDeliveryOrderLine(saveDeliveryOrderLineRequest)
  262. // Update m18_data_log with success
  263. val successSaveM18DeliveryOrderLineLogRequest = SaveM18DataLogRequest(
  264. id = saveM18DeliveryOrderLineLog.id,
  265. dataLog = lineJson,
  266. statusEnum = M18DataLogStatus.SUCCESS
  267. )
  268. m18DataLogService.saveM18DataLog(successSaveM18DeliveryOrderLineLogRequest)
  269. // log success info
  270. successDetailList.add(line.id)
  271. logger.info("${doLineRefType}: Delivery order ID: ${deliveryOrderId} | M18 ID: ${deliveryOrder.id}")
  272. logger.info("${doLineRefType}: Saved delivery order line. ID: ${saveDeliveryOrderLineResponse.id} | M18 Line ID: ${line.id}")
  273. } catch (e: Exception) {
  274. failDetailList.add(line.id)
  275. failItemDetailList.add(line.proId)
  276. logger.error("${doLineRefType}: Saving Failure!")
  277. logger.error("Error on Function - ${e.stackTrace} | Type: ${doLineRefType} | M18 ID: ${line.id}")
  278. logger.error(e.message)
  279. val errorSaveM18DeliveryOrderLineLogRequest = SaveM18DataLogRequest(
  280. id = saveM18DeliveryOrderLineLog.id,
  281. dataLog = mutableMapOf(Pair("Exception Message", e.message)),
  282. statusEnum = M18DataLogStatus.FAIL
  283. )
  284. m18DataLogService.saveM18DataLog(errorSaveM18DeliveryOrderLineLogRequest)
  285. logger.error("${doLineRefType}: M18 Data Log Updated! Please see the error. ID: ${saveM18DeliveryOrderLineLog.id}")
  286. }
  287. }
  288. } else {
  289. // pot
  290. logger.error("${doLineRefType}: Saving Failure!")
  291. val saveM18DeliveryOrderLineLogRequest = SaveM18DataLogRequest(
  292. id = null,
  293. refType = "${doLineRefType}",
  294. m18Id = deliveryOrder.id,
  295. m18LastModifyDate = commonUtils.timestampToLocalDateTime(mainpo.lastModifyDate),
  296. // dataLog = mutableMapOf(Pair("Error Message", "${doLineRefType} is null")),
  297. dataLog = mutableMapOf(
  298. Pair(
  299. "${doLineRefType} Error Message",
  300. "pot is null"
  301. ),
  302. Pair(
  303. "${doLineRefType} Error Code",
  304. deliveryOrderLineMessage?.get(0)?.msgCode ?: "No Msg Code from M18"
  305. ),
  306. Pair(
  307. "${doLineRefType} Error Detail",
  308. deliveryOrderLineMessage?.get(0)?.msgDetail ?: "No Msg Detail from M18"
  309. ),
  310. ),
  311. statusEnum = M18DataLogStatus.FAIL
  312. )
  313. val errorLog = m18DataLogService.saveM18DataLog(saveM18DeliveryOrderLineLogRequest)
  314. logger.error("${doLineRefType}: M18 Data Log Updated! Please see the error. ID: ${errorLog.id}")
  315. }
  316. } else {
  317. // mainpo
  318. failList.add(deliveryOrder.id)
  319. logger.error("${doRefType}: Saving Failure!")
  320. val saveM18DataLogRequest = SaveM18DataLogRequest(
  321. id = null,
  322. refType = "${doRefType}",
  323. m18Id = deliveryOrder.id,
  324. // m18LastModifyDate = if(mainpo?.lastModifyDate != null) commonUtils.instantToLocalDateTime(mainpo.lastModifyDate) else LocalDateTime.now(),
  325. m18LastModifyDate = LocalDateTime.now(),
  326. dataLog = mutableMapOf(
  327. Pair(
  328. "${doRefType} Error",
  329. "mainpo is null"
  330. ),
  331. Pair(
  332. "${doRefType} Error Code",
  333. deliveryOrdersMessages?.get(0)?.msgCode ?: "No Msg Code from M18"
  334. ),
  335. Pair(
  336. "${doRefType} Error Detail",
  337. deliveryOrdersMessages?.get(0)?.msgDetail ?: "No Msg Detail from M18"
  338. ),
  339. ),
  340. statusEnum = M18DataLogStatus.FAIL
  341. )
  342. val errorLog = m18DataLogService.saveM18DataLog(saveM18DataLogRequest)
  343. logger.error("${doLineRefType}: M18 Data Log Updated! Please see the error. ID: ${errorLog.id}")
  344. }
  345. }
  346. } else {
  347. logger.error("${doRefType} List is null. May occur errors.")
  348. }
  349. }
  350. } else {
  351. logger.error("${doRefType} List is null. May occur errors.")
  352. }
  353. // End of save. Check result
  354. logger.info("Total Success (${doRefType}) (${successList.size}): $successList")
  355. // if (failList.size > 0) {
  356. logger.error("Total Fail (${doRefType}) (${failList.size}): $failList")
  357. // }
  358. logger.info("Total Success (${doLineRefType}) (${successDetailList.size}): $successDetailList")
  359. // if (failDetailList.size > 0) {
  360. logger.error("Total Fail (${doLineRefType}) (${failDetailList.size}): $failDetailList")
  361. logger.error("Total Fail M18 Items (${doLineRefType}) (${failItemDetailList.distinct().size}): ${failItemDetailList.distinct()}")
  362. // }
  363. logger.info("--------------------------------------------End - Saving M18 Delivery Order--------------------------------------------")
  364. }
  365. }