diff --git a/src/digital-components/sierra-webchat/sierra-webchat.vue b/src/digital-components/sierra-webchat/sierra-webchat.vue
index 2a114616a..8210e9075 100644
--- a/src/digital-components/sierra-webchat/sierra-webchat.vue
+++ b/src/digital-components/sierra-webchat/sierra-webchat.vue
@@ -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"
diff --git a/src/fmg-components/cart/cart.vue b/src/fmg-components/cart/cart.vue
index 2a715bc93..ef3e0300c 100644
--- a/src/fmg-components/cart/cart.vue
+++ b/src/fmg-components/cart/cart.vue
@@ -117,6 +117,10 @@
{{ amountPaidText }}
{{ getLineItemAmount(amountPaid) }}
+
+ {{ donationCartItemName }}
+ {{ getLineItemAmount(donationCartItem.subTotal) }}
+
{{ amountDueText }}
{{ getLineItemAmount(amountDue, showCoverageAsPending) }}
@@ -472,10 +476,6 @@ export default {
});
}
- if (this.donationCartItem) {
- cartItems.push(this.donationCartItem);
- }
-
return cartItems;
},
},
@@ -1309,12 +1309,15 @@ export default {
.sub-total,
.sales-tax,
.amount-due,
- .amount-paid {
- font-weight: 500;
+ .amount-paid,
+ .donation-amount {
+ font-family:
+ UrbanistSemibold, AvertaSemibold; //Okay to remove AvertaSemibold after 2025.06.19 merge/release
color: $black;
}
.sub-total {
border-top: 1px solid $green;
+ background-color: $green-100;
}
.service-type,
.deductible {
diff --git a/src/layouts/estimate/estimate.vue b/src/layouts/estimate/estimate.vue
index 811cd1a86..2818d2ecb 100644
--- a/src/layouts/estimate/estimate.vue
+++ b/src/layouts/estimate/estimate.vue
@@ -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;
diff --git a/src/router/methods/helpers/querystring-stash.js b/src/router/methods/helpers/querystring-stash.js
index 96b206572..b000f8feb 100644
--- a/src/router/methods/helpers/querystring-stash.js
+++ b/src/router/methods/helpers/querystring-stash.js
@@ -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;
}
diff --git a/src/router/methods/route-logic/payment.js b/src/router/methods/route-logic/payment.js
new file mode 100644
index 000000000..73f2b5cac
--- /dev/null
+++ b/src/router/methods/route-logic/payment.js
@@ -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);
+ }
+}
diff --git a/src/router/methods/routes.js b/src/router/methods/routes.js
index 19c802aae..c029ce2cb 100644
--- a/src/router/methods/routes.js
+++ b/src/router/methods/routes.js
@@ -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),
diff --git a/src/store/index.js b/src/store/index.js
index c3ad4996e..073a50e23 100644
--- a/src/store/index.js
+++ b/src/store/index.js
@@ -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,
+};
diff --git a/src/styles/ux-variables.scss b/src/styles/ux-variables.scss
index 1f17a6cf1..9acab9499 100644
--- a/src/styles/ux-variables.scss
+++ b/src/styles/ux-variables.scss
@@ -121,8 +121,8 @@ $body-color: $gray-600;
//Fonts
$font-family-sans-serif: AvertaRegular, Arial, Helvetica, sans-serif;
-$font-family-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New",
- monospace;
+$font-family-monospace:
+ SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
// stylelint-enable value-keyword-case
$font-family-base: $font-family-sans-serif;
$font-family-code: $font-family-monospace;
@@ -170,8 +170,7 @@ $spacers: (
/* 16px */ 5: $spacer * 1.5,
/* 24px */ 6: $spacer * 2,
/* 32px */ 7: $spacer * 2.5,
- /* 40px */ 8: $spacer * 3,
- /* 48px */
+ /* 40px */ 8: $spacer * 3 /* 48px */,
);
//Enable negative spacing (does NOT work on padding)