Skip to content

Commit

Permalink
fix: guest with shipping as billing (#775)
Browse files Browse the repository at this point in the history
* fix: guest with shipping as billing

* fix: guest with shipping as billing

* fix: guest with shipping as billing

* fix: guest with shipping as billing

* fix: guest with shipping as billing

* fix: guest with shipping as billing

* fix: guest with shipping as billing

* test: add e2e test for guest address change

* chore: remove test .only

* chore: fix lint

---------

Co-authored-by: Maximilian Röll <30629157+maxiroellplenty@users.noreply.github.com>
  • Loading branch information
csandru-plenty and maxiroellplenty authored Nov 7, 2024
1 parent 987ae8e commit eb33b6c
Show file tree
Hide file tree
Showing 8 changed files with 67 additions and 21 deletions.
11 changes: 10 additions & 1 deletion apps/web/__tests__/support/pageObjects/CheckoutPageObject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ export class CheckoutPageObject extends PageObject {
return cy.getByTestId('save-address-2');
}

get saveBilling() {
return cy.getByTestId('save-address-1');
}

get contactInformationFormSaveButton() {
return cy.getByTestId('contact-information-save-button');
}
Expand All @@ -49,6 +53,11 @@ export class CheckoutPageObject extends PageObject {
return cy.getByTestId('checkout-edit-address-modal');
}

editBillingAddress() {
cy.getByTestId('edit-address-1').click();
return this;
}

get thankYouBanner() {
return cy.getByTestId('success-header');
}
Expand Down Expand Up @@ -190,7 +199,7 @@ export class CheckoutPageObject extends PageObject {

shouldShowShippingAsBillingText() {
this.shippingAsBillingText.contains('Same as shipping address');
return this;
return this;
}

fillCreditCardForm() {
Expand Down
18 changes: 18 additions & 0 deletions apps/web/__tests__/test/feature/checkout-addresses.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,22 @@ describe('Checkout Addresses', () => {
.fillShippingAddressForm()
.shouldShowShippingAsBillingText();
});

it('should be able to edit the billing address as a guest user if selected same as shipping', () => {
homePage.goToCategory();
productListPage.addToCart()

cart.openCart();
checkout
.goToCheckout()
.goToGuestCheckout()
.fillContactInformationForm()
.fillShippingAddressForm()
.shouldShowShippingAsBillingText()
.editBillingAddress();
checkout.firstNameInput.clear();
checkout.firstNameInput.type('John Guest Edit');
checkout.saveBilling.click({ force: true });
cy.get('#billing-address').should('contain', 'John Guest Edit');
});
});
7 changes: 6 additions & 1 deletion apps/web/components/AddressContainer/AddressContainer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,12 @@
class="ml-2"
:label="!editing && !showNewForm && !disabled ? t('editAddress') : ''"
>
<UiButton @click="edit(checkoutAddress)" :disabled="formIsLoading || disabled" variant="secondary">
<UiButton
@click="edit(checkoutAddress)"
:disabled="formIsLoading || disabled"
variant="secondary"
:data-testid="'edit-address-' + type"
>
<template v-if="!editing && !showNewForm">{{ t('contactInfo.edit') }}</template>
<SfIconClose v-else />
</UiButton>
Expand Down
10 changes: 2 additions & 8 deletions apps/web/components/AddressForm/AddressForm.vue
Original file line number Diff line number Diff line change
Expand Up @@ -112,15 +112,9 @@ const { type, savedAddress: propertySavedAddress, useAsShippingDefault = true }
const { loading: loadBilling } = useAddress(AddressType.Billing);
const { loading: loadShipping } = useAddress(AddressType.Shipping);
const {
useGeoRegulatedCountries,
default: defaultCountries,
geoRegulated: geoRegulatedCountries,
} = useAggregatedCountries();
const { billingCountries, default: defaultCountries } = useAggregatedCountries();
const countries = computed(() =>
type === AddressType.Billing && useGeoRegulatedCountries ? geoRegulatedCountries.value : defaultCountries.value,
);
const countries = computed(() => (type === AddressType.Billing ? billingCountries.value : defaultCountries.value));
const isCartUpdateLoading = computed(() => loadBilling.value || loadShipping.value);
const useAsShippingAddress = ref(useAsShippingDefault);
const savedAddress = propertySavedAddress || ({} as Address);
Expand Down
19 changes: 10 additions & 9 deletions apps/web/components/AddressFormBilling/AddressFormBilling.vue
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@
:invalid="Boolean(errors['country'])"
>
<option
v-for="(billingCountry, index) in countries"
v-for="(billingCountry, index) in billingCountries"
:key="`billing-country-${index}`"
:value="billingCountry.id.toString()"
>
Expand All @@ -139,17 +139,13 @@ import { type Address, AddressType, userAddressGetters } from '@plentymarkets/sh
const { address, addAddress = false } = defineProps<AddressFormProps>();
const { isGuest } = useCustomer();
const { shippingAsBilling } = useShippingAsBilling();
const { hasCompany, addressToSave, save: saveAddress, validationSchema } = useAddressForm(AddressType.Billing);
const { addresses: billingAddresses } = useAddressStore(AddressType.Billing);
const { set: setCheckoutAddress } = useCheckoutAddress(AddressType.Billing);
const { defineField, errors, setValues, validate, handleSubmit } = useForm({ validationSchema: validationSchema });
const {
useGeoRegulatedCountries,
default: defaultCountries,
geoRegulated: geoRegulatedCountries,
} = useAggregatedCountries();
const countries = computed(() => (useGeoRegulatedCountries ? geoRegulatedCountries.value : defaultCountries.value));
const { billingCountries } = useAggregatedCountries();
const [firstName, firstNameAttributes] = defineField('firstName');
const [lastName, lastNameAttributes] = defineField('lastName');
Expand All @@ -170,18 +166,23 @@ if (!addAddress) {
}
}
const guestHasShippingAsBilling = isGuest.value && shippingAsBilling.value;
const syncCheckoutAddress = async () => {
await setCheckoutAddress(
addAddress
addAddress || guestHasShippingAsBilling
? (billingAddresses.value[0] as Address)
: (userAddressGetters.getDefault(billingAddresses.value) as Address),
!addAddress,
);
if (guestHasShippingAsBilling) shippingAsBilling.value = false;
};
const submitForm = handleSubmit((billingAddressForm) => {
addressToSave.value = billingAddressForm as Address;
if (guestHasShippingAsBilling && !addAddress) delete addressToSave.value?.id;
if (addAddress) addressToSave.value.primary = true;
if (!hasCompany.value) {
addressToSave.value.companyName = '';
Expand Down
7 changes: 6 additions & 1 deletion apps/web/composables/useAggregatedCountries/types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import { type AggregatedCountries } from '@plentymarkets/shop-api';
import {
type ActiveShippingCountry,
type GeoRegulatedCountry,
type AggregatedCountries,
} from '@plentymarkets/shop-api';

export interface UseAggregatedCountriesState {
default: AggregatedCountries['default'];
Expand All @@ -14,6 +18,7 @@ export interface UseAggregatedCountries {
loading: Readonly<Ref<boolean>>;
fetchAggregatedCountries: FetchAggregatedCountries;
useGeoRegulatedCountries: boolean;
billingCountries: ComputedRef<(ActiveShippingCountry | GeoRegulatedCountry)[]>;
}

export type UseAggregatedCountriesReturn = () => UseAggregatedCountries;
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ import { type UseAggregatedCountriesReturn, UseAggregatedCountriesState, type Fe

/**
* @description Composable for getting `AggregatedCountries`:
* - Active shipping countries
* - Default shipping countries
* - EU geo-regulated countries
* - A combined list of countries
*
* @example
* ``` ts
Expand All @@ -14,6 +15,7 @@ import { type UseAggregatedCountriesReturn, UseAggregatedCountriesState, type Fe
* loading,
* fetchAggregatedCountries,
* useGeoRegulatedCountries,
* billingCountries,
* } = useAggregatedCountries();
* ```
*/
Expand Down Expand Up @@ -43,9 +45,20 @@ export const useAggregatedCountries: UseAggregatedCountriesReturn = () => {

const useGeoRegulatedCountries = state.value.geoRegulated.length > 0;

const billingCountries = computed(() => {
if (!useGeoRegulatedCountries) return state.value.default;

const uniqueCountries = new Map(
[...state.value.default, ...state.value.geoRegulated].map((country) => [country.id, country]),
);

return [...uniqueCountries.values()].sort((first, second) => first.id - second.id);
});

return {
fetchAggregatedCountries,
useGeoRegulatedCountries,
billingCountries,
...toRefs(state.value),
};
};
1 change: 1 addition & 0 deletions docs/changelog/changelog_en.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@

### 🩹 Fixed

- Addressed an unhandled scenario in which a guest user attempts to modify their billing address while using the same address for shipping.
- Fixed an issue where increasing the quantity beyond maximum stock would clear the cart.
- Removed the "Add to Cart" notification from item and category pages when the quick checkout modal is not present.
- Improved accessibility for the cart and wishlist pages by increasing the font size.
Expand Down

0 comments on commit eb33b6c

Please sign in to comment.