feat(core-flows): begin returns, claims and exchanges (#8088)
* chore(order): begin return * claims and exchanges
This commit is contained in:
@@ -0,0 +1,393 @@
|
||||
import {
|
||||
beginClaimOrderWorkflow,
|
||||
createShippingOptionsWorkflow,
|
||||
} from "@medusajs/core-flows"
|
||||
import {
|
||||
FulfillmentWorkflow,
|
||||
IOrderModuleService,
|
||||
IRegionModuleService,
|
||||
IStockLocationService,
|
||||
OrderWorkflow,
|
||||
ProductDTO,
|
||||
StockLocationDTO,
|
||||
} from "@medusajs/types"
|
||||
import {
|
||||
ClaimType,
|
||||
ContainerRegistrationKeys,
|
||||
ModuleRegistrationName,
|
||||
Modules,
|
||||
RuleOperator,
|
||||
remoteQueryObjectFromString,
|
||||
} from "@medusajs/utils"
|
||||
import { medusaIntegrationTestRunner } from "medusa-test-utils"
|
||||
|
||||
jest.setTimeout(500000)
|
||||
|
||||
const env = { MEDUSA_FF_MEDUSA_V2: true }
|
||||
const providerId = "manual_test-provider"
|
||||
|
||||
async function prepareDataFixtures({ container }) {
|
||||
const fulfillmentService = container.resolve(
|
||||
ModuleRegistrationName.FULFILLMENT
|
||||
)
|
||||
const salesChannelService = container.resolve(
|
||||
ModuleRegistrationName.SALES_CHANNEL
|
||||
)
|
||||
const stockLocationModule: IStockLocationService = container.resolve(
|
||||
ModuleRegistrationName.STOCK_LOCATION
|
||||
)
|
||||
const productModule = container.resolve(ModuleRegistrationName.PRODUCT)
|
||||
const pricingModule = container.resolve(ModuleRegistrationName.PRICING)
|
||||
const inventoryModule = container.resolve(ModuleRegistrationName.INVENTORY)
|
||||
|
||||
const shippingProfile = await fulfillmentService.createShippingProfiles({
|
||||
name: "test",
|
||||
type: "default",
|
||||
})
|
||||
|
||||
const fulfillmentSet = await fulfillmentService.createFulfillmentSets({
|
||||
name: "Test fulfillment set",
|
||||
type: "manual_test",
|
||||
})
|
||||
|
||||
const serviceZone = await fulfillmentService.createServiceZones({
|
||||
name: "Test service zone",
|
||||
fulfillment_set_id: fulfillmentSet.id,
|
||||
geo_zones: [
|
||||
{
|
||||
type: "country",
|
||||
country_code: "US",
|
||||
},
|
||||
],
|
||||
})
|
||||
|
||||
const regionService = container.resolve(
|
||||
ModuleRegistrationName.REGION
|
||||
) as IRegionModuleService
|
||||
|
||||
const [region] = await regionService.createRegions([
|
||||
{
|
||||
name: "Test region",
|
||||
currency_code: "eur",
|
||||
countries: ["fr"],
|
||||
},
|
||||
])
|
||||
|
||||
const salesChannel = await salesChannelService.createSalesChannels({
|
||||
name: "Webshop",
|
||||
})
|
||||
|
||||
const location: StockLocationDTO =
|
||||
await stockLocationModule.createStockLocations({
|
||||
name: "Warehouse",
|
||||
address: {
|
||||
address_1: "Test",
|
||||
city: "Test",
|
||||
country_code: "US",
|
||||
postal_code: "12345",
|
||||
phone: "12345",
|
||||
},
|
||||
})
|
||||
|
||||
const [product] = await productModule.createProducts([
|
||||
{
|
||||
title: "Test product",
|
||||
variants: [
|
||||
{
|
||||
title: "Test variant",
|
||||
sku: "test-variant",
|
||||
},
|
||||
],
|
||||
},
|
||||
])
|
||||
|
||||
const inventoryItem = await inventoryModule.createInventoryItems({
|
||||
sku: "inv-1234",
|
||||
})
|
||||
|
||||
await inventoryModule.createInventoryLevels([
|
||||
{
|
||||
inventory_item_id: inventoryItem.id,
|
||||
location_id: location.id,
|
||||
stocked_quantity: 2,
|
||||
reserved_quantity: 0,
|
||||
},
|
||||
])
|
||||
|
||||
const remoteLink = container.resolve(ContainerRegistrationKeys.REMOTE_LINK)
|
||||
|
||||
await remoteLink.create([
|
||||
{
|
||||
[Modules.STOCK_LOCATION]: {
|
||||
stock_location_id: location.id,
|
||||
},
|
||||
[Modules.FULFILLMENT]: {
|
||||
fulfillment_set_id: fulfillmentSet.id,
|
||||
},
|
||||
},
|
||||
{
|
||||
[Modules.SALES_CHANNEL]: {
|
||||
sales_channel_id: salesChannel.id,
|
||||
},
|
||||
[Modules.STOCK_LOCATION]: {
|
||||
stock_location_id: location.id,
|
||||
},
|
||||
},
|
||||
{
|
||||
[Modules.PRODUCT]: {
|
||||
variant_id: product.variants[0].id,
|
||||
},
|
||||
[Modules.INVENTORY]: {
|
||||
inventory_item_id: inventoryItem.id,
|
||||
},
|
||||
},
|
||||
])
|
||||
|
||||
await pricingModule.createPricePreferences([
|
||||
{
|
||||
attribute: "currency_code",
|
||||
value: "usd",
|
||||
is_tax_inclusive: true,
|
||||
},
|
||||
{
|
||||
attribute: "region_id",
|
||||
value: region.id,
|
||||
is_tax_inclusive: true,
|
||||
},
|
||||
])
|
||||
|
||||
const shippingOptionData: FulfillmentWorkflow.CreateShippingOptionsWorkflowInput =
|
||||
{
|
||||
name: "Return shipping option",
|
||||
price_type: "flat",
|
||||
service_zone_id: serviceZone.id,
|
||||
shipping_profile_id: shippingProfile.id,
|
||||
provider_id: providerId,
|
||||
type: {
|
||||
code: "manual-type",
|
||||
label: "Manual Type",
|
||||
description: "Manual Type Description",
|
||||
},
|
||||
prices: [
|
||||
{
|
||||
currency_code: "usd",
|
||||
amount: 10,
|
||||
},
|
||||
{
|
||||
region_id: region.id,
|
||||
amount: 100,
|
||||
},
|
||||
],
|
||||
rules: [
|
||||
{
|
||||
attribute: "is_return",
|
||||
operator: RuleOperator.EQ,
|
||||
value: '"true"',
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
const { result } = await createShippingOptionsWorkflow(container).run({
|
||||
input: [shippingOptionData],
|
||||
})
|
||||
|
||||
const remoteQueryObject = remoteQueryObjectFromString({
|
||||
entryPoint: "shipping_option",
|
||||
variables: {
|
||||
id: result[0].id,
|
||||
},
|
||||
fields: [
|
||||
"id",
|
||||
"name",
|
||||
"price_type",
|
||||
"service_zone_id",
|
||||
"shipping_profile_id",
|
||||
"provider_id",
|
||||
"data",
|
||||
"metadata",
|
||||
"type.*",
|
||||
"created_at",
|
||||
"updated_at",
|
||||
"deleted_at",
|
||||
"shipping_option_type_id",
|
||||
"prices.*",
|
||||
],
|
||||
})
|
||||
|
||||
const remoteQuery = container.resolve(ContainerRegistrationKeys.REMOTE_QUERY)
|
||||
|
||||
const [createdShippingOption] = await remoteQuery(remoteQueryObject)
|
||||
return {
|
||||
shippingOption: createdShippingOption,
|
||||
region,
|
||||
salesChannel,
|
||||
location,
|
||||
product,
|
||||
fulfillmentSet,
|
||||
}
|
||||
}
|
||||
|
||||
async function createOrderFixture({ container, product }) {
|
||||
const orderService: IOrderModuleService = container.resolve(
|
||||
ModuleRegistrationName.ORDER
|
||||
)
|
||||
let order = await orderService.createOrders({
|
||||
region_id: "test_region_idclear",
|
||||
email: "foo@bar.com",
|
||||
items: [
|
||||
{
|
||||
title: "Custom Item 2",
|
||||
variant_sku: product.variants[0].sku,
|
||||
variant_title: product.variants[0].title,
|
||||
quantity: 1,
|
||||
unit_price: 50,
|
||||
adjustments: [
|
||||
{
|
||||
code: "VIP_25 ETH",
|
||||
amount: "0.000000000000000005",
|
||||
description: "VIP discount",
|
||||
promotion_id: "prom_123",
|
||||
provider_id: "coupon_kings",
|
||||
},
|
||||
],
|
||||
} as any,
|
||||
],
|
||||
transactions: [
|
||||
{
|
||||
amount: 50,
|
||||
currency_code: "usd",
|
||||
},
|
||||
],
|
||||
sales_channel_id: "test",
|
||||
shipping_address: {
|
||||
first_name: "Test",
|
||||
last_name: "Test",
|
||||
address_1: "Test",
|
||||
city: "Test",
|
||||
country_code: "US",
|
||||
postal_code: "12345",
|
||||
phone: "12345",
|
||||
},
|
||||
billing_address: {
|
||||
first_name: "Test",
|
||||
last_name: "Test",
|
||||
address_1: "Test",
|
||||
city: "Test",
|
||||
country_code: "US",
|
||||
postal_code: "12345",
|
||||
},
|
||||
shipping_methods: [
|
||||
{
|
||||
name: "Test shipping method",
|
||||
amount: 10,
|
||||
data: {},
|
||||
tax_lines: [
|
||||
{
|
||||
description: "shipping Tax 1",
|
||||
tax_rate_id: "tax_usa_shipping",
|
||||
code: "code",
|
||||
rate: 10,
|
||||
},
|
||||
],
|
||||
adjustments: [
|
||||
{
|
||||
code: "VIP_10",
|
||||
amount: 1,
|
||||
description: "VIP discount",
|
||||
promotion_id: "prom_123",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
currency_code: "usd",
|
||||
customer_id: "joe",
|
||||
})
|
||||
|
||||
await orderService.addOrderAction([
|
||||
{
|
||||
action: "FULFILL_ITEM",
|
||||
order_id: order.id,
|
||||
version: order.version,
|
||||
reference: "fullfilment",
|
||||
reference_id: "fulfill_123",
|
||||
details: {
|
||||
reference_id: order.items![0].id,
|
||||
quantity: 1,
|
||||
},
|
||||
},
|
||||
{
|
||||
action: "SHIP_ITEM",
|
||||
order_id: order.id,
|
||||
version: order.version,
|
||||
reference: "fullfilment",
|
||||
reference_id: "fulfill_123",
|
||||
details: {
|
||||
reference_id: order.items![0].id,
|
||||
quantity: 1,
|
||||
},
|
||||
},
|
||||
])
|
||||
|
||||
await orderService.applyPendingOrderActions(order.id)
|
||||
|
||||
order = await orderService.retrieveOrder(order.id, {
|
||||
relations: ["items"],
|
||||
})
|
||||
|
||||
return order
|
||||
}
|
||||
|
||||
medusaIntegrationTestRunner({
|
||||
env,
|
||||
testSuite: ({ getContainer }) => {
|
||||
let container
|
||||
|
||||
beforeAll(() => {
|
||||
container = getContainer()
|
||||
})
|
||||
|
||||
describe("Begin claim order workflow", () => {
|
||||
let product: ProductDTO
|
||||
|
||||
beforeEach(async () => {
|
||||
const fixtures = await prepareDataFixtures({
|
||||
container,
|
||||
})
|
||||
|
||||
product = fixtures.product
|
||||
})
|
||||
|
||||
it("should begin a claim order", async () => {
|
||||
const order = await createOrderFixture({ container, product })
|
||||
|
||||
const createClaimOrderData: OrderWorkflow.beginOrderClaimWorkflowInput =
|
||||
{
|
||||
type: ClaimType.REFUND,
|
||||
order_id: order.id,
|
||||
}
|
||||
|
||||
await beginClaimOrderWorkflow(container).run({
|
||||
input: createClaimOrderData,
|
||||
throwOnError: true,
|
||||
})
|
||||
|
||||
const remoteQuery = container.resolve(
|
||||
ContainerRegistrationKeys.REMOTE_QUERY
|
||||
)
|
||||
const remoteQueryObject = remoteQueryObjectFromString({
|
||||
entryPoint: "order_claim",
|
||||
variables: {
|
||||
order_id: createClaimOrderData.order_id,
|
||||
},
|
||||
fields: ["order_id", "id", "type"],
|
||||
})
|
||||
|
||||
const [returnOrder] = await remoteQuery(remoteQueryObject)
|
||||
|
||||
expect(returnOrder.order_id).toEqual(order.id)
|
||||
expect(returnOrder.type).toEqual("refund")
|
||||
expect(returnOrder.id).toBeDefined()
|
||||
})
|
||||
})
|
||||
},
|
||||
})
|
||||
@@ -0,0 +1,400 @@
|
||||
import {
|
||||
beginExchangeOrderWorkflow,
|
||||
createShippingOptionsWorkflow,
|
||||
} from "@medusajs/core-flows"
|
||||
import {
|
||||
FulfillmentWorkflow,
|
||||
IOrderModuleService,
|
||||
IRegionModuleService,
|
||||
IStockLocationService,
|
||||
OrderWorkflow,
|
||||
ProductDTO,
|
||||
StockLocationDTO,
|
||||
} from "@medusajs/types"
|
||||
import {
|
||||
ContainerRegistrationKeys,
|
||||
ModuleRegistrationName,
|
||||
Modules,
|
||||
RuleOperator,
|
||||
remoteQueryObjectFromString,
|
||||
} from "@medusajs/utils"
|
||||
import { medusaIntegrationTestRunner } from "medusa-test-utils"
|
||||
|
||||
jest.setTimeout(500000)
|
||||
|
||||
const env = { MEDUSA_FF_MEDUSA_V2: true }
|
||||
const providerId = "manual_test-provider"
|
||||
|
||||
async function prepareDataFixtures({ container }) {
|
||||
const fulfillmentService = container.resolve(
|
||||
ModuleRegistrationName.FULFILLMENT
|
||||
)
|
||||
const salesChannelService = container.resolve(
|
||||
ModuleRegistrationName.SALES_CHANNEL
|
||||
)
|
||||
const stockLocationModule: IStockLocationService = container.resolve(
|
||||
ModuleRegistrationName.STOCK_LOCATION
|
||||
)
|
||||
const productModule = container.resolve(ModuleRegistrationName.PRODUCT)
|
||||
const pricingModule = container.resolve(ModuleRegistrationName.PRICING)
|
||||
const inventoryModule = container.resolve(ModuleRegistrationName.INVENTORY)
|
||||
|
||||
const shippingProfile = await fulfillmentService.createShippingProfiles({
|
||||
name: "test",
|
||||
type: "default",
|
||||
})
|
||||
|
||||
const fulfillmentSet = await fulfillmentService.createFulfillmentSets({
|
||||
name: "Test fulfillment set",
|
||||
type: "manual_test",
|
||||
})
|
||||
|
||||
const serviceZone = await fulfillmentService.createServiceZones({
|
||||
name: "Test service zone",
|
||||
fulfillment_set_id: fulfillmentSet.id,
|
||||
geo_zones: [
|
||||
{
|
||||
type: "country",
|
||||
country_code: "US",
|
||||
},
|
||||
],
|
||||
})
|
||||
|
||||
const regionService = container.resolve(
|
||||
ModuleRegistrationName.REGION
|
||||
) as IRegionModuleService
|
||||
|
||||
const [region] = await regionService.createRegions([
|
||||
{
|
||||
name: "Test region",
|
||||
currency_code: "eur",
|
||||
countries: ["fr"],
|
||||
},
|
||||
])
|
||||
|
||||
const salesChannel = await salesChannelService.createSalesChannels({
|
||||
name: "Webshop",
|
||||
})
|
||||
|
||||
const location: StockLocationDTO =
|
||||
await stockLocationModule.createStockLocations({
|
||||
name: "Warehouse",
|
||||
address: {
|
||||
address_1: "Test",
|
||||
city: "Test",
|
||||
country_code: "US",
|
||||
postal_code: "12345",
|
||||
phone: "12345",
|
||||
},
|
||||
})
|
||||
|
||||
const [product] = await productModule.createProducts([
|
||||
{
|
||||
title: "Test product",
|
||||
variants: [
|
||||
{
|
||||
title: "Test variant",
|
||||
sku: "test-variant",
|
||||
},
|
||||
],
|
||||
},
|
||||
])
|
||||
|
||||
const inventoryItem = await inventoryModule.createInventoryItems({
|
||||
sku: "inv-1234",
|
||||
})
|
||||
|
||||
await inventoryModule.createInventoryLevels([
|
||||
{
|
||||
inventory_item_id: inventoryItem.id,
|
||||
location_id: location.id,
|
||||
stocked_quantity: 2,
|
||||
reserved_quantity: 0,
|
||||
},
|
||||
])
|
||||
|
||||
const remoteLink = container.resolve(ContainerRegistrationKeys.REMOTE_LINK)
|
||||
|
||||
await remoteLink.create([
|
||||
{
|
||||
[Modules.STOCK_LOCATION]: {
|
||||
stock_location_id: location.id,
|
||||
},
|
||||
[Modules.FULFILLMENT]: {
|
||||
fulfillment_set_id: fulfillmentSet.id,
|
||||
},
|
||||
},
|
||||
{
|
||||
[Modules.SALES_CHANNEL]: {
|
||||
sales_channel_id: salesChannel.id,
|
||||
},
|
||||
[Modules.STOCK_LOCATION]: {
|
||||
stock_location_id: location.id,
|
||||
},
|
||||
},
|
||||
{
|
||||
[Modules.PRODUCT]: {
|
||||
variant_id: product.variants[0].id,
|
||||
},
|
||||
[Modules.INVENTORY]: {
|
||||
inventory_item_id: inventoryItem.id,
|
||||
},
|
||||
},
|
||||
])
|
||||
|
||||
await pricingModule.createPricePreferences([
|
||||
{
|
||||
attribute: "currency_code",
|
||||
value: "usd",
|
||||
is_tax_inclusive: true,
|
||||
},
|
||||
{
|
||||
attribute: "region_id",
|
||||
value: region.id,
|
||||
is_tax_inclusive: true,
|
||||
},
|
||||
])
|
||||
|
||||
const shippingOptionData: FulfillmentWorkflow.CreateShippingOptionsWorkflowInput =
|
||||
{
|
||||
name: "Return shipping option",
|
||||
price_type: "flat",
|
||||
service_zone_id: serviceZone.id,
|
||||
shipping_profile_id: shippingProfile.id,
|
||||
provider_id: providerId,
|
||||
type: {
|
||||
code: "manual-type",
|
||||
label: "Manual Type",
|
||||
description: "Manual Type Description",
|
||||
},
|
||||
prices: [
|
||||
{
|
||||
currency_code: "usd",
|
||||
amount: 10,
|
||||
},
|
||||
{
|
||||
region_id: region.id,
|
||||
amount: 100,
|
||||
},
|
||||
],
|
||||
rules: [
|
||||
{
|
||||
attribute: "is_return",
|
||||
operator: RuleOperator.EQ,
|
||||
value: '"true"',
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
const { result } = await createShippingOptionsWorkflow(container).run({
|
||||
input: [shippingOptionData],
|
||||
})
|
||||
|
||||
const remoteQueryObject = remoteQueryObjectFromString({
|
||||
entryPoint: "shipping_option",
|
||||
variables: {
|
||||
id: result[0].id,
|
||||
},
|
||||
fields: [
|
||||
"id",
|
||||
"name",
|
||||
"price_type",
|
||||
"service_zone_id",
|
||||
"shipping_profile_id",
|
||||
"provider_id",
|
||||
"data",
|
||||
"metadata",
|
||||
"type.*",
|
||||
"created_at",
|
||||
"updated_at",
|
||||
"deleted_at",
|
||||
"shipping_option_type_id",
|
||||
"prices.*",
|
||||
],
|
||||
})
|
||||
|
||||
const remoteQuery = container.resolve(ContainerRegistrationKeys.REMOTE_QUERY)
|
||||
|
||||
const [createdShippingOption] = await remoteQuery(remoteQueryObject)
|
||||
return {
|
||||
shippingOption: createdShippingOption,
|
||||
region,
|
||||
salesChannel,
|
||||
location,
|
||||
product,
|
||||
fulfillmentSet,
|
||||
}
|
||||
}
|
||||
|
||||
async function createOrderFixture({ container, product }) {
|
||||
const orderService: IOrderModuleService = container.resolve(
|
||||
ModuleRegistrationName.ORDER
|
||||
)
|
||||
let order = await orderService.createOrders({
|
||||
region_id: "test_region_idclear",
|
||||
email: "foo@bar.com",
|
||||
items: [
|
||||
{
|
||||
title: "Custom Item 2",
|
||||
variant_sku: product.variants[0].sku,
|
||||
variant_title: product.variants[0].title,
|
||||
quantity: 1,
|
||||
unit_price: 50,
|
||||
adjustments: [
|
||||
{
|
||||
code: "VIP_25 ETH",
|
||||
amount: "0.000000000000000005",
|
||||
description: "VIP discount",
|
||||
promotion_id: "prom_123",
|
||||
provider_id: "coupon_kings",
|
||||
},
|
||||
],
|
||||
} as any,
|
||||
],
|
||||
transactions: [
|
||||
{
|
||||
amount: 50,
|
||||
currency_code: "usd",
|
||||
},
|
||||
],
|
||||
sales_channel_id: "test",
|
||||
shipping_address: {
|
||||
first_name: "Test",
|
||||
last_name: "Test",
|
||||
address_1: "Test",
|
||||
city: "Test",
|
||||
country_code: "US",
|
||||
postal_code: "12345",
|
||||
phone: "12345",
|
||||
},
|
||||
billing_address: {
|
||||
first_name: "Test",
|
||||
last_name: "Test",
|
||||
address_1: "Test",
|
||||
city: "Test",
|
||||
country_code: "US",
|
||||
postal_code: "12345",
|
||||
},
|
||||
shipping_methods: [
|
||||
{
|
||||
name: "Test shipping method",
|
||||
amount: 10,
|
||||
data: {},
|
||||
tax_lines: [
|
||||
{
|
||||
description: "shipping Tax 1",
|
||||
tax_rate_id: "tax_usa_shipping",
|
||||
code: "code",
|
||||
rate: 10,
|
||||
},
|
||||
],
|
||||
adjustments: [
|
||||
{
|
||||
code: "VIP_10",
|
||||
amount: 1,
|
||||
description: "VIP discount",
|
||||
promotion_id: "prom_123",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
currency_code: "usd",
|
||||
customer_id: "joe",
|
||||
})
|
||||
|
||||
await orderService.addOrderAction([
|
||||
{
|
||||
action: "FULFILL_ITEM",
|
||||
order_id: order.id,
|
||||
version: order.version,
|
||||
reference: "fullfilment",
|
||||
reference_id: "fulfill_123",
|
||||
details: {
|
||||
reference_id: order.items![0].id,
|
||||
quantity: 1,
|
||||
},
|
||||
},
|
||||
{
|
||||
action: "SHIP_ITEM",
|
||||
order_id: order.id,
|
||||
version: order.version,
|
||||
reference: "fullfilment",
|
||||
reference_id: "fulfill_123",
|
||||
details: {
|
||||
reference_id: order.items![0].id,
|
||||
quantity: 1,
|
||||
},
|
||||
},
|
||||
])
|
||||
|
||||
await orderService.applyPendingOrderActions(order.id)
|
||||
|
||||
order = await orderService.retrieveOrder(order.id, {
|
||||
relations: ["items"],
|
||||
})
|
||||
|
||||
return order
|
||||
}
|
||||
|
||||
medusaIntegrationTestRunner({
|
||||
env,
|
||||
testSuite: ({ getContainer }) => {
|
||||
let container
|
||||
|
||||
beforeAll(() => {
|
||||
container = getContainer()
|
||||
})
|
||||
|
||||
describe("Begin exchange order workflow", () => {
|
||||
let product: ProductDTO
|
||||
|
||||
beforeEach(async () => {
|
||||
const fixtures = await prepareDataFixtures({
|
||||
container,
|
||||
})
|
||||
|
||||
product = fixtures.product
|
||||
})
|
||||
|
||||
it("should begin an exchange order", async () => {
|
||||
const order = await createOrderFixture({ container, product })
|
||||
|
||||
const createExchangeOrderData: OrderWorkflow.beginOrderExchangeWorkflowInput =
|
||||
{
|
||||
order_id: order.id,
|
||||
metadata: {
|
||||
reason: "test",
|
||||
extra: "data",
|
||||
value: 1234,
|
||||
},
|
||||
}
|
||||
|
||||
await beginExchangeOrderWorkflow(container).run({
|
||||
input: createExchangeOrderData,
|
||||
throwOnError: true,
|
||||
})
|
||||
|
||||
const remoteQuery = container.resolve(
|
||||
ContainerRegistrationKeys.REMOTE_QUERY
|
||||
)
|
||||
const remoteQueryObject = remoteQueryObjectFromString({
|
||||
entryPoint: "order_exchange",
|
||||
variables: {
|
||||
order_id: createExchangeOrderData.order_id,
|
||||
},
|
||||
fields: ["order_id", "id", "metadata"],
|
||||
})
|
||||
|
||||
const [returnOrder] = await remoteQuery(remoteQueryObject)
|
||||
|
||||
expect(returnOrder.order_id).toEqual(order.id)
|
||||
expect(returnOrder.metadata).toEqual({
|
||||
reason: "test",
|
||||
extra: "data",
|
||||
value: 1234,
|
||||
})
|
||||
expect(returnOrder.id).toBeDefined()
|
||||
})
|
||||
})
|
||||
},
|
||||
})
|
||||
@@ -0,0 +1,391 @@
|
||||
import {
|
||||
beginReturnOrderWorkflow,
|
||||
createShippingOptionsWorkflow,
|
||||
} from "@medusajs/core-flows"
|
||||
import {
|
||||
FulfillmentWorkflow,
|
||||
IOrderModuleService,
|
||||
IRegionModuleService,
|
||||
IStockLocationService,
|
||||
OrderWorkflow,
|
||||
ProductDTO,
|
||||
StockLocationDTO,
|
||||
} from "@medusajs/types"
|
||||
import {
|
||||
ContainerRegistrationKeys,
|
||||
ModuleRegistrationName,
|
||||
Modules,
|
||||
RuleOperator,
|
||||
remoteQueryObjectFromString,
|
||||
} from "@medusajs/utils"
|
||||
import { medusaIntegrationTestRunner } from "medusa-test-utils"
|
||||
|
||||
jest.setTimeout(500000)
|
||||
|
||||
const env = { MEDUSA_FF_MEDUSA_V2: true }
|
||||
const providerId = "manual_test-provider"
|
||||
|
||||
async function prepareDataFixtures({ container }) {
|
||||
const fulfillmentService = container.resolve(
|
||||
ModuleRegistrationName.FULFILLMENT
|
||||
)
|
||||
const salesChannelService = container.resolve(
|
||||
ModuleRegistrationName.SALES_CHANNEL
|
||||
)
|
||||
const stockLocationModule: IStockLocationService = container.resolve(
|
||||
ModuleRegistrationName.STOCK_LOCATION
|
||||
)
|
||||
const productModule = container.resolve(ModuleRegistrationName.PRODUCT)
|
||||
const pricingModule = container.resolve(ModuleRegistrationName.PRICING)
|
||||
const inventoryModule = container.resolve(ModuleRegistrationName.INVENTORY)
|
||||
|
||||
const shippingProfile = await fulfillmentService.createShippingProfiles({
|
||||
name: "test",
|
||||
type: "default",
|
||||
})
|
||||
|
||||
const fulfillmentSet = await fulfillmentService.createFulfillmentSets({
|
||||
name: "Test fulfillment set",
|
||||
type: "manual_test",
|
||||
})
|
||||
|
||||
const serviceZone = await fulfillmentService.createServiceZones({
|
||||
name: "Test service zone",
|
||||
fulfillment_set_id: fulfillmentSet.id,
|
||||
geo_zones: [
|
||||
{
|
||||
type: "country",
|
||||
country_code: "US",
|
||||
},
|
||||
],
|
||||
})
|
||||
|
||||
const regionService = container.resolve(
|
||||
ModuleRegistrationName.REGION
|
||||
) as IRegionModuleService
|
||||
|
||||
const [region] = await regionService.createRegions([
|
||||
{
|
||||
name: "Test region",
|
||||
currency_code: "eur",
|
||||
countries: ["fr"],
|
||||
},
|
||||
])
|
||||
|
||||
const salesChannel = await salesChannelService.createSalesChannels({
|
||||
name: "Webshop",
|
||||
})
|
||||
|
||||
const location: StockLocationDTO =
|
||||
await stockLocationModule.createStockLocations({
|
||||
name: "Warehouse",
|
||||
address: {
|
||||
address_1: "Test",
|
||||
city: "Test",
|
||||
country_code: "US",
|
||||
postal_code: "12345",
|
||||
phone: "12345",
|
||||
},
|
||||
})
|
||||
|
||||
const [product] = await productModule.createProducts([
|
||||
{
|
||||
title: "Test product",
|
||||
variants: [
|
||||
{
|
||||
title: "Test variant",
|
||||
sku: "test-variant",
|
||||
},
|
||||
],
|
||||
},
|
||||
])
|
||||
|
||||
const inventoryItem = await inventoryModule.createInventoryItems({
|
||||
sku: "inv-1234",
|
||||
})
|
||||
|
||||
await inventoryModule.createInventoryLevels([
|
||||
{
|
||||
inventory_item_id: inventoryItem.id,
|
||||
location_id: location.id,
|
||||
stocked_quantity: 2,
|
||||
reserved_quantity: 0,
|
||||
},
|
||||
])
|
||||
|
||||
const remoteLink = container.resolve(ContainerRegistrationKeys.REMOTE_LINK)
|
||||
|
||||
await remoteLink.create([
|
||||
{
|
||||
[Modules.STOCK_LOCATION]: {
|
||||
stock_location_id: location.id,
|
||||
},
|
||||
[Modules.FULFILLMENT]: {
|
||||
fulfillment_set_id: fulfillmentSet.id,
|
||||
},
|
||||
},
|
||||
{
|
||||
[Modules.SALES_CHANNEL]: {
|
||||
sales_channel_id: salesChannel.id,
|
||||
},
|
||||
[Modules.STOCK_LOCATION]: {
|
||||
stock_location_id: location.id,
|
||||
},
|
||||
},
|
||||
{
|
||||
[Modules.PRODUCT]: {
|
||||
variant_id: product.variants[0].id,
|
||||
},
|
||||
[Modules.INVENTORY]: {
|
||||
inventory_item_id: inventoryItem.id,
|
||||
},
|
||||
},
|
||||
])
|
||||
|
||||
await pricingModule.createPricePreferences([
|
||||
{
|
||||
attribute: "currency_code",
|
||||
value: "usd",
|
||||
is_tax_inclusive: true,
|
||||
},
|
||||
{
|
||||
attribute: "region_id",
|
||||
value: region.id,
|
||||
is_tax_inclusive: true,
|
||||
},
|
||||
])
|
||||
|
||||
const shippingOptionData: FulfillmentWorkflow.CreateShippingOptionsWorkflowInput =
|
||||
{
|
||||
name: "Return shipping option",
|
||||
price_type: "flat",
|
||||
service_zone_id: serviceZone.id,
|
||||
shipping_profile_id: shippingProfile.id,
|
||||
provider_id: providerId,
|
||||
type: {
|
||||
code: "manual-type",
|
||||
label: "Manual Type",
|
||||
description: "Manual Type Description",
|
||||
},
|
||||
prices: [
|
||||
{
|
||||
currency_code: "usd",
|
||||
amount: 10,
|
||||
},
|
||||
{
|
||||
region_id: region.id,
|
||||
amount: 100,
|
||||
},
|
||||
],
|
||||
rules: [
|
||||
{
|
||||
attribute: "is_return",
|
||||
operator: RuleOperator.EQ,
|
||||
value: '"true"',
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
const { result } = await createShippingOptionsWorkflow(container).run({
|
||||
input: [shippingOptionData],
|
||||
})
|
||||
|
||||
const remoteQueryObject = remoteQueryObjectFromString({
|
||||
entryPoint: "shipping_option",
|
||||
variables: {
|
||||
id: result[0].id,
|
||||
},
|
||||
fields: [
|
||||
"id",
|
||||
"name",
|
||||
"price_type",
|
||||
"service_zone_id",
|
||||
"shipping_profile_id",
|
||||
"provider_id",
|
||||
"data",
|
||||
"metadata",
|
||||
"type.*",
|
||||
"created_at",
|
||||
"updated_at",
|
||||
"deleted_at",
|
||||
"shipping_option_type_id",
|
||||
"prices.*",
|
||||
],
|
||||
})
|
||||
|
||||
const remoteQuery = container.resolve(ContainerRegistrationKeys.REMOTE_QUERY)
|
||||
|
||||
const [createdShippingOption] = await remoteQuery(remoteQueryObject)
|
||||
return {
|
||||
shippingOption: createdShippingOption,
|
||||
region,
|
||||
salesChannel,
|
||||
location,
|
||||
product,
|
||||
fulfillmentSet,
|
||||
}
|
||||
}
|
||||
|
||||
async function createOrderFixture({ container, product }) {
|
||||
const orderService: IOrderModuleService = container.resolve(
|
||||
ModuleRegistrationName.ORDER
|
||||
)
|
||||
let order = await orderService.createOrders({
|
||||
region_id: "test_region_idclear",
|
||||
email: "foo@bar.com",
|
||||
items: [
|
||||
{
|
||||
title: "Custom Item 2",
|
||||
variant_sku: product.variants[0].sku,
|
||||
variant_title: product.variants[0].title,
|
||||
quantity: 1,
|
||||
unit_price: 50,
|
||||
adjustments: [
|
||||
{
|
||||
code: "VIP_25 ETH",
|
||||
amount: "0.000000000000000005",
|
||||
description: "VIP discount",
|
||||
promotion_id: "prom_123",
|
||||
provider_id: "coupon_kings",
|
||||
},
|
||||
],
|
||||
} as any,
|
||||
],
|
||||
transactions: [
|
||||
{
|
||||
amount: 50,
|
||||
currency_code: "usd",
|
||||
},
|
||||
],
|
||||
sales_channel_id: "test",
|
||||
shipping_address: {
|
||||
first_name: "Test",
|
||||
last_name: "Test",
|
||||
address_1: "Test",
|
||||
city: "Test",
|
||||
country_code: "US",
|
||||
postal_code: "12345",
|
||||
phone: "12345",
|
||||
},
|
||||
billing_address: {
|
||||
first_name: "Test",
|
||||
last_name: "Test",
|
||||
address_1: "Test",
|
||||
city: "Test",
|
||||
country_code: "US",
|
||||
postal_code: "12345",
|
||||
},
|
||||
shipping_methods: [
|
||||
{
|
||||
name: "Test shipping method",
|
||||
amount: 10,
|
||||
data: {},
|
||||
tax_lines: [
|
||||
{
|
||||
description: "shipping Tax 1",
|
||||
tax_rate_id: "tax_usa_shipping",
|
||||
code: "code",
|
||||
rate: 10,
|
||||
},
|
||||
],
|
||||
adjustments: [
|
||||
{
|
||||
code: "VIP_10",
|
||||
amount: 1,
|
||||
description: "VIP discount",
|
||||
promotion_id: "prom_123",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
currency_code: "usd",
|
||||
customer_id: "joe",
|
||||
})
|
||||
|
||||
await orderService.addOrderAction([
|
||||
{
|
||||
action: "FULFILL_ITEM",
|
||||
order_id: order.id,
|
||||
version: order.version,
|
||||
reference: "fullfilment",
|
||||
reference_id: "fulfill_123",
|
||||
details: {
|
||||
reference_id: order.items![0].id,
|
||||
quantity: 1,
|
||||
},
|
||||
},
|
||||
{
|
||||
action: "SHIP_ITEM",
|
||||
order_id: order.id,
|
||||
version: order.version,
|
||||
reference: "fullfilment",
|
||||
reference_id: "fulfill_123",
|
||||
details: {
|
||||
reference_id: order.items![0].id,
|
||||
quantity: 1,
|
||||
},
|
||||
},
|
||||
])
|
||||
|
||||
await orderService.applyPendingOrderActions(order.id)
|
||||
|
||||
order = await orderService.retrieveOrder(order.id, {
|
||||
relations: ["items"],
|
||||
})
|
||||
|
||||
return order
|
||||
}
|
||||
|
||||
medusaIntegrationTestRunner({
|
||||
env,
|
||||
testSuite: ({ getContainer }) => {
|
||||
let container
|
||||
|
||||
beforeAll(() => {
|
||||
container = getContainer()
|
||||
})
|
||||
|
||||
describe("Begin return order workflow", () => {
|
||||
let product: ProductDTO
|
||||
|
||||
beforeEach(async () => {
|
||||
const fixtures = await prepareDataFixtures({
|
||||
container,
|
||||
})
|
||||
|
||||
product = fixtures.product
|
||||
})
|
||||
|
||||
it("should begin a return order", async () => {
|
||||
const order = await createOrderFixture({ container, product })
|
||||
|
||||
const createReturnOrderData: OrderWorkflow.beginOrderReturnWorkflowInput =
|
||||
{
|
||||
order_id: order.id,
|
||||
}
|
||||
|
||||
await beginReturnOrderWorkflow(container).run({
|
||||
input: createReturnOrderData,
|
||||
throwOnError: true,
|
||||
})
|
||||
|
||||
const remoteQuery = container.resolve(
|
||||
ContainerRegistrationKeys.REMOTE_QUERY
|
||||
)
|
||||
const remoteQueryObject = remoteQueryObjectFromString({
|
||||
entryPoint: "return",
|
||||
variables: {
|
||||
order_id: createReturnOrderData.order_id,
|
||||
},
|
||||
fields: ["order_id", "id", "status"],
|
||||
})
|
||||
|
||||
const [returnOrder] = await remoteQuery(remoteQueryObject)
|
||||
|
||||
expect(returnOrder.order_id).toEqual(order.id)
|
||||
expect(returnOrder.status).toEqual("requested")
|
||||
expect(returnOrder.id).toBeDefined()
|
||||
})
|
||||
})
|
||||
},
|
||||
})
|
||||
@@ -0,0 +1,32 @@
|
||||
import { CreateOrderClaimDTO, IOrderModuleService } from "@medusajs/types"
|
||||
import { ModuleRegistrationName } from "@medusajs/utils"
|
||||
import { StepResponse, createStep } from "@medusajs/workflows-sdk"
|
||||
|
||||
type CreateOrderClaimsStepInput = CreateOrderClaimDTO[]
|
||||
|
||||
export const createOrderClaimsStepId = "create-order-claims"
|
||||
export const createOrderClaimsStep = createStep(
|
||||
createOrderClaimsStepId,
|
||||
async (data: CreateOrderClaimsStepInput, { container }) => {
|
||||
const service = container.resolve<IOrderModuleService>(
|
||||
ModuleRegistrationName.ORDER
|
||||
)
|
||||
|
||||
const orderClaims = await service.createOrderClaims(data)
|
||||
|
||||
const claimIds = orderClaims.map((claim) => claim.id)
|
||||
|
||||
return new StepResponse(orderClaims, claimIds)
|
||||
},
|
||||
async (claimIds, { container }) => {
|
||||
if (!claimIds) {
|
||||
return
|
||||
}
|
||||
|
||||
const service = container.resolve<IOrderModuleService>(
|
||||
ModuleRegistrationName.ORDER
|
||||
)
|
||||
|
||||
await service.deleteOrderClaims(claimIds)
|
||||
}
|
||||
)
|
||||
+5
-5
@@ -2,12 +2,12 @@ import { CreateOrderReturnDTO, IOrderModuleService } from "@medusajs/types"
|
||||
import { ModuleRegistrationName } from "@medusajs/utils"
|
||||
import { StepResponse, createStep } from "@medusajs/workflows-sdk"
|
||||
|
||||
type CreateReturnStepInput = CreateOrderReturnDTO
|
||||
type CreateCompleteReturnStepInput = CreateOrderReturnDTO
|
||||
|
||||
export const createReturnStepId = "create-return"
|
||||
export const createReturnStep = createStep(
|
||||
createReturnStepId,
|
||||
async (data: CreateReturnStepInput, { container }) => {
|
||||
export const createCompleteReturnStepId = "create-complete-return"
|
||||
export const createCompleteReturnStep = createStep(
|
||||
createCompleteReturnStepId,
|
||||
async (data: CreateCompleteReturnStepInput, { container }) => {
|
||||
const service = container.resolve<IOrderModuleService>(
|
||||
ModuleRegistrationName.ORDER
|
||||
)
|
||||
@@ -0,0 +1,32 @@
|
||||
import { CreateOrderExchangeDTO, IOrderModuleService } from "@medusajs/types"
|
||||
import { ModuleRegistrationName } from "@medusajs/utils"
|
||||
import { StepResponse, createStep } from "@medusajs/workflows-sdk"
|
||||
|
||||
type CreateOrderExchangesStepInput = CreateOrderExchangeDTO[]
|
||||
|
||||
export const createOrderExchangesStepId = "create-order-exchanges"
|
||||
export const createOrderExchangesStep = createStep(
|
||||
createOrderExchangesStepId,
|
||||
async (data: CreateOrderExchangesStepInput, { container }) => {
|
||||
const service = container.resolve<IOrderModuleService>(
|
||||
ModuleRegistrationName.ORDER
|
||||
)
|
||||
|
||||
const orderExchanges = await service.createOrderExchanges(data)
|
||||
|
||||
const exchangeIds = orderExchanges.map((exchange) => exchange.id)
|
||||
|
||||
return new StepResponse(orderExchanges, exchangeIds)
|
||||
},
|
||||
async (exchangeIds, { container }) => {
|
||||
if (!exchangeIds) {
|
||||
return
|
||||
}
|
||||
|
||||
const service = container.resolve<IOrderModuleService>(
|
||||
ModuleRegistrationName.ORDER
|
||||
)
|
||||
|
||||
await service.deleteOrderExchanges(exchangeIds)
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,32 @@
|
||||
import { CreateOrderReturnDTO, IOrderModuleService } from "@medusajs/types"
|
||||
import { ModuleRegistrationName } from "@medusajs/utils"
|
||||
import { StepResponse, createStep } from "@medusajs/workflows-sdk"
|
||||
|
||||
type CreateReturnsStepInput = CreateOrderReturnDTO[]
|
||||
|
||||
export const createReturnsStepId = "create-returns"
|
||||
export const createReturnsStep = createStep(
|
||||
createReturnsStepId,
|
||||
async (data: CreateReturnsStepInput, { container }) => {
|
||||
const service = container.resolve<IOrderModuleService>(
|
||||
ModuleRegistrationName.ORDER
|
||||
)
|
||||
|
||||
const orderReturns = await service.createReturns(data)
|
||||
|
||||
const returnIds = orderReturns.map((ret) => ret.id)
|
||||
|
||||
return new StepResponse(orderReturns, returnIds)
|
||||
},
|
||||
async (returnIds, { container }) => {
|
||||
if (!returnIds) {
|
||||
return
|
||||
}
|
||||
|
||||
const service = container.resolve<IOrderModuleService>(
|
||||
ModuleRegistrationName.ORDER
|
||||
)
|
||||
|
||||
await service.deleteReturns(returnIds)
|
||||
}
|
||||
)
|
||||
@@ -5,9 +5,13 @@ export * from "./cancel-order-change"
|
||||
export * from "./cancel-orders"
|
||||
export * from "./cancel-return"
|
||||
export * from "./complete-orders"
|
||||
export * from "./create-claims"
|
||||
export * from "./create-complete-return"
|
||||
export * from "./create-exchanges"
|
||||
export * from "./create-order-change"
|
||||
export * from "./create-order-change-actions"
|
||||
export * from "./create-orders"
|
||||
export * from "./create-returns"
|
||||
export * from "./decline-order-change"
|
||||
export * from "./delete-order-change"
|
||||
export * from "./delete-order-change-actions"
|
||||
|
||||
@@ -18,7 +18,7 @@ export function throwIfItemsDoesNotExistsInOrder({
|
||||
inputItems: OrderWorkflow.CreateOrderFulfillmentWorkflowInput["items"]
|
||||
}) {
|
||||
const orderItemIds = order.items?.map((i) => i.id) ?? []
|
||||
const inputItemIds = inputItems.map((i) => i.id)
|
||||
const inputItemIds = inputItems?.map((i) => i.id)
|
||||
const diff = arrayDifference(inputItemIds, orderItemIds)
|
||||
|
||||
if (diff.length) {
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
import { OrderChangeDTO, OrderDTO, OrderWorkflow } from "@medusajs/types"
|
||||
import {
|
||||
WorkflowData,
|
||||
createStep,
|
||||
createWorkflow,
|
||||
transform,
|
||||
} from "@medusajs/workflows-sdk"
|
||||
import { useRemoteQueryStep } from "../../common"
|
||||
import { createOrderClaimsStep } from "../steps/create-claims"
|
||||
import { createOrderChangeStep } from "../steps/create-order-change"
|
||||
import { throwIfOrderIsCancelled } from "../utils/order-validation"
|
||||
|
||||
const validationStep = createStep(
|
||||
"begin-claim-order-validation",
|
||||
async function ({ order }: { order: OrderDTO }) {
|
||||
throwIfOrderIsCancelled({ order })
|
||||
}
|
||||
)
|
||||
|
||||
export const beginClaimOrderWorkflowId = "begin-claim-order"
|
||||
export const beginClaimOrderWorkflow = createWorkflow(
|
||||
beginClaimOrderWorkflowId,
|
||||
function (
|
||||
input: WorkflowData<OrderWorkflow.beginOrderClaimWorkflowInput>
|
||||
): WorkflowData<OrderChangeDTO> {
|
||||
const order: OrderDTO = useRemoteQueryStep({
|
||||
entry_point: "orders",
|
||||
fields: ["id", "status"],
|
||||
variables: { id: input.order_id },
|
||||
list: false,
|
||||
throw_if_key_not_found: true,
|
||||
})
|
||||
|
||||
validationStep({ order })
|
||||
|
||||
const created = createOrderClaimsStep([
|
||||
{
|
||||
type: input.type,
|
||||
order_id: input.order_id,
|
||||
metadata: input.metadata,
|
||||
},
|
||||
])
|
||||
|
||||
const orderChangeInput = transform(
|
||||
{ created, input },
|
||||
({ created, input }) => {
|
||||
return {
|
||||
change_type: "claim" as const,
|
||||
order_id: input.order_id,
|
||||
claim_id: created[0].id,
|
||||
created_by: input.created_by,
|
||||
description: input.description,
|
||||
internal_note: input.internal_note,
|
||||
}
|
||||
}
|
||||
)
|
||||
return createOrderChangeStep(orderChangeInput)
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,58 @@
|
||||
import { OrderChangeDTO, OrderDTO, OrderWorkflow } from "@medusajs/types"
|
||||
import {
|
||||
WorkflowData,
|
||||
createStep,
|
||||
createWorkflow,
|
||||
transform,
|
||||
} from "@medusajs/workflows-sdk"
|
||||
import { useRemoteQueryStep } from "../../common"
|
||||
import { createOrderExchangesStep } from "../steps/create-exchanges"
|
||||
import { createOrderChangeStep } from "../steps/create-order-change"
|
||||
import { throwIfOrderIsCancelled } from "../utils/order-validation"
|
||||
|
||||
const validationStep = createStep(
|
||||
"begin-exchange-order-validation",
|
||||
async function ({ order }: { order: OrderDTO }) {
|
||||
throwIfOrderIsCancelled({ order })
|
||||
}
|
||||
)
|
||||
|
||||
export const beginExchangeOrderWorkflowId = "begin-exchange-order"
|
||||
export const beginExchangeOrderWorkflow = createWorkflow(
|
||||
beginExchangeOrderWorkflowId,
|
||||
function (
|
||||
input: WorkflowData<OrderWorkflow.beginOrderExchangeWorkflowInput>
|
||||
): WorkflowData<OrderChangeDTO> {
|
||||
const order: OrderDTO = useRemoteQueryStep({
|
||||
entry_point: "orders",
|
||||
fields: ["id", "status"],
|
||||
variables: { id: input.order_id },
|
||||
list: false,
|
||||
throw_if_key_not_found: true,
|
||||
})
|
||||
|
||||
validationStep({ order })
|
||||
|
||||
const created = createOrderExchangesStep([
|
||||
{
|
||||
order_id: input.order_id,
|
||||
metadata: input.metadata,
|
||||
},
|
||||
])
|
||||
|
||||
const orderChangeInput = transform(
|
||||
{ created, input },
|
||||
({ created, input }) => {
|
||||
return {
|
||||
change_type: "exchange" as const,
|
||||
order_id: input.order_id,
|
||||
exchange_id: created[0].id,
|
||||
created_by: input.created_by,
|
||||
description: input.description,
|
||||
internal_note: input.internal_note,
|
||||
}
|
||||
}
|
||||
)
|
||||
return createOrderChangeStep(orderChangeInput)
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,58 @@
|
||||
import { OrderChangeDTO, OrderDTO, OrderWorkflow } from "@medusajs/types"
|
||||
import {
|
||||
WorkflowData,
|
||||
createStep,
|
||||
createWorkflow,
|
||||
transform,
|
||||
} from "@medusajs/workflows-sdk"
|
||||
import { useRemoteQueryStep } from "../../common"
|
||||
import { createOrderChangeStep } from "../steps/create-order-change"
|
||||
import { createReturnsStep } from "../steps/create-returns"
|
||||
import { throwIfOrderIsCancelled } from "../utils/order-validation"
|
||||
|
||||
const validationStep = createStep(
|
||||
"begin-return-order-validation",
|
||||
async function ({ order }: { order: OrderDTO }) {
|
||||
throwIfOrderIsCancelled({ order })
|
||||
}
|
||||
)
|
||||
|
||||
export const beginReturnOrderWorkflowId = "begin-return-order"
|
||||
export const beginReturnOrderWorkflow = createWorkflow(
|
||||
beginReturnOrderWorkflowId,
|
||||
function (
|
||||
input: WorkflowData<OrderWorkflow.beginOrderReturnWorkflowInput>
|
||||
): WorkflowData<OrderChangeDTO> {
|
||||
const order: OrderDTO = useRemoteQueryStep({
|
||||
entry_point: "orders",
|
||||
fields: ["id", "status"],
|
||||
variables: { id: input.order_id },
|
||||
list: false,
|
||||
throw_if_key_not_found: true,
|
||||
})
|
||||
|
||||
validationStep({ order })
|
||||
|
||||
const created = createReturnsStep([
|
||||
{
|
||||
order_id: input.order_id,
|
||||
metadata: input.metadata,
|
||||
},
|
||||
])
|
||||
|
||||
const orderChangeInput = transform(
|
||||
{ created, input },
|
||||
({ created, input }) => {
|
||||
return {
|
||||
change_type: "return" as const,
|
||||
order_id: input.order_id,
|
||||
return_id: created[0].id,
|
||||
created_by: input.created_by,
|
||||
description: input.description,
|
||||
internal_note: input.internal_note,
|
||||
}
|
||||
}
|
||||
)
|
||||
return createOrderChangeStep(orderChangeInput)
|
||||
}
|
||||
)
|
||||
@@ -25,7 +25,7 @@ import {
|
||||
} from "@medusajs/workflows-sdk"
|
||||
import { createRemoteLinkStep, useRemoteQueryStep } from "../../common"
|
||||
import { createReturnFulfillmentWorkflow } from "../../fulfillment"
|
||||
import { createReturnStep } from "../steps/create-return"
|
||||
import { createCompleteReturnStep } from "../steps/create-complete-return"
|
||||
import { receiveReturnStep } from "../steps/receive-return"
|
||||
import {
|
||||
throwIfItemsDoesNotExistsInOrder,
|
||||
@@ -273,6 +273,13 @@ const validationStep = createStep(
|
||||
},
|
||||
context
|
||||
) {
|
||||
if (!input.items) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
`Items are required to create a return.`
|
||||
)
|
||||
}
|
||||
|
||||
throwIfOrderIsCancelled({ order })
|
||||
throwIfItemsDoesNotExistsInOrder({ order, inputItems: input.items })
|
||||
await validateReturnReasons(
|
||||
@@ -359,7 +366,7 @@ export const createAndCompleteReturnOrderWorkflow = createWorkflow(
|
||||
)
|
||||
|
||||
const [returnCreated] = parallelize(
|
||||
createReturnStep({
|
||||
createCompleteReturnStep({
|
||||
order_id: input.order_id,
|
||||
items: input.items,
|
||||
shipping_method: shippingMethodData,
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
export * from "./archive-orders"
|
||||
export * from "./begin-order-claim"
|
||||
export * from "./begin-order-exchange"
|
||||
export * from "./begin-return"
|
||||
export * from "./cancel-order"
|
||||
export * from "./cancel-order-change"
|
||||
export * from "./cancel-order-fulfillment"
|
||||
|
||||
@@ -1609,13 +1609,39 @@ export interface FilterableOrderItemProps
|
||||
item_id?: string | string[] | OperatorMap<string>
|
||||
}
|
||||
|
||||
export interface FilterableOrderReturnReasonProps {
|
||||
export interface FilterableOrderReturnReasonProps
|
||||
extends BaseFilterable<FilterableOrderReturnReasonProps> {
|
||||
id?: string | string[]
|
||||
value?: string | string[]
|
||||
label?: string
|
||||
description?: string
|
||||
}
|
||||
|
||||
export interface FilterableReturnProps
|
||||
extends BaseFilterable<FilterableReturnProps> {
|
||||
id?: string | string[]
|
||||
order_id?: string | string[]
|
||||
claim_id?: string | string[]
|
||||
exchange_id?: string | string[]
|
||||
status?: string | string[]
|
||||
refund_amount?: string | string[]
|
||||
}
|
||||
|
||||
export interface FilterableOrderClaimProps
|
||||
extends BaseFilterable<FilterableOrderClaimProps> {
|
||||
id?: string | string[]
|
||||
order_id?: string | string[]
|
||||
return_id?: string | string[]
|
||||
}
|
||||
|
||||
export interface FilterableOrderExchangeProps
|
||||
extends BaseFilterable<FilterableOrderExchangeProps> {
|
||||
id?: string | string[]
|
||||
order_id?: string | string[]
|
||||
return_id?: string | string[]
|
||||
allow_backorder?: boolean
|
||||
}
|
||||
|
||||
export interface OrderChangeReturn {
|
||||
items: {
|
||||
item_id: string
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
import { BigNumberInput } from "../totals"
|
||||
import {
|
||||
ChangeActionType,
|
||||
OrderClaimDTO,
|
||||
OrderExchangeDTO,
|
||||
OrderItemDTO,
|
||||
OrderLineItemDTO,
|
||||
OrderReturnReasonDTO,
|
||||
OrderTransactionDTO,
|
||||
ReturnDTO,
|
||||
} from "./common"
|
||||
|
||||
/** ADDRESS START */
|
||||
@@ -256,6 +259,7 @@ export interface CreateOrderChangeDTO {
|
||||
return_id?: string
|
||||
claim_id?: string
|
||||
exchange_id?: string
|
||||
change_type?: "return" | "exchange" | "claim" | "edit"
|
||||
description?: string
|
||||
internal_note?: string | null
|
||||
requested_by?: string
|
||||
@@ -412,24 +416,64 @@ export interface CancelOrderFulfillmentDTO extends BaseOrderBundledActionsDTO {
|
||||
}
|
||||
|
||||
export interface RegisterOrderShipmentDTO extends BaseOrderBundledActionsDTO {
|
||||
items: BaseOrderBundledItemActionsDTO[]
|
||||
items?: BaseOrderBundledItemActionsDTO[]
|
||||
no_notification?: boolean
|
||||
}
|
||||
|
||||
export interface CreateOrderReturnDTO extends BaseOrderBundledActionsDTO {
|
||||
items: {
|
||||
items?: {
|
||||
id: string
|
||||
quantity: BigNumberInput
|
||||
internal_note?: string | null
|
||||
note?: string | null
|
||||
reason_id?: string | null
|
||||
metadata?: Record<string, any>
|
||||
metadata?: Record<string, unknown> | null
|
||||
}[]
|
||||
shipping_method?: Omit<CreateOrderShippingMethodDTO, "order_id"> | string
|
||||
refund_amount?: BigNumberInput
|
||||
no_notification?: boolean
|
||||
claim_id?: string
|
||||
exchange_id?: string
|
||||
}
|
||||
|
||||
export interface UpdateOrderReturnDTO {
|
||||
refund_amount?: BigNumberInput
|
||||
no_notification?: boolean
|
||||
claim_id?: string
|
||||
exchange_id?: string
|
||||
metadata?: Record<string, unknown> | null
|
||||
}
|
||||
|
||||
export interface UpdateOrderClaimDTO {
|
||||
refund_amount?: BigNumberInput
|
||||
no_notification?: boolean
|
||||
return_id?: string
|
||||
type?: OrderClaimType
|
||||
metadata?: Record<string, unknown> | null
|
||||
}
|
||||
|
||||
export interface UpdateOrderExchangeDTO {
|
||||
difference_due?: BigNumberInput
|
||||
no_notification?: boolean
|
||||
return_id?: string
|
||||
allow_backorder?: boolean
|
||||
metadata?: Record<string, unknown> | null
|
||||
}
|
||||
|
||||
export interface UpdateOrderReturnWithSelectorDTO {
|
||||
selector: Partial<ReturnDTO>
|
||||
data: Partial<UpdateOrderReturnDTO>
|
||||
}
|
||||
|
||||
export interface UpdateOrderClaimWithSelectorDTO {
|
||||
selector: Partial<OrderClaimDTO>
|
||||
data: Partial<UpdateOrderClaimDTO>
|
||||
}
|
||||
|
||||
export interface UpdateOrderExchangeWithSelectorDTO {
|
||||
selector: Partial<OrderExchangeDTO>
|
||||
data: Partial<UpdateOrderExchangeDTO>
|
||||
}
|
||||
export interface CancelOrderReturnDTO
|
||||
extends Omit<BaseOrderBundledActionsDTO, "order_id"> {
|
||||
return_id: string
|
||||
@@ -443,11 +487,11 @@ export type ClaimReason =
|
||||
| "other"
|
||||
export interface CreateOrderClaimDTO extends BaseOrderBundledActionsDTO {
|
||||
type: OrderClaimType
|
||||
claim_items: (BaseOrderBundledItemActionsDTO & {
|
||||
claim_items?: (BaseOrderBundledItemActionsDTO & {
|
||||
reason: ClaimReason
|
||||
images?: {
|
||||
url: string
|
||||
metadata?: Record<string, any>
|
||||
metadata?: Record<string, unknown> | null
|
||||
}[]
|
||||
})[]
|
||||
additional_items?: BaseOrderBundledItemActionsDTO[]
|
||||
|
||||
@@ -5,6 +5,8 @@ import { Context } from "../shared-context"
|
||||
import {
|
||||
FilterableOrderAddressProps,
|
||||
FilterableOrderChangeActionProps,
|
||||
FilterableOrderClaimProps,
|
||||
FilterableOrderExchangeProps,
|
||||
FilterableOrderLineItemAdjustmentProps,
|
||||
FilterableOrderLineItemProps,
|
||||
FilterableOrderLineItemTaxLineProps,
|
||||
@@ -14,6 +16,7 @@ import {
|
||||
FilterableOrderShippingMethodProps,
|
||||
FilterableOrderShippingMethodTaxLineProps,
|
||||
FilterableOrderTransactionProps,
|
||||
FilterableReturnProps,
|
||||
OrderAddressDTO,
|
||||
OrderChangeActionDTO,
|
||||
OrderChangeDTO,
|
||||
@@ -62,14 +65,20 @@ import {
|
||||
UpdateOrderAddressDTO,
|
||||
UpdateOrderChangeActionDTO,
|
||||
UpdateOrderChangeDTO,
|
||||
UpdateOrderClaimDTO,
|
||||
UpdateOrderClaimWithSelectorDTO,
|
||||
UpdateOrderDTO,
|
||||
UpdateOrderExchangeDTO,
|
||||
UpdateOrderExchangeWithSelectorDTO,
|
||||
UpdateOrderItemDTO,
|
||||
UpdateOrderItemWithSelectorDTO,
|
||||
UpdateOrderLineItemDTO,
|
||||
UpdateOrderLineItemTaxLineDTO,
|
||||
UpdateOrderLineItemWithSelectorDTO,
|
||||
UpdateOrderReturnDTO,
|
||||
UpdateOrderReturnReasonDTO,
|
||||
UpdateOrderReturnReasonWithSelectorDTO,
|
||||
UpdateOrderReturnWithSelectorDTO,
|
||||
UpdateOrderShippingMethodAdjustmentDTO,
|
||||
UpdateOrderShippingMethodTaxLineDTO,
|
||||
UpsertOrderLineItemAdjustmentDTO,
|
||||
@@ -1865,13 +1874,128 @@ export interface IOrderModuleService extends IModuleService {
|
||||
): Promise<void>
|
||||
|
||||
softDeleteReturnReasons<TReturnableLinkableKeys extends string = string>(
|
||||
storeIds: string[],
|
||||
ids: string[],
|
||||
config?: SoftDeleteReturn<TReturnableLinkableKeys>,
|
||||
sharedContext?: Context
|
||||
): Promise<Record<string, string[]> | void>
|
||||
|
||||
restoreReturnReasons<TReturnableLinkableKeys extends string = string>(
|
||||
storeIds: string[],
|
||||
ids: string[],
|
||||
config?: RestoreReturn<TReturnableLinkableKeys>,
|
||||
sharedContext?: Context
|
||||
): Promise<Record<string, string[]> | void>
|
||||
|
||||
createReturns(
|
||||
data: CreateOrderReturnDTO,
|
||||
sharedContext?: Context
|
||||
): Promise<ReturnDTO>
|
||||
|
||||
createReturns(
|
||||
data: CreateOrderReturnDTO[],
|
||||
sharedContext?: Context
|
||||
): Promise<ReturnDTO[]>
|
||||
|
||||
updateReturns(data: UpdateOrderReturnWithSelectorDTO[]): Promise<ReturnDTO[]>
|
||||
|
||||
updateReturns(
|
||||
selector: Partial<FilterableReturnProps>,
|
||||
data: Partial<UpdateOrderReturnDTO>,
|
||||
sharedContext?: Context
|
||||
): Promise<ReturnDTO[]>
|
||||
updateReturns(
|
||||
id: string,
|
||||
data: Partial<UpdateOrderReturnDTO>,
|
||||
sharedContext?: Context
|
||||
): Promise<ReturnDTO>
|
||||
|
||||
deleteReturns(ids: string[], sharedContext?: Context): Promise<void>
|
||||
|
||||
softDeleteReturns<TReturnableLinkableKeys extends string = string>(
|
||||
ids: string[],
|
||||
config?: SoftDeleteReturn<TReturnableLinkableKeys>,
|
||||
sharedContext?: Context
|
||||
): Promise<Record<string, string[]> | void>
|
||||
|
||||
restoreReturns<TReturnableLinkableKeys extends string = string>(
|
||||
ids: string[],
|
||||
config?: RestoreReturn<TReturnableLinkableKeys>,
|
||||
sharedContext?: Context
|
||||
): Promise<Record<string, string[]> | void>
|
||||
|
||||
createOrderClaims(
|
||||
data: CreateOrderClaimDTO,
|
||||
sharedContext?: Context
|
||||
): Promise<OrderClaimDTO>
|
||||
|
||||
createOrderClaims(
|
||||
data: CreateOrderClaimDTO[],
|
||||
sharedContext?: Context
|
||||
): Promise<OrderClaimDTO[]>
|
||||
|
||||
updateOrderClaims(
|
||||
data: UpdateOrderClaimWithSelectorDTO[]
|
||||
): Promise<OrderClaimDTO[]>
|
||||
|
||||
updateOrderClaims(
|
||||
selector: Partial<FilterableOrderClaimProps>,
|
||||
data: Partial<UpdateOrderClaimDTO>,
|
||||
sharedContext?: Context
|
||||
): Promise<OrderClaimDTO[]>
|
||||
updateOrderClaims(
|
||||
id: string,
|
||||
data: Partial<UpdateOrderClaimDTO>,
|
||||
sharedContext?: Context
|
||||
): Promise<OrderClaimDTO>
|
||||
|
||||
deleteOrderClaims(ids: string[], sharedContext?: Context): Promise<void>
|
||||
|
||||
softDeleteOrderClaims<TReturnableLinkableKeys extends string = string>(
|
||||
ids: string[],
|
||||
config?: SoftDeleteReturn<TReturnableLinkableKeys>,
|
||||
sharedContext?: Context
|
||||
): Promise<Record<string, string[]> | void>
|
||||
|
||||
restoreOrderClaims<TReturnableLinkableKeys extends string = string>(
|
||||
ids: string[],
|
||||
config?: RestoreReturn<TReturnableLinkableKeys>,
|
||||
sharedContext?: Context
|
||||
): Promise<Record<string, string[]> | void>
|
||||
|
||||
createOrderExchanges(
|
||||
data: CreateOrderExchangeDTO,
|
||||
sharedContext?: Context
|
||||
): Promise<OrderExchangeDTO>
|
||||
|
||||
createOrderExchanges(
|
||||
data: CreateOrderExchangeDTO[],
|
||||
sharedContext?: Context
|
||||
): Promise<OrderExchangeDTO[]>
|
||||
|
||||
updateOrderExchanges(
|
||||
data: UpdateOrderExchangeWithSelectorDTO[]
|
||||
): Promise<OrderExchangeDTO[]>
|
||||
|
||||
updateOrderExchanges(
|
||||
selector: Partial<FilterableOrderExchangeProps>,
|
||||
data: Partial<UpdateOrderExchangeDTO>,
|
||||
sharedContext?: Context
|
||||
): Promise<OrderExchangeDTO[]>
|
||||
updateOrderExchanges(
|
||||
id: string,
|
||||
data: Partial<UpdateOrderExchangeDTO>,
|
||||
sharedContext?: Context
|
||||
): Promise<OrderExchangeDTO>
|
||||
|
||||
deleteOrderExchanges(ids: string[], sharedContext?: Context): Promise<void>
|
||||
|
||||
softDeleteOrderExchanges<TReturnableLinkableKeys extends string = string>(
|
||||
ids: string[],
|
||||
config?: SoftDeleteReturn<TReturnableLinkableKeys>,
|
||||
sharedContext?: Context
|
||||
): Promise<Record<string, string[]> | void>
|
||||
|
||||
restoreOrderExchanges<TReturnableLinkableKeys extends string = string>(
|
||||
ids: string[],
|
||||
config?: RestoreReturn<TReturnableLinkableKeys>,
|
||||
sharedContext?: Context
|
||||
): Promise<Record<string, string[]> | void>
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
import { OrderClaimType } from "../../order/mutations"
|
||||
|
||||
export interface beginOrderClaimWorkflowInput {
|
||||
type: OrderClaimType
|
||||
order_id: string
|
||||
created_by?: string
|
||||
internal_note?: string
|
||||
description?: string
|
||||
metadata?: Record<string, unknown> | null
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
export interface beginOrderExchangeWorkflowInput {
|
||||
order_id: string
|
||||
created_by?: string
|
||||
internal_note?: string
|
||||
description?: string
|
||||
metadata?: Record<string, unknown> | null
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
export interface beginOrderReturnWorkflowInput {
|
||||
order_id: string
|
||||
created_by?: string
|
||||
internal_note?: string
|
||||
description?: string
|
||||
metadata?: Record<string, unknown> | null
|
||||
}
|
||||
@@ -1,3 +1,6 @@
|
||||
export * from "./begin-claim-order"
|
||||
export * from "./begin-exchange-order"
|
||||
export * from "./begin-return-order"
|
||||
export * from "./cancel-claim"
|
||||
export * from "./cancel-exchange"
|
||||
export * from "./cancel-fulfillment"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { createAndCompleteReturnOrderWorkflow } from "@medusajs/core-flows"
|
||||
import { beginReturnOrderWorkflow } from "@medusajs/core-flows"
|
||||
import {
|
||||
ContainerRegistrationKeys,
|
||||
remoteQueryObjectFromString,
|
||||
@@ -42,7 +42,7 @@ export const POST = async (
|
||||
) => {
|
||||
const input = req.validatedBody as AdminPostReturnsReqSchemaType
|
||||
|
||||
const workflow = createAndCompleteReturnOrderWorkflow(req.scope)
|
||||
const workflow = beginReturnOrderWorkflow(req.scope)
|
||||
const { result } = await workflow.run({
|
||||
input,
|
||||
})
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { ClaimType } from "@medusajs/utils"
|
||||
import { z } from "zod"
|
||||
import {
|
||||
createFindParams,
|
||||
@@ -37,31 +38,44 @@ export const AdminGetOrdersParams = createFindParams({
|
||||
|
||||
export type AdminGetOrdersParamsType = z.infer<typeof AdminGetOrdersParams>
|
||||
|
||||
const ReturnShippingSchema = z.object({
|
||||
option_id: z.string(),
|
||||
price: z.number().optional(),
|
||||
})
|
||||
|
||||
const ItemSchema = z.object({
|
||||
id: z.string(),
|
||||
quantity: z.number().min(1),
|
||||
reason_id: z.string().nullish(),
|
||||
note: z.string().nullish(),
|
||||
note: z.string().optional(),
|
||||
})
|
||||
|
||||
export const AdminPostReturnsReqSchema = z.object({
|
||||
order_id: z.string(),
|
||||
items: z.array(ItemSchema),
|
||||
return_shipping: ReturnShippingSchema.optional(),
|
||||
internal_note: z.string().nullish(),
|
||||
receive_now: z.boolean().optional(),
|
||||
refund_amount: z.number().optional(),
|
||||
location_id: z.string().nullish(),
|
||||
description: z.string().optional(),
|
||||
internal_note: z.string().optional(),
|
||||
metadata: z.record(z.unknown()).nullish(),
|
||||
})
|
||||
export type AdminPostReturnsReqSchemaType = z.infer<
|
||||
typeof AdminPostReturnsReqSchema
|
||||
>
|
||||
|
||||
export const AdminPostOrderClaimsReqSchema = z.object({
|
||||
type: z.nativeEnum(ClaimType),
|
||||
order_id: z.string(),
|
||||
description: z.string().optional(),
|
||||
internal_note: z.string().optional(),
|
||||
metadata: z.record(z.unknown()).nullish(),
|
||||
})
|
||||
export type AdminPostOrderClaimsReqSchemaType = z.infer<
|
||||
typeof AdminPostOrderClaimsReqSchema
|
||||
>
|
||||
|
||||
export const AdminPostOrderExchangesReqSchema = z.object({
|
||||
order_id: z.string(),
|
||||
description: z.string().optional(),
|
||||
internal_note: z.string().optional(),
|
||||
metadata: z.record(z.unknown()).nullish(),
|
||||
})
|
||||
export type AdminPostOrderExchangesReqSchemaType = z.infer<
|
||||
typeof AdminPostOrderExchangesReqSchema
|
||||
>
|
||||
|
||||
export const AdminPostReceiveReturnsReqSchema = z.object({
|
||||
return_id: z.string(),
|
||||
items: z.array(ItemSchema),
|
||||
|
||||
@@ -12,7 +12,7 @@ export async function registerShipment(
|
||||
): Promise<void> {
|
||||
let shippingMethodId
|
||||
|
||||
const actions: CreateOrderChangeActionDTO[] = data.items.map((item) => {
|
||||
const actions: CreateOrderChangeActionDTO[] = data.items!.map((item) => {
|
||||
return {
|
||||
action: ChangeActionType.SHIP_ITEM,
|
||||
internal_note: item.internal_note,
|
||||
|
||||
@@ -1718,6 +1718,134 @@ export default class OrderModuleService<
|
||||
})
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
async createReturns(
|
||||
data: OrderTypes.CreateOrderReturnDTO,
|
||||
sharedContext?: Context
|
||||
): Promise<OrderTypes.ReturnDTO>
|
||||
|
||||
async createReturns(
|
||||
data: OrderTypes.CreateOrderReturnDTO[],
|
||||
sharedContext?: Context
|
||||
): Promise<OrderTypes.ReturnDTO[]>
|
||||
|
||||
@InjectTransactionManager("baseRepository_")
|
||||
async createReturns(
|
||||
data: OrderTypes.CreateOrderReturnDTO | OrderTypes.CreateOrderReturnDTO[],
|
||||
@MedusaContext() sharedContext?: Context
|
||||
): Promise<OrderTypes.ReturnDTO | OrderTypes.ReturnDTO[]> {
|
||||
const created = await this.createOrderRelatedEntity_(
|
||||
data,
|
||||
this.returnService_,
|
||||
sharedContext
|
||||
)
|
||||
|
||||
return await this.baseRepository_.serialize<OrderTypes.ReturnDTO>(
|
||||
!Array.isArray(data) ? created[0] : created,
|
||||
{
|
||||
populate: true,
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
async createOrderClaims(
|
||||
data: OrderTypes.CreateOrderClaimDTO,
|
||||
sharedContext?: Context
|
||||
): Promise<OrderTypes.OrderClaimDTO>
|
||||
|
||||
async createOrderClaims(
|
||||
data: OrderTypes.CreateOrderClaimDTO[],
|
||||
sharedContext?: Context
|
||||
): Promise<OrderTypes.OrderClaimDTO[]>
|
||||
|
||||
@InjectTransactionManager("baseRepository_")
|
||||
async createOrderClaims(
|
||||
data: OrderTypes.CreateOrderClaimDTO | OrderTypes.CreateOrderClaimDTO[],
|
||||
@MedusaContext() sharedContext?: Context
|
||||
): Promise<OrderTypes.OrderClaimDTO | OrderTypes.OrderClaimDTO[]> {
|
||||
const created = await this.createOrderRelatedEntity_(
|
||||
data,
|
||||
this.orderClaimService_,
|
||||
sharedContext
|
||||
)
|
||||
|
||||
return await this.baseRepository_.serialize<OrderTypes.OrderClaimDTO>(
|
||||
!Array.isArray(data) ? created[0] : created,
|
||||
{
|
||||
populate: true,
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
async createOrderExchanges(
|
||||
data: OrderTypes.CreateOrderExchangeDTO,
|
||||
sharedContext?: Context
|
||||
): Promise<OrderTypes.OrderExchangeDTO>
|
||||
|
||||
async createOrderExchanges(
|
||||
data: OrderTypes.CreateOrderExchangeDTO[],
|
||||
sharedContext?: Context
|
||||
): Promise<OrderTypes.OrderExchangeDTO[]>
|
||||
|
||||
@InjectTransactionManager("baseRepository_")
|
||||
async createOrderExchanges(
|
||||
data:
|
||||
| OrderTypes.CreateOrderExchangeDTO
|
||||
| OrderTypes.CreateOrderExchangeDTO[],
|
||||
@MedusaContext() sharedContext?: Context
|
||||
): Promise<OrderTypes.OrderExchangeDTO | OrderTypes.OrderExchangeDTO[]> {
|
||||
const created = await this.createOrderRelatedEntity_(
|
||||
data,
|
||||
this.orderExchangeService_,
|
||||
sharedContext
|
||||
)
|
||||
|
||||
return await this.baseRepository_.serialize<OrderTypes.OrderExchangeDTO>(
|
||||
!Array.isArray(data) ? created[0] : created,
|
||||
{
|
||||
populate: true,
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
@InjectTransactionManager("baseRepository_")
|
||||
private async createOrderRelatedEntity_(
|
||||
data: any,
|
||||
service: any,
|
||||
sharedContext?: Context
|
||||
) {
|
||||
const data_ = Array.isArray(data) ? data : [data]
|
||||
|
||||
const inputDataMap = data_.reduce((acc, curr) => {
|
||||
acc[curr.order_id] = curr
|
||||
return acc
|
||||
}, {})
|
||||
|
||||
const orderIds = data_.map((d) => d.order_id)
|
||||
const orders = await this.orderService_.list(
|
||||
{ id: orderIds },
|
||||
{ select: ["id", "version"] },
|
||||
sharedContext
|
||||
)
|
||||
|
||||
if (orders.length !== orderIds.length) {
|
||||
const foundOrders = orders.map((o) => o.id)
|
||||
const missing = orderIds.filter((id) => !foundOrders.includes(id))
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
`Order could not be found: ${missing.join(", ")}`
|
||||
)
|
||||
}
|
||||
|
||||
for (const order of orders) {
|
||||
inputDataMap[order.id].order_version = order.version
|
||||
}
|
||||
|
||||
return await service.create(data_, sharedContext)
|
||||
}
|
||||
|
||||
async createOrderChange(
|
||||
data: CreateOrderChangeDTO,
|
||||
sharedContext?: Context
|
||||
@@ -1770,7 +1898,7 @@ export default class OrderModuleService<
|
||||
dataMap[change.order_id] = change
|
||||
}
|
||||
|
||||
const orders = await this.listOrders(
|
||||
const orders = await this.orderService_.list(
|
||||
{ id: orderIds },
|
||||
{ select: ["id", "version"] },
|
||||
sharedContext
|
||||
@@ -2013,7 +2141,7 @@ export default class OrderModuleService<
|
||||
): Promise<OrderTypes.OrderChangeReturn> {
|
||||
const orderIds = Array.isArray(orderId) ? orderId : [orderId]
|
||||
|
||||
const orders = await this.listOrders(
|
||||
const orders = await this.orderService_.list(
|
||||
{ id: orderIds },
|
||||
{
|
||||
select: ["id", "version"],
|
||||
|
||||
Reference in New Issue
Block a user