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.
 
 
 
 
 

563 regels
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.model.*
  6. import com.ffii.fpsms.m18.utils.CommonUtils
  7. import com.ffii.fpsms.modules.master.entity.UomConversion
  8. import com.ffii.fpsms.modules.master.enums.ShopType
  9. import com.ffii.fpsms.modules.master.service.*
  10. import com.ffii.fpsms.modules.master.web.models.*
  11. import org.slf4j.Logger
  12. import org.slf4j.LoggerFactory
  13. import org.springframework.stereotype.Service
  14. import java.math.BigDecimal
  15. import java.time.LocalDate
  16. import java.time.LocalDateTime
  17. import java.time.format.DateTimeFormatter
  18. @Service
  19. open class M18MasterDataService(
  20. val m18Config: M18Config,
  21. val apiCallerService: ApiCallerService,
  22. val itemsService: ItemsService,
  23. val shopService: ShopService,
  24. val uomConversionService: UomConversionService,
  25. val currencyService: CurrencyService,
  26. val itemUomService: ItemUomService,
  27. val bomService: BomService,
  28. val bomMaterialService: BomMaterialService,
  29. ) {
  30. val logger: Logger = LoggerFactory.getLogger(JwtTokenUtil::class.java)
  31. val commonUtils = CommonUtils()
  32. val formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")
  33. // M18 Conditions
  34. val lastModifyDate = LocalDate.now().minusDays(1)
  35. val lastModifyDateConds = "lastModifyDate=largerThan=$lastModifyDate"
  36. val seriesIdList =
  37. listOf(m18Config.SERIESID_SC, m18Config.SERIESID_SE, m18Config.SERIESID_SF, m18Config.SERIESID_SR)
  38. val seriesIdConds =
  39. "(" + commonUtils.listToString(seriesIdList.filterNotNull(), "seriesId=unequal=", "=or=") + ")"
  40. val beIdList = listOf(m18Config.BEID_PF, m18Config.BEID_PP, m18Config.BEID_TOA)
  41. val beIdConds = "(" + commonUtils.listToString(beIdList.filterNotNull(), "beId=equal=", "=or=") + ")"
  42. // val beIdConds = commonUtils.BEID_CONDS
  43. // M18 API
  44. val M18_COMMON_FETCH_LIST_API = "/search/search"
  45. val M18_COMMON_LOAD_LINE_API = "/root/api/read"
  46. val M18_LOAD_PRODUCT_API = "${M18_COMMON_LOAD_LINE_API}/${StSearchType.PRODUCT.value}"
  47. val M18_LOAD_VENDOR_API = "${M18_COMMON_LOAD_LINE_API}/${StSearchType.VENDOR.value}"
  48. val M18_LOAD_UNIT_API = "${M18_COMMON_LOAD_LINE_API}/${StSearchType.UNIT.value}"
  49. val M18_LOAD_CURRENCY_API = "${M18_COMMON_LOAD_LINE_API}/${StSearchType.CURRENCY.value}"
  50. val M18_LOAD_BOM_API = "${M18_COMMON_LOAD_LINE_API}/${StSearchType.BOM.value}"
  51. // --------------------------------------------- Common Function --------------------------------------------- ///
  52. private inline fun <reified T : Any> getList(
  53. stSearch: String?,
  54. params: String? = null,
  55. conds: String? = null,
  56. ): T? {
  57. val request = M18CommonListRequest(
  58. stSearch = stSearch,
  59. params = params,
  60. conds = conds
  61. )
  62. val response = apiCallerService.get<T, M18CommonListRequest>(
  63. M18_COMMON_FETCH_LIST_API,
  64. request
  65. ).block()
  66. return response
  67. }
  68. private inline fun <reified T : Any> getLine(
  69. id: Long,
  70. params: String?,
  71. api: String,
  72. ): T? {
  73. val request = M18CommonLineRequest(
  74. id = id,
  75. params = params,
  76. )
  77. val response = apiCallerService.get<T, M18CommonLineRequest>(
  78. api,
  79. request
  80. ).block()
  81. return response
  82. }
  83. // --------------------------------------------- Product --------------------------------------------- ///
  84. open fun getProducts(): M18ProductListResponse? {
  85. // seems no beId
  86. return getList<M18ProductListResponse>(
  87. stSearch = StSearchType.PRODUCT.value,
  88. params = null,
  89. conds = seriesIdConds
  90. )
  91. // val itemsParams = M18CommonListRequest(
  92. // stSearch = StSearchType.PRODUCT.value,
  93. // params = null,
  94. // conds = seriesIdConds
  95. // )
  96. //
  97. // val items = apiCallerService.get<M18ProductListResponse, M18CommonListRequest>(
  98. // M18_COMMON_FETCH_LIST_API,
  99. // itemsParams
  100. // ).block()
  101. //
  102. // return items
  103. }
  104. open fun getProduct(id: Long): M18ProductResponse? {
  105. logger.info("M18 Product ID: $id")
  106. return getLine<M18ProductResponse>(
  107. id = id,
  108. params = null,
  109. api = M18_LOAD_PRODUCT_API
  110. )
  111. }
  112. open fun saveProducts() {
  113. logger.info("--------------------------------------------Start - Saving M18 Products / Materials--------------------------------------------")
  114. val items = getProducts()
  115. val exampleProducts = listOf<Long>(10946L, 3825L)
  116. val successList = mutableListOf<Long>()
  117. val failList = mutableListOf<Long>()
  118. val values = items?.values?.sortedBy { it.id }
  119. if (values != null) {
  120. values.forEach { item ->
  121. // if (item.id in exampleProducts) {
  122. try {
  123. val itemDetail = getProduct(item.id)
  124. val pro = itemDetail?.data?.pro?.get(0)
  125. val price = itemDetail?.data?.price
  126. if (itemDetail != null && pro != null) {
  127. val existingItem = itemsService.findByM18Id(item.id)
  128. val saveItemRequest = NewItemRequest(
  129. code = pro.code,
  130. name = pro.desc,
  131. // type = if (pro.seriesId == m18Config.SERIESID_PF) ProductType.MATERIAL
  132. // else ItemType.PRODUCT,
  133. type = ItemType.MATERIAL,
  134. id = existingItem?.id,
  135. description = pro.desc,
  136. remarks = null,
  137. shelfLife = null,
  138. countryOfOrigin = null,
  139. maxQty = null,
  140. m18Id = item.id,
  141. m18LastModifyDate = commonUtils.timestampToLocalDateTime(pro.lastModifyDate)
  142. )
  143. val savedItem = itemsService.saveItem(saveItemRequest)
  144. logger.info("Processing item uom...")
  145. // Find the item uom that ready to delete (not in m18)
  146. val existingItemUoms = savedItem.id?.let { itemUomService.findAllByItemsId(it) }
  147. val m18ItemUomIds = price?.map { it.id } ?: listOf()
  148. // Delete the item uom
  149. logger.info("Deleting item uom...")
  150. // logger.info("Item Uom: ${existingItemUoms?.map { it.m18Id }}")
  151. // logger.info("M18: ${m18ItemUomIds}")
  152. existingItemUoms?.filter { it.m18Id !in m18ItemUomIds }?.mapNotNull { it.id }
  153. ?.let { itemUomService.deleteItemUoms(it) }
  154. // Update the item uom
  155. logger.info("Updating item uom...")
  156. price?.forEach {
  157. val itemUomRequest = ItemUomRequest(
  158. m18UomId = it.unitId,
  159. itemId = savedItem.id,
  160. baseUnit = it.basicUnit,
  161. stockUnit = it.stkUnit,
  162. pickingUnit = it.pickUnit,
  163. salesUnit = it.saleUnit,
  164. purchaseUnit = it.purUnit,
  165. price = null,
  166. currencyId = null,
  167. m18Id = it.id,
  168. m18LastModifyDate = commonUtils.timestampToLocalDateTime(pro.lastModifyDate)
  169. )
  170. // logger.info("saved item id: ${savedItem.id}")
  171. itemUomService.saveItemUom(itemUomRequest)
  172. }
  173. successList.add(item.id)
  174. logger.info("Success Count ${successList.size}: ${item.id} | ${pro.code} | ${pro.desc}")
  175. } else {
  176. failList.add(item.id)
  177. logger.error("Fail Message: ${itemDetail?.messages?.get(0)?.msgDetail}")
  178. logger.error("Fail Count ${failList.size}: Item ID - ${item.id} Not Found")
  179. }
  180. } catch (e: Exception) {
  181. failList.add(item.id)
  182. logger.error("Exception")
  183. logger.error("Fail Message: ${e.message}")
  184. logger.error("Fail Count ${failList.size}: Item ID - ${item.id}")
  185. }
  186. }
  187. } else {
  188. logger.error("Items List is null. May occur errors.")
  189. }
  190. logger.info("Total Success (${successList.size})")
  191. if (failList.size > 0) {
  192. logger.error("Total Fail (${failList.size}): $failList")
  193. }
  194. logger.info("--------------------------------------------End - Saving M18 Products / Materials--------------------------------------------")
  195. }
  196. // --------------------------------------------- Vendor --------------------------------------------- ///
  197. open fun getVendors(): M18VendorListResponse? {
  198. return getList<M18VendorListResponse>(
  199. stSearch = StSearchType.VENDOR.value,
  200. params = null,
  201. conds = beIdConds
  202. )
  203. }
  204. open fun getVendor(id: Long): M18VendorResponse? {
  205. logger.info("M18 Vendor ID: $id")
  206. return getLine<M18VendorResponse>(
  207. id = id,
  208. params = null,
  209. api = M18_LOAD_VENDOR_API
  210. )
  211. }
  212. open fun saveVendors() {
  213. logger.info("--------------------------------------------Start - Saving M18 Vendors--------------------------------------------")
  214. val vendors = getVendors()
  215. val exampleVendors = listOf<Long>(191L)
  216. val successList = mutableListOf<Long>()
  217. val failList = mutableListOf<Long>()
  218. val values = vendors?.values?.sortedBy { it.id }
  219. if (values != null) {
  220. values.forEach { vendor ->
  221. // if (vendor.id in exampleVendors) {
  222. try {
  223. val vendorDetail = getVendor(vendor.id)
  224. if (vendorDetail != null && vendorDetail.data?.ven != null) {
  225. val ven = vendorDetail.data.ven[0]
  226. val saveShopRequest = SaveShopRequest(
  227. id = null,
  228. code = ven.code,
  229. name = ven.desc.ifEmpty { ven.`desc_zh-TW` },
  230. brNo = null,
  231. contactNo = ven.tel,
  232. contactEmail = ven.email,
  233. contactName = null,
  234. addr1 = ven.ad1,
  235. addr2 = ven.ad2,
  236. addr3 = ven.ad3,
  237. addr4 = ven.ad4,
  238. district = null,
  239. type = ShopType.SUPPLIER.value,
  240. m18Id = vendor.id,
  241. m18LastModifyDate = commonUtils.timestampToLocalDateTime(ven.lastModifyDate)
  242. )
  243. shopService.saveShop(saveShopRequest)
  244. successList.add(vendor.id)
  245. logger.info("Success Count ${successList.size}: ${vendor.id} | ${ven.code} | ${ven.desc}")
  246. } else {
  247. failList.add(vendor.id)
  248. logger.error("Fail Message: ${vendorDetail?.messages?.get(0)?.msgDetail}")
  249. logger.error("Fail Count ${failList.size}: Vendor ID - ${vendor.id} Not Found")
  250. }
  251. } catch (e: Exception) {
  252. failList.add(vendor.id)
  253. logger.error("Exception")
  254. logger.error("Fail Message: ${e.message}")
  255. logger.error("Fail Count ${failList.size}: Vendor ID - ${vendor.id}")
  256. }
  257. // }
  258. }
  259. } else {
  260. logger.error("Vendor List is null. May occur errors.")
  261. }
  262. logger.info("Total Success (${successList.size})")
  263. if (failList.size > 0) {
  264. logger.error("Total Fail (${failList.size}): $failList")
  265. }
  266. logger.info("--------------------------------------------End - Saving M18 Vendors--------------------------------------------")
  267. }
  268. // --------------------------------------------- Unit --------------------------------------------- ///
  269. open fun getUnits(): M18UnitListResponse? {
  270. // seems no beId
  271. return getList<M18UnitListResponse>(
  272. stSearch = StSearchType.UNIT.value,
  273. params = null,
  274. conds = null
  275. )
  276. }
  277. open fun getUnit(id: Long): M18UnitResponse? {
  278. logger.info("M18 Unit ID: $id")
  279. return getLine<M18UnitResponse>(
  280. id = id,
  281. params = null,
  282. api = M18_LOAD_UNIT_API
  283. )
  284. }
  285. open fun saveUnits() {
  286. logger.info("--------------------------------------------Start - Saving M18 Units--------------------------------------------")
  287. val units = getUnits()
  288. val successTransformList = mutableListOf<Long>()
  289. val successSaveList = mutableListOf<Long>()
  290. val failTransformList = mutableListOf<Long>()
  291. val failSaveList = mutableListOf<Long>()
  292. val values = units?.values?.sortedBy { it.id }
  293. if (values != null) {
  294. val finalUnitList = arrayListOf<UomConversion>()
  295. // transform unit
  296. values.forEach { unit ->
  297. try {
  298. val tempObject = UomConversionService.BomObject().apply {
  299. code = unit.code
  300. udfudesc = unit.udfudesc
  301. lastModifyDate = unit.lastModifyDate
  302. id = unit.id
  303. }
  304. finalUnitList += uomConversionService.transformItem(tempObject)
  305. successTransformList += unit.id
  306. logger.info("Transform Success (M18): ${unit.id}")
  307. } catch (e: Exception) {
  308. failTransformList.add(unit.id)
  309. logger.error("Transform Exception")
  310. logger.error("Transform Fail Message: ${e.message}")
  311. logger.error("Transform Fail Count ${failTransformList.size}: Unit ID - ${unit.id}")
  312. }
  313. }
  314. uomConversionService.calculateSizeInGram(finalUnitList)
  315. finalUnitList.forEach {
  316. try {
  317. uomConversionService.saveUomConversion(it)
  318. successSaveList += it.m18Id
  319. logger.info("Save Success (M18): ${it.m18Id}")
  320. } catch (e: Exception) {
  321. failSaveList.add(it.m18Id)
  322. logger.error("Save Exception")
  323. logger.error("Save Fail Message: ${e.message}")
  324. logger.error("Save Fail Count ${failTransformList.size}: Unit ID - ${it.m18Id}")
  325. }
  326. }
  327. } else {
  328. logger.error("Unit List is null. May occur errors.")
  329. }
  330. logger.info("Total Transform Success (${successTransformList.size})")
  331. logger.info("Total Save Success (${successSaveList.size})")
  332. if (failTransformList.size > 0) {
  333. logger.error("Total Transform Fail (${failTransformList.size}): $failTransformList")
  334. }
  335. if (failSaveList.size > 0) {
  336. logger.error("Total Save Fail (${failSaveList.size}): $failSaveList")
  337. }
  338. logger.info("--------------------------------------------End - Saving M18 Units--------------------------------------------")
  339. }
  340. // --------------------------------------------- Currency --------------------------------------------- ///
  341. open fun getCurrencies(): M18CurrencyListResponse? {
  342. return getList<M18CurrencyListResponse>(
  343. stSearch = StSearchType.CURRENCY.value,
  344. params = null,
  345. conds = null
  346. )
  347. }
  348. open fun getCurrency(id: Long): M18CurrencyResponse? {
  349. logger.info("M18 Currency ID: $id")
  350. return getLine<M18CurrencyResponse>(
  351. id = id,
  352. params = null,
  353. api = M18_LOAD_CURRENCY_API
  354. )
  355. }
  356. open fun saveCurrencies() {
  357. logger.info("--------------------------------------------Start - Saving M18 Currencies--------------------------------------------")
  358. val currencies = getCurrencies()
  359. val successList = mutableListOf<Long>()
  360. val failList = mutableListOf<Long>()
  361. val values = currencies?.values?.sortedBy { it.id }
  362. if (values != null) {
  363. // save currency
  364. values.forEach { currency ->
  365. try {
  366. val currencyRequest = SaveCurrencyRequest(
  367. id = null,
  368. code = currency.code,
  369. name = currency.sym,
  370. description = currency.curDesc,
  371. m18Id = currency.id,
  372. m18LastModifyDate = LocalDateTime.parse(currency.lastModifyDate, formatter)
  373. )
  374. currencyService.saveCurrency(currencyRequest)
  375. successList += currency.id
  376. logger.info("Save Success (M18): ${currency.id}")
  377. } catch (e: Exception) {
  378. failList += currency.id
  379. logger.error("Exception")
  380. logger.error("Fail Message: ${e.message}")
  381. logger.error("Fail Count ${failList.size}: Unit ID - ${currency.id}")
  382. }
  383. }
  384. } else {
  385. logger.error("Currency List is null. May occur errors.")
  386. }
  387. logger.info("Total Save Success (${successList.size})")
  388. if (failList.size > 0) {
  389. logger.error("Total Fail (${failList.size}): $failList")
  390. }
  391. logger.info("--------------------------------------------End - Saving Currencies--------------------------------------------")
  392. }
  393. // --------------------------------------------- Bom --------------------------------------------- ///
  394. open fun getBoms(): M18BomListResponse? {
  395. return getList<M18BomListResponse>(
  396. stSearch = StSearchType.BOM.value,
  397. params = null,
  398. conds = beIdConds
  399. )
  400. }
  401. open fun getBom(id: Long): M18BomResponse? {
  402. logger.info("M18 Bom ID: $id")
  403. return getLine<M18BomResponse>(
  404. id = id,
  405. params = null,
  406. api = M18_LOAD_BOM_API
  407. )
  408. }
  409. open fun saveBoms() {
  410. logger.info("--------------------------------------------Start - Saving M18 Boms--------------------------------------------")
  411. val boms = getBoms()
  412. val successList = mutableListOf<Long>()
  413. val successDetailList = mutableListOf<Long>()
  414. val failList = mutableListOf<Long>()
  415. val failDetailList = mutableListOf<Pair<Long, MutableList<Long>>>()
  416. var failDetailCount = 0
  417. val values = boms?.values?.sortedBy { it.id }
  418. if (values != null) {
  419. values.forEach { bom ->
  420. try {
  421. val bomDetail = getBom(bom.id)
  422. val bomUdfBomForShop = bomDetail?.data?.udfbomforshop?.get(0)
  423. val bomUdfProduct = bomDetail?.data?.udfproduct
  424. logger.info(bomUdfBomForShop.toString())
  425. logger.info(bomUdfProduct.toString())
  426. if (bomUdfBomForShop != null && bomUdfProduct != null) {
  427. // Save Bom
  428. logger.info("AAAAA")
  429. val saveBomRequest = SaveBomRequest(
  430. // itemId = itemsService.findByNameAndM18UomId(bomUdfBomForShop.desc, bomUdfBomForShop.udfUnit)?.id,
  431. code = bomUdfBomForShop.code,
  432. name = bomUdfBomForShop.desc,
  433. description = bomUdfBomForShop.desc,
  434. outputQty = if (bomUdfBomForShop.udfHarvest.trim().toBigDecimalOrNull() != null) bomUdfBomForShop.udfHarvest.trim().toBigDecimal() else BigDecimal(0),
  435. outputQtyUom = bomUdfBomForShop.udfHarvestUnit,
  436. yield = bomUdfBomForShop.udfYieldratePP,
  437. m18UomId = bomUdfBomForShop.udfUnit,
  438. m18Id = bomUdfBomForShop.id,
  439. m18LastModifyDate = commonUtils.timestampToLocalDateTime(bomUdfBomForShop.lastModifyDate)
  440. )
  441. logger.info("BBBBB")
  442. val bomId = bomService.saveBom(saveBomRequest).id
  443. successList += bom.id
  444. // Save Bom Material
  445. logger.info("Start saving bom material...")
  446. val tempFailList = mutableListOf<Long>()
  447. bomUdfProduct.forEach { bomMaterial ->
  448. try {
  449. val saveBomMaterialRequest = SaveBomMaterialRequest(
  450. m18ItemId = bomMaterial.udfProduct,
  451. itemName = bomMaterial.udfIngredients,
  452. qty = bomMaterial.udfqty,
  453. m18UomId = bomMaterial.udfpurchaseUnit,
  454. uomName = bomMaterial.udfBaseUnit,
  455. bomId = bomId,
  456. m18Id = bomMaterial.id,
  457. m18LastModifyDate = commonUtils.timestampToLocalDateTime(bomUdfBomForShop.lastModifyDate)
  458. )
  459. bomMaterialService.saveBomMaterial(saveBomMaterialRequest)
  460. successDetailList += bomMaterial.id
  461. } catch (e: Exception) {
  462. tempFailList += bomMaterial.id
  463. logger.error("(Bom Material) Exception")
  464. logger.error("(Bom Material) Fail Message: ${e.message}")
  465. logger.error("(Bom Material) Fail Count ${++failDetailCount}: Bom Material ID - ${bomMaterial.id} | Bom ID - ${bom.id}")
  466. }
  467. }
  468. failDetailList += Pair(bom.id, tempFailList)
  469. logger.info("Save Success (M18): ${bom.id}")
  470. } else {
  471. failList.add(bom.id)
  472. logger.error("(Bom) Fail Message: ${bomDetail?.messages?.get(0)?.msgDetail}")
  473. logger.error("(Bom) Fail Count ${failList.size}: Bom ID - ${bom.id} Not Found")
  474. }
  475. } catch (e: Exception) {
  476. failList += bom.id
  477. logger.error("(Bom) Exception")
  478. logger.error("(Bom) Fail Message: ${e.message}")
  479. logger.error("(Bom) Fail Count ${failList.size}: Bom ID - ${bom.id}")
  480. }
  481. }
  482. } else {
  483. logger.error("Currency List is null. May occur errors.")
  484. }
  485. logger.info("Total Bom Save Success (${successList.size})")
  486. logger.info("Total Bom Save Detail Success (${successDetailList.size})")
  487. if (failList.size > 0) {
  488. logger.error("Total Bom Fail (${failList.size}): $failList")
  489. }
  490. if (failDetailCount > 0) {
  491. logger.error("Total Bom Detail Fail (${failDetailCount}): $failDetailList")
  492. }
  493. logger.info("--------------------------------------------End - Saving Boms--------------------------------------------")
  494. }
  495. }