This commit is contained in:
Sneha 2023-11-08 16:28:27 +05:30
parent b25b2abde1
commit 8455ec926b
7 changed files with 247 additions and 8 deletions

View file

@ -33,6 +33,7 @@ const errorMessages = {
MAKE_REQUIRED: "Please select your vehicle make",
MODEL_REQUIRED: "Please select your vehicle model",
STYLE_REQUIRED: "Please select your vehicle style",
PROMO_REQUIRED: "Please enter a promo code",
};
export { errorMessages };

View file

@ -239,15 +239,15 @@ export default {
let cartItem = null;
cartItem = {
name: "Some Kind of Promo", // get from CMS?
name: promoLineItem?.[0]?.promoCode, // get from CMS?
category: cartItemCategories.PROMOS,
cartItemType: promoLineItem.partType,
cartItemType: promoLineItem?.[0]?.partType,
isDisplayed: true,
subTotal:
(promoLineItem.kitPrice ?? 0) +
(promoLineItem.laborAmount ?? 0) +
(promoLineItem.sellingPrice ?? 0),
salesTax: promoLineItem.salesTax,
(promoLineItem?.[0]?.kitPrice ?? 0) +
(promoLineItem?.[0]?.laborAmount ?? 0) +
(promoLineItem?.[0]?.sellingPrice ?? 0),
salesTax: promoLineItem?.[0]?.salesTax,
};
cartItems.push(cartItem);

View file

@ -30,7 +30,13 @@
@cart-remove="cartRemove"
recyclingModalCmsWidgetName="RecycleModal" />
<hr class="my-5" />
<hr class="my-5"/>
<promoModalQuestion
v-model="lineItems"
:availableLineItems="availableLineItems"
@added-to-cart="showAlert"
linkWidgetName="PromoLinkWidget"
modalWidgetName="PromoModalWidget" />
<div>
<alert
@ -74,6 +80,7 @@ import funnelSubHeader from "@/fmg-components/funnel-sub-header/funnel-sub-heade
import paymentMethodQuestion from "@/layouts/payment-method/payment-method-question/payment-method-question";
import loadingModal from "@/fmg-components/loading-modal/loading-modal.vue";
import cart from "@/fmg-components/cart/cart";
import promoModalQuestion from "@/layouts/payment-method/promo-modal-question/promo-modal-question";
import addVapsModalButtons from "./add-vaps-modal-buttons/add-vaps-modal-buttons";
import { submitWorkOrder } from "@/helpers/heritage-integration/order-helper.js";
import alert from "@/ux-components/alert/alert";
@ -464,6 +471,7 @@ export default {
alert,
addVapsModalButtons,
paymentMethodQuestion,
promoModalQuestion,
},
};
</script>

View file

