Skip to content

Commit

Permalink
Fixed: changed code to handle error & refrectored(#285)
Browse files Browse the repository at this point in the history
  • Loading branch information
R-Sourabh committed May 30, 2024
1 parent faba737 commit 884e3d6
Show file tree
Hide file tree
Showing 7 changed files with 184 additions and 83 deletions.
2 changes: 1 addition & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@ VUE_APP_ALIAS={}
VUE_APP_MAPPING_TYPES={"PO": "PO_MAPPING_PREF","RSTINV": "INV_MAPPING_PREF","RSTSTK": "STK_MAPPING_PREF"}
VUE_APP_MAPPING_PO={"orderId": { "label": "Order ID", "required": true }, "productSku": { "label": "Shopify product SKU", "required": true },"orderDate": { "label": "Arrival date", "required": true }, "quantity": { "label": "Ordered quantity", "required": true }, "facility": { "label": "Facility ID", "required": true }}
VUE_APP_MAPPING_RSTINV={"productIdentification": { "label": "Product Identification", "required": true }, "quantity": { "label": "Quantity", "required": true }, "facility": { "label": "Facility ID", "required": true }}
VUE_APP_MAPPING_RSTSTK={"product": { "label": "Product", "required": true }, "facility": { "label": "Facility", "required": true }, "restockQuantity": { "label": "Restock quantity", "required": true }, "schedule": { "label": "Schedule", "required": false }, "shopifyStore": { "label": "Shopify store", "required": false }, "restockName": { "label": "Restock name", "required": false }}
VUE_APP_MAPPING_RSTSTK={"product": { "label": "Product", "required": true }, "facility": { "label": "Facility", "required": true }, "restockQuantity": { "label": "Restock quantity", "required": true }}
VUE_APP_DEFAULT_LOG_LEVEL="error"
VUE_APP_LOGIN_URL="http://launchpad.hotwax.io/login"
33 changes: 30 additions & 3 deletions src/components/ScheduledRestockPopover.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,31 @@
<ion-content>
<ion-list>
<ion-list-header>
jobname
{{ job.jobName || job.jobId }}
</ion-list-header>
<ion-item button>
Reschedule
</ion-item>
<ion-item button>
<ion-item button @click="cancelJob()" lines="none">
Cancel
</ion-item>
</ion-list>
</ion-content>
</template>

<script lang="ts">
import logger from "@/logger";
import { StockService } from "@/services/StockService";
import { hasError, showToast } from "@/utils";
import { translate } from "@hotwax/dxp-components";
import {
IonContent,
IonItem,
IonList,
IonListHeader
} from "@ionic/vue";
import { defineComponent } from "vue";
import { useStore } from "vuex";
export default defineComponent({
name: "ScheduledRestockPopover",
Expand All @@ -31,10 +36,32 @@ export default defineComponent({
IonList,
IonListHeader
},
props: ["job"],
methods: {
async cancelJob() {
let resp;
try {
resp = await StockService.cancelJob({
jobId: this.job.jobId
});
if (resp.status == 200 && !hasError(resp)) {
showToast(translate('Service updated successfully'))
await this.store.dispatch('stock/fetchJobs')
} else {
throw resp.data;
}
} catch (err) {
showToast(translate('Failed to cancel job'))
logger.error(err)
}
return resp;
},
},
setup() {
const store = useStore();
return {
store
}
},
});
Expand Down
20 changes: 19 additions & 1 deletion src/services/StockService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,25 @@ const fetchJobInformation = async (payload: any): Promise <any> => {
});
}

const updateJob = async (payload: any): Promise <any> => {
return api({
url: "service/updateJobSandbox",
method: "post",
data: payload
});
}

const cancelJob = async (payload: any): Promise <any> => {
return api({
url: "service/cancelScheduledJob",
method: "post",
data: payload
});
}

export const StockService = {
cancelJob,
scheduleJob,
fetchJobInformation
fetchJobInformation,
updateJob
}
2 changes: 1 addition & 1 deletion src/store/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ const state: any = {
}

const persistState = createPersistedState({
paths: ['user'],
paths: ['user', 'util.productStores'],
fetchBeforeUse: true
})

Expand Down
17 changes: 4 additions & 13 deletions src/store/modules/stock/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import { StockService } from "@/services/StockService";
import { translate } from "@hotwax/dxp-components";
import logger from "@/logger";
import { DateTime } from 'luxon'
import router from '@/router'

