diff --git a/integration-tests/api/__tests__/store/__snapshots__/cart.js.snap b/integration-tests/api/__tests__/store/__snapshots__/cart.js.snap index 520fe3a3ae..3d843b87ed 100644 --- a/integration-tests/api/__tests__/store/__snapshots__/cart.js.snap +++ b/integration-tests/api/__tests__/store/__snapshots__/cart.js.snap @@ -23,3 +23,24 @@ Object { "type": "not_allowed", } `; + +exports[`/store/carts shipping address + region updates updates region only - single to multipe countries 1`] = ` +Object { + "address_1": null, + "address_2": null, + "city": null, + "company": null, + "country_code": null, + "created_at": Any, + "customer_id": null, + "deleted_at": null, + "first_name": "lebron", + "id": Any, + "last_name": null, + "metadata": null, + "phone": null, + "postal_code": null, + "province": null, + "updated_at": Any, +} +`; diff --git a/integration-tests/api/__tests__/store/cart.js b/integration-tests/api/__tests__/store/cart.js index 4b2c0546a3..560654bc51 100644 --- a/integration-tests/api/__tests__/store/cart.js +++ b/integration-tests/api/__tests__/store/cart.js @@ -744,4 +744,59 @@ describe("/store/carts", () => { expect(response.status).toEqual(200) }) }) + + describe("shipping address + region updates", () => { + beforeEach(async () => { + try { + await cartSeeder(dbConnection) + } catch (err) { + console.log(err) + throw err + } + }) + + afterEach(async () => { + await doAfterEach() + }) + + it("updates region only - single to multipe countries", async () => { + const api = useApi() + + const { data, status } = await api + .post(`/store/carts/test-cart`, { + region_id: `test-region-multiple`, + }) + .catch((err) => { + console.log(err) + throw err + }) + + expect(status).toEqual(200) + expect(data.cart.region_id).toEqual("test-region-multiple") + expect(data.cart.shipping_address).toMatchSnapshot({ + id: expect.any(String), + country_code: null, + created_at: expect.any(String), + updated_at: expect.any(String), + }) + }) + + it("updates region only - single to multipe countries", async () => { + const api = useApi() + + const { data, status } = await api + .post(`/store/carts/test-cart`, { + shipping_address: null, + }) + .catch((err) => { + console.log(err) + throw err + }) + + expect(status).toEqual(200) + expect(data.cart.shipping_address).toEqual(null) + }) + + // it("updates cart.customer_id on cart retrieval if cart.customer_id differ from session customer", async () => {}) + }) }) diff --git a/packages/medusa-plugin-meilisearch/README.md b/packages/medusa-plugin-meilisearch/README.md index 1063118052..b4055107f5 100644 --- a/packages/medusa-plugin-meilisearch/README.md +++ b/packages/medusa-plugin-meilisearch/README.md @@ -3,6 +3,7 @@ Meilisearch Plugin for Medusa to search for products. ## Plugin Options + ``` { config: { @@ -17,4 +18,4 @@ Meilisearch Plugin for Medusa to search for products. } } } -``` \ No newline at end of file +``` diff --git a/packages/medusa/src/api/routes/store/carts/update-cart.js b/packages/medusa/src/api/routes/store/carts/update-cart.js index 83f1e79301..be1370be2f 100644 --- a/packages/medusa/src/api/routes/store/carts/update-cart.js +++ b/packages/medusa/src/api/routes/store/carts/update-cart.js @@ -72,11 +72,9 @@ export default async (req, res) => { const schema = Validator.object().keys({ region_id: Validator.string().optional(), country_code: Validator.string().optional(), - email: Validator.string() - .email() - .optional(), - billing_address: Validator.address().optional(), - shipping_address: Validator.address().optional(), + email: Validator.string().email().optional(), + billing_address: Validator.address().optional().allow(null), + shipping_address: Validator.address().optional().allow(null), gift_cards: Validator.array() .items({ code: Validator.string(), diff --git a/packages/medusa/src/services/cart.js b/packages/medusa/src/services/cart.js index 24dcb514b9..a584832c4a 100644 --- a/packages/medusa/src/services/cart.js +++ b/packages/medusa/src/services/cart.js @@ -771,8 +771,8 @@ class CartService extends BaseService { addressOrId.country_code = addressOrId.country_code.toLowerCase() if (addressOrId.id) { - cart.billing_address_id = addressOrId.id - cart.billing_address = addressOrId + const updated = await addrRepo.save(addressOrId) + cart.billing_address = updated } else { if (cart.billing_address_id) { const addr = await addrRepo.findOne({ @@ -797,15 +797,21 @@ class CartService extends BaseService { * @return {Promise} the result of the update operation */ async updateShippingAddress_(cart, addressOrId, addrRepo) { + if (addressOrId === null) { + cart.shipping_address = null + return + } + if (typeof addressOrId === `string`) { addressOrId = await addrRepo.findOne({ where: { id: addressOrId }, }) } - addressOrId.country_code = addressOrId.country_code.toLowerCase() + addressOrId.country_code = addressOrId.country_code?.toLowerCase() ?? null if ( + addressOrId.country_code && !cart.region.countries.find( ({ iso_2 }) => addressOrId.country_code === iso_2 ) @@ -817,8 +823,8 @@ class CartService extends BaseService { } if (addressOrId.id) { - cart.shipping_address = addressOrId - cart.shipping_address_id = addressOrId.id + const updated = await addrRepo.save(addressOrId) + cart.shipping_address = updated } else { if (cart.shipping_address_id) { const addr = await addrRepo.findOne({ @@ -1481,6 +1487,14 @@ class CartService extends BaseService { ) } + /* + * When changing the region you are changing the set of countries that your + * cart can be shipped to so we need to make sure that the current shipping + * address adheres to the new country set. + * + * First check if there is an existing shipping address on the cart if so + * fetch the entire thing so we can modify the shipping country + */ let shippingAddress = {} if (cart.shipping_address_id) { shippingAddress = await addrRepo.findOne({ @@ -1488,6 +1502,10 @@ class CartService extends BaseService { }) } + /* + * If the client has specified which country code we are updating to check + * that that country is in fact in the country and perform the update. + */ if (countryCode !== undefined) { if ( !region.countries.find( @@ -1507,7 +1525,17 @@ class CartService extends BaseService { await addrRepo.save(updated) } else { + /* + * In the case where the country code is not specified we need to check + * + * 1. if the region we are switching to has only one country preselect + * that + * 2. if the region has multiple countries we need to unset the country + * and wait for client to decide which country to use + */ + let updated = { ...shippingAddress } + // If the country code of a shipping address is set we need to clear it if (!_.isEmpty(shippingAddress) && shippingAddress.country_code) { updated = {