From 73f5a9d107f7beb15a3a0349bb400fce8f2c061a Mon Sep 17 00:00:00 2001 From: Disha Talreja Date: Mon, 21 Nov 2022 15:11:12 +0530 Subject: [PATCH 01/50] Initial commit(#31a0f22) --- src/store/modules/stock/StockState.ts | 8 ++ src/store/modules/stock/actions.ts | 52 ++++++++ src/store/modules/stock/getters.ts | 13 ++ src/store/modules/stock/index.ts | 23 ++++ src/store/modules/stock/mutation-types.ts | 4 + src/store/modules/stock/mutations.ts | 18 +++ src/views/Inventory.vue | 152 ++++++++++++++++++++++ 7 files changed, 270 insertions(+) create mode 100644 src/store/modules/stock/StockState.ts create mode 100644 src/store/modules/stock/actions.ts create mode 100644 src/store/modules/stock/getters.ts create mode 100644 src/store/modules/stock/index.ts create mode 100644 src/store/modules/stock/mutation-types.ts create mode 100644 src/store/modules/stock/mutations.ts create mode 100644 src/views/Inventory.vue diff --git a/src/store/modules/stock/StockState.ts b/src/store/modules/stock/StockState.ts new file mode 100644 index 00000000..aaa7d56d --- /dev/null +++ b/src/store/modules/stock/StockState.ts @@ -0,0 +1,8 @@ +export default interface OrderState { + list: { + items: any, + original: any, + unidentifiedProductItems: any, + }, + fileName: string + } diff --git a/src/store/modules/stock/actions.ts b/src/store/modules/stock/actions.ts new file mode 100644 index 00000000..2702fe2a --- /dev/null +++ b/src/store/modules/stock/actions.ts @@ -0,0 +1,52 @@ +import { ActionTree } from 'vuex' +import store from '@/store' +import RootState from '@/store/RootState' +import StockState from './StockState' +import * as types from './mutation-types' +import { DateTime } from 'luxon'; + + +const actions: ActionTree = { + async updatedOrderList ({commit, rootGetters}, items) { + const productIds = items.map((item: any) => { + return item.shopifyProductSKU + }) + const viewSize = productIds.length; + const viewIndex = 0; + const payload = { + viewSize, + viewIndex, + productIds + } + await store.dispatch("product/fetchProducts", payload); + const unidentifiedProductItems = [] as any; + items = items.map((item: any) => { + const product = rootGetters['product/getProduct'](item.shopifyProductSKU) + + if(Object.keys(product).length > 0){ + item.parentProductId = product.groupId; + item.internalName = product.internalName; + item.parentProductName = product.parentProductName; + item.imageUrl = product.mainImageUrl; + item.isNewProduct = "N"; + item.isSelected = true; + return item; + } + unidentifiedProductItems.push(item); + return ; + }).filter((item: any) => item); + const original = JSON.parse(JSON.stringify(items)) + + commit(types.ORDER_LIST_UPDATED, { items, original, unidentifiedProductItems }); + }, + updatedOrderListItems({ commit }, orderListItems){ + commit(types.ORDER_LIST_ITEMS_UPDATED, orderListItems) + }, + updateFileName({ commit }, fileName){ + commit(types.ORDER_FILE_NAME_UPDATED, fileName) + }, + clearOrderList({ commit }){ + commit(types.ORDER_LIST_UPDATED, { items: [], original: [], unidentifiedProductItems: []}); + } +} +export default actions; diff --git a/src/store/modules/stock/getters.ts b/src/store/modules/stock/getters.ts new file mode 100644 index 00000000..415ecc43 --- /dev/null +++ b/src/store/modules/stock/getters.ts @@ -0,0 +1,13 @@ +import { GetterTree } from "vuex"; +import OrderState from "./StockState"; +import RootState from "../../RootState"; + +const getters: GetterTree = { + getOrder(state) { + return state.list; + }, + getFileName(state) { + return state.fileName; + } +}; +export default getters; \ No newline at end of file diff --git a/src/store/modules/stock/index.ts b/src/store/modules/stock/index.ts new file mode 100644 index 00000000..6b033475 --- /dev/null +++ b/src/store/modules/stock/index.ts @@ -0,0 +1,23 @@ +import getters from './getters' +import { Module } from 'vuex' +import actions from './actions' +import mutations from './mutations' +import StockState from './StockState' +import RootState from '../../RootState' + +const orderModule: Module = { + namespaced: true, + state: { + list: { + items: [], + original: [], + unidentifiedProductItems: [], + }, + fileName: "" + }, + actions, + getters, + mutations +} + +export default orderModule; \ No newline at end of file diff --git a/src/store/modules/stock/mutation-types.ts b/src/store/modules/stock/mutation-types.ts new file mode 100644 index 00000000..ed11141c --- /dev/null +++ b/src/store/modules/stock/mutation-types.ts @@ -0,0 +1,4 @@ +export const SN_ORDER = 'order' +export const ORDER_LIST_UPDATED = SN_ORDER + '/LIST_UPDATED' +export const ORDER_LIST_ITEMS_UPDATED = SN_ORDER + '/LIST_ITEMS_UPDATED' +export const ORDER_FILE_NAME_UPDATED = SN_ORDER + '/FILE_NAME_UPDATED' diff --git a/src/store/modules/stock/mutations.ts b/src/store/modules/stock/mutations.ts new file mode 100644 index 00000000..cebaafc7 --- /dev/null +++ b/src/store/modules/stock/mutations.ts @@ -0,0 +1,18 @@ +import { MutationTree } from 'vuex' +import StockState from './StockState' +import * as types from './mutation-types' + +const mutations: MutationTree = { + [types.ORDER_LIST_UPDATED] (state, payload) { + state.list.items = payload.items; + state.list.original = payload.original; + state.list.unidentifiedProductItems = payload.unidentifiedProductItems; + }, + [types.ORDER_LIST_ITEMS_UPDATED] (state, payload) { + state.list.items = payload; + }, + [types.ORDER_FILE_NAME_UPDATED] (state, payload) { + state.fileName = payload; + } +} +export default mutations; \ No newline at end of file diff --git a/src/views/Inventory.vue b/src/views/Inventory.vue new file mode 100644 index 00000000..40447b5e --- /dev/null +++ b/src/views/Inventory.vue @@ -0,0 +1,152 @@ + + + + \ No newline at end of file From 66e8b1f89d1f8d163596bc269367fa197b8cf5bb Mon Sep 17 00:00:00 2001 From: Disha Talreja Date: Mon, 28 Nov 2022 18:51:52 +0530 Subject: [PATCH 02/50] Implemented inventory details page(#31a0f22) --- src/components/Menu.vue | 9 +- src/router/index.ts | 14 + src/store/index.ts | 4 +- src/store/modules/stock/StockState.ts | 16 +- src/store/modules/stock/actions.ts | 21 +- src/store/modules/stock/getters.ts | 9 +- src/store/modules/stock/mutation-types.ts | 6 +- src/store/modules/stock/mutations.ts | 8 +- src/views/Inventory.vue | 8 +- src/views/InventoryDetail.vue | 458 ++++++++++++++++++++++ 10 files changed, 506 insertions(+), 47 deletions(-) create mode 100644 src/views/InventoryDetail.vue diff --git a/src/components/Menu.vue b/src/components/Menu.vue index d338e684..d3573177 100644 --- a/src/components/Menu.vue +++ b/src/components/Menu.vue @@ -55,7 +55,7 @@ import { import { defineComponent, ref } from "vue"; import { mapGetters } from "vuex"; -import { settings, calendar } from "ionicons/icons"; +import { settings, calendar, albumsOutline } from "ionicons/icons"; import { useStore } from "@/store"; export default defineComponent({ @@ -101,6 +101,12 @@ export default defineComponent({ const store = useStore(); const selectedIndex = ref(0); const appPages = [ + { + title: "Inventory", + url: "/inventory", + iosIcon: albumsOutline, + mdIcon: albumsOutline + }, { title: "Purchase order", url: "/purchase-order", @@ -117,6 +123,7 @@ export default defineComponent({ return { selectedIndex, appPages, + albumsOutline, calendar, settings, store diff --git a/src/router/index.ts b/src/router/index.ts index 3a708f06..b3f90086 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -2,6 +2,8 @@ import { createRouter, createWebHistory } from '@ionic/vue-router'; import { RouteRecordRaw } from 'vue-router'; import PurchaseOrder from '@/views/PurchaseOrder.vue' import OrderDetail from '@/views/OrderDetail.vue' +import Inventory from '@/views/Inventory.vue' +import InventoryDetail from '@/views/InventoryDetail.vue' import Login from '@/views/Login.vue' import Settings from "@/views/Settings.vue" import store from '@/store' @@ -39,6 +41,18 @@ const routes: Array = [ component: OrderDetail, beforeEnter: authGuard }, + { + path: '/inventory', + name: 'Inventory', + component: Inventory, + beforeEnter: authGuard + }, + { + path: '/inventory-detail', + name: 'InventoryDetail', + component: InventoryDetail, + beforeEnter: authGuard + }, { path: '/login', name: 'Login', diff --git a/src/store/index.ts b/src/store/index.ts index 60efd539..729b603e 100644 --- a/src/store/index.ts +++ b/src/store/index.ts @@ -7,6 +7,7 @@ import createPersistedState from "vuex-persistedstate"; import userModule from './modules/user'; import productModule from "./modules/product"; import orderModule from "./modules/order"; +import stockModule from "./modules/stock"; // TODO check how to register it from the components only @@ -33,7 +34,8 @@ const store = createStore({ modules: { 'user': userModule, 'product': productModule, - 'order': orderModule + 'order': orderModule, + 'stock': stockModule }, }) diff --git a/src/store/modules/stock/StockState.ts b/src/store/modules/stock/StockState.ts index aaa7d56d..4f6ef02c 100644 --- a/src/store/modules/stock/StockState.ts +++ b/src/store/modules/stock/StockState.ts @@ -1,8 +1,8 @@ -export default interface OrderState { - list: { - items: any, - original: any, - unidentifiedProductItems: any, - }, - fileName: string - } +export default interface StockState { + list: { + items: any, + original: any, + unidentifiedProductItems: any, + }, + fileName: string +} diff --git a/src/store/modules/stock/actions.ts b/src/store/modules/stock/actions.ts index 2702fe2a..9e00b38c 100644 --- a/src/store/modules/stock/actions.ts +++ b/src/store/modules/stock/actions.ts @@ -3,13 +3,11 @@ import store from '@/store' import RootState from '@/store/RootState' import StockState from './StockState' import * as types from './mutation-types' -import { DateTime } from 'luxon'; - const actions: ActionTree = { - async updatedOrderList ({commit, rootGetters}, items) { + async updatedStockList ({commit, rootGetters}, items) { const productIds = items.map((item: any) => { - return item.shopifyProductSKU + return item.productSKU }) const viewSize = productIds.length; const viewIndex = 0; @@ -21,8 +19,8 @@ const actions: ActionTree = { await store.dispatch("product/fetchProducts", payload); const unidentifiedProductItems = [] as any; items = items.map((item: any) => { - const product = rootGetters['product/getProduct'](item.shopifyProductSKU) - + const product = rootGetters['product/getProduct'](item.productSKU) + if(Object.keys(product).length > 0){ item.parentProductId = product.groupId; item.internalName = product.internalName; @@ -37,16 +35,7 @@ const actions: ActionTree = { }).filter((item: any) => item); const original = JSON.parse(JSON.stringify(items)) - commit(types.ORDER_LIST_UPDATED, { items, original, unidentifiedProductItems }); - }, - updatedOrderListItems({ commit }, orderListItems){ - commit(types.ORDER_LIST_ITEMS_UPDATED, orderListItems) + commit(types.STOCK_LIST_UPDATED, { items, original, unidentifiedProductItems }); }, - updateFileName({ commit }, fileName){ - commit(types.ORDER_FILE_NAME_UPDATED, fileName) - }, - clearOrderList({ commit }){ - commit(types.ORDER_LIST_UPDATED, { items: [], original: [], unidentifiedProductItems: []}); - } } export default actions; diff --git a/src/store/modules/stock/getters.ts b/src/store/modules/stock/getters.ts index 415ecc43..c0b4441f 100644 --- a/src/store/modules/stock/getters.ts +++ b/src/store/modules/stock/getters.ts @@ -3,11 +3,8 @@ import OrderState from "./StockState"; import RootState from "../../RootState"; const getters: GetterTree = { - getOrder(state) { - return state.list; - }, - getFileName(state) { - return state.fileName; - } + getStock(state) { + return state.list; + }, }; export default getters; \ No newline at end of file diff --git a/src/store/modules/stock/mutation-types.ts b/src/store/modules/stock/mutation-types.ts index ed11141c..56ee79ee 100644 --- a/src/store/modules/stock/mutation-types.ts +++ b/src/store/modules/stock/mutation-types.ts @@ -1,4 +1,2 @@ -export const SN_ORDER = 'order' -export const ORDER_LIST_UPDATED = SN_ORDER + '/LIST_UPDATED' -export const ORDER_LIST_ITEMS_UPDATED = SN_ORDER + '/LIST_ITEMS_UPDATED' -export const ORDER_FILE_NAME_UPDATED = SN_ORDER + '/FILE_NAME_UPDATED' +export const SN_STOCK = 'stock' +export const STOCK_LIST_UPDATED = SN_STOCK + '/LIST_UPDATED' diff --git a/src/store/modules/stock/mutations.ts b/src/store/modules/stock/mutations.ts index cebaafc7..97e4b281 100644 --- a/src/store/modules/stock/mutations.ts +++ b/src/store/modules/stock/mutations.ts @@ -3,16 +3,10 @@ import StockState from './StockState' import * as types from './mutation-types' const mutations: MutationTree = { - [types.ORDER_LIST_UPDATED] (state, payload) { + [types.STOCK_LIST_UPDATED] (state, payload) { state.list.items = payload.items; state.list.original = payload.original; state.list.unidentifiedProductItems = payload.unidentifiedProductItems; }, - [types.ORDER_LIST_ITEMS_UPDATED] (state, payload) { - state.list.items = payload; - }, - [types.ORDER_FILE_NAME_UPDATED] (state, payload) { - state.fileName = payload; - } } export default mutations; \ No newline at end of file diff --git a/src/views/Inventory.vue b/src/views/Inventory.vue index 40447b5e..e85de27a 100644 --- a/src/views/Inventory.vue +++ b/src/views/Inventory.vue @@ -3,14 +3,14 @@ - {{ $t("Purchase orders") }} + {{ $t("Inventory") }}
- {{ file.name ? $t("Purchase order ") + file.name : $t('Purchase order') }} + {{ file.name ? $t("Inventory ") + file.name : $t('Inventory') }} @@ -118,9 +118,9 @@ export default defineComponent({ externalFacilityId: item[this.facilityField] } }) - this.store.dispatch('order/updatedOrderList', this.productsList); + this.store.dispatch('stock/updatedStockList', this.productsList); this.router.push({ - name:'PurchaseOrderDetail' + name:'InventoryDetail' }) }, }, diff --git a/src/views/InventoryDetail.vue b/src/views/InventoryDetail.vue new file mode 100644 index 00000000..45a53b98 --- /dev/null +++ b/src/views/InventoryDetail.vue @@ -0,0 +1,458 @@ + + + + \ No newline at end of file From e879dc51fe5532fec64cba490b9f362b45e30f19 Mon Sep 17 00:00:00 2001 From: Disha Talreja Date: Fri, 2 Dec 2022 19:06:03 +0530 Subject: [PATCH 03/50] Implemented logic to fetch facility locations and option to update facility location(#31a0f22) --- src/services/UserService.ts | 19 ++++++++--- src/store/modules/stock/actions.ts | 6 ++-- src/store/modules/user/UserState.ts | 1 + src/store/modules/user/actions.ts | 37 +++++++++++++++++++++ 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 | 6 +++- src/views/Inventory.vue | 11 ++++++- src/views/InventoryDetail.vue | 41 +++++++++--------------- 10 files changed, 93 insertions(+), 37 deletions(-) diff --git a/src/services/UserService.ts b/src/services/UserService.ts index 82175e75..06676bb1 100644 --- a/src/services/UserService.ts +++ b/src/services/UserService.ts @@ -44,10 +44,19 @@ const setUserTimeZone = async (payload: any): Promise => { }); } +const getFacilityLocations = async (payload: any): Promise => { + return api({ + url: "/performFind", + method: "POST", + data: payload + }) +} + export const UserService = { - login, - getAvailableTimeZones, - getProfile, - setUserTimeZone, - checkPermission + login, + getAvailableTimeZones, + getProfile, + setUserTimeZone, + checkPermission, + getFacilityLocations } \ No newline at end of file diff --git a/src/store/modules/stock/actions.ts b/src/store/modules/stock/actions.ts index 9e00b38c..435ddc2d 100644 --- a/src/store/modules/stock/actions.ts +++ b/src/store/modules/stock/actions.ts @@ -6,9 +6,8 @@ import * as types from './mutation-types' const actions: ActionTree = { async updatedStockList ({commit, rootGetters}, items) { - const productIds = items.map((item: any) => { - return item.productSKU - }) + const productIds = items.map((item: any) => item.productSKU) + const facilityIds = items.map((item: any) => item.externalFacilityId) const viewSize = productIds.length; const viewIndex = 0; const payload = { @@ -16,6 +15,7 @@ const actions: ActionTree = { viewIndex, productIds } + await store.dispatch('user/fetchFacilityLocations', facilityIds); await store.dispatch("product/fetchProducts", payload); const unidentifiedProductItems = [] as any; items = items.map((item: any) => { diff --git a/src/store/modules/user/UserState.ts b/src/store/modules/user/UserState.ts index a4a0f729..1925be11 100644 --- a/src/store/modules/user/UserState.ts +++ b/src/store/modules/user/UserState.ts @@ -4,4 +4,5 @@ export default interface UserState { currentFacility: object; instanceUrl: string; preferredDateTimeFormat: string; + facilityLocationsByFacilityId: any; } \ No newline at end of file diff --git a/src/store/modules/user/actions.ts b/src/store/modules/user/actions.ts index 665aa834..29938bce 100644 --- a/src/store/modules/user/actions.ts +++ b/src/store/modules/user/actions.ts @@ -116,6 +116,43 @@ const actions: ActionTree = { */ setUserInstanceUrl ({ commit }, payload){ commit(types.USER_INSTANCE_URL_UPDATED, payload) + }, + + async fetchFacilityLocations({ commit }, facilityId){ + let resp; + const params = { + "inputFields": { + facilityId, + "facilityId_op": 'in' + }, + // Assuming we will not have more than 20 facility locations, hardcoded the viewSize value 20. + "viewSize": 20, + "fieldList": ["locationSeqId", "areaId", "aisleId", "sectionId", "levelId", "positionId", "facilityId"], + "entityName": "FacilityLocation", + "distinct": "Y", + "noConditionFind": "Y" + } + try{ + resp = await UserService.getFacilityLocations(params); + if(resp.status === 200 && !hasError(resp) && resp.data?.count > 0) { + let facilityLocations = resp.data.docs + facilityLocations = facilityLocations.reduce((locations: any, location: any) => { + const locationPath = [location.areaId, location.aisleId, location.sectionId, location.levelId, location.positionId].filter((value: any) => value).join(""); + const facilityLocation = { + locationSeqId: location.locationSeqId, + locationPath: locationPath + } + locations[location.facilityId] ? locations[location.facilityId].push(facilityLocation) : locations[location.facilityId] = [facilityLocation] + return locations; + }, {}) + commit(types.USER_FACILITY_LOCATIONS_BY_FACILITY_ID, facilityLocations); + return facilityLocations; + } else { + console.error(resp); + } + } catch(err) { + console.error(err); + } } } diff --git a/src/store/modules/user/getters.ts b/src/store/modules/user/getters.ts index 1ba4aed6..06bfa077 100644 --- a/src/store/modules/user/getters.ts +++ b/src/store/modules/user/getters.ts @@ -24,6 +24,9 @@ const getters: GetterTree = { }, getDateTimeFormat (state) { return state.preferredDateTimeFormat; + }, + getFacilityLocationsByFacilityId: (state) => (facilityId: string) => { + return state.facilityLocationsByFacilityId[facilityId] } } 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 ed5247b1..aebc15e0 100644 --- a/src/store/modules/user/index.ts +++ b/src/store/modules/user/index.ts @@ -12,7 +12,8 @@ const userModule: Module = { current: null, currentFacility: {}, instanceUrl: '', - preferredDateTimeFormat: '' + preferredDateTimeFormat: '', + facilityLocationsByFacilityId: {} }, getters, actions, diff --git a/src/store/modules/user/mutation-types.ts b/src/store/modules/user/mutation-types.ts index 65cfd3c8..73769e55 100644 --- a/src/store/modules/user/mutation-types.ts +++ b/src/store/modules/user/mutation-types.ts @@ -4,4 +4,5 @@ export const USER_END_SESSION = SN_USER + '/END_SESSION' export const USER_INFO_UPDATED = SN_USER + '/INFO_UPDATED' export const USER_CURRENT_FACILITY_UPDATED = SN_USER + '/CURRENT_FACILITY_UPDATED' export const USER_INSTANCE_URL_UPDATED = SN_USER + '/INSTANCE_URL_UPDATED' -export const USER_DATETIME_FORMAT_UPDATED = SN_USER + '/DATETIME_FORMAT_UPDATED' \ No newline at end of file +export const USER_DATETIME_FORMAT_UPDATED = SN_USER + '/DATETIME_FORMAT_UPDATED' +export const USER_FACILITY_LOCATIONS_BY_FACILITY_ID = SN_USER + '/FACILITY_LOCATIONS_BY_FACILITY_ID' \ No newline at end of file diff --git a/src/store/modules/user/mutations.ts b/src/store/modules/user/mutations.ts index 9940d786..54e28496 100644 --- a/src/store/modules/user/mutations.ts +++ b/src/store/modules/user/mutations.ts @@ -9,7 +9,8 @@ const mutations: MutationTree = { [types.USER_END_SESSION] (state) { state.token = '' state.current = null - state.currentFacility = {} + state.currentFacility = {}, + state.facilityLocationsByFacilityId = {} }, [types.USER_INFO_UPDATED] (state, payload) { state.current = payload @@ -22,6 +23,9 @@ const mutations: MutationTree = { }, [types.USER_DATETIME_FORMAT_UPDATED] (state, payload) { state.preferredDateTimeFormat = payload; + }, + [types.USER_FACILITY_LOCATIONS_BY_FACILITY_ID] (state, payload) { + state.facilityLocationsByFacilityId = payload; } } export default mutations; \ No newline at end of file diff --git a/src/views/Inventory.vue b/src/views/Inventory.vue index e85de27a..7c74be60 100644 --- a/src/views/Inventory.vue +++ b/src/views/Inventory.vue @@ -38,6 +38,13 @@ {{ prop }} + + + {{ $t("Facility Location") }} + + {{ prop }} + + @@ -88,6 +95,7 @@ export default defineComponent({ productSkuField: "", quantityField: "", facilityField: "", + locationSeqIdField: "", productsList: [], } }, @@ -115,7 +123,8 @@ export default defineComponent({ productSKU: item[this.productSkuField], quantityOrdered: item[this.quantityField], facilityId: '', - externalFacilityId: item[this.facilityField] + externalFacilityId: item[this.facilityField], + locationSeqId: item[this.locationSeqIdField] } }) this.store.dispatch('stock/updatedStockList', this.productsList); diff --git a/src/views/InventoryDetail.vue b/src/views/InventoryDetail.vue index 45a53b98..9d19eee0 100644 --- a/src/views/InventoryDetail.vue +++ b/src/views/InventoryDetail.vue @@ -25,27 +25,9 @@
- - {{ $t("Buffer location") }} - - - - - {{ $t("Inventory buffer") }} - - - - - {{ $t("Catalog") }} - - {{ $t("Backorder") }} - {{ $t("Preorder") }} - - - {{ $t("Facility") }} - + {{ facility.facilityName }} @@ -121,10 +103,11 @@ {{ item.externalFacilityId }} - - 234567890 + + {{ facilityLocation.locationSeqId }} + @@ -156,7 +139,7 @@ import { useRouter } from 'vue-router'; import { DateTime } from 'luxon'; import { showToast } from '@/utils'; import { translate } from "@/i18n"; -import { IonPage, IonHeader, IonToolbar, IonBackButton, IonTitle, IonContent, IonSearchbar, IonItem, IonThumbnail, IonLabel, IonInput, IonChip, IonIcon, IonButton, IonCheckbox, IonSelect, IonSelectOption, IonButtons, popoverController, IonFab, IonFabButton, alertController, modalController } from '@ionic/vue' +import { IonPage, IonHeader, IonToolbar, IonBackButton, IonTitle, IonContent, IonSearchbar, IonItem, IonThumbnail, IonLabel, IonChip, IonIcon, IonButton, IonCheckbox, IonSelect, IonSelectOption, IonButtons, popoverController, IonFab, IonFabButton, alertController, modalController } from '@ionic/vue' import { ellipsisVerticalOutline, locationOutline, checkboxOutline, cloudUploadOutline, arrowUndoOutline } from 'ionicons/icons' import { hasError } from "@/utils"; import MissingSkuModal from "@/components/MissingSkuModal.vue" @@ -175,7 +158,6 @@ export default defineComponent({ IonItem, IonThumbnail, IonLabel, - IonInput, IonChip, IonIcon, IonButton, @@ -192,7 +174,8 @@ export default defineComponent({ getProduct: 'product/getProduct', instanceUrl: 'user/getInstanceUrl', dateTimeFormat : 'user/getDateTimeFormat', - fileName: 'order/getFileName' + fileName: 'order/getFileName', + getFacilityLocationsByFacilityId: 'user/getFacilityLocationsByFacilityId' }), orderId(){ return (this as any).ordersList.items[0]?.orderId @@ -208,7 +191,8 @@ export default defineComponent({ queryString: "", searchedProduct: {} as any, isParentProductUpdated: false, - isPOUploadedSuccessfully: false + isPOUploadedSuccessfully: false, + facilityLocations: {} } }, ionViewDidEnter(){ @@ -243,6 +227,9 @@ export default defineComponent({ }, methods: { + setFacilityLocation(ev: Event){ + console.log(ev); + }, async listMissingSkus() { const missingSkuModal = await modalController.create({ component: MissingSkuModal, @@ -439,6 +426,10 @@ export default defineComponent({ background-color: var(--ion-color-light); } +ion-chip > ion-select { + padding: 0px; +} + @media (min-width: 991px) { .header { display: grid; From 5fdc602930e977454fb5719df1633ec2c87ae5e0 Mon Sep 17 00:00:00 2001 From: Disha Talreja Date: Mon, 5 Dec 2022 18:22:27 +0530 Subject: [PATCH 04/50] Removed unwanted code, implement logic to change locationSeqId and fixed the UI of inventory detail page(#31a0f22) --- src/components/ProductPopover.vue | 23 +++--- src/locales/en.json | 1 + src/store/modules/stock/actions.ts | 3 + src/store/modules/stock/mutation-types.ts | 1 + src/store/modules/stock/mutations.ts | 3 + src/theme/variables.css | 4 +- src/views/InventoryDetail.vue | 96 ++++++++++------------- src/views/OrderDetail.vue | 10 +-- 8 files changed, 72 insertions(+), 69 deletions(-) diff --git a/src/components/ProductPopover.vue b/src/components/ProductPopover.vue index d3c64f13..f18a5916 100644 --- a/src/components/ProductPopover.vue +++ b/src/components/ProductPopover.vue @@ -23,12 +23,13 @@ import { arrowUndoOutline } from 'ionicons/icons'; export default defineComponent({ - props: ['id', 'isVirtual', 'item'], + props: ['id', 'isVirtual', 'item', 'type'], name: 'parentProductPopover', components: { IonContent, IonIcon, IonLabel, IonItem }, computed: { ...mapGetters({ ordersList: 'order/getOrder', + stock: 'stock/getStock' }), }, methods: { @@ -39,20 +40,23 @@ export default defineComponent({ this.isVirtual ? this.onlySelectParentProduct() : this.onlySelectSingleProduct(); }, onlySelectParentProduct() { - this.ordersList.items.forEach(element => { + const items = this.type === 'order' ? this.ordersList.items : this.stock.items; + items.forEach(element => { element.isSelected = element.parentProductId === this.id; }); popoverController.dismiss({ dismissed: true }); }, onlySelectSingleProduct() { - this.ordersList.items.forEach(element => { + const items = this.type === 'order' ? this.ordersList.items : this.stock.items; + items.forEach(element => { element.isSelected = element.internalName === this.id; }); popoverController.dismiss({ dismissed: true }); }, revertProduct() { - const original = JSON.parse(JSON.stringify(this.ordersList.original)); - const items = this.ordersList.items.map(element => { + const items = this.type === 'order' ? this.ordersList.items : this.stock.items; + const original = this.type === 'order' ? JSON.parse(JSON.stringify(this.ordersList.original)) : JSON.parse(JSON.stringify(this.stock.original)); + const itemsList = items.map(element => { if(element.internalName === this.id) { const item = original.find(item => { return item.internalName === this.id; @@ -61,12 +65,13 @@ export default defineComponent({ } return element; }); - this.store.dispatch('order/updatedOrderListItems', items) + this.type === 'order' ? this.store.dispatch('order/updatedOrderListItems', itemsList) : this.store.dispatch('stock/updatedStockListItems', itemsList) popoverController.dismiss({ dismissed: true }); }, revertParentProduct(){ - const original = JSON.parse(JSON.stringify(this.ordersList.original)); - const items = this.ordersList.items.map(element => { + const items = this.type === 'order' ? this.ordersList.items : this.stock.items; + const original = this.type === 'order' ? JSON.parse(JSON.stringify(this.ordersList.original)) : JSON.parse(JSON.stringify(this.stock.original)); + const itemsList = items.map(element => { if(element.parentProductId === this.id) { const item = original.find(item => { return item.parentProductId === this.id && item.shopifyProductSKU === element.shopifyProductSKU; @@ -75,7 +80,7 @@ export default defineComponent({ } return element; }); - this.store.dispatch('order/updatedOrderListItems', items) + this.type === 'order' ? this.store.dispatch('order/updatedOrderListItems', itemsList) : this.store.dispatch('stock/updatedStockListItems', itemsList); popoverController.dismiss({ dismissed: true }); } }, diff --git a/src/locales/en.json b/src/locales/en.json index 35aeadd2..b4c1760e 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -75,5 +75,6 @@ "Update time zone": "Update time zone", "Upload": "Upload", "Username": "Username", + "View": "View", "Would you like to update your time zone to . Your profile is currently set to . This setting can always be changed from the settings menu.": "Would you like to update your time zone to {localTimeZone}. Your profile is currently set to {profileTimeZone}. This setting can always be changed from the settings menu." } \ No newline at end of file diff --git a/src/store/modules/stock/actions.ts b/src/store/modules/stock/actions.ts index 435ddc2d..7171b121 100644 --- a/src/store/modules/stock/actions.ts +++ b/src/store/modules/stock/actions.ts @@ -37,5 +37,8 @@ const actions: ActionTree = { commit(types.STOCK_LIST_UPDATED, { items, original, unidentifiedProductItems }); }, + updatedStockListItems({ commit }, stockItems){ + commit(types.STOCK_LIST_ITEMS_UPDATED, stockItems); + }, } export default actions; diff --git a/src/store/modules/stock/mutation-types.ts b/src/store/modules/stock/mutation-types.ts index 56ee79ee..295a2b98 100644 --- a/src/store/modules/stock/mutation-types.ts +++ b/src/store/modules/stock/mutation-types.ts @@ -1,2 +1,3 @@ export const SN_STOCK = 'stock' export const STOCK_LIST_UPDATED = SN_STOCK + '/LIST_UPDATED' +export const STOCK_LIST_ITEMS_UPDATED = SN_STOCK + '/LIST_ITEMS_UPDATED' \ No newline at end of file diff --git a/src/store/modules/stock/mutations.ts b/src/store/modules/stock/mutations.ts index 97e4b281..62d46bab 100644 --- a/src/store/modules/stock/mutations.ts +++ b/src/store/modules/stock/mutations.ts @@ -8,5 +8,8 @@ const mutations: MutationTree = { state.list.original = payload.original; state.list.unidentifiedProductItems = payload.unidentifiedProductItems; }, + [types.STOCK_LIST_ITEMS_UPDATED] (state, payload) { + state.list.items = payload; + }, } export default mutations; \ No newline at end of file diff --git a/src/theme/variables.css b/src/theme/variables.css index c9177b47..29dcb8be 100644 --- a/src/theme/variables.css +++ b/src/theme/variables.css @@ -292,7 +292,7 @@ body { } .tablet { - display: unset; + display: flex; } } @@ -306,7 +306,7 @@ body { } .tablet { - display: unset; + display: flex; } } diff --git a/src/views/InventoryDetail.vue b/src/views/InventoryDetail.vue index 9d19eee0..aa2bbca5 100644 --- a/src/views/InventoryDetail.vue +++ b/src/views/InventoryDetail.vue @@ -2,8 +2,7 @@ - - {{ orderId }} + @@ -47,30 +46,32 @@ - {{ searchedProduct.isNewProduct === "Y"? $t("Preorder") : $t("Backorder") }} + {{ searchedProduct.quantityOrdered }} {{ $t("Items") }} - - {{ searchedProduct.quantityOrdered }} {{ $t("Ordered") }} + + {{ searchedProduct.externalFacilityId }} - - - {{ searchedProduct.arrivalDate }} + + + + {{ facilityLocation.locationSeqId }} + - +
-
+
- {{ getParentInformation(id, ordersList.items).parentProductName }} + {{ getParentInformation(id, stock.items).parentProductName }}
@@ -81,11 +82,11 @@ - +
-
+
@@ -97,7 +98,7 @@ - {{ item.quantityOrdered }} {{ $t("Ordered") }} + {{ item.quantityOrdered }} {{ $t("Items") }} @@ -105,7 +106,7 @@ - + {{ facilityLocation.locationSeqId }} @@ -113,7 +114,7 @@ - +
@@ -136,10 +137,9 @@ import ProductPopover from '@/components/ProductPopover.vue' import { defineComponent } from 'vue'; import { mapGetters, useStore } from "vuex"; import { useRouter } from 'vue-router'; -import { DateTime } from 'luxon'; import { showToast } from '@/utils'; import { translate } from "@/i18n"; -import { IonPage, IonHeader, IonToolbar, IonBackButton, IonTitle, IonContent, IonSearchbar, IonItem, IonThumbnail, IonLabel, IonChip, IonIcon, IonButton, IonCheckbox, IonSelect, IonSelectOption, IonButtons, popoverController, IonFab, IonFabButton, alertController, modalController } from '@ionic/vue' +import { IonPage, IonHeader, IonToolbar, IonBackButton, IonContent, IonSearchbar, IonItem, IonThumbnail, IonLabel, IonChip, IonIcon, IonButton, IonCheckbox, IonSelect, IonSelectOption, IonButtons, popoverController, IonFab, IonFabButton, alertController, modalController } from '@ionic/vue' import { ellipsisVerticalOutline, locationOutline, checkboxOutline, cloudUploadOutline, arrowUndoOutline } from 'ionicons/icons' import { hasError } from "@/utils"; import MissingSkuModal from "@/components/MissingSkuModal.vue" @@ -152,7 +152,6 @@ export default defineComponent({ IonHeader, IonToolbar, IonBackButton, - IonTitle, IonContent, IonSearchbar, IonItem, @@ -170,23 +169,16 @@ export default defineComponent({ }, computed: { ...mapGetters({ - ordersList: 'stock/getStock', + stock: 'stock/getStock', getProduct: 'product/getProduct', instanceUrl: 'user/getInstanceUrl', - dateTimeFormat : 'user/getDateTimeFormat', fileName: 'order/getFileName', getFacilityLocationsByFacilityId: 'user/getFacilityLocationsByFacilityId' - }), - orderId(){ - return (this as any).ordersList.items[0]?.orderId - } + }) }, data() { return { - numberOfDays: 0, - numberOfPieces: 0, - catalog: "N", - facilityId: (this as any)?.ordersList?.items[0]?.facilityId, + facilityId: (this as any)?.stock?.items[0]?.facilityId, facilities: [] as any, queryString: "", searchedProduct: {} as any, @@ -202,7 +194,7 @@ export default defineComponent({ let canLeave = false; const alert = await alertController.create({ header: this.$t("Leave page"), - message: this.$t("Any edits made to this PO will be lost."), + message: this.$t("Any edits made to this CSV will be lost."), buttons: [ { text: this.$t("STAY"), @@ -227,36 +219,36 @@ export default defineComponent({ }, methods: { - setFacilityLocation(ev: Event){ - console.log(ev); + setFacilityLocation(ev: CustomEvent, product: any){ + this.stock.items.map((item: any) => { + if(item.internalName === product.internalName){ + item.locationSeqId = ev.detail.value; + } + }); + this.store.dispatch('stock/updatedStockListItems', this.stock.items); }, async listMissingSkus() { const missingSkuModal = await modalController.create({ component: MissingSkuModal, - componentProps: { 'unidentifiedProductItems': this.ordersList.unidentifiedProductItems } + componentProps: { 'unidentifiedProductItems': this.stock.unidentifiedProductItems } }); return missingSkuModal.present(); }, searchProduct(sku: any) { const product = this.getProduct(sku); - this.searchedProduct = this.ordersList.items.find((item: any) => { + this.searchedProduct = this.stock.items.find((item: any) => { return item.internalName === product.internalName; }) }, async save(){ - const uploadData = this.ordersList.items.filter((item: any) => { + const uploadData = this.stock.items.filter((item: any) => { return item.isSelected; }).map((item: any) => { return { "poId": " ", - "externalId": item.orderId, "facilityId": item.facilityId, "externalFacilityId": item.externalFacilityId, - //Convert date in the format accepted by the server. - "arrivalDate": DateTime.fromFormat(item.arrivalDate, this.dateTimeFormat).toFormat('MM/dd/yyyy'), - "quantity": item.quantityOrdered, - "isNewProduct": item.isNewProduct, - "idValue": item.shopifyProductSKU, + "idValue": item.productSKU, "idType": "SKU" }; }) @@ -269,7 +261,7 @@ export default defineComponent({ message: this.$t("Make sure all the data you have entered is correct and only pre-order or backorder items are selected."), buttons: [ { - text: this.$t("cancel"), + text: this.$t("Cancel"), role: 'cancel', }, { @@ -321,14 +313,14 @@ export default defineComponent({ console.error(err) } }, - async UpdateProduct(ev: Event, id: any, isVirtual: boolean, item: any) { + async UpdateProduct(ev: Event, id: any, isVirtual: boolean, item: any, type: string) { const popover = await popoverController .create({ component: ProductPopover, event: ev, translucent: true, showBackdrop: true, - componentProps: { 'id': id, 'isVirtual': isVirtual, 'item': item } + componentProps: { 'id': id, 'isVirtual': isVirtual, 'item': item, 'type': type } }); popover.onDidDismiss().then(() => { this.searchProduct(this.queryString); @@ -336,28 +328,26 @@ export default defineComponent({ return popover.present(); }, isParentProductChecked(parentProductId: string) { - const items = this.getGroupItems(parentProductId, this.ordersList.items); + const items = this.getGroupItems(parentProductId, this.stock.items); return items.every((item: any) => item.isSelected) }, selectProduct(item: any, event: any) { item.isSelected = event.detail.checked; }, revertAll() { - const original = JSON.parse(JSON.stringify(this.ordersList.original)); - this.store.dispatch('order/updatedOrderListItems', original); + const original = JSON.parse(JSON.stringify(this.stock.original)); + this.store.dispatch('stock/updatedStockListItems', original); }, apply() { - this.ordersList.items.map((item: any) => { + this.stock.items.map((item: any) => { if (item.isSelected) { - item.quantityOrdered -= this.numberOfPieces - item.isNewProduct = this.catalog; if(this.facilityId) { item.facilityId = this.facilityId; item.externalFacilityId = ""; } } }) - this.store.dispatch('order/updatedOrderListItems', this.ordersList.items); + this.store.dispatch('stock/updatedStockListItems', this.stock.items); }, getGroupList (items: any) { return Array.from(new Set(items.map((ele: any) => ele.parentProductId))); @@ -369,14 +359,14 @@ export default defineComponent({ return items.find((item: any) => item.parentProductId == id) }, selectAllItems() { - this.ordersList.items.forEach((item: any) => { + this.stock.items.forEach((item: any) => { item.isSelected = true; }) }, selectParentProduct(parentProductId: any, event: any) { // Todo: Need to find a better approach. if(this.isParentProductUpdated){ - this.ordersList.items.forEach((item: any) => { + this.stock.items.forEach((item: any) => { if (item.parentProductId === parentProductId) { item.isSelected = event.detail.checked; } diff --git a/src/views/OrderDetail.vue b/src/views/OrderDetail.vue index 7acbca81..1f65e708 100644 --- a/src/views/OrderDetail.vue +++ b/src/views/OrderDetail.vue @@ -80,7 +80,7 @@ - +
@@ -99,7 +99,7 @@ - +
@@ -130,7 +130,7 @@ - +
@@ -338,14 +338,14 @@ export default defineComponent({ console.error(err) } }, - async UpdateProduct(ev: Event, id: any, isVirtual: boolean, item: any) { + async UpdateProduct(ev: Event, id: any, isVirtual: boolean, item: any, type: string) { const popover = await popoverController .create({ component: ProductPopover, event: ev, translucent: true, showBackdrop: true, - componentProps: { 'id': id, 'isVirtual': isVirtual, 'item': item } + componentProps: { 'id': id, 'isVirtual': isVirtual, 'item': item, 'type': type } }); popover.onDidDismiss().then(() => { this.searchProduct(this.queryString); From 07ad7be883c380f49ae693f9498d565a0147afea Mon Sep 17 00:00:00 2001 From: Disha Talreja Date: Mon, 5 Dec 2022 18:31:11 +0530 Subject: [PATCH 05/50] Added static text in en.json file(#31a0f22) --- src/locales/en.json | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/locales/en.json b/src/locales/en.json index b4c1760e..001e80c1 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -1,6 +1,7 @@ { "App": "App", "Apply": "Apply", + "Any edits made to this CSV will be lost.": "Any edits made to this CSV will be lost.", "Any edits made to this PO will be lost.": "Any edits made to this PO will be lost.", "Are you sure you want to change the time zone to?": "Are you sure you want to change the time zone to?", "Arrival date": "Arrival date", @@ -18,12 +19,15 @@ "Enter a custom date time format that you want to use when uploading documents to HotWax Commerce.": "Enter a custom date time format that you want to use when uploading documents to HotWax Commerce.", "Facility": "Facility", "Facility ID": "Facility ID", + "Facility Location": "Facility Location", "File upload": "File upload", "File uploaded successfully": "File uploaded successfully", "Go to OMS": "Go to OMS", "here": "here", "Import": "Import", + "Inventory": "Inventory", "Instance Url": "Instance Url", + "Items": "Items", "Lead time": "Lead time", "LEAVE": "LEAVE", "Leave page": "Leave page", @@ -42,8 +46,10 @@ "Password": "Password", "PO External Order ID": "PO External Order ID", "Preorder": "Preorder", + "Product SKU": "Product SKU", "Purchase order": "Purchase order", "Purchase orders": "Purchase orders", + "Quantity": "Quantity", "Ready to create an app?": "Ready to create an app?", "Review": "Review", "Reset": "Reset", From 725b777ab44eb63423f4228998d7aae5614aa16c Mon Sep 17 00:00:00 2001 From: Disha Talreja Date: Mon, 5 Dec 2022 19:04:53 +0530 Subject: [PATCH 06/50] Improved code to fetch facility locations on click(#31a0f22) --- src/store/modules/user/actions.ts | 20 ++++++++++---------- src/store/modules/user/mutations.ts | 2 +- src/views/InventoryDetail.vue | 15 ++++++++++----- 3 files changed, 21 insertions(+), 16 deletions(-) diff --git a/src/store/modules/user/actions.ts b/src/store/modules/user/actions.ts index 29938bce..9d744b7c 100644 --- a/src/store/modules/user/actions.ts +++ b/src/store/modules/user/actions.ts @@ -120,10 +120,9 @@ const actions: ActionTree = { async fetchFacilityLocations({ commit }, facilityId){ let resp; - const params = { + const payload = { "inputFields": { - facilityId, - "facilityId_op": 'in' + facilityId }, // Assuming we will not have more than 20 facility locations, hardcoded the viewSize value 20. "viewSize": 20, @@ -133,25 +132,26 @@ const actions: ActionTree = { "noConditionFind": "Y" } try{ - resp = await UserService.getFacilityLocations(params); + resp = await UserService.getFacilityLocations(payload); if(resp.status === 200 && !hasError(resp) && resp.data?.count > 0) { let facilityLocations = resp.data.docs - facilityLocations = facilityLocations.reduce((locations: any, location: any) => { + + facilityLocations = facilityLocations.map((location: any) => { const locationPath = [location.areaId, location.aisleId, location.sectionId, location.levelId, location.positionId].filter((value: any) => value).join(""); - const facilityLocation = { + return { locationSeqId: location.locationSeqId, locationPath: locationPath } - locations[location.facilityId] ? locations[location.facilityId].push(facilityLocation) : locations[location.facilityId] = [facilityLocation] - return locations; - }, {}) - commit(types.USER_FACILITY_LOCATIONS_BY_FACILITY_ID, facilityLocations); + }) + commit(types.USER_FACILITY_LOCATIONS_BY_FACILITY_ID, { facilityLocations, facilityId }); return facilityLocations; } else { console.error(resp); + return []; } } catch(err) { console.error(err); + return []; } } } diff --git a/src/store/modules/user/mutations.ts b/src/store/modules/user/mutations.ts index 54e28496..108bb3ce 100644 --- a/src/store/modules/user/mutations.ts +++ b/src/store/modules/user/mutations.ts @@ -25,7 +25,7 @@ const mutations: MutationTree = { state.preferredDateTimeFormat = payload; }, [types.USER_FACILITY_LOCATIONS_BY_FACILITY_ID] (state, payload) { - state.facilityLocationsByFacilityId = payload; + state.facilityLocationsByFacilityId[payload.facilityId] = payload.facilityLocations; } } export default mutations; \ No newline at end of file diff --git a/src/views/InventoryDetail.vue b/src/views/InventoryDetail.vue index aa2bbca5..d9c8a649 100644 --- a/src/views/InventoryDetail.vue +++ b/src/views/InventoryDetail.vue @@ -26,7 +26,7 @@
{{ $t("Facility") }} - + {{ facility.facilityName }} @@ -50,10 +50,10 @@ - {{ searchedProduct.externalFacilityId }} + {{ searchedProduct.externalFacilityId ? searchedProduct.externalFacilityId : searchedProduct.facilityId }} - + {{ facilityLocation.locationSeqId }} @@ -102,9 +102,9 @@ - {{ item.externalFacilityId }} + {{ item.externalFacilityId ? item.externalFacilityId : item.facilityId }} - + {{ facilityLocation.locationSeqId }} @@ -219,6 +219,11 @@ export default defineComponent({ }, methods: { + fetchFacilityLocations(facilityId: any){ + const facilityLocations = this.getFacilityLocationsByFacilityId(facilityId); + if(facilityLocations?.length) return facilityLocations; + return this.store.dispatch('user/fetchFacilityLocations', facilityId); + }, setFacilityLocation(ev: CustomEvent, product: any){ this.stock.items.map((item: any) => { if(item.internalName === product.internalName){ From e8a388db461d7bdb5684eb1cfb6a0064f09c0c19 Mon Sep 17 00:00:00 2001 From: Disha Talreja Date: Mon, 26 Dec 2022 12:31:41 +0530 Subject: [PATCH 07/50] Revert "Improved code to fetch facility locations on click(#31a0f22)" This reverts commit 725b777ab44eb63423f4228998d7aae5614aa16c. --- src/store/modules/user/actions.ts | 19 ++++++++++--------- src/store/modules/user/mutations.ts | 2 +- src/views/InventoryDetail.vue | 15 +++++---------- 3 files changed, 16 insertions(+), 20 deletions(-) diff --git a/src/store/modules/user/actions.ts b/src/store/modules/user/actions.ts index 54daef29..06ad6689 100644 --- a/src/store/modules/user/actions.ts +++ b/src/store/modules/user/actions.ts @@ -120,9 +120,10 @@ const actions: ActionTree = { async fetchFacilityLocations({ commit }, facilityId){ let resp; - const payload = { + const params = { "inputFields": { - facilityId + facilityId, + "facilityId_op": 'in' }, // Assuming we will not have more than 20 facility locations, hardcoded the viewSize value 20. "viewSize": 20, @@ -132,22 +133,22 @@ const actions: ActionTree = { "noConditionFind": "Y" } try{ - resp = await UserService.getFacilityLocations(payload); + resp = await UserService.getFacilityLocations(params); if(resp.status === 200 && !hasError(resp) && resp.data?.count > 0) { let facilityLocations = resp.data.docs - - facilityLocations = facilityLocations.map((location: any) => { + facilityLocations = facilityLocations.reduce((locations: any, location: any) => { const locationPath = [location.areaId, location.aisleId, location.sectionId, location.levelId, location.positionId].filter((value: any) => value).join(""); - return { + const facilityLocation = { locationSeqId: location.locationSeqId, locationPath: locationPath } - }) - commit(types.USER_FACILITY_LOCATIONS_BY_FACILITY_ID, { facilityLocations, facilityId }); + locations[location.facilityId] ? locations[location.facilityId].push(facilityLocation) : locations[location.facilityId] = [facilityLocation] + return locations; + }, {}) + commit(types.USER_FACILITY_LOCATIONS_BY_FACILITY_ID, facilityLocations); return facilityLocations; } else { console.error(resp); - return []; } } catch(err) { console.error(err); diff --git a/src/store/modules/user/mutations.ts b/src/store/modules/user/mutations.ts index 03f14748..c9d5b21f 100644 --- a/src/store/modules/user/mutations.ts +++ b/src/store/modules/user/mutations.ts @@ -28,7 +28,7 @@ const mutations: MutationTree = { state.preferredDateTimeFormat = payload; }, [types.USER_FACILITY_LOCATIONS_BY_FACILITY_ID] (state, payload) { - state.facilityLocationsByFacilityId[payload.facilityId] = payload.facilityLocations; + state.facilityLocationsByFacilityId = payload; } } export default mutations; \ No newline at end of file diff --git a/src/views/InventoryDetail.vue b/src/views/InventoryDetail.vue index d9c8a649..aa2bbca5 100644 --- a/src/views/InventoryDetail.vue +++ b/src/views/InventoryDetail.vue @@ -26,7 +26,7 @@
{{ $t("Facility") }} - + {{ facility.facilityName }} @@ -50,10 +50,10 @@ - {{ searchedProduct.externalFacilityId ? searchedProduct.externalFacilityId : searchedProduct.facilityId }} + {{ searchedProduct.externalFacilityId }} - + {{ facilityLocation.locationSeqId }} @@ -102,9 +102,9 @@ - {{ item.externalFacilityId ? item.externalFacilityId : item.facilityId }} + {{ item.externalFacilityId }} - + {{ facilityLocation.locationSeqId }} @@ -219,11 +219,6 @@ export default defineComponent({ }, methods: { - fetchFacilityLocations(facilityId: any){ - const facilityLocations = this.getFacilityLocationsByFacilityId(facilityId); - if(facilityLocations?.length) return facilityLocations; - return this.store.dispatch('user/fetchFacilityLocations', facilityId); - }, setFacilityLocation(ev: CustomEvent, product: any){ this.stock.items.map((item: any) => { if(item.internalName === product.internalName){ From 9634bedbf4669d234c00d606d4ae6d5d70a1797f Mon Sep 17 00:00:00 2001 From: Disha Talreja Date: Mon, 26 Dec 2022 13:00:36 +0530 Subject: [PATCH 08/50] Improved code to clear stock state and redirect to inventory page after upload action(#31a0f22) --- src/store/modules/stock/actions.ts | 3 +++ src/views/InventoryDetail.vue | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/store/modules/stock/actions.ts b/src/store/modules/stock/actions.ts index 7171b121..fcfa3000 100644 --- a/src/store/modules/stock/actions.ts +++ b/src/store/modules/stock/actions.ts @@ -40,5 +40,8 @@ const actions: ActionTree = { updatedStockListItems({ commit }, stockItems){ commit(types.STOCK_LIST_ITEMS_UPDATED, stockItems); }, + clearStockList({ commit }){ + commit(types.STOCK_LIST_UPDATED, { items: [], original: [], unidentifiedProductItems: []}); + } } export default actions; diff --git a/src/views/InventoryDetail.vue b/src/views/InventoryDetail.vue index aa2bbca5..a2e95b28 100644 --- a/src/views/InventoryDetail.vue +++ b/src/views/InventoryDetail.vue @@ -280,8 +280,8 @@ export default defineComponent({ window.open(`https://${this.instanceUrl}.hotwax.io/commerce/control/ImportData?configId=IMP_PO`, '_blank'); } }]) - this.router.push("/purchase-order"); - this.store.dispatch('order/clearOrderList'); + this.router.push("/inventory"); + this.store.dispatch('stock/clearStockList'); }).catch(() => { showToast(translate("Something went wrong, please try again")); }) From 16d90c3b1a0f79c209144d096d882dd70e5a03af Mon Sep 17 00:00:00 2001 From: Disha Talreja Date: Mon, 26 Dec 2022 18:42:25 +0530 Subject: [PATCH 09/50] Updated code to upload csv to oms, set default locationSeqId on changing facilityId and added static text in en.json file(#31a0f22) --- src/locales/en.json | 3 +++ src/views/Inventory.vue | 2 +- src/views/InventoryDetail.vue | 41 +++++++++++++++++++---------------- 3 files changed, 26 insertions(+), 20 deletions(-) diff --git a/src/locales/en.json b/src/locales/en.json index 81577960..0506a371 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -35,6 +35,7 @@ "Login": "Login", "Logout": "Logout", "Mapping name": "Mapping name", + "Make sure all the data you have entered is correct.": "Make sure all the data you have entered is correct.", "Luxon date time formats can be found": "Luxon date time formats can be found", "Missing SKUs": "Missing SKUs", "No time zone found": "No time zone found", @@ -56,6 +57,7 @@ "Ready to create an app?": "Ready to create an app?", "Review": "Review", "Reset": "Reset", + "Reset inventory": "Reset inventory", "Reset password": "Reset password", "Safety stock": "Safety stock", "Save mapping": "Save mapping", @@ -79,6 +81,7 @@ "Start with Ionic": "Start with Ionic", "STAY": "STAY", "store name": "store name", + "The inventory has been updated successfully": "The inventory has been updated successfully", "The PO has been uploaded successfully": "The PO has been uploaded successfully", "The timezone you select is used to ensure automations you schedule are always accurate to the time you select.": "The timezone you select is used to ensure automations you schedule are always accurate to the time you select.", "This is the name of the OMS you are connected to right now. Make sure that you are connected to the right instance before proceeding.": "This is the name of the OMS you are connected to right now. Make sure that you are connected to the right instance before proceeding.", diff --git a/src/views/Inventory.vue b/src/views/Inventory.vue index 7c74be60..0fd6e261 100644 --- a/src/views/Inventory.vue +++ b/src/views/Inventory.vue @@ -121,7 +121,7 @@ export default defineComponent({ this.productsList = this.content.map(item => { return { productSKU: item[this.productSkuField], - quantityOrdered: item[this.quantityField], + quantity: item[this.quantityField], facilityId: '', externalFacilityId: item[this.facilityField], locationSeqId: item[this.locationSeqIdField] diff --git a/src/views/InventoryDetail.vue b/src/views/InventoryDetail.vue index a2e95b28..80e2d61e 100644 --- a/src/views/InventoryDetail.vue +++ b/src/views/InventoryDetail.vue @@ -26,7 +26,7 @@
{{ $t("Facility") }} - + {{ facility.facilityName }} @@ -46,7 +46,7 @@ - {{ searchedProduct.quantityOrdered }} {{ $t("Items") }} + {{ searchedProduct.quantity }} {{ $t("Items") }} @@ -98,16 +98,16 @@ - {{ item.quantityOrdered }} {{ $t("Items") }} + {{ item.quantity }} {{ $t("Items") }} - {{ item.externalFacilityId }} + {{ item.externalFacilityId ? item.externalFacilityId : item.facilityId }} - {{ facilityLocation.locationSeqId }} + {{ facilityLocation.locationSeqId }} @@ -245,20 +245,21 @@ export default defineComponent({ return item.isSelected; }).map((item: any) => { return { - "poId": " ", "facilityId": item.facilityId, "externalFacilityId": item.externalFacilityId, "idValue": item.productSKU, - "idType": "SKU" + "idType": "SKU", + "locationSeqId": item.locationSeqId, + "availableQty": item.quantity }; }) const fileName = this.fileName.replace(".csv", ".json"); const params = { - "configId": "IMP_PO" + "configId": "RESET_INVENTORY" } const alert = await alertController.create({ - header: this.$t("Upload purchase order"), - message: this.$t("Make sure all the data you have entered is correct and only pre-order or backorder items are selected."), + header: this.$t("Reset inventory"), + message: this.$t("Make sure all the data you have entered is correct."), buttons: [ { text: this.$t("Cancel"), @@ -273,11 +274,11 @@ export default defineComponent({ params })).then(() => { this.isPOUploadedSuccessfully = true; - showToast(translate("The PO has been uploaded successfully"), [{ + showToast(translate("The inventory has been updated successfully"), [{ text: translate('View'), role: 'view', handler: () => { - window.open(`https://${this.instanceUrl}.hotwax.io/commerce/control/ImportData?configId=IMP_PO`, '_blank'); + window.open(`https://${this.instanceUrl}.hotwax.io/commerce/control/ImportData?configId=RESET_INVENTORY`, '_blank'); } }]) this.router.push("/inventory"); @@ -338,16 +339,18 @@ export default defineComponent({ const original = JSON.parse(JSON.stringify(this.stock.original)); this.store.dispatch('stock/updatedStockListItems', original); }, - apply() { - this.stock.items.map((item: any) => { - if (item.isSelected) { - if(this.facilityId) { + async apply() { + if(this.facilityId) { + const facilityLocations = await this.store.dispatch('user/fetchFacilityLocations', [this.facilityId]); + await this.stock.items.map( async (item: any) => { + if (item.isSelected) { item.facilityId = this.facilityId; + item.locationSeqId = facilityLocations && facilityLocations[this.facilityId] && facilityLocations[this.facilityId][0].locationSeqId ? facilityLocations[this.facilityId][0].locationSeqId : ""; item.externalFacilityId = ""; } - } - }) - this.store.dispatch('stock/updatedStockListItems', this.stock.items); + }) + } + await this.store.dispatch('stock/updatedStockListItems', this.stock.items); }, getGroupList (items: any) { return Array.from(new Set(items.map((ele: any) => ele.parentProductId))); From 414c73d560c2d8283089040a9fb2fb3d2b649a56 Mon Sep 17 00:00:00 2001 From: Disha Talreja Date: Mon, 26 Dec 2022 18:47:51 +0530 Subject: [PATCH 10/50] Added comments(#31a0f22) --- src/views/InventoryDetail.vue | 1 + 1 file changed, 1 insertion(+) diff --git a/src/views/InventoryDetail.vue b/src/views/InventoryDetail.vue index 80e2d61e..1221546b 100644 --- a/src/views/InventoryDetail.vue +++ b/src/views/InventoryDetail.vue @@ -345,6 +345,7 @@ export default defineComponent({ await this.stock.items.map( async (item: any) => { if (item.isSelected) { item.facilityId = this.facilityId; + //TODO: Need to improve the handling of locationSeqId. item.locationSeqId = facilityLocations && facilityLocations[this.facilityId] && facilityLocations[this.facilityId][0].locationSeqId ? facilityLocations[this.facilityId][0].locationSeqId : ""; item.externalFacilityId = ""; } From 77e837c43c0cf073e239769ed3bb762374f32c57 Mon Sep 17 00:00:00 2001 From: Disha Talreja Date: Tue, 27 Dec 2022 13:01:44 +0530 Subject: [PATCH 11/50] Fixed: single product revert and parent product revert not working(#31a0f22) --- src/store/modules/stock/actions.ts | 2 +- src/store/modules/user/actions.ts | 6 +++--- src/store/modules/user/mutations.ts | 2 +- src/views/InventoryDetail.vue | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/store/modules/stock/actions.ts b/src/store/modules/stock/actions.ts index fcfa3000..27b29843 100644 --- a/src/store/modules/stock/actions.ts +++ b/src/store/modules/stock/actions.ts @@ -7,7 +7,7 @@ import * as types from './mutation-types' const actions: ActionTree = { async updatedStockList ({commit, rootGetters}, items) { const productIds = items.map((item: any) => item.productSKU) - const facilityIds = items.map((item: any) => item.externalFacilityId) + const facilityIds = [...new Set(items.map((item: any) => item.externalFacilityId))] const viewSize = productIds.length; const viewIndex = 0; const payload = { diff --git a/src/store/modules/user/actions.ts b/src/store/modules/user/actions.ts index 06ad6689..4794a828 100644 --- a/src/store/modules/user/actions.ts +++ b/src/store/modules/user/actions.ts @@ -142,10 +142,10 @@ const actions: ActionTree = { locationSeqId: location.locationSeqId, locationPath: locationPath } - locations[location.facilityId] ? locations[location.facilityId].push(facilityLocation) : locations[location.facilityId] = [facilityLocation] + locations.push(facilityLocation); return locations; - }, {}) - commit(types.USER_FACILITY_LOCATIONS_BY_FACILITY_ID, facilityLocations); + }, []); + commit(types.USER_FACILITY_LOCATIONS_BY_FACILITY_ID, { facilityLocations, facilityId }); return facilityLocations; } else { console.error(resp); diff --git a/src/store/modules/user/mutations.ts b/src/store/modules/user/mutations.ts index c9d5b21f..03f14748 100644 --- a/src/store/modules/user/mutations.ts +++ b/src/store/modules/user/mutations.ts @@ -28,7 +28,7 @@ const mutations: MutationTree = { state.preferredDateTimeFormat = payload; }, [types.USER_FACILITY_LOCATIONS_BY_FACILITY_ID] (state, payload) { - state.facilityLocationsByFacilityId = payload; + state.facilityLocationsByFacilityId[payload.facilityId] = payload.facilityLocations; } } export default mutations; \ No newline at end of file diff --git a/src/views/InventoryDetail.vue b/src/views/InventoryDetail.vue index 1221546b..c8e31464 100644 --- a/src/views/InventoryDetail.vue +++ b/src/views/InventoryDetail.vue @@ -342,11 +342,11 @@ export default defineComponent({ async apply() { if(this.facilityId) { const facilityLocations = await this.store.dispatch('user/fetchFacilityLocations', [this.facilityId]); - await this.stock.items.map( async (item: any) => { + await this.stock.items.map((item: any) => { if (item.isSelected) { item.facilityId = this.facilityId; //TODO: Need to improve the handling of locationSeqId. - item.locationSeqId = facilityLocations && facilityLocations[this.facilityId] && facilityLocations[this.facilityId][0].locationSeqId ? facilityLocations[this.facilityId][0].locationSeqId : ""; + item.locationSeqId = facilityLocations && facilityLocations[0] && facilityLocations[0].locationSeqId ? facilityLocations[0].locationSeqId : ""; item.externalFacilityId = ""; } }) From 28053a991517b5023f0364bbbb479c833c1c63ae Mon Sep 17 00:00:00 2001 From: Disha Talreja Date: Tue, 27 Dec 2022 13:16:41 +0530 Subject: [PATCH 12/50] Improved code(#31a0f22) --- src/views/Inventory.vue | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/views/Inventory.vue b/src/views/Inventory.vue index 0fd6e261..3efc9269 100644 --- a/src/views/Inventory.vue +++ b/src/views/Inventory.vue @@ -10,7 +10,8 @@
- {{ file.name ? $t("Inventory ") + file.name : $t('Inventory') }} + {{ $t("Inventory") }} + {{ file.name }} From 13857207c2a7a378a1974090c3192c4bc36c0897 Mon Sep 17 00:00:00 2001 From: Disha Talreja Date: Mon, 2 Jan 2023 14:45:13 +0530 Subject: [PATCH 13/50] Fixed indentation and improved component name(#31a0f22) --- src/store/modules/stock/getters.ts | 6 +++--- src/views/Inventory.vue | 8 +++----- src/views/InventoryDetail.vue | 4 ++-- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/src/store/modules/stock/getters.ts b/src/store/modules/stock/getters.ts index c0b4441f..e274ebe7 100644 --- a/src/store/modules/stock/getters.ts +++ b/src/store/modules/stock/getters.ts @@ -3,8 +3,8 @@ import OrderState from "./StockState"; import RootState from "../../RootState"; const getters: GetterTree = { - getStock(state) { - return state.list; - }, + getStock(state) { + return state.list; + }, }; export default getters; \ No newline at end of file diff --git a/src/views/Inventory.vue b/src/views/Inventory.vue index 3efc9269..7c951ade 100644 --- a/src/views/Inventory.vue +++ b/src/views/Inventory.vue @@ -64,10 +64,9 @@ import { useStore, mapGetters } from "vuex"; import { showToast, parseCsv } from '@/utils'; import { translate } from "@/i18n"; import { arrowForwardOutline } from 'ionicons/icons'; -import { DateTime } from 'luxon' export default defineComponent({ - name: "purchase orders", + name: "Inventory", components: { IonPage, IonHeader, @@ -103,12 +102,11 @@ export default defineComponent({ methods: { getFile(event) { this.file = event.target.files[0]; - if(this.file){ + if(this.file) { showToast(translate("File uploaded successfully")); this.parseFile(); this.store.dispatch('order/updateFileName', this.file.name); - } - else { + } else { showToast(translate("Something went wrong, Please try again")); } }, diff --git a/src/views/InventoryDetail.vue b/src/views/InventoryDetail.vue index c8e31464..1c233a28 100644 --- a/src/views/InventoryDetail.vue +++ b/src/views/InventoryDetail.vue @@ -55,7 +55,7 @@ - + {{ facilityLocation.locationSeqId }} @@ -145,7 +145,7 @@ import { hasError } from "@/utils"; import MissingSkuModal from "@/components/MissingSkuModal.vue" export default defineComponent({ - name: 'PurchaseOrderDetail', + name: 'InventoryDetail', components: { Image, IonPage, From 2e4bc361f22ac3fe3996d44e1acbb164e8e7ccb1 Mon Sep 17 00:00:00 2001 From: Disha Talreja Date: Wed, 4 Jan 2023 11:00:01 +0530 Subject: [PATCH 14/50] Updated code to display toast if file is not upladed or any of the fields is not mapped(#31a0f22) --- src/locales/en.json | 1 + src/views/Inventory.vue | 124 +++++++++++++++++++++------------------- 2 files changed, 67 insertions(+), 58 deletions(-) diff --git a/src/locales/en.json b/src/locales/en.json index 0506a371..6da62929 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -48,6 +48,7 @@ "Ordered quantity": "Ordered quantity", "Password": "Password", "Please upload a valid purchase order csv to continue": "Please upload a valid purchase order csv to continue", + "Please upload a valid reset inventory csv to continue": "Please upload a valid reset inventory csv to continue", "PO External Order ID": "PO External Order ID", "Preorder": "Preorder", "Product SKU": "Product SKU", diff --git a/src/views/Inventory.vue b/src/views/Inventory.vue index 7c951ade..364fef92 100644 --- a/src/views/Inventory.vue +++ b/src/views/Inventory.vue @@ -21,28 +21,28 @@ {{ $t("Product SKU") }} - + {{ prop }} {{ $t("Quantity") }} - + {{ prop }} {{ $t("Facility ID") }} - + {{ prop }} {{ $t("Facility Location") }} - + {{ prop }} @@ -66,73 +66,81 @@ import { translate } from "@/i18n"; import { arrowForwardOutline } from 'ionicons/icons'; export default defineComponent({ - name: "Inventory", - components: { - IonPage, - IonHeader, - IonToolbar, - IonTitle, - IonContent, - IonItem, - IonLabel, - IonButton, - IonMenuButton, - IonSelect, - IonSelectOption, - IonIcon, - IonListHeader, - IonList + name: "Inventory", + components: { + IonPage, + IonHeader, + IonToolbar, + IonTitle, + IonContent, + IonItem, + IonLabel, + IonButton, + IonMenuButton, + IonSelect, + IonSelectOption, + IonIcon, + IonListHeader, + IonList + }, + computed: { + ...mapGetters({ + dateTimeFormat : 'user/getDateTimeFormat', + }) + }, + data() { + return { + file: "", + content: [], + fieldMapping: { + productSku: "", + quantity: "", + facility: "", + locationSeqId: "", + }, + productsList: [], + } + }, + methods: { + getFile(event) { + this.file = event.target.files[0]; + if(this.file) { + showToast(translate("File uploaded successfully")); + this.parseFile(); + this.store.dispatch('order/updateFileName', this.file.name); + } else { + showToast(translate("Something went wrong, Please try again")); + } }, - computed: { - ...mapGetters({ - dateTimeFormat : 'user/getDateTimeFormat', + async parseFile(){ + await parseCsv(this.file).then(res => { + this.content = res; }) }, - data() { - return { - file: "", - content: [], - productSkuField: "", - quantityField: "", - facilityField: "", - locationSeqIdField: "", - productsList: [], - } - }, - methods: { - getFile(event) { - this.file = event.target.files[0]; - if(this.file) { - showToast(translate("File uploaded successfully")); - this.parseFile(); - this.store.dispatch('order/updateFileName', this.file.name); - } else { - showToast(translate("Something went wrong, Please try again")); - } - }, - - async parseFile(){ - await parseCsv(this.file).then(res => { - this.content = res; - }) - }, - mapFields() { + mapFields() { + const areAllFieldsSelected = Object.values(this.fieldMapping).every(field => field !== ""); + if (this.content.length <= 0) { + showToast(translate("Please upload a valid reset inventory csv to continue")); + } else if (areAllFieldsSelected) { this.productsList = this.content.map(item => { return { - productSKU: item[this.productSkuField], - quantity: item[this.quantityField], + productSKU: item[this.fieldMapping.productSku], + quantity: item[this.fieldMapping.quantity], facilityId: '', - externalFacilityId: item[this.facilityField], - locationSeqId: item[this.locationSeqIdField] + externalFacilityId: item[this.fieldMapping.facility], + locationSeqId: item[this.fieldMapping.locationSeqId] } }) this.store.dispatch('stock/updatedStockList', this.productsList); this.router.push({ name:'InventoryDetail' }) - }, + } else { + showToast(translate("Select all the fields to continue")); + } }, - setup() { + }, + setup() { const router = useRouter(); const store = useStore(); return { From d6293c836da8dcff87f9a9a85fb7212f8d1f4cee Mon Sep 17 00:00:00 2001 From: Disha Talreja Date: Fri, 6 Jan 2023 13:02:19 +0530 Subject: [PATCH 15/50] Removed multiple imports from same file and unused variables(#31a0f22) --- src/views/InventoryDetail.vue | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/views/InventoryDetail.vue b/src/views/InventoryDetail.vue index 0608c7d4..51134b22 100644 --- a/src/views/InventoryDetail.vue +++ b/src/views/InventoryDetail.vue @@ -137,11 +137,10 @@ import ProductPopover from '@/components/ProductPopover.vue' import { defineComponent } from 'vue'; import { mapGetters, useStore } from "vuex"; import { useRouter } from 'vue-router'; -import { showToast } from '@/utils'; +import { showToast, hasError } from '@/utils'; import { translate } from "@/i18n"; import { IonPage, IonHeader, IonToolbar, IonBackButton, IonContent, IonSearchbar, IonItem, IonThumbnail, IonLabel, IonChip, IonIcon, IonButton, IonCheckbox, IonSelect, IonSelectOption, IonButtons, popoverController, IonFab, IonFabButton, alertController, modalController } from '@ionic/vue' import { ellipsisVerticalOutline, locationOutline, checkboxOutline, cloudUploadOutline, arrowUndoOutline } from 'ionicons/icons' -import { hasError } from "@/utils"; import MissingSkuModal from "@/components/MissingSkuModal.vue" export default defineComponent({ @@ -268,7 +267,7 @@ export default defineComponent({ { text: this.$t("Upload"), handler: () => { - const response = UploadService.uploadJsonFile(UploadService.prepareUploadJsonPayload({ + UploadService.uploadJsonFile(UploadService.prepareUploadJsonPayload({ uploadData, fileName, params From 4c761e789e28d5145b6456925666d2d72eb7d41b Mon Sep 17 00:00:00 2001 From: Disha Talreja Date: Fri, 6 Jan 2023 19:19:26 +0530 Subject: [PATCH 16/50] Updated method name(#31a0f22) --- src/views/InventoryDetail.vue | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/views/InventoryDetail.vue b/src/views/InventoryDetail.vue index 51134b22..dce5feed 100644 --- a/src/views/InventoryDetail.vue +++ b/src/views/InventoryDetail.vue @@ -63,7 +63,7 @@ - +
@@ -82,7 +82,7 @@ - +
@@ -114,7 +114,7 @@ - +
@@ -313,7 +313,7 @@ export default defineComponent({ console.error(err) } }, - async UpdateProduct(ev: Event, id: any, isVirtual: boolean, item: any, type: string) { + async updateProduct(ev: Event, id: any, isVirtual: boolean, item: any, type: string) { const popover = await popoverController .create({ component: ProductPopover, From b14e9e86c8ca9074bf4113728cb79f61fbdcb891 Mon Sep 17 00:00:00 2001 From: Disha Talreja Date: Mon, 9 Jan 2023 12:02:12 +0530 Subject: [PATCH 17/50] Improved code formatting and updated method name(#31a0f22) --- src/store/modules/order/actions.ts | 3 ++- src/views/OrderDetail.vue | 8 ++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/store/modules/order/actions.ts b/src/store/modules/order/actions.ts index f6e9799e..688df085 100644 --- a/src/store/modules/order/actions.ts +++ b/src/store/modules/order/actions.ts @@ -22,7 +22,7 @@ const actions: ActionTree = { items = items.filter((item: any) => item.shopifyProductSKU).map((item: any) => { const product = rootGetters['product/getProduct'](item.shopifyProductSKU) - if(Object.keys(product).length > 0){ + if (Object.keys(product).length > 0) { item.parentProductId = product?.parent?.id; item.pseudoId = product.pseudoId; item.parentProductName = product?.parent?.productName; @@ -34,6 +34,7 @@ const actions: ActionTree = { unidentifiedProductItems.push(item); return ; }).filter((item: any) => item); + const original = JSON.parse(JSON.stringify(items)) commit(types.ORDER_LIST_UPDATED, { items, original, unidentifiedProductItems }); diff --git a/src/views/OrderDetail.vue b/src/views/OrderDetail.vue index dc6907a4..62818525 100644 --- a/src/views/OrderDetail.vue +++ b/src/views/OrderDetail.vue @@ -80,7 +80,7 @@ - +
@@ -99,7 +99,7 @@ - +
@@ -130,7 +130,7 @@ - + @@ -338,7 +338,7 @@ export default defineComponent({ console.error(err) } }, - async UpdateProduct(ev: Event, id: any, isVirtual: boolean, item: any, type: string) { + async updateProduct(ev: Event, id: any, isVirtual: boolean, item: any, type: string) { const popover = await popoverController .create({ component: ProductPopover, From 4a515727c40a4956f5ee13635c0007823f57f713 Mon Sep 17 00:00:00 2001 From: Disha Talreja Date: Wed, 11 Jan 2023 18:48:26 +0530 Subject: [PATCH 18/50] Used mixins for parsing csv file(#31a0f22) --- src/mixins/parseFileMixin.ts | 20 ++++++++++++++++++++ src/views/Inventory.vue | 19 +++++-------------- src/views/PurchaseOrder.vue | 20 +++++--------------- 3 files changed, 30 insertions(+), 29 deletions(-) create mode 100644 src/mixins/parseFileMixin.ts diff --git a/src/mixins/parseFileMixin.ts b/src/mixins/parseFileMixin.ts new file mode 100644 index 00000000..c1347609 --- /dev/null +++ b/src/mixins/parseFileMixin.ts @@ -0,0 +1,20 @@ +import { translate } from "@/i18n"; +import store from "@/store"; +import { showToast, parseCsv } from "@/utils"; + +export default { + methods: { + async getFile(file: any) { + if (file) { + showToast(translate("File uploaded successfully")); + store.dispatch('order/updateFileName', file.name); + + const csvData = await parseCsv(file).then( res => { + return res; + }) + return csvData; + } + showToast(translate("Something went wrong, Please try again")); + } + } +} \ No newline at end of file diff --git a/src/views/Inventory.vue b/src/views/Inventory.vue index 364fef92..5f5c1ed5 100644 --- a/src/views/Inventory.vue +++ b/src/views/Inventory.vue @@ -12,7 +12,7 @@ {{ $t("Inventory") }} {{ file.name }} - + @@ -64,6 +64,7 @@ import { useStore, mapGetters } from "vuex"; import { showToast, parseCsv } from '@/utils'; import { translate } from "@/i18n"; import { arrowForwardOutline } from 'ionicons/icons'; +import parseFileMixin from '@/mixins/parseFileMixin'; export default defineComponent({ name: "Inventory", @@ -101,21 +102,11 @@ export default defineComponent({ productsList: [], } }, + mixins:[ parseFileMixin ], methods: { - getFile(event) { + async parse(event) { this.file = event.target.files[0]; - if(this.file) { - showToast(translate("File uploaded successfully")); - this.parseFile(); - this.store.dispatch('order/updateFileName', this.file.name); - } else { - showToast(translate("Something went wrong, Please try again")); - } - }, - async parseFile(){ - await parseCsv(this.file).then(res => { - this.content = res; - }) + this.content = await this.getFile(this.file); }, mapFields() { const areAllFieldsSelected = Object.values(this.fieldMapping).every(field => field !== ""); diff --git a/src/views/PurchaseOrder.vue b/src/views/PurchaseOrder.vue index 032fccf6..4c3a0954 100644 --- a/src/views/PurchaseOrder.vue +++ b/src/views/PurchaseOrder.vue @@ -12,7 +12,7 @@ {{ $t("Purchase order") }} {{ file.name }} - + @@ -85,6 +85,7 @@ import { showToast, parseCsv } from '@/utils'; import { translate } from "@/i18n"; import { arrowForwardOutline } from 'ionicons/icons'; import { DateTime } from 'luxon'; +import parseFileMixin from '@/mixins/parseFileMixin'; export default defineComponent({ name: "purchase orders", @@ -111,6 +112,7 @@ export default defineComponent({ fieldMappings: 'user/getFieldMappings' }) }, + mixins:[ parseFileMixin ], data() { return { file: "", @@ -149,21 +151,9 @@ export default defineComponent({ this.store.dispatch('user/updateFieldMappings', { mappingPrefId, mappingPrefName: this.mappingName, mappingPrefValue: JSON.parse(JSON.stringify(this.fieldMapping)) }) showToast(translate("Mapping saved successfully")); }, - getFile(event) { + async parse(event){ this.file = event.target.files[0]; - if(this.file){ - showToast(translate("File uploaded successfully")); - this.parseFile(); - this.store.dispatch('order/updateFileName', this.file.name); - } - else { - showToast(translate("Something went wrong, Please try again")); - } - }, - async parseFile(){ - await parseCsv(this.file).then(res => { - this.content = res; - }) + this.content = await this.getFile(this.file); }, review() { if (this.content.length <= 0) { From 5c0a3eafb52c22dbd0c15528a7d705aa616054e9 Mon Sep 17 00:00:00 2001 From: Disha Talreja Date: Wed, 11 Jan 2023 18:54:37 +0530 Subject: [PATCH 19/50] Used guard clause for field mapping(#31a0f22) --- src/views/Inventory.vue | 36 +++++++++++++++++++---------------- src/views/PurchaseOrder.vue | 38 ++++++++++++++++++++----------------- 2 files changed, 41 insertions(+), 33 deletions(-) diff --git a/src/views/Inventory.vue b/src/views/Inventory.vue index 5f5c1ed5..b111885c 100644 --- a/src/views/Inventory.vue +++ b/src/views/Inventory.vue @@ -112,23 +112,27 @@ export default defineComponent({ const areAllFieldsSelected = Object.values(this.fieldMapping).every(field => field !== ""); if (this.content.length <= 0) { showToast(translate("Please upload a valid reset inventory csv to continue")); - } else if (areAllFieldsSelected) { - this.productsList = this.content.map(item => { - return { - productSKU: item[this.fieldMapping.productSku], - quantity: item[this.fieldMapping.quantity], - facilityId: '', - externalFacilityId: item[this.fieldMapping.facility], - locationSeqId: item[this.fieldMapping.locationSeqId] - } - }) - this.store.dispatch('stock/updatedStockList', this.productsList); - this.router.push({ - name:'InventoryDetail' - }) - } else { - showToast(translate("Select all the fields to continue")); + return; } + + if (!areAllFieldsSelected) { + showToast(translate("Select all the fields to continue")); + return; + } + + this.productsList = this.content.map(item => { + return { + productSKU: item[this.fieldMapping.productSku], + quantity: item[this.fieldMapping.quantity], + facilityId: '', + externalFacilityId: item[this.fieldMapping.facility], + locationSeqId: item[this.fieldMapping.locationSeqId] + } + }) + this.store.dispatch('stock/updatedStockList', this.productsList); + this.router.push({ + name:'InventoryDetail' + }) }, }, setup() { diff --git a/src/views/PurchaseOrder.vue b/src/views/PurchaseOrder.vue index 4c3a0954..5daccf25 100644 --- a/src/views/PurchaseOrder.vue +++ b/src/views/PurchaseOrder.vue @@ -158,24 +158,28 @@ export default defineComponent({ review() { if (this.content.length <= 0) { showToast(translate("Please upload a valid purchase order csv to continue")); - } else if (this.areAllFieldsSelected()) { - this.orderItemsList = this.content.map(item => { - return { - orderId: item[this.fieldMapping.orderId], - shopifyProductSKU: item[this.fieldMapping.productSku], - arrivalDate: DateTime.fromFormat(item[this.fieldMapping.orderDate], this.dateTimeFormat).toFormat(this.dateTimeFormat), //This is to verify whether the date format is correct. - quantityOrdered: item[this.fieldMapping.quantity], - facilityId: '', - externalFacilityId: item[this.fieldMapping.facility] - } - }) - this.store.dispatch('order/updatedOrderList', this.orderItemsList); - this.router.push({ - name:'PurchaseOrderDetail' - }) - } else { - showToast(translate("Select all the fields to continue")); + return; } + + if (!this.areAllFieldsSelected()) { + showToast(translate("Select all the fields to continue")); + return; + } + + this.orderItemsList = this.content.map(item => { + return { + orderId: item[this.fieldMapping.orderId], + shopifyProductSKU: item[this.fieldMapping.productSku], + arrivalDate: DateTime.fromFormat(item[this.fieldMapping.orderDate], this.dateTimeFormat).toFormat(this.dateTimeFormat), //This is to verify whether the date format is correct. + quantityOrdered: item[this.fieldMapping.quantity], + facilityId: '', + externalFacilityId: item[this.fieldMapping.facility] + } + }) + this.store.dispatch('order/updatedOrderList', this.orderItemsList); + this.router.push({ + name:'PurchaseOrderDetail' + }) }, mapFields(event) { if(event && event.detail.value) { From e67a1c2cc5e401d32fd6b1f8ab217e421795bd3f Mon Sep 17 00:00:00 2001 From: Disha Talreja Date: Wed, 11 Jan 2023 18:59:33 +0530 Subject: [PATCH 20/50] Used text to be displayed on alert(#31a0f22) --- src/locales/en.json | 3 +-- src/views/InventoryDetail.vue | 2 +- src/views/OrderDetail.vue | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/locales/en.json b/src/locales/en.json index 30210d8f..fb212a8a 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -1,8 +1,7 @@ { "App": "App", "Apply": "Apply", - "Any edits made to this CSV will be lost.": "Any edits made to this CSV will be lost.", - "Any edits made to this PO will be lost.": "Any edits made to this PO will be lost.", + "Any edits made on this page will be lost.": "Any edits made on this page made will be lost.", "Are you sure you want to change the time zone to?": "Are you sure you want to change the time zone to?", "Arrival date": "Arrival date", "Backorder": "Backorder", diff --git a/src/views/InventoryDetail.vue b/src/views/InventoryDetail.vue index dce5feed..810b8b6c 100644 --- a/src/views/InventoryDetail.vue +++ b/src/views/InventoryDetail.vue @@ -193,7 +193,7 @@ export default defineComponent({ let canLeave = false; const alert = await alertController.create({ header: this.$t("Leave page"), - message: this.$t("Any edits made to this CSV will be lost."), + message: this.$t("Any edits made on this page will be lost."), buttons: [ { text: this.$t("STAY"), diff --git a/src/views/OrderDetail.vue b/src/views/OrderDetail.vue index 62818525..ccd9e2fb 100644 --- a/src/views/OrderDetail.vue +++ b/src/views/OrderDetail.vue @@ -218,7 +218,7 @@ export default defineComponent({ let canLeave = false; const alert = await alertController.create({ header: this.$t("Leave page"), - message: this.$t("Any edits made to this PO will be lost."), + message: this.$t("Any edits made on this page will be lost."), buttons: [ { text: this.$t("STAY"), From b29e8a651331ca42e3fb5cb52f405772424a82d2 Mon Sep 17 00:00:00 2001 From: Disha Talreja Date: Mon, 30 Jan 2023 15:07:23 +0530 Subject: [PATCH 21/50] Improved code(#31a0f22) --- src/components/MissingSkuModal.vue | 4 +- src/components/ProductPopover.vue | 19 ++++---- src/mixins/parseFileMixin.ts | 6 +-- src/store/modules/stock/StockState.ts | 8 ++-- src/store/modules/stock/actions.ts | 8 ++-- src/store/modules/stock/getters.ts | 4 +- src/store/modules/stock/index.ts | 6 +-- src/store/modules/stock/mutations.ts | 8 ++-- src/views/InventoryDetail.vue | 64 ++++++++++++++------------- 9 files changed, 66 insertions(+), 61 deletions(-) diff --git a/src/components/MissingSkuModal.vue b/src/components/MissingSkuModal.vue index dfc45732..2a255c54 100644 --- a/src/components/MissingSkuModal.vue +++ b/src/components/MissingSkuModal.vue @@ -11,9 +11,9 @@ - + - {{ item.shopifyProductSKU }} + {{ item.shopifyProductSKU ? item.shopifyProductSKU : item.productSKU }} diff --git a/src/components/ProductPopover.vue b/src/components/ProductPopover.vue index eded8623..8d0be937 100644 --- a/src/components/ProductPopover.vue +++ b/src/components/ProductPopover.vue @@ -29,7 +29,7 @@ export default defineComponent({ computed: { ...mapGetters({ ordersList: 'order/getOrder', - stock: 'stock/getStock' + stock: 'stock/getItemsStock' }), }, methods: { @@ -40,21 +40,22 @@ export default defineComponent({ this.isVirtual ? this.onlySelectParentProduct() : this.onlySelectSingleProduct(); }, onlySelectParentProduct() { - const items = this.type === 'order' ? this.ordersList.items : this.stock.items; - items.forEach(element => { - element.isSelected = element.parentProductId === this.id; + let items = this.type === 'order' ? this.ordersList.items : this.stock.parsed; + items = items.map(item => { + item.isSelected = item.parentProductId === this.id; + return item; }); popoverController.dismiss({ dismissed: true }); }, onlySelectSingleProduct() { - const items = this.type === 'order' ? this.ordersList.items : this.stock.items; - items.forEach(element => { - element.isSelected = element.pseudoId === this.id; + let items = this.type === 'order' ? this.ordersList.items : this.stock.parsed; + items = items.map(item => { + item.isSelected = item.pseudoId === this.id; }); popoverController.dismiss({ dismissed: true }); }, revertProduct() { - const items = this.type === 'order' ? this.ordersList.items : this.stock.items; + const items = this.type === 'order' ? this.ordersList.items : this.stock.parsed; const original = this.type === 'order' ? JSON.parse(JSON.stringify(this.ordersList.original)) : JSON.parse(JSON.stringify(this.stock.original)); const itemsList = items.map(element => { if(element.pseudoId === this.id) { @@ -69,7 +70,7 @@ export default defineComponent({ popoverController.dismiss({ dismissed: true }); }, revertParentProduct(){ - const items = this.type === 'order' ? this.ordersList.items : this.stock.items; + const items = this.type === 'order' ? this.ordersList.items : this.stock.parsed; const original = this.type === 'order' ? JSON.parse(JSON.stringify(this.ordersList.original)) : JSON.parse(JSON.stringify(this.stock.original)); const itemsList = items.map(element => { if(element.parentProductId === this.id) { diff --git a/src/mixins/parseFileMixin.ts b/src/mixins/parseFileMixin.ts index c1347609..9e3f6c5e 100644 --- a/src/mixins/parseFileMixin.ts +++ b/src/mixins/parseFileMixin.ts @@ -4,14 +4,14 @@ import { showToast, parseCsv } from "@/utils"; export default { methods: { - async getFile(file: any) { + async getFile(file: any) { if (file) { showToast(translate("File uploaded successfully")); store.dispatch('order/updateFileName', file.name); const csvData = await parseCsv(file).then( res => { - return res; - }) + return res; + }) return csvData; } showToast(translate("Something went wrong, Please try again")); diff --git a/src/store/modules/stock/StockState.ts b/src/store/modules/stock/StockState.ts index 4f6ef02c..c5924eef 100644 --- a/src/store/modules/stock/StockState.ts +++ b/src/store/modules/stock/StockState.ts @@ -1,8 +1,8 @@ export default interface StockState { - list: { - items: any, + items: { + parsed: any, original: any, - unidentifiedProductItems: any, - }, + unidentifiedItems: any, + }, fileName: string } diff --git a/src/store/modules/stock/actions.ts b/src/store/modules/stock/actions.ts index 7d55ba4c..1f2b63a2 100644 --- a/src/store/modules/stock/actions.ts +++ b/src/store/modules/stock/actions.ts @@ -17,7 +17,7 @@ const actions: ActionTree = { } await store.dispatch('user/fetchFacilityLocations', facilityIds); await store.dispatch("product/fetchProducts", payload); - const unidentifiedProductItems = [] as any; + const unidentifiedItems = [] as any; items = items.map((item: any) => { const product = rootGetters['product/getProduct'](item.productSKU) @@ -30,18 +30,18 @@ const actions: ActionTree = { item.isSelected = true; return item; } - unidentifiedProductItems.push(item); + unidentifiedItems.push(item); return ; }).filter((item: any) => item); const original = JSON.parse(JSON.stringify(items)) - commit(types.STOCK_LIST_UPDATED, { items, original, unidentifiedProductItems }); + commit(types.STOCK_LIST_UPDATED, { items, original, unidentifiedItems }); }, updatedStockListItems({ commit }, stockItems){ commit(types.STOCK_LIST_ITEMS_UPDATED, stockItems); }, clearStockList({ commit }){ - commit(types.STOCK_LIST_UPDATED, { items: [], original: [], unidentifiedProductItems: []}); + commit(types.STOCK_LIST_UPDATED, { items: [], original: [], unidentifiedItems: []}); } } export default actions; diff --git a/src/store/modules/stock/getters.ts b/src/store/modules/stock/getters.ts index e274ebe7..775c695f 100644 --- a/src/store/modules/stock/getters.ts +++ b/src/store/modules/stock/getters.ts @@ -3,8 +3,8 @@ import OrderState from "./StockState"; import RootState from "../../RootState"; const getters: GetterTree = { - getStock(state) { - return state.list; + getItemsStock(state) { + return state.items; }, }; export default getters; \ No newline at end of file diff --git a/src/store/modules/stock/index.ts b/src/store/modules/stock/index.ts index 6b033475..41751b03 100644 --- a/src/store/modules/stock/index.ts +++ b/src/store/modules/stock/index.ts @@ -8,10 +8,10 @@ import RootState from '../../RootState' const orderModule: Module = { namespaced: true, state: { - list: { - items: [], + items: { + parsed: [], original: [], - unidentifiedProductItems: [], + unidentifiedItems: [], }, fileName: "" }, diff --git a/src/store/modules/stock/mutations.ts b/src/store/modules/stock/mutations.ts index 62d46bab..1fd743c2 100644 --- a/src/store/modules/stock/mutations.ts +++ b/src/store/modules/stock/mutations.ts @@ -4,12 +4,12 @@ import * as types from './mutation-types' const mutations: MutationTree = { [types.STOCK_LIST_UPDATED] (state, payload) { - state.list.items = payload.items; - state.list.original = payload.original; - state.list.unidentifiedProductItems = payload.unidentifiedProductItems; + state.items.parsed = payload.items; + state.items.original = payload.original; + state.items.unidentifiedItems = payload.unidentifiedItems; }, [types.STOCK_LIST_ITEMS_UPDATED] (state, payload) { - state.list.items = payload; + state.items.parsed = payload; }, } export default mutations; \ No newline at end of file diff --git a/src/views/InventoryDetail.vue b/src/views/InventoryDetail.vue index 810b8b6c..5fbb6c08 100644 --- a/src/views/InventoryDetail.vue +++ b/src/views/InventoryDetail.vue @@ -8,7 +8,7 @@ - + @@ -18,7 +18,7 @@
@@ -27,7 +27,7 @@ {{ $t("Facility") }} - {{ facility.facilityName }} + {{ facility.facilityName }} @@ -36,7 +36,7 @@
- + @@ -63,15 +63,15 @@ - +
-
+
- {{ getParentInformation(id, stock.items).parentProductName }} + {{ getParentInformation(id, stock.parsed).parentProductName }}
@@ -82,11 +82,11 @@ - +
-
+
@@ -104,7 +104,7 @@ {{ item.externalFacilityId ? item.externalFacilityId : item.facilityId }} - + {{ facilityLocation.locationSeqId }} @@ -114,7 +114,7 @@ - +
@@ -168,7 +168,7 @@ export default defineComponent({ }, computed: { ...mapGetters({ - stock: 'stock/getStock', + stock: 'stock/getItemsStock', getProduct: 'product/getProduct', instanceUrl: 'user/getInstanceUrl', fileName: 'order/getFileName', @@ -177,7 +177,7 @@ export default defineComponent({ }, data() { return { - facilityId: (this as any)?.stock?.items[0]?.facilityId, + facilityId: (this as any)?.stock?.parsed[0]?.facilityId, facilities: [] as any, queryString: "", searchedProduct: {} as any, @@ -219,28 +219,28 @@ export default defineComponent({ methods: { setFacilityLocation(ev: CustomEvent, product: any){ - this.stock.items.map((item: any) => { + this.stock.parsed.map((item: any) => { if(item.pseudoId === product.pseudoId){ item.locationSeqId = ev.detail.value; } }); - this.store.dispatch('stock/updatedStockListItems', this.stock.items); + this.store.dispatch('stock/updatedStockListItems', this.stock.parsed); }, - async listMissingSkus() { + async openMissingSkuModal() { const missingSkuModal = await modalController.create({ component: MissingSkuModal, - componentProps: { 'unidentifiedProductItems': this.stock.unidentifiedProductItems } + componentProps: { 'unidentifiedProductItems': this.stock.unidentifiedItems } }); return missingSkuModal.present(); }, searchProduct(sku: any) { const product = this.getProduct(sku); - this.searchedProduct = this.stock.items.find((item: any) => { + this.searchedProduct = this.stock.parsed.find((item: any) => { return item.pseudoId === product.pseudoId; }) }, async save(){ - const uploadData = this.stock.items.filter((item: any) => { + const uploadData = this.stock.parsed.filter((item: any) => { return item.isSelected; }).map((item: any) => { return { @@ -313,8 +313,8 @@ export default defineComponent({ console.error(err) } }, - async updateProduct(ev: Event, id: any, isVirtual: boolean, item: any, type: string) { - const popover = await popoverController + async openProductPopover(ev: Event, id: any, isVirtual: boolean, item: any, type: string) { + const productPopover = await popoverController .create({ component: ProductPopover, event: ev, @@ -322,13 +322,13 @@ export default defineComponent({ showBackdrop: true, componentProps: { 'id': id, 'isVirtual': isVirtual, 'item': item, 'type': type } }); - popover.onDidDismiss().then(() => { + productPopover.onDidDismiss().then(() => { this.searchProduct(this.queryString); }); - return popover.present(); + return productPopover.present(); }, isParentProductChecked(parentProductId: string) { - const items = this.getGroupItems(parentProductId, this.stock.items); + const items = this.getItemsByParentProduct(parentProductId, this.stock.parsed); return items.every((item: any) => item.isSelected) }, selectProduct(item: any, event: any) { @@ -341,7 +341,7 @@ export default defineComponent({ async apply() { if(this.facilityId) { const facilityLocations = await this.store.dispatch('user/fetchFacilityLocations', [this.facilityId]); - await this.stock.items.map((item: any) => { + await this.stock.parsed.map((item: any) => { if (item.isSelected) { item.facilityId = this.facilityId; //TODO: Need to improve the handling of locationSeqId. @@ -350,26 +350,26 @@ export default defineComponent({ } }) } - await this.store.dispatch('stock/updatedStockListItems', this.stock.items); + await this.store.dispatch('stock/updatedStockListItems', this.stock.parsed); }, - getGroupList (items: any) { + getParentProductIds (items: any) { return Array.from(new Set(items.map((ele: any) => ele.parentProductId))); }, - getGroupItems(parentProductId: any, items: any) { + getItemsByParentProduct(parentProductId: any, items: any) { return items.filter((item: any) => item.parentProductId == parentProductId) }, getParentInformation(id: any, items: any) { return items.find((item: any) => item.parentProductId == id) }, selectAllItems() { - this.stock.items.forEach((item: any) => { + this.stock.parsed.forEach((item: any) => { item.isSelected = true; }) }, selectParentProduct(parentProductId: any, event: any) { // Todo: Need to find a better approach. if(this.isParentProductUpdated){ - this.stock.items.forEach((item: any) => { + this.stock.parsed.forEach((item: any) => { if (item.parentProductId === parentProductId) { item.isSelected = event.detail.checked; } @@ -423,6 +423,10 @@ ion-chip > ion-select { padding: 0px; } +.location { + display: flex; +} + @media (min-width: 991px) { .header { display: grid; From 569fc948d37a97f5721bd68901b1bf768715c53d Mon Sep 17 00:00:00 2001 From: Disha Talreja Date: Mon, 30 Jan 2023 18:17:53 +0530 Subject: [PATCH 22/50] fix: disable alert on token expire(#31a0f22) --- src/views/InventoryDetail.vue | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/views/InventoryDetail.vue b/src/views/InventoryDetail.vue index 5fbb6c08..252151ac 100644 --- a/src/views/InventoryDetail.vue +++ b/src/views/InventoryDetail.vue @@ -189,7 +189,8 @@ export default defineComponent({ ionViewDidEnter(){ this.fetchFacilities(); }, - async beforeRouteLeave(to, from) { + async beforeRouteLeave(to) { + if(to.path === '/login') return; let canLeave = false; const alert = await alertController.create({ header: this.$t("Leave page"), From 918de31adbcd8ecd1c91f3969ecf3144b1a40082 Mon Sep 17 00:00:00 2001 From: Disha Talreja Date: Thu, 2 Feb 2023 12:35:05 +0530 Subject: [PATCH 23/50] fix: errors(#31a0f22) --- src/store/index.ts | 2 +- src/store/modules/order/actions.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/store/index.ts b/src/store/index.ts index 56218a9e..0f60a0a0 100644 --- a/src/store/index.ts +++ b/src/store/index.ts @@ -8,7 +8,7 @@ import userModule from './modules/user'; import productModule from "./modules/product"; import orderModule from "./modules/order"; import stockModule from "./modules/stock"; -import utilModule from "./modules/util"; +import utilModule from "./modules/util" // TODO check how to register it from the components only diff --git a/src/store/modules/order/actions.ts b/src/store/modules/order/actions.ts index 3cdbfa20..42e2e7eb 100644 --- a/src/store/modules/order/actions.ts +++ b/src/store/modules/order/actions.ts @@ -36,7 +36,7 @@ const actions: ActionTree = { return ; }).filter((item: any) => item); - const original = JSON.parse(JSON.stringify(items)) + const original = JSON.parse(JSON.stringify(items)); items = items.reduce((itemsByPoId: any, item: any) => { itemsByPoId[item.orderId] ? itemsByPoId[item.orderId].push(item) : itemsByPoId[item.orderId] = [item] From 083cddaef08306f8d50be7739c2457126c340583 Mon Sep 17 00:00:00 2001 From: Disha Talreja Date: Thu, 2 Feb 2023 17:07:19 +0530 Subject: [PATCH 24/50] Improved code(#31a0f22) --- src/components/ProductPopover.vue | 10 +++++----- src/store/modules/stock/getters.ts | 2 +- src/views/InventoryDetail.vue | 3 +++ 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/components/ProductPopover.vue b/src/components/ProductPopover.vue index 21f21aa0..32763098 100644 --- a/src/components/ProductPopover.vue +++ b/src/components/ProductPopover.vue @@ -40,29 +40,30 @@ export default defineComponent({ this.isVirtual ? this.onlySelectParentProduct() : this.onlySelectSingleProduct(); }, onlySelectParentProduct() { - let items = this.type === 'order' ? this.ordersList.items : this.stock.parsed; if(this.type === 'order') { Object.values(this.purchaseOrders.parsed).flat().map(item => { item.isSelected = item.parentProductId === this.id && item.orderId === this.poId; }); + this.store.dispatch('order/updatePurchaseOrders', this.purchaseOrders) } else { this.stock.parsed.map(item => { item.isSelected = item.parentProductId === this.id; }) + this.store.dispatch('stock/updatedStockListItems', this.stock.parsed) } popoverController.dismiss({ dismissed: true }); }, - onlySelectSingleProduct() { - let items = this.type === 'order' ? this.ordersList.items : this.stock.parsed; - + onlySelectSingleProduct() { if(this.type === 'order') { Object.values(this.purchaseOrders.parsed).flat().map(item => { item.isSelected = item.pseudoId === this.id && item.orderId === this.poId; }); + this.store.dispatch('order/updatePurchaseOrders', this.purchaseOrders) } else { this.stock.parsed.map(item => { item.isSelected = item.pseudoId === this.id; }); + this.store.dispatch('stock/updatedStockListItems', this.stock.parsed) } popoverController.dismiss({ dismissed: true }); @@ -97,7 +98,6 @@ export default defineComponent({ popoverController.dismiss({ dismissed: true }); }, revertParentProduct(){ - if(this.type === 'order') { const original = JSON.parse(JSON.stringify(this.purchaseOrders.original)); this.purchaseOrders.parsed[this.poId] = this.purchaseOrders.parsed[this.poId].map(element => { diff --git a/src/store/modules/stock/getters.ts b/src/store/modules/stock/getters.ts index 775c695f..3f309f18 100644 --- a/src/store/modules/stock/getters.ts +++ b/src/store/modules/stock/getters.ts @@ -4,7 +4,7 @@ import RootState from "../../RootState"; const getters: GetterTree = { getItemsStock(state) { - return state.items; + return JSON.parse(JSON.stringify(state.items)); }, }; export default getters; \ No newline at end of file diff --git a/src/views/InventoryDetail.vue b/src/views/InventoryDetail.vue index 9c2075a3..15135e2e 100644 --- a/src/views/InventoryDetail.vue +++ b/src/views/InventoryDetail.vue @@ -311,6 +311,7 @@ export default defineComponent({ }, selectProduct(item: any, event: any) { item.isSelected = event.detail.checked; + this.store.dispatch('stock/updatedStockListItems', this.stock.parsed) }, revertAll() { const original = JSON.parse(JSON.stringify(this.stock.original)); @@ -343,6 +344,7 @@ export default defineComponent({ this.stock.parsed.forEach((item: any) => { item.isSelected = true; }) + this.store.dispatch('stock/updatedStockListItems', this.stock.parsed) }, selectParentProduct(parentProductId: any, event: any) { // Todo: Need to find a better approach. @@ -354,6 +356,7 @@ export default defineComponent({ }) this.isParentProductUpdated = false; } + this.store.dispatch('stock/updatedStockListItems', this.stock.parsed); } }, setup() { From 80b4625bf52707b08c5628e2b94dcbf9ff9d6b36 Mon Sep 17 00:00:00 2001 From: Disha Talreja Date: Thu, 2 Feb 2023 17:19:12 +0530 Subject: [PATCH 25/50] Removed unwanted code(#31a0f22) --- src/views/PurchaseOrder.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/views/PurchaseOrder.vue b/src/views/PurchaseOrder.vue index fecf1ab0..bff1b23e 100644 --- a/src/views/PurchaseOrder.vue +++ b/src/views/PurchaseOrder.vue @@ -163,7 +163,7 @@ export default defineComponent({ return { orderId: item[this.fieldMapping.orderId], shopifyProductSKU: item[this.fieldMapping.productSku], - arrivalDate: DateTime.fromFormat(item[this.fieldMapping.orderDate], this.dateTimeFormat).toFormat(this.dateTimeFormat), //This is to verify whether the date format is correct. + arrivalDate: item[this.fieldMapping.orderDate], quantityOrdered: item[this.fieldMapping.quantity], facilityId: '', externalFacilityId: item[this.fieldMapping.facility] From 2b0d5f87e381a600168861a5c05b73494307a39b Mon Sep 17 00:00:00 2001 From: Disha Talreja Date: Thu, 2 Feb 2023 17:53:54 +0530 Subject: [PATCH 26/50] Updated code(#31a0f22) --- src/views/InventoryDetail.vue | 21 +++++++-------------- src/views/PurchaseOrder.vue | 1 - 2 files changed, 7 insertions(+), 15 deletions(-) diff --git a/src/views/InventoryDetail.vue b/src/views/InventoryDetail.vue index 15135e2e..f848b1ab 100644 --- a/src/views/InventoryDetail.vue +++ b/src/views/InventoryDetail.vue @@ -17,8 +17,8 @@
@@ -136,7 +136,7 @@ import ProductPopover from '@/components/ProductPopover.vue' import { defineComponent } from 'vue'; import { mapGetters, useStore } from "vuex"; import { useRouter } from 'vue-router'; -import { showToast, hasError } from '@/utils'; +import { showToast } from '@/utils'; import { translate } from "@/i18n"; import { IonPage, IonHeader, IonToolbar, IonBackButton, IonContent, IonSearchbar, IonItem, IonThumbnail, IonLabel, IonChip, IonIcon, IonButton, IonCheckbox, IonSelect, IonSelectOption, IonButtons, popoverController, IonFab, IonFabButton, alertController, modalController } from '@ionic/vue' import { ellipsisVerticalOutline, locationOutline, checkboxOutline, cloudUploadOutline, arrowUndoOutline } from 'ionicons/icons' @@ -181,7 +181,7 @@ export default defineComponent({ queryString: "", searchedProduct: {} as any, isParentProductUpdated: false, - isPOUploadedSuccessfully: false, + isCsvUploadedSuccessfully: false, facilityLocations: {} } }, @@ -209,10 +209,10 @@ export default defineComponent({ }, ], }); - if(!this.isPOUploadedSuccessfully){ + if(!this.isCsvUploadedSuccessfully){ alert.present(); await alert.onDidDismiss(); - this.isPOUploadedSuccessfully = false; + this.isCsvUploadedSuccessfully = false; return canLeave; } }, @@ -225,13 +225,6 @@ export default defineComponent({ } }); this.store.dispatch('stock/updatedStockListItems', this.stock.parsed); - }, - async openMissingSkuModal() { - const missingSkuModal = await modalController.create({ - component: MissingSkuModal, - componentProps: { 'unidentifiedProductItems': this.stock.unidentifiedItems } - }); - return missingSkuModal.present(); }, searchProduct(sku: any) { const product = this.getProduct(sku); @@ -272,7 +265,7 @@ export default defineComponent({ fileName, params })).then(() => { - this.isPOUploadedSuccessfully = true; + this.isCsvUploadedSuccessfully = true; showToast(translate("The inventory has been updated successfully"), [{ text: translate('View'), role: 'view', diff --git a/src/views/PurchaseOrder.vue b/src/views/PurchaseOrder.vue index bff1b23e..5bea703c 100644 --- a/src/views/PurchaseOrder.vue +++ b/src/views/PurchaseOrder.vue @@ -83,7 +83,6 @@ import { defineComponent } from "vue"; import { useRouter } from 'vue-router'; import { showToast, parseCsv } from '@/utils'; import { translate } from "@/i18n"; -import { DateTime } from 'luxon'; import parseFileMixin from '@/mixins/parseFileMixin'; import { mapGetters, useStore } from "vuex"; import { addOutline, arrowForwardOutline } from 'ionicons/icons'; From 5d0158adafde480e79b71f48afd2d4236f44a725 Mon Sep 17 00:00:00 2001 From: Disha Talreja Date: Thu, 2 Feb 2023 19:18:49 +0530 Subject: [PATCH 27/50] Improved code(#31a0f22) --- src/mixins/parseFileMixin.ts | 2 +- src/views/Inventory.vue | 4 ++-- src/views/InventoryDetail.vue | 3 +-- src/views/PurchaseOrder.vue | 19 +++++-------------- 4 files changed, 9 insertions(+), 19 deletions(-) diff --git a/src/mixins/parseFileMixin.ts b/src/mixins/parseFileMixin.ts index 9e3f6c5e..77c95c7d 100644 --- a/src/mixins/parseFileMixin.ts +++ b/src/mixins/parseFileMixin.ts @@ -4,7 +4,7 @@ import { showToast, parseCsv } from "@/utils"; export default { methods: { - async getFile(file: any) { + async parseCsv(file: any) { if (file) { showToast(translate("File uploaded successfully")); store.dispatch('order/updateFileName', file.name); diff --git a/src/views/Inventory.vue b/src/views/Inventory.vue index b111885c..89b51910 100644 --- a/src/views/Inventory.vue +++ b/src/views/Inventory.vue @@ -61,7 +61,7 @@ import { IonPage, IonHeader, IonToolbar, IonTitle, IonContent, IonItem, IonLabel import { defineComponent } from "vue"; import { useRouter } from 'vue-router'; import { useStore, mapGetters } from "vuex"; -import { showToast, parseCsv } from '@/utils'; +import { showToast } from '@/utils'; import { translate } from "@/i18n"; import { arrowForwardOutline } from 'ionicons/icons'; import parseFileMixin from '@/mixins/parseFileMixin'; @@ -106,7 +106,7 @@ export default defineComponent({ methods: { async parse(event) { this.file = event.target.files[0]; - this.content = await this.getFile(this.file); + this.content = await this.parseCsv(this.file); }, mapFields() { const areAllFieldsSelected = Object.values(this.fieldMapping).every(field => field !== ""); diff --git a/src/views/InventoryDetail.vue b/src/views/InventoryDetail.vue index f848b1ab..14151efc 100644 --- a/src/views/InventoryDetail.vue +++ b/src/views/InventoryDetail.vue @@ -138,9 +138,8 @@ import { mapGetters, useStore } from "vuex"; import { useRouter } from 'vue-router'; import { showToast } from '@/utils'; import { translate } from "@/i18n"; -import { IonPage, IonHeader, IonToolbar, IonBackButton, IonContent, IonSearchbar, IonItem, IonThumbnail, IonLabel, IonChip, IonIcon, IonButton, IonCheckbox, IonSelect, IonSelectOption, IonButtons, popoverController, IonFab, IonFabButton, alertController, modalController } from '@ionic/vue' +import { IonPage, IonHeader, IonToolbar, IonBackButton, IonContent, IonSearchbar, IonItem, IonThumbnail, IonLabel, IonChip, IonIcon, IonButton, IonCheckbox, IonSelect, IonSelectOption, IonButtons, popoverController, IonFab, IonFabButton, alertController } from '@ionic/vue' import { ellipsisVerticalOutline, locationOutline, checkboxOutline, cloudUploadOutline, arrowUndoOutline } from 'ionicons/icons' -import MissingSkuModal from "@/components/MissingSkuModal.vue" export default defineComponent({ name: 'InventoryDetail', diff --git a/src/views/PurchaseOrder.vue b/src/views/PurchaseOrder.vue index 5bea703c..182e0063 100644 --- a/src/views/PurchaseOrder.vue +++ b/src/views/PurchaseOrder.vue @@ -12,7 +12,7 @@ {{ $t("Purchase order") }} {{ file.name }} - + @@ -81,7 +81,7 @@ import { IonChip, IonPage, IonHeader, IonToolbar, IonTitle, IonContent, IonItem, IonLabel, IonList, IonListHeader, IonMenuButton, IonButton, IonSelect, IonSelectOption, IonIcon, modalController } from "@ionic/vue"; import { defineComponent } from "vue"; import { useRouter } from 'vue-router'; -import { showToast, parseCsv } from '@/utils'; +import { showToast } from '@/utils'; import { translate } from "@/i18n"; import parseFileMixin from '@/mixins/parseFileMixin'; import { mapGetters, useStore } from "vuex"; @@ -134,18 +134,9 @@ export default defineComponent({ const id = Math.floor(Math.random() * 1000); return !this.fieldMappings[id] ? id : this.generateUniqueMappingPrefId(); }, - async parseFile(event) { - const file = event.target.files[0]; - if(file){ - this.file = file; - await parseCsv(this.file).then(res => { - this.content = res; - }) - this.store.dispatch('order/updateFileName', this.file.name); - showToast(translate("File uploaded successfully")); - } else { - showToast(translate("No new file upload. Please try again")); - } + async parse(event) { + this.file = event.target.files[0]; + this.content = await this.parseCsv(this.file); }, review() { if (this.content.length <= 0) { From 5cd69e203057ae594ac92fe8477c1a5916a3fb3e Mon Sep 17 00:00:00 2001 From: Disha Talreja Date: Mon, 6 Feb 2023 12:12:05 +0530 Subject: [PATCH 28/50] Implemented bulk inventory adjustment modal(#31a0f22) --- .../BulkInventoryAdjustmentModal.vue | 116 ++++++++++++++++++ src/components/ProductPopover.vue | 8 +- src/locales/en.json | 1 + src/store/modules/stock/actions.ts | 2 +- src/views/InventoryDetail.vue | 51 ++++---- 5 files changed, 152 insertions(+), 26 deletions(-) create mode 100644 src/components/BulkInventoryAdjustmentModal.vue diff --git a/src/components/BulkInventoryAdjustmentModal.vue b/src/components/BulkInventoryAdjustmentModal.vue new file mode 100644 index 00000000..5db2d68c --- /dev/null +++ b/src/components/BulkInventoryAdjustmentModal.vue @@ -0,0 +1,116 @@ + + \ No newline at end of file diff --git a/src/components/ProductPopover.vue b/src/components/ProductPopover.vue index 32763098..cca6a372 100644 --- a/src/components/ProductPopover.vue +++ b/src/components/ProductPopover.vue @@ -49,7 +49,7 @@ export default defineComponent({ this.stock.parsed.map(item => { item.isSelected = item.parentProductId === this.id; }) - this.store.dispatch('stock/updatedStockListItems', this.stock.parsed) + this.store.dispatch('stock/updateStockItems', this.stock.parsed) } popoverController.dismiss({ dismissed: true }); }, @@ -63,7 +63,7 @@ export default defineComponent({ this.stock.parsed.map(item => { item.isSelected = item.pseudoId === this.id; }); - this.store.dispatch('stock/updatedStockListItems', this.stock.parsed) + this.store.dispatch('stock/updateStockItems', this.stock.parsed) } popoverController.dismiss({ dismissed: true }); @@ -92,7 +92,7 @@ export default defineComponent({ } return element; }); - this.store.dispatch('stock/updatedStockListItems', this.stock.parsed) + this.store.dispatch('stock/updateStockItems', this.stock.parsed) } popoverController.dismiss({ dismissed: true }); @@ -122,7 +122,7 @@ export default defineComponent({ } return element; }); - this.store.dispatch('stock/updatedStockListItems', this.stock.parsed); + this.store.dispatch('stock/updateStockItems', this.stock.parsed); } popoverController.dismiss({ dismissed: true }); } diff --git a/src/locales/en.json b/src/locales/en.json index 9db956a7..bb866193 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -12,6 +12,7 @@ "Blank": "Blank", "Buffer days": "Buffer days", "Bulk adjustment": "Bulk adjustment", + "Buffer quantity": "Buffer quantity", "cancel": "cancel", "Cancel": "Cancel", "Catalog": "Catalog", diff --git a/src/store/modules/stock/actions.ts b/src/store/modules/stock/actions.ts index 1f2b63a2..d118bfdb 100644 --- a/src/store/modules/stock/actions.ts +++ b/src/store/modules/stock/actions.ts @@ -37,7 +37,7 @@ const actions: ActionTree = { commit(types.STOCK_LIST_UPDATED, { items, original, unidentifiedItems }); }, - updatedStockListItems({ commit }, stockItems){ + updateStockItems({ commit }, stockItems){ commit(types.STOCK_LIST_ITEMS_UPDATED, stockItems); }, clearStockList({ commit }){ diff --git a/src/views/InventoryDetail.vue b/src/views/InventoryDetail.vue index 14151efc..1bc0ced3 100644 --- a/src/views/InventoryDetail.vue +++ b/src/views/InventoryDetail.vue @@ -18,20 +18,16 @@
+
- - {{ $t("Facility") }} - - {{ facility.facilityName }} - + + + {{ $t("Bulk adjustment") }} + {{ getSelectedItems() }} {{ $t("items selected") }} + - {{ $t("Apply") }}
@@ -133,13 +129,14 @@ import { UploadService } from "@/services/UploadService"; import Image from '@/components/Image.vue'; import ProductPopover from '@/components/ProductPopover.vue' +import BulkInventoryAdjustmentModal from '@/components/BulkInventoryAdjustmentModal.vue' import { defineComponent } from 'vue'; import { mapGetters, useStore } from "vuex"; import { useRouter } from 'vue-router'; import { showToast } from '@/utils'; import { translate } from "@/i18n"; -import { IonPage, IonHeader, IonToolbar, IonBackButton, IonContent, IonSearchbar, IonItem, IonThumbnail, IonLabel, IonChip, IonIcon, IonButton, IonCheckbox, IonSelect, IonSelectOption, IonButtons, popoverController, IonFab, IonFabButton, alertController } from '@ionic/vue' -import { ellipsisVerticalOutline, locationOutline, checkboxOutline, cloudUploadOutline, arrowUndoOutline } from 'ionicons/icons' +import { IonPage, IonHeader, IonToolbar, IonBackButton, IonContent, IonSearchbar, IonItem, IonThumbnail, IonLabel, IonChip, IonIcon, IonButton, IonCheckbox, IonSelect, IonSelectOption, IonButtons, popoverController, IonFab, IonFabButton, modalController, alertController, IonNote } from '@ionic/vue' +import { calculatorOutline, chevronForwardOutline, ellipsisVerticalOutline, locationOutline, checkboxOutline, cloudUploadOutline, arrowUndoOutline } from 'ionicons/icons' export default defineComponent({ name: 'InventoryDetail', @@ -162,7 +159,8 @@ export default defineComponent({ IonSelectOption, IonButtons, IonFab, - IonFabButton + IonFabButton, + IonNote }, computed: { ...mapGetters({ @@ -217,14 +215,17 @@ export default defineComponent({ }, methods: { + getSelectedItems(){ + return Object.values(this.stock.parsed).filter((item: any) => item.isSelected).length; + }, setFacilityLocation(ev: CustomEvent, product: any){ this.stock.parsed.map((item: any) => { if(item.pseudoId === product.pseudoId){ item.locationSeqId = ev.detail.value; } }); - this.store.dispatch('stock/updatedStockListItems', this.stock.parsed); - }, + this.store.dispatch('stock/updateStockItems', this.stock.parsed); + }, searchProduct(sku: any) { const product = this.getProduct(sku); this.searchedProduct = this.stock.parsed.find((item: any) => { @@ -303,11 +304,11 @@ export default defineComponent({ }, selectProduct(item: any, event: any) { item.isSelected = event.detail.checked; - this.store.dispatch('stock/updatedStockListItems', this.stock.parsed) + this.store.dispatch('stock/updateStockItems', this.stock.parsed) }, revertAll() { const original = JSON.parse(JSON.stringify(this.stock.original)); - this.store.dispatch('stock/updatedStockListItems', original); + this.store.dispatch('stock/updateStockItems', original); }, async apply() { if(this.facilityId) { @@ -321,7 +322,7 @@ export default defineComponent({ } }) } - await this.store.dispatch('stock/updatedStockListItems', this.stock.parsed); + await this.store.dispatch('stock/updateStockItems', this.stock.parsed); }, getParentProductIds (items: any) { return Array.from(new Set(items.map((ele: any) => ele.parentProductId))); @@ -336,7 +337,7 @@ export default defineComponent({ this.stock.parsed.forEach((item: any) => { item.isSelected = true; }) - this.store.dispatch('stock/updatedStockListItems', this.stock.parsed) + this.store.dispatch('stock/updateStockItems', this.stock.parsed) }, selectParentProduct(parentProductId: any, event: any) { // Todo: Need to find a better approach. @@ -348,14 +349,22 @@ export default defineComponent({ }) this.isParentProductUpdated = false; } - this.store.dispatch('stock/updatedStockListItems', this.stock.parsed); - } + this.store.dispatch('stock/updateStockItems', this.stock.parsed); + }, + async openBulkInventoryAdjustmentModal() { + const bulkInventoryAdjustmentModal = await modalController.create({ + component: BulkInventoryAdjustmentModal, + }); + return bulkInventoryAdjustmentModal.present(); + }, }, setup() { const router = useRouter(); const store = useStore(); return { + calculatorOutline, + chevronForwardOutline, checkboxOutline, ellipsisVerticalOutline, locationOutline, From d67608a7fbf578b88e583a12b214adaa7dd7af49 Mon Sep 17 00:00:00 2001 From: Disha Talreja Date: Mon, 6 Feb 2023 16:08:51 +0530 Subject: [PATCH 29/50] Implemented logic to map missing facilities(#31a0f22) --- .../BulkInventoryAdjustmentModal.vue | 9 +++-- src/components/MissingFacilitiesModal.vue | 40 ++++++++++++++----- src/views/InventoryDetail.vue | 23 ++++++++++- src/views/PurchaseOrderReview.vue | 6 +-- 4 files changed, 60 insertions(+), 18 deletions(-) diff --git a/src/components/BulkInventoryAdjustmentModal.vue b/src/components/BulkInventoryAdjustmentModal.vue index 5db2d68c..9d2ee78b 100644 --- a/src/components/BulkInventoryAdjustmentModal.vue +++ b/src/components/BulkInventoryAdjustmentModal.vue @@ -88,18 +88,21 @@ export default defineComponent({ closeModal() { modalController.dismiss({ dismissed: true }); }, - save() { - this.stock.parsed.map((item: any) => { + async save() { + const facilityLocations = await this.store.dispatch('user/fetchFacilityLocations', [this.facilityId]); + await this.stock.parsed.map((item: any) => { if (item.isSelected) { if(this.quantityBuffer != '') item.quantity = this.quantityBuffer; if(this.facilityId) { item.facilityId = this.facilityId; item.externalFacilityId = ""; + //TODO: Need to improve the handling of locationSeqId. + item.locationSeqId = facilityLocations && facilityLocations[0] && facilityLocations[0].locationSeqId ? facilityLocations[0].locationSeqId : ""; } } }) - this.store.dispatch('stock/updateStockItems', this.stock.parsed) + await this.store.dispatch('stock/updateStockItems', this.stock.parsed) this.closeModal(); showToast(translate("Changes have been successfully applied")); }, diff --git a/src/components/MissingFacilitiesModal.vue b/src/components/MissingFacilitiesModal.vue index 2b48e246..5ea1fb0e 100644 --- a/src/components/MissingFacilitiesModal.vue +++ b/src/components/MissingFacilitiesModal.vue @@ -70,7 +70,7 @@ export default defineComponent({ IonTitle, IonToolbar }, - props: ["itemsWithMissingFacility", "facilities"], + props: ["itemsWithMissingFacility", "facilities", "type"], data() { return { itemsByFacilityId: {}, @@ -79,23 +79,41 @@ export default defineComponent({ }, computed: { ...mapGetters({ - purchaseOrders: 'order/getPurchaseOrders' + purchaseOrders: 'order/getPurchaseOrders', + stock: 'stock/getItemsStock', + getFacilityLocationsByFacilityId: 'user/getFacilityLocationsByFacilityId', }) }, mounted(){ this.groupItemsByFacilityId(); }, methods: { - save(){ - Object.keys(this.facilityMapping).map((facilityId: any) => { - Object.values(this.purchaseOrders.parsed).flat().map((item: any) => { - if(item.externalFacilityId === facilityId){ - item.externalFacilityId = ""; - item.facilityId = this.facilityMapping[facilityId]; - } + async save(){ + if(this.type === 'order'){ + Object.keys(this.facilityMapping).map((facilityId: any) => { + Object.values(this.purchaseOrders.parsed).flat().map((item: any) => { + if(item.externalFacilityId === facilityId){ + item.externalFacilityId = ""; + item.facilityId = this.facilityMapping[facilityId]; + } + }) }) - }) - this.store.dispatch('order/updatePurchaseOrders', this.purchaseOrders); + this.store.dispatch('order/updatePurchaseOrders', this.purchaseOrders); + } else { + await this.store.dispatch('user/fetchFacilityLocations', Object.values(this.facilityMapping)); + Object.keys(this.facilityMapping).map((facilityId: any) => { + const locationSeqId = this.getFacilityLocationsByFacilityId(this.facilityMapping[facilityId]).length ? this.getFacilityLocationsByFacilityId(this.facilityMapping[facilityId])[0].locationSeqId : ''; + this.stock.parsed.map((item: any) => { + if(item.externalFacilityId === facilityId){ + item.externalFacilityId = ""; + item.facilityId = this.facilityMapping[facilityId]; + item.locationSeqId = locationSeqId; + } + }) + }) + this.store.dispatch('stock/updateStockItems', this.stock.parsed); + } + this.closeModal(); showToast(translate("Changes have been successfully applied")); }, diff --git a/src/views/InventoryDetail.vue b/src/views/InventoryDetail.vue index 1bc0ced3..59dcca6c 100644 --- a/src/views/InventoryDetail.vue +++ b/src/views/InventoryDetail.vue @@ -28,6 +28,13 @@ + + + {{ $t("Missing facilities") }} + {{ getItemsWithMissingFacility().length }} {{ $t("items") }} + + +
@@ -130,13 +137,14 @@ import { UploadService } from "@/services/UploadService"; import Image from '@/components/Image.vue'; import ProductPopover from '@/components/ProductPopover.vue' import BulkInventoryAdjustmentModal from '@/components/BulkInventoryAdjustmentModal.vue' +import MissingFacilitiesModal from '@/components/MissingFacilitiesModal.vue' import { defineComponent } from 'vue'; import { mapGetters, useStore } from "vuex"; import { useRouter } from 'vue-router'; import { showToast } from '@/utils'; import { translate } from "@/i18n"; import { IonPage, IonHeader, IonToolbar, IonBackButton, IonContent, IonSearchbar, IonItem, IonThumbnail, IonLabel, IonChip, IonIcon, IonButton, IonCheckbox, IonSelect, IonSelectOption, IonButtons, popoverController, IonFab, IonFabButton, modalController, alertController, IonNote } from '@ionic/vue' -import { calculatorOutline, chevronForwardOutline, ellipsisVerticalOutline, locationOutline, checkboxOutline, cloudUploadOutline, arrowUndoOutline } from 'ionicons/icons' +import { businessOutline, calculatorOutline, chevronForwardOutline, ellipsisVerticalOutline, locationOutline, checkboxOutline, cloudUploadOutline, arrowUndoOutline } from 'ionicons/icons' export default defineComponent({ name: 'InventoryDetail', @@ -215,6 +223,18 @@ export default defineComponent({ }, methods: { + getItemsWithMissingFacility() { + const facilityIds = this.facilities.map((facility: any) => facility.facilityId) + return this.stock.parsed.filter((item: any) => !facilityIds.includes(item.externalFacilityId) && item.externalFacilityId !== ""); + }, + async openMissingFacilitiesModal() { + const itemsWithMissingFacility = this.getItemsWithMissingFacility(); + const missingFacilitiesModal = await modalController.create({ + component: MissingFacilitiesModal, + componentProps: { itemsWithMissingFacility, facilities: this.facilities, type: 'stock' } + }); + return missingFacilitiesModal.present(); + }, getSelectedItems(){ return Object.values(this.stock.parsed).filter((item: any) => item.isSelected).length; }, @@ -363,6 +383,7 @@ export default defineComponent({ const store = useStore(); return { + businessOutline, calculatorOutline, chevronForwardOutline, checkboxOutline, diff --git a/src/views/PurchaseOrderReview.vue b/src/views/PurchaseOrderReview.vue index 99fba765..7babb844 100644 --- a/src/views/PurchaseOrderReview.vue +++ b/src/views/PurchaseOrderReview.vue @@ -88,7 +88,7 @@ import { ellipsisVerticalOutline, businessOutline, shirtOutline, sendOutline, ch import PurchaseOrderDetail from '@/components/PurchaseOrderDetail.vue' import DateTimeParseErrorModal from '@/components/DateTimeParseErrorModal.vue'; import BulkAdjustmentModal from '@/components/BulkAdjustmentModal.vue'; -import MissingFacilityModal from '@/components/MissingFacilitiesModal.vue'; +import MissingFacilitiesModal from '@/components/MissingFacilitiesModal.vue'; import MissingSkuModal from "@/components/MissingSkuModal.vue" import { UploadService } from "@/services/UploadService"; import { showToast } from '@/utils'; @@ -269,8 +269,8 @@ export default defineComponent({ async openMissingFacilitiesModal() { const itemsWithMissingFacility = this.getItemsWithMissingFacility(); const missingFacilitiesModal = await modalController.create({ - component: MissingFacilityModal, - componentProps: { itemsWithMissingFacility, facilities: this.facilities } + component: MissingFacilitiesModal, + componentProps: { itemsWithMissingFacility, facilities: this.facilities, type: 'order' } }); return missingFacilitiesModal.present(); }, From c89d2588209e7d081a4107f82b2aca351b9d22cd Mon Sep 17 00:00:00 2001 From: Disha Talreja Date: Mon, 6 Feb 2023 19:37:40 +0530 Subject: [PATCH 30/50] Implemented logic to update missing skus(#31a0f22) --- .../BulkInventoryAdjustmentModal.vue | 2 +- src/components/MissingFacilitiesModal.vue | 2 +- src/components/MissingSkuModal.vue | 32 ++++++++++++------- src/components/ProductPopover.vue | 8 ++--- src/store/modules/stock/actions.ts | 23 ++++++++++--- src/store/modules/stock/mutation-types.ts | 2 +- src/store/modules/stock/mutations.ts | 4 +-- src/views/InventoryDetail.vue | 31 +++++++++++++----- src/views/PurchaseOrderReview.vue | 2 +- 9 files changed, 72 insertions(+), 34 deletions(-) diff --git a/src/components/BulkInventoryAdjustmentModal.vue b/src/components/BulkInventoryAdjustmentModal.vue index 9d2ee78b..e0865167 100644 --- a/src/components/BulkInventoryAdjustmentModal.vue +++ b/src/components/BulkInventoryAdjustmentModal.vue @@ -102,7 +102,7 @@ export default defineComponent({ } } }) - await this.store.dispatch('stock/updateStockItems', this.stock.parsed) + await this.store.dispatch('stock/updateStockItems', this.stock) this.closeModal(); showToast(translate("Changes have been successfully applied")); }, diff --git a/src/components/MissingFacilitiesModal.vue b/src/components/MissingFacilitiesModal.vue index 5ea1fb0e..c7860250 100644 --- a/src/components/MissingFacilitiesModal.vue +++ b/src/components/MissingFacilitiesModal.vue @@ -111,7 +111,7 @@ export default defineComponent({ } }) }) - this.store.dispatch('stock/updateStockItems', this.stock.parsed); + this.store.dispatch('stock/updateStockItems', this.stock); } this.closeModal(); diff --git a/src/components/MissingSkuModal.vue b/src/components/MissingSkuModal.vue index e9f515b1..86d34b00 100644 --- a/src/components/MissingSkuModal.vue +++ b/src/components/MissingSkuModal.vue @@ -14,7 +14,7 @@
- {{ $t("The SKU is successfully changed") }} + {{ $t("The SKU is successfully changed") }} {{ $t("This SKU is not available, please try again") }} {{ $t("Update") }} @@ -31,12 +31,12 @@ - + - {{ item.shopifyProductSKU }} + {{ item.shopifyProductSKU ? item.shopifyProductSKU : item.productSKU }}

{{ item.orderId }}

- +
@@ -122,8 +122,10 @@ export default defineComponent({ computed: { ...mapGetters({ purchaseOrders: 'order/getPurchaseOrders', + stock: 'stock/getItemsStock', }) }, + props: ['type'], methods: { selectInputText(event: any) { event.target.getInputElement().then((element: any) => { @@ -134,13 +136,16 @@ export default defineComponent({ modalController.dismiss({ dismissed: true }); }, getPendingItems(){ - return this.purchaseOrders.unidentifiedItems.filter((item: any) => !item.updatedSku); + if(this.type === 'order') return this.purchaseOrders.unidentifiedItems.filter((item: any) => !item.updatedSku); + return this.stock.unidentifiedItems.filter((item: any) => !item.updatedSku); }, getCompletedItems(){ - return this.purchaseOrders.unidentifiedItems.filter((item: any) => item.updatedSku); + if(this.type === 'order') return this.purchaseOrders.unidentifiedItems.filter((item: any) => item.updatedSku); + return this.stock.unidentifiedItems.filter((item: any) => item.updatedSku); }, save(){ - this.store.dispatch('order/updateUnidentifiedItem', { unidentifiedItems: this.purchaseOrders.unidentifiedItems }); + if(this.type === 'order') this.store.dispatch('order/updateUnidentifiedItem', { unidentifiedItems: this.purchaseOrders.unidentifiedItems }); + else this.store.dispatch('stock/updateUnidentifiedItem', { unidentifiedItems: this.stock.unidentifiedItems }); this.closeModal(); }, async update() { @@ -154,18 +159,23 @@ export default defineComponent({ const products = await this.store.dispatch("product/fetchProducts", payload); if (products.length) { const item = products[0]; - const unidentifiedItem = this.purchaseOrders.unidentifiedItems.find((unidentifiedItem: any) => unidentifiedItem.shopifyProductSKU === this.unidentifiedProductSku); - + let unidentifiedItem; + if (this.type === 'order'){ + unidentifiedItem = this.purchaseOrders.unidentifiedItems.find((unidentifiedItem: any) => unidentifiedItem.shopifyProductSKU === this.unidentifiedProductSku); + unidentifiedItem.isNewProduct = "N"; + } else { + unidentifiedItem = this.stock.unidentifiedItems.find((unidentifiedItem: any) => unidentifiedItem.productSKU === this.unidentifiedProductSku); + } unidentifiedItem.updatedSku = this.updatedSku; unidentifiedItem.parentProductId = item.parent.id; unidentifiedItem.pseudoId = item.pseudoId; unidentifiedItem.parentProductName = item.parent.productName; unidentifiedItem.imageUrl = item.images.mainImageUrl; - unidentifiedItem.isNewProduct = "N"; unidentifiedItem.isSelected = true; this.hasSkuUpdated = true; - this.store.dispatch('order/updatePurchaseOrders', this.purchaseOrders); + if (this.type === 'order') this.store.dispatch('order/updatePurchaseOrders', this.purchaseOrders); + else this.store.dispatch('stock/updateStockItems', this.stock); } else { this.isSkuInvalid = true; } diff --git a/src/components/ProductPopover.vue b/src/components/ProductPopover.vue index cca6a372..6749e3dd 100644 --- a/src/components/ProductPopover.vue +++ b/src/components/ProductPopover.vue @@ -49,7 +49,7 @@ export default defineComponent({ this.stock.parsed.map(item => { item.isSelected = item.parentProductId === this.id; }) - this.store.dispatch('stock/updateStockItems', this.stock.parsed) + this.store.dispatch('stock/updateStockItems', this.stock) } popoverController.dismiss({ dismissed: true }); }, @@ -63,7 +63,7 @@ export default defineComponent({ this.stock.parsed.map(item => { item.isSelected = item.pseudoId === this.id; }); - this.store.dispatch('stock/updateStockItems', this.stock.parsed) + this.store.dispatch('stock/updateStockItems', this.stock) } popoverController.dismiss({ dismissed: true }); @@ -92,7 +92,7 @@ export default defineComponent({ } return element; }); - this.store.dispatch('stock/updateStockItems', this.stock.parsed) + this.store.dispatch('stock/updateStockItems', this.stock) } popoverController.dismiss({ dismissed: true }); @@ -122,7 +122,7 @@ export default defineComponent({ } return element; }); - this.store.dispatch('stock/updateStockItems', this.stock.parsed); + this.store.dispatch('stock/updateStockItems', this.stock); } popoverController.dismiss({ dismissed: true }); } diff --git a/src/store/modules/stock/actions.ts b/src/store/modules/stock/actions.ts index d118bfdb..d19ec9ad 100644 --- a/src/store/modules/stock/actions.ts +++ b/src/store/modules/stock/actions.ts @@ -18,7 +18,7 @@ const actions: ActionTree = { await store.dispatch('user/fetchFacilityLocations', facilityIds); await store.dispatch("product/fetchProducts", payload); const unidentifiedItems = [] as any; - items = items.map((item: any) => { + const parsed = items.map((item: any) => { const product = rootGetters['product/getProduct'](item.productSKU) if(Object.keys(product).length > 0){ @@ -26,7 +26,6 @@ const actions: ActionTree = { item.pseudoId = product.pseudoId; item.parentProductName = product?.parent?.productName; item.imageUrl = product.images?.mainImageUrl; - item.isNewProduct = "N"; item.isSelected = true; return item; } @@ -35,13 +34,27 @@ const actions: ActionTree = { }).filter((item: any) => item); const original = JSON.parse(JSON.stringify(items)) - commit(types.STOCK_LIST_UPDATED, { items, original, unidentifiedItems }); + commit(types.STOCK_ITEMS_UPDATED, { parsed, original, unidentifiedItems }); }, updateStockItems({ commit }, stockItems){ - commit(types.STOCK_LIST_ITEMS_UPDATED, stockItems); + commit(types.STOCK_ITEMS_UPDATED, stockItems); }, clearStockList({ commit }){ - commit(types.STOCK_LIST_UPDATED, { items: [], original: [], unidentifiedItems: []}); + commit(types.STOCK_ITEMS_UPDATED, { parsed: [], original: [], unidentifiedItems: []}); + }, + updateUnidentifiedItem({ commit, state }, payload: any) { + const parsed = state.items.parsed as any; + const unidentifiedItems = payload.unidentifiedItems.map((item: any) => { + if(item.updatedSku) { + item.shopifyProductSKU = item.updatedSku; + parsed.push(item); + } else { + return item; + } + }).filter((item: any) => item); + const original = JSON.parse(JSON.stringify(state.items.parsed)); + + commit(types.STOCK_ITEMS_UPDATED, { parsed, original, unidentifiedItems}); } } export default actions; diff --git a/src/store/modules/stock/mutation-types.ts b/src/store/modules/stock/mutation-types.ts index 295a2b98..4262343f 100644 --- a/src/store/modules/stock/mutation-types.ts +++ b/src/store/modules/stock/mutation-types.ts @@ -1,3 +1,3 @@ export const SN_STOCK = 'stock' -export const STOCK_LIST_UPDATED = SN_STOCK + '/LIST_UPDATED' +export const STOCK_ITEMS_UPDATED = SN_STOCK + '/LIST_UPDATED' export const STOCK_LIST_ITEMS_UPDATED = SN_STOCK + '/LIST_ITEMS_UPDATED' \ No newline at end of file diff --git a/src/store/modules/stock/mutations.ts b/src/store/modules/stock/mutations.ts index 1fd743c2..1a77426d 100644 --- a/src/store/modules/stock/mutations.ts +++ b/src/store/modules/stock/mutations.ts @@ -3,8 +3,8 @@ import StockState from './StockState' import * as types from './mutation-types' const mutations: MutationTree = { - [types.STOCK_LIST_UPDATED] (state, payload) { - state.items.parsed = payload.items; + [types.STOCK_ITEMS_UPDATED] (state, payload) { + state.items.parsed = payload.parsed; state.items.original = payload.original; state.items.unidentifiedItems = payload.unidentifiedItems; }, diff --git a/src/views/InventoryDetail.vue b/src/views/InventoryDetail.vue index 59dcca6c..6fea1d16 100644 --- a/src/views/InventoryDetail.vue +++ b/src/views/InventoryDetail.vue @@ -35,6 +35,12 @@ + + + {{ $t("Missing products") }} + {{ stock.unidentifiedItems.length }} {{ $t("items") }} + +
@@ -138,13 +144,14 @@ import Image from '@/components/Image.vue'; import ProductPopover from '@/components/ProductPopover.vue' import BulkInventoryAdjustmentModal from '@/components/BulkInventoryAdjustmentModal.vue' import MissingFacilitiesModal from '@/components/MissingFacilitiesModal.vue' +import MissingSkuModal from "@/components/MissingSkuModal.vue" import { defineComponent } from 'vue'; import { mapGetters, useStore } from "vuex"; import { useRouter } from 'vue-router'; import { showToast } from '@/utils'; import { translate } from "@/i18n"; import { IonPage, IonHeader, IonToolbar, IonBackButton, IonContent, IonSearchbar, IonItem, IonThumbnail, IonLabel, IonChip, IonIcon, IonButton, IonCheckbox, IonSelect, IonSelectOption, IonButtons, popoverController, IonFab, IonFabButton, modalController, alertController, IonNote } from '@ionic/vue' -import { businessOutline, calculatorOutline, chevronForwardOutline, ellipsisVerticalOutline, locationOutline, checkboxOutline, cloudUploadOutline, arrowUndoOutline } from 'ionicons/icons' +import { businessOutline, calculatorOutline, chevronForwardOutline, ellipsisVerticalOutline, locationOutline, shirtOutline, checkboxOutline, cloudUploadOutline, arrowUndoOutline } from 'ionicons/icons' export default defineComponent({ name: 'InventoryDetail', @@ -223,6 +230,13 @@ export default defineComponent({ }, methods: { + async openMissingSkuModal() { + const missingSkuModal = await modalController.create({ + component: MissingSkuModal, + componentProps: { 'unidentifiedItems': this.stock.unidentifiedItems, type: 'stock' } + }); + return missingSkuModal.present(); + }, getItemsWithMissingFacility() { const facilityIds = this.facilities.map((facility: any) => facility.facilityId) return this.stock.parsed.filter((item: any) => !facilityIds.includes(item.externalFacilityId) && item.externalFacilityId !== ""); @@ -244,7 +258,7 @@ export default defineComponent({ item.locationSeqId = ev.detail.value; } }); - this.store.dispatch('stock/updateStockItems', this.stock.parsed); + this.store.dispatch('stock/updateStockItems', this.stock); }, searchProduct(sku: any) { const product = this.getProduct(sku); @@ -324,11 +338,11 @@ export default defineComponent({ }, selectProduct(item: any, event: any) { item.isSelected = event.detail.checked; - this.store.dispatch('stock/updateStockItems', this.stock.parsed) + this.store.dispatch('stock/updateStockItems', this.stock) }, revertAll() { - const original = JSON.parse(JSON.stringify(this.stock.original)); - this.store.dispatch('stock/updateStockItems', original); + this.stock.parsed = JSON.parse(JSON.stringify(this.stock.original)); + this.store.dispatch('stock/updateStockItems', this.stock); }, async apply() { if(this.facilityId) { @@ -342,7 +356,7 @@ export default defineComponent({ } }) } - await this.store.dispatch('stock/updateStockItems', this.stock.parsed); + await this.store.dispatch('stock/updateStockItems', this.stock); }, getParentProductIds (items: any) { return Array.from(new Set(items.map((ele: any) => ele.parentProductId))); @@ -357,7 +371,7 @@ export default defineComponent({ this.stock.parsed.forEach((item: any) => { item.isSelected = true; }) - this.store.dispatch('stock/updateStockItems', this.stock.parsed) + this.store.dispatch('stock/updateStockItems', this.stock) }, selectParentProduct(parentProductId: any, event: any) { // Todo: Need to find a better approach. @@ -369,7 +383,7 @@ export default defineComponent({ }) this.isParentProductUpdated = false; } - this.store.dispatch('stock/updateStockItems', this.stock.parsed); + this.store.dispatch('stock/updateStockItems', this.stock); }, async openBulkInventoryAdjustmentModal() { const bulkInventoryAdjustmentModal = await modalController.create({ @@ -390,6 +404,7 @@ export default defineComponent({ ellipsisVerticalOutline, locationOutline, arrowUndoOutline, + shirtOutline, cloudUploadOutline, router, store, diff --git a/src/views/PurchaseOrderReview.vue b/src/views/PurchaseOrderReview.vue index 7babb844..2617a26d 100644 --- a/src/views/PurchaseOrderReview.vue +++ b/src/views/PurchaseOrderReview.vue @@ -187,7 +187,7 @@ export default defineComponent({ async openMissingSkuModal() { const missingSkuModal = await modalController.create({ component: MissingSkuModal, - componentProps: { 'unidentifiedItems': this.purchaseOrders.unidentifiedItems } + componentProps: { 'unidentifiedItems': this.purchaseOrders.unidentifiedItems, type: 'order' } }); return missingSkuModal.present(); }, From 8a70310b820ffcd843bd5d4a4186bc5536a4d274 Mon Sep 17 00:00:00 2001 From: Disha Talreja Date: Tue, 7 Feb 2023 12:33:15 +0530 Subject: [PATCH 31/50] fix: improved the handling of facilityLocations(#31a0f22) --- .../BulkInventoryAdjustmentModal.vue | 4 ++-- src/components/MissingFacilitiesModal.vue | 5 ++--- src/store/modules/user/actions.ts | 18 ++++++++++-------- src/store/modules/user/mutations.ts | 6 ++++-- src/views/InventoryDetail.vue | 8 ++++---- 5 files changed, 22 insertions(+), 19 deletions(-) diff --git a/src/components/BulkInventoryAdjustmentModal.vue b/src/components/BulkInventoryAdjustmentModal.vue index e0865167..63106ef1 100644 --- a/src/components/BulkInventoryAdjustmentModal.vue +++ b/src/components/BulkInventoryAdjustmentModal.vue @@ -90,6 +90,7 @@ export default defineComponent({ }, async save() { const facilityLocations = await this.store.dispatch('user/fetchFacilityLocations', [this.facilityId]); + const locationSeqId = facilityLocations[this.facilityId] && facilityLocations[this.facilityId][0] ? facilityLocations[this.facilityId][0].locationSeqId : ''; await this.stock.parsed.map((item: any) => { if (item.isSelected) { if(this.quantityBuffer != '') @@ -97,8 +98,7 @@ export default defineComponent({ if(this.facilityId) { item.facilityId = this.facilityId; item.externalFacilityId = ""; - //TODO: Need to improve the handling of locationSeqId. - item.locationSeqId = facilityLocations && facilityLocations[0] && facilityLocations[0].locationSeqId ? facilityLocations[0].locationSeqId : ""; + item.locationSeqId = locationSeqId; } } }) diff --git a/src/components/MissingFacilitiesModal.vue b/src/components/MissingFacilitiesModal.vue index c7860250..a966f5f2 100644 --- a/src/components/MissingFacilitiesModal.vue +++ b/src/components/MissingFacilitiesModal.vue @@ -81,7 +81,6 @@ export default defineComponent({ ...mapGetters({ purchaseOrders: 'order/getPurchaseOrders', stock: 'stock/getItemsStock', - getFacilityLocationsByFacilityId: 'user/getFacilityLocationsByFacilityId', }) }, mounted(){ @@ -100,9 +99,9 @@ export default defineComponent({ }) this.store.dispatch('order/updatePurchaseOrders', this.purchaseOrders); } else { - await this.store.dispatch('user/fetchFacilityLocations', Object.values(this.facilityMapping)); + const facilityLocations = await this.store.dispatch('user/fetchFacilityLocations', Object.values(this.facilityMapping)); Object.keys(this.facilityMapping).map((facilityId: any) => { - const locationSeqId = this.getFacilityLocationsByFacilityId(this.facilityMapping[facilityId]).length ? this.getFacilityLocationsByFacilityId(this.facilityMapping[facilityId])[0].locationSeqId : ''; + const locationSeqId = facilityLocations[this.facilityMapping[facilityId]].length ? facilityLocations[this.facilityMapping[facilityId]][0].locationSeqId : ''; this.stock.parsed.map((item: any) => { if(item.externalFacilityId === facilityId){ item.externalFacilityId = ""; diff --git a/src/store/modules/user/actions.ts b/src/store/modules/user/actions.ts index bb0e147f..96cdf2d7 100644 --- a/src/store/modules/user/actions.ts +++ b/src/store/modules/user/actions.ts @@ -128,11 +128,14 @@ const actions: ActionTree = { updateInstanceUrl(payload) }, - async fetchFacilityLocations({ commit }, facilityId){ + async fetchFacilityLocations({ commit, state }, facilityIds){ + facilityIds = facilityIds.filter((facilityId: any) => !state.facilityLocationsByFacilityId[facilityId]) + if(!facilityIds.length) return state.facilityLocationsByFacilityId; + let resp; const params = { "inputFields": { - facilityId, + facilityId: facilityIds, "facilityId_op": 'in' }, // Assuming we will not have more than 20 facility locations, hardcoded the viewSize value 20. @@ -142,7 +145,7 @@ const actions: ActionTree = { "distinct": "Y", "noConditionFind": "Y" } - try{ + try { resp = await UserService.getFacilityLocations(params); if(resp.status === 200 && !hasError(resp) && resp.data?.count > 0) { let facilityLocations = resp.data.docs @@ -152,18 +155,17 @@ const actions: ActionTree = { locationSeqId: location.locationSeqId, locationPath: locationPath } - locations.push(facilityLocation); + locations[location.facilityId] ? locations[location.facilityId].push(facilityLocation) : locations[location.facilityId] = [facilityLocation]; return locations; - }, []); - commit(types.USER_FACILITY_LOCATIONS_BY_FACILITY_ID, { facilityLocations, facilityId }); - return facilityLocations; + }, {}); + commit(types.USER_FACILITY_LOCATIONS_BY_FACILITY_ID, facilityLocations); } else { console.error(resp); } } catch(err) { console.error(err); - return []; } + return state.facilityLocationsByFacilityId; }, async getFieldMappings({ commit }) { diff --git a/src/store/modules/user/mutations.ts b/src/store/modules/user/mutations.ts index eba46219..f07817f8 100644 --- a/src/store/modules/user/mutations.ts +++ b/src/store/modules/user/mutations.ts @@ -27,8 +27,10 @@ const mutations: MutationTree = { [types.USER_DATETIME_FORMAT_UPDATED] (state, payload) { state.preferredDateTimeFormat = payload; }, - [types.USER_FACILITY_LOCATIONS_BY_FACILITY_ID] (state, payload) { - state.facilityLocationsByFacilityId[payload.facilityId] = payload.facilityLocations; + [types.USER_FACILITY_LOCATIONS_BY_FACILITY_ID] (state, facilityLocations) { + Object.keys(facilityLocations).map((facilityId: any) => { + state.facilityLocationsByFacilityId[facilityId] = facilityLocations[facilityId]; + }) }, [types.USER_CURRENT_FIELD_MAPPING_UPDATED] (state, payload) { state.currentMapping = payload diff --git a/src/views/InventoryDetail.vue b/src/views/InventoryDetail.vue index 6fea1d16..35a1350d 100644 --- a/src/views/InventoryDetail.vue +++ b/src/views/InventoryDetail.vue @@ -116,7 +116,7 @@ - {{ facilityLocation.locationSeqId }} + {{ facilityLocation.locationPath }} @@ -347,11 +347,11 @@ export default defineComponent({ async apply() { if(this.facilityId) { const facilityLocations = await this.store.dispatch('user/fetchFacilityLocations', [this.facilityId]); - await this.stock.parsed.map((item: any) => { + const locationSeqId = facilityLocations[this.facilityId] && facilityLocations[this.facilityId][0] && facilityLocations[this.facilityId][0].locaionSeqId ? facilityLocations[this.facilityId][0].locaionSeqId : ''; + this.stock.parsed.map((item: any) => { if (item.isSelected) { item.facilityId = this.facilityId; - //TODO: Need to improve the handling of locationSeqId. - item.locationSeqId = facilityLocations && facilityLocations[0] && facilityLocations[0].locationSeqId ? facilityLocations[0].locationSeqId : ""; + item.locationSeqId = locationSeqId; item.externalFacilityId = ""; } }) From 6df53524d671c7711dd51c21e8a8fa7aa55a67ad Mon Sep 17 00:00:00 2001 From: Disha Talreja Date: Tue, 7 Feb 2023 12:53:33 +0530 Subject: [PATCH 32/50] Improved handing of facility locations and updated variable name(#31a0f22) --- src/components/MissingSkuModal.vue | 48 ++++++++++++++++-------------- src/components/ProductPopover.vue | 2 +- src/store/modules/stock/actions.ts | 4 +-- src/views/Inventory.vue | 2 +- src/views/InventoryDetail.vue | 2 +- 5 files changed, 30 insertions(+), 28 deletions(-) diff --git a/src/components/MissingSkuModal.vue b/src/components/MissingSkuModal.vue index 86d34b00..e612db0e 100644 --- a/src/components/MissingSkuModal.vue +++ b/src/components/MissingSkuModal.vue @@ -31,12 +31,12 @@ - + - {{ item.shopifyProductSKU ? item.shopifyProductSKU : item.productSKU }} + {{ item.shopifyProductSKU }}

{{ item.orderId }}

- +
@@ -157,27 +157,29 @@ export default defineComponent({ productIds: [this.updatedSku] } const products = await this.store.dispatch("product/fetchProducts", payload); - if (products.length) { - const item = products[0]; - let unidentifiedItem; - if (this.type === 'order'){ - unidentifiedItem = this.purchaseOrders.unidentifiedItems.find((unidentifiedItem: any) => unidentifiedItem.shopifyProductSKU === this.unidentifiedProductSku); - unidentifiedItem.isNewProduct = "N"; - } else { - unidentifiedItem = this.stock.unidentifiedItems.find((unidentifiedItem: any) => unidentifiedItem.productSKU === this.unidentifiedProductSku); - } - unidentifiedItem.updatedSku = this.updatedSku; - unidentifiedItem.parentProductId = item.parent.id; - unidentifiedItem.pseudoId = item.pseudoId; - unidentifiedItem.parentProductName = item.parent.productName; - unidentifiedItem.imageUrl = item.images.mainImageUrl; - unidentifiedItem.isSelected = true; - - this.hasSkuUpdated = true; - if (this.type === 'order') this.store.dispatch('order/updatePurchaseOrders', this.purchaseOrders); - else this.store.dispatch('stock/updateStockItems', this.stock); - } else { + if (!products.length) { this.isSkuInvalid = true; + return; + } + const item = products[0]; + let unidentifiedItem; + const unidentifiedItems = this.type === 'order' ? this.purchaseOrders.unidentifiedItems : this.stock.unidentifiedItems; + + unidentifiedItem = unidentifiedItems.find((unidentifiedItem: any) => unidentifiedItem.shopifyProductSKU === this.unidentifiedProductSku); + + unidentifiedItem.updatedSku = this.updatedSku; + unidentifiedItem.parentProductId = item.parent.id; + unidentifiedItem.pseudoId = item.pseudoId; + unidentifiedItem.parentProductName = item.parent.productName; + unidentifiedItem.imageUrl = item.images.mainImageUrl; + unidentifiedItem.isSelected = true; + + this.hasSkuUpdated = true; + if (this.type === 'order'){ + unidentifiedItem.isProductNew = 'N'; + this.store.dispatch('order/updatePurchaseOrders', this.purchaseOrders); + } else { + this.store.dispatch('stock/updateStockItems', this.stock); } }, }, diff --git a/src/components/ProductPopover.vue b/src/components/ProductPopover.vue index 6749e3dd..0adc2db2 100644 --- a/src/components/ProductPopover.vue +++ b/src/components/ProductPopover.vue @@ -116,7 +116,7 @@ export default defineComponent({ this.stock.parsed = this.stock.parsed.map(element => { if(element.parentProductId === this.id) { const item = original.find(item => { - return item.parentProductId === this.id && item.productSKU === element.productSKU; + return item.parentProductId === this.id && item.shopifyProductSKU === element.shopifyProductSKU; }) element = item; } diff --git a/src/store/modules/stock/actions.ts b/src/store/modules/stock/actions.ts index d19ec9ad..c2d01a8a 100644 --- a/src/store/modules/stock/actions.ts +++ b/src/store/modules/stock/actions.ts @@ -6,7 +6,7 @@ import * as types from './mutation-types' const actions: ActionTree = { async updatedStockList ({commit, rootGetters}, items) { - const productIds = items.map((item: any) => item.productSKU) + const productIds = items.map((item: any) => item.shopifyProductSKU) const facilityIds = [...new Set(items.map((item: any) => item.externalFacilityId))] const viewSize = productIds.length; const viewIndex = 0; @@ -19,7 +19,7 @@ const actions: ActionTree = { await store.dispatch("product/fetchProducts", payload); const unidentifiedItems = [] as any; const parsed = items.map((item: any) => { - const product = rootGetters['product/getProduct'](item.productSKU) + const product = rootGetters['product/getProduct'](item.shopifyProductSKU) if(Object.keys(product).length > 0){ item.parentProductId = product?.parent?.id; diff --git a/src/views/Inventory.vue b/src/views/Inventory.vue index 89b51910..1f05a6f5 100644 --- a/src/views/Inventory.vue +++ b/src/views/Inventory.vue @@ -122,7 +122,7 @@ export default defineComponent({ this.productsList = this.content.map(item => { return { - productSKU: item[this.fieldMapping.productSku], + shopifyProductSKU: item[this.fieldMapping.productSku], quantity: item[this.fieldMapping.quantity], facilityId: '', externalFacilityId: item[this.fieldMapping.facility], diff --git a/src/views/InventoryDetail.vue b/src/views/InventoryDetail.vue index 35a1350d..d908ec1a 100644 --- a/src/views/InventoryDetail.vue +++ b/src/views/InventoryDetail.vue @@ -273,7 +273,7 @@ export default defineComponent({ return { "facilityId": item.facilityId, "externalFacilityId": item.externalFacilityId, - "idValue": item.productSKU, + "idValue": item.shopifyProductSKU, "idType": "SKU", "locationSeqId": item.locationSeqId, "availableQty": item.quantity From 7b6ce26f41cab7ccbbc7863fa51401f1bf878ccc Mon Sep 17 00:00:00 2001 From: Disha Talreja Date: Tue, 7 Feb 2023 13:40:40 +0530 Subject: [PATCH 33/50] Removed unwanted code and fixed searched prduts not updating on bulk adjustment and other operations(#31a0f22) --- src/store/modules/stock/mutation-types.ts | 3 +-- src/store/modules/stock/mutations.ts | 5 +--- src/views/InventoryDetail.vue | 29 ++++++++++------------- 3 files changed, 14 insertions(+), 23 deletions(-) diff --git a/src/store/modules/stock/mutation-types.ts b/src/store/modules/stock/mutation-types.ts index 4262343f..91e0c1a6 100644 --- a/src/store/modules/stock/mutation-types.ts +++ b/src/store/modules/stock/mutation-types.ts @@ -1,3 +1,2 @@ export const SN_STOCK = 'stock' -export const STOCK_ITEMS_UPDATED = SN_STOCK + '/LIST_UPDATED' -export const STOCK_LIST_ITEMS_UPDATED = SN_STOCK + '/LIST_ITEMS_UPDATED' \ No newline at end of file +export const STOCK_ITEMS_UPDATED = SN_STOCK + '/ITEMS_UPDATED' \ No newline at end of file diff --git a/src/store/modules/stock/mutations.ts b/src/store/modules/stock/mutations.ts index 1a77426d..637ed8f3 100644 --- a/src/store/modules/stock/mutations.ts +++ b/src/store/modules/stock/mutations.ts @@ -7,9 +7,6 @@ const mutations: MutationTree = { state.items.parsed = payload.parsed; state.items.original = payload.original; state.items.unidentifiedItems = payload.unidentifiedItems; - }, - [types.STOCK_LIST_ITEMS_UPDATED] (state, payload) { - state.items.parsed = payload; - }, + } } export default mutations; \ No newline at end of file diff --git a/src/views/InventoryDetail.vue b/src/views/InventoryDetail.vue index d908ec1a..1a0d1203 100644 --- a/src/views/InventoryDetail.vue +++ b/src/views/InventoryDetail.vue @@ -59,13 +59,13 @@ - {{ searchedProduct.externalFacilityId }} + {{ searchedProduct.externalFacilityId ? searchedProduct.externalFacilityId : searchedProduct.facilityId }} - + - {{ facilityLocation.locationSeqId }} + {{ facilityLocation.locationSeqId }} @@ -235,6 +235,9 @@ export default defineComponent({ component: MissingSkuModal, componentProps: { 'unidentifiedItems': this.stock.unidentifiedItems, type: 'stock' } }); + missingSkuModal.onDidDismiss().then(() => { + this.searchProduct(this.queryString); + }); return missingSkuModal.present(); }, getItemsWithMissingFacility() { @@ -247,6 +250,9 @@ export default defineComponent({ component: MissingFacilitiesModal, componentProps: { itemsWithMissingFacility, facilities: this.facilities, type: 'stock' } }); + missingFacilitiesModal.onDidDismiss().then(() => { + this.searchProduct(this.queryString); + }); return missingFacilitiesModal.present(); }, getSelectedItems(){ @@ -344,20 +350,6 @@ export default defineComponent({ this.stock.parsed = JSON.parse(JSON.stringify(this.stock.original)); this.store.dispatch('stock/updateStockItems', this.stock); }, - async apply() { - if(this.facilityId) { - const facilityLocations = await this.store.dispatch('user/fetchFacilityLocations', [this.facilityId]); - const locationSeqId = facilityLocations[this.facilityId] && facilityLocations[this.facilityId][0] && facilityLocations[this.facilityId][0].locaionSeqId ? facilityLocations[this.facilityId][0].locaionSeqId : ''; - this.stock.parsed.map((item: any) => { - if (item.isSelected) { - item.facilityId = this.facilityId; - item.locationSeqId = locationSeqId; - item.externalFacilityId = ""; - } - }) - } - await this.store.dispatch('stock/updateStockItems', this.stock); - }, getParentProductIds (items: any) { return Array.from(new Set(items.map((ele: any) => ele.parentProductId))); }, @@ -389,6 +381,9 @@ export default defineComponent({ const bulkInventoryAdjustmentModal = await modalController.create({ component: BulkInventoryAdjustmentModal, }); + bulkInventoryAdjustmentModal.onDidDismiss().then(() => { + this.searchProduct(this.queryString); + }); return bulkInventoryAdjustmentModal.present(); }, }, From 84cac9ad1a185e701f75c1c76fca2ccdd514f394 Mon Sep 17 00:00:00 2001 From: Disha Talreja Date: Tue, 7 Feb 2023 14:58:45 +0530 Subject: [PATCH 34/50] Updated component name(#31a0f22) --- src/router/index.ts | 6 +++--- src/views/{InventoryDetail.vue => InventoryReview.vue} | 0 2 files changed, 3 insertions(+), 3 deletions(-) rename src/views/{InventoryDetail.vue => InventoryReview.vue} (100%) diff --git a/src/router/index.ts b/src/router/index.ts index c1c6b090..24378afa 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -2,7 +2,7 @@ import { createRouter, createWebHistory } from '@ionic/vue-router'; import { RouteRecordRaw } from 'vue-router'; import PurchaseOrder from '@/views/PurchaseOrder.vue' import Inventory from '@/views/Inventory.vue' -import InventoryDetail from '@/views/InventoryDetail.vue' +import InventoryReview from '@/views/InventoryReview.vue' import PurchaseOrderReview from '@/views/PurchaseOrderReview.vue'; import Login from '@/views/Login.vue' import SavedMappings from '@/views/SavedMappings.vue' @@ -50,9 +50,9 @@ const routes: Array = [ beforeEnter: authGuard }, { - path: '/inventory-detail', + path: '/inventory-review', name: 'InventoryDetail', - component: InventoryDetail, + component: InventoryReview, beforeEnter: authGuard }, { diff --git a/src/views/InventoryDetail.vue b/src/views/InventoryReview.vue similarity index 100% rename from src/views/InventoryDetail.vue rename to src/views/InventoryReview.vue From 74c41662b2a47ae21f8eabdcabb3f6652fd52322 Mon Sep 17 00:00:00 2001 From: Disha Talreja Date: Tue, 7 Feb 2023 16:22:21 +0530 Subject: [PATCH 35/50] fix: searched product not updated on revert all(#31a0f22) --- src/views/InventoryReview.vue | 1 + 1 file changed, 1 insertion(+) diff --git a/src/views/InventoryReview.vue b/src/views/InventoryReview.vue index 1a0d1203..7043bc42 100644 --- a/src/views/InventoryReview.vue +++ b/src/views/InventoryReview.vue @@ -349,6 +349,7 @@ export default defineComponent({ revertAll() { this.stock.parsed = JSON.parse(JSON.stringify(this.stock.original)); this.store.dispatch('stock/updateStockItems', this.stock); + if(this.queryString) this.searchProduct(this.queryString); }, getParentProductIds (items: any) { return Array.from(new Set(items.map((ele: any) => ele.parentProductId))); From 8d7f47086fd519df67e96b1bf72c0f1fe4d0a581 Mon Sep 17 00:00:00 2001 From: Disha Talreja Date: Wed, 8 Feb 2023 10:57:50 +0530 Subject: [PATCH 36/50] fix: indentation and variable name(#31a0f22) --- src/mixins/parseFileMixin.ts | 12 ++++++------ src/store/modules/stock/actions.ts | 2 +- src/views/PurchaseOrder.vue | 6 +++--- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/mixins/parseFileMixin.ts b/src/mixins/parseFileMixin.ts index 77c95c7d..35203558 100644 --- a/src/mixins/parseFileMixin.ts +++ b/src/mixins/parseFileMixin.ts @@ -6,12 +6,12 @@ export default { methods: { async parseCsv(file: any) { if (file) { - showToast(translate("File uploaded successfully")); - store.dispatch('order/updateFileName', file.name); - - const csvData = await parseCsv(file).then( res => { - return res; - }) + showToast(translate("File uploaded successfully")); + store.dispatch('order/updateFileName', file.name); + + const csvData = await parseCsv(file).then( res => { + return res; + }) return csvData; } showToast(translate("Something went wrong, Please try again")); diff --git a/src/store/modules/stock/actions.ts b/src/store/modules/stock/actions.ts index c2d01a8a..c2401bd9 100644 --- a/src/store/modules/stock/actions.ts +++ b/src/store/modules/stock/actions.ts @@ -30,7 +30,7 @@ const actions: ActionTree = { return item; } unidentifiedItems.push(item); - return ; + return; }).filter((item: any) => item); const original = JSON.parse(JSON.stringify(items)) diff --git a/src/views/PurchaseOrder.vue b/src/views/PurchaseOrder.vue index 182e0063..d984d1bc 100644 --- a/src/views/PurchaseOrder.vue +++ b/src/views/PurchaseOrder.vue @@ -125,7 +125,7 @@ export default defineComponent({ quantity: "", facility: "", }, - PurchaseOrderItems: [], + purchaseOrderItems: [], } }, methods: { @@ -149,7 +149,7 @@ export default defineComponent({ return; } - this.PurchaseOrderItems = this.content.map(item => { + this.purchaseOrderItems = this.content.map(item => { return { orderId: item[this.fieldMapping.orderId], shopifyProductSKU: item[this.fieldMapping.productSku], @@ -159,7 +159,7 @@ export default defineComponent({ externalFacilityId: item[this.fieldMapping.facility] } }) - this.store.dispatch('order/fetchOrderDetails', this.PurchaseOrderItems); + this.store.dispatch('order/fetchOrderDetails', this.purchaseOrderItems); this.router.push({ name:'PurchaseOrderReview' }) From 09612427e58d1550ac7281501619753b7cf3b9f2 Mon Sep 17 00:00:00 2001 From: Disha Talreja Date: Wed, 8 Feb 2023 12:04:05 +0530 Subject: [PATCH 37/50] fix: revert all not working as expected(#31a0f22) --- src/store/modules/stock/actions.ts | 7 +++++-- src/views/InventoryReview.vue | 1 + 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/store/modules/stock/actions.ts b/src/store/modules/stock/actions.ts index c2401bd9..4768df07 100644 --- a/src/store/modules/stock/actions.ts +++ b/src/store/modules/stock/actions.ts @@ -32,7 +32,8 @@ const actions: ActionTree = { unidentifiedItems.push(item); return; }).filter((item: any) => item); - const original = JSON.parse(JSON.stringify(items)) + + const original = JSON.parse(JSON.stringify(parsed)); commit(types.STOCK_ITEMS_UPDATED, { parsed, original, unidentifiedItems }); }, @@ -48,11 +49,13 @@ const actions: ActionTree = { if(item.updatedSku) { item.shopifyProductSKU = item.updatedSku; parsed.push(item); + state.items.original.push(item); } else { return item; } }).filter((item: any) => item); - const original = JSON.parse(JSON.stringify(state.items.parsed)); + + const original = JSON.parse(JSON.stringify(state.items.original)); commit(types.STOCK_ITEMS_UPDATED, { parsed, original, unidentifiedItems}); } diff --git a/src/views/InventoryReview.vue b/src/views/InventoryReview.vue index 7043bc42..d038cda6 100644 --- a/src/views/InventoryReview.vue +++ b/src/views/InventoryReview.vue @@ -348,6 +348,7 @@ export default defineComponent({ }, revertAll() { this.stock.parsed = JSON.parse(JSON.stringify(this.stock.original)); + this.store.dispatch('stock/updateStockItems', this.stock); if(this.queryString) this.searchProduct(this.queryString); }, From 22c6c2b0d6b3bcf85a1fa1c1ce20ffd85e74d2ba Mon Sep 17 00:00:00 2001 From: Disha Talreja Date: Wed, 8 Feb 2023 17:22:49 +0530 Subject: [PATCH 38/50] Improved variable name(#31a0f22) --- .../BulkInventoryAdjustmentModal.vue | 13 +++--- src/components/MissingFacilitiesModal.vue | 6 +-- src/components/MissingSkuModal.vue | 14 +++--- src/components/ProductPopover.vue | 22 +++++----- src/views/InventoryReview.vue | 44 +++++++++---------- 5 files changed, 49 insertions(+), 50 deletions(-) diff --git a/src/components/BulkInventoryAdjustmentModal.vue b/src/components/BulkInventoryAdjustmentModal.vue index 63106ef1..c0d8d044 100644 --- a/src/components/BulkInventoryAdjustmentModal.vue +++ b/src/components/BulkInventoryAdjustmentModal.vue @@ -13,7 +13,7 @@ {{ $t("Buffer quantity") }} - + @@ -74,13 +74,13 @@ export default defineComponent({ }, data() { return { - quantityBuffer: "", + quantityBuffer: 0, facilityId: "", } }, computed: { ...mapGetters({ - stock: 'stock/getItemsStock', + stockItems: 'stock/getItemsStock', facilities: 'util/getFacilities', }) }, @@ -91,10 +91,9 @@ export default defineComponent({ async save() { const facilityLocations = await this.store.dispatch('user/fetchFacilityLocations', [this.facilityId]); const locationSeqId = facilityLocations[this.facilityId] && facilityLocations[this.facilityId][0] ? facilityLocations[this.facilityId][0].locationSeqId : ''; - await this.stock.parsed.map((item: any) => { + await this.stockItems.parsed.map((item: any) => { if (item.isSelected) { - if(this.quantityBuffer != '') - item.quantity = this.quantityBuffer; + item.quantity -= this.quantityBuffer; if(this.facilityId) { item.facilityId = this.facilityId; item.externalFacilityId = ""; @@ -102,7 +101,7 @@ export default defineComponent({ } } }) - await this.store.dispatch('stock/updateStockItems', this.stock) + await this.store.dispatch('stock/updateStockItems', this.stockItems) this.closeModal(); showToast(translate("Changes have been successfully applied")); }, diff --git a/src/components/MissingFacilitiesModal.vue b/src/components/MissingFacilitiesModal.vue index a966f5f2..27fcf704 100644 --- a/src/components/MissingFacilitiesModal.vue +++ b/src/components/MissingFacilitiesModal.vue @@ -80,7 +80,7 @@ export default defineComponent({ computed: { ...mapGetters({ purchaseOrders: 'order/getPurchaseOrders', - stock: 'stock/getItemsStock', + stockItems: 'stock/getItemsStock', }) }, mounted(){ @@ -102,7 +102,7 @@ export default defineComponent({ const facilityLocations = await this.store.dispatch('user/fetchFacilityLocations', Object.values(this.facilityMapping)); Object.keys(this.facilityMapping).map((facilityId: any) => { const locationSeqId = facilityLocations[this.facilityMapping[facilityId]].length ? facilityLocations[this.facilityMapping[facilityId]][0].locationSeqId : ''; - this.stock.parsed.map((item: any) => { + this.stockItems.parsed.map((item: any) => { if(item.externalFacilityId === facilityId){ item.externalFacilityId = ""; item.facilityId = this.facilityMapping[facilityId]; @@ -110,7 +110,7 @@ export default defineComponent({ } }) }) - this.store.dispatch('stock/updateStockItems', this.stock); + this.store.dispatch('stock/updateStockItems', this.stockItems); } this.closeModal(); diff --git a/src/components/MissingSkuModal.vue b/src/components/MissingSkuModal.vue index e612db0e..beb43f7c 100644 --- a/src/components/MissingSkuModal.vue +++ b/src/components/MissingSkuModal.vue @@ -14,7 +14,7 @@
- {{ $t("The SKU is successfully changed") }} + {{ $t("The SKU is successfully changed") }} {{ $t("This SKU is not available, please try again") }} {{ $t("Update") }} @@ -122,7 +122,7 @@ export default defineComponent({ computed: { ...mapGetters({ purchaseOrders: 'order/getPurchaseOrders', - stock: 'stock/getItemsStock', + stockItems: 'stock/getItemsStock', }) }, props: ['type'], @@ -137,15 +137,15 @@ export default defineComponent({ }, getPendingItems(){ if(this.type === 'order') return this.purchaseOrders.unidentifiedItems.filter((item: any) => !item.updatedSku); - return this.stock.unidentifiedItems.filter((item: any) => !item.updatedSku); + return this.stockItems.unidentifiedItems.filter((item: any) => !item.updatedSku); }, getCompletedItems(){ if(this.type === 'order') return this.purchaseOrders.unidentifiedItems.filter((item: any) => item.updatedSku); - return this.stock.unidentifiedItems.filter((item: any) => item.updatedSku); + return this.stockItems.unidentifiedItems.filter((item: any) => item.updatedSku); }, save(){ if(this.type === 'order') this.store.dispatch('order/updateUnidentifiedItem', { unidentifiedItems: this.purchaseOrders.unidentifiedItems }); - else this.store.dispatch('stock/updateUnidentifiedItem', { unidentifiedItems: this.stock.unidentifiedItems }); + else this.store.dispatch('stock/updateUnidentifiedItem', { unidentifiedItems: this.stockItems.unidentifiedItems }); this.closeModal(); }, async update() { @@ -163,7 +163,7 @@ export default defineComponent({ } const item = products[0]; let unidentifiedItem; - const unidentifiedItems = this.type === 'order' ? this.purchaseOrders.unidentifiedItems : this.stock.unidentifiedItems; + const unidentifiedItems = this.type === 'order' ? this.purchaseOrders.unidentifiedItems : this.stockItems.unidentifiedItems; unidentifiedItem = unidentifiedItems.find((unidentifiedItem: any) => unidentifiedItem.shopifyProductSKU === this.unidentifiedProductSku); @@ -179,7 +179,7 @@ export default defineComponent({ unidentifiedItem.isProductNew = 'N'; this.store.dispatch('order/updatePurchaseOrders', this.purchaseOrders); } else { - this.store.dispatch('stock/updateStockItems', this.stock); + this.store.dispatch('stock/updateStockItems', this.stockItems); } }, }, diff --git a/src/components/ProductPopover.vue b/src/components/ProductPopover.vue index 0adc2db2..e0d97cae 100644 --- a/src/components/ProductPopover.vue +++ b/src/components/ProductPopover.vue @@ -28,7 +28,7 @@ export default defineComponent({ components: { IonContent, IonIcon, IonLabel, IonItem }, computed: { ...mapGetters({ - stock: 'stock/getItemsStock', + stockItems: 'stock/getItemsStock', purchaseOrders: 'order/getPurchaseOrders', }), }, @@ -46,10 +46,10 @@ export default defineComponent({ }); this.store.dispatch('order/updatePurchaseOrders', this.purchaseOrders) } else { - this.stock.parsed.map(item => { + this.stockItems.parsed.map(item => { item.isSelected = item.parentProductId === this.id; }) - this.store.dispatch('stock/updateStockItems', this.stock) + this.store.dispatch('stock/updateStockItems', this.stockItems) } popoverController.dismiss({ dismissed: true }); }, @@ -60,10 +60,10 @@ export default defineComponent({ }); this.store.dispatch('order/updatePurchaseOrders', this.purchaseOrders) } else { - this.stock.parsed.map(item => { + this.stockItems.parsed.map(item => { item.isSelected = item.pseudoId === this.id; }); - this.store.dispatch('stock/updateStockItems', this.stock) + this.store.dispatch('stock/updateStockItems', this.stockItems) } popoverController.dismiss({ dismissed: true }); @@ -82,8 +82,8 @@ export default defineComponent({ }); this.store.dispatch('order/updatePurchaseOrders', this.purchaseOrders) } else { - const original = JSON.parse(JSON.stringify(this.stock.original)); - this.stock.parsed = this.stock.parsed.map(element => { + const original = JSON.parse(JSON.stringify(this.stockItems.original)); + this.stockItems.parsed = this.stockItems.parsed.map(element => { if(element.pseudoId === this.id) { const item = original.find(item => { return item.pseudoId === this.id; @@ -92,7 +92,7 @@ export default defineComponent({ } return element; }); - this.store.dispatch('stock/updateStockItems', this.stock) + this.store.dispatch('stock/updateStockItems', this.stockItems) } popoverController.dismiss({ dismissed: true }); @@ -112,8 +112,8 @@ export default defineComponent({ }); this.store.dispatch('order/updatePurchaseOrders', this.purchaseOrders) } else { - const original = JSON.parse(JSON.stringify(this.stock.original)); - this.stock.parsed = this.stock.parsed.map(element => { + const original = JSON.parse(JSON.stringify(this.stockItems.original)); + this.stockItems.parsed = this.stockItems.parsed.map(element => { if(element.parentProductId === this.id) { const item = original.find(item => { return item.parentProductId === this.id && item.shopifyProductSKU === element.shopifyProductSKU; @@ -122,7 +122,7 @@ export default defineComponent({ } return element; }); - this.store.dispatch('stock/updateStockItems', this.stock); + this.store.dispatch('stock/updateStockItems', this.stockItems); } popoverController.dismiss({ dismissed: true }); } diff --git a/src/views/InventoryReview.vue b/src/views/InventoryReview.vue index d038cda6..2dde0ebc 100644 --- a/src/views/InventoryReview.vue +++ b/src/views/InventoryReview.vue @@ -38,7 +38,7 @@ {{ $t("Missing products") }} - {{ stock.unidentifiedItems.length }} {{ $t("items") }} + {{ stockItems.unidentifiedItems.length }} {{ $t("items") }}
@@ -77,10 +77,10 @@
-
+
- {{ getParentInformation(id, stock.parsed).parentProductName }} + {{ getParentInformation(id, stockItems.parsed).parentProductName }}
@@ -91,11 +91,11 @@ - +
-
+
@@ -179,7 +179,7 @@ export default defineComponent({ }, computed: { ...mapGetters({ - stock: 'stock/getItemsStock', + stockItems: 'stock/getItemsStock', getProduct: 'product/getProduct', instanceUrl: 'user/getInstanceUrl', facilities: 'util/getFacilities', @@ -189,7 +189,7 @@ export default defineComponent({ }, data() { return { - facilityId: (this as any)?.stock?.parsed[0]?.facilityId, + facilityId: (this as any)?.stockItems?.parsed[0]?.facilityId, queryString: "", searchedProduct: {} as any, isParentProductUpdated: false, @@ -233,7 +233,7 @@ export default defineComponent({ async openMissingSkuModal() { const missingSkuModal = await modalController.create({ component: MissingSkuModal, - componentProps: { 'unidentifiedItems': this.stock.unidentifiedItems, type: 'stock' } + componentProps: { 'unidentifiedItems': this.stockItems.unidentifiedItems, type: 'stock' } }); missingSkuModal.onDidDismiss().then(() => { this.searchProduct(this.queryString); @@ -242,7 +242,7 @@ export default defineComponent({ }, getItemsWithMissingFacility() { const facilityIds = this.facilities.map((facility: any) => facility.facilityId) - return this.stock.parsed.filter((item: any) => !facilityIds.includes(item.externalFacilityId) && item.externalFacilityId !== ""); + return this.stockItems.parsed.filter((item: any) => !facilityIds.includes(item.externalFacilityId) && item.externalFacilityId !== ""); }, async openMissingFacilitiesModal() { const itemsWithMissingFacility = this.getItemsWithMissingFacility(); @@ -256,24 +256,24 @@ export default defineComponent({ return missingFacilitiesModal.present(); }, getSelectedItems(){ - return Object.values(this.stock.parsed).filter((item: any) => item.isSelected).length; + return Object.values(this.stockItems.parsed).filter((item: any) => item.isSelected).length; }, setFacilityLocation(ev: CustomEvent, product: any){ - this.stock.parsed.map((item: any) => { + this.stockItems.parsed.map((item: any) => { if(item.pseudoId === product.pseudoId){ item.locationSeqId = ev.detail.value; } }); - this.store.dispatch('stock/updateStockItems', this.stock); + this.store.dispatch('stock/updateStockItems', this.stockItems); }, searchProduct(sku: any) { const product = this.getProduct(sku); - this.searchedProduct = this.stock.parsed.find((item: any) => { + this.searchedProduct = this.stockItems.parsed.find((item: any) => { return item.pseudoId === product.pseudoId; }) }, async save(){ - const uploadData = this.stock.parsed.filter((item: any) => { + const uploadData = this.stockItems.parsed.filter((item: any) => { return item.isSelected; }).map((item: any) => { return { @@ -339,17 +339,17 @@ export default defineComponent({ return productPopover.present(); }, isParentProductChecked(parentProductId: string) { - const items = this.getItemsByParentProduct(parentProductId, this.stock.parsed); + const items = this.getItemsByParentProduct(parentProductId, this.stockItems.parsed); return items.every((item: any) => item.isSelected) }, selectProduct(item: any, event: any) { item.isSelected = event.detail.checked; - this.store.dispatch('stock/updateStockItems', this.stock) + this.store.dispatch('stock/updateStockItems', this.stockItems) }, revertAll() { - this.stock.parsed = JSON.parse(JSON.stringify(this.stock.original)); + this.stockItems.parsed = JSON.parse(JSON.stringify(this.stockItems.original)); - this.store.dispatch('stock/updateStockItems', this.stock); + this.store.dispatch('stock/updateStockItems', this.stockItems); if(this.queryString) this.searchProduct(this.queryString); }, getParentProductIds (items: any) { @@ -362,22 +362,22 @@ export default defineComponent({ return items.find((item: any) => item.parentProductId == id) }, selectAllItems() { - this.stock.parsed.forEach((item: any) => { + this.stockItems.parsed.forEach((item: any) => { item.isSelected = true; }) - this.store.dispatch('stock/updateStockItems', this.stock) + this.store.dispatch('stock/updateStockItems', this.stockItems) }, selectParentProduct(parentProductId: any, event: any) { // Todo: Need to find a better approach. if(this.isParentProductUpdated){ - this.stock.parsed.forEach((item: any) => { + this.stockItems.parsed.forEach((item: any) => { if (item.parentProductId === parentProductId) { item.isSelected = event.detail.checked; } }) this.isParentProductUpdated = false; } - this.store.dispatch('stock/updateStockItems', this.stock); + this.store.dispatch('stock/updateStockItems', this.stockItems); }, async openBulkInventoryAdjustmentModal() { const bulkInventoryAdjustmentModal = await modalController.create({ From 24ceb7086ed0a2570f0b1a6f575e7d375e9ae0d2 Mon Sep 17 00:00:00 2001 From: Disha Talreja Date: Wed, 8 Feb 2023 17:42:51 +0530 Subject: [PATCH 39/50] refactor: moved logic to map missing facilities in actions(#31a0f22) --- src/components/MissingFacilitiesModal.vue | 23 ++--------------------- src/store/modules/order/actions.ts | 11 +++++++++++ src/store/modules/stock/actions.ts | 14 ++++++++++++++ 3 files changed, 27 insertions(+), 21 deletions(-) diff --git a/src/components/MissingFacilitiesModal.vue b/src/components/MissingFacilitiesModal.vue index 27fcf704..757f6c46 100644 --- a/src/components/MissingFacilitiesModal.vue +++ b/src/components/MissingFacilitiesModal.vue @@ -89,28 +89,9 @@ export default defineComponent({ methods: { async save(){ if(this.type === 'order'){ - Object.keys(this.facilityMapping).map((facilityId: any) => { - Object.values(this.purchaseOrders.parsed).flat().map((item: any) => { - if(item.externalFacilityId === facilityId){ - item.externalFacilityId = ""; - item.facilityId = this.facilityMapping[facilityId]; - } - }) - }) - this.store.dispatch('order/updatePurchaseOrders', this.purchaseOrders); + this.store.dispatch('order/updateMissingFacilities', this.facilityMapping) } else { - const facilityLocations = await this.store.dispatch('user/fetchFacilityLocations', Object.values(this.facilityMapping)); - Object.keys(this.facilityMapping).map((facilityId: any) => { - const locationSeqId = facilityLocations[this.facilityMapping[facilityId]].length ? facilityLocations[this.facilityMapping[facilityId]][0].locationSeqId : ''; - this.stockItems.parsed.map((item: any) => { - if(item.externalFacilityId === facilityId){ - item.externalFacilityId = ""; - item.facilityId = this.facilityMapping[facilityId]; - item.locationSeqId = locationSeqId; - } - }) - }) - this.store.dispatch('stock/updateStockItems', this.stockItems); + this.store.dispatch('stock/updateMissingFacilities', this.facilityMapping) } this.closeModal(); diff --git a/src/store/modules/order/actions.ts b/src/store/modules/order/actions.ts index 9cc57ebb..84c976b9 100644 --- a/src/store/modules/order/actions.ts +++ b/src/store/modules/order/actions.ts @@ -64,6 +64,17 @@ const actions: ActionTree = { const original = JSON.parse(JSON.stringify(state.purchaseOrders.parsed)); commit(types.ORDER_PURCHASEORDERS_UPDATED, { parsed, original, unidentifiedItems}); + }, + updateMissingFacilities({state, dispatch}, facilityMapping){ + Object.keys(facilityMapping).map((facilityId: any) => { + Object.values(state.purchaseOrders.parsed).flat().map((item: any) => { + if(item.externalFacilityId === facilityId){ + item.externalFacilityId = ""; + item.facilityId = facilityMapping[facilityId]; + } + }) + }) + this.dispatch('order/updatePurchaseOrders', state.purchaseOrders); } } export default actions; diff --git a/src/store/modules/stock/actions.ts b/src/store/modules/stock/actions.ts index 4768df07..8bda9ab7 100644 --- a/src/store/modules/stock/actions.ts +++ b/src/store/modules/stock/actions.ts @@ -58,6 +58,20 @@ const actions: ActionTree = { const original = JSON.parse(JSON.stringify(state.items.original)); commit(types.STOCK_ITEMS_UPDATED, { parsed, original, unidentifiedItems}); + }, + async updateMissingFacilities({ state }, facilityMapping){ + const facilityLocations = await this.dispatch('user/fetchFacilityLocations', Object.values(facilityMapping)); + Object.keys(facilityMapping).map((facilityId: any) => { + const locationSeqId = facilityLocations[facilityMapping[facilityId]].length ? facilityLocations[facilityMapping[facilityId]][0].locationSeqId : ''; + state.items.parsed.map((item: any) => { + if(item.externalFacilityId === facilityId){ + item.externalFacilityId = ""; + item.facilityId = facilityMapping[facilityId]; + item.locationSeqId = locationSeqId; + } + }) + }) + this.dispatch('stock/updateStockItems', state.items); } } export default actions; From 63486281e1246057a268cb3980cdf377bba54fd3 Mon Sep 17 00:00:00 2001 From: Disha Talreja Date: Wed, 8 Feb 2023 18:19:02 +0530 Subject: [PATCH 40/50] refactor: used separate methods(#31a0f22) --- src/components/MissingSkuModal.vue | 30 +++--- src/components/ProductPopover.vue | 160 +++++++++++++++-------------- 2 files changed, 99 insertions(+), 91 deletions(-) diff --git a/src/components/MissingSkuModal.vue b/src/components/MissingSkuModal.vue index beb43f7c..f867a723 100644 --- a/src/components/MissingSkuModal.vue +++ b/src/components/MissingSkuModal.vue @@ -116,7 +116,8 @@ export default defineComponent({ updatedSku: '', unidentifiedProductSku: '', hasSkuUpdated: false, - isSkuInvalid: false + isSkuInvalid: false, + unidentifiedItems: [] as any } }, computed: { @@ -125,6 +126,9 @@ export default defineComponent({ stockItems: 'stock/getItemsStock', }) }, + mounted() { + this.unidentifiedItems = this.type ==='order' ? this.purchaseOrders.unidentifiedItems : this.stockItems.unidentifiedItems; + }, props: ['type'], methods: { selectInputText(event: any) { @@ -136,14 +140,12 @@ export default defineComponent({ modalController.dismiss({ dismissed: true }); }, getPendingItems(){ - if(this.type === 'order') return this.purchaseOrders.unidentifiedItems.filter((item: any) => !item.updatedSku); - return this.stockItems.unidentifiedItems.filter((item: any) => !item.updatedSku); + return this.unidentifiedItems.filter((item: any) => !item.updatedSku); }, getCompletedItems(){ - if(this.type === 'order') return this.purchaseOrders.unidentifiedItems.filter((item: any) => item.updatedSku); - return this.stockItems.unidentifiedItems.filter((item: any) => item.updatedSku); + return this.unidentifiedItems.filter((item: any) => item.updatedSku); }, - save(){ + save() { if(this.type === 'order') this.store.dispatch('order/updateUnidentifiedItem', { unidentifiedItems: this.purchaseOrders.unidentifiedItems }); else this.store.dispatch('stock/updateUnidentifiedItem', { unidentifiedItems: this.stockItems.unidentifiedItems }); this.closeModal(); @@ -161,22 +163,20 @@ export default defineComponent({ this.isSkuInvalid = true; return; } - const item = products[0]; - let unidentifiedItem; - const unidentifiedItems = this.type === 'order' ? this.purchaseOrders.unidentifiedItems : this.stockItems.unidentifiedItems; + const product = products[0]; - unidentifiedItem = unidentifiedItems.find((unidentifiedItem: any) => unidentifiedItem.shopifyProductSKU === this.unidentifiedProductSku); + const unidentifiedItem = this.unidentifiedItems.find((unidentifiedItem: any) => unidentifiedItem.shopifyProductSKU === this.unidentifiedProductSku); unidentifiedItem.updatedSku = this.updatedSku; - unidentifiedItem.parentProductId = item.parent.id; - unidentifiedItem.pseudoId = item.pseudoId; - unidentifiedItem.parentProductName = item.parent.productName; - unidentifiedItem.imageUrl = item.images.mainImageUrl; + unidentifiedItem.parentProductId = product.parent.id; + unidentifiedItem.pseudoId = product.pseudoId; + unidentifiedItem.parentProductName = product.parent.productName; + unidentifiedItem.imageUrl = product.images.mainImageUrl; unidentifiedItem.isSelected = true; this.hasSkuUpdated = true; if (this.type === 'order'){ - unidentifiedItem.isProductNew = 'N'; + unidentifiedItem.isNewProduct = 'N'; this.store.dispatch('order/updatePurchaseOrders', this.purchaseOrders); } else { this.store.dispatch('stock/updateStockItems', this.stockItems); diff --git a/src/components/ProductPopover.vue b/src/components/ProductPopover.vue index e0d97cae..55a4826e 100644 --- a/src/components/ProductPopover.vue +++ b/src/components/ProductPopover.vue @@ -39,91 +39,99 @@ export default defineComponent({ onlySelect() { this.isVirtual ? this.onlySelectParentProduct() : this.onlySelectSingleProduct(); }, + onlySelectParentProductForOrder() { + Object.values(this.purchaseOrders.parsed).flat().map(item => { + item.isSelected = item.parentProductId === this.id && item.orderId === this.poId; + }); + this.store.dispatch('order/updatePurchaseOrders', this.purchaseOrders) + }, + onlySelectParentProductForStock() { + this.stockItems.parsed.map(item => { + item.isSelected = item.parentProductId === this.id; + }) + this.store.dispatch('stock/updateStockItems', this.stockItems) + }, onlySelectParentProduct() { - if(this.type === 'order') { - Object.values(this.purchaseOrders.parsed).flat().map(item => { - item.isSelected = item.parentProductId === this.id && item.orderId === this.poId; - }); - this.store.dispatch('order/updatePurchaseOrders', this.purchaseOrders) - } else { - this.stockItems.parsed.map(item => { - item.isSelected = item.parentProductId === this.id; - }) - this.store.dispatch('stock/updateStockItems', this.stockItems) - } + this.type === 'order' ? this.onlySelectParentProductForOrder() : this.onlySelectParentProductForStock(); popoverController.dismiss({ dismissed: true }); }, + onlySelectSingleProductForOrder() { + Object.values(this.purchaseOrders.parsed).flat().map(item => { + item.isSelected = item.pseudoId === this.id && item.orderId === this.poId; + }); + this.store.dispatch('order/updatePurchaseOrders', this.purchaseOrders) + }, + onlySelectSingleProductForStock() { + this.stockItems.parsed.map(item => { + item.isSelected = item.pseudoId === this.id; + }); + this.store.dispatch('stock/updateStockItems', this.stockItems) + }, onlySelectSingleProduct() { - if(this.type === 'order') { - Object.values(this.purchaseOrders.parsed).flat().map(item => { - item.isSelected = item.pseudoId === this.id && item.orderId === this.poId; - }); - this.store.dispatch('order/updatePurchaseOrders', this.purchaseOrders) - } else { - this.stockItems.parsed.map(item => { - item.isSelected = item.pseudoId === this.id; - }); - this.store.dispatch('stock/updateStockItems', this.stockItems) - } - + this.type === 'order' ? this.onlySelectSingleProductForOrder() : this.onlySelectSingleProductForStock(); popoverController.dismiss({ dismissed: true }); }, + revertProductForOrder() { + const original = JSON.parse(JSON.stringify(this.getPurchaseOrders.original)); + this.purchaseOrders.parsed[this.poId] = this.purchaseOrders.parsed[this.poId].map(element => { + if(element.pseudoId === this.id) { + const item = original[this.poId].find(item => { + return item.pseudoId === this.id; + }) + element = item; + } + return element; + }); + this.store.dispatch('order/updatePurchaseOrders', this.purchaseOrders) + }, + revertProductForStock() { + const original = JSON.parse(JSON.stringify(this.stockItems.original)); + this.stockItems.parsed = this.stockItems.parsed.map(element => { + if(element.pseudoId === this.id) { + const item = original.find(item => { + return item.pseudoId === this.id; + }) + element = item; + } + return element; + }); + this.store.dispatch('stock/updateStockItems', this.stockItems) + }, revertProduct() { - if(this.type === 'order') { - const original = JSON.parse(JSON.stringify(this.getPurchaseOrders.original)); - this.purchaseOrders.parsed[this.poId] = this.purchaseOrders.parsed[this.poId].map(element => { - if(element.pseudoId === this.id) { - const item = original[this.poId].find(item => { - return item.pseudoId === this.id; - }) - element = item; - } - return element; - }); - this.store.dispatch('order/updatePurchaseOrders', this.purchaseOrders) - } else { - const original = JSON.parse(JSON.stringify(this.stockItems.original)); - this.stockItems.parsed = this.stockItems.parsed.map(element => { - if(element.pseudoId === this.id) { - const item = original.find(item => { - return item.pseudoId === this.id; - }) - element = item; - } - return element; - }); - this.store.dispatch('stock/updateStockItems', this.stockItems) - } - + this.type === 'order' ? this.revertProductForOrder() : this.revertProductForStock(); popoverController.dismiss({ dismissed: true }); }, - revertParentProduct(){ - if(this.type === 'order') { - const original = JSON.parse(JSON.stringify(this.purchaseOrders.original)); - this.purchaseOrders.parsed[this.poId] = this.purchaseOrders.parsed[this.poId].map(element => { - if(element.parentProductId === this.id) { - const item = original[this.poId].find(item => { + revertParentProductForOrder(){ + const original = JSON.parse(JSON.stringify(this.purchaseOrders.original)); + this.purchaseOrders.parsed[this.poId] = this.purchaseOrders.parsed[this.poId].map(element => { + if(element.parentProductId === this.id) { + const item = original[this.poId].find(item => { + // shopifyProductSKU check prevents reverting all the items of parent product to the first one as all the products have same parent product Id. // shopifyProductSKU check prevents reverting all the items of parent product to the first one as all the products have same parent product Id. - return item.parentProductId === this.id && item.shopifyProductSKU === element.shopifyProductSKU; - }) - element = item; - } - return element; - }); - this.store.dispatch('order/updatePurchaseOrders', this.purchaseOrders) - } else { - const original = JSON.parse(JSON.stringify(this.stockItems.original)); - this.stockItems.parsed = this.stockItems.parsed.map(element => { - if(element.parentProductId === this.id) { - const item = original.find(item => { - return item.parentProductId === this.id && item.shopifyProductSKU === element.shopifyProductSKU; - }) - element = item; - } - return element; - }); - this.store.dispatch('stock/updateStockItems', this.stockItems); - } + // shopifyProductSKU check prevents reverting all the items of parent product to the first one as all the products have same parent product Id. + return item.parentProductId === this.id && item.shopifyProductSKU === element.shopifyProductSKU; + }) + element = item; + } + return element; + }); + this.store.dispatch('order/updatePurchaseOrders', this.purchaseOrders) + }, + revertParentProductForStock(){ + const original = JSON.parse(JSON.stringify(this.stockItems.original)); + this.stockItems.parsed = this.stockItems.parsed.map(element => { + if(element.parentProductId === this.id) { + const item = original.find(item => { + return item.parentProductId === this.id && item.shopifyProductSKU === element.shopifyProductSKU; + }) + element = item; + } + return element; + }); + this.store.dispatch('stock/updateStockItems', this.stockItems); + }, + revertParentProduct(){ + this.type === 'order' ? this.revertParentProductForOrder() : this.revertParentProductForStock(); popoverController.dismiss({ dismissed: true }); } }, @@ -135,5 +143,5 @@ export default defineComponent({ store } } -}); +}) \ No newline at end of file From 394aaf79b630cea4601d149db871fe6c1d9a1646 Mon Sep 17 00:00:00 2001 From: Disha Talreja Date: Wed, 8 Feb 2023 18:36:14 +0530 Subject: [PATCH 41/50] fix: revert on PO review page not working(#31a0f22) --- src/components/ProductPopover.vue | 2 +- src/components/PurchaseOrderDetail.vue | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/ProductPopover.vue b/src/components/ProductPopover.vue index 55a4826e..1cb2fb36 100644 --- a/src/components/ProductPopover.vue +++ b/src/components/ProductPopover.vue @@ -72,7 +72,7 @@ export default defineComponent({ popoverController.dismiss({ dismissed: true }); }, revertProductForOrder() { - const original = JSON.parse(JSON.stringify(this.getPurchaseOrders.original)); + const original = JSON.parse(JSON.stringify(this.purchaseOrders.original)); this.purchaseOrders.parsed[this.poId] = this.purchaseOrders.parsed[this.poId].map(element => { if(element.pseudoId === this.id) { const item = original[this.poId].find(item => { diff --git a/src/components/PurchaseOrderDetail.vue b/src/components/PurchaseOrderDetail.vue index f6089d81..f5a0babe 100644 --- a/src/components/PurchaseOrderDetail.vue +++ b/src/components/PurchaseOrderDetail.vue @@ -117,7 +117,7 @@ export default defineComponent({ event: ev, translucent: true, showBackdrop: true, - componentProps: { 'id': id, 'isVirtual': isVirtual, 'item': item, poId } + componentProps: { 'id': id, 'isVirtual': isVirtual, 'item': item, poId, 'type': 'order' } }); return popover.present(); }, From 404f82cf97212d75ca7ff5349318ad225464a82b Mon Sep 17 00:00:00 2001 From: Disha Talreja Date: Wed, 8 Feb 2023 18:56:49 +0530 Subject: [PATCH 42/50] refactor: moved facility locations from user state to util state(#31a0f22) --- .../BulkInventoryAdjustmentModal.vue | 2 +- src/mixins/parseFileMixin.ts | 3 +- src/services/UserService.ts | 27 ++++-------- src/services/UtilService.ts | 26 ++++++++---- src/store/modules/stock/actions.ts | 8 ++-- src/store/modules/user/UserState.ts | 1 - src/store/modules/user/actions.ts | 42 +------------------ src/store/modules/user/getters.ts | 3 -- src/store/modules/user/index.ts | 1 - src/store/modules/user/mutation-types.ts | 1 - src/store/modules/user/mutations.ts | 6 --- src/store/modules/util/UtilState.ts | 3 +- src/store/modules/util/actions.ts | 42 ++++++++++++++++++- src/store/modules/util/getters.ts | 5 ++- src/store/modules/util/index.ts | 3 +- src/store/modules/util/mutation-types.ts | 1 + src/store/modules/util/mutations.ts | 5 +++ src/views/Inventory.vue | 9 +--- src/views/InventoryReview.vue | 4 +- 19 files changed, 93 insertions(+), 99 deletions(-) diff --git a/src/components/BulkInventoryAdjustmentModal.vue b/src/components/BulkInventoryAdjustmentModal.vue index c0d8d044..2b8c3519 100644 --- a/src/components/BulkInventoryAdjustmentModal.vue +++ b/src/components/BulkInventoryAdjustmentModal.vue @@ -89,7 +89,7 @@ export default defineComponent({ modalController.dismiss({ dismissed: true }); }, async save() { - const facilityLocations = await this.store.dispatch('user/fetchFacilityLocations', [this.facilityId]); + const facilityLocations = await this.store.dispatch('util/fetchFacilityLocations', [this.facilityId]); const locationSeqId = facilityLocations[this.facilityId] && facilityLocations[this.facilityId][0] ? facilityLocations[this.facilityId][0].locationSeqId : ''; await this.stockItems.parsed.map((item: any) => { if (item.isSelected) { diff --git a/src/mixins/parseFileMixin.ts b/src/mixins/parseFileMixin.ts index 35203558..5f73c3df 100644 --- a/src/mixins/parseFileMixin.ts +++ b/src/mixins/parseFileMixin.ts @@ -6,12 +6,11 @@ export default { methods: { async parseCsv(file: any) { if (file) { - showToast(translate("File uploaded successfully")); store.dispatch('order/updateFileName', file.name); - const csvData = await parseCsv(file).then( res => { return res; }) + showToast(translate("File uploaded successfully")); return csvData; } showToast(translate("Something went wrong, Please try again")); diff --git a/src/services/UserService.ts b/src/services/UserService.ts index 95bcfb9d..c95271f8 100644 --- a/src/services/UserService.ts +++ b/src/services/UserService.ts @@ -43,14 +43,6 @@ const setUserTimeZone = async (payload: any): Promise => { data: payload }); } - -const getFacilityLocations = async (payload: any): Promise => { - return api({ - url: "/performFind", - method: "POST", - data: payload - }) -} const createFieldMapping = async (payload: any): Promise => { return api({ @@ -85,14 +77,13 @@ const getFieldMappings = async (payload: any): Promise => { } export const UserService = { - createFieldMapping, - deleteFieldMapping, - login, - getAvailableTimeZones, - getFacilityLocations, - getFieldMappings, - getProfile, - setUserTimeZone, - checkPermission, - updateFieldMapping + createFieldMapping, + deleteFieldMapping, + login, + getAvailableTimeZones, + getFieldMappings, + getProfile, + setUserTimeZone, + checkPermission, + updateFieldMapping } \ No newline at end of file diff --git a/src/services/UtilService.ts b/src/services/UtilService.ts index d524f7c8..3ffa4578 100644 --- a/src/services/UtilService.ts +++ b/src/services/UtilService.ts @@ -1,12 +1,22 @@ import api from '@/api'; const getFacilities= async (payload: any): Promise => { - return api({ - url: "/performFind", - method: "POST", - data: payload - }); - } + return api({ + url: "/performFind", + method: "POST", + data: payload + }); +} + +const getFacilityLocations = async (payload: any): Promise => { + return api({ + url: "/performFind", + method: "POST", + data: payload + }) +} + export const UtilService = { - getFacilities - } \ No newline at end of file + getFacilities, + getFacilityLocations +} \ No newline at end of file diff --git a/src/store/modules/stock/actions.ts b/src/store/modules/stock/actions.ts index 8bda9ab7..47322199 100644 --- a/src/store/modules/stock/actions.ts +++ b/src/store/modules/stock/actions.ts @@ -5,7 +5,7 @@ import StockState from './StockState' import * as types from './mutation-types' const actions: ActionTree = { - async updatedStockList ({commit, rootGetters}, items) { + async updateStock ({commit, rootGetters}, items) { const productIds = items.map((item: any) => item.shopifyProductSKU) const facilityIds = [...new Set(items.map((item: any) => item.externalFacilityId))] const viewSize = productIds.length; @@ -15,7 +15,7 @@ const actions: ActionTree = { viewIndex, productIds } - await store.dispatch('user/fetchFacilityLocations', facilityIds); + await store.dispatch('util/fetchFacilityLocations', facilityIds); await store.dispatch("product/fetchProducts", payload); const unidentifiedItems = [] as any; const parsed = items.map((item: any) => { @@ -40,7 +40,7 @@ const actions: ActionTree = { updateStockItems({ commit }, stockItems){ commit(types.STOCK_ITEMS_UPDATED, stockItems); }, - clearStockList({ commit }){ + clearStock({ commit }){ commit(types.STOCK_ITEMS_UPDATED, { parsed: [], original: [], unidentifiedItems: []}); }, updateUnidentifiedItem({ commit, state }, payload: any) { @@ -60,7 +60,7 @@ const actions: ActionTree = { commit(types.STOCK_ITEMS_UPDATED, { parsed, original, unidentifiedItems}); }, async updateMissingFacilities({ state }, facilityMapping){ - const facilityLocations = await this.dispatch('user/fetchFacilityLocations', Object.values(facilityMapping)); + const facilityLocations = await this.dispatch('util/fetchFacilityLocations', Object.values(facilityMapping)); Object.keys(facilityMapping).map((facilityId: any) => { const locationSeqId = facilityLocations[facilityMapping[facilityId]].length ? facilityLocations[facilityMapping[facilityId]][0].locationSeqId : ''; state.items.parsed.map((item: any) => { diff --git a/src/store/modules/user/UserState.ts b/src/store/modules/user/UserState.ts index 61fe3fcd..eb20b614 100644 --- a/src/store/modules/user/UserState.ts +++ b/src/store/modules/user/UserState.ts @@ -5,7 +5,6 @@ export default interface UserState { instanceUrl: string; fieldMappings: object; preferredDateTimeFormat: string; - facilityLocationsByFacilityId: any; pwaState: any; currentMapping: { id: string; diff --git a/src/store/modules/user/actions.ts b/src/store/modules/user/actions.ts index 99ee5b6c..ae4dda37 100644 --- a/src/store/modules/user/actions.ts +++ b/src/store/modules/user/actions.ts @@ -126,47 +126,7 @@ const actions: ActionTree = { setUserInstanceUrl ({ commit }, payload){ commit(types.USER_INSTANCE_URL_UPDATED, payload) updateInstanceUrl(payload) - }, - - async fetchFacilityLocations({ commit, state }, facilityIds){ - facilityIds = facilityIds.filter((facilityId: any) => !state.facilityLocationsByFacilityId[facilityId]) - if(!facilityIds.length) return state.facilityLocationsByFacilityId; - - let resp; - const params = { - "inputFields": { - facilityId: facilityIds, - "facilityId_op": 'in' - }, - // Assuming we will not have more than 20 facility locations, hardcoded the viewSize value 20. - "viewSize": 20, - "fieldList": ["locationSeqId", "areaId", "aisleId", "sectionId", "levelId", "positionId", "facilityId"], - "entityName": "FacilityLocation", - "distinct": "Y", - "noConditionFind": "Y" - } - try { - resp = await UserService.getFacilityLocations(params); - if(resp.status === 200 && !hasError(resp) && resp.data?.count > 0) { - let facilityLocations = resp.data.docs - facilityLocations = facilityLocations.reduce((locations: any, location: any) => { - const locationPath = [location.areaId, location.aisleId, location.sectionId, location.levelId, location.positionId].filter((value: any) => value).join(""); - const facilityLocation = { - locationSeqId: location.locationSeqId, - locationPath: locationPath - } - locations[location.facilityId] ? locations[location.facilityId].push(facilityLocation) : locations[location.facilityId] = [facilityLocation]; - return locations; - }, {}); - commit(types.USER_FACILITY_LOCATIONS_BY_FACILITY_ID, facilityLocations); - } else { - console.error(resp); - } - } catch(err) { - console.error(err); - } - return state.facilityLocationsByFacilityId; - }, + }, updatePwaState({commit}, payload) { commit(types.USER_PWA_STATE_UPDATED, payload); diff --git a/src/store/modules/user/getters.ts b/src/store/modules/user/getters.ts index bbab6ecc..350ee617 100644 --- a/src/store/modules/user/getters.ts +++ b/src/store/modules/user/getters.ts @@ -30,9 +30,6 @@ const getters: GetterTree = { }, getPreferredDateTimeFormat (state) { return state.preferredDateTimeFormat; - }, - getFacilityLocationsByFacilityId: (state) => (facilityId: string) => { - return state.facilityLocationsByFacilityId[facilityId] }, getCurrentMapping(state) { return JSON.parse(JSON.stringify(state.currentMapping)) diff --git a/src/store/modules/user/index.ts b/src/store/modules/user/index.ts index 2f6bb20a..3ee72d04 100644 --- a/src/store/modules/user/index.ts +++ b/src/store/modules/user/index.ts @@ -13,7 +13,6 @@ const userModule: Module = { currentFacility: {}, instanceUrl: '', preferredDateTimeFormat: '', - facilityLocationsByFacilityId: {}, fieldMappings: {}, pwaState: { updateExists: false, diff --git a/src/store/modules/user/mutation-types.ts b/src/store/modules/user/mutation-types.ts index d5e265f0..74cafec1 100644 --- a/src/store/modules/user/mutation-types.ts +++ b/src/store/modules/user/mutation-types.ts @@ -4,7 +4,6 @@ export const USER_END_SESSION = SN_USER + '/END_SESSION' export const USER_INFO_UPDATED = SN_USER + '/INFO_UPDATED' export const USER_CURRENT_FACILITY_UPDATED = SN_USER + '/CURRENT_FACILITY_UPDATED' export const USER_INSTANCE_URL_UPDATED = SN_USER + '/INSTANCE_URL_UPDATED' -export const USER_FACILITY_LOCATIONS_BY_FACILITY_ID = SN_USER + '/FACILITY_LOCATIONS_BY_FACILITY_ID' export const USER_PWA_STATE_UPDATED = SN_USER + '/PWA_STATE_UPDATED' export const USER_DATETIME_FORMAT_UPDATED = SN_USER + '/DATETIME_FORMAT_UPDATED' export const USER_CURRENT_FIELD_MAPPING_UPDATED = SN_USER + '/_CURRENT_FIELD_MAPPING_UPDATED' diff --git a/src/store/modules/user/mutations.ts b/src/store/modules/user/mutations.ts index e6acb722..99ef46ac 100644 --- a/src/store/modules/user/mutations.ts +++ b/src/store/modules/user/mutations.ts @@ -8,7 +8,6 @@ const mutations: MutationTree = { }, [types.USER_END_SESSION] (state) { state.token = '' - state.facilityLocationsByFacilityId = {} state.current = {} state.currentFacility = {} }, @@ -30,11 +29,6 @@ const mutations: MutationTree = { }, [types.USER_DATETIME_FORMAT_UPDATED] (state, payload) { state.preferredDateTimeFormat = payload; - }, - [types.USER_FACILITY_LOCATIONS_BY_FACILITY_ID] (state, facilityLocations) { - Object.keys(facilityLocations).map((facilityId: any) => { - state.facilityLocationsByFacilityId[facilityId] = facilityLocations[facilityId]; - }) }, [types.USER_CURRENT_FIELD_MAPPING_UPDATED] (state, payload) { state.currentMapping = payload diff --git a/src/store/modules/util/UtilState.ts b/src/store/modules/util/UtilState.ts index 08c46d25..ea7f9347 100644 --- a/src/store/modules/util/UtilState.ts +++ b/src/store/modules/util/UtilState.ts @@ -1,3 +1,4 @@ export default interface UserState { - facilities: [] + facilities: [], + facilityLocationsByFacilityId: any; } \ No newline at end of file diff --git a/src/store/modules/util/actions.ts b/src/store/modules/util/actions.ts index 639042d0..155b76dd 100644 --- a/src/store/modules/util/actions.ts +++ b/src/store/modules/util/actions.ts @@ -35,7 +35,47 @@ const actions: ActionTree = { }, clearFacilities({commit}){ commit(types.UTIL_FACILITIES_UPDATED, []); - } + }, + async fetchFacilityLocations({ commit, state }, facilityIds){ + facilityIds = facilityIds.filter((facilityId: any) => !state.facilityLocationsByFacilityId[facilityId]) + if(!facilityIds.length) return state.facilityLocationsByFacilityId; + + let resp; + const params = { + "inputFields": { + facilityId: facilityIds, + "facilityId_op": 'in' + }, + // Assuming we will not have more than 20 facility locations, hardcoded the viewSize value 20. + "viewSize": 20, + "fieldList": ["locationSeqId", "areaId", "aisleId", "sectionId", "levelId", "positionId", "facilityId"], + "entityName": "FacilityLocation", + "distinct": "Y", + "noConditionFind": "Y" + } + try { + resp = await UtilService.getFacilityLocations(params); + if(resp.status === 200 && !hasError(resp) && resp.data?.count > 0) { + let facilityLocations = resp.data.docs + facilityLocations = facilityLocations.reduce((locations: any, location: any) => { + const locationPath = [location.areaId, location.aisleId, location.sectionId, location.levelId, location.positionId].filter((value: any) => value).join(""); + const facilityLocation = { + locationSeqId: location.locationSeqId, + locationPath: locationPath + } + locations[location.facilityId] ? locations[location.facilityId].push(facilityLocation) : locations[location.facilityId] = [facilityLocation]; + return locations; + }, {}); + commit(types.UTIL_FACILITY_LOCATIONS_BY_FACILITY_ID, facilityLocations); + } else { + console.error(resp); + } + } catch(err) { + console.error(err); + } + return state.facilityLocationsByFacilityId; + }, } + 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 index 3c0f4ba2..1e3d3afa 100644 --- a/src/store/modules/util/getters.ts +++ b/src/store/modules/util/getters.ts @@ -5,6 +5,9 @@ import RootState from '@/store/RootState' const getters: GetterTree = { getFacilities (state) { return state.facilities; - } + }, + getFacilityLocationsByFacilityId: (state) => (facilityId: string) => { + return state.facilityLocationsByFacilityId[facilityId] + }, } 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 index c2c081a2..1e30065f 100644 --- a/src/store/modules/util/index.ts +++ b/src/store/modules/util/index.ts @@ -8,7 +8,8 @@ import RootState from '@/store/RootState' const userModule: Module = { namespaced: true, state: { - facilities: [] + facilities: [], + facilityLocationsByFacilityId: {}, }, getters, actions, diff --git a/src/store/modules/util/mutation-types.ts b/src/store/modules/util/mutation-types.ts index efe014b5..c828d11f 100644 --- a/src/store/modules/util/mutation-types.ts +++ b/src/store/modules/util/mutation-types.ts @@ -1,2 +1,3 @@ export const SN_UTIL = 'util' export const UTIL_FACILITIES_UPDATED = SN_UTIL + '/FACILITIES_UPDATED' +export const UTIL_FACILITY_LOCATIONS_BY_FACILITY_ID = SN_UTIL + '/FACILITY_LOCATIONS_BY_FACILITY_ID' diff --git a/src/store/modules/util/mutations.ts b/src/store/modules/util/mutations.ts index f3b3a02d..ffb69d95 100644 --- a/src/store/modules/util/mutations.ts +++ b/src/store/modules/util/mutations.ts @@ -6,5 +6,10 @@ const mutations: MutationTree = { [types.UTIL_FACILITIES_UPDATED] (state, payload) { state.facilities = payload }, + [types.UTIL_FACILITY_LOCATIONS_BY_FACILITY_ID] (state, facilityLocations) { + Object.keys(facilityLocations).map((facilityId: any) => { + state.facilityLocationsByFacilityId[facilityId] = facilityLocations[facilityId]; + }) + }, } export default mutations; \ No newline at end of file diff --git a/src/views/Inventory.vue b/src/views/Inventory.vue index 1f05a6f5..94462f6c 100644 --- a/src/views/Inventory.vue +++ b/src/views/Inventory.vue @@ -60,7 +60,7 @@ import { IonPage, IonHeader, IonToolbar, IonTitle, IonContent, IonItem, IonLabel, IonList, IonListHeader, IonMenuButton, IonButton, IonSelect, IonSelectOption, IonIcon } from "@ionic/vue"; import { defineComponent } from "vue"; import { useRouter } from 'vue-router'; -import { useStore, mapGetters } from "vuex"; +import { useStore } from "vuex"; import { showToast } from '@/utils'; import { translate } from "@/i18n"; import { arrowForwardOutline } from 'ionicons/icons'; @@ -84,11 +84,6 @@ export default defineComponent({ IonListHeader, IonList }, - computed: { - ...mapGetters({ - dateTimeFormat : 'user/getDateTimeFormat', - }) - }, data() { return { file: "", @@ -129,7 +124,7 @@ export default defineComponent({ locationSeqId: item[this.fieldMapping.locationSeqId] } }) - this.store.dispatch('stock/updatedStockList', this.productsList); + this.store.dispatch('stock/updateStock', this.productsList); this.router.push({ name:'InventoryDetail' }) diff --git a/src/views/InventoryReview.vue b/src/views/InventoryReview.vue index 2dde0ebc..9acd1331 100644 --- a/src/views/InventoryReview.vue +++ b/src/views/InventoryReview.vue @@ -184,7 +184,7 @@ export default defineComponent({ instanceUrl: 'user/getInstanceUrl', facilities: 'util/getFacilities', fileName: 'order/getFileName', - getFacilityLocationsByFacilityId: 'user/getFacilityLocationsByFacilityId' + getFacilityLocationsByFacilityId: 'util/getFacilityLocationsByFacilityId' }) }, data() { @@ -314,7 +314,7 @@ export default defineComponent({ } }]) this.router.push("/inventory"); - this.store.dispatch('stock/clearStockList'); + this.store.dispatch('stock/clearStock'); }).catch(() => { showToast(translate("Something went wrong, please try again")); }) From e4fe91994d5783edc57d145cce29b11fe05d9c21 Mon Sep 17 00:00:00 2001 From: Disha Talreja Date: Wed, 8 Feb 2023 19:42:25 +0530 Subject: [PATCH 43/50] refactor: improved code(#31a0f22) --- src/store/modules/stock/actions.ts | 1 + src/views/Inventory.vue | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/store/modules/stock/actions.ts b/src/store/modules/stock/actions.ts index 47322199..1a1d182b 100644 --- a/src/store/modules/stock/actions.ts +++ b/src/store/modules/stock/actions.ts @@ -19,6 +19,7 @@ const actions: ActionTree = { await store.dispatch("product/fetchProducts", payload); const unidentifiedItems = [] as any; const parsed = items.map((item: any) => { + //TODO: use action instead of getter const product = rootGetters['product/getProduct'](item.shopifyProductSKU) if(Object.keys(product).length > 0){ diff --git a/src/views/Inventory.vue b/src/views/Inventory.vue index 94462f6c..0a5dba2d 100644 --- a/src/views/Inventory.vue +++ b/src/views/Inventory.vue @@ -104,12 +104,13 @@ export default defineComponent({ this.content = await this.parseCsv(this.file); }, mapFields() { - const areAllFieldsSelected = Object.values(this.fieldMapping).every(field => field !== ""); if (this.content.length <= 0) { showToast(translate("Please upload a valid reset inventory csv to continue")); return; } + const areAllFieldsSelected = Object.values(this.fieldMapping).every(field => field !== ""); + if (!areAllFieldsSelected) { showToast(translate("Select all the fields to continue")); return; From e44e96ddbd94a8c517e2bea9294c61eed3809a84 Mon Sep 17 00:00:00 2001 From: Aditya Sharma Date: Mon, 13 Feb 2023 12:50:50 +0530 Subject: [PATCH 44/50] Fixed: wrong alert message on page leave (#31a0f22) --- src/views/PurchaseOrderReview.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/views/PurchaseOrderReview.vue b/src/views/PurchaseOrderReview.vue index 2617a26d..21782206 100644 --- a/src/views/PurchaseOrderReview.vue +++ b/src/views/PurchaseOrderReview.vue @@ -145,7 +145,7 @@ export default defineComponent({ let canLeave = false; const alert = await alertController.create({ header: this.$t("Leave page"), - message: this.$t("Any edits made to this PO will be lost."), + message: this.$t("Any edits made on this page will be lost."), buttons: [ { text: this.$t("STAY"), From ab30e0c65d000bc8cc863736a8faa0927534fc41 Mon Sep 17 00:00:00 2001 From: Aditya Sharma Date: Mon, 13 Feb 2023 12:52:57 +0530 Subject: [PATCH 45/50] Fixed: file upload not working properly as the id was same 2 pages (#31a0f22) When navigating from Inventory review to PO import page, when the new file is upload code in inventory page is executed as the id was same. --- src/views/Inventory.vue | 4 ++-- src/views/PurchaseOrder.vue | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/views/Inventory.vue b/src/views/Inventory.vue index 0a5dba2d..345edd07 100644 --- a/src/views/Inventory.vue +++ b/src/views/Inventory.vue @@ -12,8 +12,8 @@ {{ $t("Inventory") }} {{ file.name }} - - + + diff --git a/src/views/PurchaseOrder.vue b/src/views/PurchaseOrder.vue index d984d1bc..689963ad 100644 --- a/src/views/PurchaseOrder.vue +++ b/src/views/PurchaseOrder.vue @@ -12,8 +12,8 @@ {{ $t("Purchase order") }} {{ file.name }} - - + + From d824e2685a160d3d1029b1fda3798be6a9f8b563 Mon Sep 17 00:00:00 2001 From: Aditya Sharma Date: Mon, 13 Feb 2023 16:44:45 +0530 Subject: [PATCH 46/50] Improved: fetchProducts action to return cached products (#31a0f22) When accessing the products from cached products, using it as object will be optimised approach when accessing any product using id. When returning cachedProducts object from fetchProducts method and accessing it we have an advantage of quick access, instead of returning list received Additionally: Fixed logic for viewSize when getting facility locations, instead of getting 10 location, it should be as per the no of facilityIds --- .../BulkInventoryAdjustmentModal.vue | 2 +- src/components/MissingSkuModal.vue | 6 +++--- src/store/modules/product/actions.ts | 9 ++++++--- src/store/modules/stock/actions.ts | 9 ++++----- src/store/modules/util/actions.ts | 18 ++++++++++-------- 5 files changed, 24 insertions(+), 20 deletions(-) diff --git a/src/components/BulkInventoryAdjustmentModal.vue b/src/components/BulkInventoryAdjustmentModal.vue index 2b8c3519..1eab088b 100644 --- a/src/components/BulkInventoryAdjustmentModal.vue +++ b/src/components/BulkInventoryAdjustmentModal.vue @@ -91,7 +91,7 @@ export default defineComponent({ async save() { const facilityLocations = await this.store.dispatch('util/fetchFacilityLocations', [this.facilityId]); const locationSeqId = facilityLocations[this.facilityId] && facilityLocations[this.facilityId][0] ? facilityLocations[this.facilityId][0].locationSeqId : ''; - await this.stockItems.parsed.map((item: any) => { + this.stockItems.parsed.map((item: any) => { if (item.isSelected) { item.quantity -= this.quantityBuffer; if(this.facilityId) { diff --git a/src/components/MissingSkuModal.vue b/src/components/MissingSkuModal.vue index f867a723..1db027f1 100644 --- a/src/components/MissingSkuModal.vue +++ b/src/components/MissingSkuModal.vue @@ -159,11 +159,11 @@ export default defineComponent({ productIds: [this.updatedSku] } const products = await this.store.dispatch("product/fetchProducts", payload); - if (!products.length) { + const product = products[this.updatedSku]; + if (!product) { this.isSkuInvalid = true; return; - } - const product = products[0]; + } const unidentifiedItem = this.unidentifiedItems.find((unidentifiedItem: any) => unidentifiedItem.shopifyProductSKU === this.unidentifiedProductSku); diff --git a/src/store/modules/product/actions.ts b/src/store/modules/product/actions.ts index cbec473b..c2950746 100644 --- a/src/store/modules/product/actions.ts +++ b/src/store/modules/product/actions.ts @@ -9,6 +9,9 @@ import logger from "@/logger"; const actions: ActionTree = { async fetchProducts ( { commit, state }, { productIds }) { + + // TODO Add try-catch block + const cachedProductIds = Object.keys(state.cached); const productIdFilter= productIds.reduce((filter: Array, productId: any) => { // If product does not exist in cached products then add the id @@ -19,7 +22,7 @@ const actions: ActionTree = { }, []); // If there are no product ids to search skip the API call - if (productIdFilter.length == 0) return productIds.map((productId: any) => state.cached[productId]).filter((product: any) => product); + if (productIdFilter.length == 0) return state.cached; const resp = await fetchProducts({ filters: { 'internalName': { 'value': productIdFilter }}, @@ -28,15 +31,15 @@ const actions: ActionTree = { }) if (!isError(resp)) { + console.log("resp", resp) const products = resp.products; // Handled empty response in case of failed query if (resp.total) commit(types.PRODUCT_ADD_TO_CACHED_MULTIPLE, { products }); - return resp.products; } else { logger.error(resp.serverResponse) } // TODO Handle specific error - return []; + return state.cached; }, } diff --git a/src/store/modules/stock/actions.ts b/src/store/modules/stock/actions.ts index 1a1d182b..42737e5e 100644 --- a/src/store/modules/stock/actions.ts +++ b/src/store/modules/stock/actions.ts @@ -5,7 +5,7 @@ import StockState from './StockState' import * as types from './mutation-types' const actions: ActionTree = { - async updateStock ({commit, rootGetters}, items) { + async updateStock ({ commit }, items) { const productIds = items.map((item: any) => item.shopifyProductSKU) const facilityIds = [...new Set(items.map((item: any) => item.externalFacilityId))] const viewSize = productIds.length; @@ -16,13 +16,12 @@ const actions: ActionTree = { productIds } await store.dispatch('util/fetchFacilityLocations', facilityIds); - await store.dispatch("product/fetchProducts", payload); + const cachedProducts = await store.dispatch("product/fetchProducts", payload); const unidentifiedItems = [] as any; const parsed = items.map((item: any) => { - //TODO: use action instead of getter - const product = rootGetters['product/getProduct'](item.shopifyProductSKU) + const product = cachedProducts[item.shopifyProductSKU]; - if(Object.keys(product).length > 0){ + if(product){ item.parentProductId = product?.parent?.id; item.pseudoId = product.pseudoId; item.parentProductName = product?.parent?.productName; diff --git a/src/store/modules/util/actions.ts b/src/store/modules/util/actions.ts index 155b76dd..4826d0f2 100644 --- a/src/store/modules/util/actions.ts +++ b/src/store/modules/util/actions.ts @@ -37,17 +37,19 @@ const actions: ActionTree = { commit(types.UTIL_FACILITIES_UPDATED, []); }, async fetchFacilityLocations({ commit, state }, facilityIds){ - facilityIds = facilityIds.filter((facilityId: any) => !state.facilityLocationsByFacilityId[facilityId]) - if(!facilityIds.length) return state.facilityLocationsByFacilityId; + const unavailablefacilityIds = facilityIds.filter((facilityId: any) => !state.facilityLocationsByFacilityId[facilityId]) + + // We already have required facility locations in cache + if(!unavailablefacilityIds.length) return state.facilityLocationsByFacilityId; let resp; const params = { "inputFields": { - facilityId: facilityIds, + facilityId: unavailablefacilityIds, "facilityId_op": 'in' }, - // Assuming we will not have more than 20 facility locations, hardcoded the viewSize value 20. - "viewSize": 20, + // Assuming we will not have more than 10 facility locations. + "viewSize": unavailablefacilityIds.length * 10, "fieldList": ["locationSeqId", "areaId", "aisleId", "sectionId", "levelId", "positionId", "facilityId"], "entityName": "FacilityLocation", "distinct": "Y", @@ -56,8 +58,8 @@ const actions: ActionTree = { try { resp = await UtilService.getFacilityLocations(params); if(resp.status === 200 && !hasError(resp) && resp.data?.count > 0) { - let facilityLocations = resp.data.docs - facilityLocations = facilityLocations.reduce((locations: any, location: any) => { + const facilityLocations = resp.data.docs + const facilityLocationsByFacilityId = facilityLocations.reduce((locations: any, location: any) => { const locationPath = [location.areaId, location.aisleId, location.sectionId, location.levelId, location.positionId].filter((value: any) => value).join(""); const facilityLocation = { locationSeqId: location.locationSeqId, @@ -66,7 +68,7 @@ const actions: ActionTree = { locations[location.facilityId] ? locations[location.facilityId].push(facilityLocation) : locations[location.facilityId] = [facilityLocation]; return locations; }, {}); - commit(types.UTIL_FACILITY_LOCATIONS_BY_FACILITY_ID, facilityLocations); + commit(types.UTIL_FACILITY_LOCATIONS_BY_FACILITY_ID, facilityLocationsByFacilityId); } else { console.error(resp); } From 3979ebfdbbecd3eb4f8504d4c10589673c8063c1 Mon Sep 17 00:00:00 2001 From: Aditya Sharma Date: Tue, 14 Feb 2023 11:57:25 +0530 Subject: [PATCH 47/50] Improved: getter & action name and logic to fetch facilities (#31a0f22) Fetching facilities should be one time action on mounted, used cache to persist it for atleast 1 hour to avoid any unwanted API calls --- src/components/BulkInventoryAdjustmentModal.vue | 2 +- src/components/MissingFacilitiesModal.vue | 2 +- src/components/MissingSkuModal.vue | 2 +- src/components/ProductPopover.vue | 2 +- src/services/UtilService.ts | 5 +++-- src/store/modules/product/actions.ts | 1 - src/store/modules/stock/actions.ts | 4 ++-- src/store/modules/stock/getters.ts | 2 +- src/store/modules/util/actions.ts | 4 ++-- src/views/Inventory.vue | 2 +- src/views/InventoryReview.vue | 4 ++-- src/views/PurchaseOrderReview.vue | 2 +- 12 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/components/BulkInventoryAdjustmentModal.vue b/src/components/BulkInventoryAdjustmentModal.vue index 1eab088b..4a727496 100644 --- a/src/components/BulkInventoryAdjustmentModal.vue +++ b/src/components/BulkInventoryAdjustmentModal.vue @@ -80,7 +80,7 @@ export default defineComponent({ }, computed: { ...mapGetters({ - stockItems: 'stock/getItemsStock', + stockItems: 'stock/getStockItems', facilities: 'util/getFacilities', }) }, diff --git a/src/components/MissingFacilitiesModal.vue b/src/components/MissingFacilitiesModal.vue index 757f6c46..e77eac9f 100644 --- a/src/components/MissingFacilitiesModal.vue +++ b/src/components/MissingFacilitiesModal.vue @@ -80,7 +80,7 @@ export default defineComponent({ computed: { ...mapGetters({ purchaseOrders: 'order/getPurchaseOrders', - stockItems: 'stock/getItemsStock', + stockItems: 'stock/getStockItems', }) }, mounted(){ diff --git a/src/components/MissingSkuModal.vue b/src/components/MissingSkuModal.vue index 1db027f1..f5da4a13 100644 --- a/src/components/MissingSkuModal.vue +++ b/src/components/MissingSkuModal.vue @@ -123,7 +123,7 @@ export default defineComponent({ computed: { ...mapGetters({ purchaseOrders: 'order/getPurchaseOrders', - stockItems: 'stock/getItemsStock', + stockItems: 'stock/getStockItems', }) }, mounted() { diff --git a/src/components/ProductPopover.vue b/src/components/ProductPopover.vue index 1cb2fb36..738f15da 100644 --- a/src/components/ProductPopover.vue +++ b/src/components/ProductPopover.vue @@ -28,7 +28,7 @@ export default defineComponent({ components: { IonContent, IonIcon, IonLabel, IonItem }, computed: { ...mapGetters({ - stockItems: 'stock/getItemsStock', + stockItems: 'stock/getStockItems', purchaseOrders: 'order/getPurchaseOrders', }), }, diff --git a/src/services/UtilService.ts b/src/services/UtilService.ts index 30a1fe24..138feda3 100644 --- a/src/services/UtilService.ts +++ b/src/services/UtilService.ts @@ -3,8 +3,9 @@ import { api } from '@/adapter' const getFacilities= async (payload: any): Promise => { return api({ url: "/performFind", - method: "POST", - data: payload + method: "GET", + params: payload, + cache: true }); } diff --git a/src/store/modules/product/actions.ts b/src/store/modules/product/actions.ts index c2950746..c9aafd09 100644 --- a/src/store/modules/product/actions.ts +++ b/src/store/modules/product/actions.ts @@ -31,7 +31,6 @@ const actions: ActionTree = { }) if (!isError(resp)) { - console.log("resp", resp) const products = resp.products; // Handled empty response in case of failed query if (resp.total) commit(types.PRODUCT_ADD_TO_CACHED_MULTIPLE, { products }); diff --git a/src/store/modules/stock/actions.ts b/src/store/modules/stock/actions.ts index 42737e5e..c4cbafbb 100644 --- a/src/store/modules/stock/actions.ts +++ b/src/store/modules/stock/actions.ts @@ -5,7 +5,7 @@ import StockState from './StockState' import * as types from './mutation-types' const actions: ActionTree = { - async updateStock ({ commit }, items) { + async processUpdateStockItems ({ commit }, items) { const productIds = items.map((item: any) => item.shopifyProductSKU) const facilityIds = [...new Set(items.map((item: any) => item.externalFacilityId))] const viewSize = productIds.length; @@ -15,7 +15,7 @@ const actions: ActionTree = { viewIndex, productIds } - await store.dispatch('util/fetchFacilityLocations', facilityIds); + store.dispatch('util/fetchFacilityLocations', facilityIds); const cachedProducts = await store.dispatch("product/fetchProducts", payload); const unidentifiedItems = [] as any; const parsed = items.map((item: any) => { diff --git a/src/store/modules/stock/getters.ts b/src/store/modules/stock/getters.ts index 3f309f18..81c0c5b7 100644 --- a/src/store/modules/stock/getters.ts +++ b/src/store/modules/stock/getters.ts @@ -3,7 +3,7 @@ import OrderState from "./StockState"; import RootState from "../../RootState"; const getters: GetterTree = { - getItemsStock(state) { + getStockItems(state) { return JSON.parse(JSON.stringify(state.items)); }, }; diff --git a/src/store/modules/util/actions.ts b/src/store/modules/util/actions.ts index 4826d0f2..d8e25044 100644 --- a/src/store/modules/util/actions.ts +++ b/src/store/modules/util/actions.ts @@ -48,8 +48,8 @@ const actions: ActionTree = { facilityId: unavailablefacilityIds, "facilityId_op": 'in' }, - // Assuming we will not have more than 10 facility locations. - "viewSize": unavailablefacilityIds.length * 10, + // Assuming we will not have more than 15 facility locations. + "viewSize": unavailablefacilityIds.length * 15, "fieldList": ["locationSeqId", "areaId", "aisleId", "sectionId", "levelId", "positionId", "facilityId"], "entityName": "FacilityLocation", "distinct": "Y", diff --git a/src/views/Inventory.vue b/src/views/Inventory.vue index 345edd07..a775f18b 100644 --- a/src/views/Inventory.vue +++ b/src/views/Inventory.vue @@ -125,7 +125,7 @@ export default defineComponent({ locationSeqId: item[this.fieldMapping.locationSeqId] } }) - this.store.dispatch('stock/updateStock', this.productsList); + this.store.dispatch('stock/processUpdateStockItems', this.productsList); this.router.push({ name:'InventoryDetail' }) diff --git a/src/views/InventoryReview.vue b/src/views/InventoryReview.vue index 9acd1331..25681288 100644 --- a/src/views/InventoryReview.vue +++ b/src/views/InventoryReview.vue @@ -179,7 +179,7 @@ export default defineComponent({ }, computed: { ...mapGetters({ - stockItems: 'stock/getItemsStock', + stockItems: 'stock/getStockItems', getProduct: 'product/getProduct', instanceUrl: 'user/getInstanceUrl', facilities: 'util/getFacilities', @@ -197,7 +197,7 @@ export default defineComponent({ facilityLocations: {} } }, - ionViewDidEnter(){ + mounted(){ this.store.dispatch('util/fetchFacilities'); }, async beforeRouteLeave(to) { diff --git a/src/views/PurchaseOrderReview.vue b/src/views/PurchaseOrderReview.vue index 21782206..34c98cd2 100644 --- a/src/views/PurchaseOrderReview.vue +++ b/src/views/PurchaseOrderReview.vue @@ -137,7 +137,7 @@ export default defineComponent({ isPOUploadedSuccessfully: false } }, - ionViewDidEnter(){ + mounted(){ this.store.dispatch('util/fetchFacilities'); }, async beforeRouteLeave(to) { From 9e7ffd3ce9d7392ce8dba624d6ea68ed59383179 Mon Sep 17 00:00:00 2001 From: Aditya Sharma Date: Tue, 14 Feb 2023 19:03:34 +0530 Subject: [PATCH 48/50] Improved: logic to show facility name instead of id (#31a0f22) - Fixed logic to set file if user cancels the file upload - Fixed values not getting reinitialised when logout and navigation to some other page --- src/components/MissingFacilitiesModal.vue | 3 ++- src/services/UploadService.ts | 2 +- src/store/modules/util/actions.ts | 6 +++-- src/views/Inventory.vue | 22 +++++++++++++++--- src/views/InventoryReview.vue | 26 +++++++++++++++++---- src/views/PurchaseOrder.vue | 28 ++++++++++++++++++----- src/views/PurchaseOrderReview.vue | 15 ++++++++---- 7 files changed, 80 insertions(+), 22 deletions(-) diff --git a/src/components/MissingFacilitiesModal.vue b/src/components/MissingFacilitiesModal.vue index e77eac9f..1d4c812d 100644 --- a/src/components/MissingFacilitiesModal.vue +++ b/src/components/MissingFacilitiesModal.vue @@ -70,7 +70,7 @@ export default defineComponent({ IonTitle, IonToolbar }, - props: ["itemsWithMissingFacility", "facilities", "type"], + props: ["itemsWithMissingFacility", "type"], data() { return { itemsByFacilityId: {}, @@ -81,6 +81,7 @@ export default defineComponent({ ...mapGetters({ purchaseOrders: 'order/getPurchaseOrders', stockItems: 'stock/getStockItems', + facilities: 'util/getFacilities', }) }, mounted(){ diff --git a/src/services/UploadService.ts b/src/services/UploadService.ts index d18c0681..79ed5f14 100644 --- a/src/services/UploadService.ts +++ b/src/services/UploadService.ts @@ -11,7 +11,7 @@ const uploadJsonFile = async (payload: any): Promise => { const prepareUploadJsonPayload = (request: UploadRequest) => { const blob = new Blob([JSON.stringify(request.uploadData)], { type: 'application/json'}); const formData = new FormData(); - const fileName = (request.fileName ? request.fileName : Date.now() ) +".json"; + const fileName = request.fileName ? request.fileName : Date.now() + ".json" ; formData.append("uploadedFile", blob, fileName); if (request.params) { for (const key in request.params) { diff --git a/src/store/modules/util/actions.ts b/src/store/modules/util/actions.ts index d8e25044..16ca80e4 100644 --- a/src/store/modules/util/actions.ts +++ b/src/store/modules/util/actions.ts @@ -17,20 +17,22 @@ const actions: ActionTree = { "facilityTypeId": "VIRTUAL_FACILITY", "facilityTypeId_op": "notEqual", }, - "fieldList": ["facilityId", "facilityName", "parentTypeId"], + "fieldList": ["facilityId", "facilityName", "parentTypeId", "externalId"], "viewSize": 50, "entityName": "FacilityAndType", "noConditionFind": "Y" } try { const resp = await UtilService.getFacilities(payload); - if(resp.status === 200 && resp.data.docs && !hasError(resp)){ + if(resp.status === 200 && !hasError(resp)){ commit(types.UTIL_FACILITIES_UPDATED, resp.data.docs); } else { logger.error(resp) + commit(types.UTIL_FACILITIES_UPDATED, []); } } catch(err) { logger.error(err) + commit(types.UTIL_FACILITIES_UPDATED, []); } }, clearFacilities({commit}){ diff --git a/src/views/Inventory.vue b/src/views/Inventory.vue index a775f18b..a4bc3911 100644 --- a/src/views/Inventory.vue +++ b/src/views/Inventory.vue @@ -86,7 +86,7 @@ export default defineComponent({ }, data() { return { - file: "", + file: {}, content: [], fieldMapping: { productSku: "", @@ -98,10 +98,26 @@ export default defineComponent({ } }, mixins:[ parseFileMixin ], + ionViewDidLeave() { + this.file = {} + this.content = [] + this.fieldMapping = { + productSku: "", + quantity: "", + facility: "", + locationSeqId: "", + } + }, methods: { async parse(event) { - this.file = event.target.files[0]; - this.content = await this.parseCsv(this.file); + const file = event.target.files[0]; + if(file){ + this.file = file; + this.content = await this.parseCsv(this.file); + showToast(translate("File uploaded successfully")); + } else { + showToast(translate("No new file upload. Please try again")); + } }, mapFields() { if (this.content.length <= 0) { diff --git a/src/views/InventoryReview.vue b/src/views/InventoryReview.vue index 25681288..57a3d81c 100644 --- a/src/views/InventoryReview.vue +++ b/src/views/InventoryReview.vue @@ -111,7 +111,7 @@ - {{ item.externalFacilityId ? item.externalFacilityId : item.facilityId }} + {{ getFacilityName(item.facilityId, item.externalFacilityId) }} @@ -197,7 +197,7 @@ export default defineComponent({ facilityLocations: {} } }, - mounted(){ + ionViewDidEnter(){ this.store.dispatch('util/fetchFacilities'); }, async beforeRouteLeave(to) { @@ -240,15 +240,31 @@ export default defineComponent({ }); return missingSkuModal.present(); }, + getFacilityName(facilityId: any, externalFacilityId: any) { + if (facilityId) { + const facility = this.facilities.find((facility: any) => facilityId === facility.facilityId ); + return facility ? facility.facilityName : facilityId; + } else if (externalFacilityId) { + const facility = this.facilities.find((facility: any) => externalFacilityId === facility.externalId ); + return facility ? facility.facilityName : externalFacilityId; + } + return externalFacilityId; + }, getItemsWithMissingFacility() { - const facilityIds = this.facilities.map((facility: any) => facility.facilityId) - return this.stockItems.parsed.filter((item: any) => !facilityIds.includes(item.externalFacilityId) && item.externalFacilityId !== ""); + const externalFacilityIds = this.facilities.reduce((externalFacilityIds: any, facility: any) => { + if (facility.externalId) externalFacilityIds.push(facility.externalId); + return externalFacilityIds; + }, []) + // if facilityId is set, this is facility set from the facility list + // if externalFacilityId doesn't exist, case for missing facility + // if externalFacilityId exist and not found in facility list, case for missing facility + return this.stockItems.parsed.filter((item: any) => !item.facilityId && (!item.externalFacilityId || (item.externalFacilityId && !externalFacilityIds.includes(item.externalFacilityId)))); }, async openMissingFacilitiesModal() { const itemsWithMissingFacility = this.getItemsWithMissingFacility(); const missingFacilitiesModal = await modalController.create({ component: MissingFacilitiesModal, - componentProps: { itemsWithMissingFacility, facilities: this.facilities, type: 'stock' } + componentProps: { itemsWithMissingFacility, type: 'stock' } }); missingFacilitiesModal.onDidDismiss().then(() => { this.searchProduct(this.queryString); diff --git a/src/views/PurchaseOrder.vue b/src/views/PurchaseOrder.vue index 689963ad..56287653 100644 --- a/src/views/PurchaseOrder.vue +++ b/src/views/PurchaseOrder.vue @@ -124,10 +124,20 @@ export default defineComponent({ orderDate: "", quantity: "", facility: "", - }, - purchaseOrderItems: [], + } } }, + ionViewDidLeave() { + this.file = {} + this.content = [] + this.fieldMapping = { + orderId: "", + productSku: "", + orderDate: "", + quantity: "", + facility: "", + } + }, methods: { //Todo: Generating unique identifiers as we are currently storing in local storage. Need to remove it as we will be storing data on server. generateUniqueMappingPrefId() { @@ -135,8 +145,14 @@ export default defineComponent({ return !this.fieldMappings[id] ? id : this.generateUniqueMappingPrefId(); }, async parse(event) { - this.file = event.target.files[0]; - this.content = await this.parseCsv(this.file); + const file = event.target.files[0]; + if(file){ + this.file = file; + this.content = await this.parseCsv(this.file); + showToast(translate("File uploaded successfully")); + } else { + showToast(translate("No new file upload. Please try again")); + } }, review() { if (this.content.length <= 0) { @@ -149,7 +165,7 @@ export default defineComponent({ return; } - this.purchaseOrderItems = this.content.map(item => { + const purchaseOrderItems = this.content.map(item => { return { orderId: item[this.fieldMapping.orderId], shopifyProductSKU: item[this.fieldMapping.productSku], @@ -159,7 +175,7 @@ export default defineComponent({ externalFacilityId: item[this.fieldMapping.facility] } }) - this.store.dispatch('order/fetchOrderDetails', this.purchaseOrderItems); + this.store.dispatch('order/fetchOrderDetails', purchaseOrderItems); this.router.push({ name:'PurchaseOrderReview' }) diff --git a/src/views/PurchaseOrderReview.vue b/src/views/PurchaseOrderReview.vue index 34c98cd2..b8a0ff6b 100644 --- a/src/views/PurchaseOrderReview.vue +++ b/src/views/PurchaseOrderReview.vue @@ -137,7 +137,7 @@ export default defineComponent({ isPOUploadedSuccessfully: false } }, - mounted(){ + ionViewDidEnter(){ this.store.dispatch('util/fetchFacilities'); }, async beforeRouteLeave(to) { @@ -177,8 +177,15 @@ export default defineComponent({ return Object.values(this.purchaseOrders.parsed).flat().filter((item: any) => !DateTime.fromFormat(item.arrivalDate, this.dateTimeFormat).isValid).length; }, getItemsWithMissingFacility() { - const facilityIds = this.facilities.map((facility: any) => facility.facilityId) - return Object.values(this.purchaseOrders.parsed).flat().filter((item: any) => !facilityIds.includes(item.externalFacilityId) && item.externalFacilityId !== ""); + const externalFacilityIds = this.facilities.reduce((externalFacilityIds: any, facility: any) => { + if (facility.externalId) externalFacilityIds.push(facility.externalId); + return externalFacilityIds; + }, []) + + // if facilityId is set, this is facility set from the facility list + // if externalFacilityId doesn't exist, case for missing facility + // if externalFacilityId exist and not found in facility list, case for missing facility + return Object.values(this.purchaseOrders.parsed).flat().filter((item: any) => !item.facilityId && (!item.externalFacilityId || (item.externalFacilityId && !externalFacilityIds.includes(item.externalFacilityId)))); }, isDateInvalid(){ // Checked if any of the date format is different than the selected format. @@ -270,7 +277,7 @@ export default defineComponent({ const itemsWithMissingFacility = this.getItemsWithMissingFacility(); const missingFacilitiesModal = await modalController.create({ component: MissingFacilitiesModal, - componentProps: { itemsWithMissingFacility, facilities: this.facilities, type: 'order' } + componentProps: { itemsWithMissingFacility, type: 'order' } }); return missingFacilitiesModal.present(); }, From 2cadd4bbceb23e31723ab6b4bc1e5efb76135689 Mon Sep 17 00:00:00 2001 From: Aditya Sharma Date: Wed, 15 Feb 2023 12:48:13 +0530 Subject: [PATCH 49/50] Improved: logic to get facility locations using facilityId instead of externalId (#31a0f22) Fixed input file not reset with data properties Improved logic to check if response has error Used logger instead of console.error --- src/store/modules/stock/actions.ts | 15 +++++++++++++-- src/store/modules/util/actions.ts | 9 +++++---- src/utils/index.ts | 2 +- src/views/Inventory.vue | 1 + src/views/PurchaseOrder.vue | 1 + 5 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/store/modules/stock/actions.ts b/src/store/modules/stock/actions.ts index c4cbafbb..40352927 100644 --- a/src/store/modules/stock/actions.ts +++ b/src/store/modules/stock/actions.ts @@ -7,7 +7,19 @@ import * as types from './mutation-types' const actions: ActionTree = { async processUpdateStockItems ({ commit }, items) { const productIds = items.map((item: any) => item.shopifyProductSKU) - const facilityIds = [...new Set(items.map((item: any) => item.externalFacilityId))] + + // We are getting external facilityId from CSV, extract facilityId and pass for getting locations + const externalFacilityIds = [...new Set(items.map((item: any) => item.externalFacilityId))] + const facilities = await store.dispatch('util/fetchFacilities'); + const facilityMapping = facilities.reduce((facilityMapping: any, facility: any) => { + if (facility.externalId) facilityMapping[facility.externalId] = facility.facilityId; + return facilityMapping; + }, {}) + const facilityIds = externalFacilityIds.map((externalFacilityId: any) => { + return facilityMapping[externalFacilityId]; + }).filter((facilityId: any) => facilityId) + store.dispatch('util/fetchFacilityLocations', facilityIds); + const viewSize = productIds.length; const viewIndex = 0; const payload = { @@ -15,7 +27,6 @@ const actions: ActionTree = { viewIndex, productIds } - store.dispatch('util/fetchFacilityLocations', facilityIds); const cachedProducts = await store.dispatch("product/fetchProducts", payload); const unidentifiedItems = [] as any; const parsed = items.map((item: any) => { diff --git a/src/store/modules/util/actions.ts b/src/store/modules/util/actions.ts index 16ca80e4..c0ef4f29 100644 --- a/src/store/modules/util/actions.ts +++ b/src/store/modules/util/actions.ts @@ -9,7 +9,7 @@ import logger from '@/logger' const actions: ActionTree = { async fetchFacilities({ state, commit}){ - if(state.facilities.length) return; + if(state.facilities.length) return state.facilities; const payload = { "inputFields": { "parentTypeId": "VIRTUAL_FACILITY", @@ -34,6 +34,7 @@ const actions: ActionTree = { logger.error(err) commit(types.UTIL_FACILITIES_UPDATED, []); } + return state.facilities; }, clearFacilities({commit}){ commit(types.UTIL_FACILITIES_UPDATED, []); @@ -59,7 +60,7 @@ const actions: ActionTree = { } try { resp = await UtilService.getFacilityLocations(params); - if(resp.status === 200 && !hasError(resp) && resp.data?.count > 0) { + if(resp.status === 200 && !hasError(resp)) { const facilityLocations = resp.data.docs const facilityLocationsByFacilityId = facilityLocations.reduce((locations: any, location: any) => { const locationPath = [location.areaId, location.aisleId, location.sectionId, location.levelId, location.positionId].filter((value: any) => value).join(""); @@ -72,10 +73,10 @@ const actions: ActionTree = { }, {}); commit(types.UTIL_FACILITY_LOCATIONS_BY_FACILITY_ID, facilityLocationsByFacilityId); } else { - console.error(resp); + logger.error(resp.data) } } catch(err) { - console.error(err); + logger.error(err); } return state.facilityLocationsByFacilityId; }, diff --git a/src/utils/index.ts b/src/utils/index.ts index 00dc135d..5a4296ea 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -7,7 +7,7 @@ import { DateTime } from "luxon"; // TODO Remove it when HC APIs are fully REST compliant const hasError = (response: any) => { - return !!response.data._ERROR_MESSAGE_ || !!response.data._ERROR_MESSAGE_LIST_; + return typeof response.data != "object" || !!response.data._ERROR_MESSAGE_ || !!response.data._ERROR_MESSAGE_LIST_ || !!response.data.error; } const showToast = async (message: string, configButtons?: any) => { diff --git a/src/views/Inventory.vue b/src/views/Inventory.vue index a4bc3911..ab222106 100644 --- a/src/views/Inventory.vue +++ b/src/views/Inventory.vue @@ -107,6 +107,7 @@ export default defineComponent({ facility: "", locationSeqId: "", } + this.$refs.file.value = null; }, methods: { async parse(event) { diff --git a/src/views/PurchaseOrder.vue b/src/views/PurchaseOrder.vue index 56287653..8fdcd9cb 100644 --- a/src/views/PurchaseOrder.vue +++ b/src/views/PurchaseOrder.vue @@ -137,6 +137,7 @@ export default defineComponent({ quantity: "", facility: "", } + this.$refs.file.value = null; }, methods: { //Todo: Generating unique identifiers as we are currently storing in local storage. Need to remove it as we will be storing data on server. From 1071ec11b9c0f8b0f093af1056b3138b224459cd Mon Sep 17 00:00:00 2001 From: Aditya Sharma Date: Wed, 15 Feb 2023 14:36:32 +0530 Subject: [PATCH 50/50] Improved: action name (#31a0f22) We are using stock items term for imported stocks, for consistency same term should be used --- src/store/modules/stock/actions.ts | 2 +- src/views/InventoryReview.vue | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/store/modules/stock/actions.ts b/src/store/modules/stock/actions.ts index 40352927..45151017 100644 --- a/src/store/modules/stock/actions.ts +++ b/src/store/modules/stock/actions.ts @@ -51,7 +51,7 @@ const actions: ActionTree = { updateStockItems({ commit }, stockItems){ commit(types.STOCK_ITEMS_UPDATED, stockItems); }, - clearStock({ commit }){ + clearStockItems({ commit }){ commit(types.STOCK_ITEMS_UPDATED, { parsed: [], original: [], unidentifiedItems: []}); }, updateUnidentifiedItem({ commit, state }, payload: any) { diff --git a/src/views/InventoryReview.vue b/src/views/InventoryReview.vue index 57a3d81c..b3e94cbf 100644 --- a/src/views/InventoryReview.vue +++ b/src/views/InventoryReview.vue @@ -330,7 +330,7 @@ export default defineComponent({ } }]) this.router.push("/inventory"); - this.store.dispatch('stock/clearStock'); + this.store.dispatch('stock/clearStockItems'); }).catch(() => { showToast(translate("Something went wrong, please try again")); })