@ -0,0 +1,167 @@
<template>
<div>
<textLink
id="promoLinkPromptId"
linkType="text"
:text="promoLinkText"
href="#!"
@click-event="openModal" />
<modal
:ref="modalName"
:headerText="modalHeaderText"
:footerButtonText="modalFooterText"
@footer-button-event="addPromoCode">
<promoQuestion
ref="promoQuestion"
customInputId="promoCode"
v-model="promoCode"
cmsWidgetName="PromoQuestionWidget" />
<div
v-for="(promo, i) in this.lineItems?.promos"
:key="i">
<span>Promo code "{{ promo?.promoCode }}" applied</span>
<textLink
ref="removeLink"
linkType="text"
:text="removeLinkText"
href="#!"
@click-event="removeItem()" />
</div>
<alert
ref="alertInvalidPromo"
v-if="displayInvalidPromoAlert"
v-html="InvalidPromoText"
class="my-4"
cmsWidgetName="AlertInvalidPromoWidget"
alertClass="alert-danger"
v-bind:isDismissible="true" />
</modal>
</div>
</template>
<script>
import textLink from "@/ux-components/text-link/text-link";
import promoQuestion from "@/layouts/payment-method/promo-modal-question/promo-question/promo-question";
import modal from "@/digital-components/modal/modal";
import alert from "@/ux-components/alert/alert";
import { processIfStatements } from "@/helpers/cms-content-helper";
import { deepClone } from "@/helpers/object-helper";
// import {
// getVapsThatNeedToBeAddedToSatisfyPromos,
// } from "@/helpers/promotions-helper";
export default {
name: "promo-modal-question",
data() {
return {
promoCode: String,
promoTextInputId: "",
displayInvalidPromoAlert: false,
lineItems:deepClone(this.modelValue),
};
},
props: {
modelValue: Object,
linkWidgetName: String,
modalWidgetName: String,
availableLineItems:Object
},
computed: {
promoLinkText() {
return this.getCmsContent(this.linkWidgetName, "BodyText");
},
modalHeaderText() {
return this.getCmsContent("PromoQuestionWidget", "QuestionText");
},
modalFooterText() {
return this.getCmsContent(this.modalWidgetName, "FooterText");
},
modalName() {
return this.modalWidgetName;
},
modal() {
return this.$refs[this.modalName];
},
PromoText() {
return this.getCmsContent("AlertInvalidPromoWidget", "HeadlineText");
},
InvalidPromoText() {
return this.PromoText?.replaceAll("{custom:Promocode}", this.promoCode);
},
AddPromoSuccessMessageFromCms() {
return this.getCmsContent("PromoSuccessAlertWidget", "Text");
},
removeLinkText() {
return this.getCmsContent("RemoveCartItemTextWidget", "Text");
},
},
methods: {
processIfStatements,
resetAlerts() {
this.displayInvalidPromoAlert = false;
},
resetsOnPromoInput() {
this.resetAlerts();
},
openModal() {
this.modal.openModal();
},
closeModal() {
this.modal.closeModal();
},
focusOnPromoInput() {
const input = document.getElementById(this.promoTextInputId);
input?.focus();
},
resetModalButtonStyle() {
this.modal.resetButtonStyle();
},
getPromoAddedMessage() {
return this.processIfStatements(
this.AddPromoSuccessMessageFromCms,
"custom",
this.promoCode
);
},
async addPromoCode() {
if (this.promoCode) {
this.resetAlerts();
const promoCodeData = await this.getPromoCodeData(this.promoCode,this.lineItems,this.availableLineItems, "payment-method");
if (promoCodeData.isValid) {
let promos = [];
promos.push(promoCodeData.promoCode);
const modelValue = this.modelValue;
modelValue.promos = promos;
this.closeModal();
const message = this.getPromoAddedMessage();
this.$emit("added-to-cart", {
messageHeadline: "Promo Applied!",
messageCopy: message,
type: "alert-success",
isDismissible: true,
});
} else {
if (promoCodeData.errorCode === "PromoDoesNotExist") {
this.displayInvalidPromoAlert = true;
this.focusOnPromoInput();
this.resetModalButtonStyle();
}
}
}
},
},
watch: {
promoCode() {
this.displayInvalidPromoAlert = false;
},
},
components: {
textLink,
promoQuestion,
modal,
alert,
},
};
</script>

View file

@ -0,0 +1,47 @@
<template>
<textboxQuestion
ref="promoInputTextQuestion"
:cmsWidgetName="cmsWidgetName"
v-model="value"
inputId="promoCode"
questionAlignment="center"
cornerStyle="rounded"
:displayQuestionText="false"
isRequired
validationRules="promo-required" />
</template>
<script>
import textboxQuestion from "@/digital-components/textbox-question/textbox-question";
//Supporting Files
import { defineRule } from "vee-validate";
import { required } from "@/helpers/validation-rules";
import { errorMessages } from "@/constants/error-messages";
// Define Validation Rules
defineRule("promo-required", required(errorMessages.PROMO_REQUIRED));
export default {
name: "promo-question",
props: {
modelValue: {
promoCode: String,
},
cmsWidgetName: String,
},
computed: {
value: {
get: function () {
return this.modelValue;
},
set: function (newValue) {
this.$emit("update:modelValue", newValue);
},
},
},
components: {
textboxQuestion,
},
};
</script>

View file

@ -80,6 +80,21 @@ export default {
zipCodeCtu: serviceZipValidationResponse.data.zipCodeCtu,
};
},
async getPromoCodeData(promoCode, pageNameToLog = null) {
const pageName = pageNameToLog ?? this.$options?.name;
const promoValidationResponse = await this.dispatchStoreActionWithLogging(
storeActions.VALIDATE_ORDER_PROMO_AND_SAVE_SERVER_DATA,
{ promoCode: promoCode },
pageName
);
return {
isValid: !("errorCode" in promoValidationResponse),
promoCode: promoValidationResponse?.orderPromos,
errorCode: promoValidationResponse?.errorCode,
};
},
getTierOnePackagePrice(lineItems) {
let lineItemsToPrice = lineItems.filter((lineItem) => {
return (

View file

@ -2105,6 +2105,7 @@ export const actions = {
context.commit(storeMutations.UPDATE_VAPS, vaps);
},
savePromos(context, promos) {
addGuidToLineItemsIfNotAlreadyThere(promos);
context.commit(storeMutations.UPDATE_PROMOS, promos);
},
saveInactivePromos(context, inactivePromos) {
@ -2751,7 +2752,7 @@ function renameGlassToReplaceAttributes(glassToReplace) {
}
function addGuidToLineItemsIfNotAlreadyThere(lineItems) {
lineItems.forEach((lineItem) => {
lineItems?.forEach((lineItem) => {
if (!lineItem.id) {
lineItem.id = crypto.randomUUID();
}