Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions packages/template-retail-react-app/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
- Enhanced the shopping assistant that integrates Salesforce Embedded Messaging Service with PWA Kit applications, adding comprehensive context support, localization capabilities, and improved user experience features. [#3259](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/3259)
- Removed domainUrl, locale, basetId properties as part off the ShopperAgent during initialization. [#3259](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/3259)
- Only show option to deliver to multiple addresses if there are multiple items in the basket. [#3336](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/3336)
- When registering a guest user on the confirmation page only save the delivery addresses to the new account
[#3412](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/3412)
- Added support for Choice of Bonus Products feature. Users can now select from available bonus products when they qualify for the associated promotion. The bonus product selection flow can be entered from either the "Item Added to Cart" modal (when adding the qualifying product to the cart) or from the cart page. [#3292] (https://github.com/SalesforceCommerceCloud/pwa-kit/pull/3292)
- Add @h4ad/serverless-adapter to jest config [#3325](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/3325)
- Fix bug where pick up items were displaying delivery stock levels instead of in store stock levels [#3401](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/3401)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ import {
useShopperCustomersMutation
} from '@salesforce/commerce-sdk-react'
import {getCreditCardIcon} from '@salesforce/retail-react-app/app/utils/cc-utils'
import {getConfig} from '@salesforce/pwa-kit-runtime/utils/ssr-config'
import {isPickupShipment} from '@salesforce/retail-react-app/app/utils/shipment-utils'
import {areAddressesEqual} from '@salesforce/retail-react-app/app/utils/address-utils'

// Components
import Link from '@salesforce/retail-react-app/app/components/link'
Expand All @@ -51,7 +54,10 @@ import {useCurrentCustomer} from '@salesforce/retail-react-app/app/hooks/use-cur
import {useCurrency} from '@salesforce/retail-react-app/app/hooks'

// Constants
import {API_ERROR_MESSAGE} from '@salesforce/retail-react-app/app/constants'
import {
API_ERROR_MESSAGE,
STORE_LOCATOR_IS_ENABLED
} from '@salesforce/retail-react-app/app/constants'

const onClient = typeof window !== 'undefined'

Expand Down Expand Up @@ -96,19 +102,42 @@ const CheckoutConfirmation = () => {
const CardIcon = getCreditCardIcon(order.paymentInstruments[0].paymentCard?.cardType)

const submitForm = async (data) => {
// Save the unique delivery addresses, excluding pickup shipments
const saveShippingAddress = async (customerId) => {
try {
const shippingAddress = order.shipments[0].shippingAddress
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const {id, ...shippingAddressWithoutId} = shippingAddress
const bodyShippingAddress = {
addressId: nanoid(),
...shippingAddressWithoutId
}
await createCustomerAddress.mutateAsync({
body: bodyShippingAddress,
parameters: {customerId: customerId}
const storeLocatorEnabled =
getConfig()?.app?.storeLocatorEnabled ?? STORE_LOCATOR_IS_ENABLED

const deliveryShipments = (order.shipments || []).filter((shipment) => {
if (!shipment.shippingAddress) return false
if (storeLocatorEnabled && isPickupShipment(shipment)) return false
return true
})

const uniqueAddresses = []
deliveryShipments.forEach((shipment) => {
const address = shipment.shippingAddress
const isDuplicate = uniqueAddresses.some((existingAddr) =>
areAddressesEqual(existingAddr, address)
)
if (!isDuplicate) {
uniqueAddresses.push(address)
}
})

for (let i = 0; i < uniqueAddresses.length; i++) {
const shippingAddress = uniqueAddresses[i]
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const {id, _type, ...shippingAddressWithoutId} = shippingAddress
const bodyShippingAddress = {
addressId: nanoid(),
...shippingAddressWithoutId
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: ...omit(shippingAddress, ['id', '_type'])

}
await createCustomerAddress.mutateAsync({
body: bodyShippingAddress,
parameters: {customerId: customerId}
})
}
} catch (error) {
// Fail silently
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -290,4 +290,87 @@ describe('Account form', () => {
expect(window.location.pathname).toBe('/uk/en-GB/account')
})
})

test('save delivery addresses but does not save pickup addresses when store locator is enabled', async () => {
const savedAddresses = []
const mockOrderWithPickup = {
...mockOrder,
shipments: [
{
...mockOrder.shipments[0],
shipmentId: 'delivery-shipment',
shippingAddress: {
address1: '456 Delivery St',
city: 'Vancouver',
countryCode: 'CA',
firstName: 'John',
lastName: 'Doe',
phone: '(604) 555-1234',
postalCode: 'V6B 1A1',
stateCode: 'BC'
},
shippingMethod: {
id: 'standard-delivery',
name: 'Standard Delivery'
}
},
{
shipmentId: 'pickup-shipment',
shippingAddress: {
address1: '789 Store Location Ave',
city: 'Burnaby',
countryCode: 'CA',
firstName: 'Store',
lastName: 'Pickup',
phone: '(604) 555-5678',
postalCode: 'V5H 2E2',
stateCode: 'BC'
},
shippingMethod: {
id: '005',
name: 'Store Pickup',
c_storePickupEnabled: true
},
c_fromStoreId: 'store-123'
}
]
}

global.server.use(
rest.get('*/orders/:orderId', (req, res, ctx) => {
return res(ctx.delay(0), ctx.json(mockOrderWithPickup))
}),
rest.post('*/customers', (_, res, ctx) => {
return res(ctx.status(200), ctx.json(mockCustomer))
}),
rest.post('*/customers/:customerId/addresses', (req, res, ctx) => {
savedAddresses.push(req.body)
return res(ctx.status(200))
})
)

const {user} = renderWithProviders(<MockedComponent />, {
wrapperProps: {isGuest: true}
})

const createAccountButton = await screen.findByRole('button', {name: /create account/i})
const password = screen.getByLabelText('Password')
await user.type(password, 'P4ssword!')
await user.click(createAccountButton)

await waitFor(() => {
expect(window.location.pathname).toBe('/uk/en-GB/account')
})

// Verify that only one address was saved (the delivery address, not the pickup address)
expect(savedAddresses).toHaveLength(1)
expect(savedAddresses[0].address1).toBe('456 Delivery St')
expect(savedAddresses[0].city).toBe('Vancouver')

// Verify the pickup address was NOT saved
const hasPickupAddress = savedAddresses.some(
(addr) => addr.address1 === '789 Store Location Ave'
)
expect(hasPickupAddress).toBe(false)
})
})
Loading