diff --git a/src/services/ProductService.ts b/src/services/ProductService.ts new file mode 100644 index 0000000..ed4784a --- /dev/null +++ b/src/services/ProductService.ts @@ -0,0 +1,39 @@ +import { client } from "@/api"; +import store from "@/store"; + +const fetchProducts = async (payload: any): Promise => { + const omsRedirectionInfo = store.getters["user/getOmsRedirectionInfo"]; + let baseURL = omsRedirectionInfo.url; + baseURL = baseURL && baseURL.startsWith("http") ? baseURL : `https://${baseURL}.hotwax.io/api/`; + return client({ + url: "searchProducts", + method: "post", + baseURL: baseURL, + data: payload, + headers: { + Authorization: 'Bearer ' + omsRedirectionInfo.token, + 'Content-Type': 'application/json' + } + }); +} + +const getInventoryAvailableByFacility = async (payload: any): Promise => { + const omsRedirectionInfo = store.getters["user/getOmsRedirectionInfo"]; + let baseURL = omsRedirectionInfo.url; + baseURL = baseURL && baseURL.startsWith("http") ? baseURL : `https://${baseURL}.hotwax.io/api/`; + return client({ + url: "service/getInventoryAvailableByFacility", + method: "post", + baseURL: baseURL, + data: payload, + headers: { + Authorization: 'Bearer ' + omsRedirectionInfo.token, + 'Content-Type': 'application/json' + } + }); +} + +export const ProductService = { + fetchProducts, + getInventoryAvailableByFacility +} \ No newline at end of file diff --git a/src/services/RoutingService.ts b/src/services/RoutingService.ts index 695581d..092b908 100644 --- a/src/services/RoutingService.ts +++ b/src/services/RoutingService.ts @@ -1,4 +1,5 @@ -import api from "@/api" +import api, { client } from "@/api" +import store from "@/store"; const fetchRoutingGroups = async (payload: any): Promise => { return api({ @@ -163,7 +164,48 @@ const runNow = async (routingGroupId: string): Promise => { }); } +const findOrder = async (payload: any): Promise => { + const omsRedirectionInfo = store.getters["user/getOmsRedirectionInfo"]; + let baseURL = omsRedirectionInfo.url; + baseURL = baseURL && baseURL.startsWith("http") ? baseURL : `https://${baseURL}.hotwax.io/api/`; + return client({ + url: "solr-query", + method: "post", + baseURL: baseURL, + data: payload, + headers: { + Authorization: 'Bearer ' + omsRedirectionInfo.token, + 'Content-Type': 'application/json' + } + }); +} + +const brokerOrder = async(payload: any): Promise => { + return api({ + url: `groups/${payload.routingGroupId}/run`, + method: "POST", + data: payload + }) +} + +const getOrderFacilityChangeInfo = async (payload: any): Promise => { + const omsRedirectionInfo = store.getters["user/getOmsRedirectionInfo"]; + let baseURL = omsRedirectionInfo.url; + baseURL = baseURL && baseURL.startsWith("http") ? baseURL : `https://${baseURL}.hotwax.io/api/`; + return client({ + url: "performFind", + method: "post", + baseURL: baseURL, + data: payload, + headers: { + Authorization: 'Bearer ' + omsRedirectionInfo.token, + 'Content-Type': 'application/json' + } + }); +} + export const OrderRoutingService = { + brokerOrder, cloneGroup, createOrderRouting, cloneRouting, @@ -180,6 +222,8 @@ export const OrderRoutingService = { fetchRoutingHistory, fetchRoutingScheduleInformation, fetchRule, + findOrder, + getOrderFacilityChangeInfo, runNow, scheduleBrokering, updateRouting, diff --git a/src/services/UtilService.ts b/src/services/UtilService.ts index 1a04af3..03a3f85 100644 --- a/src/services/UtilService.ts +++ b/src/services/UtilService.ts @@ -1,4 +1,5 @@ -import api from "@/api" +import api, { client } from "@/api" +import store from "@/store"; const fetchEnums = async (payload: any): Promise => { return api({ @@ -55,6 +56,38 @@ const checkOmsConnection = async (): Promise => { }); } +const getCarrierInformation = async (payload: any): Promise => { + const omsRedirectionInfo = store.getters["user/getOmsRedirectionInfo"]; + let baseURL = omsRedirectionInfo.url; + baseURL = baseURL && baseURL.startsWith("http") ? baseURL : `https://${baseURL}.hotwax.io/api/`; + return client({ + url: "performFind", + method: "post", + baseURL: baseURL, + data: payload, + headers: { + Authorization: 'Bearer ' + omsRedirectionInfo.token, + 'Content-Type': 'application/json' + } + }); +} + +const getCarrierDeliveryDays = async (payload: any): Promise => { + const omsRedirectionInfo = store.getters["user/getOmsRedirectionInfo"]; + let baseURL = omsRedirectionInfo.url; + baseURL = baseURL && baseURL.startsWith("http") ? baseURL : `https://${baseURL}.hotwax.io/api/`; + return client({ + url: "performFind", + method: "post", + baseURL: baseURL, + data: payload, + headers: { + Authorization: 'Bearer ' + omsRedirectionInfo.token, + 'Content-Type': 'application/json' + } + }); +} + export const UtilService = { checkOmsConnection, fetchEnums, @@ -62,5 +95,7 @@ export const UtilService = { fetchFacilityGroups, fetchOmsEnums, fetchShippingMethods, - fetchStatusInformation + fetchStatusInformation, + getCarrierInformation, + getCarrierDeliveryDays } \ No newline at end of file diff --git a/src/store/index.ts b/src/store/index.ts index 83e5c43..5adab0d 100644 --- a/src/store/index.ts +++ b/src/store/index.ts @@ -8,6 +8,7 @@ import userModule from "./modules/user"; import utilModule from "./modules/util" import orderRoutingModule from "./modules/orderRouting" import { setPermissions } from "@/authorization" +import productModule from "./modules/product" // TODO check how to register it from the components only // Handle same module registering multiple time on page refresh @@ -16,7 +17,7 @@ import { setPermissions } from "@/authorization" const state: any = {} const persistState = createPersistedState({ - paths: ["user", "util", "orderRouting.currentGroup", "orderRouting.currentRuleId"], + paths: ["user", "util", "orderRouting.currentGroup", "orderRouting.currentRuleId", "product"], fetchBeforeUse: true }) @@ -30,7 +31,8 @@ const store = createStore({ modules: { "user": userModule, "util": utilModule, - "orderRouting": orderRoutingModule + "orderRouting": orderRoutingModule, + "product": productModule }, }) diff --git a/src/store/modules/product/ProductState.ts b/src/store/modules/product/ProductState.ts new file mode 100644 index 0000000..77ba763 --- /dev/null +++ b/src/store/modules/product/ProductState.ts @@ -0,0 +1,4 @@ +export default interface ProductState { + products: any; + stock: any; +} \ No newline at end of file diff --git a/src/store/modules/product/actions.ts b/src/store/modules/product/actions.ts new file mode 100644 index 0000000..7bc842d --- /dev/null +++ b/src/store/modules/product/actions.ts @@ -0,0 +1,78 @@ +import { ActionTree } from "vuex" +import RootState from "@/store/RootState" +import ProductState from "./ProductState" +import logger from "@/logger" +import { hasError } from "@/utils" +import * as types from "./mutation-types" +import { ProductService } from "@/services/ProductService" + +const actions: ActionTree = { + async fetchProducts({ commit, state }, productIds) { + const cachedProductIds = Object.keys(state.products); + const productIdFilter= productIds.reduce((filter: string, productId: any) => { + // If product already exist in cached products skip + if (cachedProductIds.includes(productId)) { + return filter; + } else { + // checking condition that if the filter is not empty then adding 'OR' to the filter + if (filter !== '') filter += ' OR ' + return filter += productId; + } + }, ''); + + // If there are no products skip the API call + if (productIdFilter === '') return; + + try { + // adding viewSize as by default we are having the viewSize of 10 + const resp = await ProductService.fetchProducts({ + "filters": ['productId: (' + productIdFilter + ')'], + "viewSize": productIds.length + }) + if(resp.data.response && !hasError(resp)) { + const products = resp.data.response.docs.reduce((products: any, product: any) => { + products[product.productId] = product + return products; + }, {}); + // Handled empty response in case of failed query + if(resp.data) commit(types.PRODUCT_LIST_UPDATED, products); + } else { + throw resp.data; + } + } catch(err) { + logger.error("Failed to fetch product information", err) + } + }, + + async fetchStock({ commit, state }, shipGroup) { + const productIds = shipGroup.map((item: any) => item.productId) + const facilityId = shipGroup[0].facilityId + for(const productId of productIds) { + if(state.stock[productId]?.[facilityId]) { + continue; + } + + try { + const payload = { + productId, + facilityId + } + + const resp: any = await ProductService.getInventoryAvailableByFacility(payload); + if (!hasError(resp)) { + commit(types.PRODUCT_STOCK_UPDATED, { productId: payload.productId, facilityId: facilityId, stock: resp.data }) + } else { + throw resp.data; + } + } catch (err) { + logger.error(err) + } + } + }, + + async clearProductState({ commit }) { + commit(types.PRODUCT_CLEARED) + } +} + +export default actions; \ No newline at end of file diff --git a/src/store/modules/product/getters.ts b/src/store/modules/product/getters.ts new file mode 100644 index 0000000..58a07dc --- /dev/null +++ b/src/store/modules/product/getters.ts @@ -0,0 +1,17 @@ +import { GetterTree } from "vuex" +import ProductState from "./ProductState" +import RootState from "@/store/RootState" + +const getters: GetterTree = { + getProducts(state) { + return state.products + }, + getProductById: (state) => (id: string) => { + return state.products[id] || {} + }, + getProductStock: (state) => (productId: string, facilityId: string) => { + return state.stock[productId] ? state.stock[productId][facilityId] ? state.stock[productId][facilityId] : {} : {} + }, +} + +export default getters; \ No newline at end of file diff --git a/src/store/modules/product/index.ts b/src/store/modules/product/index.ts new file mode 100644 index 0000000..e3a1ccb --- /dev/null +++ b/src/store/modules/product/index.ts @@ -0,0 +1,19 @@ +import actions from "./actions" +import getters from "./getters" +import mutations from "./mutations" +import { Module } from "vuex" +import ProductState from "./ProductState" +import RootState from "@/store/RootState" + +const productModule: Module = { + namespaced: true, + state: { + products: {}, + stock: {} + }, + getters, + actions, + mutations, +} + +export default productModule; \ No newline at end of file diff --git a/src/store/modules/product/mutation-types.ts b/src/store/modules/product/mutation-types.ts new file mode 100644 index 0000000..29e701d --- /dev/null +++ b/src/store/modules/product/mutation-types.ts @@ -0,0 +1,5 @@ +export const SN_PRODUCT = "product" +export const PRODUCT_LIST_UPDATED = SN_PRODUCT + "/LIST_UPDATED" +export const PRODUCT_STOCK_UPDATED = SN_PRODUCT + "/STOCK_UPDATED" +export const PRODUCT_CLEARED = SN_PRODUCT + "/CLEARED" + diff --git a/src/store/modules/product/mutations.ts b/src/store/modules/product/mutations.ts new file mode 100644 index 0000000..73a79e1 --- /dev/null +++ b/src/store/modules/product/mutations.ts @@ -0,0 +1,22 @@ +import { MutationTree } from "vuex" +import ProductState from "./ProductState" +import * as types from "./mutation-types" + +const mutations: MutationTree = { + [types.PRODUCT_LIST_UPDATED](state, payload) { + state.products = payload + }, + [types.PRODUCT_CLEARED](state) { + state.products = {} + }, + [types.PRODUCT_STOCK_UPDATED] (state, payload) { + if(state.stock[payload.productId]) { + state.stock[payload.productId][payload.facilityId] = payload.stock + } else { + state.stock[payload.productId] = { + [payload.facilityId]: payload.stock + } + } + }, +} +export default mutations; \ No newline at end of file diff --git a/src/store/modules/user/actions.ts b/src/store/modules/user/actions.ts index 8e14d9f..9cfd52c 100644 --- a/src/store/modules/user/actions.ts +++ b/src/store/modules/user/actions.ts @@ -61,13 +61,13 @@ const actions: ActionTree = { Settings.defaultZone = userProfile.timeZone; } - setPermissions(appPermissions); + // setPermissions(appPermissions); if(omsRedirectionUrl && token) { dispatch("setOmsRedirectionInfo", { url: omsRedirectionUrl, token }) } commit(types.USER_TOKEN_CHANGED, { newToken: api_key }) commit(types.USER_INFO_UPDATED, userProfile); - commit(types.USER_PERMISSIONS_UPDATED, appPermissions); + // commit(types.USER_PERMISSIONS_UPDATED, appPermissions); commit(types.USER_CURRENT_ECOM_STORE_UPDATED, userProfile.stores.length ? userProfile.stores[0] : {}); emitter.emit("dismissLoader") } catch (err: any) { @@ -90,6 +90,7 @@ const actions: ActionTree = { commit(types.USER_END_SESSION) this.dispatch("orderRouting/clearRouting") this.dispatch("util/clearUtilState") + this.dispatch("product/clearProductState") dispatch("setOmsRedirectionInfo", { url: "", token: "" }) resetConfig(); resetPermissions(); diff --git a/src/store/modules/util/UtilState.ts b/src/store/modules/util/UtilState.ts index d97c986..95cc04e 100644 --- a/src/store/modules/util/UtilState.ts +++ b/src/store/modules/util/UtilState.ts @@ -10,5 +10,6 @@ export default interface UtilState { shippingMethods: object; facilityGroups: object; isOmsConnectionExist: boolean | undefined; - statuses: any + statuses: any; + carriers: any; } \ No newline at end of file diff --git a/src/store/modules/util/actions.ts b/src/store/modules/util/actions.ts index 9268552..98580fb 100644 --- a/src/store/modules/util/actions.ts +++ b/src/store/modules/util/actions.ts @@ -104,8 +104,7 @@ const actions: ActionTree = { } const payload = { - parentTypeId: "VIRTUAL_FACILITY", - pageSize: 200 + pageSize: 500 } try { @@ -226,6 +225,78 @@ const actions: ActionTree = { commit(types.UTIL_STATUSES_UPDATED, statuses) }, + async fetchCarrierInformation({ commit, state }, carrierIds: Array) { + let carriers = JSON.parse(JSON.stringify(state.carriers)) + const carrierPartyIds = carrierIds.filter((id: any) => !carriers[id]) + + if(!carrierPartyIds.length) { + return; + } + + const payload = { + inputFields: { + partyId: carrierIds, + partyId_op: "in" + }, + distinct: "Y", + viewSize: carrierIds.length, + entityName: "PartyNameView", + } + + try { + const resp = await UtilService.getCarrierInformation(payload); + + if(!hasError(resp) && resp.data.docs?.length) { + // Using only groupName as we will always pass carrier id, that only has groupName with it + carriers = resp.data.docs.reduce((carriers: any, carrier: any) => { + carriers[carrier.partyId] = { + name: carrier.groupName + } + return carriers + }, carriers) + } + } catch(err) { + logger.error(err) + } + + const deliveryDaysPayload = { + inputFields: { + partyId: carrierIds, + partyId_op: "in", + roleTypeId: "CARRIER", + deliveryDays_op: "not-empty" + }, + distinct: "Y", + viewSize: 200, + entityName: "CarrierShipmentMethod", + } + + try { + const resp = await UtilService.getCarrierDeliveryDays(deliveryDaysPayload); + + if(!hasError(resp) && resp.data.docs?.length) { + carriers = resp.data.docs.reduce((carriers: any, carrier: any) => { + if(carriers[carrier.partyId]["deliveryDays"]) { + carriers[carrier.partyId]["deliveryDays"] = { + ...carriers[carrier.partyId]["deliveryDays"], + [carrier.shipmentMethodTypeId]: carrier.deliveryDays + } + } else { + carriers[carrier.partyId]["deliveryDays"] = { + [carrier.shipmentMethodTypeId]: carrier.deliveryDays + } + } + + return carriers + }, carriers) + } + } catch(err) { + logger.error(err) + } + + commit(types.UTIL_CARRIERS_UPDATED, carriers) + }, + async clearUtilState({ commit }) { commit(types.UTIL_CLEARED) }, diff --git a/src/store/modules/util/getters.ts b/src/store/modules/util/getters.ts index 0ef32e4..cb12d4e 100644 --- a/src/store/modules/util/getters.ts +++ b/src/store/modules/util/getters.ts @@ -9,6 +9,22 @@ const getters: GetterTree = { getFacilities(state) { return state.facilities }, + getVirtualFacilities(state) { + return Object.values(state.facilities).reduce((virtualFacilities: any, facility: any) => { + if(facility.parentTypeId === "VIRTUAL_FACILITY") { + virtualFacilities[facility.facilityId] = facility + } + return virtualFacilities; + }, {}) + }, + getPhysicalFacilities(state) { + return Object.values(state.facilities).reduce((virtualFacilities: any, facility: any) => { + if(facility.parentTypeId !== "VIRTUAL_FACILITY") { + virtualFacilities[facility.facilityId] = facility + } + return virtualFacilities; + }, {}) + }, getShippingMethods(state) { return state.shippingMethods }, @@ -20,6 +36,9 @@ const getters: GetterTree = { }, getStatusDesc: (state) => (id: any) => { return state.statuses[id]?.description ? state.statuses[id]?.description : id + }, + getCarriers(state) { + return state.carriers } } diff --git a/src/store/modules/util/index.ts b/src/store/modules/util/index.ts index ba2d690..19e6bfa 100644 --- a/src/store/modules/util/index.ts +++ b/src/store/modules/util/index.ts @@ -13,7 +13,8 @@ const utilModule: Module = { shippingMethods: {}, facilityGroups: {}, isOmsConnectionExist: undefined, - statuses: {} + statuses: {}, + carriers: {} }, getters, actions, diff --git a/src/store/modules/util/mutation-types.ts b/src/store/modules/util/mutation-types.ts index f095008..035ac6b 100644 --- a/src/store/modules/util/mutation-types.ts +++ b/src/store/modules/util/mutation-types.ts @@ -5,4 +5,5 @@ export const UTIL_SHIPPING_METHOD_UPDATED = SN_UTIL + "/SHIPPING_METHOD_UPDATED" export const UTIL_FACILITY_GROUP_UPDATED = SN_UTIL + "/FACILITY_GROUP_UPDATED" export const UTIL_OMS_CONNECTION_STATUS_UPDATED = SN_UTIL + "/OMS_CONNECTION_STATUS_UPDATED" export const UTIL_STATUSES_UPDATED = SN_UTIL + "/STATUSES_UPDATED" +export const UTIL_CARRIERS_UPDATED = SN_UTIL + "/CARRIERS_UPDATED" export const UTIL_CLEARED = SN_UTIL + "/CLEARED" \ No newline at end of file diff --git a/src/store/modules/util/mutations.ts b/src/store/modules/util/mutations.ts index ef73a94..52affb6 100644 --- a/src/store/modules/util/mutations.ts +++ b/src/store/modules/util/mutations.ts @@ -25,9 +25,13 @@ const mutations: MutationTree = { state.facilityGroups = {} state.isOmsConnectionExist = undefined state.statuses = {} + state.carriers = {} }, [types.UTIL_STATUSES_UPDATED](state, payload) { state.statuses = payload + }, + [types.UTIL_CARRIERS_UPDATED](state, payload) { + state.carriers = payload } } export default mutations; \ No newline at end of file diff --git a/src/views/BrokeringQuery.vue b/src/views/BrokeringQuery.vue index efb5fdf..56a50ff 100644 --- a/src/views/BrokeringQuery.vue +++ b/src/views/BrokeringQuery.vue @@ -13,7 +13,7 @@