Skip to content

Commit

Permalink
Merge pull request #826 from amansinghbais/#813
Browse files Browse the repository at this point in the history
Implemented: support to hide reasons from the fulfillment app rejection reasons, and showing all reasons in case of admin (#813)
  • Loading branch information
ravilodhi authored Nov 13, 2024
2 parents a5f888b + 1436050 commit 5604b2f
Show file tree
Hide file tree
Showing 11 changed files with 153 additions and 16 deletions.
6 changes: 3 additions & 3 deletions src/components/ReportIssuePopover.vue
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<template>
<ion-content>
<ion-list>
<ion-item v-for="reason in rejectReasons" :key="reason.enumId" @click="updateIssue(reason.enumId)" button>
{{ reason.description ? translate(reason.description) : reason.enumId }}
<ion-item v-for="reason in rejectReasonOptions" :key="reason.enumId" @click="updateIssue(reason.enumId)" button>
{{ reason.description ? translate(reason.description) : reason.enumDescription ? translate(reason.enumDescription) : reason.enumId }}
</ion-item>
</ion-list>
</ion-content>
Expand All @@ -28,7 +28,7 @@ export default defineComponent({
},
computed: {
...mapGetters({
rejectReasons: 'util/getRejectReasons'
rejectReasonOptions: 'util/getRejectReasonOptions'
})
},
props: ["shipmentPackages"],
Expand Down
27 changes: 27 additions & 0 deletions src/services/UtilService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -586,6 +586,30 @@ const activateGiftCard = async (payload: any): Promise<any> => {
});
}

const fetchFulfillmentRejectReasons = async (payload: any): Promise<any> => {
return api({
url: "performFind",
method: "post",
data: payload
});
}

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

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

