Merge branch 'develop' into feature/CSR-1390-style

This commit is contained in:
CarlNation 2023-10-19 08:54:52 -04:00
commit cb09d401d2
8 changed files with 279 additions and 340 deletions

View file

@ -198,10 +198,6 @@ export default {
button { button {
margin: 0; margin: 0;
} }
@include media-breakpoint-up(md) {
position: relative;
background-color: transparent;
}
} }
} }
&.show .modal-dialog { &.show .modal-dialog {

View file

@ -69,7 +69,23 @@ afterEach(() => {
describe("Add-to-calendar methods...", () => { describe("Add-to-calendar methods...", () => {
test("Add-to-calendar should trigger openModal method", () => { test("Add-to-calendar should trigger openModal method", () => {
//Arrange //Arrange
const { wrapper } = setupMocks({});
const { wrapper } = setupMocks({
customMountOptions: {
propsData: {
appointment: {
RefrrlSeqNum: "123456",
StartDate: new Date(2023, 9, 11, 12, 0, 0),
EndDate: new Date(2023, 9, 11, 13, 0, 0),
Subject: "Meeting with John",
Location: "Conference Room",
Body: "Discuss the project progress",
IsHTML: true,
Duration: "1220",
},
},
},
});
//Act //Act
wrapper.vm.openCalendarModal(); wrapper.vm.openCalendarModal();
@ -77,45 +93,26 @@ describe("Add-to-calendar methods...", () => {
//Assert //Assert
expect(wrapper.vm.$refs.calendarModalQuestion.openModal).toBeCalled(); expect(wrapper.vm.$refs.calendarModalQuestion.openModal).toBeCalled();
}); });
test("serviceType should return 'replacement and recalibration' when isRepair is false and funnelHasRecalibrationPart true.", () => {
//Arrange
store.getters.order.damage.isRepair = false;
store.getters.funnelHasRecalibrationPart = true;
const { wrapper } = setupMocks({});
//Act
const testValue = wrapper.vm.serviceType();
//Assert
expect(testValue).toEqual("replacement and recalibration");
});
test("serviceType should return 'replacement' when isRepair is false and funnelHasRecalibrationPart is false.", () => {
//Arrange
store.getters.order.damage.isRepair = false;
store.getters.funnelHasRecalibrationPart = false;
const { wrapper } = setupMocks({});
//Act
const testValue = wrapper.vm.serviceType();
//Assert
expect(testValue).toEqual("replacement");
});
test("serviceType should return 'repair' when isRepair is true.", () => {
//Arrange
store.getters.order.damage.isRepair = true;
const { wrapper } = setupMocks({});
//Act
const testValue = wrapper.vm.serviceType();
//Assert
expect(testValue).toEqual("repair");
});
test("getCalendarData should return expected model value.", () => { test("getCalendarData should return expected model value.", () => {
//Arrange //Arrange
const type = calendarOptions.OUTLOOKCOM; const type = calendarOptions.OUTLOOKCOM;
const { wrapper } = setupMocks({}); const { wrapper } = setupMocks({
customMountOptions: {
propsData: {
appointment: {
RefrrlSeqNum: "123456",
StartDate: new Date(2023, 9, 11, 12, 0, 0),
EndDate: new Date(2023, 9, 11, 13, 0, 0),
Subject: "Meeting with John",
Location: "Conference Room",
Body: "Discuss the project progress",
IsHTML: true,
Duration: "1220",
},
},
},
});
//Act //Act
const testValue = wrapper.vm.getCalendarData(type); const testValue = wrapper.vm.getCalendarData(type);
@ -123,95 +120,26 @@ describe("Add-to-calendar methods...", () => {
//Assert //Assert
expect(testValue.name).toEqual(calendarOptions.OUTLOOKCOM); expect(testValue.name).toEqual(calendarOptions.OUTLOOKCOM);
}); });
test("getappointmentData should return expected model value for appointmentType mobile.", () => {
//Arrange
store.getters.order.serviceLocation.appointmentType = AppointmentTypeStrings.MOBILE;
store.getters.order.damage.isRepair = false;
store.getters.funnelHasRecalibrationPart = true;
const { wrapper } = setupMocks({});
//Act
const testValue = wrapper.vm.getappointmentData();
//Assert
expect(testValue.Subject).toEqual("Safelite replacement and recalibration appointment");
});
test("getappointmentData should return expected model value for appointmentType DROP_OFF and OVERNIGHT_DROP_OFF.", () => {
//Arrange
store.getters.order.serviceLocation.appointmentType = AppointmentTypeStrings.DROP_OFF;
store.getters.order.schedule.routeCode = RouteCodeFlags.OVERNIGHT_DROP_OFF;
const { wrapper } = setupMocks({});
//Act
const testValue = wrapper.vm.getappointmentData();
//Assert
expect(testValue.Subject).toEqual("Drop off your vehicle by 5:30 PM");
});
test("getappointmentData should return expected model value for appointmentType DROP_OFF and ALL_DAY_DROP_OFF and isSameDayDropOff.", () => {
//Arrange
store.getters.order.serviceLocation.appointmentType = AppointmentTypeStrings.DROP_OFF;
store.getters.order.schedule.routeCode = RouteCodeFlags.ALL_DAY_DROP_OFF;
store.getters.order.schedule.date = new Date().toISOString().split("T")[0];
const { wrapper } = setupMocks({});
//Act
const testValue = wrapper.vm.getappointmentData();
//Assert
expect(testValue.Subject).toEqual("Drop off your vehicle in the next 30 - 60 minutes");
});
test("getappointmentData should return expected model value for appointmentType DROP_OFF and ALL_DAY_DROP_OFF.", () => {
//Arrange
store.getters.order.serviceLocation.appointmentType = AppointmentTypeStrings.DROP_OFF;
store.getters.order.schedule.routeCode = RouteCodeFlags.ALL_DAY_DROP_OFF;
const { wrapper } = setupMocks({});
//Act
const testValue = wrapper.vm.getappointmentData();
//Assert
expect(testValue.Subject).toEqual("Drop off your vehicle between 9:00 AM - 11:00 AM");
});
test("getappointmentData should return expected model value for appointmentType DROP_OFF.", () => {
//Arrange
store.getters.order.serviceLocation.appointmentType = AppointmentTypeStrings.DROP_OFF;
store.getters.order.damage.isRepair = true;
const { wrapper } = setupMocks({});
//Act
const testValue = wrapper.vm.getappointmentData();
//Assert
expect(testValue.Subject).toEqual("Safelite repair appointment");
});
test("getappointmentData should return expected model value for appointmentType IN_SHOP.", () => {
//Arrange
store.getters.order.serviceLocation.appointmentType = AppointmentTypeStrings.IN_SHOP;
store.getters.order.damage.isRepair = true;
const { wrapper } = setupMocks({});
//Act
const testValue = wrapper.vm.getappointmentData();
//Assert
expect(testValue.Subject).toEqual("Safelite repair appointment");
});
test("isSameDayDropOff should return true for current schedule date.", () => {
//Arrange
store.getters.order.schedule.date = new Date().toISOString().split("T")[0];
const { wrapper } = setupMocks({});
//Act
const testValue = wrapper.vm.isSameDayDropOff();
//Assert
expect(testValue).toEqual(true);
});
test("setCalendarAppointment should call getAppointment method for iCAL and Outlook.", () => { test("setCalendarAppointment should call getAppointment method for iCAL and Outlook.", () => {
//Arrange //Arrange
const newValue = { name: calendarOptions.OUTLOOK }; const newValue = { name: calendarOptions.OUTLOOK };
const { wrapper } = setupMocks({}); const { wrapper } = setupMocks({
customMountOptions: {
propsData: {
appointment: {
RefrrlSeqNum: "123456",
StartDate: new Date(2023, 9, 11, 12, 0, 0),
EndDate: new Date(2023, 9, 11, 13, 0, 0),
Subject: "Meeting with John",
Location: "Conference Room",
Body: "Discuss the project progress",
IsHTML: true,
Duration: "1220",
},
},
},
});
wrapper.vm.getAppointment = jest.fn(); wrapper.vm.getAppointment = jest.fn();
//Act //Act
wrapper.vm.setCalendarAppointment(newValue); wrapper.vm.setCalendarAppointment(newValue);
@ -222,7 +150,22 @@ describe("Add-to-calendar methods...", () => {
test("setCalendarAppointment should call window.open for Google, yahoo and Outlook.com.", () => { test("setCalendarAppointment should call window.open for Google, yahoo and Outlook.com.", () => {
//Arrange //Arrange
const newValue = { name: calendarOptions.GOOGLE }; const newValue = { name: calendarOptions.GOOGLE };
const { wrapper } = setupMocks({}); const { wrapper } = setupMocks({
customMountOptions: {
propsData: {
appointment: {
RefrrlSeqNum: "123456",
StartDate: new Date(2023, 9, 11, 12, 0, 0),
EndDate: new Date(2023, 9, 11, 13, 0, 0),
Subject: "Meeting with John",
Location: "Conference Room",
Body: "Discuss the project progress",
IsHTML: true,
Duration: "1220",
},
},
},
});
window.open = jest.fn(); window.open = jest.fn();
//Act //Act

View file

@ -22,26 +22,19 @@
import { calendarOptions } from "@/constants/calendar-options"; import { calendarOptions } from "@/constants/calendar-options";
import { calendarStatus } from "@/constants/calendar-status"; import { calendarStatus } from "@/constants/calendar-status";
import calendarModalQuestion from "@/layouts/add-to-calendar/calendar-modal-question/calendar-modal-question"; import calendarModalQuestion from "@/layouts/add-to-calendar/calendar-modal-question/calendar-modal-question";
import { import { getDateFormat } from "@/helpers/date-helper";
getDateFormat,
calculateDuration,
combineDateAndTime,
shortTimeString,
addMinutes,
} from "@/helpers/date-helper";
import { getCalendarFile, download } from "@/helpers/add-to-calendar-helper"; import { getCalendarFile, download } from "@/helpers/add-to-calendar-helper";
import { AppointmentTypeStrings, RouteCodeFlags } from "@/constants/schedule-constants";
import store from "@/store";
import { serviceType } from "@/constants/service-type";
export default { export default {
name: "add-to-calendar", name: "add-to-calendar",
components: { components: {
calendarModalQuestion, calendarModalQuestion,
}, },
props: {
appointment: Object,
},
data() { data() {
return { return {
appointment: this.getappointmentData(),
selectedCalendarOption: null, selectedCalendarOption: null,
}; };
}, },
@ -83,67 +76,6 @@ export default {
openCalendarModal() { openCalendarModal() {
this.$refs["calendarModalQuestion"].openModal(); this.$refs["calendarModalQuestion"].openModal();
}, },
scheduleDate() {
return store.getters.order.schedule.date;
},
scheduleStartTime() {
return store.getters.order.schedule.startTime;
},
scheduleEndTime() {
return store.getters.order.schedule.endTime;
},
serviceLocationAddress() {
return store.getters.order.serviceLocation.address;
},
ServiceLocationAddress2() {
return store.getters.order.serviceLocation.address2;
},
serviceLocationCity() {
return store.getters.order.serviceLocation.city;
},
serviceLocationState() {
return store.getters.order.serviceLocation.state;
},
serviceLocationZipCode() {
return store.getters.order.serviceLocation.zipCode;
},
providerAddress() {
return store.getters.order.serviceLocation.provider.address.streetAddress;
},
providerCity() {
return store.getters.order.serviceLocation.provider.address.city;
},
providerState() {
return store.getters.order.serviceLocation.provider.address.state;
},
providerZipCode() {
return store.getters.order.serviceLocation.provider.address.zipCode;
},
appointmentType() {
return store.getters.order.serviceLocation.appointmentType;
},
uniqueId() {
return store.getters.order.referralNumber?.toString();
},
serviceType() {
const isRepair = store.getters.order.damage.isRepair;
const funnelHasRecalibrationPart = store.getters.funnelHasRecalibrationPart;
if (!isRepair) {
if (funnelHasRecalibrationPart) {
return serviceType.REPLACEMENT_AND_RECALIBRATION;
} else {
return serviceType.REPLACEMENT;
}
}
return serviceType.REPAIR;
},
routeCode() {
return store.getters.order.schedule.routeCode;
},
isSameDayDropOff() {
const todaysDate = new Date().toISOString().split("T")[0];
return this.scheduleDate() === todaysDate;
},
getCalendarData(type) { getCalendarData(type) {
var URL = ""; var URL = "";
const dateFormat = "yyyyMMddTHHmmss"; const dateFormat = "yyyyMMddTHHmmss";
@ -185,72 +117,6 @@ export default {
icon: require(`@/assets/img/icons/${type}.svg`), icon: require(`@/assets/img/icons/${type}.svg`),
}; };
}, },
getappointmentData() {
var subject = "";
var location = "";
var startDateTime = combineDateAndTime(this.scheduleDate(), this.scheduleStartTime());
var endDateTime = combineDateAndTime(this.scheduleDate(), this.scheduleEndTime());
var body = "";
var isHTML = false;
var duration = "";
if (this.appointmentType() === AppointmentTypeStrings.MOBILE) {
location = `${
this.ServiceLocationAddress2() ? this.ServiceLocationAddress2() + ", " : ""
}${this.serviceLocationAddress()}, ${this.serviceLocationCity()}, ${this.serviceLocationState()} ${this.serviceLocationZipCode()}`;
subject = `Safelite ${this.serviceType()} appointment`;
body =
"Your safety is our top priority, so we'll let you know who's coming to you and your tech will reach out to let you know when they're on the way.";
} else {
location = `${this.providerAddress()}, ${this.providerCity()}, ${this.providerState()} ${this.providerZipCode()}`;
if (this.appointmentType() === AppointmentTypeStrings.DROP_OFF) {
if (this.routeCode().includes(RouteCodeFlags.OVERNIGHT_DROP_OFF)) {
subject = "Drop off your vehicle by 5:30 PM";
body =
"Drop off your vehicle by 5:30 PM the night of your scheduled appointment. The shop will work with you on a convenient pick-up time.";
} else if (this.routeCode().includes(RouteCodeFlags.ALL_DAY_DROP_OFF)) {
if (this.isSameDayDropOff()) {
subject = "Drop off your vehicle in the next 30 - 60 minutes";
endDateTime = addMinutes(startDateTime, 120);
body =
"Drop your vehicle off in the next 30 - 60 minutes. We'll work your vehicle into our day's schedule. The shop will work with you on a convenient pick-up time.";
} else {
endDateTime = addMinutes(startDateTime, 120);
subject =
"Drop off your vehicle between " +
shortTimeString(startDateTime) +
" - " +
shortTimeString(endDateTime);
body = `Drop off your vehicle by ${shortTimeString(
endDateTime
)} and pick it up later in the day. When you arrive, park in an open space and follow the key drop instructions. We'll text you when your vehicle is ready.`;
}
} //normal time slot
else {
subject = `Safelite ${this.serviceType()} appointment`;
body = "Just a reminder that you're coming to us at " + location + ".";
}
} else {
subject = `Safelite ${this.serviceType()} appointment`;
body = "Just a reminder that you're coming to us at " + location + ".";
}
duration = calculateDuration(startDateTime, endDateTime);
}
return {
Subject: subject,
Location: location,
StartDate: startDateTime,
EndDate: endDateTime,
RefrrlSeqNum: this.uniqueId(),
Body: body,
IsHTML: isHTML,
Duration: duration,
};
},
getAppointment() { getAppointment() {
let body = this.appointment.Body; let body = this.appointment.Body;
body = body.replace("|", "<").replace("~", ">"); body = body.replace("|", "<").replace("~", ">");

View file

@ -115,16 +115,16 @@ describe("confirmation.vue", () => {
}); });
}); });
describe("computed properties...", () => { describe("computed properties...", () => {
// test("ScheduleDateFormatted should return date in expected format.", () => { test("ScheduleDateFormatted should return date in expected format.", () => {
// //Arrange //Arrange
// const { wrapper } = setupMocks({}); const { wrapper } = setupMocks({});
// // Act // Act
// const testValue = wrapper.vm.ScheduleDateFormatted; const testValue = wrapper.vm.ScheduleDateFormatted;
// // Assert // Assert
// expect(testValue).toEqual("Sunday, January 1"); expect(testValue).toEqual("Sunday, January 1");
// }); });
test("ScheduleTimeFormatted should return mobile time in expected format.", () => { test("ScheduleTimeFormatted should return mobile time in expected format.", () => {
//Arrange //Arrange
store.getters.order.serviceLocation.appointmentType = AppointmentTypeStrings.MOBILE; store.getters.order.serviceLocation.appointmentType = AppointmentTypeStrings.MOBILE;

View file

@ -10,10 +10,6 @@
<img :src="ScheduleConfirmationImage" /> <img :src="ScheduleConfirmationImage" />
<span v-html="ScheduleConfirmationText"></span> <span v-html="ScheduleConfirmationText"></span>
</div> </div>
<div
class="appoinmenttext"
v-html="this.getAppointmentWordingText"></div>
<div class="main"> <div class="main">
<div> <div>
<vehicleBanner <vehicleBanner
@ -21,16 +17,14 @@
:displayGenericVehicleImage="false" /> :displayGenericVehicleImage="false" />
</div> </div>
<div class="scheduleText"> <div class="scheduleText">
<p>{{ this.ScheduleDateFormatted }}</p> <p>{{ ScheduleDateFormatted }}</p>
<p>{{ this.ScheduleTimeFormatted }}</p> <p>{{ ScheduleTimeFormatted }}</p>
</div> </div>
<addToCalendar></addToCalendar> <addToCalendar :appointment="this.AppointmentData" />
<div <div class="appoinmenttext" v-html="AppointmentWordingText"></div>
class="appoinmenttext"
v-html="this.AppointmentWordingText"></div>
</div> </div>
<div class="emailtext" v-html="this.ConfirmationEmailText"></div> <div class="emailtext" v-html="ConfirmationEmailText"></div>
<navbar <navbar
cmsWidgetName="FunnelFooterWidget" cmsWidgetName="FunnelFooterWidget"
ref="navbar" ref="navbar"
@ -52,13 +46,19 @@ import navbar from "@/fmg-components/nav-bar/nav-bar";
import addToCalendar from "@/layouts/add-to-calendar/add-to-calendar"; import addToCalendar from "@/layouts/add-to-calendar/add-to-calendar";
//Supporting files //Supporting files
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper"; import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
import { AppointmentTypeStrings } from "@/constants/schedule-constants"; import { AppointmentTypeStrings, RouteCodeFlags } from "@/constants/schedule-constants";
import { settleAllPromises } from "@/helpers/layout-helper"; import { settleAllPromises } from "@/helpers/layout-helper";
import { applicationConfig } from "@/constants/application-config.js"; import { applicationConfig } from "@/constants/application-config.js";
import { convertDateStringToDate } from "@/layouts/schedule/helpers/schedule-helper"; import { convertDateStringToDate } from "@/layouts/schedule/helpers/schedule-helper";
import {
calculateDuration,
combineDateAndTime,
shortTimeString,
addMinutes,
} from "@/helpers/date-helper";
import { Form } from "vee-validate"; import { Form } from "vee-validate";
import store from "@/store"; import store from "@/store";
import { serviceType } from "@/constants/service-type";
import { get12HourTimeFormat, get12HourTimeMobileFormat } from "@/helpers/date-helper"; import { get12HourTimeFormat, get12HourTimeMobileFormat } from "@/helpers/date-helper";
export default { export default {
name: "confirmation", name: "confirmation",
@ -89,9 +89,9 @@ export default {
}, },
ConfirmationEmailText() { ConfirmationEmailText() {
return this.getCmsContent("ConfirmationEmailWidget", "BodyText") return this.getCmsContent("ConfirmationEmailWidget", "BodyText")
.replaceAll("{custom:MY_ACCOUNT_URL}", applicationConfig.MY_ACCOUNT) ?.replaceAll("{custom:MY_ACCOUNT_URL}", applicationConfig.MY_ACCOUNT)
.replaceAll("&lt;", "<") ?.replaceAll("&lt;", "<")
.replaceAll("&gt;", ">"); ?.replaceAll("&gt;", ">");
}, },
ScheduleDate() { ScheduleDate() {
return store.getters.order.schedule.date; return store.getters.order.schedule.date;
@ -143,17 +143,17 @@ export default {
}, },
AppointmentWordingText() { AppointmentWordingText() {
if (this.AppointmentType == AppointmentTypeStrings.MOBILE) { if (this.AppointmentType == AppointmentTypeStrings.MOBILE) {
return this.MobileWordingText.replaceAll( return this.MobileWordingText?.replaceAll(
"{custom:ADDRESS}", "{custom:ADDRESS}",
this.ServiceLocationFullAddress this.ServiceLocationFullAddress
); );
} else if (this.AppointmentType == AppointmentTypeStrings.DROP_OFF) { } else if (this.AppointmentType == AppointmentTypeStrings.DROP_OFF) {
return this.DropOffWordingText.replaceAll( return this.DropOffWordingText?.replaceAll(
"{custom:ADDRESS}", "{custom:ADDRESS}",
this.ProviderFullAddress this.ProviderFullAddress
); );
} else { } else {
return this.InShopWordingText.replaceAll( return this.InShopWordingText?.replaceAll(
"{custom:ADDRESS}", "{custom:ADDRESS}",
this.ProviderFullAddress this.ProviderFullAddress
); );
@ -190,6 +190,133 @@ export default {
return `at ${get12HourTimeFormat(this.ScheduleStartTime)}`; return `at ${get12HourTimeFormat(this.ScheduleStartTime)}`;
} }
}, },
IsSameDayDropOff() {
const todaysDate = new Date().toISOString().split("T")[0];
return this.ScheduleDate === todaysDate;
},
Mobile_Appointment_Subject() {
return this.getCmsContent("Mobile_Appointment_Widget", "HeaderText");
},
Mobile_Appointment_Body() {
return this.getCmsContent("Mobile_Appointment_Widget", "BodyText");
},
InShop_Appointment_Subject() {
return this.getCmsContent("InShop_Appointment_Widget", "HeaderText");
},
InShop_Appointment_Body() {
return this.getCmsContent("InShop_Appointment_Widget", "BodyText");
},
Drop_Off_Appointment_Subject() {
return this.getCmsContent("Drop_Off_Appointment_Widget", "HeaderText");
},
Drop_Off_Appointment_Body() {
return this.getCmsContent("Drop_Off_Appointment_Widget", "BodyText");
},
Overnight_Drop_Off_Appointment_Subject() {
return this.getCmsContent("Drop_Off_Appointment_Widget", "HeaderText");
},
Overnight_Drop_Off_Appointment_Body() {
return this.getCmsContent("Drop_Off_Appointment_Widget", "BodyText");
},
All_Day_Drop_Off_Appointment_Subject() {
return this.getCmsContent("All_Day_Drop_Off_Appointment_Widget", "HeaderText");
},
All_Day_Drop_Off_Appointment_Body() {
return this.getCmsContent("All_Day_Drop_Off_Appointment_Widget", "BodyText");
},
Same_Day_Drop_Off_Appointment_Subject() {
return this.getCmsContent("Same_Day_Drop_Off_Appointment_Widget", "HeaderText");
},
Same_Day_Drop_Off_Appointment_Body() {
return this.getCmsContent("Same_Day_Drop_Off_Appointment_Widget", "BodyText");
},
UniqueId() {
return store.getters.order.referralNumber?.toString();
},
ServiceType() {
const isRepair = store.getters.order.damage.isRepair;
const funnelHasRecalibrationPart = store.getters.funnelHasRecalibrationPart;
if (!isRepair) {
if (funnelHasRecalibrationPart) {
return serviceType.REPLACEMENT_AND_RECALIBRATION;
} else {
return serviceType.REPLACEMENT;
}
}
return serviceType.REPAIR;
},
RouteCode() {
return store.getters.order.schedule.routeCode;
},
AppointmentData() {
var subject = "";
var location = "";
var startDateTime = combineDateAndTime(this.ScheduleDate, this.ScheduleStartTime);
var endDateTime = combineDateAndTime(this.ScheduleDate, this.ScheduleEndTime);
var body = "";
var isHTML = false;
var duration = "";
if (this.AppointmentType === AppointmentTypeStrings.MOBILE) {
location = this.ServiceLocationFullAddress?.replace("<br/>", "");
subject = this.Mobile_Appointment_Subject?.replace(
"{custom:SERVICETYPE}",
this.ServiceType
);
body = this.Mobile_Appointment_Body;
} else {
location = this.ProviderFullAddress?.replace("<br/>", "");
if (this.AppointmentType === AppointmentTypeStrings.DROP_OFF) {
if (this.RouteCode.includes(RouteCodeFlags.OVERNIGHT_DROP_OFF)) {
subject = this.Overnight_Drop_Off_Appointment_Subject;
body = this.Overnight_Drop_Off_Appointment_Body;
} else if (this.RouteCode.includes(RouteCodeFlags.ALL_DAY_DROP_OFF)) {
if (this.IsSameDayDropOff) {
subject = this.Same_Day_Drop_Off_Appointment_Subject;
endDateTime = addMinutes(startDateTime, 120);
body = this.Same_Day_Drop_Off_Appointment_Body;
} else {
endDateTime = addMinutes(startDateTime, 120);
subject = this.All_Day_Drop_Off_Appointment_Subject?.replace(
"{custom:STARTDATETIME}",
shortTimeString(startDateTime)
).replace("{custom:ENDDATETIME}", shortTimeString(endDateTime));
body = this.All_Day_Drop_Off_Appointment_Body?.replace(
"{custom:ENDDATETIME}",
shortTimeString(endDateTime)
);
}
} //normal time slot
else {
subject = this.Drop_Off_Appointment_Subject?.replace(
"{custom:SERVICETYPE}",
this.ServiceType
);
body = this.Drop_Off_Appointment_Body?.replace(
"{custom:ADDRESS}",
location
);
}
} else {
subject = this.InShop_Appointment_Subject?.replace(
"{custom:SERVICETYPE}",
this.ServiceType
);
body = this.InShop_Appointment_Body?.replace("{custom:ADDRESS}", location);
}
duration = calculateDuration(startDateTime, endDateTime);
}
return {
Subject: subject,
Location: location,
StartDate: startDateTime,
EndDate: endDateTime,
RefrrlSeqNum: this.UniqueId,
Body: body,
IsHTML: isHTML,
Duration: duration,
};
},
}, },
data() { data() {
return { return {

View file

@ -7,7 +7,6 @@ import { getMountOptions } from "@/helpers/unit-test-helper";
import store from "@/store"; import store from "@/store";
import baseMixin from "@/mixins/base-mixin"; import baseMixin from "@/mixins/base-mixin";
import { getServiceabilityDetails } from "@/layouts/service-location/helpers/service-location-helper/service-location-helper";
// Define Mocks // Define Mocks
jest.mock("@/helpers/cms-content-helper", () => ({ jest.mock("@/helpers/cms-content-helper", () => ({
@ -412,6 +411,9 @@ describe("service-location.vue", () => {
const { wrapper } = setupMocks({}); const { wrapper } = setupMocks({});
await wrapper.setData({ await wrapper.setData({
shopProviderData: {
mobileProviderNumber: "001820",
},
selectedAppointmentType: "Mobile", selectedAppointmentType: "Mobile",
providerData: { mobileProviderNumber: "01820" }, providerData: { mobileProviderNumber: "01820" },
}); });
@ -464,6 +466,9 @@ describe("service-location.vue", () => {
const { wrapper } = setupMocks({}); const { wrapper } = setupMocks({});
await wrapper.setData({ await wrapper.setData({
shopProviderData: {
mobileProviderNumber: "001820",
},
selectedAppointmentType: "Mobile", selectedAppointmentType: "Mobile",
providerData: { mobileProviderNumber: "01820" }, providerData: { mobileProviderNumber: "01820" },
}); });
@ -528,6 +533,9 @@ describe("service-location.vue", () => {
const { wrapper } = setupMocks({}); const { wrapper } = setupMocks({});
await wrapper.setData({ await wrapper.setData({
shopProviderData: {
mobileProviderNumber: "001820",
},
selectedAppointmentType: "Mobile", selectedAppointmentType: "Mobile",
providerData: { mobileProviderNumber: "01820" }, providerData: { mobileProviderNumber: "01820" },
}); });
@ -984,14 +992,13 @@ describe("service-location.vue", () => {
describe("should be based only on glass serviceability if recalibration is not defined.", () => { describe("should be based only on glass serviceability if recalibration is not defined.", () => {
test("Should return true", async () => { test("Should return true", async () => {
// Arrange // Arrange
getServiceabilityDetails.mockImplementation(() => mockGetServiceabilityDetails = () =>
Promise.resolve({ Promise.resolve({
isGlassServiceableInshop: true, isGlassServiceableInshop: true,
isRecalibrationServiceableInshop: null, isRecalibrationServiceableInshop: null,
isGlassServiceableMobile: true, isGlassServiceableMobile: true,
isRecalibrationServiceableMobile: null, isRecalibrationServiceableMobile: null,
}) });
);
const { wrapper } = setupMocks({}); const { wrapper } = setupMocks({});
@ -1012,14 +1019,13 @@ describe("service-location.vue", () => {
test("Should return false", async () => { test("Should return false", async () => {
// Arrange // Arrange
getServiceabilityDetails.mockImplementation(() => mockGetServiceabilityDetails = () =>
Promise.resolve({ Promise.resolve({
isGlassServiceableInshop: false, isGlassServiceableInshop: false,
isRecalibrationServiceableInshop: null, isRecalibrationServiceableInshop: null,
isGlassServiceableMobile: false, isGlassServiceableMobile: false,
isRecalibrationServiceableMobile: null, isRecalibrationServiceableMobile: null,
}) });
);
const { wrapper } = setupMocks({}); const { wrapper } = setupMocks({});
@ -1040,14 +1046,13 @@ describe("service-location.vue", () => {
test("displayServiceableMobileOnly should be true if mobile is true and inshop is false.", async () => { test("displayServiceableMobileOnly should be true if mobile is true and inshop is false.", async () => {
// Arrange // Arrange
getServiceabilityDetails.mockImplementation(() => mockGetServiceabilityDetails = () =>
Promise.resolve({ Promise.resolve({
isGlassServiceableInshop: false, isGlassServiceableInshop: false,
isRecalibrationServiceableInshop: null, isRecalibrationServiceableInshop: null,
isGlassServiceableMobile: true, isGlassServiceableMobile: true,
isRecalibrationServiceableMobile: null, isRecalibrationServiceableMobile: null,
}) });
);
const { wrapper } = setupMocks({}); const { wrapper } = setupMocks({});
@ -1069,14 +1074,13 @@ describe("service-location.vue", () => {
test("displayServiceableMobileOnly should be false if mobile is false", async () => { test("displayServiceableMobileOnly should be false if mobile is false", async () => {
// Arrange // Arrange
getServiceabilityDetails.mockImplementation(() => mockGetServiceabilityDetails = () =>
Promise.resolve({ Promise.resolve({
isGlassServiceableInshop: false, isGlassServiceableInshop: false,
isRecalibrationServiceableInshop: null, isRecalibrationServiceableInshop: null,
isGlassServiceableMobile: false, isGlassServiceableMobile: false,
isRecalibrationServiceableMobile: null, isRecalibrationServiceableMobile: null,
}) });
);
const { wrapper } = setupMocks({}); const { wrapper } = setupMocks({});
@ -1098,14 +1102,13 @@ describe("service-location.vue", () => {
test("displayServiceableMobileOnly should be false if inShop is true", async () => { test("displayServiceableMobileOnly should be false if inShop is true", async () => {
// Arrange // Arrange
getServiceabilityDetails.mockImplementation(() => mockGetServiceabilityDetails = () =>
Promise.resolve({ Promise.resolve({
isGlassServiceableInshop: true, isGlassServiceableInshop: true,
isRecalibrationServiceableInshop: null, isRecalibrationServiceableInshop: null,
isGlassServiceableMobile: true, isGlassServiceableMobile: true,
isRecalibrationServiceableMobile: null, isRecalibrationServiceableMobile: null,
}) });
);
const { wrapper } = setupMocks({}); const { wrapper } = setupMocks({});
@ -1127,14 +1130,13 @@ describe("service-location.vue", () => {
test("requiresInshopRecalibration should not be true if recalibration info is null.", async () => { test("requiresInshopRecalibration should not be true if recalibration info is null.", async () => {
// Arrange // Arrange
getServiceabilityDetails.mockImplementation(() => mockGetServiceabilityDetails = () =>
Promise.resolve({ Promise.resolve({
isGlassServiceableInshop: true, isGlassServiceableInshop: true,
isRecalibrationServiceableInshop: null, isRecalibrationServiceableInshop: null,
isGlassServiceableMobile: true, isGlassServiceableMobile: true,
isRecalibrationServiceableMobile: null, isRecalibrationServiceableMobile: null,
}) });
);
const { wrapper } = setupMocks({}); const { wrapper } = setupMocks({});
@ -1158,14 +1160,13 @@ describe("service-location.vue", () => {
describe("should properly display alerts.", () => { describe("should properly display alerts.", () => {
test("Should show mobile-only error if only mobile is available.", async () => { test("Should show mobile-only error if only mobile is available.", async () => {
// Arrange // Arrange
getServiceabilityDetails.mockImplementation(() => mockGetServiceabilityDetails = () =>
Promise.resolve({ Promise.resolve({
isGlassServiceableInshop: false, isGlassServiceableInshop: false,
isRecalibrationServiceableInshop: false, isRecalibrationServiceableInshop: false,
isGlassServiceableMobile: true, isGlassServiceableMobile: true,
isRecalibrationServiceableMobile: true, isRecalibrationServiceableMobile: true,
}) });
);
const { wrapper } = setupMocks({}); const { wrapper } = setupMocks({});
@ -1187,14 +1188,13 @@ describe("service-location.vue", () => {
test("Should not show mobile-only error if not mobile-only.", async () => { test("Should not show mobile-only error if not mobile-only.", async () => {
// Arrange // Arrange
getServiceabilityDetails.mockImplementation(() => mockGetServiceabilityDetails = () =>
Promise.resolve({ Promise.resolve({
isGlassServiceableInshop: true, isGlassServiceableInshop: true,
isRecalibrationServiceableInshop: true, isRecalibrationServiceableInshop: true,
isGlassServiceableMobile: true, isGlassServiceableMobile: true,
isRecalibrationServiceableMobile: true, isRecalibrationServiceableMobile: true,
}) });
);
const { wrapper } = setupMocks({}); const { wrapper } = setupMocks({});
@ -1216,14 +1216,13 @@ describe("service-location.vue", () => {
test("Should show no-shop error if no shops are available.", async () => { test("Should show no-shop error if no shops are available.", async () => {
// Arrange // Arrange
getServiceabilityDetails.mockImplementation(() => mockGetServiceabilityDetails = () =>
Promise.resolve({ Promise.resolve({
isGlassServiceableInshop: false, isGlassServiceableInshop: false,
isRecalibrationServiceableInshop: false, isRecalibrationServiceableInshop: false,
isGlassServiceableMobile: false, isGlassServiceableMobile: false,
isRecalibrationServiceableMobile: false, isRecalibrationServiceableMobile: false,
}) });
);
const { wrapper } = setupMocks({}); const { wrapper } = setupMocks({});
@ -1245,14 +1244,13 @@ describe("service-location.vue", () => {
test("Should not show no-shop error if shops are available.", async () => { test("Should not show no-shop error if shops are available.", async () => {
// Arrange // Arrange
getServiceabilityDetails.mockImplementation(() => mockGetServiceabilityDetails = () =>
Promise.resolve({ Promise.resolve({
isGlassServiceableInshop: true, isGlassServiceableInshop: true,
isRecalibrationServiceableInshop: true, isRecalibrationServiceableInshop: true,
isGlassServiceableMobile: true, isGlassServiceableMobile: true,
isRecalibrationServiceableMobile: true, isRecalibrationServiceableMobile: true,
}) });
);
const { wrapper } = setupMocks({}); const { wrapper } = setupMocks({});
@ -1274,14 +1272,13 @@ describe("service-location.vue", () => {
test("Should show inshop-only error if only inshop is available", async () => { test("Should show inshop-only error if only inshop is available", async () => {
// Arrange // Arrange
getServiceabilityDetails.mockImplementation(() => mockGetServiceabilityDetails = () =>
Promise.resolve({ Promise.resolve({
isGlassServiceableInshop: true, isGlassServiceableInshop: true,
isRecalibrationServiceableInshop: true, isRecalibrationServiceableInshop: true,
isGlassServiceableMobile: false, isGlassServiceableMobile: false,
isRecalibrationServiceableMobile: false, isRecalibrationServiceableMobile: false,
}) });
);
const { wrapper } = setupMocks({}); const { wrapper } = setupMocks({});
@ -1303,14 +1300,13 @@ describe("service-location.vue", () => {
test("Should not show inshop-only error if not inshop-only", async () => { test("Should not show inshop-only error if not inshop-only", async () => {
// Arrange // Arrange
getServiceabilityDetails.mockImplementation(() => mockGetServiceabilityDetails = () =>
Promise.resolve({ Promise.resolve({
isGlassServiceableInshop: false, isGlassServiceableInshop: false,
isRecalibrationServiceableInshop: false, isRecalibrationServiceableInshop: false,
isGlassServiceableMobile: false, isGlassServiceableMobile: false,
isRecalibrationServiceableMobile: false, isRecalibrationServiceableMobile: false,
}) });
);
const { wrapper } = setupMocks({}); const { wrapper } = setupMocks({});
@ -1332,14 +1328,13 @@ describe("service-location.vue", () => {
test("Should not show inshop-only error if dual or static recalibration, but should show that error instead.", async () => { test("Should not show inshop-only error if dual or static recalibration, but should show that error instead.", async () => {
// Arrange // Arrange
getServiceabilityDetails.mockImplementation(() => mockGetServiceabilityDetails = () =>
Promise.resolve({ Promise.resolve({
isGlassServiceableInshop: true, isGlassServiceableInshop: true,
isRecalibrationServiceableInshop: true, isRecalibrationServiceableInshop: true,
isGlassServiceableMobile: true, isGlassServiceableMobile: true,
isRecalibrationServiceableMobile: false, isRecalibrationServiceableMobile: false,
}) });
);
const { wrapper } = setupMocks({}); const { wrapper } = setupMocks({});
@ -1363,14 +1358,13 @@ describe("service-location.vue", () => {
test("Should not show dual/static recalibration error if not those recalibration types", async () => { test("Should not show dual/static recalibration error if not those recalibration types", async () => {
// Arrange // Arrange
getServiceabilityDetails.mockImplementation(() => mockGetServiceabilityDetails = () =>
Promise.resolve({ Promise.resolve({
isGlassServiceableInshop: true, isGlassServiceableInshop: true,
isRecalibrationServiceableInshop: true, isRecalibrationServiceableInshop: true,
isGlassServiceableMobile: true, isGlassServiceableMobile: true,
isRecalibrationServiceableMobile: true, isRecalibrationServiceableMobile: true,
}) });
);
const { wrapper } = setupMocks({}); const { wrapper } = setupMocks({});

View file

@ -502,15 +502,26 @@ export default {
}, },
}, },
watch: { watch: {
selectedAppointmentType: { zipCode: {
async handler(newValue) { handler(newValue) {
if (newValue === "Mobile") { getShopProviderData(this.zipCode).then(async (result) => {
getShopProviderData(this.zipCode).then(async (result) => { this.shopProviderData = result.data;
this.shopProviderData = result.data; if (this.selectedAppointmentType === "Mobile") {
this.selectedProvider = new Provider( this.selectedProvider = new Provider(
this.shopProviderData.mobileProviderNumber this.shopProviderData.mobileProviderNumber
); );
}); } else {
this.selectedProvider = new Provider();
}
});
},
},
selectedAppointmentType: {
handler(newValue) {
if (newValue === "Mobile") {
this.selectedProvider = new Provider(
this.shopProviderData.mobileProviderNumber
);
} else { } else {
this.selectedProvider = new Provider(); this.selectedProvider = new Provider();
} }

View file

@ -214,6 +214,8 @@ export default {
}, },
shopProviders: { shopProviders: {
async handler(newValue) { async handler(newValue) {
this.resetAnswers();
await nextTick(); await nextTick();
const selectedShopIndex = this.getSelectedProviderIndex( const selectedShopIndex = this.getSelectedProviderIndex(
newValue, newValue,