Merge remote-tracking branch 'origin/develop' into feature/skiener/CSR-1452

This commit is contained in:
Scott Kiener 2023-11-15 11:12:21 -05:00
commit 8d9fbdf985
10 changed files with 117 additions and 54 deletions

View file

@ -1,20 +1,21 @@
<template>
<div class="cart mb-5">
<div class="cart">
<div class="px-0">
<div
class="row vin-toggle flex align-items-center"
class="row vin-toggle flex align-items-center py-4"
:class="[isExpanded ? 'expanded' : '']"
@click="toggleIsExpanded()">
<div class="col d-flex justify-content-between">
<span class="label">{{ amountDueText }}</span
><span class="label amount-due">{{ currencyFormatter.format(amountDue) }}</span>
><span class="label amount-due">{{ getFormattedAmount("", amountDue) }}</span>
</div>
</div>
<div class="price-table">
<div class="service-type">
<textBlock :cmsWidgetName="servicePackageTitleWidget" /><span>{{
currencyFormatter.format(packagePrice)
}}</span>
<textBlock :cmsWidgetName="servicePackageTitleWidget" />
<span>
{{ getFormattedAmount("", packagePrice) }}
</span>
</div>
<!-- Packaged Cart Items -->
@ -47,34 +48,33 @@
href="#!"
@click-event="removeItem(cartItem.cartItemType, cartItem.category)" />
<textLink
v-else-if="cartItem == recycleFeeCartItem"
v-else-if="cartItem == recycleFeeCartItem && recyclingModalCmsWidgetName"
linkType="text"
:text="recycleFeeCartItem.name"
href="#!"
@click-event="openModal(recyclingModalCmsWidgetName)" />
<span
>{{
`${
cartItem.category == "promos"
? "(" + currencyFormatter.format(cartItem.subTotal * -1) + ")"
: currencyFormatter.format(cartItem.subTotal)
}`
}}
<span v-else-if="cartItem == recycleFeeCartItem">
{{ recycleFeeCartItem.name }}
</span>
<span>{{ getFormattedAmount(cartItem.category, cartItem.subTotal) }}</span>
</div>
<!-- Sub total, sales tax, total columns -->
<div class="sub-total">
<span>{{ subtotalText }}</span
><span>{{ currencyFormatter.format(subTotal) }}</span>
><span>{{ getFormattedAmount("", subTotal) }}</span>
</div>
<div class="sales-tax">
<span>{{ salesTaxText }}</span
><span>{{ currencyFormatter.format(salesTax) }}</span>
><span>{{ getFormattedAmount("", salesTax) }}</span>
</div>
<div v-if="showAsPaid" class="amount-paid">
<span>{{ amountPaidText }}</span
><span>{{ getFormattedAmount("", amountPaid) }}</span>
</div>
<div class="amount-due">
<span>{{ amountDueText }}</span
><span>{{ currencyFormatter.format(amountDue) }}</span>
><span>{{ getFormattedAmount("", amountDue) }}</span>
</div>
</div>
</div>
@ -112,6 +112,7 @@ export default {
availableVaps: Object,
allowItemRemoval: Boolean,
recyclingModalCmsWidgetName: String,
showAsPaid: Boolean,
},
data() {
return {
@ -172,6 +173,11 @@ export default {
return vapsTypeName.Text;
},
getFormattedAmount(category, amount) {
return category == "promos"
? "(" + this.currencyFormatter.format(amount * -1) + ")"
: this.currencyFormatter.format(amount);
},
removeItem(cartItemType, category) {
this.lineItems[category] = this.lineItems[category].filter(
(lineItemsToKeep) => lineItemsToKeep.cartItemType != cartItemType
@ -319,7 +325,6 @@ export default {
}
}
});
return nonpackageCartItems;
},
frontWiperCartItemName() {
@ -670,6 +675,9 @@ export default {
amountDueText() {
return this.getCmsContent("AmountDueTextWidget", "Text");
},
amountPaidText() {
return this.getCmsContent("AmountPaidTextWidget", "Text");
},
subtotalText() {
return this.getCmsContent("SubtotalTextWidget", "Text");
},
@ -691,6 +699,15 @@ export default {
return salesTax;
},
amountDue() {
if (this.showAsPaid) {
return 0;
}
return this.subTotal + this.salesTax;
},
amountPaid() {
if (!this.showAsPaid) {
return 0;
}
return this.subTotal + this.salesTax;
},
},
@ -712,6 +729,8 @@ export default {
<style lang="scss">
.cart {
margin-bottom: 1rem;
h5 {
border-bottom: 1px solid $gray-500;
color: $black;
@ -735,6 +754,7 @@ export default {
max-height: 0;
transition: all 350ms ease-in;
overflow: hidden;
div {
display: flex;
justify-content: space-between;
@ -798,7 +818,8 @@ export default {
}
.sub-total,
.sales-tax,
.amount-due {
.amount-due,
.amount-paid {
font-weight: 500;
}
.sub-total {
@ -825,7 +846,7 @@ export default {
display: inline-flex;
position: relative;
right: 0.75rem;
margin: 1rem 0 1rem 1rem;
margin: 0.5rem 0 0.5rem 1rem;
cursor: pointer;
}
&.expanded:after {
@ -835,6 +856,7 @@ export default {
max-height: 650px;
transition: all 350ms ease-in;
overflow: hidden;
padding-top: 1rem;
}
}
}

View file

@ -5,7 +5,7 @@ export function getDateDifferenceInDays(startDate, endDate) {
// Use the built-in method to get the difference in milliseconds
var difference = date1 - date2;
// Convert milliseconds to days and return the result
return Math.floor(difference / (1000 * 3600 * 24));
return Math.round(difference / (1000 * 3600 * 24));
}
export function get12HourTimeFormat(time) {
// Check correct time format and split into components

View file

@ -56,6 +56,9 @@ beforeEach(() => {
damage: {
isRepair: false,
},
payment: {
isPia: true,
},
referralNumber: "1234567",
vehicle: {
year: "2004",
@ -113,6 +116,7 @@ beforeEach(() => {
emailAddress: "test@test.com",
},
},
damage: {},
payment: {
isInsurance: true,
},

View file

@ -37,6 +37,15 @@
<div class="appoinmenttext" v-html="AppointmentWordingText"></div>
</div>
<hr />
<cart
:damage="damageInfo"
:availableVaps="vaps"
:allowItemRemoval="false"
v-model="lineItems"
:showAsPaid="isPia"
servicePackageOptionsCmsName="ServicePackageTitle" />
<hr class="mb-5" />
<div class="emailtext" v-html="ConfirmationEmailText"></div>
<navbar
cmsWidgetName="FunnelFooterWidget"
@ -57,19 +66,21 @@ import funnelHeader from "@/fmg-components/funnel-header/funnel-header";
import vehicleBanner from "@/fmg-components/vehicle-banner/vehicle-banner";
import navbar from "@/fmg-components/nav-bar/nav-bar";
import addToCalendar from "@/layouts/confirmation/add-to-calendar/add-to-calendar";
import cart from "@/fmg-components/cart/cart";
//Supporting files
import baseMixin from "@/mixins/base-mixin.js";
import store from "@/store";
import { storeActions } from "@/constants/store-actions";
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
import { AppointmentTypeStrings } from "@/constants/schedule-constants";
import { settleAllPromises } from "@/helpers/layout-helper";
import { applicationConfig } from "@/constants/application-config.js";
import { convertDateStringToDate } from "@/layouts/schedule/helpers/schedule-helper";
import { deepClone } from "@/helpers/object-helper";
import { Form } from "vee-validate";
import store from "@/store";
import { get12HourTimeFormat, get12HourTimeMobileFormat } from "@/helpers/date-helper";
export default {
name: "confirmation",
async beforeRouteEnter(to, from, next) {
@ -87,11 +98,21 @@ export default {
];
const resultMap = await settleAllPromises(promiseResultMap);
const lineItemsFromSubmittedOrder = deepClone(store.getters.submittedOrder.lineItems);
// Call the "next" function to complete the transition to this page.
next((vm) => {
vm.setCmsContent(resultMap.cmsContent);
vm.lineItems = lineItemsFromSubmittedOrder;
vm.vaps = lineItemsFromSubmittedOrder.vaps;
});
},
data() {
return {
lineItems: [],
vaps: [],
};
},
computed: {
ScheduleConfirmationText() {
return this.getCmsContent("ScheduleConfirmationWidget", "BodyText");
@ -209,6 +230,12 @@ export default {
vehicleBannerImageUrl() {
return store.getters.submittedOrder?.vehicle.imageUrl;
},
damageInfo() {
return store.getters.damage;
},
isPia() {
return store.getters.submittedOrder?.payment.isPia;
},
},
methods: {
arePagePrerequisitesValid() {
@ -258,12 +285,14 @@ export default {
navbar,
vehicleBanner,
addToCalendar,
cart,
},
};
</script>
<style lang="scss">
.main {
margin-bottom: 1.5rem;
padding: 1rem 1.5rem 1.5rem;
box-shadow: 0 3px 10px rgb(0 0 0 / 0.2);
border-radius: 5px;
@ -336,7 +365,7 @@ export default {
}
.emailtext {
padding: 1.5rem 0 0;
padding: 0.5rem 0 0;
p {
font-size: 0.875rem;

View file

@ -287,13 +287,6 @@ export default {
return answers[answerIndex];
};
if (!this.rainDefenseInCart) {
// NO RAIN DEFENSE IN CART; SHOW RAIN DEFENSE BUTTON
const modalData = getAnswer("RainDefenseModal", this.answersCmsData);
modalData.SubText = "+$" + this.rainDefenseModal?.listPrice;
buttons.push(modalData);
}
const modalData = getAnswer("WipersModal", this.answersCmsData);
if (this.wipersOffered === wipersOfferedStrings.BOTH) {
// NO REAR WIPERS or FRONT WIPERS IN CART; SHOW COMBO BUTTON
@ -318,6 +311,13 @@ export default {
buttons.push(modalData);
}
if (!this.rainDefenseInCart) {
// NO RAIN DEFENSE IN CART; SHOW RAIN DEFENSE BUTTON
const modalData = getAnswer("RainDefenseModal", this.answersCmsData);
modalData.SubText = "+$" + this.rainDefenseModal?.listPrice;
buttons.push(modalData);
}
return buttons;
},
wipersOfferedStrings() {

View file

@ -19,7 +19,7 @@
<span>{{ noPiaDisclaimer }}</span>
</p>
<hr />
<hr class="my-0" />
<cart
:damage="damageInfo"
@ -29,14 +29,15 @@
servicePackageOptionsCmsName="ServicePackageTitle"
recyclingModalCmsWidgetName="RecycleModal" />
<hr class="my-5" />
<promoModalQuestion
class="pb-3"
class="pb-2"
v-model="lineItems"
:availableVaps="availableVaps"
linkWidgetName="PromoLinkWidget"
modalWidgetName="PromoModalWidget" />
<hr class="mb-5" />
<div>
<alert
ref="piaErrorAlert"
@ -413,7 +414,6 @@ export default {
return;
}
}
this.dispatchStoreAction(storeActions.RESET_SAVE_SESSION_PROMISE);
this.$router.navigateWithoutSaving(
this.navigationScenarios.CLICKED_PAY_NOW,

View file

@ -217,13 +217,11 @@ export default {
} else {
if (promoCodeData.errorCode == promoErrorCodes.PROMO_STACKING_NOT_ALLOWED) {
this.displayInvalidOnOrderPromoAlert = true;
this.focusOnPromoInput();
this.resetModalButtonStyle();
} else {
this.displayInvalidPromoAlert = true;
this.focusOnPromoInput();
this.resetModalButtonStyle();
}
this.focusOnPromoInput();
this.resetModalButtonStyle();
}
}
},

View file

@ -8,6 +8,7 @@
cornerStyle="rounded"
:displayQuestionText="false"
isRequired
@input="validateAlphanumeric"
validationRules="promo-required" />
</template>
@ -22,6 +23,8 @@ import { errorMessages } from "@/constants/error-messages";
// Define Validation Rules
defineRule("promo-required", required(errorMessages.PROMO_REQUIRED));
const ALPHANUMERIC_REGEX = /[^a-zA-Z0-9]/g;
export default {
name: "promo-question",
props: {
@ -38,6 +41,11 @@ export default {
},
},
},
methods: {
validateAlphanumeric() {
this.value = this.value.replace(ALPHANUMERIC_REGEX, "");
},
},
components: {
textboxQuestion,
},

View file

@ -26,13 +26,13 @@
<cart
:damage="damageInfo"
:availableLineItems="availableLineItems"
:availableVaps="availableVaps"
:allowItemRemoval="false"
v-model="lineItems"
servicePackageOptionsCmsName="ServicePackageTitle"
recyclingModalCmsWidgetName="RecycleModal" />
<hr />
<hr class="mb-5" />
<paymentSwitch
cmsWidgetName="PaymentMethodWidget"
@ -267,12 +267,6 @@ export default {
"payment"
);
const supportingItemsPromise = baseMixin.methods.dispatchStoreActionWithLogging(
storeActions.GET_SUPPORTING_ITEMS,
null,
"payment"
);
// TODO: Data fetching Promise declarations
const promiseResultMap = [
@ -292,10 +286,6 @@ export default {
resultKey: "rainDefense",
promise: rainDefensePromise,
},
{
resultKey: "supportingItems",
promise: supportingItemsPromise,
},
];
const resultMap = await settleAllPromises(promiseResultMap);
@ -363,12 +353,14 @@ export default {
taxedVaps,
lineItems
);
lineItems.vaps = lineItems.vaps ?? [];
lineItems.vaps.push(...vapsToAddToCart);
// Call the "next" function to complete the transition to this page.
next(async (vm) => {
vm.setCmsContent(resultMap.cmsContent);
vm.fetchSignatureInfo(resultMap.signature);
vm.setIFrameListener();
vm.availableVaps = taxedVaps;
vm.lineItems = lineItems;
@ -586,6 +578,16 @@ export default {
this.submitHopForm();
},
handleIFrameContentWindwMessage(event) {
if (event.data.indexOf("afterpayClosed") > -1) {
this.backButtonAction();
}
},
setIFrameListener() {
window.addEventListener("message", (event) =>
this.handleIFrameContentWindwMessage(event)
);
},
},
components: {
funnelHeader,

View file

@ -95,7 +95,7 @@ export default {
}
&.allow-ui-interaction::before {
//no-block to enable clicking on certain buttons with loaders while the loader is actives
z-index: -1;
pointer-events: none;
}
}
</style>