const actions: ActionTree<StockState, RootState> = {
async processUpdateStockItems ({ commit, rootGetters }, items) {
Expand Down Expand Up @@ -86,7 +85,7 @@ const actions: ActionTree<StockState, RootState> = {
}, {});
const facilityIds = externalFacilityIds.map((externalFacilityId: any) => facilityMapping[externalFacilityId]).filter((facilityId: any) => facilityId);

Check warning on line 86 in src/store/modules/stock/actions.ts

View workflow job for this annotation

GitHub Actions / call-workflow-in-another-repo / reusable_workflow_job (18.x)

'facilityIds' is assigned a value but never used

Check warning on line 86 in src/store/modules/stock/actions.ts

View workflow job for this annotation

GitHub Actions / call-workflow-in-another-repo / reusable_workflow_job (20.x)

'facilityIds' is assigned a value but never used
const cachedProducts = await store.dispatch("product/fetchProducts", payload);

const initial = items.map((item: any) => {
const product = cachedProducts[item.product];

Expand Down Expand Up @@ -127,7 +126,7 @@ const actions: ActionTree<StockState, RootState> = {

const payload = {
'JOB_NAME': restockName || state.schedule.restockName || `Created ${DateTime.now().toLocaleString(DateTime.DATETIME_MED)}`,
'SERVICE_NAME': "shipPackedOrders", // TODO: make dynamic
'SERVICE_NAME': job.serviceName,
'SERVICE_COUNT': '0',
'SERVICE_TEMP_EXPR': job.jobStatus,
'SERVICE_RUN_AS_SYSTEM':'Y',
Expand All @@ -137,7 +136,7 @@ const actions: ActionTree<StockState, RootState> = {
'maxRecurrenceCount': '-1',
'parentJobId': job.parentJobId,
'runAsUser': 'system', //default system, but empty in run now. TODO Need to remove this as we are using SERVICE_RUN_AS_SYSTEM, currently kept it for backward compatibility
'recurrenceTimeZone': this.state.user.current.userTimeZone,
'recurrenceTimeZone': this.state.user.current.usershipPackedOrdersTimeZone,
'createdByUserLogin': this.state.user.current.userLoginId,
'lastModifiedByUserLogin': this.state.user.current.userLoginId,
},
Expand All @@ -154,14 +153,6 @@ const actions: ActionTree<StockState, RootState> = {
resp = await StockService.scheduleJob({ ...payload });
if (resp.status == 200 && !hasError(resp)) {
showToast(translate('Service has been scheduled'));
// await dispatch('fetchJobs', {
// inputFields: {
// 'systemJobEnumId': payload.systemJobEnumId,
// 'systemJobEnumId_op': 'equals',
// },
// orderBy: "runTime ASC"
// })
router.push('/scheduled-restock')
} else {
showToast(translate('Something went wrong'))
}
Expand Down Expand Up @@ -256,4 +247,4 @@ const actions: ActionTree<StockState, RootState> = {
}
}

export default actions;
export default actions;
116 changes: 87 additions & 29 deletions src/views/ScheduledRestock.vue
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@
<ion-list>
<ion-list-header>{{ translate("Saved mappings") }}</ion-list-header>
<div>
<ion-chip outline @click="addFieldMapping()">
<ion-chip :disabled="!this.content.length" outline @click="addFieldMapping()">
<ion-icon :icon="addOutline" />
<ion-label>{{ translate("New mapping") }}</ion-label>
</ion-chip>
<ion-chip outline="true" v-for="(mapping, index) in fieldMappings('RSTSTK') ?? []" :key="index" @click="mapFields(mapping)">
<ion-chip :disabled="!this.content.length" outline="true" v-for="(mapping, index) in fieldMappings('RSTSTK') ?? []" :key="index" @click="mapFields(mapping)">
{{ mapping.name }}
</ion-chip>
</div>
Expand Down Expand Up @@ -81,24 +81,36 @@
</ion-item>
</ion-list>

<ion-button color="medium" expand="block" class="review" @click="review()">
<ion-button :disabled="!this.content.length" color="medium" expand="block" class="review" @click="review()">
{{ translate("Review") }}
<ion-icon slot="end" :icon="arrowForwardOutline" />
</ion-button>

<ion-list>
<ion-list v-if="jobs.length">
<ion-list-header>Scheduled Restock</ion-list-header>
<ion-item v-for="job in jobs" :key="job.jobId">
<ion-label>
<p class="overline">{{ job.jobId }}</p>
{{ job.jobName }}
<p>inbound</p>
</ion-label>
<ion-button color="light">{{ getTime(job.runTime) }}</ion-button>
<ion-button fill="clear" color="medium" @click="openScheduledRestockPopover($event)">
<ion-button color="light" @click="changeRunTime(job)">{{ getTime(job.runTime) }}</ion-button>
<ion-button fill="clear" color="medium" @click="openScheduledRestockPopover($event, job)">
<ion-icon slot="icon-only" :icon="ellipsisVerticalOutline" />
</ion-button>
</ion-button>
</ion-item>
<ion-modal class="date-time-modal" :is-open="isUpdateDateTimeModalOpen" @didDismiss="() => isUpdateDateTimeModalOpen = false">
<ion-content force-overscroll="false">
<ion-datetime
id="schedule-datetime"
show-default-buttons
hour-cycle="h23"
presentation="date-time"
:value="currentJob.runTime ? getDateTime(currentJob.runTime) : getDateTime(DateTime.now().toMillis())"
@ionChange="changeJobRunTime($event)"
/>
</ion-content>
</ion-modal>
</ion-list>

</main>
Expand All @@ -120,6 +132,7 @@ import CreateMappingModal from "@/components/CreateMappingModal.vue";
import { DateTime } from 'luxon';
import { UtilService } from '@/services/UtilService'
import logger from "@/logger";
import { StockService } from "@/services/StockService";
export default defineComponent({
name: "ScheduledRestock",
Expand Down Expand Up @@ -156,18 +169,24 @@ export default defineComponent({
shopifyShops: [],
restockName: '',
selectedProductStoreId: '',
selectedShopifyShopId: ''
selectedShopifyShopId: '',
isUpdateDateTimeModalOpen: false,
shopId: '',
currentJob: {}
}
},
computed: {
...mapGetters({
fieldMappings: 'user/getFieldMappings',
jobs: 'stock/getScheduledJobs',
productStores: 'util/getProductStores'
productStores: 'util/getProductStores',
userProfile: 'user/getUserProfile'
})
},
mixins:[ parseFileMixin ],
async ionViewDidEnter() {
this.selectedProductStoreId = ""
this.selectedShopifyShopId = ""
this.file = {}
this.content = []
this.fieldMapping = Object.keys(this.fields)?.reduce((fieldMapping, field) => {
Expand Down Expand Up @@ -204,6 +223,10 @@ export default defineComponent({
updateTime() {
this.isDateTimeModalOpen = true
},
changeRunTime(job) {
this.currentJob = job
this.isUpdateDateTimeModalOpen = true
},
getTime(time) {
return DateTime.fromMillis(time, { setZone: true}).toFormat("hh:mm a dd MMM yyyy")
},
Expand All @@ -216,6 +239,49 @@ export default defineComponent({
}
this.schedule = setTime;
},
changeJobRunTime(event) {
const currentTime = DateTime.now().toMillis();
const setTime = DateTime.fromISO(event.detail.value).toMillis();
if (setTime < currentTime) {
showToast('Please provide a future date and time');
return;
}
this.updateJob(setTime)
},
async updateJob(updatedTime) {
let resp;
const job = {
...this.currentJob,
runTime: updatedTime
}
const payload = {
'jobId': job.jobId,
'systemJobEnumId': job.systemJobEnumId,
'recurrenceTimeZone': this.userProfile.userTimeZone,
'tempExprId': job.jobStatus,
'statusId': "SERVICE_PENDING",
'runTimeEpoch': '', // when updating a job clearning the epoch time, as job honors epoch time as runTime and the new job created also uses epoch time as runTime
'lastModifiedByUserLogin': this.userProfile.userLoginId
}
job?.runTime && (payload['runTime'] = job.runTime)
job?.sinceId && (payload['sinceId'] = job.sinceId)
job?.jobName && (payload['jobName'] = job.jobName)
try {
resp = await StockService.updateJob(payload)
if (!hasError(resp) && resp.data.successMessage) {
await this.store.dispatch('stock/fetchJobs')
showToast(translate('Service updated successfully'))
} else {
throw resp.data
}
} catch (err) {
showToast(translate('Failed to update job'))
logger.error(err)
}
},
mapFields(mapping) {
const fieldMapping = JSON.parse(JSON.stringify(mapping));
Expand Down Expand Up @@ -251,29 +317,20 @@ export default defineComponent({
showToast(translate("Please upload a valid reset inventory csv to continue"));
}
},
async openScheduledRestockPopover(ev) {
async openScheduledRestockPopover(ev, job) {
const popover = await popoverController.create({
component: ScheduledRestockPopover,
event: ev,
translucent: true,
showBackdrop: false,
componentProps: { job }
});
return popover.present();
},
review() {
// const areAllFieldsSelected = Object.values(this.fieldMapping).every(field => field !== "");
// if (!areAllFieldsSelected) {
// showToast(translate("Select all the fields to continue"));
// return;
// }
if(!this.selectedProductStoreId) {
showToast(translate("Please select product store."));
return;
}
if(!this.selectedProductStoreId) {
showToast(translate("Please select shopify shop"));
async review() {
const areAllFieldsSelected = Object.values(this.fieldMapping).every(field => field !== "");
if (!areAllFieldsSelected) {
showToast(translate("Select all the fields to continue"));
return;
}
Expand All @@ -287,9 +344,8 @@ export default defineComponent({
}
})
console.log('this.schedule', this.schedule)
this.store.dispatch('stock/processUpdateRestockItems', restockItems);
this.store.dispatch('stock/scheduledStock', {
await this.store.dispatch('stock/processUpdateRestockItems', restockItems);
await this.store.dispatch('stock/scheduledStock', {
productStoreId: this.selectedProductStoreId,
shopId: this.selectedShopifyShopId,
restockName: this.restockName,
Expand All @@ -310,8 +366,10 @@ export default defineComponent({
this.selectedShopifyShopId = ''
this.selectedProductStoreId = event.detail.value;
this.fetchShopifyShops(this.selectedProductStoreId);
}
},
getDateTime(time) {
return DateTime.fromMillis(time).toISO()
},
},
setup() {
const router = useRouter();
Expand Down
Loading

0 comments on commit 884e3d6

Please sign in to comment.