diff --git a/src/components/FacilityAddressModal.vue b/src/components/FacilityAddressModal.vue index 38a35a78..f16e2c22 100644 --- a/src/components/FacilityAddressModal.vue +++ b/src/components/FacilityAddressModal.vue @@ -56,11 +56,14 @@ {{ telecomNumberValue?.countryCode }} + + + - + @@ -93,7 +96,7 @@ import { translate } from '@hotwax/dxp-components' import { FacilityService } from '@/services/FacilityService'; import { getTelecomCountryCode, hasError } from "@/adapter"; import logger from "@/logger"; -import { showToast } from "@/utils"; +import { showToast, isValidEmail } from "@/utils"; import emitter from "@/event-bus"; export default defineComponent({ @@ -121,19 +124,21 @@ export default defineComponent({ postalAddress: 'facility/getPostalAddress', countries: 'util/getCountries', states: 'util/getStates', - telecomNumber: 'facility/getTelecomNumber' + contactDetails: 'facility/getTelecomAndEmailAddress' }) }, data() { return { address: {} as any, - telecomNumberValue: {} as any + telecomNumberValue: {} as any, + emailAddress: {} as any } }, props: ['facilityId', 'facilityName'], beforeMount() { this.address = JSON.parse(JSON.stringify(this.postalAddress)) - this.telecomNumberValue = this.telecomNumber ? JSON.parse(JSON.stringify(this.telecomNumber)) : {} + this.telecomNumberValue = this.contactDetails?.telecomNumber ? JSON.parse(JSON.stringify(this.contactDetails.telecomNumber)) : {} + this.emailAddress = this.contactDetails?.emailAddress ? JSON.parse(JSON.stringify(this.contactDetails.emailAddress)) : {}; }, async mounted() { await this.store.dispatch('util/fetchCountries', { countryGeoId: this.address?.countryGeoId }) @@ -157,8 +162,14 @@ export default defineComponent({ return } + if(this.emailAddress.infoString && !isValidEmail(this.emailAddress.infoString)) { + showToast(translate("Invalid email address")) + return + } + emitter.emit('presentLoader') const isTelecomNumberUpdated = this.isTelecomNumberUpdated() + const isEmailAddressUpdated = this.isEmailAddressUpdated() if(this.isAddressUpdated()) { try { @@ -174,7 +185,7 @@ export default defineComponent({ if(!hasError(resp)) { postalAddress = this.address - await this.store.dispatch('facility/fetchFacilityContactDetails', { facilityId: this.facilityId }) + await this.store.dispatch('facility/fetchFacilityContactDetailsAndTelecom', { facilityId: this.facilityId }) showToast(translate("Facility contact updated successfully.")) } else { throw resp.data @@ -186,6 +197,7 @@ export default defineComponent({ } if(isTelecomNumberUpdated) await this.saveTelecomNumber() + if(isEmailAddressUpdated) await this.saveEmailAddress() modalController.dismiss({ postalAddress }) emitter.emit('dismissLoader') @@ -197,21 +209,52 @@ export default defineComponent({ facilityId: this.facilityId, contactMechPurposeTypeId: 'PRIMARY_PHONE', contactNumber: this.telecomNumberValue.contactNumber.trim(), - countryCode: this.telecomNumberValue.countryCode + countryCode: this.telecomNumberValue.countryCode.replace('+', '') } try { - if(this.telecomNumber?.contactMechId) { + if(this.contactDetails.telecomNumber?.contactMechId) { resp = await FacilityService.updateFacilityTelecomNumber({ ...payload, - contactMechId: this.telecomNumber.contactMechId, + contactMechId: this.contactDetails.telecomNumber.contactMechId, }) } else { resp = await FacilityService.createFacilityTelecomNumber(payload) } if(!hasError(resp)) { - await this.store.dispatch('facility/fetchFacilityTelecomNumber', { facilityId: this.facilityId }) + await this.store.dispatch('facility/fetchFacilityContactDetailsAndTelecom', { facilityId: this.facilityId }) + } else { + throw resp.data + } + } catch(err) { + logger.error(err) + } + }, + async saveEmailAddress() { + let resp = {} as any; + + const payload = { + facilityId: this.facilityId, + emailAddress: this.emailAddress.infoString + } + + try { + if(this.contactDetails.emailAddress?.contactMechId) { + resp = await FacilityService.updateFacilityEmailAddress({ + ...payload, + contactMechId: this.emailAddress.contactMechId, + }) + } else { + resp = await FacilityService.createFacilityEmailAddress({ + ...payload, + contactMechTypeId: 'EMAIL_ADDRESS', + contactMechPurposeTypeId: 'PRIMARY_EMAIL', + }) + } + + if(!hasError(resp)) { + await this.store.dispatch('facility/fetchFacilityContactDetailsAndTelecom', { facilityId: this.facilityId }) } else { throw resp.data } @@ -232,8 +275,11 @@ export default defineComponent({ : true }, isTelecomNumberUpdated() { - return this.telecomNumberValue.contactNumber && JSON.stringify(this.telecomNumberValue) !== JSON.stringify(this.telecomNumber) - } + return this.telecomNumberValue?.contactNumber && JSON.stringify(this.telecomNumberValue.contactNumber) !== JSON.stringify(this.contactDetails?.telecomNumber?.contactNumber) + }, + isEmailAddressUpdated() { + return this.emailAddress?.infoString && JSON.stringify(this.emailAddress.infoString) !== JSON.stringify(this.contactDetails?.emailAddress?.infoString); + }, }, setup() { const store = useStore() diff --git a/src/components/FacilityGeoPointModal.vue b/src/components/FacilityGeoPointModal.vue index 51cd9ac8..9b97f104 100644 --- a/src/components/FacilityGeoPointModal.vue +++ b/src/components/FacilityGeoPointModal.vue @@ -145,7 +145,7 @@ export default defineComponent({ if(!hasError(resp)) { geoPoints = this.geoPoint showToast(translate("Facility latitude and longitude updated successfully.")) - await this.store.dispatch('facility/fetchFacilityContactDetails', { facilityId: this.facilityId }) + await this.store.dispatch('facility/fetchFacilityContactDetailsAndTelecom', { facilityId: this.facilityId }) } else { throw resp.data } diff --git a/src/components/GeoPointPopover.vue b/src/components/GeoPointPopover.vue index 196236e7..cd7bb57a 100644 --- a/src/components/GeoPointPopover.vue +++ b/src/components/GeoPointPopover.vue @@ -72,7 +72,7 @@ export default defineComponent({ if(!hasError(resp)) { showToast(translate("Successfully regenerated latitude and longitude for the facility.")) - await this.store.dispatch('facility/fetchFacilityContactDetails', { facilityId: this.facilityId }) + await this.store.dispatch('facility/fetchFacilityContactDetailsAndTelecom', { facilityId: this.facilityId }) } else { throw resp.data } @@ -103,7 +103,7 @@ export default defineComponent({ if(!hasError(resp)) { showToast(translate("Facility latitude and longitude removed successfully.")) - await this.store.dispatch('facility/fetchFacilityContactDetails', { facilityId: this.facilityId }) + await this.store.dispatch('facility/fetchFacilityContactDetailsAndTelecom', { facilityId: this.facilityId }) } else { throw resp.data } diff --git a/src/locales/en.json b/src/locales/en.json index 6aff2688..1badf31f 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -87,6 +87,7 @@ "Edit location": "Edit location", "End Time": "End Time", "Facility group created.": "Facility group created.", + "Email address": "Email address", "External ID": "External ID", "External mapping created successfully": "External mapping created successfully", "External mapping updated successfully": "External mapping updated successfully", @@ -202,6 +203,7 @@ "Internal ID": "Internal ID", "Internal ID cannot be more than 20 characters.": "Internal ID cannot be more than 20 characters.", "Internal locations": "Internal locations", + "Invalid email address": "Invalid email address", "is now selling on": "{facilityName} is now selling on {facilityGroupId}.", "Instance Url": "Instance Url", "Language": "Language", diff --git a/src/services/FacilityService.ts b/src/services/FacilityService.ts index dd8e7335..fc7352c8 100644 --- a/src/services/FacilityService.ts +++ b/src/services/FacilityService.ts @@ -779,6 +779,22 @@ const updateFacilityTelecomNumber = async (payload: any): Promise => { }) } +const createFacilityEmailAddress = async (payload: any): Promise => { + return api({ + url: "service/createFacilityEmailAddress", + method: "post", + data: payload + }) +} + +const updateFacilityEmailAddress = async (payload: any): Promise => { + return api({ + url: "service/updateFacilityEmailAddress", + method: "post", + data: payload + }) +} + const createProductStoreFacilityGroup = async (payload: any): Promise => { return api({ url: "service/createProductStoreFacilityGroup", @@ -804,6 +820,7 @@ export const FacilityService = { createFacilityLocation, createVirtualFacility, createEnumeration, + createFacilityEmailAddress, createFacilityCalendar, createFacilityIdentification, createFacilityPostalAddress, @@ -841,6 +858,7 @@ export const FacilityService = { removeFacilityFromGroup, removePartyFromFacility, updateFacility, + updateFacilityEmailAddress, updateFacilityGroup, updateFacilityIdentification, updateFacilityLocation, diff --git a/src/store/modules/facility/actions.ts b/src/store/modules/facility/actions.ts index e103f4bd..dca46ac0 100644 --- a/src/store/modules/facility/actions.ts +++ b/src/store/modules/facility/actions.ts @@ -227,64 +227,57 @@ const actions: ActionTree = { commit(types.FACILITY_CURRENT_UPDATED, facility); }, - async fetchFacilityContactDetails({ commit }, payload) { - let postalAddress = {} as any - const params = { - inputFields: { - contactMechPurposeTypeId: 'PRIMARY_LOCATION', - contactMechTypeId: 'POSTAL_ADDRESS', - facilityId: payload.facilityId - }, - entityName: "FacilityContactDetailByPurpose", - orderBy: 'fromDate DESC', - filterByDate: 'Y', - fieldList: ['address1', 'address2', 'city', 'contactMechId', 'countryGeoId', 'countryGeoName', 'latitude', 'longitude', 'postalCode', 'stateGeoId', 'stateGeoName', 'toName'], - viewSize: 1 - } - - try { - const resp = await FacilityService.fetchFacilityContactDetails(params) - if(!hasError(resp)) { - postalAddress = resp.data.docs[0] - postalAddress = { - ...postalAddress, - stateProvinceGeoId: postalAddress.stateGeoId - } - delete postalAddress.stateGeoId - } else { - throw resp.data - } - } catch(err) { - logger.error('Failed to fetch the postal address for the facility', err) - } - - commit(types.FACILITY_POSTAL_ADDRESS_UPDATED , postalAddress); - }, - async fetchFacilityTelecomNumber({ commit }, payload) { - let telecomNumber; - const params = { + async fetchFacilityContactDetailsAndTelecom({ commit }, facility) { + let postalAddress = {} as any; + const contactDetails = {} as any; + + const payload = { inputFields: { - contactMechPurposeTypeId: 'PRIMARY_PHONE', - contactMechTypeId: 'TELECOM_NUMBER', - facilityId: payload.facilityId + contactMechPurposeTypeId: ['PRIMARY_PHONE', 'PRIMARY_EMAIL', 'PRIMARY_LOCATION'], + contactMechPurposeTypeId_op: 'in', + contactMechTypeId: ['TELECOM_NUMBER', 'EMAIL_ADDRESS', 'POSTAL_ADDRESS'], + contactMechTypeId_op: 'in', + facilityId: facility.facilityId }, entityName: "FacilityContactDetailByPurpose", orderBy: 'fromDate DESC', filterByDate: 'Y', - fieldList: ['contactMechId', 'contactNumber', 'countryCode'], - viewSize: 1 + fieldList: ['address1', 'address2', 'city', 'contactMechId', 'contactMechTypeId', 'contactNumber', 'countryCode', 'countryGeoId', 'countryGeoName', 'infoString', 'latitude', 'longitude', 'postalCode', 'stateGeoId', 'stateGeoName', 'toName'], + viewSize: 3 } try { - const resp = await FacilityService.fetchFacilityContactDetails(params) + const resp = await FacilityService.fetchFacilityContactDetails(payload); if(!hasError(resp)) { - telecomNumber = resp.data.docs[0] - commit(types.FACILITY_TELECOM_NUMBER_UPDATED , telecomNumber); + const docs = resp.data.docs + + docs.map((item: any) => { + if(item.contactMechTypeId === "POSTAL_ADDRESS") { + postalAddress = { + ...item, + stateProvinceGeoId: item.stateGeoId + } + } else if (item.contactMechTypeId === 'TELECOM_NUMBER') { + contactDetails.telecomNumber = { + contactMechId: item.contactMechId, + contactNumber: item.contactNumber, + countryCode: item.countryCode, + } + } else if (item.contactMechTypeId === 'EMAIL_ADDRESS') { + contactDetails.emailAddress = { + contactMechId: item.contactMechId, + infoString: item.infoString + } + } + }) + + commit(types.FACILITY_POSTAL_ADDRESS_UPDATED, postalAddress) + commit(types.FACILITY_TELECOM_AND_EMAIL_ADDRESS_UPDATED, contactDetails) } else { throw resp.data } } catch(err) { - logger.error('Failed to fetch the contact number for the facility', err) + logger.error('Failed to fetch facility contact details and telecom information', err) } }, diff --git a/src/store/modules/facility/getters.ts b/src/store/modules/facility/getters.ts index 8a071f85..8f95fcaf 100644 --- a/src/store/modules/facility/getters.ts +++ b/src/store/modules/facility/getters.ts @@ -51,8 +51,8 @@ const getters: GetterTree = { getPostalAddress(state) { return state.current?.postalAddress ? JSON.parse(JSON.stringify(state.current.postalAddress)) : {} }, - getTelecomNumber(state) { - return state.current?.telecomNumber + getTelecomAndEmailAddress(state) { + return state.current?.contactDetails } } export default getters; \ No newline at end of file diff --git a/src/store/modules/facility/mutation-types.ts b/src/store/modules/facility/mutation-types.ts index 07bcc8f4..a1ad6bf6 100644 --- a/src/store/modules/facility/mutation-types.ts +++ b/src/store/modules/facility/mutation-types.ts @@ -5,7 +5,7 @@ export const FACILITY_GROUP_QUERY_UPDATED = SN_FACILITY + '/GROUP_QUERY_UPDATED' export const FACILITY_CURRENT_UPDATED = SN_FACILITY + '/CURRENT_UPDATED' export const FACILITY_LOCATIONS_UPDATED = SN_FACILITY + '/LOCATIONS_UPDATED' export const FACILITY_POSTAL_ADDRESS_UPDATED = SN_FACILITY + '/POSTAL_ADDRESS_UPDATED' -export const FACILITY_TELECOM_NUMBER_UPDATED = SN_FACILITY + '/CONTACT_NUMBER_UPDATED' +export const FACILITY_TELECOM_AND_EMAIL_ADDRESS_UPDATED = SN_FACILITY + '/TELECOM_AND_EMAIL_ADDRESS_UPDATED' export const FACILITY_MAPPINGS_UPDATED = SN_FACILITY + '/MAPPINGS_UPDATED' export const FACILITY_SHOPIFY_MAPPINGS_UPDATED = SN_FACILITY + '/SHOPIFY_MAPPINGS_UPDATED' export const FACILITY_CALENDAR_UPDATED = SN_FACILITY + '/CALENDAR_UPDATED' diff --git a/src/store/modules/facility/mutations.ts b/src/store/modules/facility/mutations.ts index 6c567c02..7fe45e09 100644 --- a/src/store/modules/facility/mutations.ts +++ b/src/store/modules/facility/mutations.ts @@ -19,8 +19,8 @@ const mutations: MutationTree = { [types.FACILITY_CURRENT_UPDATED](state, payload) { state.current = payload }, - [types.FACILITY_TELECOM_NUMBER_UPDATED](state, payload) { - state.current.telecomNumber = payload + [types.FACILITY_TELECOM_AND_EMAIL_ADDRESS_UPDATED](state, payload) { + state.current.contactDetails = payload }, [types.FACILITY_POSTAL_ADDRESS_UPDATED](state, payload) { state.current.postalAddress = payload diff --git a/src/views/AddFacilityAddress.vue b/src/views/AddFacilityAddress.vue index 1c1188e6..e0605ff6 100644 --- a/src/views/AddFacilityAddress.vue +++ b/src/views/AddFacilityAddress.vue @@ -48,11 +48,14 @@ - + {{ countryCode }} + + + @@ -72,7 +75,7 @@ - + @@ -116,7 +119,7 @@ import { mapGetters, useStore } from "vuex"; import { useRouter } from 'vue-router' import { colorWandOutline, locationOutline } from 'ionicons/icons'; import { translate } from "@hotwax/dxp-components"; -import { showToast } from "@/utils"; +import { showToast, isValidEmail } from "@/utils"; import logger from "@/logger"; import { getTelecomCountryCode, hasError } from "@/adapter"; import { FacilityService } from "@/services/FacilityService"; @@ -164,7 +167,8 @@ export default defineComponent({ longitude: '', }, contactNumber: '', - countryCode: '' + countryCode: '', + emailAddress: '' } }, props: ['facilityId'], @@ -179,6 +183,12 @@ export default defineComponent({ showToast("Please fill all the required fields.") return } + + if(this.emailAddress && !isValidEmail(this.emailAddress)) { + showToast(translate("Invalid email address")) + return + } + const payload = { facilityId: this.facilityId, contactMechPurposeTypeId: 'PRIMARY_LOCATION', @@ -198,6 +208,7 @@ export default defineComponent({ logger.error("Failed to create facility address.", error) } if(this.contactNumber) this.saveTelecomNumber() + if(this.emailAddress) this.saveEmailAddress() }, async generateLatLong() { const postalCode = this.formData.postalCode; @@ -235,7 +246,7 @@ export default defineComponent({ facilityId: this.facilityId, contactMechPurposeTypeId: 'PRIMARY_PHONE', contactNumber: this.contactNumber.trim(), - countryCode: this.countryCode + countryCode: this.countryCode.replace('+', '') }) if(hasError(resp)) { @@ -245,6 +256,22 @@ export default defineComponent({ logger.error(err) } }, + async saveEmailAddress() { + try { + const resp = await FacilityService.createFacilityEmailAddress({ + facilityId: this.facilityId, + contactMechTypeId: 'EMAIL_ADDRESS', + contactMechPurposeTypeId: 'PRIMARY_EMAIL', + emailAddress: this.emailAddress, + }) + + if(hasError(resp)) { + throw resp.data; + } + } catch(err) { + logger.error(err) + } + } }, setup() { const store = useStore(); diff --git a/src/views/FacilityDetails.vue b/src/views/FacilityDetails.vue index 0ef9b8b0..8b86f08b 100644 --- a/src/views/FacilityDetails.vue +++ b/src/views/FacilityDetails.vue @@ -53,7 +53,8 @@

{{ postalAddress.address2 }}

{{ postalAddress.postalCode ? `${postalAddress.city}, ${postalAddress.postalCode}` : postalAddress.city }}

{{ postalAddress.countryGeoName ? `${postalAddress.stateGeoName}, ${postalAddress.countryGeoName}` : postalAddress.stateGeoName }}

-

{{ `${telecomNumber.countryCode}-${telecomNumber.contactNumber}` }}

+

{{ `${contactDetails.telecomNumber?.countryCode}-${contactDetails.telecomNumber?.contactNumber}` }}

+

{{ contactDetails.emailAddress?.infoString }}

{{ translate("Edit") }} @@ -639,7 +640,7 @@ export default defineComponent({ baseUrl: "user/getBaseUrl", facilityGroupTypes: 'util/getFacilityGroupTypes', inventoryGroups: 'util/getInventoryGroups', - telecomNumber: 'facility/getTelecomNumber' + contactDetails: 'facility/getTelecomAndEmailAddress' }) }, props: ["facilityId"], @@ -651,7 +652,7 @@ export default defineComponent({ facilityTypeId: 'VIRTUAL_FACILITY', facilityTypeId_op: 'notEqual' })]) - 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.store.dispatch('facility/getFacilityProductStores', { facilityId: this.facilityId }), this.store.dispatch('util/fetchProductStores'), this.store.dispatch('facility/fetchFacilityContactDetails', { facilityId: this.facilityId }), this.store.dispatch('util/fetchCalendars'), this.store.dispatch('facility/fetchFacilityCalendar', { facilityId: this.facilityId }), this.store.dispatch('facility/fetchFacilityLogins', { facilityId: this.facilityId }), this.store.dispatch('facility/fetchFacilityTelecomNumber', { facilityId: this.facilityId })]) + 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.store.dispatch('facility/getFacilityProductStores', { facilityId: this.facilityId }), this.store.dispatch('util/fetchProductStores'), this.store.dispatch('facility/fetchFacilityContactDetailsAndTelecom', { facilityId: this.facilityId }), this.store.dispatch('util/fetchCalendars'), this.store.dispatch('facility/fetchFacilityCalendar', { facilityId: this.facilityId }), this.store.dispatch('facility/fetchFacilityLogins', { facilityId: this.facilityId })]) this.defaultDaysToShip = this.current.defaultDaysToShip this.isLoading = false this.parentFacilityTypeId = this.current.parentFacilityTypeId