Merge branch 'develop' into feature/SSR-1118

This commit is contained in:
Katie Kroell 2024-03-14 14:10:15 -04:00
commit 939441e287
9 changed files with 130 additions and 19 deletions

View file

@ -16,6 +16,7 @@
<div <div
id="cart-table" id="cart-table"
class="cart-table"> class="cart-table">
<!-- Deductible Line Item -->
<div <div
id="cart-deductible-or-base-price" id="cart-deductible-or-base-price"
class="mt-4 cart-line-item color-gray-100 px-5 py-1"> class="mt-4 cart-line-item color-gray-100 px-5 py-1">
@ -38,12 +39,34 @@
<span id="base-price-value">{{ getDisplayed(baseServicePrice) }}</span> <span id="base-price-value">{{ getDisplayed(baseServicePrice) }}</span>
</div> </div>
</div> </div>
<!-- Packaged Cart Items -->
<!-- Nonpackaged Cart Items -->
<!-- This will be a loop when this is implemented -->
<div class="non-packaged-cart-item">
<textLink
linkType="text"
text="Recycling"
href="javascript:void(0)"
@clickEvent="openModal(recyclingModalCmsWidgetName)" />
</div>
<!-- Sub total, sales tax, total columns -->
</div> </div>
<contentGroupModal
ref="RecycleModal"
cmsWidgetName="RecycleModal">
<textBlock cmsWidgetName="RecycleTextBlock" />
</contentGroupModal>
</div> </div>
</template> </template>
<script> <script>
import { useMainStore } from '@/store'; import { useMainStore } from '@/store';
import contentGroupModal from '@/iss-components/content-group-modal/content-group-modal.vue';
import textBlock from '@/digital-components/text-block/text-block.vue';
import textLink from '@/ux-components/text-link/text-link.vue';
import getPriceOfLineItems from '@/helpers/price-calculator.js'; import getPriceOfLineItems from '@/helpers/price-calculator.js';
import { formatAmountInDollars } from '@/helpers/text-helper.js'; import { formatAmountInDollars } from '@/helpers/text-helper.js';
@ -51,12 +74,15 @@ const VERIFYING_COVERAGE = 'Verifying coverage';
export default { export default {
name: 'cart-dropdown', name: 'cart-dropdown',
components: {}, components: { contentGroupModal,
textBlock,
textLink },
props: { props: {
showAsPaid: Boolean,
amountDueLabel: String, amountDueLabel: String,
basePriceLabel: String,
deductibleLabel: String, deductibleLabel: String,
basePriceLabel: String recyclingModalCmsWidgetName: String,
showAsPaid: Boolean
}, },
data() { data() {
const { currentDeductible } = useMainStore().order; const { currentDeductible } = useMainStore().order;
@ -97,6 +123,9 @@ export default {
} }
}, },
methods: { methods: {
openModal(modalName) {
this.$refs[modalName].openModal();
},
toggleIsExpanded() { toggleIsExpanded() {
this.isExpanded = !this.isExpanded; this.isExpanded = !this.isExpanded;
}, },
@ -131,6 +160,20 @@ export default {
visibility: hidden; visibility: hidden;
} }
:deep(.modal-content a.external-text) {
text-underline-offset: 0.25rem;
line-height: 2;
padding: 0 0 0.25rem 0;
font-weight: 500;
max-width: -webkit-fit-content;
max-width: -moz-fit-content;
max-width: fit-content;
}
:deep(#RecycleModal h5) {
text-align: center;
}
.cart-toggle { .cart-toggle {
&:after { &:after {
content: ""; content: "";

View file

@ -21,6 +21,7 @@
v-if="ModalSubBodyText" v-if="ModalSubBodyText"
class="my-4 caption modal-sub-body" class="my-4 caption modal-sub-body"
v-html="ModalSubBodyText"></p> v-html="ModalSubBodyText"></p>
<slot></slot>
</modal> </modal>
</template> </template>

View file

@ -23,7 +23,8 @@
:showAsPaid="false" :showAsPaid="false"
:amountDueLabel="amountDueText" :amountDueLabel="amountDueText"
:deductibleLabel="deductibleLabel" :deductibleLabel="deductibleLabel"
:basePriceLabel="basePriceLabel" /> :basePriceLabel="basePriceLabel"
recyclingModalCmsWidgetName="RecycleModal" />
<hr class="mt-0 mb-5" /> <hr class="mt-0 mb-5" />
<div>Pia Alert Placeholder</div> <div>Pia Alert Placeholder</div>
<paymentMethodQuestion <paymentMethodQuestion

View file

@ -468,4 +468,21 @@ describe('payment-page.vue', () => {
expect(creditCardErrorAlert.isVisible()).toBeTruthy(); expect(creditCardErrorAlert.isVisible()).toBeTruthy();
}); });
}); });
describe('AfterPay Error Alert', () => {
test('show after pay error alert', () => {
// Arrange
const queryString = {
[queryStrings.DISPLAY_PAY_IN_ADVANCE_ALERT]: paymentMethods.AFTERPAY
};
const wrapper = setupMocks({ queryString });
// Act
// Assert
const afterPayErrorAlert = wrapper.find('[name="payInAdvanceAfterPayErrorAlert"]');
expect(afterPayErrorAlert.exists()).toBeTruthy();
expect(afterPayErrorAlert.isVisible()).toBeTruthy();
});
});
}); });

