CSR-1393
This commit is contained in:
parent
84c7e8c617
commit
d041721858
5 changed files with 121 additions and 66 deletions
|
|
@ -239,15 +239,15 @@ export default {
|
||||||
let cartItem = null;
|
let cartItem = null;
|
||||||
|
|
||||||
cartItem = {
|
cartItem = {
|
||||||
name: promoLineItem?.[0]?.promoCode, // get from CMS?
|
name: promoLineItem?.promoCode, // get from CMS?
|
||||||
category: cartItemCategories.PROMOS,
|
category: cartItemCategories.PROMOS,
|
||||||
cartItemType: promoLineItem?.[0]?.partType,
|
cartItemType: promoLineItem?.partType,
|
||||||
isDisplayed: true,
|
isDisplayed: true,
|
||||||
subTotal:
|
subTotal:
|
||||||
(promoLineItem?.[0]?.kitPrice ?? 0) +
|
(promoLineItem?.kitPrice ?? 0) +
|
||||||
(promoLineItem?.[0]?.laborAmount ?? 0) +
|
(promoLineItem?.laborAmount ?? 0) +
|
||||||
(promoLineItem?.[0]?.sellingPrice ?? 0),
|
(promoLineItem?.sellingPrice ?? 0),
|
||||||
salesTax: promoLineItem?.[0]?.salesTax,
|
salesTax: promoLineItem?.salesTax,
|
||||||
};
|
};
|
||||||
|
|
||||||
cartItems.push(cartItem);
|
cartItems.push(cartItem);
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@
|
||||||
|
|
||||||
<hr class="my-5" />
|
<hr class="my-5" />
|
||||||
<promoModalQuestion
|
<promoModalQuestion
|
||||||
|
class="pb-3"
|
||||||
v-model="lineItems"
|
v-model="lineItems"
|
||||||
:availableLineItems="availableLineItems"
|
:availableLineItems="availableLineItems"
|
||||||
@added-to-cart="showAlert"
|
@added-to-cart="showAlert"
|
||||||
|
|
|
||||||
|
|
@ -16,23 +16,23 @@
|
||||||
customInputId="promoCode"
|
customInputId="promoCode"
|
||||||
v-model="promoCode"
|
v-model="promoCode"
|
||||||
cmsWidgetName="PromoQuestionWidget" />
|
cmsWidgetName="PromoQuestionWidget" />
|
||||||
<div v-for="(promo, i) in this.getPromoList" :key="i">
|
<alert
|
||||||
<span class="applied-promo">Promo code "{{ promo[i].promoCode }}" applied </span>
|
ref="alertInvalidPromo"
|
||||||
|
v-if="displayInvalidPromoAlert"
|
||||||
|
v-html="InvalidPromoText"
|
||||||
|
class="my-4 alert"
|
||||||
|
cmsWidgetName="AlertInvalidPromoWidget"
|
||||||
|
alertClass="alert-danger"
|
||||||
|
v-bind:isDismissible="true" />
|
||||||
|
<div v-for="(promo, i) in this.getPromoList()" :key="i">
|
||||||
|
<span class="applied-promo">Promo code "{{ promo.promoCode }}" applied </span>
|
||||||
<textLink
|
<textLink
|
||||||
ref="removeLink"
|
ref="removeLink"
|
||||||
linkType="text"
|
linkType="text"
|
||||||
:text="removeLinkText"
|
:text="removeLinkText"
|
||||||
href="#!"
|
href="#!"
|
||||||
@click-event="removeItem()" />
|
@click-event="removeItem(promo.promoCode)" />
|
||||||
</div>
|
</div>
|
||||||
<alert
|
|
||||||
ref="alertInvalidPromo"
|
|
||||||
v-if="displayInvalidPromoAlert"
|
|
||||||
v-html="InvalidPromoText"
|
|
||||||
class="my-4"
|
|
||||||
cmsWidgetName="AlertInvalidPromoWidget"
|
|
||||||
alertClass="alert-danger"
|
|
||||||
v-bind:isDismissible="true" />
|
|
||||||
</modal>
|
</modal>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
@ -41,13 +41,13 @@ import textLink from "@/ux-components/text-link/text-link";
|
||||||
import promoQuestion from "@/layouts/payment-method/promo-modal-question/promo-question/promo-question";
|
import promoQuestion from "@/layouts/payment-method/promo-modal-question/promo-question/promo-question";
|
||||||
import modal from "@/digital-components/modal/modal";
|
import modal from "@/digital-components/modal/modal";
|
||||||
import alert from "@/ux-components/alert/alert";
|
import alert from "@/ux-components/alert/alert";
|
||||||
import { deepClone } from "@/helpers/object-helper";
|
|
||||||
import { storeActions } from "@/constants/store-actions.js";
|
import { storeActions } from "@/constants/store-actions.js";
|
||||||
import {
|
import {
|
||||||
getVapsThatNeedToBeAddedToSatisfyPromos,
|
getVapsThatNeedToBeAddedToSatisfyPromos,
|
||||||
getAddableVapsFromAvailableLineItems,
|
getAddableVapsFromAvailableLineItems,
|
||||||
} from "@/helpers/promotions-helper";
|
} from "@/helpers/promotions-helper";
|
||||||
import baseMixin from "@/mixins/base-mixin.js";
|
import baseMixin from "@/mixins/base-mixin.js";
|
||||||
|
import { cartItemCategories } from "@/constants/cart-item-categories";
|
||||||
export default {
|
export default {
|
||||||
name: "promo-modal-question",
|
name: "promo-modal-question",
|
||||||
|
|
||||||
|
|
@ -55,7 +55,8 @@ export default {
|
||||||
return {
|
return {
|
||||||
promoCode: "",
|
promoCode: "",
|
||||||
promoTextInputId: "",
|
promoTextInputId: "",
|
||||||
displayInvalidPromoAlert: false,
|
displayInvalidPromoAlert: false,
|
||||||
|
displayInvalidOnOrderPromoAlert: false,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
|
|
@ -81,6 +82,15 @@ export default {
|
||||||
modal() {
|
modal() {
|
||||||
return this.$refs[this.modalName];
|
return this.$refs[this.modalName];
|
||||||
},
|
},
|
||||||
|
PromoOnOrderText() {
|
||||||
|
return this.getCmsContent("AlertInvalidPromoOnOrderWidget", "HeadlineText");
|
||||||
|
},
|
||||||
|
InvalidPromoOnOrderText() {
|
||||||
|
return this.PromoText?.replaceAll("{custom:NEWPROMOCODE}", this.promoCode).replaceAll(
|
||||||
|
"{custom:OLDPROMOCODE}",
|
||||||
|
this.promoCode
|
||||||
|
);
|
||||||
|
},
|
||||||
PromoText() {
|
PromoText() {
|
||||||
return this.getCmsContent("AlertInvalidPromoWidget", "HeadlineText");
|
return this.getCmsContent("AlertInvalidPromoWidget", "HeadlineText");
|
||||||
},
|
},
|
||||||
|
|
@ -93,9 +103,6 @@ export default {
|
||||||
removeLinkText() {
|
removeLinkText() {
|
||||||
return this.getCmsContent("RemoveCartItemTextWidget", "Text");
|
return this.getCmsContent("RemoveCartItemTextWidget", "Text");
|
||||||
},
|
},
|
||||||
getPromoList(){
|
|
||||||
return this.modelValue?.promos;
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
resetAlerts() {
|
resetAlerts() {
|
||||||
|
|
@ -104,6 +111,9 @@ export default {
|
||||||
resetsOnPromoInput() {
|
resetsOnPromoInput() {
|
||||||
this.resetAlerts();
|
this.resetAlerts();
|
||||||
},
|
},
|
||||||
|
getPromoList() {
|
||||||
|
return this.modelValue?.promos;
|
||||||
|
},
|
||||||
openModal() {
|
openModal() {
|
||||||
this.modal.openModal();
|
this.modal.openModal();
|
||||||
},
|
},
|
||||||
|
|
@ -118,12 +128,15 @@ export default {
|
||||||
this.modal.resetButtonStyle();
|
this.modal.resetButtonStyle();
|
||||||
},
|
},
|
||||||
getPromoAddedMessage() {
|
getPromoAddedMessage() {
|
||||||
return this.AddPromoSuccessMessageFromCms?.replaceAll("{custom:PROMOCODE}", this.promoCode);
|
return this.AddPromoSuccessMessageFromCms?.replaceAll(
|
||||||
|
"{custom:PROMOCODE}",
|
||||||
|
this.promoCode
|
||||||
|
);
|
||||||
},
|
},
|
||||||
async getPromoCodeData(promoCode, lineItems, availableLineItems, pageNameToLog = null) {
|
async getPromoCodeData(promoCode, lineItems, availableLineItems, pageNameToLog = null) {
|
||||||
const pageName = pageNameToLog ?? this.$options?.name;
|
const pageName = pageNameToLog ?? this.$options?.name;
|
||||||
const addableVaps = getAddableVapsFromAvailableLineItems(availableLineItems);
|
const addableVaps = getAddableVapsFromAvailableLineItems(availableLineItems);
|
||||||
const lineItemsToUse = lineItems.Length > 0?lineItems:null;
|
const lineItemsToUse = lineItems.Length > 0 ? lineItems : null;
|
||||||
const promoValidationResponse = await baseMixin.methods.dispatchStoreActionWithLogging(
|
const promoValidationResponse = await baseMixin.methods.dispatchStoreActionWithLogging(
|
||||||
storeActions.VALIDATE_ORDER_PROMO_AND_SAVE_SERVER_DATA,
|
storeActions.VALIDATE_ORDER_PROMO_AND_SAVE_SERVER_DATA,
|
||||||
{
|
{
|
||||||
|
|
@ -131,7 +144,8 @@ export default {
|
||||||
lineItemsToUse: lineItemsToUse,
|
lineItemsToUse: lineItemsToUse,
|
||||||
addableVaps: addableVaps,
|
addableVaps: addableVaps,
|
||||||
},
|
},
|
||||||
pageName,false
|
pageName,
|
||||||
|
false
|
||||||
);
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
@ -140,9 +154,17 @@ export default {
|
||||||
errorCode: promoValidationResponse?.errorCode,
|
errorCode: promoValidationResponse?.errorCode,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
removeItem(promo) {
|
||||||
|
let lineItems = this.modelValue;
|
||||||
|
lineItems[cartItemCategories.PROMOS] = lineItems[cartItemCategories.PROMOS].filter(
|
||||||
|
(lineItemsToKeep) => lineItemsToKeep.promoCode != promo
|
||||||
|
);
|
||||||
|
|
||||||
|
this.$emit("update:modelValue", lineItems);
|
||||||
|
},
|
||||||
async addPromoCode() {
|
async addPromoCode() {
|
||||||
if (this.promoCode) {
|
if (this.promoCode) {
|
||||||
this.resetAlerts();
|
this.resetAlerts();
|
||||||
|
|
||||||
const promoCodeData = await this.getPromoCodeData(
|
const promoCodeData = await this.getPromoCodeData(
|
||||||
this.promoCode,
|
this.promoCode,
|
||||||
|
|
@ -152,30 +174,37 @@ export default {
|
||||||
);
|
);
|
||||||
|
|
||||||
if (promoCodeData.isValid) {
|
if (promoCodeData.isValid) {
|
||||||
let promos = [];
|
|
||||||
promos.push(promoCodeData.promoCode);
|
|
||||||
const modelValue = this.modelValue;
|
const modelValue = this.modelValue;
|
||||||
modelValue.promos = promos;
|
const addedPromo = modelValue?.promos.find(
|
||||||
this.closeModal();
|
(promoItem) =>
|
||||||
const getVaps = getVapsThatNeedToBeAddedToSatisfyPromos(
|
promoItem?.promoCode == promoCodeData.promoCode?.[0]?.promoCode
|
||||||
promoCodeData.promoCode,
|
|
||||||
this.availableLineItems,
|
|
||||||
modelValue
|
|
||||||
);
|
);
|
||||||
modelValue.vaps?.push(...getVaps);
|
if (addedPromo) {
|
||||||
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.displayInvalidPromoAlert = true;
|
||||||
this.focusOnPromoInput();
|
this.focusOnPromoInput();
|
||||||
this.resetModalButtonStyle();
|
this.resetModalButtonStyle();
|
||||||
|
} else {
|
||||||
|
modelValue?.promos.push(...promoCodeData.promoCode);
|
||||||
|
const getVaps = getVapsThatNeedToBeAddedToSatisfyPromos(
|
||||||
|
promoCodeData.promoCode,
|
||||||
|
this.availableLineItems,
|
||||||
|
modelValue
|
||||||
|
);
|
||||||
|
modelValue.vaps?.push(...getVaps);
|
||||||
|
this.closeModal();
|
||||||
|
const message = this.getPromoAddedMessage();
|
||||||
|
this.$emit("added-to-cart", {
|
||||||
|
messageHeadline: "Promo Applied!",
|
||||||
|
messageCopy: message,
|
||||||
|
type: "alert-success",
|
||||||
|
isDismissible: true,
|
||||||
|
});
|
||||||
|
this.promoCode = "";
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
this.displayInvalidPromoAlert = true;
|
||||||
|
this.focusOnPromoInput();
|
||||||
|
this.resetModalButtonStyle();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -196,12 +225,16 @@ export default {
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.applied-promo {
|
.applied-promo {
|
||||||
padding-right: 7rem;
|
padding-right: 5rem;
|
||||||
font-family: Roboto;
|
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
font-style: normal;
|
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
line-height: 24px;
|
line-height: 24px;
|
||||||
color: #0c7e47;
|
color: #0c7e47;
|
||||||
}
|
}
|
||||||
|
.alert {
|
||||||
|
color: #d4281c;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 500;
|
||||||
|
line-height: 24px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,40 @@
|
||||||
|
import { shallowMount } from "@vue/test-utils";
|
||||||
|
import promoQuestion from "./promo-question";
|
||||||
|
|
||||||
|
describe("promo-question.vue", () => {
|
||||||
|
it("Should get the modelValue", async () => {
|
||||||
|
// Arrange
|
||||||
|
const text = "test";
|
||||||
|
const wrapper = shallowMount(promoQuestion, {
|
||||||
|
props: {
|
||||||
|
modelValue: text,
|
||||||
|
},
|
||||||
|
attachTo: document.body,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Act
|
||||||
|
const modelValueText = wrapper.vm.value;
|
||||||
|
wrapper.vm.value = "test also";
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(modelValueText).toEqual("test");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Should emit to set value", async () => {
|
||||||
|
// Arrange
|
||||||
|
const text = "test";
|
||||||
|
const wrapper = shallowMount(promoQuestion, {
|
||||||
|
props: {
|
||||||
|
modelValue: text,
|
||||||
|
},
|
||||||
|
attachTo: document.body,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Act
|
||||||
|
const modelValueText = wrapper.vm.value;
|
||||||
|
wrapper.vm.value = "test also";
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(wrapper.emitted("update:modelValue")).toEqual([["test also"]]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -81,25 +81,6 @@ export default {
|
||||||
zipCodeCtu: serviceZipValidationResponse.data.zipCodeCtu,
|
zipCodeCtu: serviceZipValidationResponse.data.zipCodeCtu,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
// async getPromoCodeData(promoCode, lineItems, availableLineItems, pageNameToLog = null) {
|
|
||||||
// const pageName = pageNameToLog ?? this.$options?.name;
|
|
||||||
// const addableVaps = getAddableVapsFromAvailableLineItems(availableLineItems);
|
|
||||||
// const promoValidationResponse = await this.dispatchStoreActionWithLogging(
|
|
||||||
// storeActions.VALIDATE_ORDER_PROMO_AND_SAVE_SERVER_DATA,
|
|
||||||
// {
|
|
||||||
// promoCode: promoCode,
|
|
||||||
// lineItemsToUse: lineItems,
|
|
||||||
// addableVaps: addableVaps,
|
|
||||||
// },
|
|
||||||
// pageName
|
|
||||||
// );
|
|
||||||
|
|
||||||
// return {
|
|
||||||
// isValid: !("errorCode" in promoValidationResponse),
|
|
||||||
// promoCode: promoValidationResponse?.orderPromos,
|
|
||||||
// errorCode: promoValidationResponse?.errorCode,
|
|
||||||
// };
|
|
||||||
// },
|
|
||||||
getTierOnePackagePrice(lineItems) {
|
getTierOnePackagePrice(lineItems) {
|
||||||
let lineItemsToPrice = lineItems.filter((lineItem) => {
|
let lineItemsToPrice = lineItems.filter((lineItem) => {
|
||||||
return (
|
return (
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue