Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implemented: support to exclude order and inventory filters when configure a route(#248) #262

Merged
merged 8 commits into from
Oct 15, 2024
4 changes: 2 additions & 2 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ VUE_APP_CACHE_MAX_AGE=3600
VUE_APP_VIEW_SIZE=10
VUE_APP_PERMISSION_ID=
VUE_APP_DEFAULT_LOG_LEVEL="error"
VUE_APP_RULE_ENUMS={"QUEUE":{"id":"OIP_QUEUE","code":"facilityId"},"SHIPPING_METHOD":{"id":"OIP_SHIP_METH_TYPE","code":"shipmentMethodTypeId"},"PRIORITY":{"id":"OIP_PRIORITY","code":"priority"},"PROMISE_DATE":{"id":"OIP_PROMISE_DATE","code":"promiseDaysCutoff"},"SALES_CHANNEL":{"id":"OIP_SALES_CHANNEL","code":"salesChannelEnumId"},"ORIGIN_FACILITY_GROUP":{"id":"OIP_ORIGIN_FAC_GRP","code":"originFacilityGroupId"},"SHIP_BY":{"id":"OSP_SHIP_BY","code":"shipBeforeDate"},"SHIP_AFTER":{"id":"OSP_SHIP_AFTER","code":"shipAfterDate"},"ORDER_DATE":{"id":"OSP_ORDER_DATE","code":"orderDate"},"SHIPPING_METHOD_SORT":{"id":"OSP_SHIP_METH","code":"deliveryDays"},"SORT_PRIORITY":{"id":"OSP_PRIORITY","code":"priority"}}
VUE_APP_RULE_FILTER_ENUMS={"FACILITY_GROUP":{"id":"IIP_FACILITY_GROUP","code":"facilityGroupId"},"PROXIMITY":{"id":"IIP_PROXIMITY","code":"distance"},"BRK_SAFETY_STOCK":{"id":"IIP_BRK_SFTY_STOCK","code":"brokeringSafetyStock"},"MEASUREMENT_SYSTEM":{"id":"IIP_MSMNT_SYSTEM","code":"measurementSystem"}, "SPLIT_ITEM_GROUP":{"id":"IIP_SPLIT_ITEM_GROUP","code":"splitOrderItemGroup"}, "FACILITY_ORDER_LIMIT": {"id":"IFP_IGNORE_ORD_FAC_LIMIT", "code":"ignoreFacilityOrderLimit"}}
VUE_APP_RULE_ENUMS={"QUEUE":{"id":"OIP_QUEUE","code":"facilityId"},"QUEUE_EXCLUDED":{"id":"OIP_QUEUE_EXCLUDED","code":"facilityId_excluded"},"SHIPPING_METHOD":{"id":"OIP_SHIP_METH_TYPE","code":"shipmentMethodTypeId"},"SHIPPING_METHOD_EXCLUDED":{"id":"OIP_SHIP_METH_TYPE_EXCLUDED","code":"shipmentMethodTypeId_excluded"},"PRIORITY":{"id":"OIP_PRIORITY","code":"priority"},"PRIORITY_EXCLUDED":{"id":"OIP_PRIORITY_EXCLUDED","code":"priority_excluded"},"PROMISE_DATE":{"id":"OIP_PROMISE_DATE","code":"promiseDaysCutoff"},"PROMISE_DATE_EXCLUDED":{"id":"OIP_PROMISE_DATE_EXCLUDED","code":"promiseDaysCutoff_excluded"},"SALES_CHANNEL":{"id":"OIP_SALES_CHANNEL","code":"salesChannelEnumId"},"SALES_CHANNEL_EXCLUDED":{"id":"OIP_SALES_CHANNEL_EXCLUDED","code":"salesChannelEnumId_excluded"},"ORIGIN_FACILITY_GROUP":{"id":"OIP_ORIGIN_FAC_GRP","code":"originFacilityGroupId"},"ORIGIN_FACILITY_GROUP_EXCLUDED":{"id":"OIP_ORIGIN_FAC_GRP_EXCLUDED","code":"originFacilityGroupId_excluded"},"SHIP_BY":{"id":"OSP_SHIP_BY","code":"shipBeforeDate"},"SHIP_AFTER":{"id":"OSP_SHIP_AFTER","code":"shipAfterDate"},"ORDER_DATE":{"id":"OSP_ORDER_DATE","code":"orderDate"},"SHIPPING_METHOD_SORT":{"id":"OSP_SHIP_METH","code":"deliveryDays"},"SORT_PRIORITY":{"id":"OSP_PRIORITY","code":"priority"}}
VUE_APP_RULE_FILTER_ENUMS={"FACILITY_GROUP":{"id":"IIP_FACILITY_GROUP","code":"facilityGroupId"},"FACILITY_GROUP_EXCLUDED":{"id":"IIP_FACILITY_GROUP_EXCLUDED","code":"facilityGroupId_excluded"},"PROXIMITY":{"id":"IIP_PROXIMITY","code":"distance"},"BRK_SAFETY_STOCK":{"id":"IIP_BRK_SFTY_STOCK","code":"brokeringSafetyStock"},"MEASUREMENT_SYSTEM":{"id":"IIP_MSMNT_SYSTEM","code":"measurementSystem"},"SPLIT_ITEM_GROUP":{"id":"IIP_SPLIT_ITEM_GROUP","code":"splitOrderItemGroup"}, "FACILITY_ORDER_LIMIT": {"id":"IFP_IGNORE_ORD_FAC_LIMIT", "code":"ignoreFacilityOrderLimit"}}
VUE_APP_RULE_SORT_ENUMS={"PROXIMITY":{"id":"ISP_PROXIMITY","code":"distance"},"INV_BALANCE":{"id":"ISP_INV_BAL","code":"inventoryForAllocation"},"CUSTOMER_SEQ":{"id":"ISP_CUST_SEQ","code":"facilitySequence"}}
VUE_APP_RULE_ACTION_ENUMS={"RM_AUTO_CANCEL_DATE":{"id":"ORA_RM_CANCEL_DATE","code":"RM_AUTO_CANCEL_DATE"},"AUTO_CANCEL_DAYS":{"id":"ORA_AUTO_CANCEL_DAYS","code":"ADD_AUTO_CANCEL_DATE"},"NEXT_RULE":{"id":"ORA_NEXT_RULE","code":"NEXT_RULE"},"MOVE_TO_QUEUE":{"id":"ORA_MV_TO_QUEUE","code":"MOVE_TO_QUEUE"}}
VUE_APP_CRON_EXPRESSIONS={"Every 5 minutes":"0 */5 * ? * *","Every 15 minutes":"0 */15 * ? * *","Every 30 minutes":"0 */30 * ? * *","Hourly":"0 0 * ? * *","Every six hours":"0 0 */6 ? * *","Every day at midnight":"0 0 0 * * ?"}
Expand Down
12 changes: 9 additions & 3 deletions src/components/AddInventoryFilterOptionsModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,18 @@
<div v-if="!enumerations.length" class="empty-state">
<p>{{ translate(`Failed to fetch ${props.label?.toLowerCase()} options`) }}</p>
</div>

<ion-list v-else>
<ion-item v-for="condition in enumerations" :key="condition.enumId">
<ion-checkbox :disabled="isConditionDisabled(condition.enumId)" :checked="isConditionOptionSelected(condition.enumCode)" @ionChange="addConditionOption(condition)">
<template v-if="isConditionDisabled(condition.enumId)">
{{ condition.description || condition.enumCode }}<br/>
<ion-label>{{ condition.description || condition.enumCode }}</ion-label>
<ion-note>{{ `Only applicable when ${dependentOptions[condition.enumId].label} is selected` }}</ion-note>
</template>
<template v-else-if="condition.enumCode.includes('_excluded')">
<ion-label>{{ condition.description || condition.enumCode }}</ion-label>
<ion-note color="danger">{{ translate("Excluded") }}</ion-note>
</template>
<template v-else>
{{ condition.description || condition.enumCode }}
</template>
Expand All @@ -36,7 +41,7 @@
</template>

<script setup lang="ts">
import { IonButton, IonButtons, IonCheckbox, IonContent, IonFab, IonFabButton, IonHeader, IonIcon, IonItem, IonList, IonNote, IonPage, IonTitle, IonToolbar, modalController } from "@ionic/vue";
import { IonButton, IonButtons, IonCheckbox, IonContent, IonFab, IonFabButton, IonHeader, IonIcon, IonItem, IonLabel, IonList, IonNote, IonPage, IonTitle, IonToolbar, modalController } from "@ionic/vue";
import { useStore } from "vuex";
import { computed, defineProps, onMounted, ref } from "vue";
import { saveOutline } from "ionicons/icons";
Expand Down Expand Up @@ -118,7 +123,8 @@ function addConditionOption(condition: any) {
conditionTypeEnumId: props.conditionTypeEnumId,
fieldName: condition.enumCode,
sequenceNum: Object.keys(inventoryRuleConditions.value).length && inventoryRuleConditions.value[Object.keys(inventoryRuleConditions.value)[Object.keys(inventoryRuleConditions.value).length - 1]]?.sequenceNum >= 0 ? inventoryRuleConditions.value[Object.keys(inventoryRuleConditions.value)[Object.keys(inventoryRuleConditions.value).length - 1]].sequenceNum + 5 : 0, // added check for `>= 0` as sequenceNum can be 0 which will result in again setting the new seqNum to 0
createdDate: DateTime.now().toMillis()
createdDate: DateTime.now().toMillis(),
operator: condition.enumCode.includes("_excluded") ? "not-equals" : ""
}

// Adding associatedEnum out of ternary, as we will always get the conditionTypeEnumId, as the filter will already handle that
Expand Down
26 changes: 23 additions & 3 deletions src/components/AddOrderRouteFilterOptions.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,22 @@
</ion-toolbar>
</ion-header>
<ion-content>
<ion-segment v-model="segmentSelected" v-if="conditionTypeEnumId === 'ENTCT_FILTER'">
<ion-segment-button value="included">
<ion-label>{{ translate("Include") }}</ion-label>
</ion-segment-button>
<ion-segment-button value="excluded">
<ion-label>{{ translate("Exclude") }}</ion-label>
</ion-segment-button>
</ion-segment>

<div v-if="!enums[props.parentEnumId]" class="empty-state">
<p>{{ translate(`Failed to fetch ${$props.label?.toLowerCase()} options`) }}</p>
</div>
<ion-list v-else>
<!-- Added this div as we need to hide ProductCategory option from filters, need to remove this once we add support for ProductCategory filter-->
<div v-for="sort in Object.values(enums[props.parentEnumId])" :key="sort.enumId">
<ion-item v-if="sort.enumId !== 'OIP_PROD_CATEGORY'">
<div v-for="sort in getOptions()" :key="sort.enumId">
<ion-item v-if="sort.enumId !== 'OIP_PROD_CATEGORY' && sort.enumId !== 'OIP_PROD_CATEGORY_EXCLUDED'">
<ion-checkbox :checked="isSortOptionSelected(sort.enumCode)" @ionChange="addSortOption(sort)">{{ sort.description || sort.enumCode }}</ion-checkbox>
</ion-item>
</div>
Expand All @@ -31,7 +40,7 @@
</template>

<script setup lang="ts">
import { IonButton, IonButtons, IonCheckbox, IonContent, IonFab, IonFabButton, IonHeader, IonIcon, IonItem, IonList, IonPage, IonTitle, IonToolbar, modalController } from "@ionic/vue";
import { IonButton, IonButtons, IonCheckbox, IonContent, IonFab, IonFabButton, IonHeader, IonIcon, IonItem, IonLabel, IonList, IonPage, IonSegment, IonSegmentButton, IonTitle, IonToolbar, modalController } from "@ionic/vue";
import { useStore } from "vuex";
import { computed, defineProps, onMounted, ref } from "vue";
import { saveOutline } from "ionicons/icons";
Expand Down Expand Up @@ -64,11 +73,22 @@ const props = defineProps({
})
let routingFilters = ref({}) as any
let areFiltersUpdated = ref(false)
let segmentSelected = ref("included")

onMounted(() => {
routingFilters.value = props.orderRoutingFilters ? JSON.parse(JSON.stringify(props.orderRoutingFilters)) : {}
})

function getOptions() {
if(props.conditionTypeEnumId === "ENTCT_FILTER") {
const excludeOptions = Object.values(enums.value[props.parentEnumId]).filter((enumeration: any) => enumeration.enumId.includes('_EXCLUDED'))
const includeOptions = Object.values(enums.value[props.parentEnumId]).filter((enumeration: any) => !enumeration.enumId.includes('_EXCLUDED'))
return segmentSelected.value === "excluded" ? excludeOptions : includeOptions
}

return Object.values(enums.value[props.parentEnumId])
}

function checkFilters() {
areFiltersUpdated.value = false;
areFiltersUpdated.value = Object.keys(routingFilters.value).some((options: string) => {
Expand Down
5 changes: 3 additions & 2 deletions src/components/GroupActionsPopover.vue
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,13 @@ async function updateGroupStatus(paused: string) {
let routingGroups = [];
const payload = {
routingGroupId: props.group.routingGroupId,
paused
paused,
cronExpression: props.group.schedule?.cronExpression || "0 0 0 * * ?"
}

try {
const resp = await OrderRoutingService.scheduleBrokering(payload)
if(!hasError(resp)){
if(!hasError(resp)) {
showToast(translate("Group status updated"))
routingGroups = await store.dispatch("orderRouting/updateGroupStatus", { routingGroupId: props.group.routingGroupId, value: paused })
} else {
Expand Down
3 changes: 3 additions & 0 deletions src/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@
"Edit": "Edit",
"Enter a valid value": "Enter a valid value",
"Error getting user profile": "Error getting user profile",
"Exclude": "Exclude",
"Excluded": "Excluded",
"Execution history": "Execution history",
"Expression": "Expression",
"Facilities will be sorted based on creation date if no sorting preferences are applied.": "Facilities will be sorted based on creation date if no sorting preferences are applied.",
Expand Down Expand Up @@ -75,6 +77,7 @@
"greater": "greater",
"greater than or equal to": "greater than or equal to",
"High": "High",
"Include": "Include",
"Inventory Filters": "Inventory Filters",
"Inventory rule created successfully": "Inventory rule created successfully",
"Inventory Sort": "Inventory Sort",
Expand Down
14 changes: 14 additions & 0 deletions src/store/modules/orderRouting/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,15 @@

if(!hasError(resp) && resp.data) {
currentRoute = resp.data

if(currentRoute["orderFilters"]?.length) {
currentRoute["orderFilters"].map((filter: any) => {
if(filter.operator === "not-equals" || filter.operator === "not-in") {
filter.fieldName += "_excluded"
}
})
}

currentRoute["rules"] = currentRoute["rules"]?.length ? sortSequence(currentRoute["rules"]) : []
} else {
throw resp.data
Expand Down Expand Up @@ -244,7 +253,7 @@
commit(types.ORDER_ROUTING_HISTORY_UPDATED, routingHistory)
},

async deleteRoutingFilters({ dispatch }, payload) {

Check warning on line 256 in src/store/modules/orderRouting/actions.ts

View workflow job for this annotation

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

'dispatch' is defined but never used

Check warning on line 256 in src/store/modules/orderRouting/actions.ts

View workflow job for this annotation

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

'dispatch' is defined but never used
let hasAllFiltersDeletedSuccessfully = true;
try {
// As discussed, we can't make parallel api calls, hence using for loop to make api calls
Expand All @@ -264,7 +273,7 @@
return hasAllFiltersDeletedSuccessfully
},

async updateRouting({ dispatch }, payload) {

Check warning on line 276 in src/store/modules/orderRouting/actions.ts

View workflow job for this annotation

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

'dispatch' is defined but never used

Check warning on line 276 in src/store/modules/orderRouting/actions.ts

View workflow job for this annotation

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

'dispatch' is defined but never used
let orderRoutingId = ''
try {
const resp = await OrderRoutingService.updateRouting(payload)
Expand Down Expand Up @@ -315,7 +324,7 @@
return routingRuleId;
},

async deleteRuleConditions({ dispatch }, payload) {

Check warning on line 327 in src/store/modules/orderRouting/actions.ts

View workflow job for this annotation

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

'dispatch' is defined but never used

Check warning on line 327 in src/store/modules/orderRouting/actions.ts

View workflow job for this annotation

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

'dispatch' is defined but never used
// TODO: check if we can call request in parallel for delete operation
let hasAllConditionsDeletedSuccessfully = true;
try {
Expand All @@ -335,7 +344,7 @@
return hasAllConditionsDeletedSuccessfully
},

async deleteRuleActions({ dispatch }, payload) {

Check warning on line 347 in src/store/modules/orderRouting/actions.ts

View workflow job for this annotation

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

'dispatch' is defined but never used

Check warning on line 347 in src/store/modules/orderRouting/actions.ts

View workflow job for this annotation

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

'dispatch' is defined but never used
// TODO: check if we can call request in parallel for delete operation
let hasAllActionsDeletedSuccessfully = true;
try {
Expand Down Expand Up @@ -372,6 +381,11 @@

if(rulesInformation[routingRuleId]["inventoryFilters"]?.length) {
rulesInformation[routingRuleId]["inventoryFilters"] = sortSequence(rulesInformation[routingRuleId]["inventoryFilters"]).reduce((filters: any, filter: any) => {

if(filter.operator === "not-equals") {
filter.fieldName += "_excluded"
}

if(filters[filter.conditionTypeEnumId]) {
filters[filter.conditionTypeEnumId][filter.fieldName] = filter
} else {
Expand All @@ -398,7 +412,7 @@
return rulesInformation[routingRuleId] ? JSON.parse(JSON.stringify(rulesInformation[routingRuleId])) : {}
},

async updateRule({ dispatch }, payload) {

Check warning on line 415 in src/store/modules/orderRouting/actions.ts

View workflow job for this annotation

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

'dispatch' is defined but never used

Check warning on line 415 in src/store/modules/orderRouting/actions.ts

View workflow job for this annotation

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

'dispatch' is defined but never used
let routingRuleId = ''
try {
const resp = await OrderRoutingService.updateRule(payload)
Expand Down
24 changes: 24 additions & 0 deletions src/store/modules/util/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,30 @@ const actions: ActionTree<UtilState, RootState> = {
}
return enumerations
}, enums)

if(enums["ORD_FILTER_PRM_TYPE"]) {
Object.values(enums["ORD_FILTER_PRM_TYPE"]).reduce((filters: any, filter: any) => {
filters[filter.enumId + "_EXCLUDED"] = {
"enumId": filter.enumId + "_EXCLUDED",
"enumTypeId": filter.enumTypeId,
"enumCode": filter.enumCode + "_excluded",
"sequenceNum": 5,
"description": filter.description
}

return filters;
}, enums["ORD_FILTER_PRM_TYPE"])
}

if(enums["INV_FILTER_PRM_TYPE"] && enums["INV_FILTER_PRM_TYPE"]["IIP_FACILITY_GROUP"]) {
enums["INV_FILTER_PRM_TYPE"]["IIP_FACILITY_GROUP_EXCLUDED"] = {
"enumId": "IIP_FACILITY_GROUP_EXCLUDED",
"enumTypeId": "INV_FILTER_PRM_TYPE",
"enumCode": "facilityGroupId_excluded",
"sequenceNum": 5,
"description": "Facility group"
} as any
}
}
} catch(err) {
logger.error(err)
Expand Down
Loading
Loading