Merge branch 'release/2025.06.19' into rlsmerge/2025.06.19-to-develop
This commit is contained in:
commit
19ebedbb2f
6 changed files with 192 additions and 133 deletions
|
|
@ -94,8 +94,16 @@ export default {
|
|||
FirstName: transfer.data.first_name,
|
||||
LastName: transfer.data.last_name,
|
||||
Email: transfer.data.email,
|
||||
Subject: transfer.data.chat_summary, // for now passing in chat_summery in Subject. But this will be changed in future.
|
||||
Subject: transfer.data.chat_summary,
|
||||
};
|
||||
window.embedded_svc.settings.extraPrechatFormDetails = [
|
||||
{
|
||||
label: "Scarlett AI Summary",
|
||||
value: transfer.data.chat_summary,
|
||||
transcriptFields: ["Scarlett_AI_Summary__c"],
|
||||
displayToAgent: true,
|
||||
},
|
||||
];
|
||||
if (
|
||||
window.embedded_svc.liveAgentAPI &&
|
||||
typeof window.embedded_svc.liveAgentAPI.startChat === "function"
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ import { saveSession } from "@/helpers/heritage-integration/order-helper.js";
|
|||
import baseMixin from "@/mixins/base-mixin.js";
|
||||
import { queryStrings } from "@/constants/query-strings";
|
||||
import { nextTick } from "vue";
|
||||
import { consumeQueryFromStash } from "@/router/methods/helpers/querystring-stash";
|
||||
import { peekQueryFromStash } from "@/router/methods/helpers/querystring-stash";
|
||||
|
||||
// Define Validation Rules
|
||||
defineRule("zip-required", required(errorMessages.SERVICE_ZIP_REQUIRED));
|
||||
|
|
@ -100,7 +100,7 @@ export default {
|
|||
}
|
||||
|
||||
const zip =
|
||||
consumeQueryFromStash(queryStrings.ZIP_CODE) ??
|
||||
peekQueryFromStash(queryStrings.ZIP_CODE) ??
|
||||
store.getters.order.serviceLocation.zipCode;
|
||||
|
||||
var vinByAddressPromise;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import { reactive } from "vue";
|
||||
import { debugLog } from "@/helpers/debug-log-helper";
|
||||
|
||||
const queryStash = reactive({
|
||||
queries: [],
|
||||
|
|
@ -27,10 +28,18 @@ export function stashAllQueries(toRoute) {
|
|||
}
|
||||
|
||||
function getStashedQuery(key) {
|
||||
debugLog(`Fetching querystring with key:`, key);
|
||||
const match = queryStash.queries.find(
|
||||
(entry) => entry?.key?.toLowerCase() === key?.toLowerCase()
|
||||
);
|
||||
|
||||
if (match) {
|
||||
debugLog(`Found result:`, match.value);
|
||||
debugLog(`Already consumed:`, match.used);
|
||||
} else {
|
||||
debugLog(`Found no result`);
|
||||
}
|
||||
|
||||
return match;
|
||||
}
|
||||
|
||||
|
|
|
|||
14
src/router/methods/route-logic/payment.js
Normal file
14
src/router/methods/route-logic/payment.js
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
import store from "@/store";
|
||||
import { storeActions } from "@/constants/store-actions";
|
||||
import { paymentMethods } from "@/constants/payment-method-constants";
|
||||
import { debugLog } from "@/helpers/debug-log-helper";
|
||||
|
||||
export async function paymentBeforeEnter(to, from) {
|
||||
const piaType = store.getters.order?.payment?.piaType;
|
||||
debugLog(`Entering payment with type =`, piaType);
|
||||
|
||||
if (piaType === paymentMethods.PAYPAL) {
|
||||
debugLog(`Changing to payment type =`, paymentMethods.CREDIT_CARD);
|
||||
await store.dispatch(storeActions.SAVE_PAYMENT_METHOD_CHOICE, paymentMethods.CREDIT_CARD);
|
||||
}
|
||||
}
|
||||
|
|
@ -11,6 +11,7 @@ import { autoRouteBeforeEnter } from "@/router/methods/route-logic/auto-route";
|
|||
import { errorBeforeEnter } from "@/router/methods/route-logic/error";
|
||||
import { restartBeforeEnter } from "@/router/methods/route-logic/restart";
|
||||
import { paymentMethodBeforeEnter } from "@/router/methods/route-logic/payment-method";
|
||||
import { paymentBeforeEnter } from "@/router/methods/route-logic/payment";
|
||||
|
||||
export const routes = [
|
||||
// Non-virtual pages.
|
||||
|
|
@ -32,7 +33,7 @@ export const routes = [
|
|||
createRoute(routeData.SCHEDULE),
|
||||
createRoute(routeData.CUSTOMER_DETAILS),
|
||||
createRoute(routeData.PAYMENT_METHOD, paymentMethodBeforeEnter),
|
||||
createRoute(routeData.PAYMENT),
|
||||
createRoute(routeData.PAYMENT, paymentBeforeEnter),
|
||||
createRoute(routeData.PAYMENT_PIA_RETURN),
|
||||
createRoute(routeData.CONFIRMATION),
|
||||
createRoute(routeData.RETURN_USER),
|
||||
|
|
|
|||
|
|
@ -1072,33 +1072,6 @@ export const getters = {
|
|||
},
|
||||
};
|
||||
|
||||
function getNonFalseValuesOfPropertyInArrayOfObjects(array, propertyName) {
|
||||
return (array ?? []).map((x) => x[propertyName]).filter((x) => x);
|
||||
}
|
||||
|
||||
function getTimeSlotsAdditionalEventData(
|
||||
provisionalTriggers,
|
||||
zipCode,
|
||||
firstAvailableAppointmentDateString,
|
||||
shopAppointmentType
|
||||
) {
|
||||
var numberOfDays = null;
|
||||
if (firstAvailableAppointmentDateString)
|
||||
numberOfDays = getDateDifferenceInDays(
|
||||
new Date().toISOString().split("T")[0],
|
||||
firstAvailableAppointmentDateString
|
||||
);
|
||||
|
||||
if (shopAppointmentType)
|
||||
return `FirstAvailableAppointment:${numberOfDays},Zip:${zipCode},ShopAppointmentType:${shopAppointmentType},ProvisionalTriggers:${provisionalTriggers.join(
|
||||
","
|
||||
)}`;
|
||||
else
|
||||
return `FirstAvailableAppointment:${numberOfDays},Zip:${zipCode},ProvisionalTriggers:${provisionalTriggers.join(
|
||||
","
|
||||
)}`;
|
||||
}
|
||||
|
||||
// Export Actions
|
||||
export const actions = {
|
||||
// Vehicle API Actions
|
||||
|
|
@ -2059,20 +2032,31 @@ export const actions = {
|
|||
},
|
||||
};
|
||||
|
||||
return globalMethods.callHttpClient({
|
||||
let hasCalled = timeSlotCallFlags.shop;
|
||||
if (!hasCalled) {
|
||||
timeSlotCallFlags.shop = true;
|
||||
}
|
||||
|
||||
const options = {
|
||||
method: endpoints.GetShopTimeSlots.method,
|
||||
endpoint: endpoints.GetShopTimeSlots.url,
|
||||
payload: payload,
|
||||
logApiCall: true,
|
||||
pageNameToLog: pageNameToLog,
|
||||
additionalSuccessEventDataHandler: (response) =>
|
||||
};
|
||||
|
||||
// Only set handler if this is the very first call in this session
|
||||
if (!hasCalled) {
|
||||
options.additionalSuccessEventDataHandler = (response) =>
|
||||
getTimeSlotsAdditionalEventData(
|
||||
response.data.provisionalTriggers,
|
||||
order.serviceLocation.zipCode,
|
||||
response.data.days?.[0]?.date,
|
||||
shopAppointmentType
|
||||
),
|
||||
});
|
||||
);
|
||||
}
|
||||
|
||||
return globalMethods.callHttpClient(options);
|
||||
},
|
||||
|
||||
getMobileTimeSlots(context, { payload: { startDate, endDate }, pageNameToLog }) {
|
||||
|
|
@ -2116,19 +2100,30 @@ export const actions = {
|
|||
zipCode: order.serviceLocation.zipCode,
|
||||
};
|
||||
|
||||
return globalMethods.callHttpClient({
|
||||
let hasCalled = timeSlotCallFlags.mobile;
|
||||
if (!hasCalled) {
|
||||
timeSlotCallFlags.mobile = true;
|
||||
}
|
||||
|
||||
const options = {
|
||||
method: endpoints.GetMobileTimeSlots.method,
|
||||
endpoint: endpoints.GetMobileTimeSlots.url,
|
||||
payload: payload,
|
||||
logApiCall: true,
|
||||
pageNameToLog: pageNameToLog,
|
||||
additionalSuccessEventDataHandler: (response) =>
|
||||
};
|
||||
|
||||
// Only set handler if this is the very first call in this session
|
||||
if (!hasCalled) {
|
||||
options.additionalSuccessEventDataHandler = (response) =>
|
||||
getTimeSlotsAdditionalEventData(
|
||||
response.data.provisionalTriggers,
|
||||
order.serviceLocation.zipCode,
|
||||
response.data.days?.[0]?.date
|
||||
),
|
||||
});
|
||||
);
|
||||
}
|
||||
|
||||
return globalMethods.callHttpClient(options);
|
||||
},
|
||||
|
||||
getMobilePremiumFee(context, { pageNameToLog }) {
|
||||
|
|
@ -3457,100 +3452,6 @@ export default createStore({
|
|||
actions,
|
||||
});
|
||||
|
||||
// Private Functions
|
||||
|
||||
function getHasRecalibrationPart(state) {
|
||||
return containsRecalParts(state.order.lineItems);
|
||||
}
|
||||
|
||||
function sortArrayOfObjectsByPropertyValue(arrayOfObjects, propertyName) {
|
||||
if (!arrayOfObjects) return null;
|
||||
|
||||
return arrayOfObjects.sort((a, b) => {
|
||||
if (a[propertyName] < b[propertyName]) return -1;
|
||||
else if (a[propertyName] > b[propertyName]) return 1;
|
||||
else return 0;
|
||||
});
|
||||
}
|
||||
|
||||
function convertGlassPieceNamingForApi(glassArray) {
|
||||
if (!glassArray || glassArray.length === 0) return [];
|
||||
|
||||
// check if array already converted. (likely when a session has been saved previously and then reloaded)
|
||||
if (glassArray[0].location !== undefined) {
|
||||
return glassArray;
|
||||
}
|
||||
|
||||
const converted = [];
|
||||
glassArray.forEach((glass) => {
|
||||
converted.push({
|
||||
location: glass.glassLocation,
|
||||
name: glass.glassName,
|
||||
});
|
||||
});
|
||||
return converted;
|
||||
}
|
||||
|
||||
function convertResultsForApi(resultsArray) {
|
||||
if (!resultsArray) return [];
|
||||
const converted = [];
|
||||
resultsArray.forEach((answer) => {
|
||||
converted.push({
|
||||
location: answer.glassLocation,
|
||||
name: answer.glassName,
|
||||
result: answer.result,
|
||||
});
|
||||
});
|
||||
return converted;
|
||||
}
|
||||
|
||||
function convertGlassPieceNamingFromApi(glassArray) {
|
||||
glassArray.forEach((glass) => {
|
||||
glass.glassLocation = glass.glassPiece.location;
|
||||
glass.glassName = glass.glassPiece.name;
|
||||
delete glass.glassPiece;
|
||||
return glass;
|
||||
});
|
||||
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 = []) {
|
||||
pricedLineItems.forEach((pricedLineItem) => {
|
||||
const lineItemIndex = taxingLineItems.findIndex(
|
||||
(taxingLineItem) => taxingLineItem.partNumber === pricedLineItem.partNumber
|
||||
);
|
||||
|
||||
if (pricedLineItem.childParts) {
|
||||
addTaxesToPricedLineItems(pricedLineItem.childParts, taxingLineItems);
|
||||
}
|
||||
|
||||
const taxedLineItem = taxingLineItems.splice(lineItemIndex, 1)[0];
|
||||
pricedLineItem.salesTax = taxedLineItem?.salesTax ?? 0;
|
||||
});
|
||||
|
||||
return pricedLineItems;
|
||||
}
|
||||
|
||||
export function mapTaxedLineItemsToStoreFormat(availableLineItems, storeLineItems) {
|
||||
// clone the lineItems array because what we're passing in is referencing the store directly
|
||||
const lineItems = deepClone(storeLineItems);
|
||||
|
|
@ -3658,6 +3559,127 @@ export function getArrayOfAllLineItemsAndChildParts(lineItems) {
|
|||
return consolidatedLineItemsArray;
|
||||
}
|
||||
|
||||
// Private Functions
|
||||
|
||||
function getNonFalseValuesOfPropertyInArrayOfObjects(array, propertyName) {
|
||||
return (array ?? []).map((x) => x[propertyName]).filter((x) => x);
|
||||
}
|
||||
|
||||
function getTimeSlotsAdditionalEventData(
|
||||
provisionalTriggers,
|
||||
zipCode,
|
||||
firstAvailableAppointmentDateString,
|
||||
shopAppointmentType
|
||||
) {
|
||||
var numberOfDays = null;
|
||||
if (firstAvailableAppointmentDateString)
|
||||
numberOfDays = getDateDifferenceInDays(
|
||||
new Date().toISOString().split("T")[0],
|
||||
firstAvailableAppointmentDateString
|
||||
);
|
||||
|
||||
if (shopAppointmentType)
|
||||
return `FirstAvailableAppointment:${numberOfDays},Zip:${zipCode},ShopAppointmentType:${shopAppointmentType},ProvisionalTriggers:${provisionalTriggers.join(
|
||||
","
|
||||
)}`;
|
||||
else
|
||||
return `FirstAvailableAppointment:${numberOfDays},Zip:${zipCode},ProvisionalTriggers:${provisionalTriggers.join(
|
||||
","
|
||||
)}`;
|
||||
}
|
||||
|
||||
function getHasRecalibrationPart(state) {
|
||||
return containsRecalParts(state.order.lineItems);
|
||||
}
|
||||
|
||||
function sortArrayOfObjectsByPropertyValue(arrayOfObjects, propertyName) {
|
||||
if (!arrayOfObjects) return null;
|
||||
|
||||
return arrayOfObjects.sort((a, b) => {
|
||||
if (a[propertyName] < b[propertyName]) return -1;
|
||||
else if (a[propertyName] > b[propertyName]) return 1;
|
||||
else return 0;
|
||||
});
|
||||
}
|
||||
|
||||
function convertGlassPieceNamingForApi(glassArray) {
|
||||
if (!glassArray || glassArray.length === 0) return [];
|
||||
|
||||
// check if array already converted. (likely when a session has been saved previously and then reloaded)
|
||||
if (glassArray[0].location !== undefined) {
|
||||
return glassArray;
|
||||
}
|
||||
|
||||
const converted = [];
|
||||
glassArray.forEach((glass) => {
|
||||
converted.push({
|
||||
location: glass.glassLocation,
|
||||
name: glass.glassName,
|
||||
});
|
||||
});
|
||||
return converted;
|
||||
}
|
||||
|
||||
function convertResultsForApi(resultsArray) {
|
||||
if (!resultsArray) return [];
|
||||
const converted = [];
|
||||
resultsArray.forEach((answer) => {
|
||||
converted.push({
|
||||
location: answer.glassLocation,
|
||||
name: answer.glassName,
|
||||
result: answer.result,
|
||||
});
|
||||
});
|
||||
return converted;
|
||||
}
|
||||
|
||||
function convertGlassPieceNamingFromApi(glassArray) {
|
||||
glassArray.forEach((glass) => {
|
||||
glass.glassLocation = glass.glassPiece.location;
|
||||
glass.glassName = glass.glassPiece.name;
|
||||
delete glass.glassPiece;
|
||||
return glass;
|
||||
});
|
||||
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 = []) {
|
||||
pricedLineItems.forEach((pricedLineItem) => {
|
||||
const lineItemIndex = taxingLineItems.findIndex(
|
||||
(taxingLineItem) => taxingLineItem.partNumber === pricedLineItem.partNumber
|
||||
);
|
||||
|
||||
if (pricedLineItem.childParts) {
|
||||
addTaxesToPricedLineItems(pricedLineItem.childParts, taxingLineItems);
|
||||
}
|
||||
|
||||
const taxedLineItem = taxingLineItems.splice(lineItemIndex, 1)[0];
|
||||
pricedLineItem.salesTax = taxedLineItem?.salesTax ?? 0;
|
||||
});
|
||||
|
||||
return pricedLineItems;
|
||||
}
|
||||
|
||||
function getFlattenedArrayOfLineItemsWithChildParts(lineItems, childPartRecursiveCall = false) {
|
||||
let flattenedArray = [];
|
||||
lineItems?.forEach((lineItem) => {
|
||||
|
|
@ -3966,3 +3988,8 @@ function getExternalParameterDefaultState() {
|
|||
function saveExternalParameterState(externalParameterState) {
|
||||
window.sessionStorage.setItem("externalParameterState", JSON.stringify(externalParameterState));
|
||||
}
|
||||
|
||||
const timeSlotCallFlags = {
|
||||
shop: false,
|
||||
mobile: false,
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in a new issue