diff --git a/src/fmg-components/cart/cart.vue b/src/fmg-components/cart/cart.vue index be22a118c..22d40eb73 100644 --- a/src/fmg-components/cart/cart.vue +++ b/src/fmg-components/cart/cart.vue @@ -239,15 +239,15 @@ export default { let cartItem = null; cartItem = { - name: promoLineItem?.[0]?.promoCode, // get from CMS? + name: promoLineItem?.promoCode, // get from CMS? category: cartItemCategories.PROMOS, - cartItemType: promoLineItem?.[0]?.partType, + cartItemType: promoLineItem?.partType, isDisplayed: true, subTotal: - (promoLineItem?.[0]?.kitPrice ?? 0) + - (promoLineItem?.[0]?.laborAmount ?? 0) + - (promoLineItem?.[0]?.sellingPrice ?? 0), - salesTax: promoLineItem?.[0]?.salesTax, + (promoLineItem?.kitPrice ?? 0) + + (promoLineItem?.laborAmount ?? 0) + + (promoLineItem?.sellingPrice ?? 0), + salesTax: promoLineItem?.salesTax, }; cartItems.push(cartItem); diff --git a/src/layouts/payment-method/payment-method.vue b/src/layouts/payment-method/payment-method.vue index c691c6765..03d3a9e8d 100644 --- a/src/layouts/payment-method/payment-method.vue +++ b/src/layouts/payment-method/payment-method.vue @@ -32,6 +32,7 @@
-
- Promo code "{{ promo[i].promoCode }}" applied + +
+ Promo code "{{ promo.promoCode }}" applied + @click-event="removeItem(promo.promoCode)" />
-
@@ -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 modal from "@/digital-components/modal/modal"; import alert from "@/ux-components/alert/alert"; -import { deepClone } from "@/helpers/object-helper"; import { storeActions } from "@/constants/store-actions.js"; import { getVapsThatNeedToBeAddedToSatisfyPromos, getAddableVapsFromAvailableLineItems, } from "@/helpers/promotions-helper"; import baseMixin from "@/mixins/base-mixin.js"; +import { cartItemCategories } from "@/constants/cart-item-categories"; export default { name: "promo-modal-question", @@ -55,7 +55,8 @@ export default { return { promoCode: "", promoTextInputId: "", - displayInvalidPromoAlert: false, + displayInvalidPromoAlert: false, + displayInvalidOnOrderPromoAlert: false, }; }, props: { @@ -81,6 +82,15 @@ export default { modal() { 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() { return this.getCmsContent("AlertInvalidPromoWidget", "HeadlineText"); }, @@ -93,9 +103,6 @@ export default { removeLinkText() { return this.getCmsContent("RemoveCartItemTextWidget", "Text"); }, - getPromoList(){ - return this.modelValue?.promos; - } }, methods: { resetAlerts() { @@ -104,6 +111,9 @@ export default { resetsOnPromoInput() { this.resetAlerts(); }, + getPromoList() { + return this.modelValue?.promos; + }, openModal() { this.modal.openModal(); }, @@ -118,12 +128,15 @@ export default { this.modal.resetButtonStyle(); }, getPromoAddedMessage() { - return this.AddPromoSuccessMessageFromCms?.replaceAll("{custom:PROMOCODE}", this.promoCode); + return this.AddPromoSuccessMessageFromCms?.replaceAll( + "{custom:PROMOCODE}", + this.promoCode + ); }, async getPromoCodeData(promoCode, lineItems, availableLineItems, pageNameToLog = null) { const pageName = pageNameToLog ?? this.$options?.name; const addableVaps = getAddableVapsFromAvailableLineItems(availableLineItems); - const lineItemsToUse = lineItems.Length > 0?lineItems:null; + const lineItemsToUse = lineItems.Length > 0 ? lineItems : null; const promoValidationResponse = await baseMixin.methods.dispatchStoreActionWithLogging( storeActions.VALIDATE_ORDER_PROMO_AND_SAVE_SERVER_DATA, { @@ -131,7 +144,8 @@ export default { lineItemsToUse: lineItemsToUse, addableVaps: addableVaps, }, - pageName,false + pageName, + false ); return { @@ -140,9 +154,17 @@ export default { 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() { if (this.promoCode) { - this.resetAlerts(); + this.resetAlerts(); const promoCodeData = await this.getPromoCodeData( this.promoCode, @@ -152,30 +174,37 @@ export default { ); if (promoCodeData.isValid) { - let promos = []; - promos.push(promoCodeData.promoCode); const modelValue = this.modelValue; - modelValue.promos = promos; - this.closeModal(); - const getVaps = getVapsThatNeedToBeAddedToSatisfyPromos( - promoCodeData.promoCode, - this.availableLineItems, - modelValue + const addedPromo = modelValue?.promos.find( + (promoItem) => + promoItem?.promoCode == promoCodeData.promoCode?.[0]?.promoCode ); - modelValue.vaps?.push(...getVaps); - const message = this.getPromoAddedMessage(); - this.$emit("added-to-cart", { - messageHeadline: "Promo Applied!", - messageCopy: message, - type: "alert-success", - isDismissible: true, - }); - } else { - if (promoCodeData.errorCode === "PromoDoesNotExist") { + if (addedPromo) { this.displayInvalidPromoAlert = true; this.focusOnPromoInput(); 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 { diff --git a/src/layouts/payment-method/promo-modal-question/promo-question/promo-question.spec.js b/src/layouts/payment-method/promo-modal-question/promo-question/promo-question.spec.js new file mode 100644 index 000000000..97a4346ad --- /dev/null +++ b/src/layouts/payment-method/promo-modal-question/promo-question/promo-question.spec.js @@ -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"]]); + }); +}); diff --git a/src/mixins/base-mixin.js b/src/mixins/base-mixin.js index 6175c121c..1a941c94d 100644 --- a/src/mixins/base-mixin.js +++ b/src/mixins/base-mixin.js @@ -81,25 +81,6 @@ export default { 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) { let lineItemsToPrice = lineItems.filter((lineItem) => { return (