View file

@ -10,8 +10,16 @@
class="my-4" class="my-4"
cmsWidgetName="PayInAdvanceCreditCardErrorAlertWidget" cmsWidgetName="PayInAdvanceCreditCardErrorAlertWidget"
alertClass="alert-danger" alertClass="alert-danger"
@textLinkClicked="paymentFailedPayLater" :isDismissible="false"
:isDismissible="false" /> @textLinkClicked="paymentFailedPayLater" />
<alert
v-if="displayPayInAdvanceAfterPayAlert"
name="payInAdvanceAfterPayErrorAlert"
class="my-4"
cmsWidgetName="PayInAdvanceAfterpayErrorAlertWidget"
alertClass="alert-danger"
:isDismissible="false"
@textLinkClicked="paymentFailedPayLater" />
<div id="card-container"> <div id="card-container">
<iframe <iframe
@ -537,6 +545,9 @@ export default {
}, },
displayPayInAdvanceCreditCardAlert() { displayPayInAdvanceCreditCardAlert() {
return this.displayPayInAdvanceAlert(paymentMethods.CREDIT_CARD); return this.displayPayInAdvanceAlert(paymentMethods.CREDIT_CARD);
},
displayPayInAdvanceAfterPayAlert() {
return this.displayPayInAdvanceAlert(paymentMethods.AFTERPAY);
} }
}, },
methods: methods:
@ -562,7 +573,8 @@ export default {
&& providerLocation.zipCode && providerLocation.zipCode
); );
const isMobile = serviceLocation.appointmentType === AppointmentTypeStrings.MOBILE; const isMobile = serviceLocation.appointmentType === AppointmentTypeStrings.MOBILE
|| serviceLocation.appointmentType === AppointmentTypeStrings.MOBILE_NOT_ITAC_AND_NOT_NOCOMP;
const serviceLocationReqs = const serviceLocationReqs =
(isMobile && mobileReqs) || (!isMobile && dropOffInshopReqs); (isMobile && mobileReqs) || (!isMobile && dropOffInshopReqs);

View file

@ -77,7 +77,8 @@
v-model="selectedProvider" v-model="selectedProvider"
:selectedAppointmentType="selectedAppointmentType" :selectedAppointmentType="selectedAppointmentType"
:isDisplayed="isShopQuestionDisplayed" :isDisplayed="isShopQuestionDisplayed"
cmsWidgetName="ShopQuestionWidget" /> cmsWidgetName="ShopQuestionWidget"
@updatedMobileProviderNumber="setMobileProviderNumber" />
<contentGroupModal <contentGroupModal
ref="RecalModal" ref="RecalModal"
cmsWidgetName="RecalModal" /> cmsWidgetName="RecalModal" />
@ -183,7 +184,12 @@ export default {
const resultMap = await settleAllPromises(promiseResultMap); const resultMap = await settleAllPromises(promiseResultMap);
next((vm) => { next((vm) => {
vm.setCmsContent(resultMap.cmsContent); vm.setCmsContent(resultMap.cmsContent);
vm.setData(resultMap.zipCodeData, resultMap.serviceabilityDetails, resultMap.mobileFeePart); vm.setData(
resultMap.zipCodeData,
resultMap.serviceabilityDetails,
resultMap.mobileFeePart,
resultMap.shopQuestionInitialData?.mobileProviderNumber
);
vm.$refs.shopQuestion.initializeComponent(resultMap.shopQuestionInitialData); vm.$refs.shopQuestion.initializeComponent(resultMap.shopQuestionInitialData);
}); });
}, },
@ -206,6 +212,7 @@ export default {
selectedAppointmentType: this.getSelectedAppointmentType(), selectedAppointmentType: this.getSelectedAppointmentType(),
selectedProvider: this.getSelectedProvider(), selectedProvider: this.getSelectedProvider(),
mobileFeePart: null, mobileFeePart: null,
mobileProviderNumber: null,
zipContainsMilitaryBase: false, zipContainsMilitaryBase: false,
zipCodeCtu: null zipCodeCtu: null
}; };
@ -333,6 +340,19 @@ export default {
await this.$refs.shopQuestion.reloadShopData(zipCode); await this.$refs.shopQuestion.reloadShopData(zipCode);
}, },
async forwardButtonAction() { async forwardButtonAction() {
const providerToUse = this.isMobileLocationDisplayed
? {
providerNumber: this.mobileProviderNumber,
address: {
streetAddress: null,
city: null,
state: null,
zipCode: null,
zipCodeCtu: null
}
}
: this.selectedProvider;
useMainStore().saveServiceLocation({ useMainStore().saveServiceLocation({
address: this.streetAddress, address: this.streetAddress,
address2: this.streetAddress2, address2: this.streetAddress2,
@ -343,13 +363,13 @@ export default {
appointmentType: this.selectedAppointmentType, appointmentType: this.selectedAppointmentType,
isVehicleProtected: this.isVehicleProtected, isVehicleProtected: this.isVehicleProtected,
provider: { provider: {
providerNumber: this.selectedProvider?.providerNumber, providerNumber: providerToUse?.providerNumber,
address: { address: {
streetAddress: this.selectedProvider?.address?.streetAddress, streetAddress: providerToUse?.address?.streetAddress,
city: this.selectedProvider?.address?.city, city: providerToUse?.address?.city,
state: this.selectedProvider?.address?.state, state: providerToUse?.address?.state,
zipCode: this.selectedProvider?.address?.zipCode, zipCode: providerToUse?.address?.zipCode,
zipCodeCtu: this.selectedProvider?.address?.zipCodeCtu zipCodeCtu: providerToUse?.address?.zipCodeCtu
} }
} }
}); });
@ -386,7 +406,7 @@ export default {
getSelectedProvider() { getSelectedProvider() {
return useMainStore().order.serviceLocation.provider; return useMainStore().order.serviceLocation.provider;
}, },
setData(zipCodeData, serviceabilityDetails, mobileFeePart) { setData(zipCodeData, serviceabilityDetails, mobileFeePart, mobileProviderNumber) {
if (zipCodeData) { if (zipCodeData) {
this.zipContainsMilitaryBase = zipCodeData.containsMilitaryBase; this.zipContainsMilitaryBase = zipCodeData.containsMilitaryBase;
this.zipCodeCtu = zipCodeData.zipCodeCtu; this.zipCodeCtu = zipCodeData.zipCodeCtu;
@ -399,6 +419,10 @@ export default {
if (mobileFeePart) { if (mobileFeePart) {
this.mobileFeePart = mobileFeePart; this.mobileFeePart = mobileFeePart;
} }
if (mobileProviderNumber) {
this.setMobileProviderNumber(mobileProviderNumber);
}
}, },
setContainsMilitaryBase(val) { setContainsMilitaryBase(val) {
if (this.zipContainsMilitaryBase !== val) { if (this.zipContainsMilitaryBase !== val) {
@ -408,6 +432,9 @@ export default {
setMobileFeePart(mobileFeePart) { setMobileFeePart(mobileFeePart) {
this.mobileFeePart = mobileFeePart; this.mobileFeePart = mobileFeePart;
}, },
setMobileProviderNumber(providerNumber) {
this.mobileProviderNumber = providerNumber;
},
resetMobileLocation() { resetMobileLocation() {
this.streetAddress = ''; this.streetAddress = '';
this.streetAddress2 = ''; this.streetAddress2 = '';

View file

@ -78,7 +78,7 @@ export default {
validationRules: String, validationRules: String,
isDisplayed: Boolean isDisplayed: Boolean
}, },
emits: ['update:modelValue'], emits: ['update:modelValue', 'updatedMobileProviderNumber'],
data() { data() {
return { return {
shopProviders: [], shopProviders: [],
@ -237,6 +237,12 @@ export default {
const result = await this.loadData(serviceZipCode); const result = await this.loadData(serviceZipCode);
this.initializeComponent(result.data); this.initializeComponent(result.data);
if (result.data?.mobileProviderNumber
&& (this.selectedAppointmentType === AppointmentTypeStrings.MOBILE
|| this.selectedAppointmentType === AppointmentTypeStrings.MOBILE_NOT_ITAC_AND_NOT_NOCOMP)) {
this.$emit('updatedMobileProviderNumber', result.data.mobileProviderNumber);
}
this.resetAnswers(); this.resetAnswers();
await nextTick(); await nextTick();

View file

@ -1869,7 +1869,8 @@ export const useMainStore = defineStore({
); );
let queryString = ''; let queryString = '';
if (appointmentType === 'Mobile') { if (appointmentType === AppointmentTypeStrings.MOBILE
|| appointmentType === AppointmentTypeStrings.MOBILE_NOT_ITAC_AND_NOT_NOCOMP) {
queryString = queryString =
`ParentAccountNumber=${applicationConfig.CASH_PARENT_ACCOUNT_NUMBER}` `ParentAccountNumber=${applicationConfig.CASH_PARENT_ACCOUNT_NUMBER}`
+ `&BillToAccountNumber=${billToAccountNumber}` + `&BillToAccountNumber=${billToAccountNumber}`

View file

@ -64,7 +64,6 @@ body {
left: 50%; left: 50%;
transform: translateX(-50%); transform: translateX(-50%);
max-width: 576px; max-width: 576px;
height: calc(100% - 72px);
&.show { &.show {
opacity: 0.4; opacity: 0.4;
@ -79,6 +78,10 @@ body {
// Prevent scroll when modal is open // Prevent scroll when modal is open
&.modal-open { &.modal-open {
div.page-container-grouped-styles {
overflow: hidden;
}
.fade-on-route-transition { .fade-on-route-transition {
overflow: hidden; overflow: hidden;
} }