Merge pull request #2918 from Safelite/feature/CASH-1529-revert-revert
Revert "Merge pull request #2914 from Safelite/feature/CASH-1529-revert"
This commit is contained in:
commit
56229ca650
9 changed files with 228 additions and 403 deletions
|
|
@ -322,6 +322,7 @@ export default {
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
this.$emit("itemRemoved");
|
||||||
},
|
},
|
||||||
|
|
||||||
async saveVaps(lineItems) {
|
async saveVaps(lineItems) {
|
||||||
|
|
|
||||||
|
|
@ -290,8 +290,18 @@ export default {
|
||||||
);
|
);
|
||||||
if (promoCodeData.isValid) {
|
if (promoCodeData.isValid) {
|
||||||
if (this.taxPromos) {
|
if (this.taxPromos) {
|
||||||
const pricedLineItemsToTax = [];
|
const vapsToAdd = getVapsThatNeedToBeAddedToSatisfyPromos(
|
||||||
pricedLineItemsToTax.push(...promoCodeData.promoCode); // promoCodeData.promoCode should be an array
|
promoCodeData.promoCode,
|
||||||
|
this.addableVaps,
|
||||||
|
this.lineItems
|
||||||
|
);
|
||||||
|
const pricedLineItemsToTax = {
|
||||||
|
glassParts: this.lineItems.glassParts,
|
||||||
|
promos: promoCodeData.promoCode,
|
||||||
|
supportingItems: this.lineItems.supportingItems,
|
||||||
|
vaps: [...this.lineItems.vaps, ...vapsToAdd],
|
||||||
|
};
|
||||||
|
|
||||||
const taxedLineItems =
|
const taxedLineItems =
|
||||||
await baseMixin.methods.dispatchStoreActionWithLogging(
|
await baseMixin.methods.dispatchStoreActionWithLogging(
|
||||||
storeActions.TAX_ORDER_ITEMS_AND_SAVE_SERVER_DATA,
|
storeActions.TAX_ORDER_ITEMS_AND_SAVE_SERVER_DATA,
|
||||||
|
|
@ -314,25 +324,10 @@ export default {
|
||||||
|
|
||||||
// Match all line items to the line items as they are in the store
|
// Match all line items to the line items as they are in the store
|
||||||
// and rebuild the original structure.
|
// and rebuild the original structure.
|
||||||
this.lineItems = mapTaxedLineItemsToStoreFormat(
|
this.lineItems = taxedLineItems;
|
||||||
taxedLineItems,
|
} else {
|
||||||
this.lineItems
|
this.lineItems?.promos.push(...promoCodeData.promoCode);
|
||||||
);
|
|
||||||
const taxedVaps = mapTaxedLineItemsToStoreFormat(
|
|
||||||
taxedLineItems,
|
|
||||||
this.addableVaps
|
|
||||||
);
|
|
||||||
|
|
||||||
const getVaps = getVapsThatNeedToBeAddedToSatisfyPromos(
|
|
||||||
promoCodeData.promoCode,
|
|
||||||
taxedVaps,
|
|
||||||
this.lineItems
|
|
||||||
);
|
|
||||||
|
|
||||||
this.lineItems.vaps?.push(...getVaps);
|
|
||||||
}
|
}
|
||||||
this.lineItems?.promos.push(...promoCodeData.promoCode);
|
|
||||||
|
|
||||||
this.$emit("promoAdded", this.lineItems);
|
this.$emit("promoAdded", this.lineItems);
|
||||||
|
|
||||||
this.closeModal();
|
this.closeModal();
|
||||||
|
|
|
||||||
|
|
@ -99,3 +99,25 @@ export async function getPricingByDayPartWithPrice(pageNameToLog) {
|
||||||
|
|
||||||
return pricingResults[0];
|
return pricingResults[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function addPricesToLineItems(lineItems, pricingLineItems) {
|
||||||
|
lineItems.forEach((lineItem) => {
|
||||||
|
const lineItemIndex = pricingLineItems.findIndex(
|
||||||
|
(pricingLineItem) => pricingLineItem.partNumber === lineItem.partNumber
|
||||||
|
);
|
||||||
|
|
||||||
|
if (lineItem.childParts) {
|
||||||
|
addPricesToLineItems(lineItem.childParts, pricingLineItems);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lineItemIndex !== -1) {
|
||||||
|
const pricedLineItem = pricingLineItems.splice(lineItemIndex, 1)[0];
|
||||||
|
lineItem.laborAmount = pricedLineItem.laborAmount;
|
||||||
|
lineItem.sellingPrice = pricedLineItem.sellingPrice;
|
||||||
|
lineItem.kitPrice = pricedLineItem.kitPrice;
|
||||||
|
lineItem.salesTax = pricedLineItem.salesTax;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return lineItems;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,8 @@
|
||||||
:isItac="isItac"
|
:isItac="isItac"
|
||||||
:isNoComp="isNoComp"
|
:isNoComp="isNoComp"
|
||||||
:isExpandedOnLoad="false"
|
:isExpandedOnLoad="false"
|
||||||
:isMSRFeeApplicable="isMSRFeeApplicable" />
|
:isMSRFeeApplicable="isMSRFeeApplicable"
|
||||||
|
@itemRemoved="evaluatePromosAndTaxItemsOnOrder" />
|
||||||
|
|
||||||
<afterpayBreakout
|
<afterpayBreakout
|
||||||
v-if="isAfterpayBreakoutDisplay"
|
v-if="isAfterpayBreakoutDisplay"
|
||||||
|
|
@ -154,7 +155,6 @@ import {
|
||||||
getNewlyInactivatedPromos,
|
getNewlyInactivatedPromos,
|
||||||
} from "@/helpers/promotions-helper";
|
} from "@/helpers/promotions-helper";
|
||||||
import { queryStrings } from "@/constants/query-strings";
|
import { queryStrings } from "@/constants/query-strings";
|
||||||
import { getQuerystringParameter } from "@/helpers/querystring-helper";
|
|
||||||
import { deepClone } from "@/helpers/object-helper";
|
import { deepClone } from "@/helpers/object-helper";
|
||||||
|
|
||||||
import { Form } from "vee-validate";
|
import { Form } from "vee-validate";
|
||||||
|
|
@ -162,18 +162,10 @@ import { defineRule } from "vee-validate";
|
||||||
import { required } from "@/helpers/validation-rules";
|
import { required } from "@/helpers/validation-rules";
|
||||||
import { errorMessages } from "@/constants/error-messages";
|
import { errorMessages } from "@/constants/error-messages";
|
||||||
import { AppointmentTypeStrings } from "@/constants/schedule-constants";
|
import { AppointmentTypeStrings } from "@/constants/schedule-constants";
|
||||||
import { partTypeStrings } from "@/constants/part-type-strings";
|
|
||||||
import { mapTaxedLineItemsToStoreFormat } from "../../store";
|
|
||||||
import { coverageStatus } from "@/constants/insurance";
|
import { coverageStatus } from "@/constants/insurance";
|
||||||
import { containsLineItemWithPartType } from "@/helpers/service-package-helper";
|
|
||||||
import { containsRecalParts } from "@/helpers/recal-helper";
|
import { containsRecalParts } from "@/helpers/recal-helper";
|
||||||
import { getBoolFromString } from "@/helpers/boolean-helper";
|
import { getBoolFromString } from "@/helpers/boolean-helper";
|
||||||
import {
|
import { getAmountDue, addPricesToLineItems } from "@/helpers/pricing-helper.js";
|
||||||
getDisplayAmountDue,
|
|
||||||
getAmountDue,
|
|
||||||
getSubTotal,
|
|
||||||
getSalesTax,
|
|
||||||
} from "@/helpers/pricing-helper.js";
|
|
||||||
import { consumeQueryFromStash } from "@/router/methods/helpers/querystring-stash";
|
import { consumeQueryFromStash } from "@/router/methods/helpers/querystring-stash";
|
||||||
import { debugLog } from "@/helpers/debug-log-helper";
|
import { debugLog } from "@/helpers/debug-log-helper";
|
||||||
import { ErrorMessage } from "vee-validate";
|
import { ErrorMessage } from "vee-validate";
|
||||||
|
|
@ -182,6 +174,23 @@ import { Field } from "vee-validate";
|
||||||
defineRule("payment-method-required", required(errorMessages.OPTION_REQUIRED));
|
defineRule("payment-method-required", required(errorMessages.OPTION_REQUIRED));
|
||||||
defineRule("recal-ack-required", required(errorMessages.RECAL_ACK_REQUIRED));
|
defineRule("recal-ack-required", required(errorMessages.RECAL_ACK_REQUIRED));
|
||||||
|
|
||||||
|
function getFlattenedArrayOfLineItemsWithChildParts(lineItems, childPartRecursiveCall = false) {
|
||||||
|
let flattenedArray = [];
|
||||||
|
lineItems?.forEach((lineItem) => {
|
||||||
|
// this assumes childparts will never be a glass part
|
||||||
|
lineItem.isChildPart = childPartRecursiveCall;
|
||||||
|
flattenedArray.push(lineItem);
|
||||||
|
if (lineItem.childParts) {
|
||||||
|
flattenedArray = [
|
||||||
|
...flattenedArray,
|
||||||
|
...getFlattenedArrayOfLineItemsWithChildParts(lineItem.childParts, true),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return flattenedArray;
|
||||||
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "paymentMethod",
|
name: "paymentMethod",
|
||||||
props: {
|
props: {
|
||||||
|
|
@ -191,32 +200,14 @@ export default {
|
||||||
// Call APIs
|
// Call APIs
|
||||||
const cmsContentPromise = fetchCmsContentForPage(to.name);
|
const cmsContentPromise = fetchCmsContentForPage(to.name);
|
||||||
|
|
||||||
const lineItemsFromStore = deepClone(store.getters.order.lineItems);
|
const wipersPromise = baseMixin.methods.dispatchStoreActionWithLogging(
|
||||||
|
storeActions.GET_WIPERS,
|
||||||
const frontWipersOnOrder =
|
{
|
||||||
lineItemsFromStore.vaps.filter(
|
serviceZipCode: store.getters.order.serviceLocation.zipCode,
|
||||||
(wiper) => wiper.partType == partTypeStrings.FRONT_WIPER
|
carId: store.getters.vehicle.carId,
|
||||||
) ?? [];
|
},
|
||||||
|
"payment-method"
|
||||||
const rearWipersOnOrder =
|
);
|
||||||
lineItemsFromStore.vaps.filter(
|
|
||||||
(wiper) => wiper.partType == partTypeStrings.REAR_WIPER
|
|
||||||
) ?? [];
|
|
||||||
|
|
||||||
const orderHasFrontWipers = frontWipersOnOrder.length > 0;
|
|
||||||
const orderHasRearWipers = rearWipersOnOrder.length > 0;
|
|
||||||
|
|
||||||
const wipersPromise =
|
|
||||||
!orderHasFrontWipers || !orderHasRearWipers
|
|
||||||
? baseMixin.methods.dispatchStoreActionWithLogging(
|
|
||||||
storeActions.GET_WIPERS,
|
|
||||||
{
|
|
||||||
serviceZipCode: store.getters.order.serviceLocation.zipCode,
|
|
||||||
carId: store.getters.vehicle.carId,
|
|
||||||
},
|
|
||||||
"payment-method"
|
|
||||||
)
|
|
||||||
: Promise.resolve([]);
|
|
||||||
|
|
||||||
const rainRepelPromise = baseMixin.methods.dispatchStoreActionWithLogging(
|
const rainRepelPromise = baseMixin.methods.dispatchStoreActionWithLogging(
|
||||||
storeActions.GET_RAIN_REPEL,
|
storeActions.GET_RAIN_REPEL,
|
||||||
|
|
@ -224,9 +215,6 @@ export default {
|
||||||
"payment-method"
|
"payment-method"
|
||||||
);
|
);
|
||||||
|
|
||||||
// const reviewDropdownPromise = reviewDropdown.methods.loadInitialData();
|
|
||||||
// (removed temporarily for Heritage parity effort)
|
|
||||||
|
|
||||||
const promiseResultMap = [
|
const promiseResultMap = [
|
||||||
{
|
{
|
||||||
resultKey: "cmsContent",
|
resultKey: "cmsContent",
|
||||||
|
|
@ -240,57 +228,40 @@ export default {
|
||||||
resultKey: "rainRepel",
|
resultKey: "rainRepel",
|
||||||
promise: rainRepelPromise,
|
promise: rainRepelPromise,
|
||||||
},
|
},
|
||||||
// {
|
|
||||||
// resultKey: "reviewDropdownData",
|
|
||||||
// promise: reviewDropdownPromise,
|
|
||||||
// },
|
|
||||||
// (removed temporarily for Heritage parity effort)
|
|
||||||
];
|
];
|
||||||
|
|
||||||
const resultMap = await settleAllPromises(promiseResultMap);
|
const resultMap = await settleAllPromises(promiseResultMap);
|
||||||
|
|
||||||
|
let lineItemsFromStore = deepClone(store.getters.order.lineItems);
|
||||||
const glassParts = lineItemsFromStore.glassParts ?? [];
|
const glassParts = lineItemsFromStore.glassParts ?? [];
|
||||||
const supportingItems = lineItemsFromStore.supportingItems ?? [];
|
const supportingItems = lineItemsFromStore.supportingItems ?? [];
|
||||||
const vaps = lineItemsFromStore.vaps ?? [];
|
const vaps = lineItemsFromStore.vaps ?? [];
|
||||||
|
|
||||||
// if the order already has wipers on it from the quote page, use those as the available wipers
|
const availableVaps = [resultMap.rainRepel, ...resultMap.wipers];
|
||||||
// instead of what comes from the backend. This is to prevent issues with part interchange.
|
|
||||||
const availableFrontWipers = orderHasFrontWipers
|
|
||||||
? frontWipersOnOrder
|
|
||||||
: (resultMap.wipers.filter((wiper) => wiper.partType == partTypeStrings.FRONT_WIPER) ??
|
|
||||||
[]);
|
|
||||||
const availableRearWipers = orderHasRearWipers
|
|
||||||
? rearWipersOnOrder
|
|
||||||
: (resultMap.wipers.filter((wiper) => wiper.partType == partTypeStrings.REAR_WIPER) ??
|
|
||||||
[]);
|
|
||||||
|
|
||||||
const allLineItems = [
|
const lineItemsOnOrderAndAvailableVaps = [
|
||||||
resultMap.rainRepel,
|
...availableVaps,
|
||||||
...supportingItems,
|
|
||||||
...availableFrontWipers,
|
|
||||||
...availableRearWipers,
|
|
||||||
...glassParts,
|
...glassParts,
|
||||||
|
...supportingItems,
|
||||||
...vaps,
|
...vaps,
|
||||||
];
|
];
|
||||||
|
|
||||||
const lineItemsToTax = Array.from(
|
// All line items are already priced except availableVaps
|
||||||
new Map(allLineItems.map((item) => [item.partNumber, item])).values()
|
// Price everything again to ensure that serverData has all values
|
||||||
);
|
// Specifically this addresses an error where insurance client glass parts are not in serverData
|
||||||
|
// See CASH-1713 for details
|
||||||
const availableVaps = [
|
let pricedLineItems = await baseMixin.methods.dispatchStoreActionWithLogging(
|
||||||
resultMap.rainRepel,
|
|
||||||
...availableFrontWipers,
|
|
||||||
...availableRearWipers,
|
|
||||||
];
|
|
||||||
|
|
||||||
const pricedLineItemsToTax = await baseMixin.methods.dispatchStoreActionWithLogging(
|
|
||||||
storeActions.PRICE_ORDER_ITEMS_AND_SAVE_SERVER_DATA,
|
storeActions.PRICE_ORDER_ITEMS_AND_SAVE_SERVER_DATA,
|
||||||
{
|
{
|
||||||
availableLineItems: lineItemsToTax,
|
availableLineItems: lineItemsOnOrderAndAvailableVaps,
|
||||||
},
|
},
|
||||||
"payment-method",
|
"payment-method",
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
|
pricedLineItems = getFlattenedArrayOfLineItemsWithChildParts(pricedLineItems);
|
||||||
|
|
||||||
|
// Add prices to the availableVaps
|
||||||
|
const pricedAvailableVaps = addPricesToLineItems(availableVaps, pricedLineItems);
|
||||||
|
|
||||||
// Promo logic
|
// Promo logic
|
||||||
// Populate the previous state of promos for toast message usage in "next()"
|
// Populate the previous state of promos for toast message usage in "next()"
|
||||||
|
|
@ -298,22 +269,38 @@ export default {
|
||||||
const oldInactivePromos = store.getters.order.payment.inactivePromos?.slice(0);
|
const oldInactivePromos = store.getters.order.payment.inactivePromos?.slice(0);
|
||||||
|
|
||||||
const promoCodeFromQueryString = consumeQueryFromStash(queryStrings.PROMO);
|
const promoCodeFromQueryString = consumeQueryFromStash(queryStrings.PROMO);
|
||||||
|
// New promos are saved to store with this
|
||||||
const { validatePromoResponse, revalidatePromoResponse } =
|
const { validatePromoResponse, revalidatePromoResponse } =
|
||||||
await revalidatePromosAndValidateQueryStringPromo(
|
await revalidatePromosAndValidateQueryStringPromo(
|
||||||
promoCodeFromQueryString,
|
promoCodeFromQueryString,
|
||||||
pricedLineItemsToTax,
|
lineItemsOnOrderAndAvailableVaps,
|
||||||
"payment-method"
|
"payment-method"
|
||||||
);
|
);
|
||||||
|
// update lineItemsFromStore with newly added promos
|
||||||
|
let lineItemsForCart = deepClone(store.getters.order.lineItems);
|
||||||
|
delete lineItemsForCart.serverData;
|
||||||
|
|
||||||
// Add newly validated promos to the array to get taxed
|
|
||||||
const newValidatedPromos = validatePromoResponse?.orderPromos ?? [];
|
|
||||||
newValidatedPromos.push(
|
|
||||||
...(revalidatePromoResponse ? revalidatePromoResponse.promoLineItems : [])
|
|
||||||
);
|
|
||||||
pricedLineItemsToTax.push(...newValidatedPromos);
|
|
||||||
// End of promo logic
|
// End of promo logic
|
||||||
|
|
||||||
const taxedLineItems = await baseMixin.methods.dispatchStoreActionWithLogging(
|
const vapsToAddToCart = getVapsThatNeedToBeAddedToSatisfyPromos(
|
||||||
|
lineItemsForCart.promos ?? [],
|
||||||
|
availableVaps,
|
||||||
|
lineItemsForCart
|
||||||
|
);
|
||||||
|
// Add prices to all line items, sometimes they are not there when they come back from heritage
|
||||||
|
// See CASH-1713 for details
|
||||||
|
lineItemsForCart.glassParts = addPricesToLineItems(
|
||||||
|
lineItemsForCart.glassParts ?? [],
|
||||||
|
pricedLineItems
|
||||||
|
);
|
||||||
|
lineItemsForCart.supportingItems = addPricesToLineItems(
|
||||||
|
lineItemsForCart.supportingItems ?? [],
|
||||||
|
pricedLineItems
|
||||||
|
);
|
||||||
|
lineItemsForCart.vaps = addPricesToLineItems(lineItemsForCart.vaps ?? [], pricedLineItems);
|
||||||
|
lineItemsForCart.vaps.push(...vapsToAddToCart);
|
||||||
|
// Tax items on order
|
||||||
|
lineItemsForCart = await baseMixin.methods.dispatchStoreActionWithLogging(
|
||||||
storeActions.TAX_ORDER_ITEMS_AND_SAVE_SERVER_DATA,
|
storeActions.TAX_ORDER_ITEMS_AND_SAVE_SERVER_DATA,
|
||||||
{
|
{
|
||||||
billToAccountNumber: store.getters.payment.billToAccountNumber,
|
billToAccountNumber: store.getters.payment.billToAccountNumber,
|
||||||
|
|
@ -322,31 +309,17 @@ export default {
|
||||||
serviceLocationCity: store.getters.order.serviceLocation.city,
|
serviceLocationCity: store.getters.order.serviceLocation.city,
|
||||||
serviceLocationState: store.getters.order.serviceLocation.state,
|
serviceLocationState: store.getters.order.serviceLocation.state,
|
||||||
serviceLocationZipCode: store.getters.order.serviceLocation.zipCode,
|
serviceLocationZipCode: store.getters.order.serviceLocation.zipCode,
|
||||||
pricedLineItems: pricedLineItemsToTax,
|
pricedLineItems: lineItemsForCart,
|
||||||
},
|
},
|
||||||
"payment-method",
|
"payment-method",
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
|
|
||||||
// Match all line items to the line items as they are in the store
|
|
||||||
// and rebuild the original structure.
|
|
||||||
const lineItems = mapTaxedLineItemsToStoreFormat(taxedLineItems, lineItemsFromStore);
|
|
||||||
const taxedVaps = mapTaxedLineItemsToStoreFormat(taxedLineItems, availableVaps);
|
|
||||||
|
|
||||||
lineItems.promos = newValidatedPromos ?? [];
|
|
||||||
const vapsToAddToCart = getVapsThatNeedToBeAddedToSatisfyPromos(
|
|
||||||
newValidatedPromos,
|
|
||||||
taxedVaps,
|
|
||||||
lineItems
|
|
||||||
);
|
|
||||||
lineItems.vaps = lineItems.vaps ?? [];
|
|
||||||
lineItems.vaps.push(...vapsToAddToCart);
|
|
||||||
|
|
||||||
// Call the "next" function to complete the transition to this page.
|
// Call the "next" function to complete the transition to this page.
|
||||||
next((vm) => {
|
next((vm) => {
|
||||||
vm.setCmsContent(resultMap.cmsContent);
|
vm.setCmsContent(resultMap.cmsContent);
|
||||||
vm.availableVaps = taxedVaps;
|
vm.availableVaps = pricedAvailableVaps;
|
||||||
vm.lineItems = lineItems;
|
vm.lineItems = lineItemsForCart;
|
||||||
vm.inactivePromos = removeCurrentlyActivePromoCodesFromInactivePromos(
|
vm.inactivePromos = removeCurrentlyActivePromoCodesFromInactivePromos(
|
||||||
vm.lineItems.promos,
|
vm.lineItems.promos,
|
||||||
vm.inactivePromos
|
vm.inactivePromos
|
||||||
|
|
@ -641,6 +614,28 @@ export default {
|
||||||
this.pageName
|
this.pageName
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
async evaluatePromosAndTaxItemsOnOrder() {
|
||||||
|
//Revalidate promos if there are any inactive, or active promos
|
||||||
|
const hasInactivePromos = this.inactivePromos.length > 0;
|
||||||
|
const hasActivePromos = this.lineItems.promos.length > 0;
|
||||||
|
if (hasInactivePromos || hasActivePromos) {
|
||||||
|
await this.revalidatePromos();
|
||||||
|
}
|
||||||
|
this.lineItems = await baseMixin.methods.dispatchStoreActionWithLogging(
|
||||||
|
storeActions.TAX_ORDER_ITEMS_AND_SAVE_SERVER_DATA,
|
||||||
|
{
|
||||||
|
billToAccountNumber: store.getters.payment.billToAccountNumber,
|
||||||
|
providerNumber: store.getters.order.serviceLocation.provider.providerNumber,
|
||||||
|
appointmentType: store.getters.order.serviceLocation.appointmentType,
|
||||||
|
serviceLocationCity: store.getters.order.serviceLocation.city,
|
||||||
|
serviceLocationState: store.getters.order.serviceLocation.state,
|
||||||
|
serviceLocationZipCode: store.getters.order.serviceLocation.zipCode,
|
||||||
|
pricedLineItems: this.lineItems,
|
||||||
|
},
|
||||||
|
"payment-method",
|
||||||
|
false
|
||||||
|
);
|
||||||
|
},
|
||||||
hasSubmittedOrder() {
|
hasSubmittedOrder() {
|
||||||
return baseMixin.methods.hasSubmittedOrder();
|
return baseMixin.methods.hasSubmittedOrder();
|
||||||
},
|
},
|
||||||
|
|
@ -861,7 +856,6 @@ export default {
|
||||||
) {
|
) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (oldValue.promos.length < newValue.promos.length) {
|
if (oldValue.promos.length < newValue.promos.length) {
|
||||||
const oldPromoCodes = oldValue.promos.map(
|
const oldPromoCodes = oldValue.promos.map(
|
||||||
(promoObject) => promoObject.promoCode
|
(promoObject) => promoObject.promoCode
|
||||||
|
|
|
||||||
|
|
@ -319,7 +319,6 @@ describe("payment.vue", () => {
|
||||||
);
|
);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
expect(vmMock.availableVaps).not.toBeUndefined();
|
|
||||||
expect(vmMock.lineItems).not.toBeUndefined();
|
expect(vmMock.lineItems).not.toBeUndefined();
|
||||||
|
|
||||||
expect(vmMock.setCmsContent).toBeCalled();
|
expect(vmMock.setCmsContent).toBeCalled();
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@
|
||||||
<cart
|
<cart
|
||||||
ref="cart"
|
ref="cart"
|
||||||
:damage="damageInfo"
|
:damage="damageInfo"
|
||||||
:availableVaps="availableVaps"
|
:availableVaps="[]"
|
||||||
:allowItemRemoval="false"
|
:allowItemRemoval="false"
|
||||||
v-model="lineItems"
|
v-model="lineItems"
|
||||||
servicePackageOptionsCmsName="ServicePackageTitle"
|
servicePackageOptionsCmsName="ServicePackageTitle"
|
||||||
|
|
@ -237,25 +237,11 @@ import { applicationConfig } from "@/constants/application-config";
|
||||||
import { paymentMethods } from "@/constants/payment-method-constants";
|
import { paymentMethods } from "@/constants/payment-method-constants";
|
||||||
import { AppointmentTypeStrings } from "@/constants/schedule-constants";
|
import { AppointmentTypeStrings } from "@/constants/schedule-constants";
|
||||||
import baseMixin from "@/mixins/base-mixin.js";
|
import baseMixin from "@/mixins/base-mixin.js";
|
||||||
import { mapTaxedLineItemsToStoreFormat } from "../../store";
|
|
||||||
import {
|
|
||||||
revalidatePromosAndValidateQueryStringPromo,
|
|
||||||
getAddableVapsFromAvailableLineItems,
|
|
||||||
getVapsThatNeedToBeAddedToSatisfyPromos,
|
|
||||||
} from "@/helpers/promotions-helper";
|
|
||||||
import { queryStrings } from "@/constants/query-strings";
|
|
||||||
import { getQuerystringParameter } from "@/helpers/querystring-helper";
|
|
||||||
import { deepClone } from "@/helpers/object-helper";
|
import { deepClone } from "@/helpers/object-helper";
|
||||||
import { submitWorkOrder } from "@/helpers/heritage-integration/order-helper.js";
|
import { submitWorkOrder } from "@/helpers/heritage-integration/order-helper.js";
|
||||||
import iframeResize from "../../../node_modules/iframe-resizer/js/iframeResizer.js";
|
import iframeResize from "../../../node_modules/iframe-resizer/js/iframeResizer.js";
|
||||||
import { coverageStatus } from "@/constants/insurance";
|
import { coverageStatus } from "@/constants/insurance";
|
||||||
import { getBoolFromString } from "@/helpers/boolean-helper.js";
|
import { getDisplayAmountDue, getAmountDue } from "@/helpers/pricing-helper.js";
|
||||||
import {
|
|
||||||
getDisplayAmountDue,
|
|
||||||
getAmountDue,
|
|
||||||
getSubTotal,
|
|
||||||
getSalesTax,
|
|
||||||
} from "@/helpers/pricing-helper.js";
|
|
||||||
import { debugLog } from "@/helpers/debug-log-helper.js";
|
import { debugLog } from "@/helpers/debug-log-helper.js";
|
||||||
import buttonQuestion from "@/digital-components/button-question/button-question";
|
import buttonQuestion from "@/digital-components/button-question/button-question";
|
||||||
import paymentMethodListButton from "@/layouts/payment-method/payment-method-question/payment-method-list-button/payment-method-list-button";
|
import paymentMethodListButton from "@/layouts/payment-method/payment-method-question/payment-method-list-button/payment-method-list-button";
|
||||||
|
|
@ -290,7 +276,6 @@ export default {
|
||||||
displayAmount: this.getDisplayAmountDue(),
|
displayAmount: this.getDisplayAmountDue(),
|
||||||
piaLineItems: "",
|
piaLineItems: "",
|
||||||
lineItems: [],
|
lineItems: [],
|
||||||
availableVaps: [],
|
|
||||||
shouldBlockInteraction: false,
|
shouldBlockInteraction: false,
|
||||||
paymentMethodListButton: paymentMethodListButton,
|
paymentMethodListButton: paymentMethodListButton,
|
||||||
showSwitchPaymentMethod: !this.isAfterpay(),
|
showSwitchPaymentMethod: !this.isAfterpay(),
|
||||||
|
|
@ -321,21 +306,6 @@ export default {
|
||||||
"payment"
|
"payment"
|
||||||
);
|
);
|
||||||
|
|
||||||
const wipersPromise = baseMixin.methods.dispatchStoreActionWithLogging(
|
|
||||||
storeActions.GET_WIPERS,
|
|
||||||
{
|
|
||||||
serviceZipCode: store.getters.order.serviceLocation.zipCode,
|
|
||||||
carId: store.getters.vehicle.carId,
|
|
||||||
},
|
|
||||||
"payment"
|
|
||||||
);
|
|
||||||
|
|
||||||
const rainRepelPromise = baseMixin.methods.dispatchStoreActionWithLogging(
|
|
||||||
storeActions.GET_RAIN_REPEL,
|
|
||||||
null,
|
|
||||||
"payment"
|
|
||||||
);
|
|
||||||
|
|
||||||
const promiseResultMap = [
|
const promiseResultMap = [
|
||||||
{
|
{
|
||||||
resultKey: "cmsContent",
|
resultKey: "cmsContent",
|
||||||
|
|
@ -345,92 +315,14 @@ export default {
|
||||||
resultKey: "signature",
|
resultKey: "signature",
|
||||||
promise: signaturePromise,
|
promise: signaturePromise,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
resultKey: "wipers",
|
|
||||||
promise: wipersPromise,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
resultKey: "rainRepel",
|
|
||||||
promise: rainRepelPromise,
|
|
||||||
},
|
|
||||||
];
|
];
|
||||||
|
|
||||||
const resultMap = await settleAllPromises(promiseResultMap);
|
const resultMap = await settleAllPromises(promiseResultMap);
|
||||||
const lineItemsFromStore = deepClone(store.getters.order.lineItems);
|
|
||||||
const glassParts = lineItemsFromStore.glassParts ?? [];
|
|
||||||
const supportingItems = lineItemsFromStore.supportingItems ?? [];
|
|
||||||
|
|
||||||
const lineItemsToTax = [
|
|
||||||
resultMap.rainRepel,
|
|
||||||
...supportingItems,
|
|
||||||
...resultMap.wipers,
|
|
||||||
...glassParts,
|
|
||||||
];
|
|
||||||
const availableVaps = [resultMap.rainRepel, ...resultMap.wipers];
|
|
||||||
|
|
||||||
const pricedLineItemsToTax = await baseMixin.methods.dispatchStoreActionWithLogging(
|
|
||||||
storeActions.PRICE_ORDER_ITEMS_AND_SAVE_SERVER_DATA,
|
|
||||||
{
|
|
||||||
availableLineItems: lineItemsToTax,
|
|
||||||
},
|
|
||||||
"payment",
|
|
||||||
false
|
|
||||||
);
|
|
||||||
|
|
||||||
// Promo logic
|
|
||||||
const promoCodeFromQueryString = getQuerystringParameter(queryStrings.PROMO);
|
|
||||||
|
|
||||||
const { validatePromoResponse, revalidatePromoResponse } =
|
|
||||||
await revalidatePromosAndValidateQueryStringPromo(
|
|
||||||
promoCodeFromQueryString,
|
|
||||||
pricedLineItemsToTax,
|
|
||||||
"payment"
|
|
||||||
);
|
|
||||||
|
|
||||||
const newValidatedPromos = validatePromoResponse?.orderPromos ?? [];
|
|
||||||
newValidatedPromos.push(
|
|
||||||
...(revalidatePromoResponse ? revalidatePromoResponse.promoLineItems : [])
|
|
||||||
);
|
|
||||||
|
|
||||||
pricedLineItemsToTax.push(...newValidatedPromos);
|
|
||||||
// End of promo logic
|
|
||||||
|
|
||||||
const taxedLineItems = await baseMixin.methods.dispatchStoreActionWithLogging(
|
|
||||||
storeActions.TAX_ORDER_ITEMS_AND_SAVE_SERVER_DATA,
|
|
||||||
{
|
|
||||||
billToAccountNumber: store.getters.payment.billToAccountNumber,
|
|
||||||
providerNumber: store.getters.order.serviceLocation.provider.providerNumber,
|
|
||||||
appointmentType: store.getters.order.serviceLocation.appointmentType,
|
|
||||||
serviceLocationCity: store.getters.order.serviceLocation.city,
|
|
||||||
serviceLocationState: store.getters.order.serviceLocation.state,
|
|
||||||
serviceLocationZipCode: store.getters.order.serviceLocation.zipCode,
|
|
||||||
pricedLineItems: pricedLineItemsToTax,
|
|
||||||
},
|
|
||||||
"payment",
|
|
||||||
false
|
|
||||||
);
|
|
||||||
|
|
||||||
// Match all line items to the line items as they are in the store
|
|
||||||
// and rebuild the original structure.
|
|
||||||
const lineItems = mapTaxedLineItemsToStoreFormat(taxedLineItems, lineItemsFromStore);
|
|
||||||
const taxedVaps = mapTaxedLineItemsToStoreFormat(taxedLineItems, availableVaps);
|
|
||||||
|
|
||||||
// Add items that were not in the store yet but added via query string promo validation
|
|
||||||
//newValidatedPromos contains both validated and revalidated promos.
|
|
||||||
lineItems.promos = Array.from(newValidatedPromos);
|
|
||||||
const vapsToAddToCart = getVapsThatNeedToBeAddedToSatisfyPromos(
|
|
||||||
newValidatedPromos,
|
|
||||||
taxedVaps,
|
|
||||||
lineItems
|
|
||||||
);
|
|
||||||
lineItems.vaps = lineItems.vaps ?? [];
|
|
||||||
lineItems.vaps.push(...vapsToAddToCart);
|
|
||||||
|
|
||||||
// Call the "next" function to complete the transition to this page.
|
// Call the "next" function to complete the transition to this page.
|
||||||
next(async (vm) => {
|
next(async (vm) => {
|
||||||
vm.setCmsContent(resultMap.cmsContent);
|
vm.setCmsContent(resultMap.cmsContent);
|
||||||
vm.availableVaps = taxedVaps;
|
vm.lineItems = deepClone(store.getters.order.lineItems);
|
||||||
vm.lineItems = lineItems;
|
|
||||||
|
|
||||||
vm.$nextTick(() => {
|
vm.$nextTick(() => {
|
||||||
if (vm.$refs.cart) {
|
if (vm.$refs.cart) {
|
||||||
|
|
|
||||||
|
|
@ -65,6 +65,7 @@
|
||||||
pageName="quote"
|
pageName="quote"
|
||||||
:taxPromos="false"
|
:taxPromos="false"
|
||||||
:useDefaultCashParentAccount="true"
|
:useDefaultCashParentAccount="true"
|
||||||
|
@promoAdded="promoAdded"
|
||||||
modalWidgetName="PromoModalWidget" />
|
modalWidgetName="PromoModalWidget" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -576,9 +577,6 @@ export default {
|
||||||
isInsuranceContinueButtonText() {
|
isInsuranceContinueButtonText() {
|
||||||
return this.getCmsContent("isInsuranceContinueButtonText", "Text");
|
return this.getCmsContent("isInsuranceContinueButtonText", "Text");
|
||||||
},
|
},
|
||||||
lineItemsCloneForWatcher() {
|
|
||||||
return Object.assign({}, this.lineItems);
|
|
||||||
},
|
|
||||||
isRecalibrationOnOrder() {
|
isRecalibrationOnOrder() {
|
||||||
return store.getters.isRecalibrationOnOrder;
|
return store.getters.isRecalibrationOnOrder;
|
||||||
},
|
},
|
||||||
|
|
@ -854,31 +852,9 @@ export default {
|
||||||
await this.forwardButtonAction();
|
await this.forwardButtonAction();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
promoAdded(lineItems) {
|
||||||
watch: {
|
const alert = createPromoSuccessAlert(lineItems.promos[0].promoCode);
|
||||||
lineItemsCloneForWatcher: {
|
this.$refs.funnelHeader.pushGlobalAlert(alert, alert.shouldAutoFade);
|
||||||
handler(newValue, oldValue) {
|
|
||||||
if (
|
|
||||||
!oldValue ||
|
|
||||||
oldValue.length == 0 ||
|
|
||||||
!oldValue.vaps ||
|
|
||||||
!newValue ||
|
|
||||||
newValue.length == 0
|
|
||||||
) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (oldValue.promos.length < newValue.promos.length) {
|
|
||||||
const oldPromoCodes = oldValue.promos.map(
|
|
||||||
(promoObject) => promoObject.promoCode
|
|
||||||
);
|
|
||||||
const newlyActivatedPromoCodes = newValue.promos.filter(
|
|
||||||
(newPromo) => !oldPromoCodes.includes(newPromo.promoCode)
|
|
||||||
);
|
|
||||||
const alert = createPromoSuccessAlert(newlyActivatedPromoCodes[0].promoCode);
|
|
||||||
this.$refs.funnelHeader.pushGlobalAlert(alert, alert.shouldAutoFade);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
deep: true,
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
|
|
|
||||||
|
|
@ -460,111 +460,47 @@ export default {
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
async beforeRouteEnter(to, from, next) {
|
async beforeRouteEnter(to, from, next) {
|
||||||
const isPricingByDayExperiment = experimentMixin.methods.hasSettingEqualTo(
|
const serviceZipCode = store.getters.order.serviceLocation.zipCode;
|
||||||
experimentSettings.PRICING_BY_DAY,
|
|
||||||
"true"
|
|
||||||
);
|
|
||||||
const showPricingByDay = !store.getters.payment.isInsurance && isPricingByDayExperiment;
|
|
||||||
|
|
||||||
// Get pricingByDayBasePrice needed for Pricing By Day
|
|
||||||
const lineItems = deepClone(store.getters.order.lineItems);
|
|
||||||
const isRecalibrationOnOrder = store.getters.isRecalibrationOnOrder;
|
|
||||||
const shouldHideRecalibration =
|
|
||||||
experimentMixin.methods.hasSettingEqualTo(
|
|
||||||
experimentSettings.RECAL_PRICE_REMOVE,
|
|
||||||
"true"
|
|
||||||
) && isRecalibrationOnOrder;
|
|
||||||
const glassParts =
|
|
||||||
isRecalibrationOnOrder && shouldHideRecalibration
|
|
||||||
? getItemsWithoutRecalParts(lineItems.glassParts)
|
|
||||||
: (lineItems.glassParts ?? []);
|
|
||||||
const supportingItemsWithoutFees = baseMixin.methods.filterOutCertainPartTypesOrNumbers(
|
|
||||||
lineItems.supportingItems,
|
|
||||||
{
|
|
||||||
partNumbersToRemove: [
|
|
||||||
partNumberStrings.RECYCLE_FEE,
|
|
||||||
partNumberStrings.PRICING_BY_DAY_UPCHARGE,
|
|
||||||
],
|
|
||||||
}
|
|
||||||
);
|
|
||||||
const lineItemsToBePriced = {
|
|
||||||
glassParts: glassParts,
|
|
||||||
supportingItems: supportingItemsWithoutFees,
|
|
||||||
vaps: lineItems.vaps ?? [],
|
|
||||||
promos: lineItems.promos ?? [],
|
|
||||||
};
|
|
||||||
const priceString = getAmountDue(lineItemsToBePriced, false); // pass the IncludeTax param as false
|
|
||||||
const priceStringIntegerRoundedDown = priceString?.split(".")[0]; // same method used as getDisplayPrice() in service-package-radio used on /quote
|
|
||||||
const pricingByDayBasePrice = parseInt(priceStringIntegerRoundedDown);
|
|
||||||
let includePricingByDayUpcharge = false;
|
|
||||||
let appointmentType = store.getters.order.serviceLocation.appointmentType;
|
|
||||||
|
|
||||||
// Check to see if date should be pre-selected
|
|
||||||
let scheduleFromStore = await store.getters.order.schedule;
|
|
||||||
let preSelectedDate;
|
|
||||||
|
|
||||||
if (scheduleFromStore.date && scheduleFromStore.date.length > 0) {
|
|
||||||
preSelectedDate = scheduleFromStore.date;
|
|
||||||
|
|
||||||
if (appointmentType === AppointmentTypeStrings.MOBILE) {
|
|
||||||
preSelectedDate += "-mobile";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check to see if pre-selected date should have pricing by day upcharge
|
|
||||||
if (showPricingByDay) {
|
|
||||||
// is this preSelectedDate a higher priced pricingByDay day?
|
|
||||||
const dayIndex = convertDateStringToDate(scheduleFromStore?.date).getDay();
|
|
||||||
const dayObject = DAYS_OF_WEEK[dayIndex];
|
|
||||||
if (dayObject.isPricingByDayUpchargeDay) {
|
|
||||||
includePricingByDayUpcharge = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set up promises
|
|
||||||
const cmsContentPromise = fetchCmsContentForPage(to.name);
|
const cmsContentPromise = fetchCmsContentForPage(to.name);
|
||||||
|
|
||||||
const alertReasonsPromise = locationAlerts.methods.loadInitialData(
|
const alertReasonsPromise = locationAlerts.methods.loadInitialData(
|
||||||
store.getters.order.serviceLocation.zipCodeCtu,
|
store.getters.order.serviceLocation.zipCodeCtu,
|
||||||
store.getters.order.serviceLocation.provider?.address?.zipCodeCtu
|
store.getters.order.serviceLocation.provider?.address?.zipCodeCtu
|
||||||
);
|
);
|
||||||
|
|
||||||
const serviceZipCode = store.getters.order.serviceLocation.zipCode;
|
|
||||||
const zipCodeDataPromise = getZipCodeData(serviceZipCode, to.name);
|
|
||||||
const serviceabilityDetailsPromise = getServiceabilityDetails(
|
const serviceabilityDetailsPromise = getServiceabilityDetails(
|
||||||
serviceZipCode,
|
serviceZipCode,
|
||||||
null,
|
null,
|
||||||
to.name
|
"schedule"
|
||||||
|
);
|
||||||
|
let zipCodeData;
|
||||||
|
const zipCodeDataPromise = getZipCodeData(serviceZipCode, to.name);
|
||||||
|
let shopProviderData;
|
||||||
|
const shopProviderDataPromise = getShopProviderData(serviceZipCode, to.name);
|
||||||
|
const zipCodeDataAndShopProviderDataPromise = Promise.all([
|
||||||
|
zipCodeDataPromise,
|
||||||
|
shopProviderDataPromise,
|
||||||
|
]);
|
||||||
|
const mobileFeePartPromise = zipCodeDataAndShopProviderDataPromise.then(
|
||||||
|
([zipCodeDataResult, shopProviderDataResult]) => {
|
||||||
|
zipCodeData = zipCodeDataResult;
|
||||||
|
shopProviderData = shopProviderDataResult;
|
||||||
|
return baseMixin.methods.dispatchStoreActionWithLogging(
|
||||||
|
storeActions.GET_MOBILE_FEE_PART,
|
||||||
|
{
|
||||||
|
serviceZipCode: serviceZipCode,
|
||||||
|
serviceZipCodeCtu: zipCodeData.zipCodeCtu,
|
||||||
|
mobileProviderNumber: shopProviderData.data.mobileProviderNumber,
|
||||||
|
},
|
||||||
|
to.name,
|
||||||
|
false
|
||||||
|
);
|
||||||
|
}
|
||||||
);
|
);
|
||||||
const mobileFeePartPromise = getPricedMobileFeePart(serviceZipCode, to.name);
|
|
||||||
const shopProviderData = await getShopProviderData(serviceZipCode, to.name);
|
|
||||||
const providerNumber = shopProviderData?.data?.shopProviders[0]?.providerNumber;
|
|
||||||
|
|
||||||
// Get pricingByDayUpcharge needed for Pricing By Day
|
|
||||||
const pricingByDayUpchargePartPromise = showPricingByDay
|
|
||||||
? getPricingByDayPartWithPrice()
|
|
||||||
: null;
|
|
||||||
|
|
||||||
const premiumFeePromise = baseMixin.methods.dispatchStoreActionWithLogging(
|
const premiumFeePromise = baseMixin.methods.dispatchStoreActionWithLogging(
|
||||||
storeActions.GET_MOBILE_PREMIUM_FEE,
|
storeActions.GET_MOBILE_PREMIUM_FEE,
|
||||||
null,
|
null,
|
||||||
to.name
|
to.name
|
||||||
);
|
);
|
||||||
const premiumFeeWithPricePromise = premiumFeePromise.then((result) => {
|
|
||||||
if (result.data) {
|
|
||||||
return baseMixin.methods.dispatchStoreActionWithLogging(
|
|
||||||
storeActions.PRICE_ORDER_ITEMS_AND_SAVE_SERVER_DATA,
|
|
||||||
{
|
|
||||||
availableLineItems: [result.data],
|
|
||||||
},
|
|
||||||
to.name,
|
|
||||||
false
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
return result.data;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Settle promises and get results
|
// Settle promises and get results
|
||||||
const promiseResultMap = [
|
const promiseResultMap = [
|
||||||
{
|
{
|
||||||
|
|
@ -575,18 +511,6 @@ export default {
|
||||||
resultKey: "alertReasons",
|
resultKey: "alertReasons",
|
||||||
promise: alertReasonsPromise,
|
promise: alertReasonsPromise,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
resultKey: "pricingByDayUpchargePart",
|
|
||||||
promise: pricingByDayUpchargePartPromise,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
resultKey: "premiumFeeWithPrice",
|
|
||||||
promise: premiumFeeWithPricePromise,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
resultKey: "zipCodeData",
|
|
||||||
promise: zipCodeDataPromise,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
resultKey: "mobileFeePart",
|
resultKey: "mobileFeePart",
|
||||||
promise: mobileFeePartPromise,
|
promise: mobileFeePartPromise,
|
||||||
|
|
@ -595,39 +519,70 @@ export default {
|
||||||
resultKey: "serviceabilityDetails",
|
resultKey: "serviceabilityDetails",
|
||||||
promise: serviceabilityDetailsPromise,
|
promise: serviceabilityDetailsPromise,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
resultKey: "premiumFee",
|
||||||
|
promise: premiumFeePromise,
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const resultMap = await settleAllPromises(promiseResultMap);
|
const resultMap = await settleAllPromises(promiseResultMap);
|
||||||
|
const itemsToPrice = [];
|
||||||
|
if (resultMap.mobileFeePart) {
|
||||||
|
itemsToPrice.push(resultMap.mobileFeePart);
|
||||||
|
}
|
||||||
|
if (resultMap.premiumFee) {
|
||||||
|
itemsToPrice.push(resultMap.premiumFee);
|
||||||
|
}
|
||||||
|
|
||||||
// add pricing by day data
|
let pricedMobileFeePart = null;
|
||||||
const pricingByDayUpcharge =
|
let pricedPremiumFee = null;
|
||||||
showPricingByDay && resultMap.pricingByDayUpchargePart
|
|
||||||
? await baseMixin.methods.getTotalLineItemPrice(
|
if (itemsToPrice.length) {
|
||||||
resultMap.pricingByDayUpchargePart,
|
const pricedItems = await baseMixin.methods.dispatchStoreActionWithLogging(
|
||||||
false
|
storeActions.PRICE_ORDER_ITEMS_AND_SAVE_SERVER_DATA,
|
||||||
)
|
{
|
||||||
: null;
|
availableLineItems: itemsToPrice,
|
||||||
|
},
|
||||||
|
to.name,
|
||||||
|
false
|
||||||
|
);
|
||||||
|
pricedMobileFeePart = pricedItems.find(
|
||||||
|
(item) => item.partNumber === resultMap.mobileFeePart.partNumber
|
||||||
|
);
|
||||||
|
pricedPremiumFee = pricedItems.find(
|
||||||
|
(item) => item.partNumber === resultMap.premiumFee.partNumber
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
let appointmentType = store.getters.order.serviceLocation.appointmentType;
|
||||||
|
// Check to see if date should be pre-selected
|
||||||
|
let scheduleFromStore = await store.getters.order.schedule;
|
||||||
|
let preSelectedDate;
|
||||||
|
if (scheduleFromStore.date && scheduleFromStore.date.length > 0) {
|
||||||
|
preSelectedDate = scheduleFromStore.date;
|
||||||
|
|
||||||
|
if (appointmentType === AppointmentTypeStrings.MOBILE) {
|
||||||
|
preSelectedDate += "-mobile";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Call the "next" function to complete the transition to this page.
|
// Call the "next" function to complete the transition to this page.
|
||||||
next((vm) => {
|
next((vm) => {
|
||||||
vm.setCmsContent(resultMap.cmsContent);
|
vm.setCmsContent(resultMap.cmsContent);
|
||||||
vm.$refs.locationAlerts.initializeComponent(resultMap.alertReasons);
|
vm.$refs.locationAlerts.initializeComponent(resultMap.alertReasons);
|
||||||
vm.mobilePremiumAppointmentFee = resultMap.premiumFeeWithPrice
|
vm.mobilePremiumAppointmentFee = pricedPremiumFee;
|
||||||
? resultMap.premiumFeeWithPrice[0]
|
|
||||||
: null;
|
|
||||||
vm.updateFooterButtonText(vm.selectedTimeSlotInfo);
|
vm.updateFooterButtonText(vm.selectedTimeSlotInfo);
|
||||||
vm.pricingByDayUpchargeLineItem = resultMap.pricingByDayUpchargePart;
|
vm.pricingByDayUpchargeLineItem = null; // Pricing By Day Upcharge Line Item is not used in this version
|
||||||
vm.includePricingByDayUpcharge = includePricingByDayUpcharge;
|
vm.includePricingByDayUpcharge = false; // Pricing By Day Upcharge is not used in this version
|
||||||
vm.isPricingByDayExperiment = isPricingByDayExperiment;
|
vm.isPricingByDayExperiment = false; // Pricing By Day Experiment is not used in this version
|
||||||
vm.pricingByDayBasePrice = pricingByDayBasePrice;
|
vm.pricingByDayBasePrice = null; // Pricing By Day Base Price is not used in this version
|
||||||
vm.pricingByDayUpcharge = pricingByDayUpcharge;
|
vm.pricingByDayUpcharge = null; // Pricing By Day Upcharge is not used in this version
|
||||||
vm.showPricingByDay = showPricingByDay;
|
vm.showPricingByDay = false; // Pricing By Day is not used in this version
|
||||||
vm.preSelectedDate = preSelectedDate;
|
vm.preSelectedDate = preSelectedDate;
|
||||||
vm.appointmentType = appointmentType;
|
vm.appointmentType = appointmentType;
|
||||||
vm.setData(
|
vm.setData(
|
||||||
resultMap.zipCodeData,
|
zipCodeData,
|
||||||
resultMap.serviceabilityDetails,
|
resultMap.serviceabilityDetails,
|
||||||
resultMap.mobileFeePart,
|
pricedMobileFeePart,
|
||||||
shopProviderData.data
|
shopProviderData.data
|
||||||
);
|
);
|
||||||
vm.initializeDatePicker();
|
vm.initializeDatePicker();
|
||||||
|
|
|
||||||
|
|
@ -59,6 +59,7 @@ import {
|
||||||
} from "@/helpers/recal-helper";
|
} from "@/helpers/recal-helper";
|
||||||
import { externalParameterStatus } from "@/constants/external-parameters";
|
import { externalParameterStatus } from "@/constants/external-parameters";
|
||||||
import { experimentSettings } from "@/constants/experiments";
|
import { experimentSettings } from "@/constants/experiments";
|
||||||
|
import { addPricesToLineItems } from "@/helpers/pricing-helper";
|
||||||
|
|
||||||
// Export State
|
// Export State
|
||||||
const getDefaultState = () => {
|
const getDefaultState = () => {
|
||||||
|
|
@ -3063,8 +3064,14 @@ export const actions = {
|
||||||
pageNameToLog,
|
pageNameToLog,
|
||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
|
const arrayOfLineItems = [
|
||||||
|
...(pricedLineItems.glassParts ?? []),
|
||||||
|
...(pricedLineItems.promos ?? []),
|
||||||
|
...(pricedLineItems.supportingItems ?? []),
|
||||||
|
...(pricedLineItems.vaps ?? []),
|
||||||
|
];
|
||||||
const flattenedLineItemsWithChildParts =
|
const flattenedLineItemsWithChildParts =
|
||||||
getFlattenedArrayOfLineItemsWithChildParts(pricedLineItems);
|
getFlattenedArrayOfLineItemsWithChildParts(arrayOfLineItems);
|
||||||
|
|
||||||
const lineItemsWithOnlyPriceInfo = flattenedLineItemsWithChildParts.map((lineItem) => ({
|
const lineItemsWithOnlyPriceInfo = flattenedLineItemsWithChildParts.map((lineItem) => ({
|
||||||
partNumber: lineItem.partNumber,
|
partNumber: lineItem.partNumber,
|
||||||
|
|
@ -3113,8 +3120,12 @@ export const actions = {
|
||||||
});
|
});
|
||||||
|
|
||||||
context.commit(storeMutations.UPDATE_LINE_ITEMS_SERVER_DATA, response.data.serverData);
|
context.commit(storeMutations.UPDATE_LINE_ITEMS_SERVER_DATA, response.data.serverData);
|
||||||
|
Object.keys(pricedLineItems).forEach((key) => {
|
||||||
pricedLineItems = addTaxesToPricedLineItems(pricedLineItems, response.data.taxedLineItems);
|
pricedLineItems[key] = addTaxesToPricedLineItems(
|
||||||
|
pricedLineItems[key] ?? [],
|
||||||
|
response.data.taxedLineItems
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
return pricedLineItems;
|
return pricedLineItems;
|
||||||
},
|
},
|
||||||
|
|
@ -3796,26 +3807,6 @@ function convertGlassPieceNamingFromApi(glassArray) {
|
||||||
return glassArray;
|
return glassArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
function addPricesToLineItems(lineItems, pricingLineItems) {
|
|
||||||
lineItems.forEach((lineItem) => {
|
|
||||||
const lineItemIndex = pricingLineItems.findIndex(
|
|
||||||
(pricingLineItem) => pricingLineItem.partNumber === lineItem.partNumber
|
|
||||||
);
|
|
||||||
|
|
||||||
if (lineItem.childParts) {
|
|
||||||
addPricesToLineItems(lineItem.childParts, pricingLineItems);
|
|
||||||
}
|
|
||||||
|
|
||||||
const pricedLineItem = pricingLineItems.splice(lineItemIndex, 1)[0];
|
|
||||||
lineItem.laborAmount = pricedLineItem.laborAmount;
|
|
||||||
lineItem.sellingPrice = pricedLineItem.sellingPrice;
|
|
||||||
lineItem.kitPrice = pricedLineItem.kitPrice;
|
|
||||||
lineItem.salesTax = pricedLineItem.salesTax;
|
|
||||||
});
|
|
||||||
|
|
||||||
return lineItems;
|
|
||||||
}
|
|
||||||
|
|
||||||
function addTaxesToPricedLineItems(pricedLineItems, taxingLineItems = []) {
|
function addTaxesToPricedLineItems(pricedLineItems, taxingLineItems = []) {
|
||||||
pricedLineItems.forEach((pricedLineItem) => {
|
pricedLineItems.forEach((pricedLineItem) => {
|
||||||
const lineItemIndex = taxingLineItems.findIndex(
|
const lineItemIndex = taxingLineItems.findIndex(
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue