feat(core-flows, fulfillment): validate shipping options to stock locations (#8291)

what:

- validate shipping options to stock locations

RESOLVES CC-232
This commit is contained in:
Riqwan Thamir
2024-07-26 14:26:26 +02:00
committed by GitHub
parent 74d0d166b3
commit 91c17651f1
23 changed files with 607 additions and 18 deletions

View File

@@ -0,0 +1,118 @@
import { ServiceZoneDTO, ShippingOptionDTO } from "@medusajs/types"
import {
ContainerRegistrationKeys,
MedusaError,
ModuleRegistrationName,
remoteQueryObjectFromString,
} from "@medusajs/utils"
import { createStep, StepResponse } from "@medusajs/workflows-sdk"
type FulfillmentProviderValidationInput = {
id?: string
service_zone_id?: string
provider_id?: string
}
export const validateFulfillmentProvidersStepId =
"validate-fulfillment-providers-step"
export const validateFulfillmentProvidersStep = createStep(
validateFulfillmentProvidersStepId,
async (input: FulfillmentProviderValidationInput[], { container }) => {
const dataToValidate: {
service_zone_id: string
provider_id: string
}[] = []
const fulfillmentService = container.resolve(
ModuleRegistrationName.FULFILLMENT
)
const shippingOptions = await fulfillmentService.listShippingOptions({
id: input.map((d) => d.id).filter(Boolean) as string[],
})
const shippingOptionsMap = new Map<string, ShippingOptionDTO>(
shippingOptions.map((so) => [so.id, so])
)
const remoteQuery = container.resolve(
ContainerRegistrationKeys.REMOTE_QUERY
)
for (const data of input) {
if ("id" in data) {
const existingShippingOption = shippingOptionsMap.get(data.id!)
dataToValidate.push({
service_zone_id:
data.service_zone_id! || existingShippingOption?.service_zone_id!,
provider_id:
data.provider_id! || existingShippingOption?.provider_id!,
})
continue
}
if (data.service_zone_id && data.provider_id) {
dataToValidate.push({
service_zone_id: data.service_zone_id,
provider_id: data.provider_id,
})
continue
}
throw new MedusaError(
MedusaError.Types.NOT_ALLOWED,
`service_zone_id and provider_id are required to create a shipping option`
)
}
const serviceZoneQuery = remoteQueryObjectFromString({
entryPoint: "service_zone",
fields: ["id", "fulfillment_set.locations.fulfillment_providers.id"],
})
const serviceZones = await remoteQuery(serviceZoneQuery, {
id: input.map((d) => d.service_zone_id),
})
const serviceZonesMap = new Map<
string,
ServiceZoneDTO & {
fulfillment_set: {
locations: { fulfillment_providers: { id: string }[] }[]
}
}
>(serviceZones.map((sz) => [sz.id, sz]))
const invalidProviders: string[] = []
for (const data of dataToValidate) {
const serviceZone = serviceZonesMap.get(data.service_zone_id)!
const stockLocations = serviceZone.fulfillment_set.locations
const fulfillmentProviders: string[] = []
for (const stockLocation of stockLocations) {
const providersForStockLocation =
stockLocation.fulfillment_providers.map((fp) => fp.id)
fulfillmentProviders.push(...providersForStockLocation)
}
if (!fulfillmentProviders.includes(data.provider_id)) {
invalidProviders.push(data.provider_id)
}
}
if (invalidProviders.length) {
throw new MedusaError(
MedusaError.Types.NOT_ALLOWED,
`Providers (${invalidProviders.join(
","
)}) are not enabled for the service location`
)
}
return new StepResponse(void 0)
}
)

View File

@@ -9,6 +9,7 @@ import {
upsertShippingOptionsStep,
} from "../steps"
import { setShippingOptionsPriceSetsStep } from "../steps/set-shipping-options-price-sets"
import { validateFulfillmentProvidersStep } from "../steps/validate-fulfillment-providers"
export const createShippingOptionsWorkflowId =
"create-shipping-options-workflow"
@@ -19,6 +20,8 @@ export const createShippingOptionsWorkflow = createWorkflow(
FulfillmentWorkflow.CreateShippingOptionsWorkflowInput[]
>
): WorkflowData<FulfillmentWorkflow.CreateShippingOptionsWorkflowOutput> => {
validateFulfillmentProvidersStep(input)
const data = transform(input, (data) => {
const shippingOptionsIndexToPrices = data.map((option, index) => {
const prices = option.prices

View File

@@ -8,6 +8,7 @@ import {
setShippingOptionsPricesStep,
upsertShippingOptionsStep,
} from "../steps"
import { validateFulfillmentProvidersStep } from "../steps/validate-fulfillment-providers"
export const updateShippingOptionsWorkflowId =
"update-shipping-options-workflow"
@@ -18,6 +19,8 @@ export const updateShippingOptionsWorkflow = createWorkflow(
FulfillmentWorkflow.UpdateShippingOptionsWorkflowInput[]
>
): WorkflowData<FulfillmentWorkflow.UpdateShippingOptionsWorkflowOutput> => {
validateFulfillmentProvidersStep(input)
const data = transform(input, (data) => {
const shippingOptionsIndexToPrices = data.map((option, index) => {
const prices = option.prices