fix: Add shipping method data validation (#9542)
* fix: Add shipping method data validation * fix: return type
This commit is contained in:
1 parent
6829d3b162
commit
43324b9294
7 files changed
+258
-45
No files matched your search
@@ -1,5 +1,5 @@
|
|||||||
import {
|
import {
|
||||||
addShippingMethodToWorkflow,
|
addShippingMethodToCartWorkflow,
|
||||||
addToCartWorkflow,
|
addToCartWorkflow,
|
||||||
createCartWorkflow,
|
createCartWorkflow,
|
||||||
createPaymentCollectionForCartWorkflow,
|
createPaymentCollectionForCartWorkflow,
|
||||||
@@ -1638,22 +1638,7 @@ medusaIntegrationTestRunner({
|
|||||||
},
|
},
|
||||||
])
|
])
|
||||||
|
|
||||||
await addShippingMethodToWorkflow(appContainer).run({
|
await addShippingMethodToCartWorkflow(appContainer).run({
|
||||||
input: {
|
|
||||||
options: [{ id: shippingOption.id }],
|
|
||||||
cart_id: cart.id,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
await addShippingMethodToWorkflow(appContainer).run({
|
|
||||||
input: {
|
|
||||||
options: [{ id: shippingOption.id }],
|
|
||||||
cart_id: cart.id,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
// should remove the previous shipping method
|
|
||||||
await addShippingMethodToWorkflow(appContainer).run({
|
|
||||||
input: {
|
input: {
|
||||||
options: [{ id: shippingOption.id }],
|
options: [{ id: shippingOption.id }],
|
||||||
cart_id: cart.id,
|
cart_id: cart.id,
|
||||||
@@ -1707,7 +1692,7 @@ medusaIntegrationTestRunner({
|
|||||||
},
|
},
|
||||||
])
|
])
|
||||||
|
|
||||||
const { errors } = await addShippingMethodToWorkflow(
|
const { errors } = await addShippingMethodToCartWorkflow(
|
||||||
appContainer
|
appContainer
|
||||||
).run({
|
).run({
|
||||||
input: {
|
input: {
|
||||||
@@ -1729,7 +1714,7 @@ medusaIntegrationTestRunner({
|
|||||||
})
|
})
|
||||||
|
|
||||||
it("should throw error when shipping option is not present in the db", async () => {
|
it("should throw error when shipping option is not present in the db", async () => {
|
||||||
const { errors } = await addShippingMethodToWorkflow(
|
const { errors } = await addShippingMethodToCartWorkflow(
|
||||||
appContainer
|
appContainer
|
||||||
).run({
|
).run({
|
||||||
input: {
|
input: {
|
||||||
@@ -1749,6 +1734,103 @@ medusaIntegrationTestRunner({
|
|||||||
}),
|
}),
|
||||||
])
|
])
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it("should add shipping method with custom data", async () => {
|
||||||
|
const stockLocation = (
|
||||||
|
await api.post(
|
||||||
|
`/admin/stock-locations`,
|
||||||
|
{ name: "test location" },
|
||||||
|
adminHeaders
|
||||||
|
)
|
||||||
|
).data.stock_location
|
||||||
|
|
||||||
|
await remoteLink.create([
|
||||||
|
{
|
||||||
|
[Modules.STOCK_LOCATION]: {
|
||||||
|
stock_location_id: stockLocation.id,
|
||||||
|
},
|
||||||
|
[Modules.FULFILLMENT]: {
|
||||||
|
fulfillment_set_id: fulfillmentSet.id,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
])
|
||||||
|
|
||||||
|
await api.post(
|
||||||
|
`/admin/stock-locations/${stockLocation.id}/fulfillment-providers`,
|
||||||
|
{ add: ["manual_test-provider"] },
|
||||||
|
adminHeaders
|
||||||
|
)
|
||||||
|
|
||||||
|
const shippingOption = await fulfillmentModule.createShippingOptions({
|
||||||
|
name: "Test shipping option",
|
||||||
|
service_zone_id: fulfillmentSet.service_zones[0].id,
|
||||||
|
shipping_profile_id: shippingProfile.id,
|
||||||
|
provider_id: "manual_test-provider",
|
||||||
|
price_type: "flat",
|
||||||
|
type: {
|
||||||
|
label: "Test type",
|
||||||
|
description: "Test description",
|
||||||
|
code: "test-code",
|
||||||
|
},
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
operator: RuleOperator.EQ,
|
||||||
|
attribute: "is_return",
|
||||||
|
value: "false",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
operator: RuleOperator.EQ,
|
||||||
|
attribute: "enabled_in_store",
|
||||||
|
value: "true",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
|
||||||
|
await remoteLink.create([
|
||||||
|
{
|
||||||
|
[Modules.FULFILLMENT]: { shipping_option_id: shippingOption.id },
|
||||||
|
[Modules.PRICING]: { price_set_id: priceSet.id },
|
||||||
|
},
|
||||||
|
])
|
||||||
|
|
||||||
|
await addShippingMethodToCartWorkflow(appContainer).run({
|
||||||
|
input: {
|
||||||
|
options: [{ id: shippingOption.id, data: { test: "test" } }],
|
||||||
|
cart_id: cart.id,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
cart = await cartModuleService.retrieveCart(cart.id, {
|
||||||
|
select: ["id"],
|
||||||
|
relations: ["shipping_methods"],
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(cart).toEqual(
|
||||||
|
expect.objectContaining({
|
||||||
|
id: cart.id,
|
||||||
|
shipping_methods: [
|
||||||
|
{
|
||||||
|
id: expect.any(String),
|
||||||
|
cart_id: cart.id,
|
||||||
|
description: null,
|
||||||
|
amount: 3000,
|
||||||
|
raw_amount: {
|
||||||
|
value: "3000",
|
||||||
|
precision: 20,
|
||||||
|
},
|
||||||
|
metadata: null,
|
||||||
|
is_tax_inclusive: true,
|
||||||
|
name: "Test shipping option",
|
||||||
|
data: { test: "test" },
|
||||||
|
shipping_option_id: shippingOption.id,
|
||||||
|
deleted_at: null,
|
||||||
|
updated_at: expect.any(Date),
|
||||||
|
created_at: expect.any(Date),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe("listShippingOptionsForCartWorkflow", () => {
|
describe("listShippingOptionsForCartWorkflow", () => {
|
||||||
|
|||||||
@@ -0,0 +1,50 @@
|
|||||||
|
import { Modules, promiseAll } from "@medusajs/framework/utils"
|
||||||
|
import { IFulfillmentModuleService } from "@medusajs/types"
|
||||||
|
import { createStep, StepResponse } from "@medusajs/workflows-sdk"
|
||||||
|
|
||||||
|
export interface ValidateShippingMethodsDataInput {
|
||||||
|
context: Record<string, unknown>
|
||||||
|
options_to_validate: {
|
||||||
|
id: string
|
||||||
|
provider_id: string
|
||||||
|
option_data: Record<string, unknown>
|
||||||
|
method_data: Record<string, unknown>
|
||||||
|
}[]
|
||||||
|
}
|
||||||
|
|
||||||
|
export const validateAndReturnShippingMethodsDataStepId =
|
||||||
|
"validate-and-return-shipping-methods-data"
|
||||||
|
/**
|
||||||
|
* This step validates shipping options to ensure they can be applied on a cart.
|
||||||
|
*/
|
||||||
|
export const validateAndReturnShippingMethodsDataStep = createStep(
|
||||||
|
validateAndReturnShippingMethodsDataStepId,
|
||||||
|
async (data: ValidateShippingMethodsDataInput, { container }) => {
|
||||||
|
const { options_to_validate = [] } = data
|
||||||
|
|
||||||
|
if (!options_to_validate.length) {
|
||||||
|
return new StepResponse(void 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
const fulfillmentModule = container.resolve<IFulfillmentModuleService>(
|
||||||
|
Modules.FULFILLMENT
|
||||||
|
)
|
||||||
|
|
||||||
|
const validatedData = await promiseAll(
|
||||||
|
options_to_validate.map(async (option) => {
|
||||||
|
const validated = await fulfillmentModule.validateFulfillmentData(
|
||||||
|
option.provider_id,
|
||||||
|
option.option_data,
|
||||||
|
option.method_data,
|
||||||
|
data.context
|
||||||
|
)
|
||||||
|
|
||||||
|
return {
|
||||||
|
[option.id]: validated,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
|
return new StepResponse(validatedData)
|
||||||
|
}
|
||||||
|
)
|
||||||
@@ -12,6 +12,7 @@ import {
|
|||||||
validateCartShippingOptionsStep,
|
validateCartShippingOptionsStep,
|
||||||
} from "../steps"
|
} from "../steps"
|
||||||
import { validateCartStep } from "../steps/validate-cart"
|
import { validateCartStep } from "../steps/validate-cart"
|
||||||
|
import { validateAndReturnShippingMethodsDataStep } from "../steps/validate-shipping-methods-data"
|
||||||
import { cartFieldsForRefreshSteps } from "../utils/fields"
|
import { cartFieldsForRefreshSteps } from "../utils/fields"
|
||||||
import { updateCartPromotionsWorkflow } from "./update-cart-promotions"
|
import { updateCartPromotionsWorkflow } from "./update-cart-promotions"
|
||||||
import { updateTaxLinesWorkflow } from "./update-tax-lines"
|
import { updateTaxLinesWorkflow } from "./update-tax-lines"
|
||||||
@@ -28,7 +29,7 @@ export const addShippingMethodToCartWorkflowId = "add-shipping-method-to-cart"
|
|||||||
/**
|
/**
|
||||||
* This workflow adds shipping methods to a cart.
|
* This workflow adds shipping methods to a cart.
|
||||||
*/
|
*/
|
||||||
export const addShippingMethodToWorkflow = createWorkflow(
|
export const addShippingMethodToCartWorkflow = createWorkflow(
|
||||||
addShippingMethodToCartWorkflowId,
|
addShippingMethodToCartWorkflowId,
|
||||||
(
|
(
|
||||||
input: WorkflowData<AddShippingMethodToCartWorkflowInput>
|
input: WorkflowData<AddShippingMethodToCartWorkflowInput>
|
||||||
@@ -59,6 +60,7 @@ export const addShippingMethodToWorkflow = createWorkflow(
|
|||||||
"name",
|
"name",
|
||||||
"calculated_price.calculated_amount",
|
"calculated_price.calculated_amount",
|
||||||
"calculated_price.is_calculated_price_tax_inclusive",
|
"calculated_price.is_calculated_price_tax_inclusive",
|
||||||
|
"provider_id",
|
||||||
],
|
],
|
||||||
variables: {
|
variables: {
|
||||||
id: optionIds,
|
id: optionIds,
|
||||||
@@ -68,8 +70,30 @@ export const addShippingMethodToWorkflow = createWorkflow(
|
|||||||
},
|
},
|
||||||
}).config({ name: "fetch-shipping-option" })
|
}).config({ name: "fetch-shipping-option" })
|
||||||
|
|
||||||
const shippingMethodInput = transform(
|
const validateShippingMethodsDataInput = transform(
|
||||||
{ input, shippingOptions },
|
{ input, shippingOptions },
|
||||||
|
(data) => {
|
||||||
|
return data.input.options.map((inputOption) => {
|
||||||
|
const shippingOption = data.shippingOptions.find(
|
||||||
|
(so) => so.id === inputOption.id
|
||||||
|
)
|
||||||
|
return {
|
||||||
|
id: inputOption.id,
|
||||||
|
provider_id: shippingOption?.provider_id,
|
||||||
|
option_data: shippingOption?.data ?? {},
|
||||||
|
method_data: inputOption.data ?? {},
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
const validatedMethodData = validateAndReturnShippingMethodsDataStep({
|
||||||
|
options_to_validate: validateShippingMethodsDataInput,
|
||||||
|
context: {}, // TODO: Add cart, when we have a better idea about what's appropriate to pass
|
||||||
|
})
|
||||||
|
|
||||||
|
const shippingMethodInput = transform(
|
||||||
|
{ input, shippingOptions, validatedMethodData },
|
||||||
(data) => {
|
(data) => {
|
||||||
const options = (data.input.options ?? []).map((option) => {
|
const options = (data.input.options ?? []).map((option) => {
|
||||||
const shippingOption = data.shippingOptions.find(
|
const shippingOption = data.shippingOptions.find(
|
||||||
@@ -83,13 +107,17 @@ export const addShippingMethodToWorkflow = createWorkflow(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const methodData = data.validatedMethodData?.find((methodData) => {
|
||||||
|
return methodData?.[option.id]
|
||||||
|
})
|
||||||
|
|
||||||
return {
|
return {
|
||||||
shipping_option_id: shippingOption.id,
|
shipping_option_id: shippingOption.id,
|
||||||
amount: shippingOption.calculated_price.calculated_amount,
|
amount: shippingOption.calculated_price.calculated_amount,
|
||||||
is_tax_inclusive:
|
is_tax_inclusive:
|
||||||
!!shippingOption.calculated_price
|
!!shippingOption.calculated_price
|
||||||
.is_calculated_price_tax_inclusive,
|
.is_calculated_price_tax_inclusive,
|
||||||
data: option.data ?? {},
|
data: methodData?.[option.id] ?? {},
|
||||||
name: shippingOption.name,
|
name: shippingOption.name,
|
||||||
cart_id: data.input.cart_id,
|
cart_id: data.input.cart_id,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2572,6 +2572,38 @@ export interface IFulfillmentModuleService extends IModuleService {
|
|||||||
data: Record<string, unknown>
|
data: Record<string, unknown>
|
||||||
): Promise<boolean>
|
): Promise<boolean>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method validates fulfillment data with the provider it belongs to.
|
||||||
|
* e.g. if the shipping option requires a drop point, the data you pass to create the
|
||||||
|
* shipping method must contain a drop point ID. This method can be used to
|
||||||
|
* validate that.
|
||||||
|
*
|
||||||
|
* @param {string} providerId - The fulfillment provider's ID.
|
||||||
|
* @param {Record<string, unknown>} optionData - The fulfillment option data to validate.
|
||||||
|
* @param {Record<string, unknown>} data - The fulfillment data to validate.
|
||||||
|
* @param {Record<string, unknown>} context - The context to validate the fulfillment option data in.
|
||||||
|
* @returns {Promise<boolean>} Whether the fulfillment option data is valid with the specified provider.
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* const isValid =
|
||||||
|
* await fulfillmentModuleService.validateFulfillmentData(
|
||||||
|
* "webshipper",
|
||||||
|
* {
|
||||||
|
* requires_drop_point: true,
|
||||||
|
* },
|
||||||
|
* {
|
||||||
|
* drop_point_id: "dp_123",
|
||||||
|
* },
|
||||||
|
* {}
|
||||||
|
* )
|
||||||
|
*/
|
||||||
|
validateFulfillmentData(
|
||||||
|
providerId: string,
|
||||||
|
optionData: Record<string, unknown>,
|
||||||
|
data: Record<string, unknown>,
|
||||||
|
context: Record<string, unknown>
|
||||||
|
): Promise<Record<string, unknown>>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method checks whether a shipping option can be used for a specified context.
|
* This method checks whether a shipping option can be used for a specified context.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -79,14 +79,6 @@ export class AbstractFulfillmentProviderService
|
|||||||
return obj?.constructor?._isFulfillmentService
|
return obj?.constructor?._isFulfillmentService
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @ignore
|
|
||||||
*
|
|
||||||
* @privateRemarks
|
|
||||||
* This method is ignored as {@link validateOption} is the one used by the Fulfillment Module.
|
|
||||||
*/
|
|
||||||
static validateOptions(options: Record<any, any>): void | never {}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ignore
|
* @ignore
|
||||||
*/
|
*/
|
||||||
@@ -154,7 +146,11 @@ export class AbstractFulfillmentProviderService
|
|||||||
* }
|
* }
|
||||||
* }
|
* }
|
||||||
*/
|
*/
|
||||||
async validateFulfillmentData(optionData, data, context): Promise<any> {
|
async validateFulfillmentData(
|
||||||
|
optionData: Record<string, unknown>,
|
||||||
|
data: Record<string, unknown>,
|
||||||
|
context: Record<string, unknown>
|
||||||
|
): Promise<any> {
|
||||||
throw Error("validateFulfillmentData must be overridden by the child class")
|
throw Error("validateFulfillmentData must be overridden by the child class")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -175,7 +171,7 @@ export class AbstractFulfillmentProviderService
|
|||||||
* }
|
* }
|
||||||
* }
|
* }
|
||||||
*/
|
*/
|
||||||
async validateOption(data): Promise<boolean> {
|
async validateOption(data: Record<string, unknown>): Promise<boolean> {
|
||||||
throw Error("validateOption must be overridden by the child class")
|
throw Error("validateOption must be overridden by the child class")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -194,7 +190,7 @@ export class AbstractFulfillmentProviderService
|
|||||||
* }
|
* }
|
||||||
* }
|
* }
|
||||||
*/
|
*/
|
||||||
async canCalculate(data): Promise<boolean> {
|
async canCalculate(data: Record<string, unknown>): Promise<boolean> {
|
||||||
throw Error("canCalculate must be overridden by the child class")
|
throw Error("canCalculate must be overridden by the child class")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -221,7 +217,11 @@ export class AbstractFulfillmentProviderService
|
|||||||
* }
|
* }
|
||||||
* }
|
* }
|
||||||
*/
|
*/
|
||||||
async calculatePrice(optionData, data, cart): Promise<number> {
|
async calculatePrice(
|
||||||
|
optionData: Record<string, unknown>,
|
||||||
|
data: Record<string, unknown>,
|
||||||
|
context: Record<string, unknown>
|
||||||
|
): Promise<number> {
|
||||||
throw Error("calculatePrice must be overridden by the child class")
|
throw Error("calculatePrice must be overridden by the child class")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -265,7 +265,12 @@ export class AbstractFulfillmentProviderService
|
|||||||
* }
|
* }
|
||||||
* }
|
* }
|
||||||
*/
|
*/
|
||||||
async createFulfillment(data, items, order, fulfillment): Promise<any> {
|
async createFulfillment(
|
||||||
|
data: object,
|
||||||
|
items: object[],
|
||||||
|
order: object | undefined,
|
||||||
|
fulfillment: Record<string, unknown>
|
||||||
|
): Promise<any> {
|
||||||
throw Error("createFulfillment must be overridden by the child class")
|
throw Error("createFulfillment must be overridden by the child class")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -285,7 +290,7 @@ export class AbstractFulfillmentProviderService
|
|||||||
* }
|
* }
|
||||||
* }
|
* }
|
||||||
*/
|
*/
|
||||||
async cancelFulfillment(fulfillment): Promise<any> {
|
async cancelFulfillment(fulfillment: Record<string, unknown>): Promise<any> {
|
||||||
throw Error("cancelFulfillment must be overridden by the child class")
|
throw Error("cancelFulfillment must be overridden by the child class")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -305,7 +310,7 @@ export class AbstractFulfillmentProviderService
|
|||||||
* }
|
* }
|
||||||
* }
|
* }
|
||||||
*/
|
*/
|
||||||
async getFulfillmentDocuments(data) {
|
async getFulfillmentDocuments(data: Record<string, unknown>) {
|
||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -340,7 +345,7 @@ export class AbstractFulfillmentProviderService
|
|||||||
* }
|
* }
|
||||||
* }
|
* }
|
||||||
*/
|
*/
|
||||||
async createReturnFulfillment(fulfillment): Promise<any> {
|
async createReturnFulfillment(fulfillment: Record<string, unknown>): Promise<any> {
|
||||||
throw Error("createReturn must be overridden by the child class")
|
throw Error("createReturn must be overridden by the child class")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -360,7 +365,7 @@ export class AbstractFulfillmentProviderService
|
|||||||
* }
|
* }
|
||||||
* }
|
* }
|
||||||
*/
|
*/
|
||||||
async getReturnDocuments(data) {
|
async getReturnDocuments(data: Record<string, unknown>) {
|
||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -381,7 +386,7 @@ export class AbstractFulfillmentProviderService
|
|||||||
* }
|
* }
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
async getShipmentDocuments(data) {
|
async getShipmentDocuments(data: Record<string, unknown>) {
|
||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -408,7 +413,10 @@ export class AbstractFulfillmentProviderService
|
|||||||
* }
|
* }
|
||||||
* }
|
* }
|
||||||
*/
|
*/
|
||||||
async retrieveDocuments(fulfillmentData, documentType) {
|
async retrieveDocuments(
|
||||||
|
fulfillmentData: Record<string, unknown>,
|
||||||
|
documentType: string
|
||||||
|
) {
|
||||||
throw Error("retrieveDocuments must be overridden by the child class")
|
throw Error("retrieveDocuments must be overridden by the child class")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,17 +1,16 @@
|
|||||||
import { addShippingMethodToWorkflow } from "@medusajs/core-flows"
|
import { addShippingMethodToCartWorkflow } from "@medusajs/core-flows"
|
||||||
import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http"
|
import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http"
|
||||||
|
import { HttpTypes } from "@medusajs/framework/types"
|
||||||
import { refetchCart } from "../../helpers"
|
import { refetchCart } from "../../helpers"
|
||||||
import { StoreAddCartShippingMethodsType } from "../../validators"
|
import { StoreAddCartShippingMethodsType } from "../../validators"
|
||||||
import { HttpTypes } from "@medusajs/framework/types"
|
|
||||||
|
|
||||||
export const POST = async (
|
export const POST = async (
|
||||||
req: MedusaRequest<StoreAddCartShippingMethodsType>,
|
req: MedusaRequest<StoreAddCartShippingMethodsType>,
|
||||||
res: MedusaResponse<HttpTypes.StoreCartResponse>
|
res: MedusaResponse<HttpTypes.StoreCartResponse>
|
||||||
) => {
|
) => {
|
||||||
const workflow = addShippingMethodToWorkflow(req.scope)
|
|
||||||
const payload = req.validatedBody
|
const payload = req.validatedBody
|
||||||
|
|
||||||
await workflow.run({
|
await addShippingMethodToCartWorkflow(req.scope).run({
|
||||||
input: {
|
input: {
|
||||||
options: [{ id: payload.option_id, data: payload.data }],
|
options: [{ id: payload.option_id, data: payload.data }],
|
||||||
cart_id: req.params.id,
|
cart_id: req.params.id,
|
||||||
|
|||||||
@@ -1927,6 +1927,20 @@ export default class FulfillmentModuleService
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async validateFulfillmentData(
|
||||||
|
providerId: string,
|
||||||
|
optionData: Record<string, unknown>,
|
||||||
|
data: Record<string, unknown>,
|
||||||
|
context: Record<string, unknown>
|
||||||
|
): Promise<Record<string, unknown>> {
|
||||||
|
return await this.fulfillmentProviderService_.validateFulfillmentData(
|
||||||
|
providerId,
|
||||||
|
optionData,
|
||||||
|
data,
|
||||||
|
context
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
async validateFulfillmentOption(
|
async validateFulfillmentOption(
|
||||||
providerId: string,
|
providerId: string,
|
||||||
data: Record<string, unknown>
|
data: Record<string, unknown>
|
||||||
|
|||||||
Reference in new issue
Block a user