fix: Handle region updates on cart (1/n) (#9369)
**What**
On cart creation:
- If region only has one country -> create cart with country code
On cart updates:
- If shipping address country code is provided in input ->
- If cart region doesn't include that country -> throw
- If cart includes the country -> update shipping address
- If region is provided in input and is different from the one currently on the cart ->
- If there is a shipping address on the cart -> clear the address
- If the region only has one country -> set country code of address
- If there is not a shipping address on the cart ->
- If the region only has one country -> set country code of address
Closes CC-545
This commit is contained in:
@@ -316,6 +316,49 @@ medusaIntegrationTestRunner({
|
||||
)
|
||||
})
|
||||
|
||||
it("should create cart with shipping address country code when there is only one country assigned to the region", async () => {
|
||||
const region = await regionModule.createRegions({
|
||||
name: "US",
|
||||
currency_code: "usd",
|
||||
countries: ["us"],
|
||||
})
|
||||
|
||||
const response = await api.post(
|
||||
`/store/carts`,
|
||||
{
|
||||
email: "tony@stark.com",
|
||||
currency_code: "usd",
|
||||
region_id: region.id,
|
||||
},
|
||||
storeHeaders
|
||||
)
|
||||
|
||||
expect(response.status).toEqual(200)
|
||||
expect(response.data.cart).toEqual(
|
||||
expect.objectContaining({
|
||||
id: response.data.cart.id,
|
||||
currency_code: "usd",
|
||||
email: "tony@stark.com",
|
||||
region: expect.objectContaining({
|
||||
id: region.id,
|
||||
}),
|
||||
shipping_address: {
|
||||
id: expect.any(String),
|
||||
country_code: "us",
|
||||
first_name: null,
|
||||
last_name: null,
|
||||
company: null,
|
||||
address_1: null,
|
||||
address_2: null,
|
||||
city: null,
|
||||
province: null,
|
||||
postal_code: null,
|
||||
phone: null,
|
||||
},
|
||||
})
|
||||
)
|
||||
})
|
||||
|
||||
it("should create cart with default store sales channel", async () => {
|
||||
const sc = await scModule.createSalesChannels({
|
||||
name: "Webshop",
|
||||
@@ -711,12 +754,6 @@ medusaIntegrationTestRunner({
|
||||
it("should not generate tax lines if region is not present or automatic taxes is false", async () => {
|
||||
await setupTaxStructure(taxModule)
|
||||
|
||||
const region = await regionModule.createRegions({
|
||||
name: "US",
|
||||
currency_code: "usd",
|
||||
automatic_taxes: false,
|
||||
})
|
||||
|
||||
const cart = await cartModule.createCarts({
|
||||
currency_code: "usd",
|
||||
email: "tony@stark.com",
|
||||
@@ -759,13 +796,15 @@ medusaIntegrationTestRunner({
|
||||
})
|
||||
)
|
||||
|
||||
await cartModule.updateCarts(cart.id, {
|
||||
region_id: region.id,
|
||||
const region = await regionModule.createRegions({
|
||||
name: "US",
|
||||
currency_code: "usd",
|
||||
automatic_taxes: false,
|
||||
})
|
||||
|
||||
updated = await api.post(
|
||||
`/store/carts/${cart.id}`,
|
||||
{ email: "another@tax.com" },
|
||||
{ email: "another@tax.com", region_id: region.id },
|
||||
storeHeaders
|
||||
)
|
||||
|
||||
@@ -790,6 +829,7 @@ medusaIntegrationTestRunner({
|
||||
const region = await regionModule.createRegions({
|
||||
name: "us",
|
||||
currency_code: "usd",
|
||||
countries: ["us"],
|
||||
})
|
||||
|
||||
const salesChannel = await scModule.createSalesChannels({
|
||||
@@ -917,19 +957,21 @@ medusaIntegrationTestRunner({
|
||||
}),
|
||||
sales_channel_id: salesChannel.id,
|
||||
shipping_address: expect.objectContaining({
|
||||
city: "ny",
|
||||
// We clear the shipping address on region update and only set the country code if the region has one country
|
||||
city: null,
|
||||
country_code: "us",
|
||||
province: "ny",
|
||||
province: null,
|
||||
}),
|
||||
shipping_methods: expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
shipping_option_id: shippingOption2.id,
|
||||
amount: 500,
|
||||
tax_lines: [
|
||||
// Since we clear the shipping address on region update, the tax lines are computed based on the new country code
|
||||
expect.objectContaining({
|
||||
description: "NY Default Rate",
|
||||
code: "NYDEFAULT",
|
||||
rate: 6,
|
||||
description: "US Default Rate",
|
||||
code: "US_DEF",
|
||||
rate: 2,
|
||||
provider_id: "system",
|
||||
}),
|
||||
],
|
||||
@@ -939,10 +981,11 @@ medusaIntegrationTestRunner({
|
||||
shipping_option_id: shippingOption.id,
|
||||
amount: 500,
|
||||
tax_lines: [
|
||||
// Since we clear the shipping address on region update, the tax lines are computed based on the new country code
|
||||
expect.objectContaining({
|
||||
description: "NY Default Rate",
|
||||
code: "NYDEFAULT",
|
||||
rate: 6,
|
||||
description: "US Default Rate",
|
||||
code: "US_DEF",
|
||||
rate: 2,
|
||||
provider_id: "system",
|
||||
}),
|
||||
],
|
||||
@@ -954,9 +997,9 @@ medusaIntegrationTestRunner({
|
||||
id: "item-1",
|
||||
tax_lines: [
|
||||
expect.objectContaining({
|
||||
description: "NY Default Rate",
|
||||
code: "NYDEFAULT",
|
||||
rate: 6,
|
||||
description: "US Default Rate",
|
||||
code: "US_DEF",
|
||||
rate: 2,
|
||||
provider_id: "system",
|
||||
}),
|
||||
],
|
||||
@@ -966,39 +1009,39 @@ medusaIntegrationTestRunner({
|
||||
})
|
||||
)
|
||||
|
||||
updated = await api.post(
|
||||
`/store/carts/${cart.id}`,
|
||||
{
|
||||
email: null,
|
||||
sales_channel_id: null,
|
||||
},
|
||||
storeHeaders
|
||||
)
|
||||
// updated = await api.post(
|
||||
// `/store/carts/${cart.id}`,
|
||||
// {
|
||||
// email: null,
|
||||
// sales_channel_id: null,
|
||||
// },
|
||||
// storeHeaders
|
||||
// )
|
||||
|
||||
expect(updated.status).toEqual(200)
|
||||
expect(updated.data.cart).toEqual(
|
||||
expect.objectContaining({
|
||||
id: cart.id,
|
||||
currency_code: "usd",
|
||||
email: null,
|
||||
customer_id: null,
|
||||
sales_channel_id: null,
|
||||
items: [
|
||||
expect.objectContaining({
|
||||
id: "item-1",
|
||||
tax_lines: [
|
||||
expect.objectContaining({
|
||||
description: "NY Default Rate",
|
||||
code: "NYDEFAULT",
|
||||
rate: 6,
|
||||
provider_id: "system",
|
||||
}),
|
||||
],
|
||||
adjustments: [],
|
||||
}),
|
||||
],
|
||||
})
|
||||
)
|
||||
// expect(updated.status).toEqual(200)
|
||||
// expect(updated.data.cart).toEqual(
|
||||
// expect.objectContaining({
|
||||
// id: cart.id,
|
||||
// currency_code: "usd",
|
||||
// email: null,
|
||||
// customer_id: null,
|
||||
// sales_channel_id: null,
|
||||
// items: [
|
||||
// expect.objectContaining({
|
||||
// id: "item-1",
|
||||
// tax_lines: [
|
||||
// expect.objectContaining({
|
||||
// description: "NY Default Rate",
|
||||
// code: "NYDEFAULT",
|
||||
// rate: 6,
|
||||
// provider_id: "system",
|
||||
// }),
|
||||
// ],
|
||||
// adjustments: [],
|
||||
// }),
|
||||
// ],
|
||||
// })
|
||||
// )
|
||||
})
|
||||
|
||||
it("should update tax lines on cart items when region changes", async () => {
|
||||
@@ -1132,6 +1175,364 @@ medusaIntegrationTestRunner({
|
||||
)
|
||||
})
|
||||
|
||||
it("should update tax inclusivity on cart items when region changes", async () => {
|
||||
await setupTaxStructure(taxModule)
|
||||
|
||||
const [region, otherRegion] = await regionModule.createRegions([
|
||||
{
|
||||
name: "us",
|
||||
currency_code: "usd",
|
||||
countries: ["us"],
|
||||
},
|
||||
{
|
||||
name: "dk",
|
||||
currency_code: "dkk",
|
||||
countries: ["dk"],
|
||||
},
|
||||
])
|
||||
|
||||
const salesChannel = await scModule.createSalesChannels({
|
||||
name: "Webshop",
|
||||
})
|
||||
|
||||
const [productWithDefaultTax] = await productModule.createProducts([
|
||||
{
|
||||
title: "Test product default tax",
|
||||
variants: [
|
||||
{ title: "Test variant default tax", manage_inventory: false },
|
||||
],
|
||||
},
|
||||
])
|
||||
|
||||
const [priceSetDefaultTax] = await pricingModule.createPriceSets([
|
||||
{
|
||||
prices: [{ amount: 2000, currency_code: "usd" }],
|
||||
},
|
||||
])
|
||||
|
||||
await remoteLink.create([
|
||||
{
|
||||
Product: {
|
||||
variant_id: productWithDefaultTax.variants[0].id,
|
||||
},
|
||||
Pricing: { price_set_id: priceSetDefaultTax.id },
|
||||
},
|
||||
])
|
||||
|
||||
await api.post(
|
||||
"/admin/price-preferences",
|
||||
{
|
||||
attribute: "currency_code",
|
||||
value: "usd",
|
||||
is_tax_inclusive: true,
|
||||
},
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
let response = await api.post(
|
||||
`/store/carts`,
|
||||
{
|
||||
sales_channel_id: salesChannel.id,
|
||||
shipping_address: {
|
||||
country_code: "us",
|
||||
},
|
||||
region_id: region.id,
|
||||
items: [
|
||||
{
|
||||
variant_id: productWithDefaultTax.variants[0].id,
|
||||
quantity: 1,
|
||||
},
|
||||
],
|
||||
},
|
||||
storeHeaders
|
||||
)
|
||||
|
||||
expect(response.data.cart).toEqual(
|
||||
expect.objectContaining({
|
||||
id: response.data.cart.id,
|
||||
currency_code: "usd",
|
||||
region_id: region.id,
|
||||
items: expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
unit_price: 2000,
|
||||
quantity: 1,
|
||||
title: "Test variant default tax",
|
||||
tax_lines: [
|
||||
// Uses the california default rate
|
||||
expect.objectContaining({
|
||||
description: "US Default Rate",
|
||||
code: "US_DEF",
|
||||
rate: 2,
|
||||
provider_id: "system",
|
||||
}),
|
||||
],
|
||||
}),
|
||||
]),
|
||||
})
|
||||
)
|
||||
|
||||
response = await api.post(
|
||||
`/store/carts/${response.data.cart.id}`,
|
||||
{
|
||||
region_id: otherRegion.id,
|
||||
shipping_address: {
|
||||
country_code: "dk",
|
||||
},
|
||||
},
|
||||
storeHeaders
|
||||
)
|
||||
|
||||
expect(response.data.cart).toEqual(
|
||||
expect.objectContaining({
|
||||
id: response.data.cart.id,
|
||||
currency_code: "dkk",
|
||||
region_id: otherRegion.id,
|
||||
items: expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
unit_price: 2000,
|
||||
quantity: 1,
|
||||
title: "Test variant default tax",
|
||||
tax_lines: [
|
||||
// Uses the danish default rate
|
||||
expect.objectContaining({
|
||||
description: "Denmark Default Rate",
|
||||
code: "DK_DEF",
|
||||
rate: 25,
|
||||
provider_id: "system",
|
||||
}),
|
||||
],
|
||||
}),
|
||||
]),
|
||||
})
|
||||
)
|
||||
})
|
||||
|
||||
it("should update region + set shipping address country code to dk when region has only one country", async () => {
|
||||
await setupTaxStructure(taxModule)
|
||||
|
||||
const region = await regionModule.createRegions({
|
||||
name: "us",
|
||||
currency_code: "usd",
|
||||
countries: ["us"],
|
||||
})
|
||||
|
||||
const otherRegion = await regionModule.createRegions({
|
||||
name: "dk",
|
||||
currency_code: "usd",
|
||||
countries: ["dk"],
|
||||
})
|
||||
|
||||
const cart = await cartModule.createCarts({
|
||||
currency_code: "eur",
|
||||
region_id: region.id,
|
||||
email: "tony@stark.com",
|
||||
shipping_address: {
|
||||
country_code: "us",
|
||||
},
|
||||
})
|
||||
|
||||
const updated = await api.post(
|
||||
`/store/carts/${cart.id}`,
|
||||
{
|
||||
region_id: otherRegion.id,
|
||||
},
|
||||
storeHeaders
|
||||
)
|
||||
|
||||
expect(updated.status).toEqual(200)
|
||||
expect(updated.data.cart).toEqual(
|
||||
expect.objectContaining({
|
||||
id: cart.id,
|
||||
currency_code: "usd",
|
||||
region: expect.objectContaining({
|
||||
id: otherRegion.id,
|
||||
currency_code: "usd",
|
||||
countries: [expect.objectContaining({ iso_2: "dk" })],
|
||||
}),
|
||||
shipping_address: expect.objectContaining({
|
||||
country_code: "dk",
|
||||
}),
|
||||
})
|
||||
)
|
||||
})
|
||||
|
||||
it("should update region + set shipping address to null when region has more than one country", async () => {
|
||||
await setupTaxStructure(taxModule)
|
||||
|
||||
const region = await regionModule.createRegions({
|
||||
name: "us",
|
||||
currency_code: "usd",
|
||||
countries: ["us"],
|
||||
})
|
||||
|
||||
const otherRegion = await regionModule.createRegions({
|
||||
name: "dk",
|
||||
currency_code: "eur",
|
||||
countries: ["dk", "no"],
|
||||
})
|
||||
|
||||
const cart = await cartModule.createCarts({
|
||||
currency_code: "eur",
|
||||
region_id: region.id,
|
||||
email: "tony@stark.com",
|
||||
shipping_address: {
|
||||
country_code: "us",
|
||||
},
|
||||
})
|
||||
|
||||
const updated = await api.post(
|
||||
`/store/carts/${cart.id}`,
|
||||
{
|
||||
region_id: otherRegion.id,
|
||||
},
|
||||
storeHeaders
|
||||
)
|
||||
|
||||
expect(updated.status).toEqual(200)
|
||||
expect(updated.data.cart).toEqual(
|
||||
expect.objectContaining({
|
||||
id: cart.id,
|
||||
currency_code: "eur",
|
||||
region: expect.objectContaining({
|
||||
id: otherRegion.id,
|
||||
currency_code: "eur",
|
||||
countries: [
|
||||
expect.objectContaining({ iso_2: "dk" }),
|
||||
expect.objectContaining({ iso_2: "no" }),
|
||||
],
|
||||
}),
|
||||
shipping_address: null,
|
||||
})
|
||||
)
|
||||
})
|
||||
|
||||
it("should update region and shipping address when country code is within region", async () => {
|
||||
await setupTaxStructure(taxModule)
|
||||
|
||||
const region = await regionModule.createRegions({
|
||||
name: "us",
|
||||
currency_code: "usd",
|
||||
countries: ["us"],
|
||||
})
|
||||
|
||||
const otherRegion = await regionModule.createRegions({
|
||||
name: "dk",
|
||||
currency_code: "eur",
|
||||
countries: ["dk", "no"],
|
||||
})
|
||||
|
||||
const cart = await cartModule.createCarts({
|
||||
currency_code: "eur",
|
||||
region_id: region.id,
|
||||
email: "tony@stark.com",
|
||||
shipping_address: {
|
||||
country_code: "us",
|
||||
},
|
||||
})
|
||||
|
||||
const updated = await api.post(
|
||||
`/store/carts/${cart.id}`,
|
||||
{
|
||||
region_id: otherRegion.id,
|
||||
shipping_address: {
|
||||
country_code: "dk",
|
||||
},
|
||||
},
|
||||
storeHeaders
|
||||
)
|
||||
|
||||
expect(updated.status).toEqual(200)
|
||||
expect(updated.data.cart).toEqual(
|
||||
expect.objectContaining({
|
||||
id: cart.id,
|
||||
currency_code: "eur",
|
||||
region: expect.objectContaining({
|
||||
id: otherRegion.id,
|
||||
currency_code: "eur",
|
||||
countries: [
|
||||
expect.objectContaining({ iso_2: "dk" }),
|
||||
expect.objectContaining({ iso_2: "no" }),
|
||||
],
|
||||
}),
|
||||
shipping_address: expect.objectContaining({
|
||||
country_code: "dk",
|
||||
}),
|
||||
})
|
||||
)
|
||||
})
|
||||
|
||||
it("should throw when updating shipping address country code when country is not within region", async () => {
|
||||
await setupTaxStructure(taxModule)
|
||||
|
||||
const region = await regionModule.createRegions({
|
||||
name: "Unites States",
|
||||
currency_code: "usd",
|
||||
countries: ["us"],
|
||||
})
|
||||
|
||||
const cart = await cartModule.createCarts({
|
||||
currency_code: "eur",
|
||||
email: "tony@stark.com",
|
||||
region_id: region.id,
|
||||
shipping_address: {
|
||||
country_code: "us",
|
||||
},
|
||||
})
|
||||
|
||||
let errResponse = await api
|
||||
.post(
|
||||
`/store/carts/${cart.id}`,
|
||||
{
|
||||
shipping_address: {
|
||||
country_code: "dk",
|
||||
},
|
||||
},
|
||||
storeHeaders
|
||||
)
|
||||
.catch((e) => e)
|
||||
|
||||
expect(errResponse.response.status).toEqual(400)
|
||||
expect(errResponse.response.data.message).toEqual(
|
||||
`Country with code dk is not within region ${region.name}`
|
||||
)
|
||||
})
|
||||
|
||||
it("should throw when updating region and shipping address, but shipping address country code is not within region", async () => {
|
||||
await setupTaxStructure(taxModule)
|
||||
|
||||
const region = await regionModule.createRegions({
|
||||
name: "Unites States",
|
||||
currency_code: "usd",
|
||||
countries: ["us"],
|
||||
})
|
||||
|
||||
const cart = await cartModule.createCarts({
|
||||
currency_code: "eur",
|
||||
email: "tony@stark.com",
|
||||
shipping_address: {
|
||||
country_code: "us",
|
||||
},
|
||||
})
|
||||
|
||||
let errResponse = await api
|
||||
.post(
|
||||
`/store/carts/${cart.id}`,
|
||||
{
|
||||
region_id: region.id,
|
||||
shipping_address: {
|
||||
country_code: "dk",
|
||||
},
|
||||
},
|
||||
storeHeaders
|
||||
)
|
||||
.catch((e) => e)
|
||||
|
||||
expect(errResponse.response.status).toEqual(400)
|
||||
expect(errResponse.response.data.message).toEqual(
|
||||
`Country with code dk is not within region ${region.name}`
|
||||
)
|
||||
})
|
||||
|
||||
it("should remove invalid shipping methods", async () => {
|
||||
await setupTaxStructure(taxModule)
|
||||
|
||||
@@ -1714,9 +2115,10 @@ medusaIntegrationTestRunner({
|
||||
)
|
||||
|
||||
expect(response.status).toEqual(200)
|
||||
expect(response.data.cart.items).toHaveLength(2)
|
||||
expect(response.data.cart).toEqual(
|
||||
expect.objectContaining({
|
||||
items: [
|
||||
items: expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
unit_price: 1500,
|
||||
quantity: 2,
|
||||
@@ -1727,7 +2129,7 @@ medusaIntegrationTestRunner({
|
||||
quantity: 1,
|
||||
title: "S / Black",
|
||||
}),
|
||||
],
|
||||
]),
|
||||
subtotal: 4500,
|
||||
})
|
||||
)
|
||||
|
||||
@@ -18,7 +18,9 @@ export const findOneOrAnyRegionStep = createStep(
|
||||
|
||||
if (data.regionId) {
|
||||
try {
|
||||
const region = await service.retrieveRegion(data.regionId)
|
||||
const region = await service.retrieveRegion(data.regionId, {
|
||||
relations: ["countries"],
|
||||
})
|
||||
return new StepResponse(region)
|
||||
} catch (error) {
|
||||
return new StepResponse(null)
|
||||
@@ -31,9 +33,12 @@ export const findOneOrAnyRegionStep = createStep(
|
||||
throw new MedusaError(MedusaError.Types.NOT_FOUND, "Store not found")
|
||||
}
|
||||
|
||||
const [region] = await service.listRegions({
|
||||
id: store.default_region_id,
|
||||
})
|
||||
const [region] = await service.listRegions(
|
||||
{
|
||||
id: store.default_region_id,
|
||||
},
|
||||
{ relations: ["countries"] }
|
||||
)
|
||||
|
||||
if (!region) {
|
||||
return new StepResponse(null)
|
||||
|
||||
@@ -27,9 +27,6 @@ import { refreshPaymentCollectionForCartWorkflow } from "./refresh-payment-colle
|
||||
import { updateCartPromotionsWorkflow } from "./update-cart-promotions"
|
||||
import { updateTaxLinesWorkflow } from "./update-tax-lines"
|
||||
|
||||
// TODO: The createCartWorkflow are missing the following steps:
|
||||
// - Refresh/delete shipping methods (fulfillment module)
|
||||
|
||||
export const createCartWorkflowId = "create-cart"
|
||||
/**
|
||||
* This workflow creates a cart.
|
||||
@@ -119,6 +116,13 @@ export const createCartWorkflow = createWorkflow(
|
||||
data_.sales_channel_id = data.salesChannel.id
|
||||
}
|
||||
|
||||
// If there is only one country in the region, we prepare a shipping address with that country's code.
|
||||
if (!data.input.shipping_address && data.region.countries.length === 1) {
|
||||
data_.shipping_address = {
|
||||
country_code: data.region.countries[0].iso_2,
|
||||
}
|
||||
}
|
||||
|
||||
return data_
|
||||
}
|
||||
)
|
||||
|
||||
@@ -2,11 +2,7 @@ import {
|
||||
AdditionalData,
|
||||
UpdateCartWorkflowInputDTO,
|
||||
} from "@medusajs/framework/types"
|
||||
import {
|
||||
MedusaError,
|
||||
PromotionActions,
|
||||
isPresent,
|
||||
} from "@medusajs/framework/utils"
|
||||
import { MedusaError, PromotionActions } from "@medusajs/framework/utils"
|
||||
import {
|
||||
WorkflowData,
|
||||
WorkflowResponse,
|
||||
@@ -14,10 +10,10 @@ import {
|
||||
createWorkflow,
|
||||
parallelize,
|
||||
transform,
|
||||
when,
|
||||
} from "@medusajs/framework/workflows-sdk"
|
||||
import { useRemoteQueryStep } from "../../common"
|
||||
import {
|
||||
findOneOrAnyRegionStep,
|
||||
findOrCreateCustomerStep,
|
||||
findSalesChannelStep,
|
||||
refreshCartShippingMethodsStep,
|
||||
@@ -35,35 +31,85 @@ export const updateCartWorkflowId = "update-cart"
|
||||
export const updateCartWorkflow = createWorkflow(
|
||||
updateCartWorkflowId,
|
||||
(input: WorkflowData<UpdateCartWorkflowInputDTO & AdditionalData>) => {
|
||||
const [salesChannel, region, customerData] = parallelize(
|
||||
const cartToUpdate = useRemoteQueryStep({
|
||||
entry_point: "cart",
|
||||
variables: { id: input.id },
|
||||
fields: ["id", "shipping_address.*", "region.*", "region.countries.*"],
|
||||
list: false,
|
||||
throw_if_key_not_found: true,
|
||||
}).config({ name: "get-cart" })
|
||||
|
||||
const [salesChannel, customerData] = parallelize(
|
||||
findSalesChannelStep({
|
||||
salesChannelId: input.sales_channel_id,
|
||||
}),
|
||||
findOneOrAnyRegionStep({
|
||||
regionId: input.region_id,
|
||||
}),
|
||||
findOrCreateCustomerStep({
|
||||
customerId: input.customer_id,
|
||||
email: input.email,
|
||||
})
|
||||
)
|
||||
|
||||
const newRegion = when({ input }, (data) => {
|
||||
return !!data.input.region_id
|
||||
}).then(() => {
|
||||
return useRemoteQueryStep({
|
||||
entry_point: "region",
|
||||
variables: { id: input.region_id },
|
||||
fields: ["id", "countries.*", "currency_code", "name"],
|
||||
list: false,
|
||||
throw_if_key_not_found: true,
|
||||
}).config({ name: "get-region" })
|
||||
})
|
||||
|
||||
const region = transform({ cartToUpdate, newRegion }, (data) => {
|
||||
return data.newRegion ?? data.cartToUpdate.region
|
||||
})
|
||||
|
||||
const cartInput = transform(
|
||||
{ input, region, customerData, salesChannel },
|
||||
{ input, region, customerData, salesChannel, cartToUpdate },
|
||||
(data) => {
|
||||
const { promo_codes, ...updateCartData } = data.input
|
||||
const data_ = { ...updateCartData }
|
||||
|
||||
if (isPresent(updateCartData.region_id)) {
|
||||
if (!data.region) {
|
||||
const data_ = {
|
||||
...updateCartData,
|
||||
currency_code: data.region?.currency_code,
|
||||
region_id: data.region?.id, // This is either the region from the input or the region from the cart or null
|
||||
}
|
||||
|
||||
// When the region is updated, we do a few things:
|
||||
// - We need to make sure the provided shipping address country code is in the new region
|
||||
// - We clear the shipping address if the new region has more than one country
|
||||
const regionIsNew = data.region?.id !== data.cartToUpdate.region?.id
|
||||
const shippingAddress = data.input.shipping_address
|
||||
|
||||
if (shippingAddress?.country_code) {
|
||||
const country = data.region.countries.find(
|
||||
(c) => c.iso_2 === shippingAddress.country_code
|
||||
)
|
||||
|
||||
if (!country) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.NOT_FOUND,
|
||||
"Region not found"
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
`Country with code ${shippingAddress.country_code} is not within region ${data.region.name}`
|
||||
)
|
||||
}
|
||||
|
||||
data_.currency_code = data.region.currency_code
|
||||
data_.region_id = data.region.id
|
||||
data_.shipping_address = {
|
||||
...shippingAddress,
|
||||
country_code: country.iso_2,
|
||||
}
|
||||
}
|
||||
|
||||
if (regionIsNew) {
|
||||
if (data.region.countries.length === 1) {
|
||||
data_.shipping_address = {
|
||||
country_code: data.region.countries[0].iso_2,
|
||||
}
|
||||
}
|
||||
|
||||
if (!data_.shipping_address?.country_code) {
|
||||
data_.shipping_address = null
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
|
||||
@@ -5,7 +5,11 @@ import { ProductDTO } from "../product"
|
||||
import { RegionDTO } from "../region"
|
||||
import { BigNumberInput } from "../totals"
|
||||
import { CartDTO, CartLineItemDTO } from "./common"
|
||||
import { UpdateLineItemDTO } from "./mutations"
|
||||
import {
|
||||
CreateAddressDTO,
|
||||
UpdateAddressDTO,
|
||||
UpdateLineItemDTO,
|
||||
} from "./mutations"
|
||||
|
||||
export interface CreateCartCreateLineItemDTO {
|
||||
quantity: BigNumberInput
|
||||
@@ -89,6 +93,8 @@ export interface UpdateCartWorkflowInputDTO {
|
||||
email?: string | null
|
||||
currency_code?: string
|
||||
metadata?: Record<string, unknown> | null
|
||||
shipping_address?: CreateAddressDTO | UpdateAddressDTO | null
|
||||
billing_address?: CreateAddressDTO | UpdateAddressDTO | null
|
||||
}
|
||||
|
||||
export interface CreatePaymentCollectionForCartWorkflowInputDTO {
|
||||
|
||||
Reference in New Issue
Block a user