recalAckModal WIP

This commit is contained in:
Katie Kroell 2026-03-24 15:18:24 -04:00
parent b7d87252de
commit 29f727a342
3 changed files with 131 additions and 22 deletions

View file

@ -52,3 +52,31 @@ export function getRecalPartNumbers(glassPartsArray) {
} }
} }
export function containsRecalParts(lineItems) {
if (!lineItems) {
return false;
}
if (Array.isArray(lineItems)) {
return lineItems.some((li) => isRecalPartOrHasChildRecalPart(li));
} else {
// complex object form -- flatten and re-call.
const flattened = [
...(lineItems.glassParts ?? []),
...(lineItems.supportingItems ?? []),
...(lineItems.vaps ?? []),
...(lineItems.promos ?? []),
];
return flattened.some((li) => isRecalPartOrHasChildRecalPart(li));
}
}
export function anyPartWithRequiresRecalFlag(lineItems) {
if (!lineItems) {
return false;
}
return lineItems.glassParts?.some((li) => li.requiresRecalibration === true);
}

View file

@ -46,6 +46,19 @@
:customSelectableDatesCallback="getAvailableDatesMethod" :customSelectableDatesCallback="getAvailableDatesMethod"
@dateSelected="dateSelectedFromPicker" @dateSelected="dateSelectedFromPicker"
@timeSlotSelected="timeSlotSelectedFromPicker" /> @timeSlotSelected="timeSlotSelectedFromPicker" />
<modal
ref="recalAckModal"
class="recal-ack-modal"
:headerText="recalModalContent.headerText"
:footerButtonText="recalModalContent.footerButtonText"
@footerButtonEvent="closeRecalModal">
<div class="recal-ack-modal-subheader">
{{ recalModalContent.subHeaderText }}
</div>
<div
class="recal-ack-modal-body"
v-html="recalModalContent.bodyText"></div>
</modal>
</div> </div>
</div> </div>
<div class="site-footer-container iss-heritage-content-container-width"> <div class="site-footer-container iss-heritage-content-container-width">
@ -70,6 +83,7 @@ import locationAlerts from '@/layouts/schedule-page/location-alerts/location-ale
import datePicker from '@/digital-components/date-picker/date-picker.vue'; import datePicker from '@/digital-components/date-picker/date-picker.vue';
import serviceLocation from '@/layouts/schedule-page/service-location/service-location.vue'; import serviceLocation from '@/layouts/schedule-page/service-location/service-location.vue';
import siteFooter from '@/iss-components/site-footer/site-footer.vue'; import siteFooter from '@/iss-components/site-footer/site-footer.vue';
import modal from '@/digital-components/modal/modal.vue';
// Supporting files // Supporting files
import { import {
@ -96,6 +110,7 @@ import {
import { Form } from 'vee-validate'; import { Form } from 'vee-validate';
import BaseFormMixin from '@/mixins/base-form-mixin.js'; import BaseFormMixin from '@/mixins/base-form-mixin.js';
import { useMainStore } from '@/store'; import { useMainStore } from '@/store';
import { containsRecalParts } from '@/helpers/recal-helper';
// Define constants // Define constants
const TIME_SLOTS_CALL_DAYS_LIMIT = 15; const TIME_SLOTS_CALL_DAYS_LIMIT = 15;
@ -219,7 +234,8 @@ export default {
datePicker, datePicker,
serviceLocation, serviceLocation,
siteFooter, siteFooter,
Form Form,
modal
}, },
mixins: [BaseFormMixin], mixins: [BaseFormMixin],
async beforeRouteEnter(to, from, next) { async beforeRouteEnter(to, from, next) {
@ -393,7 +409,28 @@ export default {
}, },
supportingItems() { supportingItems() {
return useMainStore().lineItems.supportingItems; return useMainStore().lineItems.supportingItems;
} },
displayRecalAckModalwidget() {
// if any of the glass parts contain an item with the requiresRecalibration flag set to true
// and the order does not contain a recalibration part, show the recalibration acknowledgement modal
const containsRecalPart = containsRecalParts(useMainStore().order.lineItems);
const hasPartWithRecalRequirement = anyPartWithRequiresRecalFlag(useMainStore().order.lineItems);
if (!containsRecalPart && hasPartWithRecalRequirement) {
return true;
}
return false;
},
recalModalContent() {
const widgetName = 'RecalAckModalWidget';
return {
headerText: this.getCmsContent(widgetName, widgetFields.CONTENT_GROUP_WIDGET.HEADER_TEXT),
subHeaderText: this.getCmsContent(widgetName, widgetFields.CONTENT_GROUP_WIDGET.SUBHEADER_TEXT),
bodyText: this.getCmsContent(widgetName, widgetFields.CONTENT_GROUP_WIDGET.BODY_TEXT),
bodyText2: this.getCmsContent(widgetName, widgetFields.CONTENT_GROUP_WIDGET.BODY_TEXT_2),
footerButtonText: this.getCmsContent(widgetName, widgetFields.CONTENT_GROUP_WIDGET.FOOTER_TEXT)
};
},
}, },
watch: { watch: {
inShopDatesData(newData) { inShopDatesData(newData) {

View file

@ -22,11 +22,12 @@ import {
repairWaivedForSelectedVehicle repairWaivedForSelectedVehicle
} from '@/helpers/policy-vehicle-helper'; } from '@/helpers/policy-vehicle-helper';
import { buildURLSearchParams, getPartNumbersListForQueryString } from '@/helpers/querystring-helper'; import { buildURLSearchParams, getPartNumbersListForQueryString } from '@/helpers/querystring-helper';
import { getTopLevelGlassPartsWithRecal } from '@/helpers/recal-helper'; import { getTopLevelGlassPartsWithRecal, isRecalPartOrHasChildRecalPart } from '@/helpers/recal-helper';
import { getDateForSavedSessionTimeout } from '@/helpers/session-helper'; import { getDateForSavedSessionTimeout } from '@/helpers/session-helper';
import { isMobileDevice } from '@/helpers/useragent-helper'; import { isMobileDevice } from '@/helpers/useragent-helper';
import issPageValues from '@/router/router-constants/issPage-values'; import issPageValues from '@/router/router-constants/issPage-values';
import CoverageStatuses from '@/constants/coverage-statuses'; import CoverageStatuses from '@/constants/coverage-statuses';
import { buildQueryStringParameterFromArrayOfComplexObjects } from '@/helpers/querystring-helper';
const storeId = 'main'; const storeId = 'main';
@ -1343,28 +1344,72 @@ export const useMainStore = defineStore({
}, },
getServiceabilityDetails(serviceZipCode) { getServiceabilityDetails(serviceZipCode) {
const { vehicle, damage, parentAccountNumber, referralSequenceNumber, lineItems } = this.order; const { vehicle, damage, parentAccountNumber, referralSequenceNumber } = this.order;
const { carId } = vehicle; const escapeRecalibrationType = (rt) => rt.split("&").join("%26");
const glassArray = convertGlassPieceNamingForApi(damage.glassToReplace);
const lineItemParts = [...(lineItems.glassParts || []), ...(lineItems.supportingItems || [])].map((part) => ({
partNumber: part.partNumber,
recalibrationType: part.recalibrationType
}));
const params = buildURLSearchParams({ const partialLineItemsObjects = this.order.lineItems.glassParts?.map(
applicationName: applicationConfig.APPLICATION_NAME, (lineItem) => ({
parentAccountNumber, partNumber: lineItem.partNumber,
referralSequenceNumber, recalibrationType:
zip: serviceZipCode, lineItem.recalibrationType && isRecalPartOrHasChildRecalPart(lineItem)
carId, ? escapeRecalibrationType(lineItem.recalibrationType)
glassPieces: glassArray, : undefined,
lineItems: lineItemParts })
}); );
var lineItems = null;
if (partialLineItemsObjects) {
lineItems = buildQueryStringParameterFromArrayOfComplexObjects(
partialLineItemsObjects,
"lineItems"
);
}
const carId = vehicle.carId;
const glassArray = convertGlassPieceNamingForApi(damage.glassToReplace);
const glassPieces = buildQueryStringParameterFromArrayOfComplexObjects(
glassArray,
"glassPieces"
);
var endPoint = `${endpoints.GetServiceabilityDetails.url}?zip=${serviceZipCode}&carId=${carId}&parentAccountNumber=${parentAccountNumber}&referralSequenceNumber=${referralSequenceNumber}&applicationName=${applicationConfig.ANALYTICS_APPLICATION_NAME}`;
if (lineItems) {
endPoint += `&${lineItems}`;
}
if (glassPieces) {
endPoint += `&${glassPieces}`;
}
endPoint += `&isHeavyTruckVehicle=${vehicle.isBigTruck}`;
return globalMethods.callHttpClient({ return globalMethods.callHttpClient({
method: endpoints.GetServiceabilityDetails.method, method: endpoints.GetServiceabilityDetails.method,
endpoint: `${endpoints.GetServiceabilityDetails.url}?${params.toString()}` endpoint: endPoint
}); });
// const { vehicle, damage, parentAccountNumber, referralSequenceNumber, lineItems } = this.order;
// const { carId } = vehicle;
// const glassArray = convertGlassPieceNamingForApi(damage.glassToReplace);
// const lineItemParts = [...(lineItems.glassParts || []), ...(lineItems.supportingItems || [])].map((part) => ({
// partNumber: part.partNumber,
// recalibrationType: part.recalibrationType
// }));
// const params = buildURLSearchParams({
// applicationName: applicationConfig.APPLICATION_NAME,
// parentAccountNumber,
// referralSequenceNumber,
// zip: serviceZipCode,
// carId,
// glassPieces: glassArray,
// lineItems: lineItemParts
// });
// return globalMethods.callHttpClient({
// method: endpoints.GetServiceabilityDetails.method,
// endpoint: `${endpoints.GetServiceabilityDetails.url}?${params.toString()}`
// });
}, },
lookupVehicleByVin(vin) { lookupVehicleByVin(vin) {
return globalMethods.callHttpClient({ return globalMethods.callHttpClient({
@ -2787,7 +2832,6 @@ export const useMainStore = defineStore({
); );
}, },
updateContactInfo(contactInfo) { updateContactInfo(contactInfo) {
this.order.customer.firstName = contactInfo?.firstName ?? this.order.customer.firstName; this.order.customer.firstName = contactInfo?.firstName ?? this.order.customer.firstName;
this.order.customer.lastName = contactInfo?.lastName ?? this.order.customer.lastName; this.order.customer.lastName = contactInfo?.lastName ?? this.order.customer.lastName;