Skip to content

Commit

Permalink
Merge pull request #212 from amansinghbais/210-link-group-to-store
Browse files Browse the repository at this point in the history
Implemented: logic to link group to product stores (#210)
  • Loading branch information
ymaheshwari1 authored Mar 7, 2024
2 parents 51fb7d8 + fac7109 commit 29da01c
Show file tree
Hide file tree
Showing 5 changed files with 293 additions and 3 deletions.
182 changes: 182 additions & 0 deletions src/components/AddProductStoreToGroupModal.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
<template>
<ion-header>
<ion-toolbar>
<ion-buttons slot="start">
<ion-button @click="closeModal">
<ion-icon slot="icon-only" :icon="closeOutline" />
</ion-button>
</ion-buttons>
<ion-title>{{ translate("Product stores") }}</ion-title>
</ion-toolbar>
</ion-header>

<ion-content>
<ion-list>
<ion-item v-for="productStore in productStores" :key="productStore.productStoreId" @click="toggleProductStoreSelection(productStore)" >
<ion-label>
{{ productStore.storeName }}
<p>{{ productStore.productStoreId }}</p>
</ion-label>
<ion-checkbox :checked="isSelected(productStore.productStoreId)" slot="end" />
</ion-item>
</ion-list>
<ion-fab vertical="bottom" horizontal="end" slot="fixed">
<ion-fab-button :disabled="!areProductStoresUpdated()" @click="saveProductStores()">
<ion-icon :icon="saveOutline" />
</ion-fab-button>
</ion-fab>
</ion-content>
</template>

<script lang="ts">
import {
IonButton,
IonButtons,
IonCheckbox,
IonContent,
IonFab,
IonFabButton,
IonHeader,
IonIcon,
IonItem,
IonLabel,
IonList,
IonTitle,
IonToolbar,
modalController
} from "@ionic/vue";
import { defineComponent } from "vue";
import { closeOutline, saveOutline } from "ionicons/icons";
import { translate } from '@hotwax/dxp-components'
import { mapGetters, useStore } from "vuex";
import { FacilityService } from "@/services/FacilityService";
import logger from "@/logger";
import { hasError } from "@/adapter";
import { showToast } from "@/utils";
import { DateTime } from "luxon";
export default defineComponent({
name: "AddProductStoreToGroupModal",
components: {
IonButton,
IonButtons,
IonCheckbox,
IonContent,
IonFab,
IonFabButton,
IonHeader,
IonIcon,
IonItem,
IonLabel,
IonList,
IonTitle,
IonToolbar
},
props: ["group"],
computed: {
...mapGetters({
productStores: 'util/getProductStores',
facilityProductStores: 'facility/getFacilityProductStores',
groups: "facility/getFacilityGroups"
})
},
data() {
return {
selectedProductStores: [],
selectedProductStoreValues: [] as any
}
},
async mounted() {
await this.store.dispatch('util/fetchProductStores')
this.fetchGroupProductStores()
},
methods: {
closeModal() {
modalController.dismiss({ dismissed: true});
},
async fetchGroupProductStores() {
try {
const resp = await FacilityService.fetchAssociatedProductStoresToGroup({
"inputFields": {
"facilityGroupId": this.group.facilityGroupId
},
"viewSize": 250, // maximum view size
"entityName": 'ProductStoreFacilityGroup',
"noConditionFind": "Y",
"filterByDate": 'Y'
})
if(!hasError(resp)) {
this.selectedProductStores = resp.data.docs
this.selectedProductStoreValues = JSON.parse(JSON.stringify(resp.data.docs))
} else {
throw resp.data
}
} catch(err) {
logger.error(err)
}
},
isSelected(productStoreId: any) {
return this.selectedProductStoreValues.some((productStore: any) => productStore.productStoreId === productStoreId);
},
toggleProductStoreSelection(store: any) {
if(this.isSelected(store.productStoreId)) {
this.selectedProductStoreValues = this.selectedProductStoreValues.filter((productStore: any) => productStore.productStoreId !== store.productStoreId);
} else {
this.selectedProductStoreValues.push(store);
}
},
async saveProductStores() {
const productStoresToAdd = this.selectedProductStoreValues.filter((selectedStore: any) => !this.selectedProductStores.some((store: any) => store.productStoreId === selectedStore.productStoreId))
const productStoresToRemove = this.selectedProductStores.filter((store: any) => !this.selectedProductStoreValues.some((selectedStore: any) => store.productStoreId === selectedStore.productStoreId))
const removeResponses = await Promise.allSettled(productStoresToRemove
.map(async (store: any) => await FacilityService.updateProductStoreFacilityGroup({
"productStoreId": store.productStoreId,
"facilityGroupId": this.group.facilityGroupId,
"fromDate": store.fromDate,
"thruDate": DateTime.now().toMillis()
}))
)
const addResponses = await Promise.allSettled(productStoresToAdd
.map(async (store: any) => await FacilityService.createProductStoreFacilityGroup({
"productStoreId": store.productStoreId,
"facilityGroupId": this.group.facilityGroupId,
"fromDate": DateTime.now().toMillis()
}))
)
const hasFailedResponse = [...removeResponses, ...addResponses].some((response: any) => response.status === 'rejected')
if (hasFailedResponse) {
showToast(translate("Failed to associate some product stores to group."))
} else {
showToast(translate("Product stores associated to group successfully."))
}
this.fetchGroupsCount()
modalController.dismiss()
},
async fetchGroupsCount() {
const productStoreCountByGroup = await FacilityService.fetchProductStoreCountByGroup([this.group.facilityGroupId])
const currentGroup = this.groups.find((group: any) => group.facilityGroupId === this.group.facilityGroupId)
currentGroup.productStoreCount = productStoreCountByGroup[this.group.facilityGroupId]
await this.store.dispatch('facility/updateFacilityGroups', this.groups)
},
areProductStoresUpdated() {
return JSON.stringify(this.selectedProductStoreValues) !== JSON.stringify(this.selectedProductStores)
}
},
setup() {
const store = useStore()
return {
closeOutline,
saveOutline,
store,
translate
};
},
});
</script>

1 change: 1 addition & 0 deletions src/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,7 @@
"primary store": "primary store",
"Product Store": "Product Store",
"Product Stores": "Product Stores",
"Product stores": "Product stores",
"Product stores updated successfully.": "Product stores updated successfully.",
"Quick edit": "Quick edit",
"Reason:": "Reason:",
Expand Down
83 changes: 82 additions & 1 deletion src/services/FacilityService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -560,7 +560,8 @@ const fetchFacilityCountByGroup = async (facilityGroupIds: any): Promise<any> =>
const batch = facilityGroupIdList.splice(0, 10)
const params = {
inputFields: {
facilityGroupId: batch
facilityGroupId: batch,
facilityGroupId_op: "in"
},
viewSize: 250, // maximum view size
entityName: 'FacilityGroupAndMember',
Expand Down Expand Up @@ -601,6 +602,58 @@ const fetchFacilityCountByGroup = async (facilityGroupIds: any): Promise<any> =>
}, {})
}

