feat(tax): normalize country and province code (#6513)
**What** - Ensures that country and province codes are always stored as lower case. - Ensures that calculation context normalizes input before getting region rates.
This commit is contained in:
1 parent
be8122bc0d
commit
d03b72ecdd
3 files changed
+68
-29
No files matched your search
@@ -34,14 +34,14 @@ moduleIntegrationTestRunner({
|
|||||||
expect.arrayContaining([
|
expect.arrayContaining([
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
id: region.id,
|
id: region.id,
|
||||||
country_code: "US",
|
country_code: "us",
|
||||||
province_code: null,
|
province_code: null,
|
||||||
parent_id: null,
|
parent_id: null,
|
||||||
}),
|
}),
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
id: provinceRegion.id,
|
id: provinceRegion.id,
|
||||||
country_code: "US",
|
country_code: "us",
|
||||||
province_code: "CA",
|
province_code: "ca",
|
||||||
parent_id: region.id,
|
parent_id: region.id,
|
||||||
}),
|
}),
|
||||||
])
|
])
|
||||||
@@ -397,6 +397,7 @@ moduleIntegrationTestRunner({
|
|||||||
expect(taxRegions).toEqual([
|
expect(taxRegions).toEqual([
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
id: region.id,
|
id: region.id,
|
||||||
|
country_code: "us",
|
||||||
deleted_at: expect.any(Date),
|
deleted_at: expect.any(Date),
|
||||||
}),
|
}),
|
||||||
])
|
])
|
||||||
|
|||||||
@@ -160,28 +160,10 @@ export default class TaxModuleService<
|
|||||||
data: TaxTypes.CreateTaxRegionDTO | TaxTypes.CreateTaxRegionDTO[],
|
data: TaxTypes.CreateTaxRegionDTO | TaxTypes.CreateTaxRegionDTO[],
|
||||||
@MedusaContext() sharedContext: Context = {}
|
@MedusaContext() sharedContext: Context = {}
|
||||||
) {
|
) {
|
||||||
const input = Array.isArray(data) ? data : [data]
|
const { defaultRates, regionData } =
|
||||||
await this.verifyProvinceToCountryMatch(input, sharedContext)
|
this.prepareTaxRegionInputForCreate(data)
|
||||||
const [defaultRates, regionData] = input.reduce(
|
|
||||||
(acc, region) => {
|
await this.verifyProvinceToCountryMatch(regionData, sharedContext)
|
||||||
const { default_tax_rate, ...rest } = region
|
|
||||||
if (!default_tax_rate) {
|
|
||||||
acc[0].push(null)
|
|
||||||
} else {
|
|
||||||
acc[0].push({
|
|
||||||
...default_tax_rate,
|
|
||||||
is_default: true,
|
|
||||||
created_by: region.created_by,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
acc[1].push(rest)
|
|
||||||
return acc
|
|
||||||
},
|
|
||||||
[[], []] as [
|
|
||||||
(Omit<TaxTypes.CreateTaxRateDTO, "tax_region_id"> | null)[],
|
|
||||||
Partial<TaxTypes.CreateTaxRegionDTO>[]
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
const regions = await this.taxRegionService_.create(
|
const regions = await this.taxRegionService_.create(
|
||||||
regionData,
|
regionData,
|
||||||
@@ -251,16 +233,18 @@ export default class TaxModuleService<
|
|||||||
calculationContext: TaxTypes.TaxCalculationContext,
|
calculationContext: TaxTypes.TaxCalculationContext,
|
||||||
@MedusaContext() sharedContext: Context = {}
|
@MedusaContext() sharedContext: Context = {}
|
||||||
): Promise<(TaxTypes.ItemTaxLineDTO | TaxTypes.ShippingTaxLineDTO)[]> {
|
): Promise<(TaxTypes.ItemTaxLineDTO | TaxTypes.ShippingTaxLineDTO)[]> {
|
||||||
|
const normalizedContext =
|
||||||
|
this.normalizeTaxCalculationContext(calculationContext)
|
||||||
const regions = await this.taxRegionService_.list(
|
const regions = await this.taxRegionService_.list(
|
||||||
{
|
{
|
||||||
$or: [
|
$or: [
|
||||||
{
|
{
|
||||||
country_code: calculationContext.address.country_code,
|
country_code: normalizedContext.address.country_code,
|
||||||
province_code: null,
|
province_code: null,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
country_code: calculationContext.address.country_code,
|
country_code: normalizedContext.address.country_code,
|
||||||
province_code: calculationContext.address.province_code,
|
province_code: normalizedContext.address.province_code,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@@ -355,6 +339,56 @@ export default class TaxModuleService<
|
|||||||
return itemTaxLines
|
return itemTaxLines
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private normalizeTaxCalculationContext(
|
||||||
|
context: TaxTypes.TaxCalculationContext
|
||||||
|
): TaxTypes.TaxCalculationContext {
|
||||||
|
return {
|
||||||
|
...context,
|
||||||
|
address: {
|
||||||
|
...context.address,
|
||||||
|
country_code: this.normalizeRegionCodes(context.address.country_code),
|
||||||
|
province_code: context.address.province_code
|
||||||
|
? this.normalizeRegionCodes(context.address.province_code)
|
||||||
|
: null,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private prepareTaxRegionInputForCreate(
|
||||||
|
data: TaxTypes.CreateTaxRegionDTO | TaxTypes.CreateTaxRegionDTO[]
|
||||||
|
) {
|
||||||
|
const regionsWithDefaultRate = Array.isArray(data) ? data : [data]
|
||||||
|
|
||||||
|
const defaultRates: (Omit<
|
||||||
|
TaxTypes.CreateTaxRateDTO,
|
||||||
|
"tax_region_id"
|
||||||
|
> | null)[] = []
|
||||||
|
const regionData: TaxTypes.CreateTaxRegionDTO[] = []
|
||||||
|
|
||||||
|
for (const region of regionsWithDefaultRate) {
|
||||||
|
const { default_tax_rate, ...rest } = region
|
||||||
|
if (!default_tax_rate) {
|
||||||
|
defaultRates.push(null)
|
||||||
|
} else {
|
||||||
|
defaultRates.push({
|
||||||
|
...default_tax_rate,
|
||||||
|
is_default: true,
|
||||||
|
created_by: region.created_by,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
regionData.push({
|
||||||
|
...rest,
|
||||||
|
province_code: rest.province_code
|
||||||
|
? this.normalizeRegionCodes(rest.province_code)
|
||||||
|
: null,
|
||||||
|
country_code: this.normalizeRegionCodes(rest.country_code),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return { defaultRates, regionData }
|
||||||
|
}
|
||||||
|
|
||||||
private async verifyProvinceToCountryMatch(
|
private async verifyProvinceToCountryMatch(
|
||||||
regionsToVerify: TaxTypes.CreateTaxRegionDTO[],
|
regionsToVerify: TaxTypes.CreateTaxRegionDTO[],
|
||||||
sharedContext: Context = {}
|
sharedContext: Context = {}
|
||||||
@@ -531,4 +565,8 @@ export default class TaxModuleService<
|
|||||||
(a, b) => (a as any).priority_score - (b as any).priority_score
|
(a, b) => (a as any).priority_score - (b as any).priority_score
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private normalizeRegionCodes(code: string) {
|
||||||
|
return code.toLowerCase()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -15,7 +15,7 @@ export interface CreateTaxRegionDTO {
|
|||||||
parent_id?: string | null
|
parent_id?: string | null
|
||||||
metadata?: Record<string, unknown>
|
metadata?: Record<string, unknown>
|
||||||
created_by?: string
|
created_by?: string
|
||||||
default_tax_rate: {
|
default_tax_rate?: {
|
||||||
rate?: number | null
|
rate?: number | null
|
||||||
code?: string | null
|
code?: string | null
|
||||||
name: string
|
name: string
|
||||||
|
|||||||
Reference in new issue
Block a user