From 369afeffba6989b1eca3792bf9d605b0508f7af6 Mon Sep 17 00:00:00 2001 From: R-Sourabh Date: Wed, 11 Dec 2024 15:39:52 +0530 Subject: [PATCH 01/11] Fixed: Disable upload button until all required fields are mapped correctly(#533) --- src/views/BulkUpload.vue | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/views/BulkUpload.vue b/src/views/BulkUpload.vue index b0868a3e..7bef4044 100644 --- a/src/views/BulkUpload.vue +++ b/src/views/BulkUpload.vue @@ -58,7 +58,7 @@ - + {{ translate("Upload") }} @@ -130,6 +130,7 @@ let fieldMapping = ref({}) let fileColumns = ref([]) let selectedMappingId = ref(null) const fileUploaded = ref(false); +const isUploadDisabled = ref(true); const fields = process.env["VUE_APP_MAPPING_INVCOUNT"] ? JSON.parse(process.env["VUE_APP_MAPPING_INVCOUNT"]) : {} @@ -288,8 +289,12 @@ function mapFields(mapping, mappingId) { const missingFields = Object.values(fieldMappingData.value).filter(field => { if(!csvFields.includes(field)) return field; }); - - if(missingFields.length) showToast(translate("Some of the mapping fields are missing in the CSV: ", { missingFields: missingFields.join(", ") })) + if(missingFields.length) { + isUploadDisabled.value = true + showToast(translate("Some of the mapping fields are missing in the CSV: ", { missingFields: missingFields.join(", ") })) + } else { + isUploadDisabled.value = false; + } Object.keys(fieldMappingData).map((key) => { if(!csvFields.includes(fieldMappingData.value[key])){ From c779f37885e5be76174c21342b10b5eed26bc038 Mon Sep 17 00:00:00 2001 From: R-Sourabh Date: Wed, 11 Dec 2024 17:57:03 +0530 Subject: [PATCH 02/11] Fixed: Users not associated with any facility will not be able to log in to the app (#529) --- src/store/modules/user/actions.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/store/modules/user/actions.ts b/src/store/modules/user/actions.ts index d80c990e..650b8faa 100644 --- a/src/store/modules/user/actions.ts +++ b/src/store/modules/user/actions.ts @@ -182,6 +182,7 @@ const actions: ActionTree = { } } catch(err) { logger.error("Failed to fetch facilities") + throw err } // Updating current facility with a default first facility when fetching facilities on login From 5cca610815ed0be27913371f8adf0de05b6a35af Mon Sep 17 00:00:00 2001 From: R-Sourabh Date: Thu, 12 Dec 2024 12:29:04 +0530 Subject: [PATCH 03/11] Fixed: field mapping iteration by accessing nested 'value' property on fieldMappingData(#533) --- src/views/BulkUpload.vue | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/src/views/BulkUpload.vue b/src/views/BulkUpload.vue index 7bef4044..9047db22 100644 --- a/src/views/BulkUpload.vue +++ b/src/views/BulkUpload.vue @@ -58,7 +58,7 @@ - + {{ translate("Upload") }} @@ -130,7 +130,6 @@ let fieldMapping = ref({}) let fileColumns = ref([]) let selectedMappingId = ref(null) const fileUploaded = ref(false); -const isUploadDisabled = ref(true); const fields = process.env["VUE_APP_MAPPING_INVCOUNT"] ? JSON.parse(process.env["VUE_APP_MAPPING_INVCOUNT"]) : {} @@ -289,14 +288,9 @@ function mapFields(mapping, mappingId) { const missingFields = Object.values(fieldMappingData.value).filter(field => { if(!csvFields.includes(field)) return field; }); - if(missingFields.length) { - isUploadDisabled.value = true - showToast(translate("Some of the mapping fields are missing in the CSV: ", { missingFields: missingFields.join(", ") })) - } else { - isUploadDisabled.value = false; - } + if(missingFields.length) showToast(translate("Some of the mapping fields are missing in the CSV: ", { missingFields: missingFields.join(", ") })) - Object.keys(fieldMappingData).map((key) => { + Object.keys(fieldMappingData.value).map((key) => { if(!csvFields.includes(fieldMappingData.value[key])){ fieldMappingData.value[key] = ""; } From 36d340bd5a3060bef6c81acfd0a4e6c5d8e26283 Mon Sep 17 00:00:00 2001 From: Yash Maheshwari Date: Mon, 16 Dec 2024 16:29:23 +0530 Subject: [PATCH 04/11] Fixed: logger error message when fetching product stores --- src/store/modules/user/actions.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/store/modules/user/actions.ts b/src/store/modules/user/actions.ts index d80c990e..bc2066f8 100644 --- a/src/store/modules/user/actions.ts +++ b/src/store/modules/user/actions.ts @@ -250,7 +250,7 @@ const actions: ActionTree = { productStores = Object.values(productStoresResp) } } catch(err) { - logger.error("Failed to fetch facilities") + logger.error("Failed to fetch product stores") } // Updating current facility with a default first facility when fetching facilities on login From 403717a211c884628629d2ad05a704e87c058495 Mon Sep 17 00:00:00 2001 From: Yash Maheshwari Date: Mon, 16 Dec 2024 16:31:45 +0530 Subject: [PATCH 05/11] Improved: error message when fetching associated product stores for facilities --- src/store/modules/user/actions.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/store/modules/user/actions.ts b/src/store/modules/user/actions.ts index bc2066f8..04814240 100644 --- a/src/store/modules/user/actions.ts +++ b/src/store/modules/user/actions.ts @@ -210,7 +210,7 @@ const actions: ActionTree = { facility.productStore = resp.data[0] } } catch(err) { - logger.error("Failed to fetch facilities for product store") + logger.error("Failed to fetch product stores for facility") } } From 6ca6798d04d813dd782dbc91b811665c351f293d Mon Sep 17 00:00:00 2001 From: amansinghbais Date: Wed, 18 Dec 2024 18:42:27 +0530 Subject: [PATCH 06/11] Implemented: support for creating hard counts (#528) --- .env.example | 2 +- src/components/Menu.vue | 2 +- src/router/index.ts | 10 + src/services/UtilService.ts | 58 +++- src/store/index.ts | 2 + src/store/modules/util/UtilState.ts | 4 + src/store/modules/util/actions.ts | 28 ++ src/store/modules/util/getters.ts | 10 + src/store/modules/util/index.ts | 19 ++ src/store/modules/util/mutation-types.ts | 2 + src/store/modules/util/mutations.ts | 10 + src/views/Count.vue | 29 +- src/views/Draft.vue | 5 +- src/views/HardCount.vue | 323 +++++++++++++++++++++++ 14 files changed, 489 insertions(+), 15 deletions(-) create mode 100644 src/store/modules/util/UtilState.ts create mode 100644 src/store/modules/util/actions.ts create mode 100644 src/store/modules/util/getters.ts create mode 100644 src/store/modules/util/index.ts create mode 100644 src/store/modules/util/mutation-types.ts create mode 100644 src/store/modules/util/mutations.ts create mode 100644 src/views/HardCount.vue diff --git a/.env.example b/.env.example index a6d915d4..55135f63 100644 --- a/.env.example +++ b/.env.example @@ -1,7 +1,7 @@ VUE_APP_I18N_LOCALE=en VUE_APP_I18N_FALLBACK_LOCALE=en VUE_APP_CACHE_MAX_AGE=3600 -VUE_APP_VIEW_SIZE=10 +VUE_APP_VIEW_SIZE=20 VUE_APP_PERMISSION_ID="INVCOUNT_APP_VIEW" VUE_APP_DEFAULT_LOG_LEVEL="error" VUE_APP_PRDT_IDENT=["productId", "groupId", "groupName", "internalName", "parentProductName", "primaryProductCategoryName", "title"] diff --git a/src/components/Menu.vue b/src/components/Menu.vue index b18b1000..2b3bfa86 100644 --- a/src/components/Menu.vue +++ b/src/components/Menu.vue @@ -68,7 +68,7 @@ export default defineComponent({ url: "/draft", iosIcon: createOutline, mdIcon: createOutline, - childRoutes: ["/draft/", "/bulkUpload"], + childRoutes: ["/draft/", "/bulkUpload", "/hard-count"], meta: { permissionId: "APP_DRAFT_VIEW" } diff --git a/src/router/index.ts b/src/router/index.ts index 7ca0a198..82fb2a1d 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -19,6 +19,7 @@ import Closed from "@/views/Closed.vue"; import StorePermissions from "@/views/StorePermissions.vue"; import Settings from "@/views/Settings.vue"; import BulkUpload from "@/views/BulkUpload.vue" +import HardCount from "@/views/HardCount.vue" // Defining types for the meta values declare module 'vue-router' { @@ -107,6 +108,15 @@ const routes: Array = [ permissionId: "APP_DRAFT_VIEW" } }, + { + path: '/hard-count', + name: 'Hard Count', + component: HardCount, + beforeEnter: authGuard, + meta: { + permissionId: "APP_DRAFT_VIEW" + } + }, { path: "/draft/:inventoryCountImportId", name: "DraftDetail", diff --git a/src/services/UtilService.ts b/src/services/UtilService.ts index 6cece1fd..c66a8911 100644 --- a/src/services/UtilService.ts +++ b/src/services/UtilService.ts @@ -1,4 +1,5 @@ -import { api } from '@/adapter'; +import api, {client} from '@/api'; +import store from '@/store'; const fetchVarianceReasons = async (payload: any): Promise => { return api({ @@ -16,7 +17,62 @@ function getOrdinalSuffix(day: any) { return 'th'; } +const fetchFacilities = async (payload: any): Promise => { + return api({ + url: "facilities", + method: "GET", + params: payload + }) +} + +const createBulCycleCounts = async (payload: any): Promise => { + return api({ + url: `cycleCounts/bulk`, + method: "POST", + data: payload + }) +} + +const fetchFacilityGroups = async (payload: any): Promise => { + const token = store.getters["user/getUserToken"] + const url = store.getters["user/getBaseUrl"] + const baseURL = url.startsWith('http') ? url.includes('/rest/s1/inventory-cycle-count') ? url.replace("inventory-cycle-count", "available-to-promise") : `${url}/rest/s1/available-to-promise/` : `https://${url}.hotwax.io/rest/s1/available-to-promise/`; + + return client({ + url: "facilityGroups", + baseURL, + method: "GET", + params: payload, + headers: { + "api_key": token, + "Content-Type": "application/json" + } + }) +} + +const fetchGroupFacilities = async (payload: any): Promise => { + const token = store.getters["user/getUserToken"] + const url = store.getters["user/getBaseUrl"] + + const baseURL = url.startsWith('http') ? url.includes('/rest/s1/inventory-cycle-count') ? url.replace("inventory-cycle-count", "available-to-promise") : `${url}/rest/s1/available-to-promise/` : `https://${url}.hotwax.io/rest/s1/available-to-promise/`; + + return client({ + url: `facilityGroups/${payload.facilityGroupId}/facilities`, + baseURL, + method: "GET", + params: payload, + headers: { + "api_key": token, + "Content-Type": "application/json" + } + }) +} + export const UtilService = { + createBulCycleCounts, + fetchFacilities, + fetchFacilityGroups, + fetchGroupFacilities, fetchVarianceReasons, getOrdinalSuffix } \ No newline at end of file diff --git a/src/store/index.ts b/src/store/index.ts index 888039f2..0ef093e6 100644 --- a/src/store/index.ts +++ b/src/store/index.ts @@ -7,6 +7,7 @@ import actions from "./actions"; import userModule from "./modules/user"; import productModule from "./modules/product"; import countModule from "./modules/count"; +import utilModule from "./modules/util"; import { setPermissions } from "@/authorization" @@ -32,6 +33,7 @@ const store = createStore({ user: userModule, product: productModule, count: countModule, + util: utilModule, }, }) diff --git a/src/store/modules/util/UtilState.ts b/src/store/modules/util/UtilState.ts new file mode 100644 index 00000000..b6504ab1 --- /dev/null +++ b/src/store/modules/util/UtilState.ts @@ -0,0 +1,4 @@ +export default interface UtilState { + facilities: any; + facilityGroups: any; +} \ No newline at end of file diff --git a/src/store/modules/util/actions.ts b/src/store/modules/util/actions.ts new file mode 100644 index 00000000..dda8e3af --- /dev/null +++ b/src/store/modules/util/actions.ts @@ -0,0 +1,28 @@ +import { ActionTree } from 'vuex' +import RootState from '@/store/RootState' +import * as types from './mutation-types' +import { hasError } from '@/utils'; +import logger from '@/logger' +import { UtilService } from '@/services/UtilService' +import UtilState from './UtilState'; + +const actions: ActionTree = { + + async fetchFacilityGroups ( { commit }) { + let facilityGroups = []; + + try { + const resp = await UtilService.fetchFacilityGroups({ pageSize: 200 }) + if(!hasError(resp)) { + facilityGroups = resp.data; + } else { + throw resp + } + } catch(err) { + logger.error("Failed to fetch facility", err) + } + commit(types.UTIL_FACILITY_GROUPS_UPDATED, facilityGroups); + } +} + +export default actions; \ No newline at end of file diff --git a/src/store/modules/util/getters.ts b/src/store/modules/util/getters.ts new file mode 100644 index 00000000..2a0620bb --- /dev/null +++ b/src/store/modules/util/getters.ts @@ -0,0 +1,10 @@ +import { GetterTree } from "vuex"; +import RootState from "../../RootState"; +import UtilState from "./UtilState"; + +const getters: GetterTree = { + getFacilityGroups(state) { + return state.facilityGroups + } +}; +export default getters; \ No newline at end of file diff --git a/src/store/modules/util/index.ts b/src/store/modules/util/index.ts new file mode 100644 index 00000000..026c291a --- /dev/null +++ b/src/store/modules/util/index.ts @@ -0,0 +1,19 @@ +import actions from './actions' +import getters from './getters' +import mutations from './mutations' +import { Module } from 'vuex' +import RootState from '../../RootState' +import UtilState from './UtilState' + +const utilModule: Module = { + namespaced: true, + state: { + facilityGroups: [], + facilities: [] + }, + getters, + actions, + mutations, +} + +export default utilModule; \ No newline at end of file diff --git a/src/store/modules/util/mutation-types.ts b/src/store/modules/util/mutation-types.ts new file mode 100644 index 00000000..709680ea --- /dev/null +++ b/src/store/modules/util/mutation-types.ts @@ -0,0 +1,2 @@ +export const SN_UTIL = 'util' +export const UTIL_FACILITY_GROUPS_UPDATED = SN_UTIL + '/FACILITY_GROUPS_UPDATED' \ No newline at end of file diff --git a/src/store/modules/util/mutations.ts b/src/store/modules/util/mutations.ts new file mode 100644 index 00000000..1a244474 --- /dev/null +++ b/src/store/modules/util/mutations.ts @@ -0,0 +1,10 @@ +import { MutationTree } from 'vuex' +import * as types from './mutation-types' +import UtilState from './UtilState'; + +const mutations: MutationTree = { + [types.UTIL_FACILITY_GROUPS_UPDATED] (state, payload) { + state.facilityGroups = payload + } +} +export default mutations; \ No newline at end of file diff --git a/src/views/Count.vue b/src/views/Count.vue index d304fd3f..39db4a06 100644 --- a/src/views/Count.vue +++ b/src/views/Count.vue @@ -24,14 +24,21 @@