const fetchProductStoreCountByGroup = async (facilityGroupIds: Array<string>): Promise<any> => {
if (!facilityGroupIds.length) return {}
const requests = []

const facilityGroupIdList = facilityGroupIds
while (facilityGroupIdList.length) {
const batch = facilityGroupIdList.splice(0, 10)
const params = {
inputFields: {
facilityGroupId: batch,
facilityGroupId_op: "in"
},
viewSize: 250, // maximum view size
entityName: 'ProductStoreFacilityGroup',
noConditionFind: "Y",
filterByDate: 'Y',
fieldList: ['facilityGroupId', 'productStoreId']
}
requests.push(params)
}

const productStoreCountResponse = await Promise.allSettled(requests.map((params) => api({
url: 'performFind',
method: 'POST',
data: params
})))

const hasFailedResponse = productStoreCountResponse.some((response: any) => hasError(response.value) && !response?.data?.count)

if (hasFailedResponse) {
logger.error('Failed to fetch product store count for some groups')
}

// taking out the response from Promise.allSettled's 'value' field first
const allResponseData = productStoreCountResponse.map((response: any) => response.value)
.reduce((responseData: any, response: any) => {
if (!hasError(response)) {
responseData.push(...response.data.docs)
}
return responseData
}, [])

return allResponseData.reduce((productStoreCountByGroup: any, responseData: any) => {
if (productStoreCountByGroup[responseData.facilityGroupId]) {
productStoreCountByGroup[responseData.facilityGroupId] += 1
} else {
productStoreCountByGroup[responseData.facilityGroupId] = 1
}
return productStoreCountByGroup
}, {})
}

const updateFacilityGroup = async (payload: any): Promise<any> => {
return api({
url: "service/updateFacilityGroup",
Expand Down Expand Up @@ -701,6 +754,14 @@ const fetchAssociatedFacilitiesToGroup = async (payload: any): Promise<any> => {
})
}

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

const createFacilityTelecomNumber = async (payload: any): Promise<any> => {
return api({
url: "service/createFacilityTelecomNumber",
Expand All @@ -717,6 +778,22 @@ const updateFacilityTelecomNumber = async (payload: any): Promise<any> => {
})
}

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

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

export const FacilityService = {
addFacilityToGroup,
addPartyToFacility,
Expand All @@ -731,13 +808,15 @@ export const FacilityService = {
createFacilityPostalAddress,
createFacilityTelecomNumber,
createProductStoreFacility,
createProductStoreFacilityGroup,
createShopifyShopLocation,
deleteFacilityGroup,
deleteFacilityLocation,
createFacilityLogin,
deleteShopifyShopLocation,
fetchArchivedFacilities,
fetchAssociatedFacilitiesToGroup,
fetchAssociatedProductStoresToGroup,
fetchFacilityGroup,
fetchFacilityGroups,
fetchFacilityLocations,
Expand All @@ -752,6 +831,7 @@ export const FacilityService = {
fetchInactiveFacilityGroupAssociations,
fetchJobData,
fetchOrderCountsByFacility,
fetchProductStoreCountByGroup,
getFacilityProductStores,
fetchShopifyFacilityMappings,
getFacilityParties,
Expand All @@ -767,5 +847,6 @@ export const FacilityService = {
updateFacilityTelecomNumber,
updateFacilityToGroup,
updateProductStoreFacility,
updateProductStoreFacilityGroup,
updateShopifyShopLocation
}
9 changes: 8 additions & 1 deletion src/store/modules/facility/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -744,10 +744,17 @@ const actions: ActionTree<FacilityState, RootState> = {
stateGroups = stateGroups.filter((group: any) => !facilityGroupIds.includes(group.facilityGroupId))

try {
const facilityCountByGroup = await FacilityService.fetchFacilityCountByGroup(facilityGroupIds)
// facilityGroupIds is list of ids which gets empty at the end of below api call
// We again want's to use this facilityGroupIds in another api hence deep cloning it.
const facilityCountByGroup = await FacilityService.fetchFacilityCountByGroup(JSON.parse(JSON.stringify(facilityGroupIds)))
groups.map((group: any) => {
group.facilityCount = facilityCountByGroup[group.facilityGroupId] || 0
})

const productStoreCountByGroup = await FacilityService.fetchProductStoreCountByGroup(facilityGroupIds)
groups.map((group: any) => {
group.productStoreCount = productStoreCountByGroup[group.facilityGroupId] || 0
})
} catch (error) {
logger.error(error)
}
Expand Down
Loading

0 comments on commit 29da01c

Please sign in to comment.