diff --git a/src/components/AddExternalMappingPopover.vue b/src/components/AddExternalMappingPopover.vue deleted file mode 100644 index a4cb3456..00000000 --- a/src/components/AddExternalMappingPopover.vue +++ /dev/null @@ -1,53 +0,0 @@ - - - diff --git a/src/components/AddStaffMemberModal.vue b/src/components/AddStaffMemberModal.vue index 6782829f..09ab95b9 100644 --- a/src/components/AddStaffMemberModal.vue +++ b/src/components/AddStaffMemberModal.vue @@ -135,13 +135,16 @@ export default defineComponent({ } const payload = { - inputFields, + inputFields: { + ...inputFields, + roleTypeId: 'APPLICATION_USER' + }, viewSize: 10, entityName: 'PartyRoleAndPartyDetail', noConditionFind: 'Y', distinct: 'Y', orderBy: "firstName ASC", - fieldList: ['firstName', 'groupName', 'lastName', 'partyId'] + fieldList: ['partyId', 'firstName', 'groupName', 'lastName'] } try { diff --git a/src/components/CustomMappingModal.vue b/src/components/CustomMappingModal.vue index 36b1de5f..84c9b14f 100644 --- a/src/components/CustomMappingModal.vue +++ b/src/components/CustomMappingModal.vue @@ -15,11 +15,11 @@ {{ translate("Facility details") }} {{ translate("Facility ID") }} -

{{ "" }}

+

{{ currentFacility.facilityId }}

{{ translate("Facility name") }} -

{{ "" }}

+

{{ currentFacility.facilityName }}

@@ -27,20 +27,20 @@ {{ translate("Custom mapping") }} {{ translate("Mapping ID") }} - + {{ translate("Mapping Name") }} - + {{ translate("Identification") }} - + - + @@ -67,6 +67,11 @@ import { import { defineComponent } from "vue"; import { closeOutline, saveOutline } from "ionicons/icons"; import { translate } from '@hotwax/dxp-components' +import { mapGetters, useStore } from 'vuex' +import { showToast } from "@/utils"; +import { FacilityService } from "@/services/FacilityService"; +import { hasError } from "@/adapter"; +import logger from "@/logger"; export default defineComponent({ name: "CustomMappingModal", @@ -86,15 +91,70 @@ export default defineComponent({ IonTitle, IonToolbar }, + data() { + return { + mappingId: '', + mappingName: '', + mappingValue: '' + } + }, + computed: { + ...mapGetters({ + currentFacility: 'facility/getCurrent' + }) + }, methods: { closeModal() { modalController.dismiss() + }, + async saveMapping() { + if(!this.mappingId.trim() || !this.mappingName.trim() || !this.mappingValue.trim()) { + showToast(translate('Please fill all the required fields')) + return; + } + + let resp; + + try { + resp = await FacilityService.createEnumeration({ + "enumId": this.mappingId, + "enumTypeId": "FACILITY_IDENTITY", + "description": this.mappingName + }) + + if(!hasError(resp) && resp.data.enumId) { + resp = await FacilityService.createFacilityIdentification({ + "facilityId": this.currentFacility.facilityId, + "facilityIdenTypeId": resp.data.enumId, + "idValue": this.mappingValue + }) + + if(!hasError(resp)) { + showToast(translate('External mapping created successfully')) + // fetching external mapping types again, as we have created a new mapping type that needs to be included in popover + // added skipState property to not check for cached type and always make an api call + await this.store.dispatch('util/fetchExternalMappingTypes', { skipState: true }) + this.store.dispatch('facility/fetchFacilityMappings', { facilityId: this.currentFacility.facilityId }) + this.closeModal(); + } else { + throw resp.data + } + } else { + throw resp.data + } + } catch(err) { + showToast(translate('Failed to create external mapping')) + logger.error('Failed to create external mapping', err) + } } }, setup() { + const store = useStore() + return { closeOutline, saveOutline, + store, translate }; }, diff --git a/src/components/FacilityMappingModal.vue b/src/components/FacilityMappingModal.vue new file mode 100644 index 00000000..07dc3f54 --- /dev/null +++ b/src/components/FacilityMappingModal.vue @@ -0,0 +1,177 @@ + + + \ No newline at end of file diff --git a/src/components/FacilityMappingPopover.vue b/src/components/FacilityMappingPopover.vue new file mode 100644 index 00000000..09f8955d --- /dev/null +++ b/src/components/FacilityMappingPopover.vue @@ -0,0 +1,80 @@ + + + diff --git a/src/components/FacilityShopifyMappingModal.vue b/src/components/FacilityShopifyMappingModal.vue new file mode 100644 index 00000000..a2212548 --- /dev/null +++ b/src/components/FacilityShopifyMappingModal.vue @@ -0,0 +1,181 @@ + + + \ No newline at end of file diff --git a/src/components/Filters.vue b/src/components/Filters.vue index d5a64495..fe4a0e74 100644 --- a/src/components/Filters.vue +++ b/src/components/Filters.vue @@ -21,7 +21,7 @@ {{ translate("Type") }} {{ translate("All") }} - {{ facilityType.description }} + {{ description }} diff --git a/src/components/LocationDetailsPopover.vue b/src/components/LocationDetailsPopover.vue index 2e4fed31..bea37435 100644 --- a/src/components/LocationDetailsPopover.vue +++ b/src/components/LocationDetailsPopover.vue @@ -19,7 +19,7 @@ import { IonList, IonListHeader, modalController, -popoverController + popoverController } from "@ionic/vue"; import { defineComponent } from "vue"; import { translate } from "@hotwax/dxp-components"; @@ -51,11 +51,8 @@ export default defineComponent({ componentProps: { location: this.location } }) + await popoverController.dismiss(); addLocationModal.present() - - addLocationModal.onDidDismiss().then(() => { - popoverController.dismiss(); - }) }, async removeLocation() { const params = { diff --git a/src/components/TimezoneModal.vue b/src/components/TimezoneModal.vue index a86a4f91..7363e67f 100644 --- a/src/components/TimezoneModal.vue +++ b/src/components/TimezoneModal.vue @@ -71,7 +71,7 @@ import { defineComponent } from "vue"; import { closeOutline, saveOutline } from "ionicons/icons"; import { useStore } from "@/store"; import { UserService } from "@/services/UserService"; -import { hasError } from '@/utils' +import { hasError } from '@/adapter' import { DateTime } from 'luxon'; import logger from "@/logger"; diff --git a/src/locales/en.json b/src/locales/en.json index 4caf2b62..e3d6663c 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -6,6 +6,7 @@ "Address": "Address", "Address line 1": "Address line 1", "Address line 2": "Address line 2", + "add your location ID from Shopify": "add your location ID from Shopify", "Aisle": "Aisle", "aisle": "aisle", "All": "All", @@ -37,6 +38,8 @@ "Filters": "Filters", "Edit": "Edit", "Edit location": "Edit location", + "External mapping created successfully": "External mapping created successfully", + "External mapping updated successfully": "External mapping updated successfully", "External mappings": "External mappings", "Facilities": "Facilities", "Facility details": "Facility details", @@ -46,15 +49,21 @@ "Facility location updated successfully": "Facility location updated successfully", "Facility name": "Facility name", "Facility Management": "Facility Management", + "Failed to create external mapping": "Failed to create external mapping", "Failed to create facility location": "Failed to create facility location", + "Failed to create shopify mapping": "Failed to create shopify mapping", "Failed to fetch facility information": "Failed to fetch facility information", "Failed to find the facility locations": "Failed to find the facility locations", "Failed to remove facility location": "Failed to remove facility location", + "Failed to remove facility mapping": "Failed to remove facility mapping", "Failed to remove party from facility.": "Failed to remove party from facility.", + "Failed to remove shopify mapping": "Failed to remove shopify mapping", "Failed to update default days to ship": "Failed to update default days to ship", + "Failed to update external mapping": "Failed to update external mapping", "Failed to update facility location": "Failed to update facility location", "Failed to update fulfillment capacity for ": "Failed to update fulfillment capacity for {facilityName}", "Failed to update fulfillment setting": "Failed to update fulfillment setting", + "Failed to update shopify mapping": "Failed to update shopify mapping", "Failed to update some role(s).": "Failed to update some role(s).", "Fetching TimeZones": "Fetching TimeZones", "Find Facilities": "Find Facilities", @@ -77,6 +86,7 @@ "level": "level", "Loading": "Loading", "Location": "Location", + "Location ID": "Location ID", "Location details": "Location details", "Locations": "Locations", "Logging in": "Logging in", @@ -111,17 +121,20 @@ "Party Id": "Party Id", "Party successfully removed from facility.": "Party successfully removed from facility.", "Please update atleast one party role.": "Please update atleast one party role.", - "party id": "party id", "Password": "Password", + "party id": "party id", "Please contact the administrator.": "Please contact the administrator.", + "Please enter a valid value": "Please enter a valid value", "Please fill all the required fields": "Please fill all the required fields", "primary store": "primary store", "Product Store": "Product Store", "Product Stores": "Product Stores", "Reason:": "Reason:", - "Reset": "Reset", "Remove": "Remove", "Remove location": "Remove location", + "Removed facility mapping successfully": "Removed facility mapping successfully", + "Removed shopify mapping successfully": "Removed shopify mapping successfully", + "Reset": "Reset", "Role": "Role", "role": "role", "Role(s) updated successfully.": "Role(s) updated successfully.", @@ -144,6 +157,10 @@ "Setting fulfillment capacity to 0 disables new order from being allocated to this facility. Leave this empty if this facility's fulfillment capacity is unrestricted.": "Setting fulfillment capacity to 0 disables new order from being allocated to this facility. Leave this empty if this facility's fulfillment capacity is unrestricted.", "Shopify": "Shopify", "Shopify facility": "Shopify facility", + "Shopify location": "Shopify location", + "Shopify mapping created successfully": "Shopify mapping created successfully", + "Shopify mapping updated successfully": "Shopify mapping updated successfully", + "Shopify store": "Shopify store", "Something went wrong": "Something went wrong", "Something went wrong while login. Please contact administrator.": "Something went wrong while login. Please contact administrator.", "Sorry, your username or password is incorrect. Please try again.": "Sorry, your username or password is incorrect. Please try again.", diff --git a/src/services/FacilityService.ts b/src/services/FacilityService.ts index a3032404..a1204239 100644 --- a/src/services/FacilityService.ts +++ b/src/services/FacilityService.ts @@ -214,20 +214,92 @@ const updateFacilityToGroup = async (payload: any): Promise => { }) } +const fetchFacilityMappings = async (payload: any): Promise => { + return api({ + url: "performFind", + method: "post", + data: payload + }) +} + +const fetchShopifyFacilityMappings = async (payload: any): Promise => { + return api({ + url: "performFind", + method: "post", + data: payload + }) +} + +const createFacilityIdentification = async (payload: any): Promise => { + return api({ + url: "service/createFacilityIdentification", + method: "post", + data: payload + }) +} + +const updateFacilityIdentification = async (payload: any): Promise => { + return api({ + url: "service/updateFacilityIdentification", + method: "post", + data: payload + }) +} + +const createShopifyShopLocation = async (payload: any): Promise => { + return api({ + url: "service/createShopifyShopLocation", + method: "post", + data: payload + }) +} + +const updateShopifyShopLocation = async (payload: any): Promise => { + return api({ + url: "service/updateShopifyShopLocation", + method: "post", + data: payload + }) +} + +const deleteShopifyShopLocation = async (payload: any): Promise => { + return api({ + url: "service/deleteShopifyShopLocation", + method: "post", + data: payload + }) +} + +const createEnumeration = async (payload: any): Promise => { + return api({ + url: "service/createEnumeration", + method: "post", + data: payload + }) +} + export const FacilityService = { addFacilityToGroup, addPartyToFacility, - deleteFacilityLocation, + createEnumeration, + createFacilityIdentification, createFacilityLocation, - fetchFacilitiesOrderCount, + createShopifyShopLocation, + deleteFacilityLocation, + deleteShopifyShopLocation, fetchFacilities, + fetchFacilitiesOrderCount, fetchFacilityGroupInformation, fetchFacilityLocations, + fetchFacilityMappings, fetchFacilityOrderCounts, + fetchShopifyFacilityMappings, getFacilityParties, getPartyRoleAndPartyDetails, removePartyFromFacility, updateFacility, + updateFacilityIdentification, updateFacilityLocation, - updateFacilityToGroup + updateFacilityToGroup, + updateShopifyShopLocation } \ No newline at end of file diff --git a/src/services/UtilService.ts b/src/services/UtilService.ts index 7440a9b2..7fba2177 100644 --- a/src/services/UtilService.ts +++ b/src/services/UtilService.ts @@ -35,7 +35,17 @@ const fetchLocationTypes = async (payload: any): Promise => { }) } +const fetchExternalMappingTypes = async (payload: any): Promise => { + return api({ + url: "performFind", + method: "POST", + data: payload, + cache: true + }) +} + export const UtilService = { + fetchExternalMappingTypes, fetchFacilityTypes, fetchLocationTypes, fetchPartyRoles, diff --git a/src/store/modules/facility/actions.ts b/src/store/modules/facility/actions.ts index 4ac936e6..513a37a5 100644 --- a/src/store/modules/facility/actions.ts +++ b/src/store/modules/facility/actions.ts @@ -195,6 +195,34 @@ const actions: ActionTree = { } }, + async fetchFacilityMappings({ commit }, payload) { + let mappings = [] + try { + const params = { + inputFields: { + facilityId: payload.facilityId, + facilityIdenTypeId: payload.facilityIdenTypeIds, + facilityIdenTypeId_op: "in" + }, + entityName: "FacilityIdentification", + filterByDate: "Y", + fieldList: ["facilityIdenTypeId", "idValue", "fromDate"], + viewSize: 100 + } + + const resp = await FacilityService.fetchFacilityMappings(params) + + if(!hasError(resp) && resp.data.count > 0) { + mappings = resp.data.docs + } else { + throw resp.data + } + } catch(err) { + logger.error('Failed to fetch facility mappings', err) + } + commit(types.FACILITY_MAPPINGS_UPDATED, mappings) + }, + async getFacilityParties({ commit }, payload) { let parties = [] const params = { @@ -222,10 +250,35 @@ const actions: ActionTree = { } } catch(err) { showToast(translate("Something went wrong")) - logger.error + logger.error('Failed to fetch facility parties', err) } commit(types.FACILITY_PARTIES_UPDATED, parties) + }, + + async fetchShopifyFacilityMappings({ commit }, payload) { + let shopifyFacilityMappings = [] + try { + const params = { + inputFields: { + facilityId: payload.facilityId + }, + entityName: "ShopifyShopLocationView", + fieldList: ["shopifyShopId", "domain", "name", "myshopifyDomain", "shopId", "shopifyLocationId"], + viewSize: 100 + } + + const resp = await FacilityService.fetchShopifyFacilityMappings(params) + + if(!hasError(resp) && resp.data.count > 0) { + shopifyFacilityMappings = resp.data.docs + } else { + throw resp.data + } + } catch(err) { + logger.error('Failed to fetch shopify facility mappings', err) + } + commit(types.FACILITY_SHOPIFY_MAPPINGS_UPDATED, shopifyFacilityMappings) } } diff --git a/src/store/modules/facility/mutation-types.ts b/src/store/modules/facility/mutation-types.ts index a46327a7..02f14ea3 100644 --- a/src/store/modules/facility/mutation-types.ts +++ b/src/store/modules/facility/mutation-types.ts @@ -2,6 +2,8 @@ export const SN_FACILITY = 'facility' export const FACILITY_LIST_UPDATED = SN_FACILITY + '/LIST_UPDATED' export const FACILITY_QUERY_UPDATED = SN_FACILITY + '/QUERY_UPDATED' export const FACILITY_CURRENT_UPDATED = SN_FACILITY + '/CURRENT_UPDATED' -export const FACILITY_CURRENT_LOCATION_UPDATED = SN_FACILITY + '/CURRENT_LOCATION_UPDATED' export const FACILITY_LOCATIONS_UPDATED = SN_FACILITY + '/LOCATIONS_UPDATED' +export const FACILITY_MAPPINGS_UPDATED = SN_FACILITY + '/MAPPINGS_UPDATED' +export const FACILITY_SHOPIFY_MAPPINGS_UPDATED = SN_FACILITY + '/SHOPIFY_MAPPINGS_UPDATED' +export const FACILITY_CURRENT_LOCATION_UPDATED = SN_FACILITY + '/CURRENT_LOCATION_UPDATED' export const FACILITY_PARTIES_UPDATED = SN_FACILITY + '/PARTIES_UPDATED' diff --git a/src/store/modules/facility/mutations.ts b/src/store/modules/facility/mutations.ts index 160c73b4..d09530d5 100644 --- a/src/store/modules/facility/mutations.ts +++ b/src/store/modules/facility/mutations.ts @@ -16,6 +16,12 @@ const mutations: MutationTree = { [types.FACILITY_LOCATIONS_UPDATED](state, payload) { state.current.locations = payload }, + [types.FACILITY_MAPPINGS_UPDATED](state, payload) { + state.current.facilityMappings = payload + }, + [types.FACILITY_SHOPIFY_MAPPINGS_UPDATED](state, payload) { + state.current.shopifyFacilityMappings = payload + }, [types.FACILITY_PARTIES_UPDATED](state, payload) { state.current.parties = payload } diff --git a/src/store/modules/util/UtilState.ts b/src/store/modules/util/UtilState.ts index 0efb66fe..fda1accd 100644 --- a/src/store/modules/util/UtilState.ts +++ b/src/store/modules/util/UtilState.ts @@ -1,6 +1,7 @@ export default interface UtilState { facilityTypes: object; locationTypes: object; + externalMappingTypes: object; productStores: any[]; partyRoles: any[]; } \ No newline at end of file diff --git a/src/store/modules/util/actions.ts b/src/store/modules/util/actions.ts index 87ee4878..21f04cee 100644 --- a/src/store/modules/util/actions.ts +++ b/src/store/modules/util/actions.ts @@ -37,7 +37,7 @@ const actions: ActionTree = { return; } - let facilityTypes = [] + let facilityTypes = {} const params = { inputFields: { ...payload @@ -51,7 +51,11 @@ const actions: ActionTree = { try { const resp = await UtilService.fetchFacilityTypes(params) if (!hasError(resp)) { - facilityTypes = resp.data.docs + facilityTypes = resp.data.docs.reduce((facilityType: any, type: any) => { + facilityType[type.facilityTypeId] = type.description + + return facilityType + }, {}) } else { throw resp.data } @@ -133,9 +137,50 @@ const actions: ActionTree = { commit(types.UTIL_PARTY_ROLES_UPDATED, partyRoles) }, + async fetchExternalMappingTypes({ commit, state }, payload) { + const cachedExternalMappingTypes = JSON.parse(JSON.stringify(state.externalMappingTypes)) + + // not fetching external mapping type information again if already present, as it will not be changed so frequently + if(cachedExternalMappingTypes.length && !payload?.skipState) { + return; + } + + let externalMappingTypes = [] + const params = { + inputFields: { + enumTypeId: 'FACILITY_IDENTITY', + enumId: 'SHOPIFY_FAC_ID', + enumId_op: 'notEqual' // excluding shopify enum as we have included shopify as an hardcoded option + }, + viewSize: 100, + noConditionFind: 'Y', + entityName: 'Enumeration', + fieldList: ['enumId', 'description'] + } as any + + try { + const resp = await UtilService.fetchExternalMappingTypes(params) + if (!hasError(resp)) { + externalMappingTypes = resp.data.docs.reduce((externalMappingType: any, type: any) => { + externalMappingType[type.enumId] = type.description + + return externalMappingType + }, {}) + } else { + throw resp.data + } + } catch (error) { + logger.error(error) + } + + commit(types.UTIL_EXTERNAL_MAPPING_TYPES_UPDATED, externalMappingTypes) + }, + clearUtilState({ commit }) { commit(types.UTIL_PRODUCT_STORES_UPDATED, []) - commit(types.UTIL_FACILITY_TYPES_UPDATED, []) + commit(types.UTIL_FACILITY_TYPES_UPDATED, {}) + commit(types.UTIL_LOCATION_TYPES_UPDATED, {}) + commit(types.UTIL_EXTERNAL_MAPPING_TYPES_UPDATED, {}) } } diff --git a/src/store/modules/util/getters.ts b/src/store/modules/util/getters.ts index b38e3c43..c351ece6 100644 --- a/src/store/modules/util/getters.ts +++ b/src/store/modules/util/getters.ts @@ -14,6 +14,9 @@ const getters: GetterTree = { }, getLocationTypes(state) { return state.locationTypes + }, + getExternalMappingTypes(state) { + return state.externalMappingTypes } } export default getters; \ No newline at end of file diff --git a/src/store/modules/util/index.ts b/src/store/modules/util/index.ts index ded1a803..6e3bfde4 100644 --- a/src/store/modules/util/index.ts +++ b/src/store/modules/util/index.ts @@ -11,7 +11,8 @@ const utilModule: Module = { partyRoles: [], productStores: [], facilityTypes: {}, - locationTypes: {} + locationTypes: {}, + externalMappingTypes: {} }, getters, actions, diff --git a/src/store/modules/util/mutation-types.ts b/src/store/modules/util/mutation-types.ts index 46e28e9a..1d73909f 100644 --- a/src/store/modules/util/mutation-types.ts +++ b/src/store/modules/util/mutation-types.ts @@ -2,4 +2,5 @@ export const SN_UTIL = 'util' export const UTIL_PRODUCT_STORES_UPDATED = SN_UTIL + '/PRODUCT_STORES_UPDATED' export const UTIL_FACILITY_TYPES_UPDATED = SN_UTIL + '/FACILITY_TYPES_UPDATED' export const UTIL_LOCATION_TYPES_UPDATED = SN_UTIL + '/LOCATION_TYPES_UPDATED' +export const UTIL_EXTERNAL_MAPPING_TYPES_UPDATED = SN_UTIL + '/EXTERNAL_MAPPING_TYPES_UPDATED' export const UTIL_PARTY_ROLES_UPDATED = SN_UTIL + '/PARTY_ROLES_UPDATED' diff --git a/src/store/modules/util/mutations.ts b/src/store/modules/util/mutations.ts index 4e0d3208..060f0486 100644 --- a/src/store/modules/util/mutations.ts +++ b/src/store/modules/util/mutations.ts @@ -12,6 +12,9 @@ const mutations: MutationTree = { [types.UTIL_LOCATION_TYPES_UPDATED](state, payload) { state.locationTypes = payload }, + [types.UTIL_EXTERNAL_MAPPING_TYPES_UPDATED](state, payload) { + state.externalMappingTypes = payload + }, [types.UTIL_PARTY_ROLES_UPDATED](state, payload) { state.partyRoles = payload } diff --git a/src/utils/index.ts b/src/utils/index.ts index 1d99845b..2ebc61d5 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -1,16 +1,9 @@ import { translate } from '@hotwax/dxp-components'; -import store from '@/store'; import { Plugins } from '@capacitor/core'; import { toastController } from '@ionic/vue'; -import { DateTime } from 'luxon'; // TODO Use separate files for specific utilities -// TODO Remove it when HC APIs are fully REST compliant -const hasError = (response: any) => { - return typeof response.data != "object" || !!response.data._ERROR_MESSAGE_ || !!response.data._ERROR_MESSAGE_LIST_ || !!response.data.error; -} - const showToast = async (message: string, options?: any) => { const config = { message, @@ -37,38 +30,6 @@ const showToast = async (message: string, options?: any) => { return !options?.manualDismiss ? toast.present() : toast } -const handleDateTimeInput = (dateTimeValue: any) => { - // TODO Handle it in a better way - // Remove timezone and then convert to timestamp - // Current date time picker picks browser timezone and there is no supprt to change it - const dateTime = DateTime.fromISO(dateTimeValue, { setZone: true}).toFormat("yyyy-MM-dd'T'HH:mm:ss") - return DateTime.fromISO(dateTime).toMillis() -} - -const formatDate = (value: any, inFormat?: string, outFormat?: string) => { - // TODO Make default format configurable and from environment variables - if(inFormat){ - return DateTime.fromFormat(value, inFormat).toFormat(outFormat ? outFormat : 'MM-dd-yyyy'); - } - return DateTime.fromISO(value).toFormat(outFormat ? outFormat : 'MM-dd-yyyy'); -} - -const formatUtcDate = (value: any, outFormat: string) => { - // TODO Make default format configurable and from environment variables - // TODO Fix this setDefault should set the default timezone instead of getting it everytiem and setting the tz - return DateTime.fromISO(value, { zone: 'utc' }).setZone(store.state.user.current.userTimeZone).toFormat(outFormat ? outFormat : 'MM-dd-yyyy') -} - -const getFeature = (featureHierarchy: any, featureKey: string) => { - let featureValue = '' - if (featureHierarchy) { - const feature = featureHierarchy.find((featureItem: any) => featureItem.startsWith(featureKey)) - const featureSplit = feature ? feature.split('/') : []; - featureValue = featureSplit[2] ? featureSplit[2] : ''; - } - return featureValue; -} - const copyToClipboard = async (value: string, text?: string) => { const { Clipboard } = Plugins; @@ -79,14 +40,4 @@ const copyToClipboard = async (value: string, text?: string) => { }); } -const getIdentificationId = (identifications: any, id: string) => { - let externalId = '' - if (identifications) { - const externalIdentification = identifications.find((identification: any) => identification.startsWith(id)) - const externalIdentificationSplit = externalIdentification ? externalIdentification.split('/') : []; - externalId = externalIdentificationSplit[1] ? externalIdentificationSplit[1] : ''; - } - return externalId; -} - -export { copyToClipboard, formatDate, formatUtcDate, getFeature, getIdentificationId, handleDateTimeInput, showToast, hasError } +export { copyToClipboard, showToast } diff --git a/src/views/FacilityDetails.vue b/src/views/FacilityDetails.vue index 84e65efb..da1261b9 100644 --- a/src/views/FacilityDetails.vue +++ b/src/views/FacilityDetails.vue @@ -251,7 +251,7 @@ {{ translate("Map facility to an external system") }}
- + {{ translate("Shopify facility") }} @@ -259,29 +259,40 @@ - {{ "shop name" }} -

{{ "" }}

+ {{ shopifyFacilityMapping.name }} +

{{ shopifyFacilityMapping.shopId }}

- {{"note"}}
- {{ "" }} - {{"note"}} + {{ shopifyFacilityMapping.shopifyLocationId }} - {{ "" }} - + {{ shopifyFacilityMapping.myshopifyDomain + '/admin' }} + - {{ "" }} - + {{ shopifyFacilityMapping.myshopifyDomain }} + - {{ translate("Edit") }} - {{ translate("Remove") }} + {{ translate("Edit") }} + {{ translate("Remove") }} +
+ + + + {{ externalMappingTypes[mapping.facilityIdenTypeId] }} + + + + {{ translate('Identification') }} + {{ mapping.idValue }} + + {{ translate("Edit") }} + {{ translate("Remove") }}
@@ -389,7 +400,6 @@ import { IonItem, IonLabel, IonList, - IonNote, IonPage, IonProgressBar, IonSegment, @@ -413,7 +423,7 @@ import { personOutline } from 'ionicons/icons' import { translate } from '@hotwax/dxp-components'; -import AddExternalMappingPopover from '@/components/AddExternalMappingPopover.vue' +import FacilityMappingPopover from '@/components/FacilityMappingPopover.vue' import LocationDetailsPopover from '@/components/LocationDetailsPopover.vue'; import OpenStorePopover from '@/components/OpenStorePopover.vue'; import AddAddressModal from '@/components/AddAddressModal.vue' @@ -429,6 +439,8 @@ import { DateTime } from 'luxon'; import { FacilityService } from '@/services/FacilityService'; import { hasError } from '@/adapter'; import logger from '@/logger'; +import FacilityShopifyMappingModal from '@/components/FacilityShopifyMappingModal.vue' +import FacilityMappingModal from '@/components/FacilityMappingModal.vue' import { showToast } from '@/utils'; export default defineComponent({ @@ -449,7 +461,6 @@ export default defineComponent({ IonItem, IonLabel, IonList, - IonNote, IonPage, IonProgressBar, IonSegment, @@ -464,25 +475,31 @@ export default defineComponent({ isTimeModalOpen: false as boolean, isLoading: true, // shows whether the facility information fetching is completed or not segment: 'external-mappings', - defaultDaysToShip: '' // not assinging 0 by default as it will convey the user that the facility can ship same day, but actually defaultDays are not setup on the facility + defaultDaysToShip: '' // not assinging 0 by default as it will convey the user that the facility can ship same day(as the value is 0), but actually defaultDays are not setup on the facility } }, computed: { ...mapGetters({ current: 'facility/getCurrent', - facilityParties: 'facility/getFacilityParties', locationTypes: 'util/getLocationTypes', + externalMappingTypes: 'util/getExternalMappingTypes', + facilityParties: 'facility/getFacilityParties', partyRoles: 'util/getPartyRoles' }) }, props: ["facilityId"], async ionViewWillEnter() { - await this.store.dispatch('facility/fetchCurrentFacility', { facilityId: this.facilityId }) - await Promise.all([this.store.dispatch('facility/fetchFacilityLocations', { facilityId: this.facilityId }), this.store.dispatch('util/fetchLocationTypes'), this.store.dispatch('facility/getFacilityParties', { facilityId: this.facilityId }), this.store.dispatch('util/fetchPartyRoles')]) + await Promise.all([this.store.dispatch('facility/fetchCurrentFacility', { facilityId: this.facilityId }), this.store.dispatch('util/fetchExternalMappingTypes'), this.store.dispatch('util/fetchLocationTypes'), this.store.dispatch('util/fetchPartyRoles')]) + await Promise.all([this.store.dispatch('facility/fetchFacilityLocations', { facilityId: this.facilityId }), this.store.dispatch('facility/getFacilityParties', { facilityId: this.facilityId }), this.store.dispatch('facility/fetchFacilityMappings', { facilityId: this.facilityId, facilityIdenTypeIds: Object.keys(this.externalMappingTypes)}), this.store.dispatch('facility/fetchShopifyFacilityMappings', { facilityId: this.facilityId })]) this.defaultDaysToShip = this.current.defaultDaysToShip this.isLoading = false }, methods: { + goToLink(link: string) { + const url = link.startsWith('http') ? link : `https://${link}` + // opening link in new tab without passing any reference + window.open(url, '_blank', 'noopener, noreferrer') + }, async openStorePopover(ev: Event) { const popover = await popoverController.create({ component: OpenStorePopover, @@ -545,7 +562,7 @@ export default defineComponent({ }, async openExternalMappingPopover(ev: Event) { const externalMappingPopover = await popoverController.create({ - component: AddExternalMappingPopover, + component: FacilityMappingPopover, event: ev, showBackdrop: false }); @@ -691,6 +708,67 @@ export default defineComponent({ logger.error('Failed to update default days to ship', err) showToast(translate('Failed to update default days to ship')) } + }, + async removeFacilityMapping(mapping: any) { + try { + const payload = { + facilityId: this.current.facilityId, + facilityIdenTypeId: mapping.facilityIdenTypeId, + fromDate: mapping.fromDate, + thruDate: DateTime.now().toMillis() + } + + const resp = await FacilityService.updateFacilityIdentification(payload) + + if(!hasError(resp)) { + showToast(translate('Removed facility mapping successfully')) + await this.store.dispatch('facility/fetchFacilityMappings', { facilityId: this.facilityId, facilityIdenTypeIds: Object.keys(this.externalMappingTypes) }) + } else { + throw resp.data + } + } catch(err) { + logger.error('Failed to remove facility mapping', err) + showToast(translate('Failed to remove facility mapping')) + } + }, + async removeShopifyFacilityMapping(shopifyFacilityMapping: any) { + try { + const payload = { + facilityId: this.current.facilityId, + shopId: shopifyFacilityMapping.shopId, + shopifyLocationId: shopifyFacilityMapping.shopifyLocationId, + } + + const resp = await FacilityService.deleteShopifyShopLocation(payload) + + if(!hasError(resp)) { + showToast(translate('Removed shopify mapping successfully')) + await this.store.dispatch('facility/fetchShopifyFacilityMappings', { facilityId: this.facilityId }) + } else { + throw resp.data + } + } catch(err) { + logger.error('Failed to remove shopify mapping', err) + showToast(translate('Failed to remove shopify mapping')) + } + }, + async editFacilityMapping(mapping: any) { + const customMappingModal = await modalController.create({ + component: FacilityMappingModal, + componentProps: { mappingId: mapping.facilityIdenTypeId, mapping, type: 'update' } + }) + + await popoverController.dismiss() + customMappingModal.present() + }, + async editShopifyFacilityMapping(shopifyFacilityMapping: any) { + const customMappingModal = await modalController.create({ + component: FacilityShopifyMappingModal, + componentProps: { shopifyFacilityMapping, type: 'update' } + }) + + await popoverController.dismiss() + customMappingModal.present() } }, setup() { diff --git a/src/views/FindFacilities.vue b/src/views/FindFacilities.vue index 1fa1c2b5..0c53f80a 100644 --- a/src/views/FindFacilities.vue +++ b/src/views/FindFacilities.vue @@ -35,7 +35,7 @@ {{ translate("Type") }} {{ translate("All") }} - {{ facilityType.description }} + {{ description }} @@ -46,7 +46,7 @@ -

{{ facility.facilityTypeId ? facility.facilityTypeId : '' }}

+

{{ facility.facilityTypeId ? facilityTypes[facility.facilityTypeId] ? facilityTypes[facility.facilityTypeId] : facilityTypes.facilityTypeId : '' }}

{{ facility.facilityName }}

{{ facility.facilityId }}

diff --git a/src/views/Settings.vue b/src/views/Settings.vue index 4ff10e0b..fb5e69fa 100644 --- a/src/views/Settings.vue +++ b/src/views/Settings.vue @@ -140,7 +140,6 @@ export default defineComponent({ methods: { logout () { this.store.dispatch('user/logout', { isUserUnauthorised: false }).then((redirectionUrl: string) => { - this.store.dispatch('order/clearOrders') // if not having redirection url then redirect the user to launchpad if(!redirectionUrl) {