Merge pull request #1092 from Safelite/feature/richardson/INSR-2birds.1pr
Misc fixes
This commit is contained in:
commit
d9ad960bf3
5 changed files with 99 additions and 60 deletions
|
|
@ -10,7 +10,7 @@
|
|||
When would you like service?
|
||||
</div>
|
||||
<div class="appointment-estimate-header">
|
||||
Your service will take approximately <span>{{ appointmentEstimate }}</span>
|
||||
Your service will take approximately <span>{{ appointmentEstimate }}</span>.
|
||||
</div>
|
||||
<div
|
||||
class="appointment-date-picker-container"
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
<div class="service-location-content-container">
|
||||
<serviceLocation
|
||||
ref="serviceLocation"
|
||||
:schedulingInshopAvailabilityRating="inShopAvailabilityRating"
|
||||
@appointmentTypeChanged="appointmentTypeChangedFromServiceLocation"
|
||||
@cityUpdated="cityUpdatedFromServiceLocation"
|
||||
@inShopZipUpdated="inShopZipUpdatedFromServiceLocation"
|
||||
|
|
@ -231,7 +232,7 @@ export default {
|
|||
const mobileFeePartPromise = getPricedMobileFeePart(serviceZipCode);
|
||||
const serviceabilityDetailsPromise = getServiceabilityDetails(serviceZipCode);
|
||||
const getGlassFeesPromise = useMainStore().getGlassFees();
|
||||
const providersPromise = useMainStore().getSafeliteProviders(serviceZipCode);
|
||||
const providersPromise = useMainStore().getSafeliteProviders(serviceZipCode, 150);
|
||||
|
||||
const premiumFeePromise = useMainStore().getMobilePremiumFee();
|
||||
const premiumFeeWithPricePromise = premiumFeePromise.then((result) => {
|
||||
|
|
@ -275,25 +276,39 @@ export default {
|
|||
|
||||
// use resultMap to populate layout content.
|
||||
const resultMap = await settleAllPromises(promiseResultMap);
|
||||
const providersUnderOneHundredMiles = resultMap.providers?.shopProviders?.filter((provider) => provider.distanceMiles <= 100);
|
||||
const serviceLocationData = {
|
||||
defaultMobileZipCode: isMobileAppointment
|
||||
? storeServiceLocation?.zipCode
|
||||
: '',
|
||||
glassFees: resultMap.glassFees,
|
||||
mobileFeePart: resultMap.mobileFeePart,
|
||||
providers: resultMap.providers,
|
||||
providers: {
|
||||
...resultMap.providers,
|
||||
shopProviders: providersUnderOneHundredMiles || []
|
||||
},
|
||||
serviceabilityDetails: resultMap.serviceabilityDetails,
|
||||
zipCodeData: resultMap.zipCodeData
|
||||
};
|
||||
useMainStore().updateIsSafeliteProvider(true);
|
||||
next(async (vm) => {
|
||||
const providerToUse = resultMap.providers?.shopProviders
|
||||
const foundProviderInFullList = resultMap.providers?.shopProviders
|
||||
.find((provider) => provider.providerNumber === storeSelectedProvider?.providerNumber) || resultMap.providers?.shopProviders[0];
|
||||
const foundProviderInHundredMiles = providersUnderOneHundredMiles
|
||||
.find((provider) => provider.providerNumber === storeSelectedProvider?.providerNumber) || providersUnderOneHundredMiles[0];
|
||||
|
||||
if (!foundProviderInHundredMiles && !foundProviderInFullList) {
|
||||
if (storeSelectedProvider?.providerNumber && resultMap.providers?.shopProviders) {
|
||||
serviceLocationData.providers?.shopProviders.push(storeSelectedProvider);
|
||||
}
|
||||
} else if (!foundProviderInHundredMiles && foundProviderInFullList) {
|
||||
serviceLocationData.providers?.shopProviders.push(foundProviderInFullList);
|
||||
}
|
||||
const initialServiceLocationObj = {
|
||||
mobileProviderNumber: isMobileAppointment
|
||||
? storeSelectedProvider?.providerNumber
|
||||
: null,
|
||||
provider: isMobileAppointment ? null : providerToUse,
|
||||
provider: isMobileAppointment ? null : foundProviderInFullList,
|
||||
zipCode: useMainStore().order.serviceLocation.zipCode || useMainStore().order.customer.address.zipCode,
|
||||
zipCodeCtu: resultMap.zipCodeData?.zipCodeCtu
|
||||
};
|
||||
|
|
@ -310,6 +325,7 @@ export default {
|
|||
},
|
||||
data() {
|
||||
return {
|
||||
inShopAvailabilityRating: 'high',
|
||||
inShopDatesData: [],
|
||||
isMobileView: false,
|
||||
mobileDatesData: [],
|
||||
|
|
@ -364,6 +380,27 @@ export default {
|
|||
return useMainStore().lineItems.supportingItems;
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
inShopDatesData(newData) {
|
||||
if (newData?.initialShopTimeSlotsResponse?.days?.length > 0) {
|
||||
const numberOfDaysNeededToBeHighAvailability = 2;
|
||||
const availabilityEndDate = new Date();
|
||||
availabilityEndDate.setDate(availabilityEndDate.getDate() + 6);
|
||||
|
||||
const datesInAvailabilityRange = newData.initialShopTimeSlotsResponse.days.filter((day) => {
|
||||
const dayDate = new Date(`${day.date}T00:00:00`);
|
||||
return dayDate <= availabilityEndDate;
|
||||
});
|
||||
const isGoodAvailability =
|
||||
datesInAvailabilityRange.filter((x) => x.timeSlots.length > 0).length
|
||||
>= numberOfDaysNeededToBeHighAvailability;
|
||||
|
||||
this.inShopAvailabilityRating = isGoodAvailability ? 'high' : 'low';
|
||||
} else {
|
||||
this.inShopAvailabilityRating = 'low';
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
showIssLoadingModal(true);
|
||||
this.mql = window.matchMedia('(min-width: 1200px)');
|
||||
|
|
@ -453,9 +490,6 @@ export default {
|
|||
},
|
||||
getAvailableDates,
|
||||
async getDatePickerInitialData(defaultProviderNumber = null) {
|
||||
this.inShopDatesData = [];
|
||||
this.mobileDatesData = [];
|
||||
|
||||
let todayDateString;
|
||||
const todayDateObject = new Date();
|
||||
const calendarViewDirection = 'future';
|
||||
|
|
@ -504,7 +538,20 @@ export default {
|
|||
preSelectedDate,
|
||||
initialDaysLoaded: endDateObject.newDaysLoaded || initialDays,
|
||||
daysFromStart: endDateObject.daysFromStart || null
|
||||
}));
|
||||
}))
|
||||
.catch(() => {
|
||||
console.warn('Error fetching initial available dates...');
|
||||
return {
|
||||
todayDate: todayDateString,
|
||||
initialViewStartDate,
|
||||
initialViewEndDate,
|
||||
calendarViewDirection,
|
||||
initialShopTimeSlotsResponse: { days: [] },
|
||||
preSelectedDate,
|
||||
initialDaysLoaded: endDateObject.newDaysLoaded || initialDays,
|
||||
daysFromStart: endDateObject.daysFromStart || null
|
||||
};
|
||||
});
|
||||
|
||||
if (this.selectedAppointmentType === AppointmentTypeStrings.MOBILE
|
||||
|| this.selectedAppointmentType === AppointmentTypeStrings.MOBILE_NOT_ITAC_AND_NOT_NOCOMP) {
|
||||
|
|
@ -532,6 +579,7 @@ export default {
|
|||
}
|
||||
} else {
|
||||
this.inShopDatesData = initialData;
|
||||
this.mobileDatesData = [];
|
||||
}
|
||||
|
||||
return initialData;
|
||||
|
|
@ -618,12 +666,20 @@ export default {
|
|||
}
|
||||
}
|
||||
},
|
||||
providerChangedFromServiceLocation(newProvider) {
|
||||
async providerChangedFromServiceLocation(newProvider) {
|
||||
this.selectedProvider = newProvider?.provider;
|
||||
if (newProvider?.refreshDatePicker && newProvider.provider) {
|
||||
this.mainStore.updateServiceLocationProvider(newProvider.provider);
|
||||
|
||||
if (newProvider?.refreshDatePicker) {
|
||||
showIssLoadingModal(true);
|
||||
this.refreshDatePicker();
|
||||
await this.mainStore.getBillToInfo(newProvider.provider?.providerNumber)
|
||||
.then(() => {
|
||||
this.refreshDatePicker();
|
||||
})
|
||||
.catch(() => {
|
||||
console.warn('Error fetching bill to info...');
|
||||
showIssLoadingModal(false);
|
||||
});
|
||||
}
|
||||
},
|
||||
async refreshDatePicker() {
|
||||
|
|
|
|||
|
|
@ -129,7 +129,6 @@ import errorMessages from '@/constants/error-messages';
|
|||
import { useMainStore } from '@/store';
|
||||
import showIssLoadingModal from '@/helpers/loading-modal-helper.js';
|
||||
import {
|
||||
getAvailabilityRating,
|
||||
getServiceabilityDetails,
|
||||
getZipCodeData,
|
||||
getMobileZipCodeData
|
||||
|
|
@ -160,6 +159,12 @@ export default {
|
|||
},
|
||||
mixins: [baseFormMixin],
|
||||
emits: ['appointment-type-changed', 'city-updated', 'in-shop-zip-updated', 'mobile-zip-updated', 'provider-changed'],
|
||||
props: {
|
||||
schedulingInshopAvailabilityRating: {
|
||||
type: String,
|
||||
default: 'high'
|
||||
}
|
||||
},
|
||||
setup() {
|
||||
const mainStore = useMainStore();
|
||||
return { mainStore };
|
||||
|
|
@ -198,7 +203,7 @@ export default {
|
|||
return this.isBigTruck && !this.isServiceableInshop && !this.isServiceableMobile;
|
||||
},
|
||||
displayLowAvailabilityInshop() {
|
||||
return this.availabilityRating === 'low' && this.isInshop;
|
||||
return this.availabilityRating === 'low' && this.isInshop && this.selectedProvider !== null;
|
||||
},
|
||||
displayMilitaryZipAlert() {
|
||||
return this.zipContainsMilitaryBase && this.isServiceableMobile;
|
||||
|
|
@ -307,10 +312,11 @@ export default {
|
|||
this.$emit('mobile-zip-updated', updateMobileZipServiceLocationObj);
|
||||
}
|
||||
},
|
||||
schedulingInshopAvailabilityRating(newRating) {
|
||||
this.availabilityRating = newRating;
|
||||
},
|
||||
selectedAppointmentType(newValue, oldValue) {
|
||||
if (this.isInshop && this.selectedProvider && this.availabilityRating === null) {
|
||||
this.refreshAvailabilityRating();
|
||||
|
||||
const appointmenTypeServiceLocationObj = {
|
||||
appointmentType: newValue,
|
||||
mobileProviderNumber: null,
|
||||
|
|
@ -342,10 +348,6 @@ export default {
|
|||
refreshDatePicker: appointmentIsInshop && oldProvider?.providerNumber !== null
|
||||
};
|
||||
|
||||
if (appointmentIsInshop && newProvider?.providerNumber != null) {
|
||||
this.refreshAvailabilityRating();
|
||||
}
|
||||
|
||||
if (newProvider?.providerNumber !== oldProvider?.providerNumber) {
|
||||
this.$emit('provider-changed', returnedProvider);
|
||||
}
|
||||
|
|
@ -444,24 +446,6 @@ export default {
|
|||
this.$emit('in-shop-zip-updated', inShopZipServiceLocationObj);
|
||||
});
|
||||
},
|
||||
refreshAvailabilityRating() {
|
||||
const startDate = new Date();
|
||||
const endDate = new Date();
|
||||
endDate.setDate(startDate.getDate() + 6);
|
||||
const formattedStartDate = startDate.toISOString().split('T')[0];
|
||||
const formattedEndDate = endDate.toISOString().split('T')[0];
|
||||
|
||||
getAvailabilityRating(
|
||||
formattedStartDate,
|
||||
formattedEndDate,
|
||||
AppointmentTypeStrings.IN_SHOP,
|
||||
this.selectedProvider ? this.selectedProvider.providerNumber : null
|
||||
).then((rating) => {
|
||||
this.availabilityRating = rating;
|
||||
}).catch(() => {
|
||||
this.availabilityRating = null;
|
||||
});
|
||||
},
|
||||
setCtuForMobile(val) {
|
||||
this.zipCodeCtu = val;
|
||||
},
|
||||
|
|
@ -636,5 +620,8 @@ $page-side-padding: 1.5rem;
|
|||
}
|
||||
}
|
||||
}
|
||||
:deep(.alert-shop-distance) {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -68,8 +68,7 @@
|
|||
groupName="chooseShop"
|
||||
textPosition="text-start"
|
||||
isRequired
|
||||
validationRules="option-required"
|
||||
:additionalButtonData="additionalButtonData" />
|
||||
validationRules="option-required" />
|
||||
<span class="service-zip-prompt">
|
||||
{{ serviceZipPrompt }}
|
||||
</span>
|
||||
|
|
@ -108,7 +107,6 @@ import baseMixin from '@/mixins/base-mixin.js';
|
|||
import showIssLoadingModal from '@/helpers/loading-modal-helper.js';
|
||||
import { toTitleCase } from '@/helpers/text-helper.js';
|
||||
import { markRaw } from 'vue';
|
||||
import { getAvailabilityRating } from '@/helpers/service-location-helper';
|
||||
import { useMainStore } from '@/store';
|
||||
import widgetFields from '@/constants/cms-widget-fields';
|
||||
import { dropdownVariants, modalPositions } from '@/constants/component-variants';
|
||||
|
|
@ -185,22 +183,6 @@ export default {
|
|||
modalName() {
|
||||
return this.modalWidgetName;
|
||||
},
|
||||
additionalButtonData() {
|
||||
const startDate = new Date();
|
||||
const endDate = new Date();
|
||||
endDate.setDate(startDate.getDate() + 6);
|
||||
|
||||
const formattedStartDate = startDate.toISOString().split('T')[0];
|
||||
const formattedEndDate = endDate.toISOString().split('T')[0];
|
||||
|
||||
return {
|
||||
displayAvailabilityIndicators: false,
|
||||
availabilityRatingCallback: getAvailabilityRating,
|
||||
startDate: formattedStartDate,
|
||||
endDate: formattedEndDate,
|
||||
shopAppointmentType: 'InshopOrDropoff'
|
||||
};
|
||||
},
|
||||
serviceZipPrompt() {
|
||||
return this.getCmsContent(this.modalWidgetName, widgetFields.CONTENT_GROUP_WIDGET.BODY_TEXT_2);
|
||||
},
|
||||
|
|
@ -271,6 +253,7 @@ export default {
|
|||
currentSearchIndex += 1;
|
||||
}
|
||||
if (result.length === 0) {
|
||||
this.nearbyShops = [];
|
||||
this.errorMessage = errorMessages.ZIP_CODE_NOT_SERVICED_FOR_VEHICLE;
|
||||
} else {
|
||||
if (!result.find((shop) => shop.providerNumber === this.internalProviderNumber)) {
|
||||
|
|
|
|||
|
|
@ -1848,7 +1848,20 @@ export const useMainStore = defineStore({
|
|||
}
|
||||
this.order.serviceLocation.tpaSearchRadius = serviceLocationInfo.tpaSearchRadius;
|
||||
},
|
||||
|
||||
updateServiceLocationProvider(providerInfo) {
|
||||
this.order.serviceLocation.provider = {
|
||||
providerNumber: providerInfo?.providerNumber,
|
||||
address: {
|
||||
streetAddress: providerInfo?.address?.streetAddress,
|
||||
city: providerInfo?.address?.city,
|
||||
state: providerInfo?.address?.state,
|
||||
zipCode: providerInfo?.address?.zipCode,
|
||||
zipCodeCtu: providerInfo?.address?.zipCodeCtu
|
||||
},
|
||||
companyName: providerInfo?.companyName,
|
||||
phoneNumber: providerInfo?.phoneNumber
|
||||
};
|
||||
},
|
||||
resetState() {
|
||||
Object.assign(this, getDefaultState());
|
||||
},
|
||||
|
|
@ -2684,12 +2697,12 @@ export const useMainStore = defineStore({
|
|||
}
|
||||
},
|
||||
|
||||
async getBillToInfo() {
|
||||
async getBillToInfo(componentProviderNumber = null) {
|
||||
const { order, issConfig } = this;
|
||||
try {
|
||||
const params = new URLSearchParams({
|
||||
parentAccountNumber: order.parentAccountNumber.toString(),
|
||||
providerNumber: this.providerNumber,
|
||||
providerNumber: componentProviderNumber || this.providerNumber,
|
||||
typeOfClaim: 'GLASS ONLY',
|
||||
lineOfBusiness: 'PERSONAL',
|
||||
isItac: this.isITAC
|
||||
|
|
|
|||
Loading…
Reference in a new issue