Merge pull request #1377 from Safelite/feature/CSR-1395-calculate-sales-tax
Feature/csr 1395 calculate sales tax
This commit is contained in:
commit
002dace442
10 changed files with 90 additions and 22 deletions
|
|
@ -31,5 +31,5 @@ module.exports = {
|
|||
},
|
||||
},
|
||||
// Uncomment this to avoid the massive amount of warnings we are getting for onSubmit and onInvalidSubmit
|
||||
// silent: true,
|
||||
silent: true,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
:answers="answersToDisplay"
|
||||
:groupName="groupName"
|
||||
buttonTypeString="listCard"
|
||||
v-model="selectedValues"
|
||||
v-model="selectedValue"
|
||||
:suppressError="suppressError"
|
||||
:validationRules="validationRules"
|
||||
isRequired />
|
||||
|
|
@ -55,7 +55,7 @@ export default {
|
|||
})
|
||||
: [];
|
||||
},
|
||||
selectedValues: {
|
||||
selectedValue: {
|
||||
get: function () {
|
||||
return this.modelValue;
|
||||
},
|
||||
|
|
|
|||
15
src/layouts/service-location/classes/provider-address.js
Normal file
15
src/layouts/service-location/classes/provider-address.js
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
export class ProviderAddress {
|
||||
constructor(
|
||||
streetAddress = null,
|
||||
city = null,
|
||||
state = null,
|
||||
zipCode = null,
|
||||
zipCodeCtu = null
|
||||
) {
|
||||
this.streetAddress = streetAddress;
|
||||
this.city = city;
|
||||
this.state = state;
|
||||
this.zipCode = zipCode;
|
||||
this.zipCodeCtu = zipCodeCtu;
|
||||
}
|
||||
}
|
||||
8
src/layouts/service-location/classes/provider.js
Normal file
8
src/layouts/service-location/classes/provider.js
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
import { ProviderAddress } from "./provider-address";
|
||||
|
||||
export class Provider {
|
||||
constructor(providerNumber = null, address = null) {
|
||||
this.providerNumber = providerNumber;
|
||||
this.address = address ?? new ProviderAddress();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,4 @@
|
|||
import { storeActions } from "@/constants/store-actions";
|
||||
import store from "@/store";
|
||||
import baseMixin from "@/mixins/base-mixin.js";
|
||||
|
||||
export async function getPricedMobileFeePart(serviceZipCode, pageNameToLog) {
|
||||
|
|
|
|||
|
|
@ -314,9 +314,10 @@ export default {
|
|||
margin-top: 0em;
|
||||
}
|
||||
|
||||
#mobileLocationLinkPromptId {
|
||||
.update-mobile-location-text-link {
|
||||
white-space: pre-line;
|
||||
}
|
||||
|
||||
.text-black {
|
||||
color: $black;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,10 @@ import { getMountOptions } from "@/helpers/unit-test-helper";
|
|||
|
||||
import store from "@/store";
|
||||
import baseMixin from "@/mixins/base-mixin";
|
||||
import { getServiceabilityDetails } from "@/layouts/service-location/helpers/service-location-helper/service-location-helper";
|
||||
import {
|
||||
getServiceabilityDetails,
|
||||
Provider,
|
||||
} from "@/layouts/service-location/helpers/service-location-helper/service-location-helper";
|
||||
|
||||
// Define Mocks
|
||||
jest.mock("@/helpers/cms-content-helper", () => ({
|
||||
|
|
@ -16,6 +19,8 @@ jest.mock("@/helpers/cms-content-helper", () => ({
|
|||
}),
|
||||
}));
|
||||
|
||||
jest.mock("./classes/provider");
|
||||
|
||||
const mockGetPricedMobileFeePart = (mockServiceZipCode) => {
|
||||
let mobileFeePart = {};
|
||||
|
||||
|
|
@ -397,6 +402,7 @@ describe("service-location.vue", () => {
|
|||
|
||||
await wrapper.setData({
|
||||
selectedAppointmentType: "Mobile",
|
||||
providerData: { mobileProviderNumber: "01820" },
|
||||
});
|
||||
|
||||
const mobileLocationQuestionsComponent = wrapper.findComponent({
|
||||
|
|
@ -448,6 +454,7 @@ describe("service-location.vue", () => {
|
|||
|
||||
await wrapper.setData({
|
||||
selectedAppointmentType: "Mobile",
|
||||
providerData: { mobileProviderNumber: "01820" },
|
||||
});
|
||||
|
||||
const mobileLocationQuestionsComponent = wrapper.findComponent({
|
||||
|
|
@ -511,6 +518,7 @@ describe("service-location.vue", () => {
|
|||
|
||||
await wrapper.setData({
|
||||
selectedAppointmentType: "Mobile",
|
||||
providerData: { mobileProviderNumber: "01820" },
|
||||
});
|
||||
|
||||
const mobileLocationQuestionsComponent = wrapper.findComponent({
|
||||
|
|
|
|||
|
|
@ -95,6 +95,7 @@
|
|||
v-model="selectedProvider"
|
||||
:selectedAppointmentType="selectedAppointmentType"
|
||||
:isDisplayed="isShopQuestionDisplayed"
|
||||
@updated-shop-list="setUpdatedShopList"
|
||||
cmsWidgetName="ShopQuestionWidget" />
|
||||
|
||||
<contentGroupModal ref="RecalModal" cmsWidgetName="RecalModal" />
|
||||
|
|
@ -135,6 +136,9 @@ import {
|
|||
getPricedMobileFeePart,
|
||||
getServiceabilityDetails,
|
||||
} from "@/layouts/service-location/helpers/service-location-helper/service-location-helper";
|
||||
|
||||
import { Provider } from "@/layouts/service-location/classes/provider";
|
||||
|
||||
import store from "@/store";
|
||||
|
||||
// Validation
|
||||
|
|
@ -176,6 +180,7 @@ export default {
|
|||
mobileFeePart: null,
|
||||
zipContainsMilitaryBase: false,
|
||||
zipCodeCtu: null,
|
||||
providerData: null,
|
||||
};
|
||||
},
|
||||
async beforeRouteEnter(to, from, next) {
|
||||
|
|
@ -229,7 +234,12 @@ export default {
|
|||
resultMap.serviceabilityDetails,
|
||||
resultMap.mobileFeePart
|
||||
);
|
||||
|
||||
// Initialize the Shop Question component
|
||||
vm.$refs.shopQuestion.initializeComponent(resultMap.shopQuestionInitialData);
|
||||
|
||||
// Initialize the page level shop data
|
||||
vm.providerData = resultMap.shopQuestionInitialData;
|
||||
});
|
||||
},
|
||||
computed: {
|
||||
|
|
@ -333,6 +343,9 @@ export default {
|
|||
displayNoShopsAlert() {
|
||||
return !this.isServiceableInshop && !this.isServiceableMobile;
|
||||
},
|
||||
recalibrationInformationModal() {
|
||||
return this.$refs.recalibrationInformationModal;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
arePagePrerequisitesValid() {
|
||||
|
|
@ -403,6 +416,15 @@ export default {
|
|||
this.isRecalibrationServiceableMobile =
|
||||
serviceabilityDetails.isRecalibrationServiceableMobile;
|
||||
},
|
||||
async reloadShopData(zipCode) {
|
||||
await this.$refs.shopQuestion.reloadShopData(zipCode);
|
||||
},
|
||||
setUpdatedShopList(providerData) {
|
||||
this.providerData = providerData;
|
||||
},
|
||||
openRecalibrationInformationModal() {
|
||||
this.recalibrationInformationModal.openModal();
|
||||
},
|
||||
backButtonAction() {
|
||||
this.$router.navigateWithoutSaving(this.navigationScenarios.CLICKED_BACK, this.$route);
|
||||
},
|
||||
|
|
@ -472,11 +494,25 @@ export default {
|
|||
this.updateAndSaveSupportingItems();
|
||||
this.$router.navigateWithSaving(this.navigationScenarios.CLICKED_FORWARD, this.$route);
|
||||
},
|
||||
openModalAction(modalName) {
|
||||
this.$refs[modalName].openModal();
|
||||
},
|
||||
watch: {
|
||||
selectedAppointmentType: {
|
||||
handler(newValue) {
|
||||
if (newValue === "Mobile") {
|
||||
this.selectedProvider = new Provider(this.providerData.mobileProviderNumber);
|
||||
} else {
|
||||
this.selectedProvider = new Provider();
|
||||
}
|
||||
},
|
||||
},
|
||||
async reloadShopData() {
|
||||
await this.$refs.shopQuestion.reloadShopData(this.zipCode);
|
||||
providerData: {
|
||||
handler(newValue) {
|
||||
if (newValue === "Mobile") {
|
||||
this.selectedProvider = new Provider(this.providerData.mobileProviderNumber);
|
||||
} else {
|
||||
this.selectedProvider = new Provider();
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
components: {
|
||||
|
|
|
|||
|
|
@ -54,6 +54,8 @@ import { nextTick } from "vue";
|
|||
|
||||
import { getAvailabilityRating } from "@/layouts/service-location/helpers/service-location-helper/service-location-helper";
|
||||
|
||||
import { Provider } from "@/layouts/service-location/classes/provider";
|
||||
|
||||
defineRule("option-required", required(errorMessages.OPTION_REQUIRED));
|
||||
|
||||
export default {
|
||||
|
|
@ -136,6 +138,7 @@ export default {
|
|||
},
|
||||
initializeComponent(shopQuestionInitialData) {
|
||||
this.shopProviders = shopQuestionInitialData.shopProviders;
|
||||
this.$emit("updated-shop-list", shopQuestionInitialData);
|
||||
},
|
||||
async getNextShopsFromList(numberToGet = 3) {
|
||||
const shopIterator = (array, n) => {
|
||||
|
|
@ -206,9 +209,9 @@ export default {
|
|||
await this.getNextShopsFromList();
|
||||
},
|
||||
getSelectedProviderObject(providerNumber) {
|
||||
const provider = this.shopProviders?.find(
|
||||
(provider) => provider.providerNumber == providerNumber
|
||||
);
|
||||
const provider =
|
||||
this.shopProviders?.find((provider) => provider.providerNumber == providerNumber) ??
|
||||
new Provider();
|
||||
|
||||
return provider;
|
||||
},
|
||||
|
|
@ -222,18 +225,15 @@ export default {
|
|||
},
|
||||
watch: {
|
||||
selectedAppointmentType: {
|
||||
async handler(newValue) {
|
||||
// Question: Does it matter if this fires when clicking Mobile? Ideally it should not, but it doesn't seem to effect anything
|
||||
// What we DON'T want to do here is create a dependency by checking if the selectedAppointmentType is Mobile as that has
|
||||
// nothing to do with this component. We could mitigate this by showing / hiding this component with v-if but that messes
|
||||
// up the component initialization on page load.
|
||||
async handler() {
|
||||
this.resetAnswers();
|
||||
|
||||
await nextTick();
|
||||
|
||||
this.selectedProviderNumber = null;
|
||||
|
||||
await nextTick();
|
||||
|
||||
if (newValue !== "Mobile") {
|
||||
this.getNextShopsFromList();
|
||||
}
|
||||
this.getNextShopsFromList();
|
||||
},
|
||||
},
|
||||
shopProviders: {
|
||||
|
|
|
|||
|
|
@ -1381,6 +1381,7 @@ export const actions = {
|
|||
? convertGlassPieceToBackEndCompatibleFormat(order.damage.glassToReplace)
|
||||
: [];
|
||||
var payload = {
|
||||
zipCode: order.serviceLocation.provider.zipCode,
|
||||
providerNumber: providerNumber,
|
||||
startDate: startDate,
|
||||
endDate: endDate,
|
||||
|
|
|
|||
Loading…
Reference in a new issue