diff --git a/src/components/ScheduledRestockPopover.vue b/src/components/ScheduledRestockPopover.vue index e39b816..e00edab 100644 --- a/src/components/ScheduledRestockPopover.vue +++ b/src/components/ScheduledRestockPopover.vue @@ -4,7 +4,7 @@ {{ job.jobName || job.jobId }} - Reschedule + {{ translate("Reschedule") }} isUpdateDateTimeModalOpen = false"> - Cancel + {{ translate("Cancel") }} @@ -96,7 +96,7 @@ export default defineComponent({ const currentTime = DateTime.now().toMillis(); const setTime = DateTime.fromISO(event.detail.value).toMillis(); if (setTime < currentTime) { - showToast('Please provide a future date and time'); + showToast(translate("Please provide a future date and time")); return; } this.updateJob(setTime) diff --git a/src/locales/en.json b/src/locales/en.json index 096004e..4e8ef99 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -44,9 +44,13 @@ "Expected input": "Expected input", "Enter product sku to search": "Enter product sku to search", "Facility": "Facility", + "Facility not found": "Facility not found", + "Facilities": "Facilities", "Facility ID": "Facility ID", "Facility Location": "Facility Location", "Failed to save CSV mapping.": "Failed to save CSV mapping.", + "Failed to schedule job": "Failed to schedule job", + "Failed to cancel job": "Failed to cancel job", "Failed to delete CSV mapping.": "Failed to delete CSV mapping.", "Failed to update CSV mapping.": "Failed to update CSV mapping.", "Fetching TimeZones": "Fetching TimeZones", @@ -93,12 +97,14 @@ "New version available, please update the app.": "New version available, please update the app.", "There are no saved CSV mappings to show. Create a new mapping from a file upload screen": "There are no saved CSV mappings to show. Create a new mapping from a file upload screen", "No new file upload. Please try again": "No new file upload. Please try again", + "No product found": "No product found", "No results found": "No results found", "No time zone found": "No time zone found", "of": "of", "OMS": "OMS", "OMS instance": "OMS instance", "Only select": "Only select", + "Optional, or select during review": "Optional, or select during review", "Order buffer": "Order buffer", "Order ID": "Order ID", "Ordered": "Ordered", @@ -107,17 +113,23 @@ "Password": "Password", "Pending": "Pending", "Please ensure that the uploaded file contains accurate product information. If a product does not exist, the corresponding records will not be processed.": "Please ensure that the uploaded file contains accurate product information. If a product does not exist, the corresponding records will not be processed.", + "Please provide a future date and time": "Please provide a future date and time", + "Please select a schedule time": "Please select a schedule time", + "Please select a product store": "Please select a product store", + "Please select a shopify shop": "Please select a shopify shop", "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 Identification": "Product Identification", "Product SKU": "Product SKU", + "Product store": "Product store", "Product not found": "Product not found", "Purchase order": "Purchase order", "Purchase orders": "Purchase orders", "Quantity": "Quantity", "Ready to create an app?": "Ready to create an app?", + "Restock quantity": "Restock quantity", "Review": "Review", "Review PO details": "Review PO details", "Review purchase order": "Review purchase order", @@ -125,7 +137,12 @@ "Reset": "Reset", "Reset inventory": "Reset inventory", "Reset password": "Reset password", + "Restock": "Restock", + "Restock name": "Restock name", + "Restock details": "Restock details", "Results": "Results", + "Reschedule": "Reschedule", + "Required": "Required", "Safety stock": "Safety stock", "Save mapping": "Save mapping", "Sample": "Sample", @@ -136,12 +153,18 @@ "Search products": "Search products", "Search time zones": "Search time zones", "Seems like uploaded file has missing products, checked with initial records.": "Seems like uploaded file has missing products, checked with initial {initialCount} records.", + "Schedule": "Schedule", "Select": "Select", "Select mapping": "Select mapping", "Select SKU": "Select SKU", "Select all the fields to continue": "Select all the fields to continue", "Select time zone": "Select time zone", + "Select time": "Select time", "Select the column index for the following information in the uploaded CSV.": "Select the column index for the following information in the uploaded CSV.", + "Service updated successfully": "Service updated successfully", + "Service has been scheduled": "Service has been scheduled", + "Scheduled Restock": "Scheduled Restock", + "Shopify store": "Shopify store", "Some of the mapping fields are missing in the CSV: ": "Some of the mapping fields are missing in the CSV: {missingFields}", "Changes have been successfully applied. Some of the selected items have quantity less than or equal to order buffer. The quantity of those items is set to 1.": "Changes have been successfully applied. {newLine} Some of the selected items have quantity less than or equal to order buffer. The quantity of those items is set to 1.", "Something went wrong": "Something went wrong", diff --git a/src/router/index.ts b/src/router/index.ts index a681987..9490497 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -78,13 +78,13 @@ const routes: Array = [ path: '/scheduled-restock', name: 'ScheduledRestock', component: ScheduledRestock, - // beforeEnter: authGuard + beforeEnter: authGuard }, { path: '/scheduled-restock-review', name: 'ScheduledRestockDetail', component: ScheduledRestockReview, - // beforeEnter: authGuard + beforeEnter: authGuard }, { path: '/login', diff --git a/src/store/modules/stock/StockState.ts b/src/store/modules/stock/StockState.ts index d73333a..7ed4ec7 100644 --- a/src/store/modules/stock/StockState.ts +++ b/src/store/modules/stock/StockState.ts @@ -8,10 +8,10 @@ export default interface StockState { fileName: string, restockItems: [], schedule: { - scheduledTime: string, - shopId: string, - restockName: string , - productStoreId: string + scheduledTime: any, + shopId: any, + restockName: any , + productStoreId: any } shopifyShops: any, jobs: any diff --git a/src/store/modules/stock/actions.ts b/src/store/modules/stock/actions.ts index 748aff0..d389e3e 100644 --- a/src/store/modules/stock/actions.ts +++ b/src/store/modules/stock/actions.ts @@ -17,7 +17,6 @@ const actions: ActionTree = { //Fetching only top const productIds = items.slice(0, process.env['VUE_APP_VIEW_SIZE']).map((item: any) => item.identification); - // 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'); @@ -30,7 +29,6 @@ const actions: ActionTree = { }).filter((facilityId: any) => facilityId) store.dispatch('util/fetchFacilityLocations', facilityIds); - const viewSize = productIds.length; const viewIndex = 0; const payload = { @@ -85,6 +83,7 @@ const actions: ActionTree = { }, {}); const facilityIds = externalFacilityIds.map((externalFacilityId: any) => facilityMapping[externalFacilityId]).filter((facilityId: any) => facilityId); const cachedProducts = await store.dispatch("product/fetchProducts", payload); + // creating products object based on identification selected const products: any = Object.values(cachedProducts).reduce((updatedProducts: any, product: any) => { const identification = product.identifications.find((identification: any) => payload.identificationTypeId.toLowerCase() === identification.productIdTypeEnumId.toLowerCase()) @@ -112,12 +111,14 @@ const actions: ActionTree = { async scheduledStock({ commit }, payload) { commit(types.STOCK_SCHEDULED_INFORMATION, payload) }, - + async clearScheduledStock({ commit }) { + commit(types.STOCK_SCHEDULED_INFORMATION, {}) + }, async shopifyShop({ commit }, payload) { commit(types.STOCK_SHOPIFY_SHOPS_UPDATED, payload) }, - async scheduleService({ dispatch, state }, { params, restockName, scheduledTime}) { + async scheduleService({ dispatch, state }, { params, restockName }) { let resp; const job = await dispatch("fetchDraftJob") @@ -149,7 +150,7 @@ const actions: ActionTree = { } job?.priority && (payload['SERVICE_PRIORITY'] = job.priority.toString()) - payload['SERVICE_TIME'] = scheduledTime.toString() || state.schedule.scheduledTime.toString() + payload['SERVICE_TIME'] = state.schedule.scheduledTime.toString() job?.sinceId && (payload['sinceId'] = job.sinceId) try { @@ -199,7 +200,7 @@ const actions: ActionTree = { throw resp.data } } catch(err) { - logger.error('Failed to fetcg draft job') + logger.error('Failed to fetch draft job') job = {} } diff --git a/src/store/modules/user/actions.ts b/src/store/modules/user/actions.ts index b86b12e..3b00dce 100644 --- a/src/store/modules/user/actions.ts +++ b/src/store/modules/user/actions.ts @@ -108,6 +108,7 @@ const actions: ActionTree = { resetConfig(); this.dispatch('order/updatePurchaseOrders', {parsed: {}, original: {}, unidentifiedItems: []}); this.dispatch('util/clearFacilities'); + this.dispatch('stock/clearScheduledStock') // clearing field mappings and current mapping when the user logout commit(types.USER_FIELD_MAPPINGS_UPDATED, {}) commit(types.USER_CURRENT_FIELD_MAPPING_UPDATED, {id: '', mappingType: '', name: '', value: {}}) diff --git a/src/views/ScheduledRestock.vue b/src/views/ScheduledRestock.vue index 39fdec7..c3086ad 100644 --- a/src/views/ScheduledRestock.vue +++ b/src/views/ScheduledRestock.vue @@ -3,14 +3,14 @@ - Scheduled Restock + {{ translate("Scheduled Restock") }} - Restock + {{ translate("Restock") }} {{ file.name }} {{ translate("Upload") }} @@ -32,7 +32,7 @@ {{ translate("Select the column index for the following information in the uploaded CSV.") }} - Required + {{ translate("Required") }} @@ -51,11 +51,11 @@ - Optional, or select during review + {{ translate("Optional, or select during review") }} - Schedule - {{ schedule ? getTime(schedule) : 'Select time' }} + {{ translate("Schedule") }} + {{ schedule ? getTime(schedule) : translate("Select time") }} isDateTimeModalOpen = false"> - + {{ shop.name ? shop.name : shop.shopId }} - + @@ -93,15 +93,15 @@ - - Scheduled Restock + + {{ translate("Scheduled Restock") }} {{ job.jobId }} {{ job.jobName }} {{ job?.runtimeData?.shipmentId }} - {{ getTime(job.runTime) ? getTime(job.runTime) : 'Select time' }} + {{ getTime(job.runTime) ? getTime(job.runTime) : translate("Select time") }} @@ -193,10 +193,6 @@ export default defineComponent({ }, mixins:[ parseFileMixin ], async ionViewDidEnter() { - this.schedule = "" - this.restockName = "" - this.selectedProductStoreId = "" - this.selectedShopifyShopId = "" this.file = {} this.content = [] this.fieldMapping = Object.keys(this.fields)?.reduce((fieldMapping, field) => { @@ -204,6 +200,10 @@ export default defineComponent({ return fieldMapping; }, {}) this.$refs.file.value = null; + this.schedule = "" + this.restockName = "" + this.selectedProductStoreId = "" + this.selectedShopifyShopId = "" await this.store.dispatch('stock/fetchJobs') await this.store.dispatch('util/fetchProductStores') await this.store.dispatch('util/fetchGoodIdentificationTypes'); @@ -230,7 +230,7 @@ export default defineComponent({ throw resp.data } } catch (error) { - logger.error('Failed to fetch shopify shops.', error) + logger.error('Failed to fetch shopify shops', error) } this.shopifyShops = shopifyShops }, @@ -248,7 +248,7 @@ export default defineComponent({ const currentTime = DateTime.now().toMillis(); const setTime = DateTime.fromISO(event.detail.value).toMillis(); if (setTime < currentTime) { - showToast('Please provide a future date and time'); + showToast(translate("Please provide a future date and time")); return; } this.schedule = setTime; @@ -257,7 +257,7 @@ export default defineComponent({ const currentTime = DateTime.now().toMillis(); const setTime = DateTime.fromISO(event.detail.value).toMillis(); if (setTime < currentTime) { - showToast('Please provide a future date and time'); + showToast(translate("Please provide a future date and time")); return; } this.updateJob(setTime) @@ -414,4 +414,8 @@ main { label { cursor: pointer; } + +.job-section { + margin-bottom: 16px; +} \ No newline at end of file diff --git a/src/views/ScheduledRestockReview.vue b/src/views/ScheduledRestockReview.vue index df6f575..1487587 100644 --- a/src/views/ScheduledRestockReview.vue +++ b/src/views/ScheduledRestockReview.vue @@ -3,8 +3,7 @@ - Restock details - + {{ translate("Restock details")}} @@ -25,8 +24,8 @@ - Schedule - {{ scheduledTime ? getTime(scheduledTime) : 'Select time' }} + {{ translate("Schedule") }} + {{ schedule.scheduledTime ? getTime(schedule.scheduledTime) : translate("Select time") }} isDateTimeModalOpen = false"> @@ -42,27 +41,27 @@ - + {{ getFacilityName(facilityId) }} - + - {{ productStore.storeName || productStore.productStoreId}} + {{ productStore.storeName || productStore.productStoreId }} - + {{ shop.name ? shop.name : shop.shopId }} - + @@ -161,11 +160,7 @@ export default defineComponent({ isCsvUploadedSuccessfully: false, originalItems: {}, parsedItems: {}, - restockName: '', isDateTimeModalOpen: false, - selectedProductStoreId: '', - selectedShopifyShopId: '', - scheduledTime: '', shopifyShops: [] } }, @@ -173,13 +168,8 @@ export default defineComponent({ async ionViewDidEnter() { await this.store.dispatch('util/fetchFacilities'); this.getFilteredRestockItems(); - this.restockName = this.schedule.restockName - this.selectedProductStoreId = this.schedule.productStoreId; - this.selectedShopifyShopId = this.schedule.shopId - this.scheduledTime = this.schedule.scheduledTime; - - if(this.selectedProductStoreId) { - this.fetchShopifyShops(this.selectedProductStoreId); + if(this.schedule.productStoreId) { + this.fetchShopifyShops(this.schedule.productStoreId); } }, // async beforeRouteLeave(to) { @@ -212,9 +202,8 @@ export default defineComponent({ // } // }, methods: { - getPlaceholder() { - return `Created ${this.getTime(this.scheduledTime ? this.scheduledTime : DateTime.now().toMillis())}` + return `Created ${this.getTime(this.schedule.scheduledTime ? this.schedule.scheduledTime : DateTime.now().toMillis())}` }, getFilteredRestockItems() { const filteredItems = {}; @@ -226,7 +215,6 @@ export default defineComponent({ this.originalItems = filteredItems; this.parsedItems = JSON.parse(JSON.stringify(this.originalItems)) }, - getFacilityName(externalFacilityId) { const facility = this.facilities.find(fac => fac.externalId === externalFacilityId); return facility ? facility.facilityName : externalFacilityId; @@ -241,24 +229,24 @@ export default defineComponent({ const currentTime = DateTime.now().toMillis(); const setTime = DateTime.fromISO(event.detail.value).toMillis(); if (setTime < currentTime) { - showToast('Please provide a future date and time'); + showToast(translate("Please provide a future date and time")); return; } - this.scheduledTime = setTime; + this.schedule.scheduledTime = setTime; }, async save() { - if(!this.scheduledTime) { + if(!this.schedule.scheduledTime) { showToast(translate("Please select a schedule time")); return; } - if(!this.selectedProductStoreId) { - showToast(translate("Please select product store")); + if(!this.schedule.productStoreId) { + showToast(translate("Please select a product store")); return; } - if(!this.selectedShopifyShopId) { - showToast(translate("Please select shopify shop")); + if(!this.schedule.shopId) { + showToast(translate("Please select a shopify shop")); return; } @@ -310,11 +298,11 @@ export default defineComponent({ await this.store.dispatch("stock/scheduleService", { params: { shipmentId: resp.data.shipmentId, - shopId: this.selectedShopifyShopId, - productStoreId: this.selectedProductStoreId + shopId: this.schedule.shopId, + productStoreId: this.schedule.productStoreId }, - restockName: this.restockName, - scheduledTime: this.scheduledTime, + restockName: this.schedule.restockName, + scheduledTime: this.schedule.scheduledTime, }) } else { throw resp.data; @@ -336,15 +324,14 @@ export default defineComponent({ }, selectAllItems() { for (const facilityId in this.parsedItems) { - this.parsedItems[facilityId].forEach(item => { - item.isSelected = true; - }); - } + this.parsedItems[facilityId].forEach(item => { + item.isSelected = true; + }); + } }, - areAnyItemsUnchecked() { return Object.values(this.parsedItems).some(facilityItems => - facilityItems.some(item => !item.isSelected)); + facilityItems.some(item => !item.isSelected)); }, searchProducts(query) { if (!query) { @@ -355,21 +342,21 @@ export default defineComponent({ for (const facilityId in this.originalItems) { filteredItems[facilityId] = this.originalItems[facilityId].filter(item => { return item.parentProductId.includes(query) || - item.productId.includes(query) || - item.parentProductName.toLowerCase().includes(query.toLowerCase()) || - item.identification.toLowerCase().includes(query.toLowerCase()); + item.productId.includes(query) || + item.parentProductName.toLowerCase().includes(query.toLowerCase()) || + item.identification.toLowerCase().includes(query.toLowerCase()); }); } const noItemsFound = !Object.values(filteredItems).some(items => items.length > 0); if(noItemsFound) { - showToast("No product found") + showToast(translate("No product found")) } this.parsedItems = filteredItems; }, updateProductStore(event) { - this.selectedShopifyShopId = '' - this.selectedProductStoreId = event.detail.value; - this.fetchShopifyShops(this.selectedProductStoreId); + this.schedule.shopId = '' + this.schedule.productStoreId = event.detail.value; + this.fetchShopifyShops(this.schedule.productStoreId); }, async fetchShopifyShops(productStoreId) { let shopifyShops = [] @@ -417,7 +404,6 @@ export default defineComponent({
{{ job.jobId }}
{{ job?.runtimeData?.shipmentId }}