const isEnumExists = async (enumId: string): Promise<any> => {
try {
const resp = await api({
Expand Down Expand Up @@ -614,6 +638,7 @@ const isEnumExists = async (enumId: string): Promise<any> => {
export const UtilService = {
activateGiftCard,
createBarcodeIdentificationPref,
createEnumerationGroupMember,
createForceScanSetting,
createPicklist,
createEnumeration,
Expand All @@ -622,6 +647,7 @@ export const UtilService = {
fetchEnumeration,
fetchFacilities,
fetchFacilityTypeInformation,
fetchFulfillmentRejectReasons,
fetchGiftCardFulfillmentInfo,
fetchGiftCardItemPriceInfo,
fetchPartyInformation,
Expand Down Expand Up @@ -651,5 +677,6 @@ export const UtilService = {
deleteEnumeration,
updateEnumeration,
updateBarcodeIdentificationPref,
updateEnumerationGroupMember,
updateForceScanSetting
}
2 changes: 2 additions & 0 deletions src/store/modules/util/UtilState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,7 @@ export default interface UtilState {
facilities: any;
shipmentGatewayConfigs: any;
isForceScanEnabled: boolean;
fulfillmentRejectReasons: any;
rejectReasonOptions: any;
barcodeIdentificationPref: string;
}
47 changes: 47 additions & 0 deletions src/store/modules/util/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,53 @@ const actions: ActionTree<UtilState, RootState> = {

commit(types.UTIL_REJECT_REASONS_UPDATED, rejectReasons)
},

async fetchRejectReasonOptions({ commit, dispatch, state }) {
const permissions = store.getters['user/getUserPermissions'];

const isAdminUser = permissions.some((permission: any) => permission.action === "APP_STOREFULFILLMENT_ADMIN")
const isApiSuccess = isAdminUser ? await dispatch("fetchRejectReasons") : await dispatch("fetchFulfillmentRejectReasons")

commit(types.UTIL_REJECT_REASON_OPTIONS_UPDATED, ((!isAdminUser && isApiSuccess) ? Object.values(state.fulfillmentRejectReasons) : state.rejectReasons ));
},

async fetchFulfillmentRejectReasons({ commit, dispatch }) {
let isApiSuccess = true;
const fulfillmentRejectReasons = {} as any;
try {
const payload = {
"inputFields": {
"enumerationGroupId": "FF_REJ_RSN_GRP"
},
// We shouldn't fetch description here, as description contains EnumGroup description which we don't wanna show on UI.
"fieldList": ["enumerationGroupId", "enumId", "fromDate", "sequenceNum", "enumDescription", "enumName"],
"distinct": "Y",
"entityName": "EnumerationGroupAndMember",
"viewSize": 200,
"filterByDate": "Y",
"orderBy": "sequenceNum"
}

const resp = await UtilService.fetchFulfillmentRejectReasons(payload)

if(!hasError(resp)) {
resp.data.docs.map((reason: any) => {
fulfillmentRejectReasons[reason.enumId] = reason
})
} else {
throw resp.data
}
} catch (err) {
logger.error('Failed to fetch fulfillment reject reasons', err)
// Fetching all rejection reasons if the api fails due to no entity found.
// Todo: remove this once all the oms are updated.
await dispatch("fetchRejectReasons");
isApiSuccess = false;
}

commit(types.UTIL_FULFILLMENT_REJECT_REASONS_UPDATED, fulfillmentRejectReasons)
return isApiSuccess
},

async fetchPartyInformation({ commit, state }, partyIds) {
let partyInformation = JSON.parse(JSON.stringify(state.partyNames))
Expand Down
6 changes: 6 additions & 0 deletions src/store/modules/util/getters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,12 @@ const getters: GetterTree <UtilState, RootState> = {
isForceScanEnabled(state) {
return state.isForceScanEnabled
},
getFulfillmentRejectReasons(state) {
return state.fulfillmentRejectReasons
},
getRejectReasonOptions(state) {
return state.rejectReasonOptions
},
getBarcodeIdentificationPref(state) {
return state.barcodeIdentificationPref
}
Expand Down
2 changes: 2 additions & 0 deletions src/store/modules/util/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ const utilModule: Module<UtilState, RootState> = {
facilities: [],
shipmentGatewayConfigs: [],
isForceScanEnabled: false,
fulfillmentRejectReasons: {},
rejectReasonOptions: [],
barcodeIdentificationPref: "internalName"
},
getters,
Expand Down
2 changes: 2 additions & 0 deletions src/store/modules/util/mutation-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,6 @@ export const UTIL_FACILITIES_UPDATED = SN_UTIL + '/FACILITIES_UPDATED'
export const UTIL_PRODUCT_STORES_UPDATED = SN_UTIL + '/PRODUCT_STORES_UPDATED'
export const UTIL_SHIPMENT_GATEWAY_CONFIGS_UPDATED = SN_UTIL + '/SHIPMENT_GATEWAY_CONFIGS_UPDATED'
export const UTIL_FORCE_SCAN_STATUS_UPDATED = SN_UTIL + '/FORCE_SCAN_STATUS_UPDATED'
export const UTIL_FULFILLMENT_REJECT_REASONS_UPDATED = SN_UTIL + '/FULFILLMENT_REJECT_REASONS_UPDATED'
export const UTIL_REJECT_REASON_OPTIONS_UPDATED = SN_UTIL + '/REJECT_REASON_OPTIONS_UPDATED'
export const UTIL_BARCODE_IDENTIFICATION_PREF_UPDATED = SN_UTIL + '/BARCODE_IDENTIFICATION_PREF_UPDATED'
6 changes: 6 additions & 0 deletions src/store/modules/util/mutations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,12 @@ const mutations: MutationTree <UtilState> = {
[types.UTIL_FORCE_SCAN_STATUS_UPDATED](state, payload) {
state.isForceScanEnabled = payload
},
[types.UTIL_FULFILLMENT_REJECT_REASONS_UPDATED](state, payload) {
state.fulfillmentRejectReasons = payload
},
[types.UTIL_REJECT_REASON_OPTIONS_UPDATED](state, payload) {
state.rejectReasonOptions = payload
},
[types.UTIL_BARCODE_IDENTIFICATION_PREF_UPDATED](state, payload) {
state.barcodeIdentificationPref = payload
}
Expand Down
8 changes: 4 additions & 4 deletions src/views/InProgress.vue
Original file line number Diff line number Diff line change
Expand Up @@ -359,7 +359,7 @@ export default defineComponent({
currentFacility: 'user/getCurrentFacility',
inProgressOrders: 'order/getInProgressOrders',
getProduct: 'product/getProduct',
rejectReasons: 'util/getRejectReasons',
rejectReasonOptions: 'util/getRejectReasonOptions',
currentEComStore: 'user/getCurrentEComStore',
userPreference: 'user/getUserPreference',
boxTypeDesc: 'util/getShipmentBoxDesc',
Expand Down Expand Up @@ -389,7 +389,7 @@ export default defineComponent({
},
methods: {
getRejectionReasonDescription (rejectionReasonId: string) {
return this.rejectReasons?.find((reason: any) => reason.enumId === rejectionReasonId)?.description;
return this.rejectReasonOptions?.find((reason: any) => reason.enumId === rejectionReasonId)?.description;
},
async openRejectReasonPopover(ev: Event, item: any, order: any) {
const reportIssuePopover = await popoverController.create({
Expand Down Expand Up @@ -692,7 +692,7 @@ export default defineComponent({
// This variable is used in messages to display name of first rejected item from the itemsToReject array
const rejectedItem = itemsToReject[0];
if (itemsToReject.length === 1) {
message = translate('is identified as. This order item will be unassigned from the store and sent to be rebrokered.', { productName: rejectedItem.productName, rejectReason: ((this.rejectReasons.find((rejectReason: {[key: string]: any}) => rejectReason.enumId === rejectedItem.rejectReason)).description).toLowerCase() });
message = translate('is identified as. This order item will be unassigned from the store and sent to be rebrokered.', { productName: rejectedItem.productName, rejectReason: ((this.rejectReasonOptions.find((rejectReason: {[key: string]: any}) => rejectReason.enumId === rejectedItem.rejectReason)).description).toLowerCase() });
} else {
message = translate(', and other products were identified as unfulfillable. These items will be unassigned from this store and sent to be rebrokered.', { productName: rejectedItem.productName, products: itemsToReject.length - 1, space: '<br /><br />' });
}
Expand Down Expand Up @@ -1315,7 +1315,7 @@ export default defineComponent({
}
},
async mounted () {
this.store.dispatch('util/fetchRejectReasons')
this.store.dispatch('util/fetchRejectReasonOptions')
await Promise.all([this.fetchPickersInformation(), this.initialiseOrderQuery()])
emitter.on('updateOrderQuery', this.updateOrderQuery)
},
Expand Down
8 changes: 4 additions & 4 deletions src/views/OrderDetail.vue
Original file line number Diff line number Diff line change
Expand Up @@ -507,7 +507,7 @@ export default defineComponent({
getProductStock: 'stock/getProductStock',
inProgressOrders: 'order/getInProgressOrders',
order: "order/getCurrent",
rejectReasons: 'util/getRejectReasons',
rejectReasonOptions: 'util/getRejectReasonOptions',
userPreference: 'user/getUserPreference',
getPartyName: 'util/getPartyName',
getfacilityTypeDesc: 'util/getFacilityTypeDesc',
Expand Down Expand Up @@ -553,7 +553,7 @@ export default defineComponent({
}
},
async ionViewDidEnter() {
this.store.dispatch('util/fetchRejectReasons')
this.store.dispatch('util/fetchRejectReasonOptions')
this.category === 'open'
? await this.store.dispatch('order/getOpenOrder', { orderId: this.orderId, shipGroupSeqId: this.shipGroupSeqId })
: this.category === 'in-progress'
Expand Down Expand Up @@ -683,7 +683,7 @@ export default defineComponent({
}
},
getRejectionReasonDescription (rejectionReasonId: string) {
return this.rejectReasons?.find((reason: any) => reason.enumId === rejectionReasonId)?.description;
return this.rejectReasonOptions?.find((reason: any) => reason.enumId === rejectionReasonId)?.description;
},
isEntierOrderRejectionEnabled(order: any) {
return (!this.partialOrderRejectionConfig || !this.partialOrderRejectionConfig.settingValue || !JSON.parse(this.partialOrderRejectionConfig.settingValue)) && order.hasRejectedItem
Expand Down Expand Up @@ -1342,7 +1342,7 @@ export default defineComponent({
// This variable is used in messages to display name of first rejected item from the itemsToReject array
const rejectedItem = itemsToReject[0];
if (itemsToReject.length === 1) {
message = translate('is identified as. This order item will be unassigned from the store and sent to be rebrokered.', { productName: rejectedItem.productName, rejectReason: ((this.rejectReasons.find((rejectReason: {[key: string]: any}) => rejectReason.enumId === rejectedItem.rejectReason)).description).toLowerCase() });
message = translate('is identified as. This order item will be unassigned from the store and sent to be rebrokered.', { productName: rejectedItem.productName, rejectReason: ((this.rejectReasonOptions.find((rejectReason: {[key: string]: any}) => rejectReason.enumId === rejectedItem.rejectReason)).description).toLowerCase() });
} else {
message = translate(', and other products were identified as unfulfillable. These items will be unassigned from this store and sent to be rebrokered.', { productName: rejectedItem.productName, products: itemsToReject.length - 1, space: '<br /><br />' });
}
Expand Down
55 changes: 50 additions & 5 deletions src/views/RejectionReasons.vue
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,11 @@
<ion-icon :icon="caretDownOutline" />
</ion-chip>
</div>


<div class="tablet">
<ion-toggle :checked="fulfillmentRejectReasons[reason.enumId]" @click.prevent="updateFulfillmentRejectReasonAssocStatus($event, reason)" />
</div>

<ion-reorder />

<ion-button fill="clear" color="medium" @click="openRejectionReasonActionsPopover($event, reason)">
Expand Down Expand Up @@ -63,6 +67,7 @@ import {
IonReorder,
IonReorderGroup,
IonTitle,
IonToggle,
IonToolbar,
alertController,
modalController,
Expand All @@ -77,6 +82,9 @@ import VarianceTypeActionsPopover from '@/components/VarianceTypeActionsPopover.
import { mapGetters, useStore } from 'vuex';
import { UtilService } from '@/services/UtilService';
import { showToast } from '@/utils';
import { DateTime } from 'luxon';
import { hasError } from '@hotwax/oms-api';
import logger from '@/logger';
export default defineComponent({
name: 'RejectionReasons',
Expand All @@ -94,22 +102,24 @@ export default defineComponent({
IonReorder,
IonReorderGroup,
IonTitle,
IonToggle,
IonToolbar,
},
data() {
return {
filteredReasons: [],
filteredReasons: [] as any,
toast: null as any
}
},
computed: {
...mapGetters({
rejectReasons: 'util/getRejectReasons',
rejectReasonEnumTypes: 'util/getRejectReasonEnumTypes',
fulfillmentRejectReasons: 'util/getFulfillmentRejectReasons'
})
},
async ionViewWillEnter() {
await Promise.all([this.store.dispatch('util/fetchRejectReasons'), this.store.dispatch('util/fetchRejectReasonEnumTypes')])
await Promise.all([this.store.dispatch('util/fetchRejectReasons'), this.store.dispatch('util/fetchFulfillmentRejectReasons'), this.store.dispatch('util/fetchRejectReasonEnumTypes')])
this.filteredReasons = this.rejectReasons ? JSON.parse(JSON.stringify(this.rejectReasons)) : []
},
async beforeRouteLeave() {
Expand Down Expand Up @@ -240,7 +250,42 @@ export default defineComponent({
} else {
showToast(translate("Sequence for rejection reasons updated successfully."))
}
}
},
async updateFulfillmentRejectReasonAssocStatus(event: any, reason: any) {
event.stopImmediatePropagation();
let resp;
const payload = {
enumerationId: reason.enumId,
enumerationGroupId: "FF_REJ_RSN_GRP",
sequenceNum: reason.sequenceNum
}
try {
if(this.fulfillmentRejectReasons[reason.enumId]?.fromDate) {
resp = await UtilService.updateEnumerationGroupMember({
...payload,
fromDate: this.fulfillmentRejectReasons[reason.enumId]?.fromDate,
thruDate: DateTime.now().toMillis()
})
} else {
resp = await UtilService.createEnumerationGroupMember({
...payload,
fromDate: DateTime.now().toMillis()
})
}
if(!hasError(resp)) {
await this.store.dispatch("util/fetchFulfillmentRejectReasons");
} else {
throw resp.data;
}
} catch(error: any) {
logger.error(error);
showToast(translate("Failed to update reason association with fulfillment group."))
}
},
},
setup() {
const store = useStore()
Expand All @@ -258,7 +303,7 @@ export default defineComponent({

<style scoped>
.list-item {
--columns-desktop: 4;
--columns-desktop: 5;
}
.list-item:hover {
Expand Down

0 comments on commit 5604b2f

Please sign in to comment.