| @@ -2,6 +2,7 @@ package com.ffii.fpsms.api.service | |||||
| import com.ffii.core.utils.JwtTokenUtil | import com.ffii.core.utils.JwtTokenUtil | ||||
| import com.ffii.fpsms.m18.M18Config | import com.ffii.fpsms.m18.M18Config | ||||
| import com.ffii.fpsms.m18.service.M18TokenService | |||||
| import org.slf4j.Logger | import org.slf4j.Logger | ||||
| import org.slf4j.LoggerFactory | import org.slf4j.LoggerFactory | ||||
| import org.springframework.beans.factory.annotation.Value | import org.springframework.beans.factory.annotation.Value | ||||
| @@ -15,14 +16,17 @@ import org.springframework.web.reactive.function.client.bodyToMono | |||||
| import reactor.core.publisher.Mono | import reactor.core.publisher.Mono | ||||
| import kotlin.reflect.full.memberProperties | import kotlin.reflect.full.memberProperties | ||||
| import org.springframework.cloud.context.config.annotation.RefreshScope | import org.springframework.cloud.context.config.annotation.RefreshScope | ||||
| import org.springframework.context.annotation.Lazy | |||||
| import org.springframework.http.HttpStatus | import org.springframework.http.HttpStatus | ||||
| import org.springframework.http.HttpStatusCode | |||||
| import org.springframework.web.reactive.function.client.ClientRequest | import org.springframework.web.reactive.function.client.ClientRequest | ||||
| import org.springframework.web.reactive.function.client.WebClientResponseException | import org.springframework.web.reactive.function.client.WebClientResponseException | ||||
| import org.springframework.web.reactive.function.client.awaitBody | import org.springframework.web.reactive.function.client.awaitBody | ||||
| @Service | @Service | ||||
| open class ApiCallerService( | open class ApiCallerService( | ||||
| val m18Config: M18Config | |||||
| val m18Config: M18Config, | |||||
| @Lazy val m18TokenService: M18TokenService, | |||||
| ) { | ) { | ||||
| val logger: Logger = LoggerFactory.getLogger(JwtTokenUtil::class.java) | val logger: Logger = LoggerFactory.getLogger(JwtTokenUtil::class.java) | ||||
| @@ -80,6 +84,9 @@ open class ApiCallerService( | |||||
| logger.error("WebClientResponseException") | logger.error("WebClientResponseException") | ||||
| logger.error("Error Status: ${error.statusCode} - ${error.statusText}") | logger.error("Error Status: ${error.statusCode} - ${error.statusText}") | ||||
| logger.error("Error Message: ${error.message}") | logger.error("Error Message: ${error.message}") | ||||
| if (error.statusCode == HttpStatusCode.valueOf(400)) { | |||||
| m18TokenService.run() | |||||
| } | |||||
| Mono.error(error) | Mono.error(error) | ||||
| } | } | ||||
| .onErrorResume { error -> | .onErrorResume { error -> | ||||
| @@ -87,6 +94,7 @@ open class ApiCallerService( | |||||
| logger.error("Error Message: ${error.message}") | logger.error("Error Message: ${error.message}") | ||||
| Mono.error(error) | Mono.error(error) | ||||
| } | } | ||||
| .retry(5) | |||||
| } | } | ||||
| /** | /** | ||||
| @@ -29,6 +29,7 @@ open class M18Config { | |||||
| // Supplier | // Supplier | ||||
| // @Value("\${m18.config.supplier-not.material-po}") | // @Value("\${m18.config.supplier-not.material-po}") | ||||
| // var MATERIAL_PO_SUPPLIER_NOT: List<String> = listOf("P06", "P07", "T62"); // If need oem type | |||||
| var MATERIAL_PO_SUPPLIER_NOT: List<String> = listOf("P06", "P07"); | var MATERIAL_PO_SUPPLIER_NOT: List<String> = listOf("P06", "P07"); | ||||
| // @Value("\${m18.config.supplier.shop-po}") | // @Value("\${m18.config.supplier.shop-po}") | ||||
| @@ -58,13 +59,13 @@ open class M18Config { | |||||
| // BE | // BE | ||||
| // @Value("\${m18.config.beId.pp}") | // @Value("\${m18.config.beId.pp}") | ||||
| var BEID_PP: Long = 27; | |||||
| var BEID_PP: Long = 29; | |||||
| // @Value("\${m18.config.beId.pf}") | // @Value("\${m18.config.beId.pf}") | ||||
| var BEID_PF: Long = 1; | |||||
| var BEID_PF: Long = 27; | |||||
| // @Value("\${m18.config.beId.toa}") | // @Value("\${m18.config.beId.toa}") | ||||
| var BEID_TOA: Long = 29; | |||||
| var BEID_TOA: Long = 1; | |||||
| // Fetch | // Fetch | ||||
| var ACCESS_TOKEN: String? = null; | var ACCESS_TOKEN: String? = null; | ||||
| @@ -1,7 +1,10 @@ | |||||
| package com.ffii.fpsms.m18.entity | package com.ffii.fpsms.m18.entity | ||||
| import com.ffii.core.entity.BaseEntity | import com.ffii.core.entity.BaseEntity | ||||
| import com.ffii.fpsms.m18.enums.M18DataLogStatus | |||||
| import com.ffii.fpsms.m18.enums.M18DataLogStatusConverter | |||||
| import jakarta.persistence.Column | import jakarta.persistence.Column | ||||
| import jakarta.persistence.Convert | |||||
| import jakarta.persistence.Entity | import jakarta.persistence.Entity | ||||
| import jakarta.persistence.Table | import jakarta.persistence.Table | ||||
| import jakarta.validation.constraints.NotNull | import jakarta.validation.constraints.NotNull | ||||
| @@ -29,7 +32,8 @@ open class M18DataLog : BaseEntity<Long>() { | |||||
| @NotNull | @NotNull | ||||
| @Column(name = "status", nullable = false) | @Column(name = "status", nullable = false) | ||||
| open var status: Boolean? = null | |||||
| @Convert(converter = M18DataLogStatusConverter::class) | |||||
| open var status: M18DataLogStatus? = null | |||||
| @NotNull | @NotNull | ||||
| @Column(name = "m18LastModifyDate", nullable = false) | @Column(name = "m18LastModifyDate", nullable = false) | ||||
| @@ -5,5 +5,6 @@ import org.springframework.stereotype.Repository | |||||
| @Repository | @Repository | ||||
| interface M18DataLogRepository : AbstractRepository<M18DataLog, Long> { | interface M18DataLogRepository : AbstractRepository<M18DataLog, Long> { | ||||
| fun findFirstByM18IdAndRefTypeAndDeletedIsFalseOrderByM18LastModifyDateDesc(m18Id: Long, refType: String): M18DataLog? | |||||
| // find latest m18 data log by m18 id & ref type & status is true & deleted is false (order by id asc limit 1) | |||||
| fun findTopByM18IdAndRefTypeAndDeletedIsFalseAndStatusIsTrueOrderByIdDesc(m18Id: Long, refType: String): M18DataLog? | |||||
| } | } | ||||
| @@ -0,0 +1,7 @@ | |||||
| package com.ffii.fpsms.m18.enums | |||||
| enum class M18DataLogStatus(val value: Int) { | |||||
| FAIL(-1), | |||||
| NOT_PROCESS(0), | |||||
| SUCCESS(1), | |||||
| } | |||||
| @@ -0,0 +1,17 @@ | |||||
| package com.ffii.fpsms.m18.enums | |||||
| import jakarta.persistence.AttributeConverter | |||||
| import jakarta.persistence.Converter | |||||
| @Converter(autoApply = true) | |||||
| class M18DataLogStatusConverter: AttributeConverter<M18DataLogStatus, Int> { | |||||
| override fun convertToDatabaseColumn(status: M18DataLogStatus?): Int? { | |||||
| return status?.value | |||||
| } | |||||
| override fun convertToEntityAttribute(value: Int?): M18DataLogStatus? { | |||||
| return value?.let { v -> | |||||
| M18DataLogStatus.entries.find { it.value == v } | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -1,12 +1,14 @@ | |||||
| package com.ffii.fpsms.m18.model | package com.ffii.fpsms.m18.model | ||||
| import com.ffii.fpsms.m18.enums.M18DataLogStatus | |||||
| import java.time.LocalDateTime | import java.time.LocalDateTime | ||||
| data class SaveM18DataLogRequest ( | data class SaveM18DataLogRequest ( | ||||
| val id: Long?, | val id: Long?, | ||||
| val refType: String?, | |||||
| val m18Id: Long?, | |||||
| val m18LastModifyDate: LocalDateTime?, | |||||
| val dataLog: MutableMap<String, Any?>?, | |||||
| val status: Boolean? = true, | |||||
| val refType: String? = null, | |||||
| val m18Id: Long? = null, | |||||
| val m18LastModifyDate: LocalDateTime? = null, | |||||
| val dataLog: MutableMap<String, Any?>? = null, | |||||
| val status: Int? = 0, | |||||
| val statusEnum: M18DataLogStatus? = null, | |||||
| ) | ) | ||||
| @@ -4,5 +4,5 @@ data class M18DataLogResponse ( | |||||
| val id: Long?, | val id: Long?, | ||||
| val refType: String?, | val refType: String?, | ||||
| val m18Id: Long?, | val m18Id: Long?, | ||||
| val status: Boolean?, | |||||
| val status: String?, | |||||
| ) | ) | ||||
| @@ -0,0 +1,6 @@ | |||||
| package com.ffii.fpsms.m18.model | |||||
| data class M18ErrorMessages ( | |||||
| val msgDetail: String?, | |||||
| val msgCode: String?, | |||||
| ) | |||||
| @@ -7,6 +7,7 @@ enum class StSearchType(val value: String) { | |||||
| CUSTOMER("cus"), | CUSTOMER("cus"), | ||||
| UNIT("unit"), | UNIT("unit"), | ||||
| CURRENCY("cur"), | CURRENCY("cur"), | ||||
| BOM("udfbomforshop"), | |||||
| } | } | ||||
| /** M18 Common Master Data Request */ | /** M18 Common Master Data Request */ | ||||
| @@ -1,13 +1,6 @@ | |||||
| package com.ffii.fpsms.m18.model | package com.ffii.fpsms.m18.model | ||||
| import java.time.Instant | |||||
| import java.time.LocalDateTime | |||||
| /** Error Messages */ | |||||
| data class M18ErrorMessages ( | |||||
| val msgDetail: String?, | |||||
| val msgCode: String?, | |||||
| ) | |||||
| import java.math.BigDecimal | |||||
| /** Product / Material Response */ | /** Product / Material Response */ | ||||
| data class M18ProductResponse ( | data class M18ProductResponse ( | ||||
| @@ -43,6 +36,7 @@ data class M18ProductPrice ( | |||||
| /** Product / Material List Response */ | /** Product / Material List Response */ | ||||
| data class M18ProductListResponse ( | data class M18ProductListResponse ( | ||||
| val values: List<M18ProductListValue>?, | val values: List<M18ProductListValue>?, | ||||
| val messages: List<M18ErrorMessages>? | |||||
| ) | ) | ||||
| data class M18ProductListValue ( | data class M18ProductListValue ( | ||||
| @@ -79,6 +73,7 @@ data class M18VendorVen ( | |||||
| /** Vendor List Response */ | /** Vendor List Response */ | ||||
| data class M18VendorListResponse ( | data class M18VendorListResponse ( | ||||
| val values: List<M18VendorListValue>?, | val values: List<M18VendorListValue>?, | ||||
| val messages: List<M18ErrorMessages>? | |||||
| ) | ) | ||||
| data class M18VendorListValue ( | data class M18VendorListValue ( | ||||
| @@ -89,6 +84,7 @@ data class M18VendorListValue ( | |||||
| /** Unit List Response */ | /** Unit List Response */ | ||||
| data class M18UnitListResponse ( | data class M18UnitListResponse ( | ||||
| val values: List<M18UnitListValue>?, | val values: List<M18UnitListValue>?, | ||||
| val messages: List<M18ErrorMessages>? | |||||
| ) | ) | ||||
| data class M18UnitListValue ( | data class M18UnitListValue ( | ||||
| @@ -100,7 +96,8 @@ data class M18UnitListValue ( | |||||
| /** Unit Response */ | /** Unit Response */ | ||||
| data class M18UnitResponse ( | data class M18UnitResponse ( | ||||
| val data: List<M18UnitData> | |||||
| val data: M18UnitData?, | |||||
| val messages: List<M18ErrorMessages>? | |||||
| ) | ) | ||||
| data class M18UnitData ( | data class M18UnitData ( | ||||
| @@ -120,6 +117,7 @@ data class M18UnitUnit ( | |||||
| /** Currency List Response */ | /** Currency List Response */ | ||||
| data class M18CurrencyListResponse ( | data class M18CurrencyListResponse ( | ||||
| val values: List<M18CurrencyListValue>?, | val values: List<M18CurrencyListValue>?, | ||||
| val messages: List<M18ErrorMessages>? | |||||
| ) | ) | ||||
| data class M18CurrencyListValue ( | data class M18CurrencyListValue ( | ||||
| @@ -132,7 +130,8 @@ data class M18CurrencyListValue ( | |||||
| /** Currency Response */ | /** Currency Response */ | ||||
| data class M18CurrencyResponse ( | data class M18CurrencyResponse ( | ||||
| val data: List<M18CurrencyData> | |||||
| val data: M18CurrencyData?, | |||||
| val messages: List<M18ErrorMessages>? | |||||
| ) | ) | ||||
| data class M18CurrencyData ( | data class M18CurrencyData ( | ||||
| @@ -147,4 +146,49 @@ data class M18CurrencyCur ( | |||||
| val sym: String, | val sym: String, | ||||
| val desc: String, | val desc: String, | ||||
| val status: String, | val status: String, | ||||
| ) | |||||
| /** Bom List Response */ | |||||
| data class M18BomListResponse ( | |||||
| val values: List<M18BomListValue>?, | |||||
| val messages: List<M18ErrorMessages>? | |||||
| ) | |||||
| data class M18BomListValue ( | |||||
| val id: Long, | |||||
| val code: String, | |||||
| val desc: String, | |||||
| ) | |||||
| /** Bom Response */ | |||||
| data class M18BomResponse ( | |||||
| val data: M18BomData?, | |||||
| val messages: List<M18ErrorMessages>? | |||||
| ) | |||||
| data class M18BomData ( | |||||
| val udfbomforshop: List<M18BomUdfBomForShop>, | |||||
| val udfproduct: List<M18BomUdfProduct>, | |||||
| ) | |||||
| data class M18BomUdfBomForShop ( | |||||
| val id: Long, | |||||
| val expiredDate: Long, | |||||
| val lastModifyDate: Long, | |||||
| val code: String, | |||||
| val udfYieldratePP: BigDecimal, | |||||
| val udfHarvestUnit: String, | |||||
| val udfHarvest: String, | |||||
| val udfUnit: Long, | |||||
| val desc: String, | |||||
| val status: String, | |||||
| ) | |||||
| data class M18BomUdfProduct ( | |||||
| val id: Long, | |||||
| val udfqty: BigDecimal, | |||||
| val udfpurchaseUnit: Long, | |||||
| val udfProduct: Long, | |||||
| val udfIngredients: String, | |||||
| val udfBaseUnit: String, | |||||
| ) | ) | ||||
| @@ -7,12 +7,13 @@ import java.time.LocalDateTime | |||||
| /** Purchase Order Response */ | /** Purchase Order Response */ | ||||
| data class M18PurchaseOrderResponse ( | data class M18PurchaseOrderResponse ( | ||||
| val data: M18PurchaseOrderData | |||||
| val data: M18PurchaseOrderData?, | |||||
| val messages: List<M18ErrorMessages>? | |||||
| ) | ) | ||||
| data class M18PurchaseOrderData ( | data class M18PurchaseOrderData ( | ||||
| val mainpo: List<M18PurchaseOrderMainPo>, | |||||
| val pot: List<M18PurchaseOrderPot> | |||||
| val mainpo: List<M18PurchaseOrderMainPo>?, | |||||
| val pot: List<M18PurchaseOrderPot>?, | |||||
| ) | ) | ||||
| data class M18PurchaseOrderMainPo ( | data class M18PurchaseOrderMainPo ( | ||||
| @@ -24,7 +25,8 @@ data class M18PurchaseOrderMainPo ( | |||||
| val dDate: Long, | val dDate: Long, | ||||
| /** Order Date */ | /** Order Date */ | ||||
| val tDate: Long, | val tDate: Long, | ||||
| val lastModifyDate: Long | |||||
| val lastModifyDate: Long, | |||||
| val curId: Long, | |||||
| ) | ) | ||||
| data class M18PurchaseOrderPot ( | data class M18PurchaseOrderPot ( | ||||
| @@ -40,16 +42,16 @@ data class M18PurchaseOrderPot ( | |||||
| // val seriesId: Long?, | // val seriesId: Long?, | ||||
| val qty: BigDecimal, | val qty: BigDecimal, | ||||
| val amt: BigDecimal, | val amt: BigDecimal, | ||||
| val curId: Long, | |||||
| ) | ) | ||||
| /** Purchase Order List Response */ | /** Purchase Order List Response */ | ||||
| data class M18PurchaseOrderListResponseWithType ( | data class M18PurchaseOrderListResponseWithType ( | ||||
| var valuesWithType: MutableList<Pair<PurchaseOrderType, List<M18PurchaseOrderListValue>?>> | |||||
| var valuesWithType: MutableList<Pair<PurchaseOrderType, M18PurchaseOrderListResponse?>> | |||||
| ) | ) | ||||
| data class M18PurchaseOrderListResponse ( | data class M18PurchaseOrderListResponse ( | ||||
| var values: List<M18PurchaseOrderListValue> | |||||
| var values: List<M18PurchaseOrderListValue>?, | |||||
| val messages: List<M18ErrorMessages>? | |||||
| ) | ) | ||||
| data class M18PurchaseOrderListValue ( | data class M18PurchaseOrderListValue ( | ||||
| @@ -0,0 +1,14 @@ | |||||
| package com.ffii.fpsms.m18.model | |||||
| data class M18PurchaseQuotationRequest( | |||||
| val menuCode: String = "vqu", | |||||
| val id: Long?, | |||||
| val params: String? = null, | |||||
| val conds: String? = null, | |||||
| ) | |||||
| data class M18PurchaseQuotationListRequest( | |||||
| val stSearch: String = "vqu", | |||||
| val params: String? = null, | |||||
| val conds: String? = null, | |||||
| ) | |||||
| @@ -0,0 +1,52 @@ | |||||
| package com.ffii.fpsms.m18.model | |||||
| // Purchase Quotation | |||||
| data class M18PurchaseQuotationResponse( | |||||
| val data: M18PurchaseQuotationData?, | |||||
| val messages: List<M18ErrorMessages>? | |||||
| ) | |||||
| data class M18PurchaseQuotationData( | |||||
| val mainvqu: List<M18PurchaseQuotationMainvqu>, | |||||
| val remvqu: List<M18PurchaseQuotationRemvqu>, | |||||
| val vqut: List<M18PurchaseQuotationVqut>, | |||||
| ) | |||||
| data class M18PurchaseQuotationMainvqu( | |||||
| val id: Long, | |||||
| val expDate: Long, | |||||
| val lastModifyDate: Long, | |||||
| val tDate: Long, | |||||
| val venId: Long, | |||||
| val manId: Long, | |||||
| val code: String, | |||||
| ) | |||||
| data class M18PurchaseQuotationRemvqu( | |||||
| val id: Long, | |||||
| val remarks: String, | |||||
| val tradeTerm: String, | |||||
| ) | |||||
| data class M18PurchaseQuotationVqut( | |||||
| val bDesc: String, | |||||
| val id: Long, | |||||
| val refCode: String, | |||||
| val unitId: Long, | |||||
| val proId: Long, | |||||
| ) | |||||
| // Purchase Quotation List | |||||
| data class M18PurchaseQuotationListResponse( | |||||
| val values: List<M18PurchaseQuotationValues>?, | |||||
| val messages: List<M18ErrorMessages>? | |||||
| ) | |||||
| data class M18PurchaseQuotationValues( | |||||
| val id: Long, | |||||
| val code: String, | |||||
| val tDate: String, // Effective date | |||||
| val expDate: String, | |||||
| val status: String, | |||||
| val lastModifyDate: String, | |||||
| ) | |||||
| @@ -2,8 +2,10 @@ package com.ffii.fpsms.m18.service | |||||
| import com.ffii.fpsms.m18.entity.M18DataLog | import com.ffii.fpsms.m18.entity.M18DataLog | ||||
| import com.ffii.fpsms.m18.entity.M18DataLogRepository | import com.ffii.fpsms.m18.entity.M18DataLogRepository | ||||
| import com.ffii.fpsms.m18.enums.M18DataLogStatus | |||||
| import com.ffii.fpsms.m18.model.M18DataLogResponse | import com.ffii.fpsms.m18.model.M18DataLogResponse | ||||
| import com.ffii.fpsms.m18.model.SaveM18DataLogRequest | import com.ffii.fpsms.m18.model.SaveM18DataLogRequest | ||||
| import com.ffii.fpsms.modules.purchaseOrder.enums.PurchaseOrderStatus | |||||
| import org.springframework.stereotype.Service | import org.springframework.stereotype.Service | ||||
| import kotlin.jvm.optionals.getOrDefault | import kotlin.jvm.optionals.getOrDefault | ||||
| @@ -12,20 +14,21 @@ class M18DataLogService( | |||||
| val m18DataLogRepository: M18DataLogRepository | val m18DataLogRepository: M18DataLogRepository | ||||
| ) { | ) { | ||||
| fun findLatestM18DataLog(m18Id: Long, refType: String): M18DataLog? { | fun findLatestM18DataLog(m18Id: Long, refType: String): M18DataLog? { | ||||
| return m18DataLogRepository.findFirstByM18IdAndRefTypeAndDeletedIsFalseOrderByM18LastModifyDateDesc(m18Id, refType) | |||||
| return m18DataLogRepository.findTopByM18IdAndRefTypeAndDeletedIsFalseAndStatusIsTrueOrderByIdDesc(m18Id, refType) | |||||
| } | } | ||||
| fun saveM18DataLog(request: SaveM18DataLogRequest): M18DataLogResponse { | fun saveM18DataLog(request: SaveM18DataLogRequest): M18DataLogResponse { | ||||
| val id = request.id | val id = request.id | ||||
| val m18DataLog = | val m18DataLog = | ||||
| if (id != null && id > 0) m18DataLogRepository.findById(id).getOrDefault(M18DataLog()) else M18DataLog() | if (id != null && id > 0) m18DataLogRepository.findById(id).getOrDefault(M18DataLog()) else M18DataLog() | ||||
| val status = request.statusEnum ?: request.status?.let { status -> M18DataLogStatus.entries.find { it.value == status } } | |||||
| m18DataLog.apply { | m18DataLog.apply { | ||||
| refType = request.refType | |||||
| m18Id = request.m18Id | |||||
| m18LastModifyDate = request.m18LastModifyDate | |||||
| dataLog = request.dataLog | |||||
| status = request.status | |||||
| refType = request.refType ?: this.refType | |||||
| m18Id = request.m18Id ?: this.m18Id | |||||
| m18LastModifyDate = request.m18LastModifyDate ?: this.m18LastModifyDate | |||||
| dataLog = request.dataLog ?: request.dataLog | |||||
| this.status = status | |||||
| } | } | ||||
| val response = m18DataLogRepository.saveAndFlush(m18DataLog).let { dataLog -> | val response = m18DataLogRepository.saveAndFlush(m18DataLog).let { dataLog -> | ||||
| @@ -33,7 +36,7 @@ class M18DataLogService( | |||||
| id = dataLog.id, | id = dataLog.id, | ||||
| refType = dataLog.refType, | refType = dataLog.refType, | ||||
| m18Id = dataLog.m18Id, | m18Id = dataLog.m18Id, | ||||
| status = dataLog.status, | |||||
| status = dataLog.status?.toString(), | |||||
| ) | ) | ||||
| } | } | ||||
| @@ -12,6 +12,7 @@ import com.ffii.fpsms.modules.master.web.models.* | |||||
| import org.slf4j.Logger | import org.slf4j.Logger | ||||
| import org.slf4j.LoggerFactory | import org.slf4j.LoggerFactory | ||||
| import org.springframework.stereotype.Service | import org.springframework.stereotype.Service | ||||
| import java.math.BigDecimal | |||||
| import java.time.LocalDate | import java.time.LocalDate | ||||
| import java.time.LocalDateTime | import java.time.LocalDateTime | ||||
| import java.time.format.DateTimeFormatter | import java.time.format.DateTimeFormatter | ||||
| @@ -25,10 +26,12 @@ open class M18MasterDataService( | |||||
| val uomConversionService: UomConversionService, | val uomConversionService: UomConversionService, | ||||
| val currencyService: CurrencyService, | val currencyService: CurrencyService, | ||||
| val itemUomService: ItemUomService, | val itemUomService: ItemUomService, | ||||
| val bomService: BomService, | |||||
| val bomMaterialService: BomMaterialService, | |||||
| ) { | ) { | ||||
| val commonUtils = CommonUtils() | |||||
| val logger: Logger = LoggerFactory.getLogger(JwtTokenUtil::class.java) | val logger: Logger = LoggerFactory.getLogger(JwtTokenUtil::class.java) | ||||
| val commonUtils = CommonUtils() | |||||
| val formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss") | val formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss") | ||||
| // M18 Conditions | // M18 Conditions | ||||
| @@ -37,9 +40,10 @@ open class M18MasterDataService( | |||||
| val seriesIdList = | val seriesIdList = | ||||
| listOf(m18Config.SERIESID_SC, m18Config.SERIESID_SE, m18Config.SERIESID_SF, m18Config.SERIESID_SR) | listOf(m18Config.SERIESID_SC, m18Config.SERIESID_SE, m18Config.SERIESID_SF, m18Config.SERIESID_SR) | ||||
| val seriesIdConds = | val seriesIdConds = | ||||
| "(" + commonUtils.ListToString(seriesIdList.filterNotNull(), "seriesId=unequal=", "=or=") + ")" | |||||
| "(" + commonUtils.listToString(seriesIdList.filterNotNull(), "seriesId=unequal=", "=or=") + ")" | |||||
| val beIdList = listOf(m18Config.BEID_PF, m18Config.BEID_PP, m18Config.BEID_TOA) | val beIdList = listOf(m18Config.BEID_PF, m18Config.BEID_PP, m18Config.BEID_TOA) | ||||
| val beIdConds = "(" + commonUtils.ListToString(beIdList.filterNotNull(), "beId=equal=", "=or=") + ")" | |||||
| val beIdConds = "(" + commonUtils.listToString(beIdList.filterNotNull(), "beId=equal=", "=or=") + ")" | |||||
| // val beIdConds = commonUtils.BEID_CONDS | |||||
| // M18 API | // M18 API | ||||
| val M18_COMMON_FETCH_LIST_API = "/search/search" | val M18_COMMON_FETCH_LIST_API = "/search/search" | ||||
| @@ -49,6 +53,7 @@ open class M18MasterDataService( | |||||
| val M18_LOAD_VENDOR_API = "${M18_COMMON_LOAD_LINE_API}/${StSearchType.VENDOR.value}" | val M18_LOAD_VENDOR_API = "${M18_COMMON_LOAD_LINE_API}/${StSearchType.VENDOR.value}" | ||||
| val M18_LOAD_UNIT_API = "${M18_COMMON_LOAD_LINE_API}/${StSearchType.UNIT.value}" | val M18_LOAD_UNIT_API = "${M18_COMMON_LOAD_LINE_API}/${StSearchType.UNIT.value}" | ||||
| val M18_LOAD_CURRENCY_API = "${M18_COMMON_LOAD_LINE_API}/${StSearchType.CURRENCY.value}" | val M18_LOAD_CURRENCY_API = "${M18_COMMON_LOAD_LINE_API}/${StSearchType.CURRENCY.value}" | ||||
| val M18_LOAD_BOM_API = "${M18_COMMON_LOAD_LINE_API}/${StSearchType.BOM.value}" | |||||
| // --------------------------------------------- Common Function --------------------------------------------- /// | // --------------------------------------------- Common Function --------------------------------------------- /// | ||||
| private inline fun <reified T : Any> getList( | private inline fun <reified T : Any> getList( | ||||
| @@ -151,7 +156,7 @@ open class M18MasterDataService( | |||||
| countryOfOrigin = null, | countryOfOrigin = null, | ||||
| maxQty = null, | maxQty = null, | ||||
| m18Id = item.id, | m18Id = item.id, | ||||
| m18LastModifyDate = commonUtils.InstantToLocalDateTime(pro.lastModifyDate) | |||||
| m18LastModifyDate = commonUtils.timestampToLocalDateTime(pro.lastModifyDate) | |||||
| ) | ) | ||||
| val savedItem = itemsService.saveItem(saveItemRequest) | val savedItem = itemsService.saveItem(saveItemRequest) | ||||
| @@ -162,9 +167,10 @@ open class M18MasterDataService( | |||||
| // Delete the item uom | // Delete the item uom | ||||
| logger.info("Deleting item uom...") | logger.info("Deleting item uom...") | ||||
| existingItemUoms?.filter { deleteItemUom -> | |||||
| m18ItemUomIds.any { it != deleteItemUom.m18Id } | |||||
| }?.mapNotNull { it.id }?.let { itemUomService.deleteItemUoms(it) } | |||||
| // 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 the item uom | ||||
| logger.info("Updating item uom...") | logger.info("Updating item uom...") | ||||
| @@ -180,10 +186,10 @@ open class M18MasterDataService( | |||||
| price = null, | price = null, | ||||
| currencyId = null, | currencyId = null, | ||||
| m18Id = it.id, | m18Id = it.id, | ||||
| m18LastModifyDate = commonUtils.InstantToLocalDateTime(pro.lastModifyDate) | |||||
| m18LastModifyDate = commonUtils.timestampToLocalDateTime(pro.lastModifyDate) | |||||
| ) | ) | ||||
| logger.info("saved item id: ${savedItem.id}") | |||||
| // logger.info("saved item id: ${savedItem.id}") | |||||
| itemUomService.saveItemUom(itemUomRequest) | itemUomService.saveItemUom(itemUomRequest) | ||||
| } | } | ||||
| @@ -265,7 +271,7 @@ open class M18MasterDataService( | |||||
| district = null, | district = null, | ||||
| type = ShopType.SUPPLIER.value, | type = ShopType.SUPPLIER.value, | ||||
| m18Id = vendor.id, | m18Id = vendor.id, | ||||
| m18LastModifyDate = commonUtils.InstantToLocalDateTime(ven.lastModifyDate) | |||||
| m18LastModifyDate = commonUtils.timestampToLocalDateTime(ven.lastModifyDate) | |||||
| ) | ) | ||||
| shopService.saveShop(saveShopRequest) | shopService.saveShop(saveShopRequest) | ||||
| @@ -409,7 +415,7 @@ open class M18MasterDataService( | |||||
| // save currency | // save currency | ||||
| values.forEach { currency -> | values.forEach { currency -> | ||||
| try { | try { | ||||
| val currencyRequest = CurrencyRequest( | |||||
| val currencyRequest = SaveCurrencyRequest( | |||||
| id = null, | id = null, | ||||
| code = currency.code, | code = currency.code, | ||||
| name = currency.sym, | name = currency.sym, | ||||
| @@ -440,4 +446,118 @@ open class M18MasterDataService( | |||||
| logger.info("--------------------------------------------End - Saving Currencies--------------------------------------------") | logger.info("--------------------------------------------End - Saving Currencies--------------------------------------------") | ||||
| } | } | ||||
| // --------------------------------------------- Bom --------------------------------------------- /// | |||||
| open fun getBoms(): M18BomListResponse? { | |||||
| return getList<M18BomListResponse>( | |||||
| stSearch = StSearchType.BOM.value, | |||||
| params = null, | |||||
| conds = beIdConds | |||||
| ) | |||||
| } | |||||
| open fun getBom(id: Long): M18BomResponse? { | |||||
| logger.info("M18 Bom ID: $id") | |||||
| return getLine<M18BomResponse>( | |||||
| id = id, | |||||
| params = null, | |||||
| api = M18_LOAD_BOM_API | |||||
| ) | |||||
| } | |||||
| open fun saveBoms() { | |||||
| logger.info("--------------------------------------------Start - Saving M18 Boms--------------------------------------------") | |||||
| val boms = getBoms() | |||||
| val successList = mutableListOf<Long>() | |||||
| val successDetailList = mutableListOf<Long>() | |||||
| val failList = mutableListOf<Long>() | |||||
| val failDetailList = mutableListOf<Pair<Long, MutableList<Long>>>() | |||||
| var failDetailCount = 0 | |||||
| val values = boms?.values?.sortedBy { it.id } | |||||
| if (values != null) { | |||||
| values.forEach { bom -> | |||||
| try { | |||||
| val bomDetail = getBom(bom.id) | |||||
| val bomUdfBomForShop = bomDetail?.data?.udfbomforshop?.get(0) | |||||
| val bomUdfProduct = bomDetail?.data?.udfproduct | |||||
| logger.info(bomUdfBomForShop.toString()) | |||||
| logger.info(bomUdfProduct.toString()) | |||||
| if (bomUdfBomForShop != null && bomUdfProduct != null) { | |||||
| // Save Bom | |||||
| logger.info("AAAAA") | |||||
| val saveBomRequest = SaveBomRequest( | |||||
| // itemId = itemsService.findByNameAndM18UomId(bomUdfBomForShop.desc, bomUdfBomForShop.udfUnit)?.id, | |||||
| code = bomUdfBomForShop.code, | |||||
| name = bomUdfBomForShop.desc, | |||||
| description = bomUdfBomForShop.desc, | |||||
| outputQty = if (bomUdfBomForShop.udfHarvest.trim().toBigDecimalOrNull() != null) bomUdfBomForShop.udfHarvest.trim().toBigDecimal() else BigDecimal(0), | |||||
| outputQtyUom = bomUdfBomForShop.udfHarvestUnit, | |||||
| yield = bomUdfBomForShop.udfYieldratePP, | |||||
| m18UomId = bomUdfBomForShop.udfUnit, | |||||
| m18Id = bomUdfBomForShop.id, | |||||
| m18LastModifyDate = commonUtils.timestampToLocalDateTime(bomUdfBomForShop.lastModifyDate) | |||||
| ) | |||||
| logger.info("BBBBB") | |||||
| val bomId = bomService.saveBom(saveBomRequest).id | |||||
| successList += bom.id | |||||
| // Save Bom Material | |||||
| logger.info("Start saving bom material...") | |||||
| val tempFailList = mutableListOf<Long>() | |||||
| bomUdfProduct.forEach { bomMaterial -> | |||||
| try { | |||||
| val saveBomMaterialRequest = SaveBomMaterialRequest( | |||||
| m18ItemId = bomMaterial.udfProduct, | |||||
| itemName = bomMaterial.udfIngredients, | |||||
| qty = bomMaterial.udfqty, | |||||
| m18UomId = bomMaterial.udfpurchaseUnit, | |||||
| uomName = bomMaterial.udfBaseUnit, | |||||
| bomId = bomId, | |||||
| m18Id = bomMaterial.id, | |||||
| m18LastModifyDate = commonUtils.timestampToLocalDateTime(bomUdfBomForShop.lastModifyDate) | |||||
| ) | |||||
| bomMaterialService.saveBomMaterial(saveBomMaterialRequest) | |||||
| successDetailList += bomMaterial.id | |||||
| } catch (e: Exception) { | |||||
| tempFailList += bomMaterial.id | |||||
| logger.error("(Bom Material) Exception") | |||||
| logger.error("(Bom Material) Fail Message: ${e.message}") | |||||
| logger.error("(Bom Material) Fail Count ${++failDetailCount}: Bom Material ID - ${bomMaterial.id} | Bom ID - ${bom.id}") | |||||
| } | |||||
| } | |||||
| failDetailList += Pair(bom.id, tempFailList) | |||||
| logger.info("Save Success (M18): ${bom.id}") | |||||
| } else { | |||||
| failList.add(bom.id) | |||||
| logger.error("(Bom) Fail Message: ${bomDetail?.messages?.get(0)?.msgDetail}") | |||||
| logger.error("(Bom) Fail Count ${failList.size}: Bom ID - ${bom.id} Not Found") | |||||
| } | |||||
| } catch (e: Exception) { | |||||
| failList += bom.id | |||||
| logger.error("(Bom) Exception") | |||||
| logger.error("(Bom) Fail Message: ${e.message}") | |||||
| logger.error("(Bom) Fail Count ${failList.size}: Bom ID - ${bom.id}") | |||||
| } | |||||
| } | |||||
| } else { | |||||
| logger.error("Currency List is null. May occur errors.") | |||||
| } | |||||
| logger.info("Total Bom Save Success (${successList.size})") | |||||
| logger.info("Total Bom Save Detail Success (${successDetailList.size})") | |||||
| if (failList.size > 0) { | |||||
| logger.error("Total Bom Fail (${failList.size}): $failList") | |||||
| } | |||||
| if (failDetailCount > 0) { | |||||
| logger.error("Total Bom Detail Fail (${failDetailCount}): $failDetailList") | |||||
| } | |||||
| logger.info("--------------------------------------------End - Saving Boms--------------------------------------------") | |||||
| } | |||||
| } | } | ||||
| @@ -3,8 +3,10 @@ package com.ffii.fpsms.m18.service | |||||
| import com.ffii.core.utils.JwtTokenUtil | import com.ffii.core.utils.JwtTokenUtil | ||||
| import com.ffii.fpsms.api.service.ApiCallerService | import com.ffii.fpsms.api.service.ApiCallerService | ||||
| import com.ffii.fpsms.m18.M18Config | import com.ffii.fpsms.m18.M18Config | ||||
| import com.ffii.fpsms.m18.enums.M18DataLogStatus | |||||
| import com.ffii.fpsms.m18.model.* | import com.ffii.fpsms.m18.model.* | ||||
| import com.ffii.fpsms.m18.utils.CommonUtils | import com.ffii.fpsms.m18.utils.CommonUtils | ||||
| import com.ffii.fpsms.modules.master.service.ItemUomService | |||||
| import com.ffii.fpsms.modules.master.service.ItemsService | import com.ffii.fpsms.modules.master.service.ItemsService | ||||
| import com.ffii.fpsms.modules.master.service.ShopService | import com.ffii.fpsms.modules.master.service.ShopService | ||||
| import com.ffii.fpsms.modules.purchaseOrder.enums.PurchaseOrderLineStatus | import com.ffii.fpsms.modules.purchaseOrder.enums.PurchaseOrderLineStatus | ||||
| @@ -29,11 +31,16 @@ open class M18PurchaseOrderService( | |||||
| val purchaseOrderLineService: PurchaseOrderLineService, | val purchaseOrderLineService: PurchaseOrderLineService, | ||||
| val itemsService: ItemsService, | val itemsService: ItemsService, | ||||
| val shopService: ShopService, | val shopService: ShopService, | ||||
| val itemUomService: ItemUomService, | |||||
| ) { | ) { | ||||
| val commonUtils = CommonUtils() | val commonUtils = CommonUtils() | ||||
| val logger: Logger = LoggerFactory.getLogger(JwtTokenUtil::class.java) | val logger: Logger = LoggerFactory.getLogger(JwtTokenUtil::class.java) | ||||
| val lastModifyDate = LocalDateTime.now().minusMinutes(30) | |||||
| val lastModifyDateStart = "2025-05-14 14:00:00" | |||||
| val lastModifyDateEnd = "2025-05-14 14:30:00" | |||||
| val lastModifyDateConds = | |||||
| "lastModifyDate=largerOrEqual=${lastModifyDateStart}=and=lastModifyDate=lessOrEqual=${lastModifyDateEnd}" | |||||
| // val lastModifyDate = LocalDateTime.now().minusMinutes(30) | |||||
| // val commonConds = | // val commonConds = | ||||
| // "(beId=equal=${m18Config.BEID_PF}=or=beId=equal=${m18Config.BEID_PP}=or=beId=equal=${m18Config.BEID_TOA})=and=lastModifyDate=largerOrEqual=${lastModifyDate}" | // "(beId=equal=${m18Config.BEID_PF}=or=beId=equal=${m18Config.BEID_PP}=or=beId=equal=${m18Config.BEID_TOA})=and=lastModifyDate=largerOrEqual=${lastModifyDate}" | ||||
| @@ -47,9 +54,14 @@ open class M18PurchaseOrderService( | |||||
| // Material PO | // Material PO | ||||
| val materialPoBuyers = | val materialPoBuyers = | ||||
| commonUtils.ListToString(listOf(m18Config.BEID_PP, m18Config.BEID_PF), "beId=equal=", "=or=") | |||||
| val materialPoSupplierNot = "venId=unequal=${m18Config.MATERIAL_PO_SUPPLIER_NOT}" | |||||
| val materialPoConds = "${materialPoBuyers}=and=${materialPoSupplierNot}" | |||||
| commonUtils.listToString(listOf(m18Config.BEID_PP, m18Config.BEID_PF), "beId=equal=", "=or=") | |||||
| val materialPoSupplierNot = commonUtils.listToString( | |||||
| shopService.findM18VendorIdsByCodeNotRegexp(m18Config.MATERIAL_PO_SUPPLIER_NOT), | |||||
| "venId=unequal=", | |||||
| "=or=" | |||||
| ) | |||||
| val materialPoConds = "(${materialPoBuyers})=and=(${materialPoSupplierNot})=and=(${lastModifyDateConds})" | |||||
| println("materialPoConds: ${materialPoConds}") | |||||
| val materialPoParams = M18PurchaseOrderListRequest( | val materialPoParams = M18PurchaseOrderListRequest( | ||||
| params = null, | params = null, | ||||
| conds = materialPoConds | conds = materialPoConds | ||||
| @@ -61,17 +73,22 @@ open class M18PurchaseOrderService( | |||||
| apiCallerService.get<M18PurchaseOrderListResponse, M18PurchaseOrderListRequest>( | apiCallerService.get<M18PurchaseOrderListResponse, M18PurchaseOrderListRequest>( | ||||
| M18_FETCH_PURCHASE_ORDER_LIST_API, | M18_FETCH_PURCHASE_ORDER_LIST_API, | ||||
| materialPoParams | materialPoParams | ||||
| ).block()?.values ?: mutableListOf() | |||||
| ).block() | |||||
| ) | ) | ||||
| } catch (e: Exception) { | } catch (e: Exception) { | ||||
| logger.error("Error on Function - ${e.stackTrace}") | |||||
| logger.error("(Getting Material Po list) Error on Function - ${e.stackTrace}") | |||||
| logger.error(e.message) | logger.error(e.message) | ||||
| } | } | ||||
| // Shop PO | // Shop PO | ||||
| val shopPoBuyers = commonUtils.ListToString(listOf(m18Config.BEID_TOA), "beId=equal=", "=or=") | |||||
| val shopPoSupplier = "venId=equal=${m18Config.SHOP_PO_SUPPLIER}" | |||||
| val shopPoConds = "${shopPoBuyers}=and=${shopPoSupplier}" | |||||
| val shopPoBuyers = commonUtils.listToString(listOf(m18Config.BEID_TOA), "beId=equal=", "=or=") | |||||
| val shopPoSupplier = commonUtils.listToString( | |||||
| shopService.findM18VendorIdsByCodeRegexp(m18Config.SHOP_PO_SUPPLIER), | |||||
| "venId=equal=", | |||||
| "=or=" | |||||
| ) | |||||
| val shopPoConds = "(${shopPoBuyers})=and=(${shopPoSupplier})=and=(${lastModifyDateConds})" | |||||
| println("shopPoConds: ${shopPoConds}") | |||||
| val shopPoParams = M18PurchaseOrderListRequest( | val shopPoParams = M18PurchaseOrderListRequest( | ||||
| params = null, | params = null, | ||||
| conds = shopPoConds | conds = shopPoConds | ||||
| @@ -82,17 +99,22 @@ open class M18PurchaseOrderService( | |||||
| PurchaseOrderType.SHOP, apiCallerService.get<M18PurchaseOrderListResponse, M18PurchaseOrderListRequest>( | PurchaseOrderType.SHOP, apiCallerService.get<M18PurchaseOrderListResponse, M18PurchaseOrderListRequest>( | ||||
| M18_FETCH_PURCHASE_ORDER_LIST_API, | M18_FETCH_PURCHASE_ORDER_LIST_API, | ||||
| shopPoParams | shopPoParams | ||||
| ).block()?.values ?: mutableListOf() | |||||
| ).block() | |||||
| ) | ) | ||||
| } catch (e: Exception) { | } catch (e: Exception) { | ||||
| logger.error("Error on Function - ${e.stackTrace}") | |||||
| logger.error("(Getting Shop Po list) Error on Function - ${e.stackTrace}") | |||||
| logger.error(e.message) | logger.error(e.message) | ||||
| } | } | ||||
| // OEM PO | // OEM PO | ||||
| val oemPoBuyers = commonUtils.ListToString(listOf(m18Config.BEID_PF, m18Config.BEID_PP), "beId=equal=", "=or=") | |||||
| val oemPoSupplier = "venId=equal=${m18Config.OEM_PO_SUPPLIER}" | |||||
| val oemPoConds = "${oemPoBuyers}=and=${oemPoSupplier}" | |||||
| /* val oemPoBuyers = commonUtils.listToString(listOf(m18Config.BEID_PF, m18Config.BEID_PP), "beId=equal=", "=or=") | |||||
| val oemPoSupplier = commonUtils.listToString( | |||||
| shopService.findM18VendorIdsByCodeRegexp(m18Config.OEM_PO_SUPPLIER), | |||||
| "venId=equal=", | |||||
| "=or=" | |||||
| ) | |||||
| val oemPoConds = "(${oemPoBuyers})=and=(${oemPoSupplier})=and=(${lastModifyDateConds})" | |||||
| println("oemPoConds: ${oemPoConds}") | |||||
| val oemPoParams = M18PurchaseOrderListRequest( | val oemPoParams = M18PurchaseOrderListRequest( | ||||
| params = null, | params = null, | ||||
| conds = oemPoConds | conds = oemPoConds | ||||
| @@ -103,12 +125,12 @@ open class M18PurchaseOrderService( | |||||
| PurchaseOrderType.OEM, apiCallerService.get<M18PurchaseOrderListResponse, M18PurchaseOrderListRequest>( | PurchaseOrderType.OEM, apiCallerService.get<M18PurchaseOrderListResponse, M18PurchaseOrderListRequest>( | ||||
| M18_FETCH_PURCHASE_ORDER_LIST_API, | M18_FETCH_PURCHASE_ORDER_LIST_API, | ||||
| oemPoParams | oemPoParams | ||||
| ).block()?.values | |||||
| ).block() | |||||
| ) | ) | ||||
| } catch (e: Exception) { | } catch (e: Exception) { | ||||
| logger.error("Error on Function - ${e.stackTrace}") | |||||
| logger.error("(Getting OEM Po list) Error on Function - ${e.stackTrace}") | |||||
| logger.error(e.message) | logger.error(e.message) | ||||
| } | |||||
| } */ | |||||
| return purchaseOrders | return purchaseOrders | ||||
| } | } | ||||
| @@ -126,7 +148,7 @@ open class M18PurchaseOrderService( | |||||
| purchaseOrderParams | purchaseOrderParams | ||||
| ).block() | ).block() | ||||
| } catch (e: Exception) { | } catch (e: Exception) { | ||||
| logger.error("Error on Function - ${e.stackTrace}") | |||||
| logger.error("(Getting Po Detail) Error on Function - ${e.stackTrace}") | |||||
| logger.error(e.message) | logger.error(e.message) | ||||
| } | } | ||||
| @@ -150,10 +172,13 @@ open class M18PurchaseOrderService( | |||||
| // Loop for Purchase Orders (values) | // Loop for Purchase Orders (values) | ||||
| purchaseOrdersWithType.valuesWithType.forEach { purchaseOrderWithType -> | purchaseOrdersWithType.valuesWithType.forEach { purchaseOrderWithType -> | ||||
| val type = purchaseOrderWithType.first | val type = purchaseOrderWithType.first | ||||
| val purchaseOrders = purchaseOrderWithType.second | |||||
| // if success | |||||
| val purchaseOrdersValues = purchaseOrderWithType.second?.values | |||||
| // if fail | |||||
| val purchaseOrdersMessages = purchaseOrderWithType.second?.messages | |||||
| if (purchaseOrders != null) { | |||||
| purchaseOrders.forEach { purchaseOrder -> | |||||
| if (purchaseOrdersValues != null) { | |||||
| purchaseOrdersValues.forEach { purchaseOrder -> | |||||
| val purchaseOrderDetail = getPurchaseOrder(purchaseOrder.id) | val purchaseOrderDetail = getPurchaseOrder(purchaseOrder.id) | ||||
| var purchaseOrderId: Long? = null //FP-MTMS | var purchaseOrderId: Long? = null //FP-MTMS | ||||
| @@ -162,6 +187,7 @@ open class M18PurchaseOrderService( | |||||
| // Assume only one PO in the PO (search by PO ID) | // Assume only one PO in the PO (search by PO ID) | ||||
| val mainpo = purchaseOrderDetail?.data?.mainpo?.get(0) | val mainpo = purchaseOrderDetail?.data?.mainpo?.get(0) | ||||
| val pot = purchaseOrderDetail?.data?.pot | val pot = purchaseOrderDetail?.data?.pot | ||||
| val purchaseOrderLineMessage = purchaseOrderDetail?.messages | |||||
| // purchase_order + m18_data_log table | // purchase_order + m18_data_log table | ||||
| if (mainpo != null) { | if (mainpo != null) { | ||||
| @@ -169,7 +195,6 @@ open class M18PurchaseOrderService( | |||||
| logger.info("${poRefType}: Finding For Latest M18 Data Log...") | logger.info("${poRefType}: Finding For Latest M18 Data Log...") | ||||
| val latestPurchaseOrderLog = | val latestPurchaseOrderLog = | ||||
| m18DataLogService.findLatestM18DataLog(purchaseOrder.id, poRefType) | m18DataLogService.findLatestM18DataLog(purchaseOrder.id, poRefType) | ||||
| // logger.info("${poRefType}: Latest M18 Data Log ID: ${latestPurchaseOrderLog?.id}") | |||||
| // Save to m18_data_log table | // Save to m18_data_log table | ||||
| logger.info("${poRefType}: Saving for M18 Data Log...") | logger.info("${poRefType}: Saving for M18 Data Log...") | ||||
| @@ -181,9 +206,9 @@ open class M18PurchaseOrderService( | |||||
| id = null, | id = null, | ||||
| refType = poRefType, | refType = poRefType, | ||||
| m18Id = purchaseOrder.id, | m18Id = purchaseOrder.id, | ||||
| m18LastModifyDate = commonUtils.InstantToLocalDateTime(mainpo.lastModifyDate), | |||||
| dataLog = mainpoJson, | |||||
| status = true | |||||
| m18LastModifyDate = commonUtils.timestampToLocalDateTime(mainpo.lastModifyDate), | |||||
| // dataLog = mainpoJson, | |||||
| statusEnum = M18DataLogStatus.NOT_PROCESS | |||||
| ) | ) | ||||
| val saveM18PurchaseOrderLog = | val saveM18PurchaseOrderLog = | ||||
| @@ -194,18 +219,18 @@ open class M18PurchaseOrderService( | |||||
| // Find the purchase_order if exist | // Find the purchase_order if exist | ||||
| logger.info("${poRefType}: Finding exising purchase order...") | logger.info("${poRefType}: Finding exising purchase order...") | ||||
| val existingPurchaseOrder = | val existingPurchaseOrder = | ||||
| latestPurchaseOrderLog?.id?.let { purchaseOrderService.findPurchaseOrderByM18Id(it) } | |||||
| latestPurchaseOrderLog?.id?.let { purchaseOrderService.findByM18DataLogId(it) } | |||||
| logger.info("${poRefType}: Exising purchase order ID: ${existingPurchaseOrder?.id}") | logger.info("${poRefType}: Exising purchase order ID: ${existingPurchaseOrder?.id}") | ||||
| // Save to purchase_order table | // Save to purchase_order table | ||||
| logger.info("${poRefType}: Saving purchase order...") | logger.info("${poRefType}: Saving purchase order...") | ||||
| val supplierId = shopService.findByM18Id(mainpo.venId)?.id | |||||
| val savePurchaseOrderRequest = SavePurchaseOrderRequest( | val savePurchaseOrderRequest = SavePurchaseOrderRequest( | ||||
| id = existingPurchaseOrder?.id, | id = existingPurchaseOrder?.id, | ||||
| code = mainpo.code, | code = mainpo.code, | ||||
| supplierId = supplierId, | |||||
| orderDate = commonUtils.InstantToLocalDateTime(mainpo.tDate), | |||||
| estimatedArrivalDate = commonUtils.InstantToLocalDateTime(mainpo.dDate), | |||||
| m18SupplierId = mainpo.venId, | |||||
| m18CurrencyId = mainpo.curId, | |||||
| orderDate = commonUtils.timestampToLocalDateTime(mainpo.tDate), | |||||
| estimatedArrivalDate = commonUtils.timestampToLocalDateTime(mainpo.dDate), | |||||
| completeDate = null, | completeDate = null, | ||||
| status = PurchaseOrderStatus.PENDING.value, | status = PurchaseOrderStatus.PENDING.value, | ||||
| type = type.value, | type = type.value, | ||||
| @@ -216,6 +241,16 @@ open class M18PurchaseOrderService( | |||||
| purchaseOrderService.savePurchaseOrder(savePurchaseOrderRequest) | purchaseOrderService.savePurchaseOrder(savePurchaseOrderRequest) | ||||
| purchaseOrderId = savePurchaseOrderResponse.id | purchaseOrderId = savePurchaseOrderResponse.id | ||||
| // Update m18_data_log with success | |||||
| val successSaveM18PurchaseOrderLogRequest = SaveM18DataLogRequest( | |||||
| id = saveM18PurchaseOrderLogRequest.id, | |||||
| dataLog = mainpoJson, | |||||
| statusEnum = M18DataLogStatus.SUCCESS | |||||
| ) | |||||
| m18DataLogService.saveM18DataLog(successSaveM18PurchaseOrderLogRequest) | |||||
| // log success info | |||||
| successList.add(purchaseOrder.id) | successList.add(purchaseOrder.id) | ||||
| logger.info("${poRefType}: Saved purchase order. ID: ${savePurchaseOrderResponse.id} | M18 ${poRefType} ID: ${purchaseOrder.id}") | logger.info("${poRefType}: Saved purchase order. ID: ${savePurchaseOrderResponse.id} | M18 ${poRefType} ID: ${purchaseOrder.id}") | ||||
| @@ -227,11 +262,8 @@ open class M18PurchaseOrderService( | |||||
| val errorSaveM18PurchaseOrderLogRequest = SaveM18DataLogRequest( | val errorSaveM18PurchaseOrderLogRequest = SaveM18DataLogRequest( | ||||
| id = saveM18PurchaseOrderLogRequest.id, | id = saveM18PurchaseOrderLogRequest.id, | ||||
| refType = poRefType, | |||||
| m18Id = purchaseOrder.id, | |||||
| m18LastModifyDate = commonUtils.InstantToLocalDateTime(mainpo.lastModifyDate), | |||||
| dataLog = mainpoJson, | |||||
| status = false | |||||
| dataLog = mutableMapOf(Pair("Exception Message", e.message)), | |||||
| statusEnum = M18DataLogStatus.FAIL | |||||
| ) | ) | ||||
| m18DataLogService.saveM18DataLog(errorSaveM18PurchaseOrderLogRequest) | m18DataLogService.saveM18DataLog(errorSaveM18PurchaseOrderLogRequest) | ||||
| @@ -239,15 +271,16 @@ open class M18PurchaseOrderService( | |||||
| } | } | ||||
| // purchase_order_line + m18_data_log | // purchase_order_line + m18_data_log | ||||
| // TODO: check deleted po line? | |||||
| if (pot != null) { | if (pot != null) { | ||||
| // Loop for Purchase Order Lines (pot) | // Loop for Purchase Order Lines (pot) | ||||
| pot.forEach { line -> | pot.forEach { line -> | ||||
| // // Find the latest m18 data log by m18 id & type | |||||
| // Find the latest m18 data log by m18 id & type | |||||
| logger.info("${poLineRefType}: Finding For Latest M18 Data Log...") | logger.info("${poLineRefType}: Finding For Latest M18 Data Log...") | ||||
| val latestPurchaseOrderLineLog = | val latestPurchaseOrderLineLog = | ||||
| m18DataLogService.findLatestM18DataLog(line.id, poLineRefType) | m18DataLogService.findLatestM18DataLog(line.id, poLineRefType) | ||||
| // logger.info("${poLineRefType}: Latest M18 Data Log ID: ${latestPurchaseOrderLineLog?.id}") | |||||
| // logger.info("${poLineRefType}: Latest M18 Data Log ID: ${latestPurchaseOrderLineLog?.id}") | |||||
| // Save to m18_data_log table | // Save to m18_data_log table | ||||
| logger.info("${poLineRefType}: Saving for M18 Data Log...") | logger.info("${poLineRefType}: Saving for M18 Data Log...") | ||||
| @@ -262,15 +295,15 @@ open class M18PurchaseOrderService( | |||||
| id = null, | id = null, | ||||
| refType = poLineRefType, | refType = poLineRefType, | ||||
| m18Id = line.id, | m18Id = line.id, | ||||
| m18LastModifyDate = commonUtils.InstantToLocalDateTime(mainpo.lastModifyDate), | |||||
| dataLog = lineJson, | |||||
| status = true | |||||
| m18LastModifyDate = commonUtils.timestampToLocalDateTime(mainpo.lastModifyDate), | |||||
| // dataLog = lineJson, | |||||
| statusEnum = M18DataLogStatus.NOT_PROCESS | |||||
| ) | ) | ||||
| val saveM18PurchaseOrderLineLog = | val saveM18PurchaseOrderLineLog = | ||||
| m18DataLogService.saveM18DataLog(saveM18PurchaseOrderLineLogRequest) | m18DataLogService.saveM18DataLog(saveM18PurchaseOrderLineLogRequest) | ||||
| // logger.info("${poLineRefType}: Saved M18 Data Log. ID: ${saveM18PurchaseOrderLineLog.id}") | |||||
| // logger.info("${poLineRefType}: Saved M18 Data Log. ID: ${saveM18PurchaseOrderLineLog.id}") | |||||
| logger.info("${poLineRefType}: Finding item...") | logger.info("${poLineRefType}: Finding item...") | ||||
| val item = itemsService.findByM18Id(line.proId) | val item = itemsService.findByM18Id(line.proId) | ||||
| logger.info("${poLineRefType}: Item ID: ${item?.id} | M18 Item ID: ${line.proId}") | logger.info("${poLineRefType}: Item ID: ${item?.id} | M18 Item ID: ${line.proId}") | ||||
| @@ -285,14 +318,15 @@ open class M18PurchaseOrderService( | |||||
| // Save to purchase_order_line table | // Save to purchase_order_line table | ||||
| logger.info("${poLineRefType}: Saving purchase order line...") | logger.info("${poLineRefType}: Saving purchase order line...") | ||||
| val itemUom = item?.id?.let { itemUomService.findPurchaseUnitByItemId(it) } | |||||
| val savePurchaseOrderLineRequest = SavePurchaseOrderLineRequest( | val savePurchaseOrderLineRequest = SavePurchaseOrderLineRequest( | ||||
| id = existingPurchaseOrderLine?.id, | id = existingPurchaseOrderLine?.id, | ||||
| itemId = item?.id, | itemId = item?.id, | ||||
| uomId = null, | |||||
| uomId = itemUom?.uom?.id, | |||||
| purchaseOrderId = purchaseOrderId, | purchaseOrderId = purchaseOrderId, | ||||
| qty = line.qty, | qty = line.qty, | ||||
| price = line.amt, | price = line.amt, | ||||
| m18CurrencyId = line.curId, | |||||
| // m18CurrencyId = mainpo.curId, | |||||
| status = existingPurchaseOrderLine?.status?.value | status = existingPurchaseOrderLine?.status?.value | ||||
| ?: PurchaseOrderLineStatus.PENDING.value, | ?: PurchaseOrderLineStatus.PENDING.value, | ||||
| m18DataLogId = saveM18PurchaseOrderLineLog.id, | m18DataLogId = saveM18PurchaseOrderLineLog.id, | ||||
| @@ -300,6 +334,18 @@ open class M18PurchaseOrderService( | |||||
| val savePurchaseOrderLineResponse = | val savePurchaseOrderLineResponse = | ||||
| purchaseOrderLineService.savePurchaseOrderLine(savePurchaseOrderLineRequest) | purchaseOrderLineService.savePurchaseOrderLine(savePurchaseOrderLineRequest) | ||||
| // Update m18_data_log with success | |||||
| val successSaveM18PurchaseOrderLineLogRequest = SaveM18DataLogRequest( | |||||
| id = saveM18PurchaseOrderLineLog.id, | |||||
| dataLog = lineJson, | |||||
| statusEnum = M18DataLogStatus.NOT_PROCESS | |||||
| ) | |||||
| m18DataLogService.saveM18DataLog(successSaveM18PurchaseOrderLineLogRequest) | |||||
| // log success info | |||||
| successDetailList.add(line.id) | |||||
| logger.info("${poLineRefType}: Purchase order ID: ${purchaseOrderId} | M18 ID: ${purchaseOrder.id}") | logger.info("${poLineRefType}: Purchase order ID: ${purchaseOrderId} | M18 ID: ${purchaseOrder.id}") | ||||
| logger.info("${poLineRefType}: Saved purchase order line. ID: ${savePurchaseOrderLineResponse.id} | M18 Line ID: ${line.id}") | logger.info("${poLineRefType}: Saved purchase order line. ID: ${savePurchaseOrderLineResponse.id} | M18 Line ID: ${line.id}") | ||||
| } catch (e: Exception) { | } catch (e: Exception) { | ||||
| @@ -310,11 +356,8 @@ open class M18PurchaseOrderService( | |||||
| val errorSaveM18PurchaseOrderLineLogRequest = SaveM18DataLogRequest( | val errorSaveM18PurchaseOrderLineLogRequest = SaveM18DataLogRequest( | ||||
| id = saveM18PurchaseOrderLineLog.id, | id = saveM18PurchaseOrderLineLog.id, | ||||
| refType = "${poRefType}", | |||||
| m18Id = line.id, | |||||
| m18LastModifyDate = commonUtils.InstantToLocalDateTime(mainpo.lastModifyDate), | |||||
| dataLog = lineJson, | |||||
| status = false | |||||
| dataLog = mutableMapOf(Pair("Exception Message", e.message)), | |||||
| statusEnum = M18DataLogStatus.FAIL | |||||
| ) | ) | ||||
| m18DataLogService.saveM18DataLog(errorSaveM18PurchaseOrderLineLogRequest) | m18DataLogService.saveM18DataLog(errorSaveM18PurchaseOrderLineLogRequest) | ||||
| @@ -328,9 +371,23 @@ open class M18PurchaseOrderService( | |||||
| id = null, | id = null, | ||||
| refType = "${poLineRefType}", | refType = "${poLineRefType}", | ||||
| m18Id = purchaseOrder.id, | m18Id = purchaseOrder.id, | ||||
| m18LastModifyDate = commonUtils.InstantToLocalDateTime(mainpo.lastModifyDate), | |||||
| dataLog = mutableMapOf(Pair("Error Message", "${poLineRefType} is null")), | |||||
| status = false | |||||
| m18LastModifyDate = commonUtils.timestampToLocalDateTime(mainpo.lastModifyDate), | |||||
| // dataLog = mutableMapOf(Pair("Error Message", "${poLineRefType} is null")), | |||||
| dataLog = mutableMapOf( | |||||
| Pair( | |||||
| "${poLineRefType} Error Message", | |||||
| "pot is null" | |||||
| ), | |||||
| Pair( | |||||
| "${poLineRefType} Error Code", | |||||
| purchaseOrderLineMessage?.get(0)?.msgCode ?: "No Msg Code from M18" | |||||
| ), | |||||
| Pair( | |||||
| "${poLineRefType} Error Detail", | |||||
| purchaseOrderLineMessage?.get(0)?.msgDetail ?: "No Msg Detail from M18" | |||||
| ), | |||||
| ), | |||||
| statusEnum = M18DataLogStatus.FAIL | |||||
| ) | ) | ||||
| val errorLog = m18DataLogService.saveM18DataLog(saveM18PurchaseOrderLineLogRequest) | val errorLog = m18DataLogService.saveM18DataLog(saveM18PurchaseOrderLineLogRequest) | ||||
| @@ -338,15 +395,29 @@ open class M18PurchaseOrderService( | |||||
| } | } | ||||
| } else { | } else { | ||||
| // mainpo | // mainpo | ||||
| failList.add(purchaseOrder.id) | |||||
| logger.error("${poRefType}: Saving Failure!") | logger.error("${poRefType}: Saving Failure!") | ||||
| val saveM18DataLogRequest = SaveM18DataLogRequest( | val saveM18DataLogRequest = SaveM18DataLogRequest( | ||||
| id = null, | id = null, | ||||
| refType = "${poRefType}", | refType = "${poRefType}", | ||||
| m18Id = purchaseOrder.id, | m18Id = purchaseOrder.id, | ||||
| // m18LastModifyDate = if(mainpo?.lastModifyDate != null) commonUtils.InstantToLocalDateTime(mainpo.lastModifyDate) else LocalDateTime.now(), | |||||
| // m18LastModifyDate = if(mainpo?.lastModifyDate != null) commonUtils.instantToLocalDateTime(mainpo.lastModifyDate) else LocalDateTime.now(), | |||||
| m18LastModifyDate = LocalDateTime.now(), | m18LastModifyDate = LocalDateTime.now(), | ||||
| dataLog = mutableMapOf(Pair("Error Message", "${poRefType} is null")), | |||||
| status = false | |||||
| dataLog = mutableMapOf( | |||||
| Pair( | |||||
| "${poRefType} Error", | |||||
| "mainpo is null" | |||||
| ), | |||||
| Pair( | |||||
| "${poRefType} Error Code", | |||||
| purchaseOrdersMessages?.get(0)?.msgCode ?: "No Msg Code from M18" | |||||
| ), | |||||
| Pair( | |||||
| "${poRefType} Error Detail", | |||||
| purchaseOrdersMessages?.get(0)?.msgDetail ?: "No Msg Detail from M18" | |||||
| ), | |||||
| ), | |||||
| statusEnum = M18DataLogStatus.FAIL | |||||
| ) | ) | ||||
| val errorLog = m18DataLogService.saveM18DataLog(saveM18DataLogRequest) | val errorLog = m18DataLogService.saveM18DataLog(saveM18DataLogRequest) | ||||
| @@ -363,14 +434,14 @@ open class M18PurchaseOrderService( | |||||
| // End of save. Check result | // End of save. Check result | ||||
| logger.info("Total Success (${poRefType}) (${successList.size}): $successList") | logger.info("Total Success (${poRefType}) (${successList.size}): $successList") | ||||
| if (failList.size > 0) { | |||||
| logger.error("Total Fail (${poRefType}) (${failList.size}): $failList") | |||||
| } | |||||
| // if (failList.size > 0) { | |||||
| logger.error("Total Fail (${poRefType}) (${failList.size}): $failList") | |||||
| // } | |||||
| logger.info("Total Success (${poLineRefType}) (${successDetailList.size}): $successDetailList") | logger.info("Total Success (${poLineRefType}) (${successDetailList.size}): $successDetailList") | ||||
| if (failDetailList.size > 0) { | |||||
| logger.error("Total Fail (${poLineRefType}) (${failDetailList.size}): $failDetailList") | |||||
| } | |||||
| // if (failDetailList.size > 0) { | |||||
| logger.error("Total Fail (${poLineRefType}) (${failDetailList.size}): $failDetailList") | |||||
| // } | |||||
| logger.info("--------------------------------------------End - Saving M18 Purchase Order--------------------------------------------") | logger.info("--------------------------------------------End - Saving M18 Purchase Order--------------------------------------------") | ||||
| } | } | ||||
| } | } | ||||
| @@ -0,0 +1,192 @@ | |||||
| package com.ffii.fpsms.m18.service | |||||
| import com.ffii.core.utils.JwtTokenUtil | |||||
| import com.ffii.fpsms.api.service.ApiCallerService | |||||
| import com.ffii.fpsms.m18.M18Config | |||||
| import com.ffii.fpsms.m18.model.M18PurchaseQuotationListRequest | |||||
| import com.ffii.fpsms.m18.model.M18PurchaseQuotationListResponse | |||||
| import com.ffii.fpsms.m18.model.M18PurchaseQuotationRequest | |||||
| import com.ffii.fpsms.m18.model.M18PurchaseQuotationResponse | |||||
| import com.ffii.fpsms.m18.utils.CommonUtils | |||||
| import com.ffii.fpsms.modules.master.service.ItemUomService | |||||
| import com.ffii.fpsms.modules.master.service.ItemsService | |||||
| import com.ffii.fpsms.modules.purchaseQuotation.service.PurchaseQuotationLineService | |||||
| import com.ffii.fpsms.modules.purchaseQuotation.service.PurchaseQuotationService | |||||
| import com.ffii.fpsms.modules.purchaseQuotation.web.model.SavePurchaseQuotationLineRequest | |||||
| import com.ffii.fpsms.modules.purchaseQuotation.web.model.SavePurchaseQuotationRequest | |||||
| import org.slf4j.Logger | |||||
| import org.slf4j.LoggerFactory | |||||
| import org.springframework.stereotype.Service | |||||
| @Service | |||||
| open class M18PurchaseQuotationService( | |||||
| val m18Config: M18Config, | |||||
| val apiCallerService: ApiCallerService, | |||||
| val itemsService: ItemsService, | |||||
| val purchaseQuotationService: PurchaseQuotationService, | |||||
| val purchaseQuotationLineService: PurchaseQuotationLineService, | |||||
| val itemUomService: ItemUomService, | |||||
| ) { | |||||
| val commonUtils = CommonUtils() | |||||
| val logger: Logger = LoggerFactory.getLogger(JwtTokenUtil::class.java) | |||||
| val lastModifyDateStart = "2025-05-14 14:00:00" | |||||
| val lastModifyDateEnd = "2025-05-14 14:30:00" | |||||
| val lastModifyDateConds = | |||||
| "lastModifyDate=largerOrEqual=${lastModifyDateStart}=and=lastModifyDate=lessOrEqual=${lastModifyDateEnd}" | |||||
| // M18 Conditions | |||||
| val beIdList = listOf(m18Config.BEID_PF, m18Config.BEID_PP, m18Config.BEID_TOA) | |||||
| val beIdConds = "(" + commonUtils.listToString(beIdList.filterNotNull(), "beId=equal=", "=or=") + ")" | |||||
| // M18 API | |||||
| val M18_LOAD_PURCHASE_QUOTATION_API = "/root/api/read/vqu" | |||||
| val M18_FETCH_PURCHASE_QUOTATION_LIST_API = "/search/search" | |||||
| open fun getPurchaseQuotations(): M18PurchaseQuotationListResponse? { | |||||
| val params = M18PurchaseQuotationListRequest( | |||||
| conds = beIdConds | |||||
| ) | |||||
| var purchaseQuotations: M18PurchaseQuotationListResponse? = null | |||||
| try { | |||||
| purchaseQuotations = | |||||
| apiCallerService.get<M18PurchaseQuotationListResponse, M18PurchaseQuotationListRequest>( | |||||
| M18_FETCH_PURCHASE_QUOTATION_LIST_API, | |||||
| params | |||||
| ).block() | |||||
| } catch (e: Exception) { | |||||
| logger.error("(Getting Purchase Quotation list) Error on Function - ${e.stackTrace}") | |||||
| logger.error(e.message) | |||||
| } | |||||
| return purchaseQuotations | |||||
| } | |||||
| open fun getPurchaseQuotation(id: Long): M18PurchaseQuotationResponse? { | |||||
| val params = M18PurchaseQuotationRequest( | |||||
| id = id | |||||
| ) | |||||
| var purchaseQuotation: M18PurchaseQuotationResponse? = null | |||||
| try { | |||||
| purchaseQuotation = apiCallerService.get<M18PurchaseQuotationResponse, M18PurchaseQuotationRequest>( | |||||
| M18_LOAD_PURCHASE_QUOTATION_API, | |||||
| params | |||||
| ).block() | |||||
| } catch (e: Exception) { | |||||
| logger.error("(Getting Purchase Quotation Detail) Error on Function - ${e.stackTrace}") | |||||
| logger.error(e.message) | |||||
| } | |||||
| return purchaseQuotation | |||||
| } | |||||
| open fun savePurchaseQuotations() { | |||||
| logger.info("--------------------------------------------Start - Saving M18 Purchase Quotations--------------------------------------------") | |||||
| val purchaseQuotations = getPurchaseQuotations() | |||||
| val pqRefType = "Purchase Quotation" | |||||
| val pqLineRefType = "Purchase Quotation Line" | |||||
| val successList = mutableListOf<Long>() | |||||
| val successDetailList = mutableListOf<Long>() | |||||
| val failList = mutableListOf<Long>() | |||||
| val failDetailList = mutableListOf<Long>() | |||||
| val values = purchaseQuotations?.values | |||||
| val pqsMessages = purchaseQuotations?.messages?.get(0) | |||||
| if (values != null) { | |||||
| values.forEach { purchaseQuotation -> | |||||
| try { | |||||
| val pqDetail = getPurchaseQuotation(purchaseQuotation.id) | |||||
| val mainvqu = if(pqDetail?.data?.mainvqu?.isNotEmpty() == true) pqDetail.data.mainvqu[0] else null | |||||
| val remvqu = if(pqDetail?.data?.remvqu?.isNotEmpty() == true) pqDetail.data.remvqu[0] else null | |||||
| val vqut = if(pqDetail?.data?.vqut?.isNotEmpty() == true) pqDetail.data.vqut else null | |||||
| val pqMessages = if(pqDetail?.messages?.isNotEmpty() == true) pqDetail.messages[0] else null | |||||
| var pqId: Long? = null | |||||
| if (mainvqu != null) { | |||||
| // Save Purchase Quotation | |||||
| try { | |||||
| val savePqRequest = SavePurchaseQuotationRequest( | |||||
| code = mainvqu.code, | |||||
| expiryDate = commonUtils.timestampToLocalDateTime(mainvqu.expDate), | |||||
| effectiveDate = commonUtils.timestampToLocalDateTime(mainvqu.tDate), | |||||
| m18ShopId = mainvqu.venId, | |||||
| remarks = remvqu?.remarks, | |||||
| m18Id = mainvqu.id, | |||||
| m18LastModifyDate = commonUtils.timestampToLocalDateTime(mainvqu.lastModifyDate) | |||||
| ) | |||||
| pqId = purchaseQuotationService.savePurchaseQuotation(savePqRequest).id | |||||
| successList += mainvqu.id | |||||
| logger.info("${pqRefType}: Saved purchase quotation. ID: ${pqId} | M18 ID: ${purchaseQuotation.id}") | |||||
| } catch (e: Exception) { | |||||
| failList.add(mainvqu.id) | |||||
| logger.error("${pqRefType}: Saving Failure!") | |||||
| logger.error("Error on Function - ${e.stackTrace} | Type: ${pqRefType} | M18 ID: ${purchaseQuotation.id}") | |||||
| logger.error(e.message) | |||||
| } | |||||
| // Save Purchase Quotation Line | |||||
| if (vqut != null) { | |||||
| vqut.forEach { line -> | |||||
| try { | |||||
| val savePqLineRequest = SavePurchaseQuotationLineRequest( | |||||
| purchaseQuotationId = pqId, | |||||
| m18ItemId = line.proId, | |||||
| code = line.refCode, | |||||
| description = line.bDesc, | |||||
| m18Id = line.id, | |||||
| m18LastModifyDate = commonUtils.timestampToLocalDateTime(mainvqu.lastModifyDate) | |||||
| ) | |||||
| val pqLineId = purchaseQuotationLineService.savePurchaseQuotationLine(savePqLineRequest).id | |||||
| successDetailList += line.id | |||||
| logger.info("${pqRefType}: Saved purchase quotation line. ID: ${pqLineId} | M18 ID: ${purchaseQuotation.id} | M18 Line ID: ${line.id}") | |||||
| } catch (e: Exception) { | |||||
| failDetailList.add(line.id) | |||||
| logger.error("${pqLineRefType}: Saving Failure!") | |||||
| logger.error("Error on Function - ${e.stackTrace} | Type: ${pqLineRefType} | M18 ID: ${purchaseQuotation.id} | M18 Line ID: ${line.id}") | |||||
| logger.error(e.message) | |||||
| } | |||||
| } | |||||
| } else { | |||||
| logger.error("Purchase Quotation Line is null. May occur errors.") | |||||
| } | |||||
| } else { | |||||
| logger.error("Purchase Quotation is null. May occur errors.") | |||||
| logger.error("Error code: ${pqMessages?.msgDetail}") | |||||
| logger.error("Error messages: ${pqMessages?.msgDetail}") | |||||
| } | |||||
| } catch (e: Exception) { | |||||
| failList.add(purchaseQuotation.id) | |||||
| logger.error("${pqRefType} / ${pqLineRefType}: Saving Failure!") | |||||
| logger.error("Error on Function - ${e.stackTrace} | Type: ${pqRefType} / ${pqLineRefType} | M18 ID: ${purchaseQuotation.id}") | |||||
| logger.error(e.message) | |||||
| } | |||||
| } | |||||
| } else { | |||||
| logger.error("Purchase Quotation List is null. May occur errors.") | |||||
| logger.error("Error code: ${pqsMessages?.msgDetail}") | |||||
| logger.error("Error messages: ${pqsMessages?.msgDetail}") | |||||
| } | |||||
| logger.info("Total Purchase Quotation Save Success (${successList.size})") | |||||
| logger.info("Total Purchase Quotation Save Detail Success (${successDetailList.size})") | |||||
| if (failList.size > 0) { | |||||
| logger.error("Total Purchase Quotation Fail (${failList.size}): $failList") | |||||
| } | |||||
| if (failDetailList.size > 0) { | |||||
| logger.error("Total Purchase Quotation Detail Fail (${failDetailList.size}): $failDetailList") | |||||
| } | |||||
| logger.info("--------------------------------------------End - Saving M18 Purchase Quotations--------------------------------------------") | |||||
| } | |||||
| } | |||||
| @@ -15,7 +15,7 @@ open class M18TokenService( | |||||
| private val m18Config: M18Config | private val m18Config: M18Config | ||||
| ) { | ) { | ||||
| // @Bean | |||||
| @Bean | |||||
| fun run() { | fun run() { | ||||
| // val params: MutableMap<String, String> = mutableMapOf( | // val params: MutableMap<String, String> = mutableMapOf( | ||||
| // "grant_type" to m18Config.GRANT_TYPE, | // "grant_type" to m18Config.GRANT_TYPE, | ||||
| @@ -1,20 +1,26 @@ | |||||
| package com.ffii.fpsms.m18.utils | package com.ffii.fpsms.m18.utils | ||||
| import com.ffii.fpsms.m18.M18Config | |||||
| import org.springframework.beans.factory.annotation.Autowired | |||||
| import org.springframework.context.annotation.Lazy | |||||
| import org.springframework.stereotype.Component | |||||
| import java.time.Instant | import java.time.Instant | ||||
| import java.time.LocalDateTime | import java.time.LocalDateTime | ||||
| import java.time.ZoneId | import java.time.ZoneId | ||||
| open class CommonUtils() { | |||||
| open fun InstantToLocalDateTime(timestamp: Long):LocalDateTime { | |||||
| @Component | |||||
| open class CommonUtils( | |||||
| ) { | |||||
| open fun timestampToLocalDateTime(timestamp: Long):LocalDateTime { | |||||
| val localDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(timestamp), ZoneId.of("Asia/Hong_Kong")) | val localDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(timestamp), ZoneId.of("Asia/Hong_Kong")) | ||||
| // println("ZoneId: ${ZoneId.systemDefault()}") | |||||
| // println("ZoneId: ${ZoneId.of("Asia/Hong_Kong")}") | |||||
| println("Timestamp: $timestamp") | |||||
| println("Local Date Time: $localDateTime") | |||||
| return localDateTime | return localDateTime | ||||
| } | } | ||||
| open fun ListToString(numbers: List<Long>, prefix: String, delimiter: String): String { | |||||
| fun listToString(numbers: List<Long>?, prefix: String, delimiter: String): String { | |||||
| if (numbers == null) { | |||||
| return "" | |||||
| } | |||||
| return numbers.joinToString(delimiter) { "$prefix$it" } | return numbers.joinToString(delimiter) { "$prefix$it" } | ||||
| } | } | ||||
| } | } | ||||
| @@ -4,10 +4,15 @@ import com.ffii.core.utils.JwtTokenUtil | |||||
| import com.ffii.fpsms.m18.M18Config | import com.ffii.fpsms.m18.M18Config | ||||
| import com.ffii.fpsms.m18.service.M18MasterDataService | import com.ffii.fpsms.m18.service.M18MasterDataService | ||||
| import com.ffii.fpsms.m18.service.M18PurchaseOrderService | import com.ffii.fpsms.m18.service.M18PurchaseOrderService | ||||
| import com.ffii.fpsms.m18.service.M18PurchaseQuotationService | |||||
| import com.ffii.fpsms.modules.master.entity.ItemUom | |||||
| import com.ffii.fpsms.modules.master.entity.Items | |||||
| import com.ffii.fpsms.modules.master.entity.Shop | import com.ffii.fpsms.modules.master.entity.Shop | ||||
| import com.ffii.fpsms.modules.master.entity.ShopRepository | import com.ffii.fpsms.modules.master.entity.ShopRepository | ||||
| import com.ffii.fpsms.modules.master.entity.projections.SearchId | import com.ffii.fpsms.modules.master.entity.projections.SearchId | ||||
| import com.ffii.fpsms.modules.master.enums.ShopType | import com.ffii.fpsms.modules.master.enums.ShopType | ||||
| import com.ffii.fpsms.modules.master.service.ItemUomService | |||||
| import com.ffii.fpsms.modules.master.service.ItemsService | |||||
| import com.ffii.fpsms.modules.master.service.ShopService | import com.ffii.fpsms.modules.master.service.ShopService | ||||
| import org.slf4j.Logger | import org.slf4j.Logger | ||||
| import org.slf4j.LoggerFactory | import org.slf4j.LoggerFactory | ||||
| @@ -22,22 +27,36 @@ import org.springframework.web.bind.annotation.RestController | |||||
| class M18TestController ( | class M18TestController ( | ||||
| private val shopRepository: ShopRepository, | private val shopRepository: ShopRepository, | ||||
| private val shopService: ShopService, | private val shopService: ShopService, | ||||
| private val itemsService: ItemsService, | |||||
| private val m18MasterDataService: M18MasterDataService, | private val m18MasterDataService: M18MasterDataService, | ||||
| private val m18PurchaseOrderService: M18PurchaseOrderService, | private val m18PurchaseOrderService: M18PurchaseOrderService, | ||||
| private val m18Config: M18Config, | private val m18Config: M18Config, | ||||
| private val itemUomService: ItemUomService, | |||||
| private val m18PurchaseQuotationService: M18PurchaseQuotationService, | |||||
| ) { | ) { | ||||
| var logger: Logger = LoggerFactory.getLogger(JwtTokenUtil::class.java) | var logger: Logger = LoggerFactory.getLogger(JwtTokenUtil::class.java) | ||||
| @GetMapping("/test1") | @GetMapping("/test1") | ||||
| fun test1(): List<Long>? { | |||||
| return shopService.findVendorIdsByCodeRegexp(listOf("P06", "P07")) | |||||
| fun test1(@RequestParam name: String, @RequestParam m18UomId: Long): Items? { | |||||
| val temp = itemsService.findByNameAndM18UomId(name, m18UomId) | |||||
| println(name) | |||||
| println(m18UomId) | |||||
| println(temp?.id) | |||||
| return temp | |||||
| } | } | ||||
| @GetMapping("/test2") | @GetMapping("/test2") | ||||
| fun test2(): List<Long>? { | fun test2(): List<Long>? { | ||||
| return shopRepository.findIdsByCodeRegexpAndTypeAndDeletedIsFalse("P06|P07", ShopType.SUPPLIER.value) | |||||
| return shopRepository.findM18IdsByCodeRegexpAndTypeAndDeletedIsFalse("P06|P07", ShopType.SUPPLIER.value) | |||||
| } | } | ||||
| @GetMapping("/test3") | |||||
| fun test3(@RequestParam m18ItemId: Long): ItemUom? { | |||||
| val response = itemUomService.findPurchaseUnitByM18ItemId(m18ItemId) | |||||
| println(response?.item?.id) | |||||
| println(response?.uom?.id) | |||||
| return response | |||||
| } | |||||
| // --------------------------------------------- Master Data --------------------------------------------- /// | // --------------------------------------------- Master Data --------------------------------------------- /// | ||||
| @GetMapping("/product") | @GetMapping("/product") | ||||
| fun m18Products() { | fun m18Products() { | ||||
| @@ -63,10 +82,23 @@ class M18TestController ( | |||||
| m18MasterDataService.saveCurrencies() | m18MasterDataService.saveCurrencies() | ||||
| } | } | ||||
| @GetMapping("/bom") | |||||
| fun m18Bom() { | |||||
| logger.info("Access token: ${m18Config.ACCESS_TOKEN}") | |||||
| m18MasterDataService.saveBoms() | |||||
| } | |||||
| // --------------------------------------------- Purchase Order --------------------------------------------- /// | // --------------------------------------------- Purchase Order --------------------------------------------- /// | ||||
| @GetMapping("/po") | @GetMapping("/po") | ||||
| fun m18PO() { | fun m18PO() { | ||||
| logger.info("Access token: ${m18Config.ACCESS_TOKEN}") | logger.info("Access token: ${m18Config.ACCESS_TOKEN}") | ||||
| m18PurchaseOrderService.savePurchaseOrders() | m18PurchaseOrderService.savePurchaseOrders() | ||||
| } | } | ||||
| // --------------------------------------------- Purchase Quotation --------------------------------------------- /// | |||||
| @GetMapping("/pq") | |||||
| fun m18PQ() { | |||||
| logger.info("Access token: ${m18Config.ACCESS_TOKEN}") | |||||
| m18PurchaseQuotationService.savePurchaseQuotations() | |||||
| } | |||||
| } | } | ||||
| @@ -1,12 +0,0 @@ | |||||
| package com.ffii.fpsms.modules.master.web.models | |||||
| import java.time.LocalDateTime | |||||
| data class CurrencyRequest ( | |||||
| val id: Long?, | |||||
| val code: String?, | |||||
| val name: String?, | |||||
| val description: String?, | |||||
| val m18Id: Long?, | |||||
| val m18LastModifyDate: LocalDateTime?, | |||||
| ) | |||||
| @@ -42,9 +42,9 @@ m18: | |||||
| supplier-not: | supplier-not: | ||||
| material-po: P06, P07 | material-po: P06, P07 | ||||
| beId: | beId: | ||||
| toa: 29 | |||||
| pp: 27 | |||||
| pf: 1 | |||||
| toa: 1 | |||||
| pf: 27 | |||||
| pp: 29 | |||||
| seriesId: | seriesId: | ||||
| pp: 26 | pp: 26 | ||||
| pf: 33 | pf: 33 | ||||
| @@ -0,0 +1,9 @@ | |||||
| -- liquibase formatted sql | |||||
| -- changeset cyril:update bom | |||||
| ALTER TABLE `bom` | |||||
| ADD COLUMN `itemId` INT NULL AFTER `deleted`, | |||||
| ADD COLUMN `outputQtyUom` VARCHAR(50) NULL AFTER `outputQty`, | |||||
| ADD COLUMN `yield` decimal(14, 2) NULL AFTER `outputQtyUom`, | |||||
| ADD CONSTRAINT `FK_BOM_ON_ITEMID` FOREIGN KEY (`itemId`) REFERENCES `items` (`id`); | |||||
| ; | |||||
| @@ -0,0 +1,46 @@ | |||||
| -- liquibase formatted sql | |||||
| -- changeset cyril:create bom & process table | |||||
| CREATE TABLE `purchase_quotation` | |||||
| ( | |||||
| `id` INT NOT NULL AUTO_INCREMENT, | |||||
| `created` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, | |||||
| `createdBy` VARCHAR(30) NULL DEFAULT NULL, | |||||
| `version` INT NOT NULL DEFAULT '0', | |||||
| `modified` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, | |||||
| `modifiedBy` VARCHAR(30) NULL DEFAULT NULL, | |||||
| `deleted` TINYINT(1) NOT NULL DEFAULT '0', | |||||
| `code` VARCHAR(30) NOT NULL, | |||||
| `expiryDate` DATETIME NULL, | |||||
| `effectiveDate` DATETIME NULL, | |||||
| `shopId` INT NULL, | |||||
| `currencyId` INT NULL, | |||||
| `remarks` VARCHAR(500) NULL, | |||||
| `m18Id` INT NULL, | |||||
| `m18LastModifyDate` DATETIME NULL, | |||||
| CONSTRAINT pk_purchase_quotation PRIMARY KEY (id), | |||||
| CONSTRAINT `FK_PURCHASE_QUOTATION_ON_SHOPID` FOREIGN KEY (`shopId`) REFERENCES `shop` (`id`), | |||||
| CONSTRAINT `FK_PURCHASE_QUOTATION_ON_CURRENCYID` FOREIGN KEY (`currencyId`) REFERENCES `currency` (`id`) | |||||
| ); | |||||
| CREATE TABLE `purchase_quotation_line` | |||||
| ( | |||||
| `id` INT NOT NULL AUTO_INCREMENT, | |||||
| `created` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, | |||||
| `createdBy` VARCHAR(30) NULL DEFAULT NULL, | |||||
| `version` INT NOT NULL DEFAULT '0', | |||||
| `modified` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, | |||||
| `modifiedBy` VARCHAR(30) NULL DEFAULT NULL, | |||||
| `deleted` TINYINT(1) NOT NULL DEFAULT '0', | |||||
| `purchaseQuotationId` INT NULL, | |||||
| `itemId` INT NULL, | |||||
| `code` VARCHAR(30) NULL, | |||||
| `description` VARCHAR(300) NULL, | |||||
| `uomId` INT NULL, | |||||
| `m18Id` INT NULL, | |||||
| `m18LastModifyDate` DATETIME NULL, | |||||
| CONSTRAINT pk_purchase_quotation_line PRIMARY KEY (id), | |||||
| CONSTRAINT `FK_PURCHASE_QUOTATION_LINE_ON_PURCHASEQUOTATIONID` FOREIGN KEY (`purchaseQuotationId`) REFERENCES `purchase_quotation` (`id`), | |||||
| CONSTRAINT `FK_PURCHASE_QUOTATION_LINE_ON_ITEMID` FOREIGN KEY (`itemId`) REFERENCES `items` (`id`), | |||||
| CONSTRAINT `FK_PURCHASE_QUOTATION_LINE_ON_UOMID` FOREIGN KEY (`uomId`) REFERENCES `uom_conversion` (`id`) | |||||
| ); | |||||