@@ -22,13 +22,12 @@ import org.springframework.web.reactive.function.client.awaitBody | |||||
@Service | @Service | ||||
open class ApiCallerService( | open class ApiCallerService( | ||||
@Value("\${m18.config.base-url}") private val baseUrl: String, | |||||
open val m18Config: M18Config | |||||
val m18Config: M18Config | |||||
) { | ) { | ||||
val logger: Logger = LoggerFactory.getLogger(JwtTokenUtil::class.java) | val logger: Logger = LoggerFactory.getLogger(JwtTokenUtil::class.java) | ||||
val webClient: WebClient = WebClient.builder() | val webClient: WebClient = WebClient.builder() | ||||
.baseUrl(baseUrl) | |||||
.baseUrl(m18Config.BASE_URL) | |||||
.defaultHeaders { headers -> | .defaultHeaders { headers -> | ||||
headers.set(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) | headers.set(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) | ||||
// headers.set(HttpHeaders.AUTHORIZATION, "Bearer ${m18Config.ACCESS_TOKEN}") | // headers.set(HttpHeaders.AUTHORIZATION, "Bearer ${m18Config.ACCESS_TOKEN}") | ||||
@@ -10,48 +10,61 @@ import org.springframework.context.annotation.Configuration | |||||
open class M18Config { | open class M18Config { | ||||
// Account | // Account | ||||
@Value("\${m18.config.grant-type}") | |||||
lateinit var GRANT_TYPE: String; | |||||
// @Value("\${m18.config.grant-type}") | |||||
var GRANT_TYPE: String = "password"; | |||||
@Value("\${m18.config.client-id}") | |||||
lateinit var CLIENT_ID: String; | |||||
// @Value("\${m18.config.client-id}") | |||||
var CLIENT_ID: String = "M2Y1OGYxMmQtZDRiOS00OTA4LTgyNTktZDRkNzEzNWVkMzRm"; | |||||
@Value("\${m18.config.client-secret}") | |||||
lateinit var CLIENT_SECRET: String; | |||||
// @Value("\${m18.config.client-secret}") | |||||
var CLIENT_SECRET: String = "M2Y2YjQzYzQtZTc2Mi00OTFhLTkwYmItYmJhMzFjZjEyYmY5"; | |||||
@Value("\${m18.config.username}") | |||||
lateinit var USERNAME: String; | |||||
// @Value("\${m18.config.username}") | |||||
var USERNAME: String = "testingMTMS"; | |||||
@Value("\${m18.config.password}") | |||||
lateinit var PASSWORD: String; | |||||
// @Value("\${m18.config.password}") | |||||
var PASSWORD: String = "db25f2fc14cd2d2b1e7af307241f548fb03c312a"; | |||||
var BASE_URL: String = "http://16.162.251.126/jsf/rfws" | |||||
// Supplier | |||||
// @Value("\${m18.config.supplier-not.material-po}") | |||||
var MATERIAL_PO_SUPPLIER_NOT: List<String> = listOf("P06", "P07"); | |||||
// @Value("\${m18.config.supplier.shop-po}") | |||||
var SHOP_PO_SUPPLIER: List<String> = listOf("P06", "P07"); | |||||
// @Value("\${m18.config.supplier.oem-po}") | |||||
var OEM_PO_SUPPLIER: List<String> = listOf("T62"); | |||||
// Series | // Series | ||||
@Value("\${m18.config.seriesId.pp}") | |||||
var SERIESID_PP: Long? = null; | |||||
// @Value("\${m18.config.seriesId.pp}") | |||||
var SERIESID_PP: Long = 26; | |||||
// @Value("\${m18.config.seriesId.pf}") | |||||
var SERIESID_PF: Long = 33; | |||||
@Value("\${m18.config.seriesId.pf}") | |||||
var SERIESID_PF: Long? = null; | |||||
// @Value("\${m18.config.seriesId.sc}") | |||||
var SERIESID_SC: Long = 27; | |||||
@Value("\${m18.config.seriesId.sc}") | |||||
var SERIESID_SC: Long? = null; | |||||
// @Value("\${m18.config.seriesId.se}") | |||||
var SERIESID_SE: Long = 28; | |||||
@Value("\${m18.config.seriesId.se}") | |||||
var SERIESID_SE: Long? = null; | |||||
// @Value("\${m18.config.seriesId.sf}") | |||||
var SERIESID_SF: Long = 70; | |||||
@Value("\${m18.config.seriesId.sf}") | |||||
var SERIESID_SF: Long? = null; | |||||
// @Value("\${m18.config.seriesId.sr}") | |||||
var SERIESID_SR: Long = 29; | |||||
@Value("\${m18.config.seriesId.sr}") | |||||
var SERIESID_SR: Long? = null; | |||||
// BE | // BE | ||||
@Value("\${m18.config.beId.pp}") | |||||
var BEID_PP: Long? = null; | |||||
// @Value("\${m18.config.beId.pp}") | |||||
var BEID_PP: Long = 27; | |||||
@Value("\${m18.config.beId.pf}") | |||||
var BEID_PF: Long? = null; | |||||
// @Value("\${m18.config.beId.pf}") | |||||
var BEID_PF: Long = 1; | |||||
@Value("\${m18.config.beId.toa}") | |||||
var BEID_TOA: Long? = null; | |||||
// @Value("\${m18.config.beId.toa}") | |||||
var BEID_TOA: Long = 29; | |||||
// Fetch | // Fetch | ||||
var ACCESS_TOKEN: String? = null; | var ACCESS_TOKEN: String? = null; | ||||
@@ -1,40 +1,22 @@ | |||||
package com.ffii.fpsms.m18.model | package com.ffii.fpsms.m18.model | ||||
/** Product / Material Request */ | |||||
data class M18ItemRequest ( | |||||
val id: Long, | |||||
val params: String? = null, | |||||
) | |||||
/** Product / Material List Request */ | |||||
data class M18ItemListRequest ( | |||||
val stSearch: String = "pro", | |||||
val params: String? = null, | |||||
val conds: String? = null, | |||||
) | |||||
/** Vendor Request */ | |||||
data class M18VendorRequest ( | |||||
val id: Long, | |||||
val params: String? = null, | |||||
) | |||||
/** StSearch Type */ | |||||
enum class StSearchType(val value: String) { | |||||
PRODUCT("pro"), | |||||
VENDOR("ven"), | |||||
CUSTOMER("cus"), | |||||
UNIT("unit"), | |||||
CURRENCY("cur"), | |||||
} | |||||
/** Vendor List Request */ | |||||
data class M18VendorListRequest ( | |||||
val stSearch: String = "ven", | |||||
/** M18 Common Master Data Request */ | |||||
data class M18CommonListRequest ( | |||||
val stSearch: String? = null, | |||||
val params: String? = null, | val params: String? = null, | ||||
val conds: String? = null, | val conds: String? = null, | ||||
) | ) | ||||
/** Customer Request */ | |||||
data class M18CustomerRequest ( | |||||
data class M18CommonLineRequest ( | |||||
val id: Long, | val id: Long, | ||||
val params: String? = null, | val params: String? = null, | ||||
) | |||||
/** Customer List Request */ | |||||
data class M18CustomerListRequest ( | |||||
val stSearch: String = "cus", | |||||
val params: String? = null, | |||||
val conds: String? = null, | |||||
) | |||||
) |
@@ -10,16 +10,17 @@ data class M18ErrorMessages ( | |||||
) | ) | ||||
/** Product / Material Response */ | /** Product / Material Response */ | ||||
data class M18ItemResponse ( | |||||
val data: M18ItemData?, | |||||
data class M18ProductResponse ( | |||||
val data: M18ProductData?, | |||||
val messages: List<M18ErrorMessages>? | val messages: List<M18ErrorMessages>? | ||||
) | ) | ||||
data class M18ItemData ( | |||||
val pro: List<M18ItemPro>? | |||||
data class M18ProductData ( | |||||
val pro: List<M18ProductPro>?, | |||||
val price: List<M18ProductPrice>? | |||||
) | ) | ||||
data class M18ItemPro ( | |||||
data class M18ProductPro ( | |||||
val id: Long, | val id: Long, | ||||
val code: String, | val code: String, | ||||
val desc: String, | val desc: String, | ||||
@@ -28,12 +29,23 @@ data class M18ItemPro ( | |||||
val lastModifyDate: Long, | val lastModifyDate: Long, | ||||
) | ) | ||||
data class M18ProductPrice ( | |||||
val id: Long, | |||||
val hId: Long, | |||||
val unitId: Long, | |||||
val basicUnit: Boolean, | |||||
val saleUnit: Boolean, | |||||
val stkUnit: Boolean, | |||||
val purUnit: Boolean, | |||||
val pickUnit: Boolean, | |||||
) | |||||
/** Product / Material List Response */ | /** Product / Material List Response */ | ||||
data class M18ItemListResponse ( | |||||
val values: List<M18ItemListValue>?, | |||||
data class M18ProductListResponse ( | |||||
val values: List<M18ProductListValue>?, | |||||
) | ) | ||||
data class M18ItemListValue ( | |||||
data class M18ProductListValue ( | |||||
val id: Long, | val id: Long, | ||||
val lastModifyDate: String?, | val lastModifyDate: String?, | ||||
) | ) | ||||
@@ -72,4 +84,67 @@ data class M18VendorListResponse ( | |||||
data class M18VendorListValue ( | data class M18VendorListValue ( | ||||
val id: Long, | val id: Long, | ||||
val lastModifyDate: String?, | val lastModifyDate: String?, | ||||
) | |||||
/** Unit List Response */ | |||||
data class M18UnitListResponse ( | |||||
val values: List<M18UnitListValue>?, | |||||
) | |||||
data class M18UnitListValue ( | |||||
val id: Long, | |||||
val lastModifyDate: String?, | |||||
val code: String, | |||||
val udfudesc: String, | |||||
) | |||||
/** Unit Response */ | |||||
data class M18UnitResponse ( | |||||
val data: List<M18UnitData> | |||||
) | |||||
data class M18UnitData ( | |||||
val unit: List<M18UnitUnit> | |||||
) | |||||
data class M18UnitUnit ( | |||||
val id: Long, | |||||
val expiredDate: Long, | |||||
val lastModifyDate: Long, | |||||
val code: String, | |||||
val udfShortDesc: String, | |||||
val udfudesc: String, | |||||
val status: String, | |||||
) | |||||
/** Currency List Response */ | |||||
data class M18CurrencyListResponse ( | |||||
val values: List<M18CurrencyListValue>?, | |||||
) | |||||
data class M18CurrencyListValue ( | |||||
val id: Long, | |||||
val lastModifyDate: String?, | |||||
val code: String, | |||||
val sym: String, | |||||
val curDesc: String, | |||||
) | |||||
/** Currency Response */ | |||||
data class M18CurrencyResponse ( | |||||
val data: List<M18CurrencyData> | |||||
) | |||||
data class M18CurrencyData ( | |||||
val cur: List<M18CurrencyCur> | |||||
) | |||||
data class M18CurrencyCur ( | |||||
val id: Long, | |||||
val expiredDate: Long, | |||||
val lastModifyDate: Long, | |||||
val code: String, | |||||
val sym: String, | |||||
val desc: String, | |||||
val status: String, | |||||
) | ) |
@@ -1,5 +1,6 @@ | |||||
package com.ffii.fpsms.m18.model | package com.ffii.fpsms.m18.model | ||||
import com.ffii.fpsms.modules.purchaseOrder.enums.PurchaseOrderType | |||||
import java.math.BigDecimal | import java.math.BigDecimal | ||||
import java.time.Instant | import java.time.Instant | ||||
import java.time.LocalDateTime | import java.time.LocalDateTime | ||||
@@ -10,7 +11,7 @@ data class M18PurchaseOrderResponse ( | |||||
) | ) | ||||
data class M18PurchaseOrderData ( | data class M18PurchaseOrderData ( | ||||
val mainPo: List<M18PurchaseOrderMainPo>, | |||||
val mainpo: List<M18PurchaseOrderMainPo>, | |||||
val pot: List<M18PurchaseOrderPot> | val pot: List<M18PurchaseOrderPot> | ||||
) | ) | ||||
@@ -27,23 +28,35 @@ data class M18PurchaseOrderMainPo ( | |||||
) | ) | ||||
data class M18PurchaseOrderPot ( | data class M18PurchaseOrderPot ( | ||||
// Purchase Order Line ID | |||||
val id: Long, | val id: Long, | ||||
// Purchase Order ID | |||||
val hId: Long, | val hId: Long, | ||||
// product ID | |||||
val proId: Long, | |||||
val code: String, | val code: String, | ||||
val desc: String, | |||||
val bDesc: String, | |||||
val unitId: Long, | val unitId: Long, | ||||
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 ( | |||||
var valuesWithType: MutableList<Pair<PurchaseOrderType, List<M18PurchaseOrderListValue>?>> | |||||
) | |||||
data class M18PurchaseOrderListResponse ( | data class M18PurchaseOrderListResponse ( | ||||
val values: List<M18PurchaseOrderListValue> | |||||
var values: List<M18PurchaseOrderListValue> | |||||
) | ) | ||||
data class M18PurchaseOrderListValue ( | data class M18PurchaseOrderListValue ( | ||||
val id: Long, | val id: Long, | ||||
val code: String, | val code: String, | ||||
val lastModifyDate: String, | val lastModifyDate: String, | ||||
// Defined by FP-MTMS | |||||
val type: PurchaseOrderType?, | |||||
) | ) |
@@ -5,16 +5,15 @@ import com.ffii.fpsms.api.service.ApiCallerService | |||||
import com.ffii.fpsms.m18.M18Config | import com.ffii.fpsms.m18.M18Config | ||||
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.entity.UomConversion | |||||
import com.ffii.fpsms.modules.master.enums.ShopType | import com.ffii.fpsms.modules.master.enums.ShopType | ||||
import com.ffii.fpsms.modules.master.service.ItemsService | |||||
import com.ffii.fpsms.modules.master.service.ShopService | |||||
import com.ffii.fpsms.modules.master.web.models.ItemType | |||||
import com.ffii.fpsms.modules.master.web.models.NewItemRequest | |||||
import com.ffii.fpsms.modules.master.web.models.SaveShopRequest | |||||
import com.ffii.fpsms.modules.master.service.* | |||||
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.time.LocalDate | import java.time.LocalDate | ||||
import java.time.LocalDateTime | |||||
import java.time.format.DateTimeFormatter | import java.time.format.DateTimeFormatter | ||||
@Service | @Service | ||||
@@ -23,87 +22,129 @@ open class M18MasterDataService( | |||||
val apiCallerService: ApiCallerService, | val apiCallerService: ApiCallerService, | ||||
val itemsService: ItemsService, | val itemsService: ItemsService, | ||||
val shopService: ShopService, | val shopService: ShopService, | ||||
val uomConversionService: UomConversionService, | |||||
val currencyService: CurrencyService, | |||||
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 formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss") | |||||
// Everyday update the master data | |||||
// M18 Conditions | |||||
val lastModifyDate = LocalDate.now().minusDays(1) | val lastModifyDate = LocalDate.now().minusDays(1) | ||||
val lastModifyDateConds = "lastModifyDate=largerThan=$lastModifyDate" | val lastModifyDateConds = "lastModifyDate=largerThan=$lastModifyDate" | ||||
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 = "(" + commonUtils.ListToString(seriesIdList.filterNotNull(), "seriesId=unequal=", "=or=") + ")" | |||||
val seriesIdConds = | |||||
"(" + 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 commonConds =seriesIdConds + beIdConds | |||||
// "(beId=equal=${m18Config.BEID_PF}=or=beId=equal=${m18Config.BEID_PP}=or=beId=equal=${m18Config.BEID_TOA})" | |||||
val formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss") | |||||
// M18 API | // M18 API | ||||
val M18_LOAD_ITEM_API = "/root/api/read/pro" | |||||
val M18_FETCH_ITEM_LIST_API = "/search/search" | |||||
val M18_LOAD_VENDOR_API = "/root/api/read/ven" | |||||
val M18_FETCH_VENDOR_LIST_API = "/search/search" | |||||
// --------------------------------------------- Item --------------------------------------------- /// | |||||
open fun getItems(): M18ItemListResponse? { | |||||
// seems no beId | |||||
val itemsParams = M18ItemListRequest( | |||||
params = null, | |||||
conds=seriesIdConds | |||||
// conds=commonConds | |||||
// conds = "lastModifyDate=largerThan=$lastModifyDate" | |||||
val M18_COMMON_FETCH_LIST_API = "/search/search" | |||||
val M18_COMMON_LOAD_LINE_API = "/root/api/read" | |||||
val M18_LOAD_PRODUCT_API = "${M18_COMMON_LOAD_LINE_API}/${StSearchType.PRODUCT.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_CURRENCY_API = "${M18_COMMON_LOAD_LINE_API}/${StSearchType.CURRENCY.value}" | |||||
// --------------------------------------------- Common Function --------------------------------------------- /// | |||||
private inline fun <reified T : Any> getList( | |||||
stSearch: String?, | |||||
params: String? = null, | |||||
conds: String? = null, | |||||
): T? { | |||||
val request = M18CommonListRequest( | |||||
stSearch = stSearch, | |||||
params = params, | |||||
conds = conds | |||||
) | ) | ||||
val items = apiCallerService.get<M18ItemListResponse, M18ItemListRequest>( | |||||
M18_FETCH_ITEM_LIST_API, | |||||
itemsParams | |||||
val response = apiCallerService.get<T, M18CommonListRequest>( | |||||
M18_COMMON_FETCH_LIST_API, | |||||
request | |||||
).block() | ).block() | ||||
return items | |||||
return response | |||||
} | } | ||||
open fun getItem(id: Long): M18ItemResponse? { | |||||
logger.info("M18 Item ID: $id") | |||||
val itemParams = M18ItemRequest( | |||||
private inline fun <reified T : Any> getLine( | |||||
id: Long, | |||||
params: String?, | |||||
api: String, | |||||
): T? { | |||||
val request = M18CommonLineRequest( | |||||
id = id, | id = id, | ||||
params = null, | |||||
params = params, | |||||
) | ) | ||||
val item = apiCallerService.get<M18ItemResponse, M18ItemRequest>( | |||||
M18_LOAD_ITEM_API, | |||||
itemParams | |||||
val response = apiCallerService.get<T, M18CommonLineRequest>( | |||||
api, | |||||
request | |||||
).block() | ).block() | ||||
return item | |||||
return response | |||||
} | |||||
// --------------------------------------------- Product --------------------------------------------- /// | |||||
open fun getProducts(): M18ProductListResponse? { | |||||
// seems no beId | |||||
return getList<M18ProductListResponse>( | |||||
stSearch = StSearchType.PRODUCT.value, | |||||
params = null, | |||||
conds = seriesIdConds | |||||
) | |||||
// val itemsParams = M18CommonListRequest( | |||||
// stSearch = StSearchType.PRODUCT.value, | |||||
// params = null, | |||||
// conds = seriesIdConds | |||||
// ) | |||||
// | |||||
// val items = apiCallerService.get<M18ProductListResponse, M18CommonListRequest>( | |||||
// M18_COMMON_FETCH_LIST_API, | |||||
// itemsParams | |||||
// ).block() | |||||
// | |||||
// return items | |||||
} | } | ||||
open fun saveItems() { | |||||
open fun getProduct(id: Long): M18ProductResponse? { | |||||
logger.info("M18 Product ID: $id") | |||||
return getLine<M18ProductResponse>( | |||||
id = id, | |||||
params = null, | |||||
api = M18_LOAD_PRODUCT_API | |||||
) | |||||
} | |||||
val items = getItems() | |||||
val exampleItems = listOf<Long>(10946L, 3825L) | |||||
open fun saveProducts() { | |||||
logger.info("--------------------------------------------Start - Saving M18 Products / Materials--------------------------------------------") | |||||
val items = getProducts() | |||||
val exampleProducts = listOf<Long>(10946L, 3825L) | |||||
val successList = mutableListOf<Long>() | val successList = mutableListOf<Long>() | ||||
val failList = mutableListOf<Long>() | val failList = mutableListOf<Long>() | ||||
if (items?.values != null) { | |||||
items.values.forEach { item -> | |||||
// if (item.id in exampleItems) { | |||||
val values = items?.values?.sortedBy { it.id } | |||||
if (values != null) { | |||||
values.forEach { item -> | |||||
// if (item.id in exampleProducts) { | |||||
try { | try { | ||||
val itemDetail = getItem(item.id) | |||||
if (itemDetail != null && itemDetail.data?.pro != null) { | |||||
val pro = itemDetail.data.pro[0] | |||||
val itemDetail = getProduct(item.id) | |||||
val pro = itemDetail?.data?.pro?.get(0) | |||||
val price = itemDetail?.data?.price | |||||
if (itemDetail != null && pro != null) { | |||||
val existingItem = itemsService.findByM18Id(item.id) | |||||
val saveItemRequest = NewItemRequest( | val saveItemRequest = NewItemRequest( | ||||
code = pro.code, | code = pro.code, | ||||
name = pro.desc, | name = pro.desc, | ||||
// type = if (pro.seriesId == m18Config.SERIESID_PF) ItemType.MATERIAL | |||||
// type = if (pro.seriesId == m18Config.SERIESID_PF) ProductType.MATERIAL | |||||
// else ItemType.PRODUCT, | // else ItemType.PRODUCT, | ||||
type = ItemType.MATERIAL, | type = ItemType.MATERIAL, | ||||
id = null, | |||||
id = existingItem?.id, | |||||
description = pro.desc, | description = pro.desc, | ||||
remarks = null, | remarks = null, | ||||
shelfLife = null, | shelfLife = null, | ||||
@@ -113,108 +154,95 @@ open class M18MasterDataService( | |||||
m18LastModifyDate = commonUtils.InstantToLocalDateTime(pro.lastModifyDate) | m18LastModifyDate = commonUtils.InstantToLocalDateTime(pro.lastModifyDate) | ||||
) | ) | ||||
itemsService.saveItem(saveItemRequest) | |||||
val savedItem = itemsService.saveItem(saveItemRequest) | |||||
logger.info("Processing item uom...") | |||||
// Find the item uom that ready to delete (not in m18) | |||||
val existingItemUoms = savedItem.id?.let { itemUomService.findAllByItemsId(it) } | |||||
val m18ItemUomIds = price?.map { it.id } ?: listOf() | |||||
// Delete the item uom | |||||
logger.info("Deleting item uom...") | |||||
existingItemUoms?.filter { deleteItemUom -> | |||||
m18ItemUomIds.any { it != deleteItemUom.m18Id } | |||||
}?.mapNotNull { it.id }?.let { itemUomService.deleteItemUoms(it) } | |||||
// Update the item uom | |||||
logger.info("Updating item uom...") | |||||
price?.forEach { | |||||
val itemUomRequest = ItemUomRequest( | |||||
m18UomId = it.unitId, | |||||
itemId = savedItem.id, | |||||
baseUnit = it.basicUnit, | |||||
stockUnit = it.stkUnit, | |||||
pickingUnit = it.pickUnit, | |||||
salesUnit = it.saleUnit, | |||||
purchaseUnit = it.purUnit, | |||||
price = null, | |||||
currencyId = null, | |||||
m18Id = it.id, | |||||
m18LastModifyDate = commonUtils.InstantToLocalDateTime(pro.lastModifyDate) | |||||
) | |||||
logger.info("saved item id: ${savedItem.id}") | |||||
itemUomService.saveItemUom(itemUomRequest) | |||||
} | |||||
successList.add(item.id) | successList.add(item.id) | ||||
logger.info("Success Count ${successList.size}: ${item.id} | ${pro.code} | ${pro.desc}") | logger.info("Success Count ${successList.size}: ${item.id} | ${pro.code} | ${pro.desc}") | ||||
} else { | } else { | ||||
failList.add(item.id) | failList.add(item.id) | ||||
logger.error("Fail Message: ${itemDetail?.messages?.get(0)?.msgDetail}") | logger.error("Fail Message: ${itemDetail?.messages?.get(0)?.msgDetail}") | ||||
logger.error("Fail Count ${failList.size}: Item ID ${item.id} Not Found") | |||||
logger.error("Fail Count ${failList.size}: Item ID - ${item.id} Not Found") | |||||
} | } | ||||
} catch (e: Exception) { | } catch (e: Exception) { | ||||
failList.add(item.id) | failList.add(item.id) | ||||
logger.error("M18 Item Data: ${e.message}") | |||||
logger.error("Fail Count ${failList.size}: Item ID ${item.id} Not Found") | |||||
logger.error("Exception") | |||||
logger.error("Fail Message: ${e.message}") | |||||
logger.error("Fail Count ${failList.size}: Item ID - ${item.id}") | |||||
} | } | ||||
// val itemParams = M18ItemRequest( | |||||
// id = item.id, | |||||
// params = null | |||||
// ) | |||||
// apiCallerService.get<M18ItemResponse, M18ItemRequest>( | |||||
// M18_LOAD_ITEM_API, | |||||
// itemParams | |||||
// ).subscribe( | |||||
// { response -> | |||||
// val pro = response.data.pro[0] | |||||
//// when (pro.seriesId) { | |||||
//// m18Config.SERIESID_PF, m18Config.SERIESID_PP -> { | |||||
// val saveItemRequest = NewItemRequest( | |||||
// code = pro.code, | |||||
// name = pro.desc, | |||||
// type = if (pro.seriesId == m18Config.SERIESID_PF) ItemType.MATERIAL | |||||
// else ItemType.PRODUCT, | |||||
// id = null, | |||||
// description = null, | |||||
// remarks = null, | |||||
// shelfLife = null, | |||||
// countryOfOrigin = null, | |||||
// maxQty = null, | |||||
// m18Id = pro.id | |||||
// ) | |||||
// | |||||
// itemsService.saveItem(saveItemRequest) | |||||
//// } | |||||
//// } | |||||
// | |||||
// logger.info("Count ${++count}: ${pro.id} | ${pro.code} | ${pro.desc}") | |||||
// }, | |||||
// { error -> logger.error("WebClient Error: ${error.message}") } | |||||
// ) | |||||
// } | |||||
} | } | ||||
} else { | } else { | ||||
logger.error("Items List is null. May occur errors.") | logger.error("Items List is null. May occur errors.") | ||||
} | } | ||||
logger.info("Total Success (${successList.size}): $successList") | |||||
logger.info("Total Success (${successList.size})") | |||||
if (failList.size > 0) { | if (failList.size > 0) { | ||||
logger.error("Total Fail (${failList.size}): $failList") | logger.error("Total Fail (${failList.size}): $failList") | ||||
} | } | ||||
logger.info("--------------------------------------------End - Saving M18 Products / Materials--------------------------------------------") | |||||
} | } | ||||
// --------------------------------------------- Vendor --------------------------------------------- /// | // --------------------------------------------- Vendor --------------------------------------------- /// | ||||
open fun getVendors(): M18VendorListResponse? { | open fun getVendors(): M18VendorListResponse? { | ||||
val vendorsParams = M18VendorListRequest( | |||||
return getList<M18VendorListResponse>( | |||||
stSearch = StSearchType.VENDOR.value, | |||||
params = null, | params = null, | ||||
conds = beIdConds | conds = beIdConds | ||||
// conds = "lastModifyDate=largerThan=$lastModifyDate" | |||||
) | ) | ||||
val vendors = apiCallerService.get<M18VendorListResponse, M18VendorListRequest>( | |||||
M18_FETCH_VENDOR_LIST_API, | |||||
vendorsParams | |||||
).block() | |||||
return vendors | |||||
} | } | ||||
open fun getVendor(id: Long): M18VendorResponse? { | open fun getVendor(id: Long): M18VendorResponse? { | ||||
logger.info("M18 Vendor ID: $id") | logger.info("M18 Vendor ID: $id") | ||||
val vendorParams = M18VendorRequest( | |||||
return getLine<M18VendorResponse>( | |||||
id = id, | id = id, | ||||
params = null, | params = null, | ||||
api = M18_LOAD_VENDOR_API | |||||
) | ) | ||||
val vendor = apiCallerService.get<M18VendorResponse, M18VendorRequest>( | |||||
M18_LOAD_VENDOR_API, | |||||
vendorParams | |||||
).block() | |||||
return vendor | |||||
} | } | ||||
open fun saveVendors() { | open fun saveVendors() { | ||||
logger.info("--------------------------------------------Start - Saving M18 Vendors--------------------------------------------") | |||||
val vendors = getVendors() | val vendors = getVendors() | ||||
val exampleVendors = listOf<Long>(191L) | val exampleVendors = listOf<Long>(191L) | ||||
val successList = mutableListOf<Long>() | val successList = mutableListOf<Long>() | ||||
val failList = mutableListOf<Long>() | val failList = mutableListOf<Long>() | ||||
val values = vendors?.values?.sortedBy { it.id } | |||||
if (vendors?.values != null) { | |||||
vendors.values.forEach { vendor -> | |||||
if (values != null) { | |||||
values.forEach { vendor -> | |||||
// if (vendor.id in exampleVendors) { | // if (vendor.id in exampleVendors) { | ||||
try { | try { | ||||
val vendorDetail = getVendor(vendor.id) | val vendorDetail = getVendor(vendor.id) | ||||
@@ -246,23 +274,170 @@ open class M18MasterDataService( | |||||
} else { | } else { | ||||
failList.add(vendor.id) | failList.add(vendor.id) | ||||
logger.error("Fail Message: ${vendorDetail?.messages?.get(0)?.msgDetail}") | logger.error("Fail Message: ${vendorDetail?.messages?.get(0)?.msgDetail}") | ||||
logger.error("Fail Count ${failList.size}: Vendor ID ${vendor.id} Not Found") | |||||
logger.error("Fail Count ${failList.size}: Vendor ID - ${vendor.id} Not Found") | |||||
} | } | ||||
} catch (e: Exception) { | } catch (e: Exception) { | ||||
failList.add(vendor.id) | failList.add(vendor.id) | ||||
logger.error("M18 Vendor Data: ${e.message}") | |||||
logger.error("Fail Count ${failList.size}: Vendor ID ${vendor.id} Not Found") | |||||
logger.error("Exception") | |||||
logger.error("Fail Message: ${e.message}") | |||||
logger.error("Fail Count ${failList.size}: Vendor ID - ${vendor.id}") | |||||
} | } | ||||
// } | // } | ||||
} | } | ||||
} else { | } else { | ||||
logger.error("Items List is null. May occur errors.") | |||||
logger.error("Vendor List is null. May occur errors.") | |||||
} | } | ||||
logger.info("Total Success (${successList.size}): $successList") | |||||
logger.info("Total Success (${successList.size})") | |||||
if (failList.size > 0) { | if (failList.size > 0) { | ||||
logger.error("Total Fail (${failList.size}): $failList") | logger.error("Total Fail (${failList.size}): $failList") | ||||
} | } | ||||
logger.info("--------------------------------------------End - Saving M18 Vendors--------------------------------------------") | |||||
} | |||||
// --------------------------------------------- Unit --------------------------------------------- /// | |||||
open fun getUnits(): M18UnitListResponse? { | |||||
// seems no beId | |||||
return getList<M18UnitListResponse>( | |||||
stSearch = StSearchType.UNIT.value, | |||||
params = null, | |||||
conds = null | |||||
) | |||||
} | |||||
open fun getUnit(id: Long): M18UnitResponse? { | |||||
logger.info("M18 Unit ID: $id") | |||||
return getLine<M18UnitResponse>( | |||||
id = id, | |||||
params = null, | |||||
api = M18_LOAD_UNIT_API | |||||
) | |||||
} | |||||
open fun saveUnits() { | |||||
logger.info("--------------------------------------------Start - Saving M18 Units--------------------------------------------") | |||||
val units = getUnits() | |||||
val successTransformList = mutableListOf<Long>() | |||||
val successSaveList = mutableListOf<Long>() | |||||
val failTransformList = mutableListOf<Long>() | |||||
val failSaveList = mutableListOf<Long>() | |||||
val values = units?.values?.sortedBy { it.id } | |||||
if (values != null) { | |||||
val finalUnitList = arrayListOf<UomConversion>() | |||||
// transform unit | |||||
values.forEach { unit -> | |||||
try { | |||||
val tempObject = UomConversionService.BomObject().apply { | |||||
code = unit.code | |||||
udfudesc = unit.udfudesc | |||||
lastModifyDate = unit.lastModifyDate | |||||
id = unit.id | |||||
} | |||||
finalUnitList += uomConversionService.transformItem(tempObject) | |||||
successTransformList += unit.id | |||||
logger.info("Transform Success (M18): ${unit.id}") | |||||
} catch (e: Exception) { | |||||
failTransformList.add(unit.id) | |||||
logger.error("Transform Exception") | |||||
logger.error("Transform Fail Message: ${e.message}") | |||||
logger.error("Transform Fail Count ${failTransformList.size}: Unit ID - ${unit.id}") | |||||
} | |||||
} | |||||
uomConversionService.calculateSizeInGram(finalUnitList) | |||||
finalUnitList.forEach { | |||||
try { | |||||
uomConversionService.saveUomConversion(it) | |||||
successSaveList += it.m18Id | |||||
logger.info("Save Success (M18): ${it.m18Id}") | |||||
} catch (e: Exception) { | |||||
failSaveList.add(it.m18Id) | |||||
logger.error("Save Exception") | |||||
logger.error("Save Fail Message: ${e.message}") | |||||
logger.error("Save Fail Count ${failTransformList.size}: Unit ID - ${it.m18Id}") | |||||
} | |||||
} | |||||
} else { | |||||
logger.error("Unit List is null. May occur errors.") | |||||
} | |||||
logger.info("Total Transform Success (${successTransformList.size})") | |||||
logger.info("Total Save Success (${successSaveList.size})") | |||||
if (failTransformList.size > 0) { | |||||
logger.error("Total Transform Fail (${failTransformList.size}): $failTransformList") | |||||
} | |||||
if (failSaveList.size > 0) { | |||||
logger.error("Total Save Fail (${failSaveList.size}): $failSaveList") | |||||
} | |||||
logger.info("--------------------------------------------End - Saving M18 Units--------------------------------------------") | |||||
} | |||||
// --------------------------------------------- Currency --------------------------------------------- /// | |||||
open fun getCurrencies(): M18CurrencyListResponse? { | |||||
return getList<M18CurrencyListResponse>( | |||||
stSearch = StSearchType.CURRENCY.value, | |||||
params = null, | |||||
conds = null | |||||
) | |||||
} | |||||
open fun getCurrency(id: Long): M18CurrencyResponse? { | |||||
logger.info("M18 Currency ID: $id") | |||||
return getLine<M18CurrencyResponse>( | |||||
id = id, | |||||
params = null, | |||||
api = M18_LOAD_CURRENCY_API | |||||
) | |||||
} | |||||
open fun saveCurrencies() { | |||||
logger.info("--------------------------------------------Start - Saving M18 Currencies--------------------------------------------") | |||||
val currencies = getCurrencies() | |||||
val successList = mutableListOf<Long>() | |||||
val failList = mutableListOf<Long>() | |||||
val values = currencies?.values?.sortedBy { it.id } | |||||
if (values != null) { | |||||
// save currency | |||||
values.forEach { currency -> | |||||
try { | |||||
val currencyRequest = CurrencyRequest( | |||||
id = null, | |||||
code = currency.code, | |||||
name = currency.sym, | |||||
description = currency.curDesc, | |||||
m18Id = currency.id, | |||||
m18LastModifyDate = LocalDateTime.parse(currency.lastModifyDate, formatter) | |||||
) | |||||
currencyService.saveCurrency(currencyRequest) | |||||
successList += currency.id | |||||
logger.info("Save Success (M18): ${currency.id}") | |||||
} catch (e: Exception) { | |||||
failList += currency.id | |||||
logger.error("Exception") | |||||
logger.error("Fail Message: ${e.message}") | |||||
logger.error("Fail Count ${failList.size}: Unit ID - ${currency.id}") | |||||
} | |||||
} | |||||
} else { | |||||
logger.error("Currency List is null. May occur errors.") | |||||
} | |||||
logger.info("Total Save Success (${successList.size})") | |||||
if (failList.size > 0) { | |||||
logger.error("Total Fail (${failList.size}): $failList") | |||||
} | |||||
logger.info("--------------------------------------------End - Saving Currencies--------------------------------------------") | |||||
} | } | ||||
} | } |
@@ -9,6 +9,7 @@ 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 | ||||
import com.ffii.fpsms.modules.purchaseOrder.enums.PurchaseOrderStatus | import com.ffii.fpsms.modules.purchaseOrder.enums.PurchaseOrderStatus | ||||
import com.ffii.fpsms.modules.purchaseOrder.enums.PurchaseOrderType | |||||
import com.ffii.fpsms.modules.purchaseOrder.service.PurchaseOrderLineService | import com.ffii.fpsms.modules.purchaseOrder.service.PurchaseOrderLineService | ||||
import com.ffii.fpsms.modules.purchaseOrder.service.PurchaseOrderService | import com.ffii.fpsms.modules.purchaseOrder.service.PurchaseOrderService | ||||
import com.ffii.fpsms.modules.purchaseOrder.web.model.SavePurchaseOrderLineRequest | import com.ffii.fpsms.modules.purchaseOrder.web.model.SavePurchaseOrderLineRequest | ||||
@@ -16,7 +17,6 @@ import com.ffii.fpsms.modules.purchaseOrder.web.model.SavePurchaseOrderRequest | |||||
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.time.LocalDate | |||||
import java.time.LocalDateTime | import java.time.LocalDateTime | ||||
import kotlin.reflect.full.memberProperties | import kotlin.reflect.full.memberProperties | ||||
@@ -30,28 +30,81 @@ open class M18PurchaseOrderService( | |||||
val itemsService: ItemsService, | val itemsService: ItemsService, | ||||
val shopService: ShopService, | val shopService: ShopService, | ||||
) { | ) { | ||||
val dateTimeConverter = CommonUtils() | |||||
val commonUtils = CommonUtils() | |||||
val logger: Logger = LoggerFactory.getLogger(JwtTokenUtil::class.java) | val logger: Logger = LoggerFactory.getLogger(JwtTokenUtil::class.java) | ||||
val lastModifyDate = LocalDate.now().minusDays(1) | |||||
val commonConds="(beId=equal=${m18Config.BEID_PF}=or=beId=equal=${m18Config.BEID_PP}=or=beId=equal=${m18Config.BEID_TOA})=and=lastModifyDate=largerOrEqual=${lastModifyDate}" | |||||
val lastModifyDate = LocalDateTime.now().minusMinutes(30) | |||||
// val commonConds = | |||||
// "(beId=equal=${m18Config.BEID_PF}=or=beId=equal=${m18Config.BEID_PP}=or=beId=equal=${m18Config.BEID_TOA})=and=lastModifyDate=largerOrEqual=${lastModifyDate}" | |||||
// M18 API | // M18 API | ||||
val M18_LOAD_PURCHASE_ORDER_API = "/root/api/read/po" | val M18_LOAD_PURCHASE_ORDER_API = "/root/api/read/po" | ||||
val M18_FETCH_PURCHASE_ORDER_LIST_API = "/search/search" | val M18_FETCH_PURCHASE_ORDER_LIST_API = "/search/search" | ||||
open fun getPurchaseOrders(): M18PurchaseOrderListResponse? { | |||||
val purchaseOrdersParams = M18PurchaseOrderListRequest( | |||||
// Include material po, shop po, oem po | |||||
open fun getPurchaseOrdersWithType(): M18PurchaseOrderListResponseWithType? { | |||||
val purchaseOrders = M18PurchaseOrderListResponseWithType(mutableListOf()) | |||||
// Material PO | |||||
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}" | |||||
val materialPoParams = M18PurchaseOrderListRequest( | |||||
params = null, | params = null, | ||||
conds = commonConds | |||||
conds = materialPoConds | |||||
) | ) | ||||
var purchaseOrders: M18PurchaseOrderListResponse? = null | |||||
try { | try { | ||||
purchaseOrders = apiCallerService.get<M18PurchaseOrderListResponse, M18PurchaseOrderListRequest>( | |||||
M18_FETCH_PURCHASE_ORDER_LIST_API, | |||||
purchaseOrdersParams | |||||
).block() | |||||
purchaseOrders.valuesWithType += Pair( | |||||
PurchaseOrderType.MATERIAL, | |||||
apiCallerService.get<M18PurchaseOrderListResponse, M18PurchaseOrderListRequest>( | |||||
M18_FETCH_PURCHASE_ORDER_LIST_API, | |||||
materialPoParams | |||||
).block()?.values ?: mutableListOf() | |||||
) | |||||
} catch (e: Exception) { | |||||
logger.error("Error on Function - ${e.stackTrace}") | |||||
logger.error(e.message) | |||||
} | |||||
// 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 shopPoParams = M18PurchaseOrderListRequest( | |||||
params = null, | |||||
conds = shopPoConds | |||||
) | |||||
try { | |||||
purchaseOrders.valuesWithType += Pair( | |||||
PurchaseOrderType.SHOP, apiCallerService.get<M18PurchaseOrderListResponse, M18PurchaseOrderListRequest>( | |||||
M18_FETCH_PURCHASE_ORDER_LIST_API, | |||||
shopPoParams | |||||
).block()?.values ?: mutableListOf() | |||||
) | |||||
} catch (e: Exception) { | |||||
logger.error("Error on Function - ${e.stackTrace}") | |||||
logger.error(e.message) | |||||
} | |||||
// 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 oemPoParams = M18PurchaseOrderListRequest( | |||||
params = null, | |||||
conds = oemPoConds | |||||
) | |||||
try { | |||||
purchaseOrders.valuesWithType += Pair( | |||||
PurchaseOrderType.OEM, apiCallerService.get<M18PurchaseOrderListResponse, M18PurchaseOrderListRequest>( | |||||
M18_FETCH_PURCHASE_ORDER_LIST_API, | |||||
oemPoParams | |||||
).block()?.values | |||||
) | |||||
} catch (e: Exception) { | } catch (e: Exception) { | ||||
logger.error("Error on Function - ${e.stackTrace}") | logger.error("Error on Function - ${e.stackTrace}") | ||||
logger.error(e.message) | logger.error(e.message) | ||||
@@ -81,7 +134,8 @@ open class M18PurchaseOrderService( | |||||
} | } | ||||
open fun savePurchaseOrders() { | open fun savePurchaseOrders() { | ||||
val purchaseOrders = getPurchaseOrders() | |||||
logger.info("--------------------------------------------Start - Saving M18 Purchase Order--------------------------------------------") | |||||
val purchaseOrdersWithType = getPurchaseOrdersWithType() | |||||
val examplePurchaseOrders = listOf<Long>(4764034L) | val examplePurchaseOrders = listOf<Long>(4764034L) | ||||
val successList = mutableListOf<Long>() | val successList = mutableListOf<Long>() | ||||
@@ -89,180 +143,234 @@ open class M18PurchaseOrderService( | |||||
val failList = mutableListOf<Long>() | val failList = mutableListOf<Long>() | ||||
val failDetailList = mutableListOf<Long>() | val failDetailList = mutableListOf<Long>() | ||||
if (purchaseOrders != null) { | |||||
val poRefType = "Purchase Order" | |||||
val poLineRefType = "Purchase Order Line" | |||||
if (purchaseOrdersWithType != null) { | |||||
// Loop for Purchase Orders (values) | // Loop for Purchase Orders (values) | ||||
purchaseOrders.values.forEach { purchaseOrder -> | |||||
val purchaseOrderDetail = getPurchaseOrder(purchaseOrder.id) | |||||
var purchaseOrderId: Long? = null //FP-MTMS | |||||
// Process for Purchase Order (mainPo) | |||||
// Assume only one PO in the PO (search by PO ID) | |||||
val mainPo = purchaseOrderDetail?.data?.mainPo?.get(0) | |||||
val pot = purchaseOrderDetail?.data?.pot | |||||
// purchase_order + m18_data_log table | |||||
if (mainPo != null) { | |||||
val poRefType = "Purchase Order" | |||||
// Find the latest m18 data log by m18 id & type | |||||
val latestM18DataLog = m18DataLogService.findLatestM18DataLog(purchaseOrder.id, poRefType) | |||||
// Save to m18_data_log table | |||||
val mainPoJson = | |||||
mainPo::class.memberProperties.associate { prop -> prop.name to prop.getter.call(mainPo) } | |||||
.toMutableMap() | |||||
val saveM18PurchaseOrderLogRequest = SaveM18DataLogRequest( | |||||
id = null, | |||||
refType = poRefType, | |||||
m18Id = purchaseOrder.id, | |||||
m18LastModifyDate = dateTimeConverter.InstantToLocalDateTime(mainPo.lastModifyDate), | |||||
dataLog = mainPoJson, | |||||
status = true | |||||
) | |||||
val saveM18PurchaseOrderLog = m18DataLogService.saveM18DataLog(saveM18PurchaseOrderLogRequest) | |||||
try { | |||||
// Find the purchase_order if exist | |||||
val existingPurchaseOrder = latestM18DataLog?.id?.let { purchaseOrderService.findPurchaseOrderByM18Id(it) } | |||||
// Save to purchase_order table | |||||
val supplierId = shopService.findByM18Id(mainPo.venId)?.id | |||||
val savePurchaseOrderRequest = SavePurchaseOrderRequest( | |||||
id = existingPurchaseOrder?.id, | |||||
code = mainPo.code, | |||||
supplierId = supplierId, | |||||
orderDate = dateTimeConverter.InstantToLocalDateTime(mainPo.tDate), | |||||
estimatedArrivalDate = dateTimeConverter.InstantToLocalDateTime(mainPo.dDate), | |||||
completeDate = null, | |||||
status = PurchaseOrderStatus.PENDING.value, | |||||
m18DataLogId = saveM18PurchaseOrderLog.id, | |||||
) | |||||
val savePurchaseOrderResponse = purchaseOrderService.savePurchaseOrder(savePurchaseOrderRequest) | |||||
purchaseOrderId = savePurchaseOrderResponse.id | |||||
successList.add(purchaseOrder.id) | |||||
} catch (e: Exception) { | |||||
failList.add(purchaseOrder.id) | |||||
logger.error("Error on Function - ${e.stackTrace} | Type: Purchase Order | M18 ID: ${purchaseOrder.id} | Different? ${mainPo.id}") | |||||
logger.error(e.message) | |||||
val errorSaveM18PurchaseOrderLogRequest = SaveM18DataLogRequest( | |||||
id = saveM18PurchaseOrderLogRequest.id, | |||||
refType = "Purchase Order", | |||||
m18Id = purchaseOrder.id, | |||||
m18LastModifyDate = dateTimeConverter.InstantToLocalDateTime(mainPo.lastModifyDate), | |||||
dataLog = mainPoJson, | |||||
status = false | |||||
) | |||||
m18DataLogService.saveM18DataLog(errorSaveM18PurchaseOrderLogRequest) | |||||
} | |||||
purchaseOrdersWithType.valuesWithType.forEach { purchaseOrderWithType -> | |||||
val type = purchaseOrderWithType.first | |||||
val purchaseOrders = purchaseOrderWithType.second | |||||
if (purchaseOrders != null) { | |||||
purchaseOrders.forEach { purchaseOrder -> | |||||
val purchaseOrderDetail = getPurchaseOrder(purchaseOrder.id) | |||||
// purchase_order_line + m18_data_log | |||||
if (pot != null) { | |||||
// Loop for Purchase Order Lines (pot) | |||||
pot.forEach { line -> | |||||
val poLineRefType = "Purchase Order Line" | |||||
var purchaseOrderId: Long? = null //FP-MTMS | |||||
// Process for Purchase Order (mainpo) | |||||
// Assume only one PO in the PO (search by PO ID) | |||||
val mainpo = purchaseOrderDetail?.data?.mainpo?.get(0) | |||||
val pot = purchaseOrderDetail?.data?.pot | |||||
// purchase_order + m18_data_log table | |||||
if (mainpo != null) { | |||||
// Find the latest m18 data log by m18 id & type | // Find the latest m18 data log by m18 id & type | ||||
val latestM18DataLog = m18DataLogService.findLatestM18DataLog(line.id, poLineRefType) | |||||
logger.info("${poRefType}: Finding For Latest M18 Data Log...") | |||||
val latestPurchaseOrderLog = | |||||
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 | ||||
val lineJson = | |||||
line::class.memberProperties.associate { prop -> prop.name to prop.getter.call(line) } | |||||
logger.info("${poRefType}: Saving for M18 Data Log...") | |||||
val mainpoJson = | |||||
mainpo::class.memberProperties.associate { prop -> prop.name to prop.getter.call(mainpo) } | |||||
.toMutableMap() | .toMutableMap() | ||||
val saveM18PurchaseOrderLineLogRequest = SaveM18DataLogRequest( | |||||
val saveM18PurchaseOrderLogRequest = SaveM18DataLogRequest( | |||||
id = null, | id = null, | ||||
refType = poLineRefType, | |||||
m18Id = line.id, | |||||
m18LastModifyDate = dateTimeConverter.InstantToLocalDateTime(mainPo.lastModifyDate), | |||||
dataLog = lineJson, | |||||
refType = poRefType, | |||||
m18Id = purchaseOrder.id, | |||||
m18LastModifyDate = commonUtils.InstantToLocalDateTime(mainpo.lastModifyDate), | |||||
dataLog = mainpoJson, | |||||
status = true | status = true | ||||
) | ) | ||||
val saveM18PurchaseOrderLineLog = m18DataLogService.saveM18DataLog(saveM18PurchaseOrderLineLogRequest) | |||||
val item = itemsService.findByM18Id(line.id) | |||||
logger.info("Item ID: ${item?.id}") | |||||
val saveM18PurchaseOrderLog = | |||||
m18DataLogService.saveM18DataLog(saveM18PurchaseOrderLogRequest) | |||||
// logger.info("${poRefType}: Saved M18 Data Log. ID: ${saveM18PurchaseOrderLog.id}") | |||||
try { | try { | ||||
// Find the purchase_order_line if exist | |||||
val existingPurchaseOrderLine = latestM18DataLog?.id?.let { purchaseOrderLineService.findPurchaseOrderLineByM18Id(it) } | |||||
// Save to purchase_order_line table | |||||
val savePurchaseOrderLineRequest = SavePurchaseOrderLineRequest( | |||||
id = existingPurchaseOrderLine?.id, | |||||
itemId = item?.id, | |||||
uomId = null, | |||||
purchaseOrderId = purchaseOrderId, | |||||
qty = line.qty, | |||||
price = line.amt, | |||||
priceUnit = null, | |||||
status = existingPurchaseOrderLine?.status?.value ?: PurchaseOrderLineStatus.PENDING.value, | |||||
m18DataLogId = saveM18PurchaseOrderLineLog.id, | |||||
// Find the purchase_order if exist | |||||
logger.info("${poRefType}: Finding exising purchase order...") | |||||
val existingPurchaseOrder = | |||||
latestPurchaseOrderLog?.id?.let { purchaseOrderService.findPurchaseOrderByM18Id(it) } | |||||
logger.info("${poRefType}: Exising purchase order ID: ${existingPurchaseOrder?.id}") | |||||
// Save to purchase_order table | |||||
logger.info("${poRefType}: Saving purchase order...") | |||||
val supplierId = shopService.findByM18Id(mainpo.venId)?.id | |||||
val savePurchaseOrderRequest = SavePurchaseOrderRequest( | |||||
id = existingPurchaseOrder?.id, | |||||
code = mainpo.code, | |||||
supplierId = supplierId, | |||||
orderDate = commonUtils.InstantToLocalDateTime(mainpo.tDate), | |||||
estimatedArrivalDate = commonUtils.InstantToLocalDateTime(mainpo.dDate), | |||||
completeDate = null, | |||||
status = PurchaseOrderStatus.PENDING.value, | |||||
type = type.value, | |||||
m18DataLogId = saveM18PurchaseOrderLog.id, | |||||
) | ) | ||||
purchaseOrderLineService.savePurchaseOrderLine(savePurchaseOrderLineRequest) | |||||
val savePurchaseOrderResponse = | |||||
purchaseOrderService.savePurchaseOrder(savePurchaseOrderRequest) | |||||
purchaseOrderId = savePurchaseOrderResponse.id | |||||
successList.add(purchaseOrder.id) | |||||
logger.info("${poRefType}: Saved purchase order. ID: ${savePurchaseOrderResponse.id} | M18 ${poRefType} ID: ${purchaseOrder.id}") | |||||
} catch (e: Exception) { | } catch (e: Exception) { | ||||
failDetailList.add(line.id) | |||||
logger.error("Error on Function - ${e.stackTrace} | Type: Purchase Order Line | M18 ID: ${line.id}") | |||||
failList.add(purchaseOrder.id) | |||||
logger.error("${poRefType}: Saving Failure!") | |||||
logger.error("Error on Function - ${e.stackTrace} | Type: ${poRefType} | M18 ID: ${purchaseOrder.id} | Different? ${mainpo.id}") | |||||
logger.error(e.message) | logger.error(e.message) | ||||
val errorSaveM18PurchaseOrderLineLogRequest = SaveM18DataLogRequest( | |||||
id = saveM18PurchaseOrderLineLog.id, | |||||
refType = "Purchase Order", | |||||
m18Id = line.id, | |||||
m18LastModifyDate = dateTimeConverter.InstantToLocalDateTime(mainPo.lastModifyDate), | |||||
dataLog = lineJson, | |||||
val errorSaveM18PurchaseOrderLogRequest = SaveM18DataLogRequest( | |||||
id = saveM18PurchaseOrderLogRequest.id, | |||||
refType = poRefType, | |||||
m18Id = purchaseOrder.id, | |||||
m18LastModifyDate = commonUtils.InstantToLocalDateTime(mainpo.lastModifyDate), | |||||
dataLog = mainpoJson, | |||||
status = false | status = false | ||||
) | ) | ||||
m18DataLogService.saveM18DataLog(errorSaveM18PurchaseOrderLineLogRequest) | |||||
m18DataLogService.saveM18DataLog(errorSaveM18PurchaseOrderLogRequest) | |||||
logger.error("${poRefType}: M18 Data Log Updated! Please see the error. ID: ${saveM18PurchaseOrderLogRequest.id}") | |||||
} | } | ||||
// purchase_order_line + m18_data_log | |||||
if (pot != null) { | |||||
// Loop for Purchase Order Lines (pot) | |||||
pot.forEach { line -> | |||||
// // Find the latest m18 data log by m18 id & type | |||||
logger.info("${poLineRefType}: Finding For Latest M18 Data Log...") | |||||
val latestPurchaseOrderLineLog = | |||||
m18DataLogService.findLatestM18DataLog(line.id, poLineRefType) | |||||
// logger.info("${poLineRefType}: Latest M18 Data Log ID: ${latestPurchaseOrderLineLog?.id}") | |||||
// Save to m18_data_log table | |||||
logger.info("${poLineRefType}: Saving for M18 Data Log...") | |||||
val lineJson = | |||||
line::class.memberProperties.associate { prop -> | |||||
prop.name to prop.getter.call( | |||||
line | |||||
) | |||||
} | |||||
.toMutableMap() | |||||
val saveM18PurchaseOrderLineLogRequest = SaveM18DataLogRequest( | |||||
id = null, | |||||
refType = poLineRefType, | |||||
m18Id = line.id, | |||||
m18LastModifyDate = commonUtils.InstantToLocalDateTime(mainpo.lastModifyDate), | |||||
dataLog = lineJson, | |||||
status = true | |||||
) | |||||
val saveM18PurchaseOrderLineLog = | |||||
m18DataLogService.saveM18DataLog(saveM18PurchaseOrderLineLogRequest) | |||||
// logger.info("${poLineRefType}: Saved M18 Data Log. ID: ${saveM18PurchaseOrderLineLog.id}") | |||||
logger.info("${poLineRefType}: Finding item...") | |||||
val item = itemsService.findByM18Id(line.proId) | |||||
logger.info("${poLineRefType}: Item ID: ${item?.id} | M18 Item ID: ${line.proId}") | |||||
try { | |||||
// Find the purchase_order_line if exist | |||||
logger.info("${poLineRefType}: Finding exising purchase order line...") | |||||
val existingPurchaseOrderLine = latestPurchaseOrderLineLog?.id?.let { | |||||
purchaseOrderLineService.findPurchaseOrderLineByM18Id(it) | |||||
} | |||||
logger.info("${poLineRefType}: Exising purchase order line ID: ${existingPurchaseOrderLine?.id}") | |||||
// Save to purchase_order_line table | |||||
logger.info("${poLineRefType}: Saving purchase order line...") | |||||
val savePurchaseOrderLineRequest = SavePurchaseOrderLineRequest( | |||||
id = existingPurchaseOrderLine?.id, | |||||
itemId = item?.id, | |||||
uomId = null, | |||||
purchaseOrderId = purchaseOrderId, | |||||
qty = line.qty, | |||||
price = line.amt, | |||||
m18CurrencyId = line.curId, | |||||
status = existingPurchaseOrderLine?.status?.value | |||||
?: PurchaseOrderLineStatus.PENDING.value, | |||||
m18DataLogId = saveM18PurchaseOrderLineLog.id, | |||||
) | |||||
val savePurchaseOrderLineResponse = | |||||
purchaseOrderLineService.savePurchaseOrderLine(savePurchaseOrderLineRequest) | |||||
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}") | |||||
} catch (e: Exception) { | |||||
failDetailList.add(line.id) | |||||
logger.error("${poLineRefType}: Saving Failure!") | |||||
logger.error("Error on Function - ${e.stackTrace} | Type: ${poLineRefType} | M18 ID: ${line.id}") | |||||
logger.error(e.message) | |||||
val errorSaveM18PurchaseOrderLineLogRequest = SaveM18DataLogRequest( | |||||
id = saveM18PurchaseOrderLineLog.id, | |||||
refType = "${poRefType}", | |||||
m18Id = line.id, | |||||
m18LastModifyDate = commonUtils.InstantToLocalDateTime(mainpo.lastModifyDate), | |||||
dataLog = lineJson, | |||||
status = false | |||||
) | |||||
m18DataLogService.saveM18DataLog(errorSaveM18PurchaseOrderLineLogRequest) | |||||
logger.error("${poLineRefType}: M18 Data Log Updated! Please see the error. ID: ${saveM18PurchaseOrderLineLog.id}") | |||||
} | |||||
} | |||||
} else { | |||||
// pot | |||||
logger.error("${poLineRefType}: Saving Failure!") | |||||
val saveM18PurchaseOrderLineLogRequest = SaveM18DataLogRequest( | |||||
id = null, | |||||
refType = "${poLineRefType}", | |||||
m18Id = purchaseOrder.id, | |||||
m18LastModifyDate = commonUtils.InstantToLocalDateTime(mainpo.lastModifyDate), | |||||
dataLog = mutableMapOf(Pair("Error Message", "${poLineRefType} is null")), | |||||
status = false | |||||
) | |||||
val errorLog = m18DataLogService.saveM18DataLog(saveM18PurchaseOrderLineLogRequest) | |||||
logger.error("${poLineRefType}: M18 Data Log Updated! Please see the error. ID: ${errorLog.id}") | |||||
} | |||||
} else { | |||||
// mainpo | |||||
logger.error("${poRefType}: Saving Failure!") | |||||
val saveM18DataLogRequest = SaveM18DataLogRequest( | |||||
id = null, | |||||
refType = "${poRefType}", | |||||
m18Id = purchaseOrder.id, | |||||
// m18LastModifyDate = if(mainpo?.lastModifyDate != null) commonUtils.InstantToLocalDateTime(mainpo.lastModifyDate) else LocalDateTime.now(), | |||||
m18LastModifyDate = LocalDateTime.now(), | |||||
dataLog = mutableMapOf(Pair("Error Message", "${poRefType} is null")), | |||||
status = false | |||||
) | |||||
val errorLog = m18DataLogService.saveM18DataLog(saveM18DataLogRequest) | |||||
logger.error("${poLineRefType}: M18 Data Log Updated! Please see the error. ID: ${errorLog.id}") | |||||
} | } | ||||
} else { | |||||
val saveM18PurchaseOrderLineLogRequest = SaveM18DataLogRequest( | |||||
id = null, | |||||
refType = "Purchase Order Line", | |||||
m18Id = purchaseOrder.id, | |||||
m18LastModifyDate = dateTimeConverter.InstantToLocalDateTime(mainPo.lastModifyDate), | |||||
dataLog = mutableMapOf(Pair("Error Message", "Purchase Order Line is null")), | |||||
status = false | |||||
) | |||||
m18DataLogService.saveM18DataLog(saveM18PurchaseOrderLineLogRequest) | |||||
} | } | ||||
} else { | } else { | ||||
val saveM18DataLogRequest = SaveM18DataLogRequest( | |||||
id = null, | |||||
refType = "Purchase Order", | |||||
m18Id = purchaseOrder.id, | |||||
// m18LastModifyDate = if(mainPo?.lastModifyDate != null) dateTimeConverter.InstantToLocalDateTime(mainPo.lastModifyDate) else LocalDateTime.now(), | |||||
m18LastModifyDate = LocalDateTime.now(), | |||||
dataLog = mutableMapOf(Pair("Error Message", "Purchase Order is null")), | |||||
status = false | |||||
) | |||||
m18DataLogService.saveM18DataLog(saveM18DataLogRequest) | |||||
logger.error("${poRefType} List is null. May occur errors.") | |||||
} | } | ||||
} | } | ||||
} else { | } else { | ||||
logger.error("Purchase Order List is null. May occur errors.") | |||||
logger.error("${poRefType} List is null. May occur errors.") | |||||
} | } | ||||
// End of save. Check result | // End of save. Check result | ||||
logger.info("Total Success (Purchase Order) (${successList.size}): $successList") | |||||
logger.info("Total Success (${poRefType}) (${successList.size}): $successList") | |||||
if (failList.size > 0) { | if (failList.size > 0) { | ||||
logger.error("Total Fail (Purchase Order) (${failList.size}): $failList") | |||||
logger.error("Total Fail (${poRefType}) (${failList.size}): $failList") | |||||
} | } | ||||
logger.info("Total Success (Purchase Order Line) (${successDetailList.size}): $successDetailList") | |||||
logger.info("Total Success (${poLineRefType}) (${successDetailList.size}): $successDetailList") | |||||
if (failDetailList.size > 0) { | if (failDetailList.size > 0) { | ||||
logger.error("Total Fail (Purchase Order Line) (${failDetailList.size}): $failDetailList") | |||||
logger.error("Total Fail (${poLineRefType}) (${failDetailList.size}): $failDetailList") | |||||
} | } | ||||
logger.info("--------------------------------------------End - Saving M18 Purchase Order--------------------------------------------") | |||||
} | } | ||||
} | } |
@@ -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, | ||||
@@ -7,8 +7,8 @@ import java.time.ZoneId | |||||
open class CommonUtils() { | open class CommonUtils() { | ||||
open fun InstantToLocalDateTime(timestamp: Long):LocalDateTime { | open fun InstantToLocalDateTime(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("ZoneId: ${ZoneId.systemDefault()}") | |||||
// println("ZoneId: ${ZoneId.of("Asia/Hong_Kong")}") | |||||
println("Timestamp: $timestamp") | println("Timestamp: $timestamp") | ||||
println("Local Date Time: $localDateTime") | println("Local Date Time: $localDateTime") | ||||
return localDateTime | return localDateTime | ||||
@@ -4,27 +4,45 @@ 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.modules.master.entity.Shop | |||||
import com.ffii.fpsms.modules.master.entity.ShopRepository | |||||
import com.ffii.fpsms.modules.master.entity.projections.SearchId | |||||
import com.ffii.fpsms.modules.master.enums.ShopType | |||||
import com.ffii.fpsms.modules.master.service.ShopService | |||||
import org.slf4j.Logger | import org.slf4j.Logger | ||||
import org.slf4j.LoggerFactory | import org.slf4j.LoggerFactory | ||||
import org.springframework.web.bind.annotation.GetMapping | import org.springframework.web.bind.annotation.GetMapping | ||||
import org.springframework.web.bind.annotation.RequestMapping | import org.springframework.web.bind.annotation.RequestMapping | ||||
import org.springframework.web.bind.annotation.RequestParam | |||||
import org.springframework.web.bind.annotation.RestController | import org.springframework.web.bind.annotation.RestController | ||||
@RestController | @RestController | ||||
@RequestMapping("/m18") | @RequestMapping("/m18") | ||||
class M18TestController ( | class M18TestController ( | ||||
private val shopRepository: ShopRepository, | |||||
private val shopService: ShopService, | |||||
private val m18MasterDataService: M18MasterDataService, | private val m18MasterDataService: M18MasterDataService, | ||||
private val m18PurchaseOrderService: M18PurchaseOrderService, | private val m18PurchaseOrderService: M18PurchaseOrderService, | ||||
private val m18Config: M18Config, | private val m18Config: M18Config, | ||||
) { | ) { | ||||
var logger: Logger = LoggerFactory.getLogger(JwtTokenUtil::class.java) | var logger: Logger = LoggerFactory.getLogger(JwtTokenUtil::class.java) | ||||
@GetMapping("/test1") | |||||
fun test1(): List<Long>? { | |||||
return shopService.findVendorIdsByCodeRegexp(listOf("P06", "P07")) | |||||
} | |||||
@GetMapping("/test2") | |||||
fun test2(): List<Long>? { | |||||
return shopRepository.findIdsByCodeRegexpAndTypeAndDeletedIsFalse("P06|P07", ShopType.SUPPLIER.value) | |||||
} | |||||
// --------------------------------------------- Master Data --------------------------------------------- /// | // --------------------------------------------- Master Data --------------------------------------------- /// | ||||
@GetMapping("/item") | |||||
fun m18Items() { | |||||
@GetMapping("/product") | |||||
fun m18Products() { | |||||
logger.info("Access token: ${m18Config.ACCESS_TOKEN}") | logger.info("Access token: ${m18Config.ACCESS_TOKEN}") | ||||
m18MasterDataService.saveItems() | |||||
m18MasterDataService.saveProducts() | |||||
} | } | ||||
@GetMapping("/vendor") | @GetMapping("/vendor") | ||||
@@ -33,6 +51,18 @@ class M18TestController ( | |||||
m18MasterDataService.saveVendors() | m18MasterDataService.saveVendors() | ||||
} | } | ||||
@GetMapping("/unit") | |||||
fun m18Unit() { | |||||
logger.info("Access token: ${m18Config.ACCESS_TOKEN}") | |||||
m18MasterDataService.saveUnits() | |||||
} | |||||
@GetMapping("/currency") | |||||
fun m18Currency() { | |||||
logger.info("Access token: ${m18Config.ACCESS_TOKEN}") | |||||
m18MasterDataService.saveCurrencies() | |||||
} | |||||
// --------------------------------------------- Purchase Order --------------------------------------------- /// | // --------------------------------------------- Purchase Order --------------------------------------------- /// | ||||
@GetMapping("/po") | @GetMapping("/po") | ||||
fun m18PO() { | fun m18PO() { | ||||
@@ -0,0 +1,34 @@ | |||||
package com.ffii.fpsms.modules.master.entity | |||||
import com.ffii.core.entity.BaseEntity | |||||
import jakarta.persistence.Column | |||||
import jakarta.persistence.Entity | |||||
import jakarta.persistence.Table | |||||
import jakarta.validation.constraints.NotNull | |||||
import jakarta.validation.constraints.Size | |||||
import java.time.LocalDateTime | |||||
@Entity | |||||
@Table(name = "currency") | |||||
open class Currency : BaseEntity<Long>() { | |||||
@Size(max = 30) | |||||
@NotNull | |||||
@Column(name = "code", nullable = false, length = 30) | |||||
open var code: String? = null | |||||
@Size(max = 30) | |||||
@NotNull | |||||
@Column(name = "name", nullable = false, length = 30) | |||||
open var name: String? = null | |||||
@Size(max = 100) | |||||
@NotNull | |||||
@Column(name = "description", nullable = false, length = 100) | |||||
open var description: String? = null | |||||
@Column(name = "m18Id") | |||||
open var m18Id: Long? = null | |||||
@Column(name = "m18LastModifyDate") | |||||
open var m18LastModifyDate: LocalDateTime? = null | |||||
} |
@@ -0,0 +1,11 @@ | |||||
package com.ffii.fpsms.modules.master.entity | |||||
import com.ffii.core.support.AbstractRepository | |||||
import org.springframework.stereotype.Repository | |||||
@Repository | |||||
interface CurrencyRepository: AbstractRepository<Currency, Long> { | |||||
fun findByIdAndDeletedIsFalse (id: Long): Currency? | |||||
fun findByM18IdAndDeletedIsFalse (m18Id: Long): Currency? | |||||
} |
@@ -0,0 +1,55 @@ | |||||
package com.ffii.fpsms.modules.master.entity | |||||
import com.ffii.core.entity.BaseEntity | |||||
import jakarta.persistence.* | |||||
import jakarta.validation.constraints.NotNull | |||||
import java.math.BigDecimal | |||||
import java.time.LocalDateTime | |||||
@Entity | |||||
@Table(name = "item_uom") | |||||
open class ItemUom : BaseEntity<Long>() { | |||||
@NotNull | |||||
@ManyToOne(fetch = FetchType.LAZY, optional = false) | |||||
@JoinColumn(name = "uomId", nullable = false) | |||||
open var uom: UomConversion? = null | |||||
@NotNull | |||||
@ManyToOne(fetch = FetchType.LAZY, optional = false) | |||||
@JoinColumn(name = "itemId", nullable = false) | |||||
open var item: Items? = null | |||||
@NotNull | |||||
@Column(name = "baseUnit", nullable = false) | |||||
open var baseUnit: Boolean? = null | |||||
@NotNull | |||||
@Column(name = "stockUnit", nullable = false) | |||||
open var stockUnit: Boolean? = null | |||||
@NotNull | |||||
@Column(name = "pickingUnit", nullable = false) | |||||
open var pickingUnit: Boolean? = null | |||||
@NotNull | |||||
@Column(name = "salesUnit", nullable = false) | |||||
open var salesUnit: Boolean? = null | |||||
@NotNull | |||||
@Column(name = "purchaseUnit", nullable = false) | |||||
open var purchaseUnit: Boolean? = null | |||||
@Column(name = "price", precision = 14, scale = 2) | |||||
open var price: BigDecimal? = null | |||||
@ManyToOne(fetch = FetchType.LAZY) | |||||
@JoinColumn(name = "currencyId") | |||||
open var currency: Currency? = null | |||||
@NotNull | |||||
@Column(name = "m18Id", nullable = false) | |||||
open var m18Id: Long? = null | |||||
@Column(name = "m18LastModifyDate") | |||||
open var m18LastModifyDate: LocalDateTime? = null | |||||
} |
@@ -0,0 +1,18 @@ | |||||
package com.ffii.fpsms.modules.master.entity | |||||
import com.ffii.core.support.AbstractRepository | |||||
import org.springframework.stereotype.Repository | |||||
import java.io.Serializable | |||||
@Repository | |||||
interface ItemUomRespository : AbstractRepository<ItemUom, Long> { | |||||
fun findAllByItemIdAndDeletedIsFalse(itemId: Serializable): List<ItemUom> | |||||
fun findByIdAndDeletedIsFalse(id: Serializable): ItemUom? | |||||
fun findByM18IdAndDeletedIsFalse(m18Id: Serializable): ItemUom? | |||||
fun deleteAllByIdIn(id: List<Serializable>) | |||||
fun findByItemIdAndPurchaseUnitIsTrueAndDeletedIsFalse(itemId: Serializable): ItemUom? | |||||
} |
@@ -1,7 +1,6 @@ | |||||
package com.ffii.fpsms.modules.master.entity | package com.ffii.fpsms.modules.master.entity | ||||
import com.ffii.core.entity.BaseEntity | import com.ffii.core.entity.BaseEntity | ||||
import com.ffii.fpsms.modules.master.web.models.ItemType | |||||
import jakarta.persistence.* | import jakarta.persistence.* | ||||
import jakarta.validation.constraints.NotNull | import jakarta.validation.constraints.NotNull | ||||
import java.time.LocalDateTime | import java.time.LocalDateTime | ||||
@@ -41,4 +40,7 @@ open class Items : BaseEntity<Long>() { | |||||
@Column(name = "m18LastModifyDate") | @Column(name = "m18LastModifyDate") | ||||
open var m18LastModifyDate: LocalDateTime? = null | open var m18LastModifyDate: LocalDateTime? = null | ||||
@OneToMany(mappedBy = "item", cascade = [CascadeType.ALL], orphanRemoval = true) | |||||
open var itemUoms: MutableSet<ItemUom> = mutableSetOf() | |||||
} | } |
@@ -1,6 +1,9 @@ | |||||
package com.ffii.fpsms.modules.master.entity | package com.ffii.fpsms.modules.master.entity | ||||
import com.ffii.core.support.AbstractRepository | import com.ffii.core.support.AbstractRepository | ||||
import com.ffii.fpsms.modules.master.entity.projections.SearchId | |||||
import com.ffii.fpsms.modules.master.enums.ShopType | |||||
import org.springframework.data.jpa.repository.Query | |||||
import org.springframework.stereotype.Repository | import org.springframework.stereotype.Repository | ||||
@Repository | @Repository | ||||
@@ -10,4 +13,14 @@ interface ShopRepository : AbstractRepository<Shop, Long> { | |||||
fun findByIdAndDeletedIsFalse(id: Long): Shop? | fun findByIdAndDeletedIsFalse(id: Long): Shop? | ||||
fun findByM18IdAndDeletedIsFalse(m18Id: Long): Shop? | fun findByM18IdAndDeletedIsFalse(m18Id: Long): Shop? | ||||
@Query( | |||||
nativeQuery = true, | |||||
value = "select s.id from Shop s where s.code regexp ?1 and s.type = ?2 and s.deleted = false") | |||||
fun findIdsByCodeRegexpAndTypeAndDeletedIsFalse(codeRegexp: String, type: String): List<Long>? | |||||
@Query( | |||||
nativeQuery = true, | |||||
value = "select s.id from Shop s where s.code not regexp ?1 and s.type = ?2 and s.deleted = false") | |||||
fun findIdsByCodeNotRegexpAndTypeAndDeletedIsFalse(codeNotRegexp: String, type: String): List<Long>? | |||||
} | } |
@@ -8,5 +8,8 @@ import java.time.LocalDateTime | |||||
interface UomConversionRepository : AbstractRepository<UomConversion, Long> { | interface UomConversionRepository : AbstractRepository<UomConversion, Long> { | ||||
//fun importFromM18(): ArrayList<UomConversion>; | //fun importFromM18(): ArrayList<UomConversion>; | ||||
fun findByIdAndDeletedFalse(id: Long): UomConversion; | fun findByIdAndDeletedFalse(id: Long): UomConversion; | ||||
fun findByM18IdAndDeletedFalse(m18Id: Long): UomConversion?; | |||||
fun findByLastModifyDateAndM18IdAndDeletedFalse(lastModifyDate: LocalDateTime, m18Id: Long): UomConversion?; | fun findByLastModifyDateAndM18IdAndDeletedFalse(lastModifyDate: LocalDateTime, m18Id: Long): UomConversion?; | ||||
} | } |
@@ -0,0 +1,5 @@ | |||||
package com.ffii.fpsms.modules.master.entity.projections | |||||
interface SearchId { | |||||
val id: Long | |||||
} |
@@ -0,0 +1,33 @@ | |||||
package com.ffii.fpsms.modules.master.service | |||||
import com.ffii.fpsms.modules.master.entity.Currency | |||||
import com.ffii.fpsms.modules.master.entity.CurrencyRepository | |||||
import com.ffii.fpsms.modules.master.web.models.CurrencyRequest | |||||
import org.springframework.stereotype.Service | |||||
@Service | |||||
open class CurrencyService( | |||||
val currencyRepository: CurrencyRepository, | |||||
) { | |||||
open fun findById(id: Long): Currency? { | |||||
return currencyRepository.findByIdAndDeletedIsFalse(id); | |||||
} | |||||
open fun findByM18Id(m18Id: Long): Currency? { | |||||
return currencyRepository.findByM18IdAndDeletedIsFalse(m18Id); | |||||
} | |||||
open fun saveCurrency(request: CurrencyRequest): Currency { | |||||
val currency = request.m18Id?.let { findByM18Id(it) } ?: request.id?.let { findById(it) } ?: Currency() | |||||
currency.apply { | |||||
code = request.code | |||||
name = request.name | |||||
description = request.description | |||||
m18Id = request.m18Id | |||||
m18LastModifyDate = request.m18LastModifyDate | |||||
} | |||||
return currencyRepository.saveAndFlush(currency) | |||||
} | |||||
} |
@@ -0,0 +1,57 @@ | |||||
package com.ffii.fpsms.modules.master.service | |||||
import com.ffii.fpsms.modules.master.entity.ItemUom | |||||
import com.ffii.fpsms.modules.master.entity.ItemUomRespository | |||||
import com.ffii.fpsms.modules.master.web.models.ItemUomRequest | |||||
import org.springframework.stereotype.Service | |||||
import kotlin.jvm.optionals.getOrNull | |||||
@Service | |||||
open class ItemUomService( | |||||
val itemsService: ItemsService, | |||||
val uomConversionService: UomConversionService, | |||||
val itemUomRespository: ItemUomRespository, | |||||
val currencyService: CurrencyService | |||||
) { | |||||
open fun findAllByItemsId(itemId: Long): List<ItemUom> { | |||||
return itemUomRespository.findAllByItemIdAndDeletedIsFalse(itemId); | |||||
} | |||||
open fun findById(id: Long): ItemUom? { | |||||
return itemUomRespository.findByIdAndDeletedIsFalse(id); | |||||
} | |||||
open fun findByM18Id(m18Id: Long): ItemUom? { | |||||
return itemUomRespository.findByM18IdAndDeletedIsFalse(m18Id); | |||||
} | |||||
// See if need to update the response | |||||
open fun saveItemUom(request: ItemUomRequest): ItemUom { | |||||
val itemUom = request.m18Id?.let { findByM18Id(it) } ?: request.id?.let { findById(it) } ?: ItemUom() | |||||
val item = request.itemId?.let { itemsService.find(it).getOrNull() } | |||||
val uom = request.m18UomId?.let { uomConversionService.findByM18Id(it) } ?: request.uomId?.let { uomConversionService.find(it).getOrNull() } | |||||
val currency = request.currencyId?.let { currencyService.findById(it) } | |||||
itemUom.apply { | |||||
this.uom = uom | |||||
this.item = item | |||||
this.currency = currency | |||||
baseUnit = request.baseUnit | |||||
stockUnit = request.stockUnit | |||||
pickingUnit = request.pickingUnit | |||||
salesUnit = request.salesUnit | |||||
purchaseUnit = request.purchaseUnit | |||||
price = request.price | |||||
m18Id = request.m18Id | |||||
m18LastModifyDate = request.m18LastModifyDate | |||||
} | |||||
val savedItemUom = itemUomRespository.saveAndFlush(itemUom) | |||||
return savedItemUom | |||||
} | |||||
open fun deleteItemUoms(deleteIds: List<Long>) { | |||||
itemUomRespository.deleteAllByIdIn(deleteIds) | |||||
} | |||||
} |
@@ -2,6 +2,7 @@ package com.ffii.fpsms.modules.master.service | |||||
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.enums.ShopType | import com.ffii.fpsms.modules.master.enums.ShopType | ||||
import com.ffii.fpsms.modules.master.web.models.SaveShopRequest | import com.ffii.fpsms.modules.master.web.models.SaveShopRequest | ||||
import com.ffii.fpsms.modules.master.web.models.SaveShopResponse | import com.ffii.fpsms.modules.master.web.models.SaveShopResponse | ||||
@@ -24,6 +25,16 @@ open class ShopService( | |||||
return shopRepository.findByM18IdAndDeletedIsFalse(m18Id) | return shopRepository.findByM18IdAndDeletedIsFalse(m18Id) | ||||
} | } | ||||
open fun findVendorIdsByCodeRegexp(code: List<String>): List<Long>? { | |||||
val codeRegexp = code.joinToString("|") | |||||
return shopRepository.findIdsByCodeRegexpAndTypeAndDeletedIsFalse(codeRegexp, type = ShopType.SUPPLIER.value) | |||||
} | |||||
open fun findVendorIdsByCodeNotRegexp(code: List<String>): List<Long>? { | |||||
val codeRegexp = code.joinToString("|") | |||||
return shopRepository.findIdsByCodeNotRegexpAndTypeAndDeletedIsFalse(codeRegexp, type = ShopType.SUPPLIER.value) | |||||
} | |||||
open fun saveShop(request: SaveShopRequest): SaveShopResponse { | open fun saveShop(request: SaveShopRequest): SaveShopResponse { | ||||
val shop = if (request.m18Id != null) { | val shop = if (request.m18Id != null) { | ||||
findByM18Id(request.m18Id) ?: Shop() | findByM18Id(request.m18Id) ?: Shop() | ||||
@@ -196,6 +196,9 @@ open class UomConversionService( | |||||
} | } | ||||
} | } | ||||
open fun findByM18Id(m18Id: Long) : UomConversion? { | |||||
return uomConversionRepository.findByM18IdAndDeletedFalse(m18Id) | |||||
} | |||||
@Throws(IOException::class) | @Throws(IOException::class) | ||||
@Transactional | @Transactional | ||||
open fun saveUomConversion(newUomConversion: UomConversion): MessageResponse { | open fun saveUomConversion(newUomConversion: UomConversion): MessageResponse { | ||||
@@ -211,7 +214,8 @@ open class UomConversionService( | |||||
) | ) | ||||
} | } | ||||
val uomConversion = if (newUomConversion.id != null && newUomConversion.id > 0) | |||||
val uomConversion = findByM18Id(newUomConversion.m18Id) ?: | |||||
if (newUomConversion.id != null && newUomConversion.id > 0) | |||||
uomConversionRepository.findByIdAndDeletedFalse(newUomConversion.id) | uomConversionRepository.findByIdAndDeletedFalse(newUomConversion.id) | ||||
else UomConversion() | else UomConversion() | ||||
@@ -39,47 +39,6 @@ class QcItemController( | |||||
@PostMapping("/save") | @PostMapping("/save") | ||||
fun saveQcItem(@Valid @RequestBody request: SaveQcItemRequest): SaveQcItemResponse { | fun saveQcItem(@Valid @RequestBody request: SaveQcItemRequest): SaveQcItemResponse { | ||||
// val qcItemProperties = QcItem::class.members.filterIsInstance<KProperty<QcItem>>() | |||||
val errors = mutableMapOf<String, String>() | |||||
val id = request.id | |||||
val qcItem = if (id != null) qcItemRepository.findById(id).orElseThrow() else QcItem() | |||||
// check duplicated code | |||||
val duplicateQcItem = qcItemService.findQcItemByCode(request.code) | |||||
if (duplicateQcItem != null && duplicateQcItem.id != qcItem.id) { | |||||
errors["code"] = "Code is duplicated" | |||||
} | |||||
if (errors.isNotEmpty()) { | |||||
request.let { | |||||
SaveQcItemResponse( | |||||
id = it.id, | |||||
code = it.code, | |||||
name = it.name, | |||||
description = it.description, | |||||
errors = errors | |||||
) | |||||
} | |||||
} | |||||
// Save Qc Item | |||||
qcItem.apply { | |||||
code = request.code | |||||
name = request.name | |||||
description = request.description | |||||
} | |||||
val savedQcItem = qcItemRepository.save(qcItem) | |||||
return savedQcItem.let { | |||||
SaveQcItemResponse( | |||||
id = it.id, | |||||
code = it.code, | |||||
name = it.name, | |||||
description = it.description, | |||||
errors = null | |||||
) | |||||
} | |||||
return qcItemService.saveQcItem(request) | |||||
} | } | ||||
} | } |
@@ -0,0 +1,12 @@ | |||||
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?, | |||||
) |
@@ -0,0 +1,27 @@ | |||||
package com.ffii.fpsms.modules.master.web.models | |||||
import java.math.BigDecimal | |||||
import java.time.LocalDateTime | |||||
data class DeleteItemUomRequest( | |||||
val id: Long? = null, | |||||
val m18Id: Long? = null | |||||
) | |||||
data class ItemUomRequest( | |||||
val id: Long? = null, | |||||
val uomId: Long? = null, | |||||
val m18UomId: Long? = null, | |||||
val itemId: Long? = null, | |||||
val m18ItemId: Long? = null, | |||||
val baseUnit: Boolean?, | |||||
val stockUnit: Boolean?, | |||||
val pickingUnit: Boolean?, | |||||
val salesUnit: Boolean?, | |||||
val purchaseUnit: Boolean?, | |||||
val price: BigDecimal?, | |||||
val currencyId: Long? = null, | |||||
val m18CurrencyId: Long? = null, | |||||
val m18Id: Long?, | |||||
val m18LastModifyDate: LocalDateTime?, | |||||
) |
@@ -5,10 +5,11 @@ import com.ffii.fpsms.modules.master.entity.Shop | |||||
import com.ffii.fpsms.m18.entity.M18DataLog | import com.ffii.fpsms.m18.entity.M18DataLog | ||||
import com.ffii.fpsms.modules.purchaseOrder.enums.PurchaseOrderStatus | import com.ffii.fpsms.modules.purchaseOrder.enums.PurchaseOrderStatus | ||||
import com.ffii.fpsms.modules.purchaseOrder.enums.PurchaseOrderStatusConverter | import com.ffii.fpsms.modules.purchaseOrder.enums.PurchaseOrderStatusConverter | ||||
import com.ffii.fpsms.modules.purchaseOrder.enums.PurchaseOrderType | |||||
import com.ffii.fpsms.modules.purchaseOrder.enums.PurchaseOrderTypeConverter | |||||
import jakarta.persistence.* | import jakarta.persistence.* | ||||
import jakarta.validation.constraints.NotNull | import jakarta.validation.constraints.NotNull | ||||
import jakarta.validation.constraints.Size | import jakarta.validation.constraints.Size | ||||
import java.time.LocalDate | |||||
import java.time.LocalDateTime | import java.time.LocalDateTime | ||||
@Entity | @Entity | ||||
@@ -37,6 +38,11 @@ open class PurchaseOrder : BaseEntity<Long>() { | |||||
@Convert(converter = PurchaseOrderStatusConverter::class) | @Convert(converter = PurchaseOrderStatusConverter::class) | ||||
open var status: PurchaseOrderStatus? = null | open var status: PurchaseOrderStatus? = null | ||||
@NotNull | |||||
@Column(name = "type", nullable = true, length = 20) | |||||
@Convert(converter = PurchaseOrderTypeConverter::class) | |||||
open var type: PurchaseOrderType? = null | |||||
@NotNull | @NotNull | ||||
@ManyToOne | @ManyToOne | ||||
@JoinColumn(name = "m18DataLogId", nullable = false) | @JoinColumn(name = "m18DataLogId", nullable = false) | ||||
@@ -3,7 +3,7 @@ package com.ffii.fpsms.modules.purchaseOrder.entity | |||||
import com.ffii.core.entity.BaseEntity | import com.ffii.core.entity.BaseEntity | ||||
import com.ffii.fpsms.modules.master.entity.Items | import com.ffii.fpsms.modules.master.entity.Items | ||||
import com.ffii.fpsms.m18.entity.M18DataLog | import com.ffii.fpsms.m18.entity.M18DataLog | ||||
import com.ffii.fpsms.modules.master.enums.ShopTypeConverter | |||||
import com.ffii.fpsms.modules.master.entity.Currency | |||||
import com.ffii.fpsms.modules.purchaseOrder.enums.PurchaseOrderLineStatus | import com.ffii.fpsms.modules.purchaseOrder.enums.PurchaseOrderLineStatus | ||||
import com.ffii.fpsms.modules.purchaseOrder.enums.PurchaseOrderLineStatusConverter | import com.ffii.fpsms.modules.purchaseOrder.enums.PurchaseOrderLineStatusConverter | ||||
import jakarta.persistence.* | import jakarta.persistence.* | ||||
@@ -40,10 +40,6 @@ open class PurchaseOrderLine : BaseEntity<Long>(){ | |||||
@Column(name = "price", precision = 14, scale = 2) | @Column(name = "price", precision = 14, scale = 2) | ||||
open var price: BigDecimal? = null | open var price: BigDecimal? = null | ||||
@Size(max = 5) | |||||
@Column(name = "priceUnit", length = 5) | |||||
open var priceUnit: String? = null | |||||
@Convert(converter = PurchaseOrderLineStatusConverter::class) | @Convert(converter = PurchaseOrderLineStatusConverter::class) | ||||
@NotNull | @NotNull | ||||
@Column(name = "status", nullable = false, length = 10) | @Column(name = "status", nullable = false, length = 10) | ||||
@@ -53,4 +49,11 @@ open class PurchaseOrderLine : BaseEntity<Long>(){ | |||||
@ManyToOne | @ManyToOne | ||||
@JoinColumn(name = "m18DataLogId", nullable = false) | @JoinColumn(name = "m18DataLogId", nullable = false) | ||||
open var m18DataLog: M18DataLog? = null | open var m18DataLog: M18DataLog? = null | ||||
@Column(name = "uomId") | |||||
open var uomId: Long? = null | |||||
@ManyToOne(fetch = FetchType.LAZY) | |||||
@JoinColumn(name = "currencyId") | |||||
open var currency: Currency? = null | |||||
} | } |
@@ -13,4 +13,10 @@ enum class PurchaseOrderStatus(val value: String) { | |||||
?: throw IllegalArgumentException("No enum constant with value: $value") | ?: throw IllegalArgumentException("No enum constant with value: $value") | ||||
} | } | ||||
} | } | ||||
} | |||||
enum class PurchaseOrderType(val value: String) { | |||||
MATERIAL ("material"), | |||||
SHOP ("shop"), | |||||
OEM ("oem") | |||||
} | } |
@@ -3,6 +3,7 @@ package com.ffii.fpsms.modules.purchaseOrder.enums | |||||
import jakarta.persistence.AttributeConverter | import jakarta.persistence.AttributeConverter | ||||
import jakarta.persistence.Converter | import jakarta.persistence.Converter | ||||
// Purchase Order Status | |||||
@Converter(autoApply = true) | @Converter(autoApply = true) | ||||
class PurchaseOrderStatusConverter : AttributeConverter<PurchaseOrderStatus, String>{ | class PurchaseOrderStatusConverter : AttributeConverter<PurchaseOrderStatus, String>{ | ||||
override fun convertToDatabaseColumn(status: PurchaseOrderStatus?): String? { | override fun convertToDatabaseColumn(status: PurchaseOrderStatus?): String? { | ||||
@@ -14,4 +15,18 @@ class PurchaseOrderStatusConverter : AttributeConverter<PurchaseOrderStatus, Str | |||||
PurchaseOrderStatus.entries.find { it.value == v } | PurchaseOrderStatus.entries.find { it.value == v } | ||||
} | } | ||||
} | } | ||||
} | |||||
// Purchase Order Type | |||||
@Converter(autoApply = true) | |||||
class PurchaseOrderTypeConverter : AttributeConverter<PurchaseOrderType, String>{ | |||||
override fun convertToDatabaseColumn(status: PurchaseOrderType?): String? { | |||||
return status?.value | |||||
} | |||||
override fun convertToEntityAttribute(value: String?): PurchaseOrderType? { | |||||
return value?.let { v -> | |||||
PurchaseOrderType.entries.find { it.value == v } | |||||
} | |||||
} | |||||
} | } |
@@ -1,7 +1,5 @@ | |||||
package com.ffii.fpsms.modules.purchaseOrder.enums | package com.ffii.fpsms.modules.purchaseOrder.enums | ||||
import com.ffii.fpsms.modules.master.enums.ShopType | |||||
enum class PurchaseOrderLineStatus(val value: String) { | enum class PurchaseOrderLineStatus(val value: String) { | ||||
PENDING("pending"), | PENDING("pending"), | ||||
PICKING("picking"), | PICKING("picking"), |
@@ -2,8 +2,8 @@ package com.ffii.fpsms.modules.purchaseOrder.service | |||||
import com.ffii.fpsms.m18.entity.M18DataLogRepository | import com.ffii.fpsms.m18.entity.M18DataLogRepository | ||||
import com.ffii.fpsms.modules.master.entity.ItemsRepository | import com.ffii.fpsms.modules.master.entity.ItemsRepository | ||||
import com.ffii.fpsms.modules.master.service.CurrencyService | |||||
import com.ffii.fpsms.modules.master.service.ItemsService | import com.ffii.fpsms.modules.master.service.ItemsService | ||||
import com.ffii.fpsms.modules.purchaseOrder.entity.PurchaseOrder | |||||
import com.ffii.fpsms.modules.purchaseOrder.entity.PurchaseOrderLine | import com.ffii.fpsms.modules.purchaseOrder.entity.PurchaseOrderLine | ||||
import com.ffii.fpsms.modules.purchaseOrder.entity.PurchaseOrderLineRepository | import com.ffii.fpsms.modules.purchaseOrder.entity.PurchaseOrderLineRepository | ||||
import com.ffii.fpsms.modules.purchaseOrder.entity.PurchaseOrderRepository | import com.ffii.fpsms.modules.purchaseOrder.entity.PurchaseOrderRepository | ||||
@@ -12,7 +12,6 @@ import com.ffii.fpsms.modules.purchaseOrder.enums.PurchaseOrderLineStatus | |||||
import com.ffii.fpsms.modules.purchaseOrder.web.model.SavePurchaseOrderLineRequest | import com.ffii.fpsms.modules.purchaseOrder.web.model.SavePurchaseOrderLineRequest | ||||
import com.ffii.fpsms.modules.purchaseOrder.web.model.SavePurchaseOrderLineResponse | import com.ffii.fpsms.modules.purchaseOrder.web.model.SavePurchaseOrderLineResponse | ||||
import org.springframework.stereotype.Service | import org.springframework.stereotype.Service | ||||
import java.math.BigDecimal | |||||
import kotlin.jvm.optionals.getOrDefault | import kotlin.jvm.optionals.getOrDefault | ||||
import kotlin.jvm.optionals.getOrNull | import kotlin.jvm.optionals.getOrNull | ||||
@@ -22,7 +21,8 @@ open class PurchaseOrderLineService( | |||||
private val itemsService: ItemsService, | private val itemsService: ItemsService, | ||||
private val itemsRepository: ItemsRepository, | private val itemsRepository: ItemsRepository, | ||||
private val purchaseOrderRepository: PurchaseOrderRepository, | private val purchaseOrderRepository: PurchaseOrderRepository, | ||||
private val m18DataLogRepository: M18DataLogRepository | |||||
private val m18DataLogRepository: M18DataLogRepository, | |||||
private val currencyService: CurrencyService, | |||||
) { | ) { | ||||
open fun allPurchaseOrderLine(): List<PurchaseOrderLine> { | open fun allPurchaseOrderLine(): List<PurchaseOrderLine> { | ||||
return purchaseOrderLineRepository.findAll() | return purchaseOrderLineRepository.findAll() | ||||
@@ -31,6 +31,7 @@ open class PurchaseOrderLineService( | |||||
open fun findPurchaseOrderLineByM18Id(m18DataLogId: Long): PurchaseOrderLine? { | open fun findPurchaseOrderLineByM18Id(m18DataLogId: Long): PurchaseOrderLine? { | ||||
return purchaseOrderLineRepository.findByM18DataLogIdAndDeletedIsFalse(m18DataLogId) | return purchaseOrderLineRepository.findByM18DataLogIdAndDeletedIsFalse(m18DataLogId) | ||||
} | } | ||||
open fun findAllPoLineInfoByPoId(poId: Long): List<PurchaseOrderLineInfo> { | open fun findAllPoLineInfoByPoId(poId: Long): List<PurchaseOrderLineInfo> { | ||||
return purchaseOrderLineRepository.findAllPurchaseOrderLineInfoByPurchaseOrderIdAndDeletedIsFalse(poId) | return purchaseOrderLineRepository.findAllPurchaseOrderLineInfoByPurchaseOrderIdAndDeletedIsFalse(poId) | ||||
} | } | ||||
@@ -43,6 +44,8 @@ open class PurchaseOrderLineService( | |||||
val purchaseOrder = request.purchaseOrderId?.let { purchaseOrderRepository.findById(it).getOrNull() } | val purchaseOrder = request.purchaseOrderId?.let { purchaseOrderRepository.findById(it).getOrNull() } | ||||
val status = request.status?.let { status -> PurchaseOrderLineStatus.entries.find { it.value == status } } | val status = request.status?.let { status -> PurchaseOrderLineStatus.entries.find { it.value == status } } | ||||
val m18DataLog = request.m18DataLogId?.let { m18DataLogRepository.findById(it).getOrNull() } | val m18DataLog = request.m18DataLogId?.let { m18DataLogRepository.findById(it).getOrNull() } | ||||
val currency = request.m18CurrencyId?.let { currencyService.findByM18Id(it) } | |||||
?: request.currencyId?.let { currencyService.findById(it) } | |||||
purchaseOrderLine.apply { | purchaseOrderLine.apply { | ||||
this.item = item | this.item = item | ||||
@@ -50,7 +53,7 @@ open class PurchaseOrderLineService( | |||||
this.purchaseOrder = purchaseOrder | this.purchaseOrder = purchaseOrder | ||||
qty = request.qty | qty = request.qty | ||||
price = request.price | price = request.price | ||||
priceUnit = request.priceUnit | |||||
this.currency = currency | |||||
this.status = status | this.status = status | ||||
this.m18DataLog = m18DataLog ?: this.m18DataLog | this.m18DataLog = m18DataLog ?: this.m18DataLog | ||||
} | } | ||||
@@ -61,7 +64,7 @@ open class PurchaseOrderLineService( | |||||
itemNo = it.itemNo, | itemNo = it.itemNo, | ||||
qty = it.qty, | qty = it.qty, | ||||
price = it.price, | price = it.price, | ||||
priceUnit = it.priceUnit, | |||||
currency = currency?.name, | |||||
status = it.status?.value | status = it.status?.value | ||||
) | ) | ||||
} | } | ||||
@@ -10,6 +10,7 @@ import com.ffii.fpsms.modules.purchaseOrder.entity.PurchaseOrderRepository | |||||
import com.ffii.fpsms.modules.purchaseOrder.entity.projections.PoLineWithStockInLine | import com.ffii.fpsms.modules.purchaseOrder.entity.projections.PoLineWithStockInLine | ||||
import com.ffii.fpsms.modules.purchaseOrder.entity.projections.PurchaseOrderInfo | import com.ffii.fpsms.modules.purchaseOrder.entity.projections.PurchaseOrderInfo | ||||
import com.ffii.fpsms.modules.purchaseOrder.enums.PurchaseOrderStatus | import com.ffii.fpsms.modules.purchaseOrder.enums.PurchaseOrderStatus | ||||
import com.ffii.fpsms.modules.purchaseOrder.enums.PurchaseOrderType | |||||
import com.ffii.fpsms.modules.purchaseOrder.web.model.SavePurchaseOrderRequest | import com.ffii.fpsms.modules.purchaseOrder.web.model.SavePurchaseOrderRequest | ||||
import com.ffii.fpsms.modules.purchaseOrder.web.model.SavePurchaseOrderResponse | import com.ffii.fpsms.modules.purchaseOrder.web.model.SavePurchaseOrderResponse | ||||
import com.ffii.fpsms.modules.stock.entity.StockInLine | import com.ffii.fpsms.modules.stock.entity.StockInLine | ||||
@@ -77,6 +78,7 @@ open class PurchaseOrderService( | |||||
request.id?.let { purchaseOrderRepository.findById(it).getOrDefault(PurchaseOrder()) } ?: PurchaseOrder() | request.id?.let { purchaseOrderRepository.findById(it).getOrDefault(PurchaseOrder()) } ?: PurchaseOrder() | ||||
val supplier = request.supplierId?.let { shopRepository.findById(it).getOrNull() } | val supplier = request.supplierId?.let { shopRepository.findById(it).getOrNull() } | ||||
val status = request.status?.let { status -> PurchaseOrderStatus.entries.find { it.value == status } } | val status = request.status?.let { status -> PurchaseOrderStatus.entries.find { it.value == status } } | ||||
val type = request.type?.let { type -> PurchaseOrderType.entries.find { it.value == type } } | |||||
val m18DataLog = request.m18DataLogId?.let { m18DataLogRepository.findById(it).getOrNull() } | val m18DataLog = request.m18DataLogId?.let { m18DataLogRepository.findById(it).getOrNull() } | ||||
//Need check duplicate? | //Need check duplicate? | ||||
@@ -88,6 +90,7 @@ open class PurchaseOrderService( | |||||
estimatedArrivalDate = request.estimatedArrivalDate | estimatedArrivalDate = request.estimatedArrivalDate | ||||
completeDate = request.completeDate | completeDate = request.completeDate | ||||
this.status = status | this.status = status | ||||
this.type = type | |||||
this.m18DataLog = m18DataLog | this.m18DataLog = m18DataLog | ||||
} | } | ||||
@@ -1,6 +1,5 @@ | |||||
package com.ffii.fpsms.modules.purchaseOrder.web.model | package com.ffii.fpsms.modules.purchaseOrder.web.model | ||||
import com.ffii.fpsms.modules.purchaseOrder.enums.PurchaseOrderLineStatus | |||||
import java.math.BigDecimal | import java.math.BigDecimal | ||||
data class SavePurchaseOrderLineRequest( | data class SavePurchaseOrderLineRequest( | ||||
@@ -10,7 +9,8 @@ data class SavePurchaseOrderLineRequest( | |||||
val purchaseOrderId: Long?, | val purchaseOrderId: Long?, | ||||
val qty: BigDecimal?, | val qty: BigDecimal?, | ||||
val price: BigDecimal?, | val price: BigDecimal?, | ||||
val priceUnit: String?, | |||||
val currencyId: Long? = null, | |||||
val m18CurrencyId: Long? = null, | |||||
val status: String?, | val status: String?, | ||||
val m18DataLogId: Long?, | val m18DataLogId: Long?, | ||||
) | ) |
@@ -1,6 +1,5 @@ | |||||
package com.ffii.fpsms.modules.purchaseOrder.web.model | package com.ffii.fpsms.modules.purchaseOrder.web.model | ||||
import com.ffii.fpsms.modules.purchaseOrder.enums.PurchaseOrderLineStatus | |||||
import java.math.BigDecimal | import java.math.BigDecimal | ||||
data class SavePurchaseOrderLineResponse ( | data class SavePurchaseOrderLineResponse ( | ||||
@@ -8,6 +7,6 @@ data class SavePurchaseOrderLineResponse ( | |||||
val itemNo: String?, | val itemNo: String?, | ||||
val qty: BigDecimal?, | val qty: BigDecimal?, | ||||
val price: BigDecimal?, | val price: BigDecimal?, | ||||
val priceUnit: String?, | |||||
val currency: String?, | |||||
val status: String?, | val status: String?, | ||||
) | ) |
@@ -12,5 +12,6 @@ data class SavePurchaseOrderRequest ( | |||||
val estimatedArrivalDate: LocalDateTime?, | val estimatedArrivalDate: LocalDateTime?, | ||||
val completeDate: LocalDateTime?, | val completeDate: LocalDateTime?, | ||||
val status: String?, | val status: String?, | ||||
val type: String?, | |||||
val m18DataLogId: Long? | val m18DataLogId: Long? | ||||
) | ) |
@@ -36,6 +36,11 @@ m18: | |||||
password: db25f2fc14cd2d2b1e7af307241f548fb03c312a | password: db25f2fc14cd2d2b1e7af307241f548fb03c312a | ||||
base-url: http://16.162.251.126/jsf/rfws | base-url: http://16.162.251.126/jsf/rfws | ||||
base-password: qwer1234 | base-password: qwer1234 | ||||
supplier: | |||||
shop-po: P06, P07 | |||||
oem-po: T62 | |||||
supplier-not: | |||||
material-po: P06, P07 | |||||
beId: | beId: | ||||
toa: 29 | toa: 29 | ||||
pp: 27 | pp: 27 | ||||
@@ -0,0 +1,19 @@ | |||||
--liquibase formatted sql | |||||
--changeset cyril:create currency table | |||||
CREATE TABLE `currency` | |||||
( | |||||
`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, | |||||
`name` VARCHAR(30) NOT NULL, | |||||
`description` VARCHAR(100) NOT NULL DEFAULT '0', | |||||
`m18Id` INT NULL, | |||||
`m18LastModifyDate` DATETIME NULL, | |||||
CONSTRAINT pk_currency PRIMARY KEY (id) | |||||
); |
@@ -0,0 +1,28 @@ | |||||
--liquibase formatted sql | |||||
--changeset cyril:create item_uom table | |||||
CREATE TABLE `item_uom` | |||||
( | |||||
`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', | |||||
`uomId` INT NOT NULL, | |||||
`itemId` INT NOT NULL, | |||||
`baseUnit` TINYINT NOT NULL DEFAULT '0', | |||||
`stockUnit` TINYINT NOT NULL DEFAULT '0', | |||||
`pickingUnit` TINYINT NOT NULL DEFAULT '0', | |||||
`salesUnit` TINYINT NOT NULL DEFAULT '0', | |||||
`purchaseUnit` TINYINT NOT NULL DEFAULT '0', | |||||
`price` DECIMAL(14, 2) NULL, | |||||
`currencyId` INT NULL, | |||||
`m18Id` INT NOT NULL, | |||||
`m18LastModifyDate` DATETIME NULL, | |||||
CONSTRAINT pk_item_uom PRIMARY KEY (id), | |||||
CONSTRAINT FK_ITEM_UOM_ON_UOMID FOREIGN KEY (uomId) REFERENCES uom_conversion (id), | |||||
CONSTRAINT FK_ITEM_UOM_ON_ITEMID FOREIGN KEY (itemId) REFERENCES items (id), | |||||
CONSTRAINT FK_ITEM_UOM_ON_CURRENCYID FOREIGN KEY (currencyId) REFERENCES currency (id) | |||||
); |
@@ -0,0 +1,8 @@ | |||||
--liquibase formatted sql | |||||
--changeset cyril:update purchase order line | |||||
ALTER TABLE `purchase_order_line` | |||||
CHANGE COLUMN `priceUnit` `currencyId` INT NULL DEFAULT NULL, | |||||
ADD CONSTRAINT `FK_PURCHASE_ORDER_LINE_ON_UOMID` FOREIGN KEY (`uomId`) REFERENCES `uom_conversion` (`id`), | |||||
ADD CONSTRAINT `FK_PURCHASE_ORDER_LINE_ON_CURRENCYID` FOREIGN KEY (`currencyId`) REFERENCES `currency` (`id`); |
@@ -0,0 +1,6 @@ | |||||
--liquibase formatted sql | |||||
--changeset cyril:update purchase order | |||||
ALTER TABLE `purchase_order` | |||||
ADD COLUMN `type` VARCHAR(20) NULL AFTER `status`; |