From 395956298c6e4be3770c6735a364936008e88abb Mon Sep 17 00:00:00 2001 From: Yash Maheshwari Date: Fri, 25 Oct 2024 14:40:54 +0530 Subject: [PATCH 1/6] Implemented: support to display good identification options dynamically(dxp/345) --- src/services/UserService.ts | 17 ++++++++++++++++ src/store/modules/product/actions.ts | 2 +- src/store/modules/user/UserState.ts | 5 +++-- src/store/modules/user/actions.ts | 26 ++++++++++++++++++++++++ src/store/modules/user/getters.ts | 3 +++ src/store/modules/user/index.ts | 3 ++- src/store/modules/user/mutation-types.ts | 3 ++- src/store/modules/user/mutations.ts | 3 +++ src/views/Settings.vue | 6 +++--- 9 files changed, 60 insertions(+), 8 deletions(-) diff --git a/src/services/UserService.ts b/src/services/UserService.ts index c70928d4..0ecf1f5b 100644 --- a/src/services/UserService.ts +++ b/src/services/UserService.ts @@ -249,12 +249,29 @@ const getFieldMappings = async (payload: any): Promise => { }); } +const fetchGoodIdentificationTypes = async (payload: any): Promise => { + const omsRedirectionInfo = store.getters["user/getOmsRedirectionInfo"] + const baseURL = omsRedirectionInfo.url.startsWith('http') ? omsRedirectionInfo.url.includes('/api') ? omsRedirectionInfo.url : `${omsRedirectionInfo.url}/api/` : `https://${omsRedirectionInfo.url}.hotwax.io/api/`; + + return await client({ + url: "performFind", + method: "post", + baseURL, + data: payload, + headers: { + "Authorization": 'Bearer ' + omsRedirectionInfo.token, + 'Content-Type': 'application/json' + } + }); +} + export const UserService = { createFieldMapping, createProductStoreSetting, deleteFieldMapping, fetchAssociatedFacilities, fetchFacilities, + fetchGoodIdentificationTypes, fetchProductStores, fetchProductStoreSettings, getAvailableTimeZones, diff --git a/src/store/modules/product/actions.ts b/src/store/modules/product/actions.ts index be86ac2e..9ab1fc9e 100644 --- a/src/store/modules/product/actions.ts +++ b/src/store/modules/product/actions.ts @@ -72,7 +72,7 @@ const actions: ActionTree = { async clearProducts({ commit }) { commit(types.PRODUCT_LIST_UPDATED, { products: [], total: 0 }); - } + } } export default actions; diff --git a/src/store/modules/user/UserState.ts b/src/store/modules/user/UserState.ts index 1000ac45..e21f6a50 100644 --- a/src/store/modules/user/UserState.ts +++ b/src/store/modules/user/UserState.ts @@ -24,6 +24,7 @@ export default interface UserState { productIdentificationPref: { primaryId: string, secondaryId: string - } - } + }, + }, + goodIdentificationTypes: Array; } \ No newline at end of file diff --git a/src/store/modules/user/actions.ts b/src/store/modules/user/actions.ts index bd7567ac..45715d50 100644 --- a/src/store/modules/user/actions.ts +++ b/src/store/modules/user/actions.ts @@ -106,6 +106,7 @@ const actions: ActionTree = { primaryId: 'productId', secondaryId: '' }}) + commit(types.USER_GOOD_IDENTIFICATION_TYPES_UPDATED, []) this.dispatch('count/clearCycleCounts') this.dispatch('count/clearCycleCountItems') @@ -545,6 +546,31 @@ const actions: ActionTree = { name: '', value: {} }) + }, + + async fetchGoodIdentificationTypes({ commit }, parentTypeId = "HC_GOOD_ID_TYPE") { + let identificationTypes = process.env.VUE_APP_PRDT_IDENT ? JSON.parse(process.env.VUE_APP_PRDT_IDENT) : [] + const payload = { + "inputFields": { + parentTypeId + }, + "fieldList": ["goodIdentificationTypeId", "description"], + "viewSize": 50, + "entityName": "GoodIdentificationType", + } + try { + const resp = await UserService.fetchGoodIdentificationTypes(payload) + if (!hasError(resp) && resp.data?.docs?.length) { + const identificationOptions = resp.data.docs?.map((fetchedGoodIdentificationType: any) => fetchedGoodIdentificationType.goodIdentificationTypeId) || []; + // Merge the arrays and remove duplicates + identificationTypes = Array.from(new Set([...identificationOptions, ...identificationTypes])).sort(); + } else { + throw resp.data; + } + } catch (err) { + console.error('Failed to fetch the good identification types, setting default types') + } + commit(types.USER_GOOD_IDENTIFICATION_TYPES_UPDATED, identificationTypes) } } export default actions; \ No newline at end of file diff --git a/src/store/modules/user/getters.ts b/src/store/modules/user/getters.ts index 66a113c4..c1fcf271 100644 --- a/src/store/modules/user/getters.ts +++ b/src/store/modules/user/getters.ts @@ -49,6 +49,9 @@ const getters: GetterTree = { return fieldMapping ? fieldMapping : {} } return state.fieldMappings; + }, + getGoodIdentificationTypes(state) { + return state.goodIdentificationTypes; } } export default getters; \ No newline at end of file diff --git a/src/store/modules/user/index.ts b/src/store/modules/user/index.ts index cd39ea09..94535e84 100644 --- a/src/store/modules/user/index.ts +++ b/src/store/modules/user/index.ts @@ -34,7 +34,8 @@ const userModule: Module = { primaryId: 'productId', secondaryId: '' }, - } + }, + goodIdentificationTypes: [] }, getters, actions, diff --git a/src/store/modules/user/mutation-types.ts b/src/store/modules/user/mutation-types.ts index d2401776..a3b25a1d 100644 --- a/src/store/modules/user/mutation-types.ts +++ b/src/store/modules/user/mutation-types.ts @@ -12,4 +12,5 @@ export const USER_CURRENT_PRODUCT_STORE_UPDATED = SN_USER + '/CURRENT_PRODUCT_ST export const USER_PRODUCT_STORE_SETTING_UPDATED = SN_USER + '/PRODUCT_STORE_SETTING_UPDATED' export const USER_FIELD_MAPPINGS_UPDATED = SN_USER + '/FIELD_MAPPINGS_UPDATED' export const USER_FIELD_MAPPING_CREATED = SN_USER + '/FIELD_MAPPING_CREATED' -export const USER_CURRENT_FIELD_MAPPING_UPDATED = SN_USER + '/_CURRENT_FIELD_MAPPING_UPDATED' \ No newline at end of file +export const USER_CURRENT_FIELD_MAPPING_UPDATED = SN_USER + '/_CURRENT_FIELD_MAPPING_UPDATED' +export const USER_GOOD_IDENTIFICATION_TYPES_UPDATED = SN_USER + '/PRODUCT_IDENTIFICATION_OPTIONS_UPDATED' \ No newline at end of file diff --git a/src/store/modules/user/mutations.ts b/src/store/modules/user/mutations.ts index 755028e1..301d65c6 100644 --- a/src/store/modules/user/mutations.ts +++ b/src/store/modules/user/mutations.ts @@ -51,6 +51,9 @@ const mutations: MutationTree = { name: payload.name, value: payload.value }; + }, + [types.USER_GOOD_IDENTIFICATION_TYPES_UPDATED](state, payload = []) { + state.goodIdentificationTypes = payload.length ? payload : process.env.VUE_APP_PRDT_IDENT ? JSON.parse(process.env.VUE_APP_PRDT_IDENT) : [] } } export default mutations; \ No newline at end of file diff --git a/src/views/Settings.vue b/src/views/Settings.vue index e7b0a4a2..4b251494 100644 --- a/src/views/Settings.vue +++ b/src/views/Settings.vue @@ -153,8 +153,6 @@ const store = useStore() const appVersion = ref("") const appInfo = (process.env.VUE_APP_VERSION_INFO ? JSON.parse(process.env.VUE_APP_VERSION_INFO) : {}) as any -const productIdentifications = process.env.VUE_APP_PRDT_IDENT ? JSON.parse(process.env.VUE_APP_PRDT_IDENT) : [] - const userProfile = computed(() => store.getters["user/getUserProfile"]) const oms = computed(() => store.getters["user/getInstanceUrl"]) const omsRedirectionInfo = computed(() => store.getters["user/getOmsRedirectionInfo"]) @@ -163,9 +161,11 @@ const currentFacility = computed(() => store.getters["user/getCurrentFacility"]) const currentProductStore = computed(() => store.getters["user/getCurrentProductStore"]) const productStores = computed(() => store.getters["user/getProductStores"]) const productStoreSettings = computed(() => store.getters["user/getProductStoreSettings"]) +const productIdentifications = computed(() => store.getters["user/getGoodIdentificationTypes"]) -onMounted(() => { +onMounted(async () => { appVersion.value = appInfo.branch ? (appInfo.branch + "-" + appInfo.revision) : appInfo.tag; + await store.dispatch("user/fetchGoodIdentificationTypes") }) function logout() { From 29c5fead1c686c12ec74e51420bddceca443edef Mon Sep 17 00:00:00 2001 From: Yash Maheshwari Date: Fri, 25 Oct 2024 14:49:10 +0530 Subject: [PATCH 2/6] Improved: identifier labels, updated static text entry in en.json and removed some options from hard-coded identifications list as we are getting those dynamically(dxp/345) --- .env.example | 2 +- src/locales/en.json | 10 +++++----- src/views/Settings.vue | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.env.example b/.env.example index 21c07831..a6d915d4 100644 --- a/.env.example +++ b/.env.example @@ -4,7 +4,7 @@ VUE_APP_CACHE_MAX_AGE=3600 VUE_APP_VIEW_SIZE=10 VUE_APP_PERMISSION_ID="INVCOUNT_APP_VIEW" VUE_APP_DEFAULT_LOG_LEVEL="error" -VUE_APP_PRDT_IDENT=["productId", "groupId", "groupName", "internalName", "parentProductName", "sku", "title", "SHOPIFY_PROD_SKU", "ERP_ID", "UPCA"] +VUE_APP_PRDT_IDENT=["productId", "groupId", "groupName", "internalName", "parentProductName", "primaryProductCategoryName", "title"] VUE_APP_MAPPING_TYPES={"INVCOUNT": "INVCNT_MAPPING_PREF"} VUE_APP_MAPPING_INVCOUNT={"countImportName": { "label": "Count name", "required": true}, "productSku": { "label": "Product SKU", "required": true, "description": "Products will not be deduplicated. Make sure products are only added to a count once."}, "facility": { "label": "Facility", "required": false, "description": "If a file includes multiple facilities, a count is created for every facility. All items with no facility location will be added to the same count." }, "statusId": { "label": "Status", "required": false, "description": "Defaults to 'Draft'" }, "dueDate": { "label": "Due date", "description": "Format: yyyy-mm-dd", "required": false }} VUE_APP_LOGIN_URL="http://launchpad.hotwax.io/login" \ No newline at end of file diff --git a/src/locales/en.json b/src/locales/en.json index 1e899e96..96e89208 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -26,7 +26,7 @@ "Before": "Before", "Browser TimeZone": "Browser TimeZone", "Browser time zone": "Browser time zone", - "Built: ": "Built: {builtDateTime}", + "Built:": "Built: {builtDateTime}", "Bulk Upload Cycle Counts": "Bulk Upload Cycle Counts", "Camera permission denied.": "Camera permission denied.", "Cancel": "Cancel", @@ -159,6 +159,7 @@ "NOT COUNTED": "NOT COUNTED", "not counted": "not counted", "No facility": "No facility", + "None": "None", "Fetching time zones": "Fetching time zones", "Ok": "Ok", "OMS": "OMS", @@ -176,9 +177,8 @@ "Please select the column that corresponds to the product identifier": "Please select the column that corresponds to the product identifier", "Preparing file to downlaod...": "Preparing file to downlaod...", "Primary": "Primary", - "Primary identifier": "Primary identifier", "Primary product ID": "Primary product ID", - "Primary Product Identifier": "Primary Product Identifier", + "primary identifier": "primary identifier", "processed": "processed", "processing": "processing", "Product Identifier": "Product Identifier", @@ -218,7 +218,6 @@ "Saving recount will replace the existing count for item.": "Saving recount will replace the existing count for item.", "Scan": "Scan", "Scan or search products": "Scan or search products", - "Secondary Product Identifier": "Secondary Product Identifier", "selected": "selected", "Select": "Select", "Select fields": "Select fields", @@ -230,6 +229,7 @@ "Search time zones": "Search time zones", "Searching on SKU": "Searching on SKU", "Secondary": "Secondary", + "secondary identifier": "secondary identifier", "Select all the required fields to continue": "Select all the required fields to continue", "Select date": "Select date", "Select the column containing products": "Select the column containing products", @@ -284,7 +284,7 @@ "variance": "variance", "Variance reason": "Variance reason", "Variance updated successfully": "Variance updated successfully", - "Version: ": "Version: {appVersion}", + "Version:": "Version: {appVersion}", "View": "View", "You do not have permission to access the app.": "You do not have permission to access the app.", "You do not have permission to access this page": "You do not have permission to access this page", diff --git a/src/views/Settings.vue b/src/views/Settings.vue index 4b251494..18a6e89a 100644 --- a/src/views/Settings.vue +++ b/src/views/Settings.vue @@ -121,12 +121,12 @@ - + {{ identification }} - + {{ identification }} {{ translate("None") }} From 762d2e73eb70a4e587ce4b037c2b6a7c4227cd55 Mon Sep 17 00:00:00 2001 From: Yash Maheshwari Date: Fri, 25 Oct 2024 15:00:35 +0530 Subject: [PATCH 3/6] Improved: display productName as fallback value when the primary selected identifier is missing(dxp/#345) --- src/components/AddProductModal.vue | 3 ++- src/components/AssignedCountPopover.vue | 2 +- src/views/AssignedDetail.vue | 2 +- src/views/CountDetail.vue | 2 +- src/views/DraftDetail.vue | 2 +- src/views/PendingReviewDetail.vue | 2 +- src/views/ProductItemList.vue | 2 +- 7 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/components/AddProductModal.vue b/src/components/AddProductModal.vue index ef4c5735..a169dc4a 100644 --- a/src/components/AddProductModal.vue +++ b/src/components/AddProductModal.vue @@ -19,7 +19,7 @@ -

{{ getProductIdentificationValue(productStoreSettings["productIdentificationPref"].primaryId, product) }}

+

{{ getProductIdentificationValue(productStoreSettings["productIdentificationPref"].primaryId, product) || getProduct(product.productId).productName }}

{{ getProductIdentificationValue(productStoreSettings["productIdentificationPref"].secondaryId, product) }}

@@ -73,6 +73,7 @@ const props = defineProps(["cycleCount"]) const products = computed(() => store.getters["product/getProducts"]) const isScrollable = computed(() => store.getters["product/isScrollable"]) const productStoreSettings = computed(() => store.getters["user/getProductStoreSettings"]) +const getProduct = computed(() => (id: any) => store.getters["product/getProduct"](id)) let queryString = ref('') const isSearching = ref(false); diff --git a/src/components/AssignedCountPopover.vue b/src/components/AssignedCountPopover.vue index 7080012e..49403f6c 100644 --- a/src/components/AssignedCountPopover.vue +++ b/src/components/AssignedCountPopover.vue @@ -1,7 +1,7 @@