fix(fulfillment): Geozone constraints builder (#13282)

This commit is contained in:
Oli Juhl
2025-08-23 14:51:04 +02:00
committed by GitHub
parent 486621383a
commit f0ef444992
2 changed files with 867 additions and 21 deletions
@@ -35,6 +35,7 @@ import {
ModulesSdkUtils,
promiseAll,
} from "@medusajs/framework/utils"
import { isObject } from "@medusajs/utils"
import {
Fulfillment,
FulfillmentProvider,
@@ -59,7 +60,6 @@ import { joinerConfig } from "../joiner-config"
import { UpdateShippingOptionsInput } from "../types/service"
import { buildCreatedShippingOptionEvents } from "../utils/events"
import FulfillmentProviderService from "./fulfillment-provider"
import { isObject } from "@medusajs/utils"
const generateMethodForModels = {
FulfillmentSet,
@@ -1411,7 +1411,7 @@ export default class FulfillmentModuleService
shippingOption.id
)! // Guaranteed to exist since the validation above have been performed
if (isObject(shippingOption.type) && !("id" in shippingOption.type)) {
if (isObject(shippingOption.type) && !("id" in shippingOption.type)) {
optionTypeDeletedIds.push(existingShippingOption.type.id)
}
@@ -1696,11 +1696,18 @@ export default class FulfillmentModuleService
idOrSelector: string | FulfillmentTypes.FilterableShippingOptionTypeProps,
data: FulfillmentTypes.UpdateShippingOptionTypeDTO,
@MedusaContext() sharedContext: Context = {}
): Promise<FulfillmentTypes.ShippingOptionTypeDTO[] | FulfillmentTypes.ShippingOptionTypeDTO> {
): Promise<
| FulfillmentTypes.ShippingOptionTypeDTO[]
| FulfillmentTypes.ShippingOptionTypeDTO
> {
let normalizedInput: FulfillmentTypes.UpdateShippingOptionTypeDTO[] = []
if (isString(idOrSelector)) {
// Check if the type exists in the first place
await this.shippingOptionTypeService_.retrieve(idOrSelector, {}, sharedContext)
await this.shippingOptionTypeService_.retrieve(
idOrSelector,
{},
sharedContext
)
normalizedInput = [{ id: idOrSelector, ...data }]
} else {
const types = await this.shippingOptionTypeService_.list(
@@ -2486,15 +2493,22 @@ export default class FulfillmentModuleService
* Define the hierarchy of required properties for the geo zones.
*/
const geoZoneRequirePropertyHierarchy = {
postal_expression: [
"country_code",
"province_code",
"city",
"postal_expression",
],
city: ["country_code", "province_code", "city"],
province_code: ["country_code", "province_code"],
country_code: ["country_code"],
postal_expression: {
props: ["country_code", "province_code", "city", "postal_expression"],
type: "zip",
},
city: {
props: ["country_code", "province_code", "city"],
type: "city",
},
province_code: {
props: ["country_code", "province_code"],
type: "province",
},
country_code: {
props: ["country_code"],
type: "country",
},
}
/**
@@ -2504,18 +2518,21 @@ export default class FulfillmentModuleService
*/
const geoZoneConstraints = Object.entries(geoZoneRequirePropertyHierarchy)
.map(([prop, requiredProps]) => {
.map(([prop, { props, type }]) => {
if (address![prop]) {
return requiredProps.reduce((geoZoneConstraint, prop) => {
if (isPresent(address![prop])) {
geoZoneConstraint[prop] = address![prop]
}
return geoZoneConstraint
}, {} as Record<string, string | undefined>)
return {
type,
...props.reduce((geoZoneConstraint, prop) => {
if (isPresent(address![prop])) {
geoZoneConstraint[prop] = address![prop]
}
return geoZoneConstraint
}, {} as Record<string, string | undefined>),
}
}
return null
})
.filter((v): v is Record<string, any> => !!v)
.filter((v) => !!v)
return geoZoneConstraints
}