feat(core-flows, types): calculated shipping in RMA flows (#11533)
* wip: calculated SO pricing in RMA flows * fix: types * chore: small refactor * feat: caluclated shipping in return flow * fix: module integrations * fix: array containing * feat: refresh shipping on update item quantity * rm: log * rm: log2 * feat: update interface, remove flag * fix: revert change on OE for now * fix: import * feat: refactor flwos, cleanup cacluation cotext data model, wip exchanges * feat: refreshing inbound/outbound shipping on items change * feat: refresh exchange shipping on return item add, test * feat: refresh shipping on exchange/return item remove * fix: check optional * feat: test recalculation on quantity update * feat: calculated shipping on claims * fix: comment * wip: address comments * fix: more remote query, fix build * refactor: claim refresh workflow * fix: remove throw option * fix: deconstruct param --------- Co-authored-by: Oli Juhl <59018053+olivermrbl@users.noreply.github.com>
This commit is contained in:
@@ -33,9 +33,15 @@ medusaIntegrationTestRunner({
|
||||
)
|
||||
|
||||
expect(response.status).toEqual(200)
|
||||
expect(response.data.fulfillment_providers).toEqual([
|
||||
{ id: "manual_test-provider", is_enabled: true },
|
||||
])
|
||||
expect(response.data.fulfillment_providers).toEqual(
|
||||
expect.arrayContaining([
|
||||
{ id: "manual_test-provider", is_enabled: true },
|
||||
{
|
||||
id: "manual-calculated_test-provider-calculated",
|
||||
is_enabled: true,
|
||||
},
|
||||
])
|
||||
)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
@@ -13,14 +13,22 @@ import {
|
||||
} from "@medusajs/utils"
|
||||
|
||||
const providerId = "manual_test-provider"
|
||||
const providerIdCalculated = "manual-calculated_test-provider-calculated"
|
||||
|
||||
export async function prepareDataFixtures({ container }) {
|
||||
const fulfillmentService = container.resolve(Modules.FULFILLMENT)
|
||||
const salesChannelService = container.resolve(Modules.SALES_CHANNEL)
|
||||
const stockLocationModule: IStockLocationService = container.resolve(
|
||||
Modules.STOCK_LOCATION
|
||||
)
|
||||
const pricingModule = container.resolve(Modules.PRICING)
|
||||
const productModule = container.resolve(Modules.PRODUCT)
|
||||
const inventoryModule = container.resolve(Modules.INVENTORY)
|
||||
const customerService = container.resolve(Modules.CUSTOMER)
|
||||
|
||||
const customer = await customerService.createCustomers({
|
||||
email: "foo@bar.com",
|
||||
})
|
||||
|
||||
const shippingProfile = await fulfillmentService.createShippingProfiles({
|
||||
name: "test",
|
||||
@@ -71,6 +79,18 @@ export async function prepareDataFixtures({ container }) {
|
||||
},
|
||||
})
|
||||
|
||||
const priceSets = await pricingModule.createPriceSets([
|
||||
{
|
||||
prices: [
|
||||
{
|
||||
amount: 10,
|
||||
region_id: region.id,
|
||||
currency_code: "usd",
|
||||
},
|
||||
],
|
||||
},
|
||||
])
|
||||
|
||||
const [product] = await productModule.createProducts([
|
||||
{
|
||||
title: "Test product",
|
||||
@@ -91,7 +111,7 @@ export async function prepareDataFixtures({ container }) {
|
||||
{
|
||||
inventory_item_id: inventoryItem.id,
|
||||
location_id: location.id,
|
||||
stocked_quantity: 2,
|
||||
stocked_quantity: 10,
|
||||
reserved_quantity: 0,
|
||||
},
|
||||
])
|
||||
@@ -123,6 +143,14 @@ export async function prepareDataFixtures({ container }) {
|
||||
inventory_item_id: inventoryItem.id,
|
||||
},
|
||||
},
|
||||
{
|
||||
[Modules.PRODUCT]: {
|
||||
variant_id: product.variants[0].id,
|
||||
},
|
||||
[Modules.PRICING]: {
|
||||
price_set_id: priceSets[0].id,
|
||||
},
|
||||
},
|
||||
])
|
||||
|
||||
await remoteLink.create([
|
||||
@@ -131,7 +159,16 @@ export async function prepareDataFixtures({ container }) {
|
||||
stock_location_id: location.id,
|
||||
},
|
||||
[Modules.FULFILLMENT]: {
|
||||
fulfillment_provider_id: "manual_test-provider",
|
||||
fulfillment_provider_id: providerId,
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
[Modules.STOCK_LOCATION]: {
|
||||
stock_location_id: location.id,
|
||||
},
|
||||
[Modules.FULFILLMENT]: {
|
||||
fulfillment_provider_id: providerIdCalculated,
|
||||
},
|
||||
},
|
||||
])
|
||||
@@ -160,14 +197,29 @@ export async function prepareDataFixtures({ container }) {
|
||||
],
|
||||
}
|
||||
|
||||
const shippingOptionCalculatedData: FulfillmentWorkflow.CreateShippingOptionsWorkflowInput =
|
||||
{
|
||||
name: "Calculated shipping option",
|
||||
service_zone_id: serviceZone.id,
|
||||
shipping_profile_id: shippingProfile.id,
|
||||
provider_id: providerIdCalculated,
|
||||
price_type: "calculated",
|
||||
type: {
|
||||
label: "Test type",
|
||||
description: "Test description",
|
||||
code: "test-code",
|
||||
},
|
||||
rules: [],
|
||||
}
|
||||
|
||||
const { result } = await createShippingOptionsWorkflow(container).run({
|
||||
input: [shippingOptionData],
|
||||
input: [shippingOptionData, shippingOptionCalculatedData],
|
||||
})
|
||||
|
||||
const remoteQueryObject = remoteQueryObjectFromString({
|
||||
entryPoint: "shipping_option",
|
||||
variables: {
|
||||
id: result[0].id,
|
||||
id: result.map((r) => r.id),
|
||||
},
|
||||
fields: [
|
||||
"id",
|
||||
@@ -189,13 +241,17 @@ export async function prepareDataFixtures({ container }) {
|
||||
|
||||
const remoteQuery = container.resolve(ContainerRegistrationKeys.REMOTE_QUERY)
|
||||
|
||||
const [createdShippingOption] = await remoteQuery(remoteQueryObject)
|
||||
const shippingOptions = await remoteQuery(remoteQueryObject)
|
||||
return {
|
||||
shippingOption: createdShippingOption,
|
||||
shippingOption: shippingOptions.find((s) => s.price_type === "flat"),
|
||||
shippingOptionCalculated: shippingOptions.find(
|
||||
(s) => s.price_type === "calculated"
|
||||
),
|
||||
region,
|
||||
salesChannel,
|
||||
location,
|
||||
product,
|
||||
customer,
|
||||
inventoryItem,
|
||||
}
|
||||
}
|
||||
@@ -205,18 +261,31 @@ export async function createOrderFixture({
|
||||
product,
|
||||
location,
|
||||
inventoryItem,
|
||||
region,
|
||||
salesChannel,
|
||||
customer,
|
||||
overrides,
|
||||
}: {
|
||||
container: any
|
||||
product: any
|
||||
location: any
|
||||
inventoryItem: any
|
||||
salesChannel?: any
|
||||
customer?: any
|
||||
region?: any
|
||||
overrides?: { quantity?: number }
|
||||
}) {
|
||||
const orderService: IOrderModuleService = container.resolve(Modules.ORDER)
|
||||
|
||||
let order = await orderService.createOrders({
|
||||
region_id: "test_region_id",
|
||||
email: "foo@bar.com",
|
||||
region_id: region?.id || "test_region_id",
|
||||
email: customer?.email || "foo@bar.com",
|
||||
items: [
|
||||
{
|
||||
title: "Custom Item 2",
|
||||
variant_sku: product.variants[0].sku,
|
||||
variant_title: product.variants[0].title,
|
||||
quantity: 1,
|
||||
quantity: overrides?.quantity ?? 1,
|
||||
unit_price: 50,
|
||||
adjustments: [
|
||||
{
|
||||
@@ -235,7 +304,7 @@ export async function createOrderFixture({
|
||||
currency_code: "usd",
|
||||
},
|
||||
],
|
||||
sales_channel_id: "test",
|
||||
sales_channel_id: salesChannel?.id || "test",
|
||||
shipping_address: {
|
||||
first_name: "Test",
|
||||
last_name: "Test",
|
||||
@@ -277,7 +346,7 @@ export async function createOrderFixture({
|
||||
},
|
||||
],
|
||||
currency_code: "usd",
|
||||
customer_id: "joe",
|
||||
customer_id: customer?.id || "joe",
|
||||
})
|
||||
|
||||
const inventoryModule = container.resolve(Modules.INVENTORY)
|
||||
|
||||
@@ -0,0 +1,212 @@
|
||||
import {
|
||||
beginClaimOrderWorkflow,
|
||||
createClaimShippingMethodWorkflow,
|
||||
createOrderFulfillmentWorkflow,
|
||||
orderClaimAddNewItemWorkflow,
|
||||
orderClaimRequestItemReturnWorkflow,
|
||||
updateClaimAddItemWorkflow,
|
||||
} from "@medusajs/core-flows"
|
||||
import { IFulfillmentModuleService, OrderDTO } from "@medusajs/types"
|
||||
import {
|
||||
ContainerRegistrationKeys,
|
||||
Modules,
|
||||
remoteQueryObjectFromString,
|
||||
} from "@medusajs/utils"
|
||||
import { medusaIntegrationTestRunner } from "@medusajs/test-utils"
|
||||
import { createOrderFixture, prepareDataFixtures } from "../__fixtures__"
|
||||
jest.setTimeout(50000)
|
||||
|
||||
medusaIntegrationTestRunner({
|
||||
env: { MEDUSA_FF_MEDUSA_V2: true },
|
||||
testSuite: ({ getContainer }) => {
|
||||
let container
|
||||
|
||||
beforeAll(() => {
|
||||
container = getContainer()
|
||||
})
|
||||
|
||||
describe("Order change: Claim shipping", () => {
|
||||
let order: OrderDTO
|
||||
let service: IFulfillmentModuleService
|
||||
let fixtures
|
||||
|
||||
let claimOrder: OrderDTO
|
||||
|
||||
beforeEach(async () => {
|
||||
fixtures = await prepareDataFixtures({ container })
|
||||
|
||||
order = await createOrderFixture({
|
||||
container,
|
||||
product: fixtures.product,
|
||||
location: fixtures.location,
|
||||
inventoryItem: fixtures.inventoryItem,
|
||||
salesChannel: fixtures.salesChannel,
|
||||
customer: fixtures.customer,
|
||||
region: fixtures.region,
|
||||
overrides: { quantity: 2 },
|
||||
})
|
||||
|
||||
await createOrderFulfillmentWorkflow(container).run({
|
||||
input: {
|
||||
order_id: order.id,
|
||||
items: [
|
||||
{
|
||||
quantity: 2,
|
||||
id: order.items![0].id,
|
||||
},
|
||||
],
|
||||
},
|
||||
})
|
||||
|
||||
await beginClaimOrderWorkflow(container).run({
|
||||
input: { order_id: order.id, type: "replace" },
|
||||
throwOnError: true,
|
||||
})
|
||||
|
||||
const remoteQuery = container.resolve(
|
||||
ContainerRegistrationKeys.REMOTE_QUERY
|
||||
)
|
||||
|
||||
const remoteQueryObject = remoteQueryObjectFromString({
|
||||
entryPoint: "order_claim",
|
||||
variables: { order_id: order.id },
|
||||
fields: ["order_id", "id", "status", "order_change_id"],
|
||||
})
|
||||
|
||||
service = container.resolve(Modules.FULFILLMENT)
|
||||
;[claimOrder] = await remoteQuery(remoteQueryObject)
|
||||
})
|
||||
|
||||
describe("createClaimShippingMethodWorkflow", () => {
|
||||
it("should successfully add caluclated inbound and outbound shipping to order changes", async () => {
|
||||
const { result } = await orderClaimAddNewItemWorkflow(container).run({
|
||||
input: {
|
||||
claim_id: claimOrder.id,
|
||||
items: [
|
||||
{
|
||||
variant_id: fixtures.product.variants[0].id,
|
||||
quantity: 1,
|
||||
internal_note: "test",
|
||||
},
|
||||
],
|
||||
},
|
||||
})
|
||||
|
||||
const shippingOptionId = fixtures.shippingOptionCalculated.id
|
||||
|
||||
const { result: orderChangePreview } =
|
||||
await createClaimShippingMethodWorkflow(container).run({
|
||||
input: {
|
||||
claim_id: claimOrder.id,
|
||||
shipping_option_id: shippingOptionId,
|
||||
},
|
||||
})
|
||||
|
||||
// Original shipping + outbound
|
||||
expect(orderChangePreview.shipping_methods).toHaveLength(2)
|
||||
|
||||
const outboundShippingMethod =
|
||||
orderChangePreview.shipping_methods?.find(
|
||||
(sm) => sm.shipping_option_id === shippingOptionId
|
||||
)
|
||||
|
||||
expect((outboundShippingMethod as any).actions).toEqual([
|
||||
expect.objectContaining({
|
||||
id: expect.any(String),
|
||||
reference: "order_shipping_method",
|
||||
reference_id: expect.any(String),
|
||||
raw_amount: { value: "2.5", precision: 20 },
|
||||
return_id: null,
|
||||
claim_id: claimOrder.id,
|
||||
applied: false,
|
||||
action: "SHIPPING_ADD",
|
||||
amount: 2.5,
|
||||
}),
|
||||
])
|
||||
|
||||
const { result: orderChangePreview2 } =
|
||||
await orderClaimRequestItemReturnWorkflow.run({
|
||||
container,
|
||||
input: {
|
||||
claim_id: claimOrder.id,
|
||||
items: [
|
||||
{
|
||||
id: result.items[0].id,
|
||||
quantity: 1,
|
||||
},
|
||||
],
|
||||
},
|
||||
})
|
||||
|
||||
const associatedReturnId = orderChangePreview2.order_change.return_id
|
||||
|
||||
const { result: orderChangePreview3 } =
|
||||
await createClaimShippingMethodWorkflow(container).run({
|
||||
input: {
|
||||
claim_id: claimOrder.id,
|
||||
return_id: associatedReturnId,
|
||||
shipping_option_id: shippingOptionId,
|
||||
},
|
||||
})
|
||||
|
||||
expect(orderChangePreview3.shipping_methods).toHaveLength(3)
|
||||
|
||||
const inboundShippingMethod =
|
||||
orderChangePreview3.shipping_methods?.find(
|
||||
(sm) =>
|
||||
sm.shipping_option_id === shippingOptionId &&
|
||||
sm.actions?.find(
|
||||
(a) =>
|
||||
a.action === "SHIPPING_ADD" &&
|
||||
a.return_id === associatedReturnId
|
||||
)
|
||||
)
|
||||
|
||||
expect(inboundShippingMethod!.actions![0]).toEqual(
|
||||
expect.objectContaining({
|
||||
return_id: associatedReturnId,
|
||||
claim_id: claimOrder.id,
|
||||
applied: false,
|
||||
action: "SHIPPING_ADD",
|
||||
amount: 2,
|
||||
})
|
||||
)
|
||||
|
||||
// Update outbound quantity to test refresh caluclation
|
||||
|
||||
const { result: orderChangePreview4 } =
|
||||
await updateClaimAddItemWorkflow(container).run({
|
||||
input: {
|
||||
claim_id: claimOrder.id,
|
||||
action_id: result.items.find(
|
||||
(i) => i.variant_id === fixtures.product.variants[0].id
|
||||
)?.actions?.[0]?.id as string,
|
||||
data: {
|
||||
quantity: 2,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
const outboundShippingMethod2 =
|
||||
orderChangePreview4.shipping_methods?.find(
|
||||
(sm) => sm.shipping_option_id === shippingOptionId
|
||||
)
|
||||
|
||||
expect((outboundShippingMethod2 as any).actions).toEqual([
|
||||
expect.objectContaining({
|
||||
id: expect.any(String),
|
||||
reference: "order_shipping_method",
|
||||
reference_id: expect.any(String),
|
||||
raw_amount: { value: "5", precision: 20 },
|
||||
return_id: null,
|
||||
claim_id: claimOrder.id,
|
||||
applied: false,
|
||||
action: "SHIPPING_ADD",
|
||||
amount: 5,
|
||||
}),
|
||||
])
|
||||
})
|
||||
})
|
||||
})
|
||||
},
|
||||
})
|
||||
@@ -0,0 +1,214 @@
|
||||
import {
|
||||
beginExchangeOrderWorkflow,
|
||||
createExchangeShippingMethodWorkflow,
|
||||
createOrderFulfillmentWorkflow,
|
||||
orderExchangeAddNewItemWorkflow,
|
||||
orderExchangeRequestItemReturnWorkflow,
|
||||
updateExchangeAddItemWorkflow,
|
||||
} from "@medusajs/core-flows"
|
||||
import { IFulfillmentModuleService, OrderDTO } from "@medusajs/types"
|
||||
import {
|
||||
ContainerRegistrationKeys,
|
||||
Modules,
|
||||
remoteQueryObjectFromString,
|
||||
} from "@medusajs/utils"
|
||||
import { medusaIntegrationTestRunner } from "@medusajs/test-utils"
|
||||
import { createOrderFixture, prepareDataFixtures } from "../__fixtures__"
|
||||
jest.setTimeout(50000)
|
||||
|
||||
medusaIntegrationTestRunner({
|
||||
env: { MEDUSA_FF_MEDUSA_V2: true },
|
||||
testSuite: ({ getContainer }) => {
|
||||
let container
|
||||
|
||||
beforeAll(() => {
|
||||
container = getContainer()
|
||||
})
|
||||
|
||||
describe("Order change: Exchange shipping", () => {
|
||||
let order: OrderDTO
|
||||
let service: IFulfillmentModuleService
|
||||
let fixtures
|
||||
|
||||
let exchangeOrder: OrderDTO
|
||||
|
||||
beforeEach(async () => {
|
||||
fixtures = await prepareDataFixtures({ container })
|
||||
|
||||
order = await createOrderFixture({
|
||||
container,
|
||||
product: fixtures.product,
|
||||
location: fixtures.location,
|
||||
inventoryItem: fixtures.inventoryItem,
|
||||
salesChannel: fixtures.salesChannel,
|
||||
customer: fixtures.customer,
|
||||
region: fixtures.region,
|
||||
overrides: { quantity: 2 },
|
||||
})
|
||||
|
||||
await createOrderFulfillmentWorkflow(container).run({
|
||||
input: {
|
||||
order_id: order.id,
|
||||
items: [
|
||||
{
|
||||
quantity: 2,
|
||||
id: order.items![0].id,
|
||||
},
|
||||
],
|
||||
},
|
||||
})
|
||||
|
||||
await beginExchangeOrderWorkflow(container).run({
|
||||
input: { order_id: order.id },
|
||||
throwOnError: true,
|
||||
})
|
||||
|
||||
const remoteQuery = container.resolve(
|
||||
ContainerRegistrationKeys.REMOTE_QUERY
|
||||
)
|
||||
|
||||
const remoteQueryObject = remoteQueryObjectFromString({
|
||||
entryPoint: "order_exchange",
|
||||
variables: { order_id: order.id },
|
||||
fields: ["order_id", "id", "status", "order_change_id"],
|
||||
})
|
||||
|
||||
service = container.resolve(Modules.FULFILLMENT)
|
||||
;[exchangeOrder] = await remoteQuery(remoteQueryObject)
|
||||
})
|
||||
|
||||
describe("createExchangeShippingMethodWorkflow", () => {
|
||||
it("should successfully add caluclated inbound and outbound shipping to order changes", async () => {
|
||||
const { result } = await orderExchangeAddNewItemWorkflow(
|
||||
container
|
||||
).run({
|
||||
input: {
|
||||
exchange_id: exchangeOrder.id,
|
||||
items: [
|
||||
{
|
||||
variant_id: fixtures.product.variants[0].id,
|
||||
quantity: 1,
|
||||
internal_note: "test",
|
||||
},
|
||||
],
|
||||
},
|
||||
})
|
||||
|
||||
const shippingOptionId = fixtures.shippingOptionCalculated.id
|
||||
|
||||
const { result: orderChangePreview } =
|
||||
await createExchangeShippingMethodWorkflow(container).run({
|
||||
input: {
|
||||
exchange_id: exchangeOrder.id,
|
||||
shipping_option_id: shippingOptionId,
|
||||
},
|
||||
})
|
||||
|
||||
// Original shipping + outbound
|
||||
expect(orderChangePreview.shipping_methods).toHaveLength(2)
|
||||
|
||||
const outboundShippingMethod =
|
||||
orderChangePreview.shipping_methods?.find(
|
||||
(sm) => sm.shipping_option_id === shippingOptionId
|
||||
)
|
||||
|
||||
expect((outboundShippingMethod as any).actions).toEqual([
|
||||
expect.objectContaining({
|
||||
id: expect.any(String),
|
||||
reference: "order_shipping_method",
|
||||
reference_id: expect.any(String),
|
||||
raw_amount: { value: "2.5", precision: 20 },
|
||||
return_id: null,
|
||||
exchange_id: exchangeOrder.id,
|
||||
applied: false,
|
||||
action: "SHIPPING_ADD",
|
||||
amount: 2.5,
|
||||
}),
|
||||
])
|
||||
|
||||
const { result: orderChangePreview2 } =
|
||||
await orderExchangeRequestItemReturnWorkflow.run({
|
||||
container,
|
||||
input: {
|
||||
exchange_id: exchangeOrder.id,
|
||||
items: [
|
||||
{
|
||||
id: result.items[0].id,
|
||||
quantity: 1,
|
||||
},
|
||||
],
|
||||
},
|
||||
})
|
||||
|
||||
const associatedReturnId = orderChangePreview2.order_change.return_id
|
||||
|
||||
const { result: orderChangePreview3 } =
|
||||
await createExchangeShippingMethodWorkflow(container).run({
|
||||
input: {
|
||||
exchange_id: exchangeOrder.id,
|
||||
return_id: associatedReturnId,
|
||||
shipping_option_id: shippingOptionId,
|
||||
},
|
||||
})
|
||||
|
||||
expect(orderChangePreview3.shipping_methods).toHaveLength(3)
|
||||
|
||||
const inboundShippingMethod =
|
||||
orderChangePreview3.shipping_methods?.find(
|
||||
(sm) =>
|
||||
sm.shipping_option_id === shippingOptionId &&
|
||||
sm.actions?.find(
|
||||
(a) =>
|
||||
a.action === "SHIPPING_ADD" &&
|
||||
a.return_id === associatedReturnId
|
||||
)
|
||||
)
|
||||
|
||||
expect(inboundShippingMethod!.actions![0]).toEqual(
|
||||
expect.objectContaining({
|
||||
return_id: associatedReturnId,
|
||||
exchange_id: exchangeOrder.id,
|
||||
applied: false,
|
||||
action: "SHIPPING_ADD",
|
||||
amount: 2,
|
||||
})
|
||||
)
|
||||
|
||||
// Update outbound quantity to test refresh caluclation
|
||||
|
||||
const { result: orderChangePreview4 } =
|
||||
await updateExchangeAddItemWorkflow(container).run({
|
||||
input: {
|
||||
exchange_id: exchangeOrder.id,
|
||||
action_id: result.items.find(
|
||||
(i) => i.variant_id === fixtures.product.variants[0].id
|
||||
)?.actions?.[0]?.id as string,
|
||||
data: {
|
||||
quantity: 2,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
const outboundShippingMethod2 =
|
||||
orderChangePreview4.shipping_methods?.find(
|
||||
(sm) => sm.shipping_option_id === shippingOptionId
|
||||
)
|
||||
|
||||
expect((outboundShippingMethod2 as any).actions).toEqual([
|
||||
expect.objectContaining({
|
||||
id: expect.any(String),
|
||||
reference: "order_shipping_method",
|
||||
reference_id: expect.any(String),
|
||||
raw_amount: { value: "5", precision: 20 },
|
||||
return_id: null,
|
||||
exchange_id: exchangeOrder.id,
|
||||
applied: false,
|
||||
action: "SHIPPING_ADD",
|
||||
amount: 5,
|
||||
}),
|
||||
])
|
||||
})
|
||||
})
|
||||
})
|
||||
},
|
||||
})
|
||||
@@ -1,6 +1,9 @@
|
||||
import {
|
||||
beginReturnOrderWorkflow,
|
||||
createOrderFulfillmentWorkflow,
|
||||
createReturnShippingMethodWorkflow,
|
||||
requestItemReturnWorkflow,
|
||||
updateRequestItemReturnWorkflow,
|
||||
} from "@medusajs/core-flows"
|
||||
import { IFulfillmentModuleService, OrderDTO, ReturnDTO } from "@medusajs/types"
|
||||
import {
|
||||
@@ -10,7 +13,6 @@ import {
|
||||
} from "@medusajs/utils"
|
||||
import { medusaIntegrationTestRunner } from "@medusajs/test-utils"
|
||||
import { createOrderFixture, prepareDataFixtures } from "../__fixtures__"
|
||||
|
||||
jest.setTimeout(50000)
|
||||
|
||||
medusaIntegrationTestRunner({
|
||||
@@ -37,6 +39,19 @@ medusaIntegrationTestRunner({
|
||||
product: fixtures.product,
|
||||
location: fixtures.location,
|
||||
inventoryItem: fixtures.inventoryItem,
|
||||
overrides: { quantity: 2 },
|
||||
})
|
||||
|
||||
await createOrderFulfillmentWorkflow(container).run({
|
||||
input: {
|
||||
order_id: order.id,
|
||||
items: [
|
||||
{
|
||||
quantity: 2,
|
||||
id: order.items![0].id,
|
||||
},
|
||||
],
|
||||
},
|
||||
})
|
||||
|
||||
await beginReturnOrderWorkflow(container).run({
|
||||
@@ -115,6 +130,121 @@ medusaIntegrationTestRunner({
|
||||
}),
|
||||
])
|
||||
})
|
||||
|
||||
it("should successfully add calculated return shipping to order changes", async () => {
|
||||
const shippingOptionId = fixtures.shippingOptionCalculated.id
|
||||
|
||||
const { result: orderChangePreview } =
|
||||
await createReturnShippingMethodWorkflow(container).run({
|
||||
input: {
|
||||
return_id: returnOrder.id,
|
||||
shipping_option_id: shippingOptionId,
|
||||
},
|
||||
})
|
||||
|
||||
const shippingMethod = orderChangePreview.shipping_methods?.find(
|
||||
(sm) => sm.shipping_option_id === shippingOptionId
|
||||
)
|
||||
|
||||
/**
|
||||
* Shipping is 0 because the shipping option is calculated based on the return items
|
||||
* and currently there are no return items.
|
||||
*/
|
||||
|
||||
expect((shippingMethod as any).actions).toEqual([
|
||||
expect.objectContaining({
|
||||
id: expect.any(String),
|
||||
reference: "order_shipping_method",
|
||||
reference_id: expect.any(String),
|
||||
raw_amount: { value: "0", precision: 20 },
|
||||
applied: false,
|
||||
action: "SHIPPING_ADD",
|
||||
amount: 0,
|
||||
}),
|
||||
])
|
||||
|
||||
const { result } = await requestItemReturnWorkflow(container).run({
|
||||
input: {
|
||||
return_id: returnOrder.id,
|
||||
items: [
|
||||
{
|
||||
id: order.items![0].id,
|
||||
quantity: 1,
|
||||
internal_note: "test",
|
||||
},
|
||||
],
|
||||
},
|
||||
})
|
||||
|
||||
console.log(result.items[0].actions)
|
||||
|
||||
let updatedShippingMethod = result.shipping_methods?.find(
|
||||
(sm) => sm.shipping_option_id === shippingOptionId
|
||||
)
|
||||
|
||||
/**
|
||||
* Caluclated shipping is 2$ per return item.
|
||||
*/
|
||||
expect(updatedShippingMethod).toEqual(
|
||||
expect.objectContaining({
|
||||
id: expect.any(String),
|
||||
shipping_option_id: shippingOptionId,
|
||||
amount: 2,
|
||||
actions: expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
id: expect.any(String),
|
||||
reference: "order_shipping_method",
|
||||
reference_id: expect.any(String),
|
||||
raw_amount: { value: "2", precision: 20 },
|
||||
applied: false,
|
||||
action: "SHIPPING_ADD",
|
||||
amount: 2,
|
||||
}),
|
||||
]),
|
||||
})
|
||||
)
|
||||
/**
|
||||
* Update the return item quantity to 2.
|
||||
*/
|
||||
|
||||
const { result: updatedResult } =
|
||||
await updateRequestItemReturnWorkflow(container).run({
|
||||
input: {
|
||||
return_id: returnOrder.id,
|
||||
action_id: result.items
|
||||
.find((i) =>
|
||||
i.actions?.find((a) => a.action === "RETURN_ITEM")
|
||||
)
|
||||
?.actions?.find((a) => a.action === "RETURN_ITEM")?.id!,
|
||||
data: {
|
||||
quantity: 2,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
updatedShippingMethod = updatedResult.shipping_methods?.find(
|
||||
(sm) => sm.shipping_option_id === shippingOptionId
|
||||
)
|
||||
|
||||
expect(updatedShippingMethod).toEqual(
|
||||
expect.objectContaining({
|
||||
id: expect.any(String),
|
||||
shipping_option_id: shippingOptionId,
|
||||
amount: 4,
|
||||
actions: expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
id: expect.any(String),
|
||||
reference: "order_shipping_method",
|
||||
reference_id: expect.any(String),
|
||||
raw_amount: { value: "4", precision: 20 },
|
||||
applied: false,
|
||||
action: "SHIPPING_ADD",
|
||||
amount: 4,
|
||||
}),
|
||||
]),
|
||||
})
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
@@ -22,6 +22,12 @@ const customFulfillmentProvider = {
|
||||
id: "test-provider",
|
||||
}
|
||||
|
||||
const customFulfillmentProviderCalculated = {
|
||||
resolve: require("./dist/utils/providers/fulfillment-manual-calculated")
|
||||
.default,
|
||||
id: "test-provider-calculated",
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
admin: {
|
||||
disable: true,
|
||||
@@ -96,7 +102,10 @@ module.exports = {
|
||||
[Modules.FULFILLMENT]: {
|
||||
/** @type {import('@medusajs/fulfillment').FulfillmentModuleOptions} */
|
||||
options: {
|
||||
providers: [customFulfillmentProvider],
|
||||
providers: [
|
||||
customFulfillmentProvider,
|
||||
customFulfillmentProviderCalculated,
|
||||
],
|
||||
},
|
||||
},
|
||||
[Modules.NOTIFICATION]: {
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
import { ModuleProvider, Modules } from "@medusajs/framework/utils"
|
||||
import { ManualFulfillmentService } from "./services/manual-fulfillment"
|
||||
|
||||
const services = [ManualFulfillmentService]
|
||||
|
||||
export default ModuleProvider(Modules.FULFILLMENT, {
|
||||
services,
|
||||
})
|
||||
@@ -0,0 +1,80 @@
|
||||
import { AbstractFulfillmentProviderService } from "@medusajs/framework/utils"
|
||||
|
||||
export class ManualFulfillmentService extends AbstractFulfillmentProviderService {
|
||||
static identifier = "manual-calculated"
|
||||
|
||||
constructor() {
|
||||
super()
|
||||
}
|
||||
|
||||
async getFulfillmentOptions() {
|
||||
return [
|
||||
{
|
||||
id: "manual-fulfillment-calculated",
|
||||
},
|
||||
{
|
||||
id: "manual-fulfillment-return-calculated",
|
||||
is_return: true,
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
async validateFulfillmentData(optionData, data, context) {
|
||||
return data
|
||||
}
|
||||
|
||||
async calculatePrice(optionData, data, context) {
|
||||
if (context.exchange_id) {
|
||||
return {
|
||||
calculated_amount:
|
||||
context.exchange_items.reduce((acc, i) => acc + i.quantity, 0) * 2.5, // mock return cost as 2 per item
|
||||
is_calculated_price_tax_inclusive: false,
|
||||
}
|
||||
}
|
||||
if (context.claim_id) {
|
||||
return {
|
||||
calculated_amount:
|
||||
context.claim_items.reduce((acc, i) => acc + i.quantity, 0) * 2.5, // mock return cost as 2 per item
|
||||
is_calculated_price_tax_inclusive: false,
|
||||
}
|
||||
}
|
||||
|
||||
if (context.return_id) {
|
||||
return {
|
||||
calculated_amount:
|
||||
context.return_items.reduce((acc, i) => acc + i.quantity, 0) * 2, // mock return cost as 2 per item
|
||||
is_calculated_price_tax_inclusive: false,
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
calculated_amount:
|
||||
context.items.reduce((acc, i) => acc + i.quantity, 0) * 1.5, // mock caluclation as 1.5 per item
|
||||
is_calculated_price_tax_inclusive: false,
|
||||
}
|
||||
}
|
||||
|
||||
async canCalculate() {
|
||||
return true
|
||||
}
|
||||
|
||||
async validateOption(data) {
|
||||
return true
|
||||
}
|
||||
|
||||
async createFulfillment() {
|
||||
// No data is being sent anywhere
|
||||
return {
|
||||
data: {},
|
||||
labels: [],
|
||||
}
|
||||
}
|
||||
|
||||
async cancelFulfillment() {
|
||||
return {}
|
||||
}
|
||||
|
||||
async createReturnFulfillment() {
|
||||
return { data: {}, labels: [] }
|
||||
}
|
||||
}
|
||||
@@ -8,13 +8,14 @@ import { StepResponse, createStep } from "@medusajs/framework/workflows-sdk"
|
||||
/**
|
||||
* The data to calculate the prices for one or more shipping options.
|
||||
*/
|
||||
export type CalculateShippingOptionsPriceStepInput = CalculateShippingOptionPriceDTO[]
|
||||
export type CalculateShippingOptionsPriceStepInput =
|
||||
CalculateShippingOptionPriceDTO[]
|
||||
|
||||
export const calculateShippingOptionsPricesStepId =
|
||||
"calculate-shipping-options-prices"
|
||||
/**
|
||||
* This step calculates the prices for one or more shipping options.
|
||||
*
|
||||
*
|
||||
* @example
|
||||
* const data = calculateShippingOptionsPricesStep([{
|
||||
* id: "so_123",
|
||||
|
||||
@@ -22,9 +22,9 @@ export const validateShippingOptionPricesStepId =
|
||||
*
|
||||
* For flat rate prices, it validates that regions exist for the shipping option prices.
|
||||
* For calculated prices, it validates with the fulfillment provider if the price can be calculated.
|
||||
*
|
||||
*
|
||||
* If not valid, the step throws an error.
|
||||
*
|
||||
*
|
||||
* @example
|
||||
* const data = validateShippingOptionPricesStep([
|
||||
* {
|
||||
|
||||
@@ -0,0 +1,210 @@
|
||||
import {
|
||||
BigNumberInput,
|
||||
CalculatedRMAShippingContext,
|
||||
CalculateShippingOptionPriceDTO,
|
||||
ShippingOptionDTO,
|
||||
} from "@medusajs/framework/types"
|
||||
import {
|
||||
WorkflowResponse,
|
||||
createWorkflow,
|
||||
transform,
|
||||
when,
|
||||
} from "@medusajs/framework/workflows-sdk"
|
||||
import { BigNumber, ShippingOptionPriceType } from "@medusajs/framework/utils"
|
||||
import { calculateShippingOptionsPricesStep } from "../../fulfillment/steps"
|
||||
import { useRemoteQueryStep } from "../../common"
|
||||
|
||||
const COMMON_OPTIONS_FIELDS = [
|
||||
"id",
|
||||
"name",
|
||||
"price_type",
|
||||
"service_zone_id",
|
||||
"service_zone.fulfillment_set_id",
|
||||
"service_zone.fulfillment_set.type",
|
||||
"service_zone.fulfillment_set.location.*",
|
||||
"service_zone.fulfillment_set.location.address.*",
|
||||
"shipping_profile_id",
|
||||
"provider_id",
|
||||
"data",
|
||||
|
||||
"type.id",
|
||||
"type.label",
|
||||
"type.description",
|
||||
"type.code",
|
||||
|
||||
"provider.id",
|
||||
"provider.is_enabled",
|
||||
|
||||
"rules.attribute",
|
||||
"rules.value",
|
||||
"rules.operator",
|
||||
]
|
||||
|
||||
/**
|
||||
* The data to create a shipping method for an order edit.
|
||||
*/
|
||||
export type FetchShippingOptionForOrderWorkflowInput = {
|
||||
/**
|
||||
* The ID of the shipping option to create the shipping method from.
|
||||
*/
|
||||
shipping_option_id: string
|
||||
/**
|
||||
* The custom amount to create the shipping method with.
|
||||
* If not provided, the shipping option's amount is used.
|
||||
*/
|
||||
custom_amount?: BigNumberInput | null
|
||||
/**
|
||||
* The currency code of the order.
|
||||
*/
|
||||
currency_code: string
|
||||
/**
|
||||
* The ID of the order.
|
||||
*/
|
||||
order_id: string
|
||||
/**
|
||||
* The context of the order.
|
||||
*/
|
||||
context: CalculatedRMAShippingContext
|
||||
}
|
||||
|
||||
/**
|
||||
* The output of the fetch shipping option for order workflow.
|
||||
*/
|
||||
export type FetchShippingOptionForOrderWorkflowOutput = ShippingOptionDTO & {
|
||||
calculated_price: {
|
||||
calculated_amount: BigNumber
|
||||
is_calculated_price_tax_inclusive: boolean
|
||||
}
|
||||
}
|
||||
export const createOrderEditShippingMethodWorkflowId = "fetch-shipping-option"
|
||||
/**
|
||||
* This workflows fetches a shipping option for an order (used in RMA flows).
|
||||
*
|
||||
* There can be 3 cases:
|
||||
* 1. The shipping option is a flat rate shipping option.
|
||||
* In this case, pricing calculation context is not used.
|
||||
* 2. The shipping option is a calculated shipping option.
|
||||
* In this case, calculate shipping price method from the provider is called.
|
||||
* 3. The shipping option is a custom shipping option. -- TODO
|
||||
* In this case, we don't need to do caluclations above and just return the shipping option with the custom amount.
|
||||
*/
|
||||
export const fetchShippingOptionForOrderWorkflow = createWorkflow(
|
||||
createOrderEditShippingMethodWorkflowId,
|
||||
function (
|
||||
input: FetchShippingOptionForOrderWorkflowInput
|
||||
): WorkflowResponse<FetchShippingOptionForOrderWorkflowOutput> {
|
||||
const initialOption = useRemoteQueryStep({
|
||||
entry_point: "shipping_option",
|
||||
variables: { id: input.shipping_option_id },
|
||||
fields: ["id", "price_type"],
|
||||
list: false,
|
||||
}).config({ name: "shipping-option-query" })
|
||||
|
||||
const isCalculatedPriceShippingOption = transform(
|
||||
initialOption,
|
||||
(option) => option.price_type === ShippingOptionPriceType.CALCULATED
|
||||
)
|
||||
|
||||
const calculatedPriceShippingOption = when(
|
||||
"option-calculated",
|
||||
{ isCalculatedPriceShippingOption },
|
||||
({ isCalculatedPriceShippingOption }) => isCalculatedPriceShippingOption
|
||||
).then(() => {
|
||||
const order = useRemoteQueryStep({
|
||||
entry_point: "orders",
|
||||
fields: ["id", "shipping_address", "items.*", "items.variant.*"],
|
||||
variables: { id: input.order_id },
|
||||
list: false,
|
||||
throw_if_key_not_found: true,
|
||||
}).config({ name: "order-query" })
|
||||
|
||||
const shippingOption = useRemoteQueryStep({
|
||||
entry_point: "shipping_option",
|
||||
fields: [...COMMON_OPTIONS_FIELDS],
|
||||
variables: { id: input.shipping_option_id },
|
||||
list: false,
|
||||
}).config({ name: "calculated-option" })
|
||||
|
||||
const calculateShippingOptionsPricesData = transform(
|
||||
{
|
||||
shippingOption,
|
||||
order,
|
||||
input,
|
||||
},
|
||||
({ shippingOption, order, input }) => {
|
||||
return [
|
||||
{
|
||||
id: shippingOption.id as string,
|
||||
optionData: shippingOption.data,
|
||||
context: {
|
||||
...order,
|
||||
...input.context,
|
||||
from_location:
|
||||
shippingOption.service_zone.fulfillment_set.location,
|
||||
},
|
||||
// data: {}, // TODO: add data
|
||||
provider_id: shippingOption.provider_id,
|
||||
} as CalculateShippingOptionPriceDTO,
|
||||
]
|
||||
}
|
||||
)
|
||||
|
||||
const prices = calculateShippingOptionsPricesStep(
|
||||
calculateShippingOptionsPricesData
|
||||
)
|
||||
|
||||
const shippingOptionsWithPrice = transform(
|
||||
{
|
||||
shippingOption,
|
||||
prices,
|
||||
},
|
||||
({ shippingOption, prices }) => {
|
||||
return {
|
||||
id: shippingOption.id,
|
||||
name: shippingOption.name,
|
||||
calculated_price: prices[0],
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
return shippingOptionsWithPrice
|
||||
})
|
||||
|
||||
const flatRateShippingOption = when(
|
||||
"option-flat",
|
||||
{ isCalculatedPriceShippingOption },
|
||||
({ isCalculatedPriceShippingOption }) => !isCalculatedPriceShippingOption
|
||||
).then(() => {
|
||||
const shippingOption = useRemoteQueryStep({
|
||||
entry_point: "shipping_option",
|
||||
fields: [
|
||||
"id",
|
||||
"name",
|
||||
"calculated_price.calculated_amount",
|
||||
"calculated_price.is_calculated_price_tax_inclusive",
|
||||
],
|
||||
variables: {
|
||||
id: input.shipping_option_id,
|
||||
calculated_price: {
|
||||
context: { currency_code: input.currency_code },
|
||||
},
|
||||
},
|
||||
list: false,
|
||||
}).config({ name: "flat-reate-option" })
|
||||
|
||||
return shippingOption
|
||||
})
|
||||
|
||||
const result = transform(
|
||||
{
|
||||
calculatedPriceShippingOption,
|
||||
flatRateShippingOption,
|
||||
},
|
||||
({ calculatedPriceShippingOption, flatRateShippingOption }) => {
|
||||
return calculatedPriceShippingOption ?? flatRateShippingOption
|
||||
}
|
||||
)
|
||||
|
||||
return new WorkflowResponse(result)
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,173 @@
|
||||
import {
|
||||
CalculatedRMAShippingContext,
|
||||
CalculateShippingOptionPriceDTO,
|
||||
} from "@medusajs/framework/types"
|
||||
import {
|
||||
WorkflowResponse,
|
||||
createWorkflow,
|
||||
parallelize,
|
||||
transform,
|
||||
when,
|
||||
} from "@medusajs/framework/workflows-sdk"
|
||||
import { ShippingOptionPriceType } from "@medusajs/framework/utils"
|
||||
import { calculateShippingOptionsPricesStep } from "../../fulfillment/steps"
|
||||
import {
|
||||
updateOrderChangeActionsStep,
|
||||
updateOrderShippingMethodsStep,
|
||||
} from "../steps"
|
||||
import { useQueryGraphStep } from "../../common"
|
||||
|
||||
const COMMON_OPTIONS_FIELDS = [
|
||||
"id",
|
||||
"name",
|
||||
"price_type",
|
||||
"service_zone_id",
|
||||
"service_zone.fulfillment_set_id",
|
||||
"service_zone.fulfillment_set.type",
|
||||
"service_zone.fulfillment_set.location.*",
|
||||
"service_zone.fulfillment_set.location.address.*",
|
||||
"shipping_profile_id",
|
||||
"provider_id",
|
||||
"data",
|
||||
|
||||
"type.id",
|
||||
"type.label",
|
||||
"type.description",
|
||||
"type.code",
|
||||
|
||||
"provider.id",
|
||||
"provider.is_enabled",
|
||||
|
||||
"rules.attribute",
|
||||
"rules.value",
|
||||
"rules.operator",
|
||||
]
|
||||
|
||||
/**
|
||||
* The data to create a shipping method for an order edit.
|
||||
*/
|
||||
export type MaybeRefreshShippingMethodsWorkflowInput = {
|
||||
/**
|
||||
* The ID of the shipping method to refresh.
|
||||
*/
|
||||
shipping_method_id: string
|
||||
/**
|
||||
* The ID of the order.
|
||||
*/
|
||||
order_id: string
|
||||
/**
|
||||
* The ID of the ADD SHIPPING action to update.
|
||||
*/
|
||||
action_id: string
|
||||
/**
|
||||
* Data to pass for the shipping calculation.
|
||||
*/
|
||||
context: CalculatedRMAShippingContext
|
||||
}
|
||||
|
||||
export const maybeRefreshShippingMethodsWorkflowId =
|
||||
"maybe-refresh-shipping-methods"
|
||||
/**
|
||||
* This workflows refreshes shipping method an order (used in RMA flows).
|
||||
* The shipping method and the action is updated if the shipping option is calculated.
|
||||
*/
|
||||
export const maybeRefreshShippingMethodsWorkflow = createWorkflow(
|
||||
maybeRefreshShippingMethodsWorkflowId,
|
||||
function (
|
||||
input: MaybeRefreshShippingMethodsWorkflowInput
|
||||
): WorkflowResponse<void> {
|
||||
const shippingMethodQuery = useQueryGraphStep({
|
||||
entity: "order_shipping_method",
|
||||
fields: ["id", "shipping_option_id"],
|
||||
filters: {
|
||||
id: input.shipping_method_id,
|
||||
},
|
||||
}).config({ name: "fetch-shipping-method" })
|
||||
|
||||
const shippingMethod = transform(shippingMethodQuery, ({ data }) => data[0])
|
||||
|
||||
const shippingOptionQuery = useQueryGraphStep({
|
||||
entity: "shipping_option",
|
||||
fields: [...COMMON_OPTIONS_FIELDS],
|
||||
filters: { id: shippingMethod.shipping_option_id },
|
||||
}).config({ name: "calculated-option" })
|
||||
|
||||
const shippingOption = transform(shippingOptionQuery, ({ data }) => data[0])
|
||||
|
||||
const isCalculatedPriceShippingOption = transform(
|
||||
shippingOption,
|
||||
(option) => option?.price_type === ShippingOptionPriceType.CALCULATED
|
||||
)
|
||||
|
||||
when(
|
||||
{ isCalculatedPriceShippingOption, shippingOption },
|
||||
({ isCalculatedPriceShippingOption, shippingOption }) =>
|
||||
isCalculatedPriceShippingOption
|
||||
).then(() => {
|
||||
const orderQuery = useQueryGraphStep({
|
||||
entity: "order",
|
||||
fields: ["id", "shipping_address", "items.*", "items.variant.*"],
|
||||
filters: { id: input.order_id },
|
||||
options: { throwIfKeyNotFound: true },
|
||||
}).config({ name: "order-query" })
|
||||
|
||||
const order = transform(orderQuery, (data) => data[0])
|
||||
|
||||
const calculateShippingOptionsPricesData = transform(
|
||||
{
|
||||
shippingOption,
|
||||
order,
|
||||
input,
|
||||
},
|
||||
({ shippingOption, order, input }) => {
|
||||
return [
|
||||
{
|
||||
id: shippingOption.id as string,
|
||||
optionData: shippingOption.data,
|
||||
context: {
|
||||
...order,
|
||||
...input.context,
|
||||
from_location:
|
||||
shippingOption.service_zone.fulfillment_set.location,
|
||||
},
|
||||
// data: {}, // TODO: add data
|
||||
provider_id: shippingOption.provider_id,
|
||||
} as CalculateShippingOptionPriceDTO,
|
||||
]
|
||||
}
|
||||
)
|
||||
|
||||
const prices = calculateShippingOptionsPricesStep(
|
||||
calculateShippingOptionsPricesData
|
||||
)
|
||||
|
||||
const updateData = transform(
|
||||
{
|
||||
shippingOption,
|
||||
prices,
|
||||
input,
|
||||
},
|
||||
({ prices, input }) => {
|
||||
return [
|
||||
{
|
||||
id: input.action_id,
|
||||
amount: prices[0].calculated_amount,
|
||||
},
|
||||
{
|
||||
id: input.shipping_method_id,
|
||||
amount: prices[0].calculated_amount,
|
||||
is_custom_amount: false,
|
||||
},
|
||||
]
|
||||
}
|
||||
)
|
||||
|
||||
parallelize(
|
||||
updateOrderChangeActionsStep([updateData[0]]),
|
||||
updateOrderShippingMethodsStep([updateData[1]!])
|
||||
)
|
||||
})
|
||||
|
||||
return new WorkflowResponse(void 0)
|
||||
}
|
||||
)
|
||||
@@ -22,6 +22,7 @@ import {
|
||||
import { addOrderLineItemsWorkflow } from "../add-line-items"
|
||||
import { createOrderChangeActionsWorkflow } from "../create-order-change-actions"
|
||||
import { updateOrderTaxLinesWorkflow } from "../update-tax-lines"
|
||||
import { refreshClaimShippingWorkflow } from "./refresh-shipping"
|
||||
|
||||
/**
|
||||
* The data to validate adding new items to a claim.
|
||||
@@ -191,6 +192,21 @@ export const orderClaimAddNewItemWorkflow = createWorkflow(
|
||||
input: orderChangeActionInput,
|
||||
})
|
||||
|
||||
const refreshArgs = transform(
|
||||
{ orderChange, orderClaim },
|
||||
({ orderChange, orderClaim }) => {
|
||||
return {
|
||||
order_change_id: orderChange.id,
|
||||
claim_id: orderClaim.id,
|
||||
order_id: orderClaim.order_id,
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
refreshClaimShippingWorkflow.runAsStep({
|
||||
input: refreshArgs,
|
||||
})
|
||||
|
||||
return new WorkflowResponse(previewOrderChangeStep(orderClaim.order_id))
|
||||
}
|
||||
)
|
||||
|
||||
@@ -26,6 +26,7 @@ import {
|
||||
throwIfOrderChangeIsNotActive,
|
||||
} from "../../utils/order-validation"
|
||||
import { createOrderChangeActionsWorkflow } from "../create-order-change-actions"
|
||||
import { refreshClaimShippingWorkflow } from "./refresh-shipping"
|
||||
|
||||
/**
|
||||
* The data to validate that items can be requested to return as part of a claim.
|
||||
@@ -56,14 +57,14 @@ export type OrderClaimRequestItemReturnValidationStepInput = {
|
||||
/**
|
||||
* This step validates that items can be requested to return as part of a claim.
|
||||
* If the order, claim, or return is canceled, or the order change is not active, the step will throw an error.
|
||||
*
|
||||
*
|
||||
* :::note
|
||||
*
|
||||
*
|
||||
* You can retrieve an order, order claim, order return, and order change details using [Query](https://docs.medusajs.com/learn/fundamentals/module-links/query),
|
||||
* or [useQueryGraphStep](https://docs.medusajs.com/resources/references/medusa-workflows/steps/useQueryGraphStep).
|
||||
*
|
||||
*
|
||||
* :::
|
||||
*
|
||||
*
|
||||
* @example
|
||||
* const data = orderClaimRequestItemReturnValidationStep({
|
||||
* order: {
|
||||
@@ -112,10 +113,10 @@ export const orderClaimRequestItemReturnWorkflowId = "claim-request-item-return"
|
||||
* This workflow requests one or more items to be returned as part of a claim. The
|
||||
* items are added to the claim as inbound items. The workflow is used by the
|
||||
* [Add Inbound Items to Claim Admin API Route](https://docs.medusajs.com/api/admin#claims_postclaimsidinbounditems).
|
||||
*
|
||||
*
|
||||
* You can use this workflow within your customizations or your own custom workflows, allowing you to request items to be returned
|
||||
* as part of a claim in your custom flows.
|
||||
*
|
||||
*
|
||||
* @example
|
||||
* const { result } = await orderClaimRequestItemReturnWorkflow(container)
|
||||
* .run({
|
||||
@@ -130,9 +131,9 @@ export const orderClaimRequestItemReturnWorkflowId = "claim-request-item-return"
|
||||
* ]
|
||||
* }
|
||||
* })
|
||||
*
|
||||
*
|
||||
* @summary
|
||||
*
|
||||
*
|
||||
* Request one or more items to be returned as part of a claim.
|
||||
*/
|
||||
export const orderClaimRequestItemReturnWorkflow = createWorkflow(
|
||||
@@ -258,6 +259,21 @@ export const orderClaimRequestItemReturnWorkflow = createWorkflow(
|
||||
input: orderChangeActionInput,
|
||||
})
|
||||
|
||||
const refreshArgs = transform(
|
||||
{ orderChange, orderClaim },
|
||||
({ orderChange, orderClaim }) => {
|
||||
return {
|
||||
order_change_id: orderChange.id,
|
||||
claim_id: orderClaim.id,
|
||||
order_id: orderClaim.order_id,
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
refreshClaimShippingWorkflow.runAsStep({
|
||||
input: refreshArgs,
|
||||
})
|
||||
|
||||
return new WorkflowResponse(previewOrderChangeStep(orderClaim.order_id))
|
||||
}
|
||||
)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import {
|
||||
BigNumberInput,
|
||||
CalculatedRMAShippingContext,
|
||||
OrderChangeDTO,
|
||||
OrderClaimDTO,
|
||||
OrderDTO,
|
||||
@@ -22,6 +23,7 @@ import {
|
||||
import { prepareShippingMethod } from "../../utils/prepare-shipping-method"
|
||||
import { createOrderChangeActionsWorkflow } from "../create-order-change-actions"
|
||||
import { updateOrderTaxLinesWorkflow } from "../update-tax-lines"
|
||||
import { fetchShippingOptionForOrderWorkflow } from "../../utils/fetch-shipping-option"
|
||||
|
||||
/**
|
||||
* The data to validate that a shipping method can be created for a claim.
|
||||
@@ -44,14 +46,14 @@ export type CreateClaimShippingMethodValidationStepInput = {
|
||||
/**
|
||||
* This step confirms that a shipping method can be created for a claim.
|
||||
* If the order or claim is canceled, or the order change is not active, the step will throw an error.
|
||||
*
|
||||
*
|
||||
* :::note
|
||||
*
|
||||
*
|
||||
* You can retrieve an order, order claim, and order change details using [Query](https://docs.medusajs.com/learn/fundamentals/module-links/query),
|
||||
* or [useQueryGraphStep](https://docs.medusajs.com/resources/references/medusa-workflows/steps/useQueryGraphStep).
|
||||
*
|
||||
*
|
||||
* :::
|
||||
*
|
||||
*
|
||||
* @example
|
||||
* const data = createClaimShippingMethodValidationStep({
|
||||
* order: {
|
||||
@@ -111,13 +113,13 @@ export const createClaimShippingMethodWorkflowId =
|
||||
* This workflow creates an inbound (return) or outbound (delivering new items) shipping method for a claim.
|
||||
* It's used by the [Add Inbound Shipping Admin API Route](https://docs.medusajs.com/api/admin#claims_postclaimsidinboundshippingmethod),
|
||||
* and the [Add Outbound Shipping Admin API Route](https://docs.medusajs.com/api/admin#claims_postclaimsidoutboundshippingmethod).
|
||||
*
|
||||
*
|
||||
* You can use this workflow within your customizations or your own custom workflows, allowing you to create a shipping method
|
||||
* for a claim in your custom flows.
|
||||
*
|
||||
*
|
||||
* @example
|
||||
* To create an outbound shipping method for a claim:
|
||||
*
|
||||
*
|
||||
* ```ts
|
||||
* const { result } = await createClaimShippingMethodWorkflow(container)
|
||||
* .run({
|
||||
@@ -127,9 +129,9 @@ export const createClaimShippingMethodWorkflowId =
|
||||
* }
|
||||
* })
|
||||
* ```
|
||||
*
|
||||
*
|
||||
* To create an inbound shipping method for a claim, specify the ID of the return associated with the claim:
|
||||
*
|
||||
*
|
||||
* ```ts
|
||||
* const { result } = await createClaimShippingMethodWorkflow(container)
|
||||
* .run({
|
||||
@@ -140,14 +142,16 @@ export const createClaimShippingMethodWorkflowId =
|
||||
* }
|
||||
* })
|
||||
* ```
|
||||
*
|
||||
*
|
||||
* @summary
|
||||
*
|
||||
*
|
||||
* Create an inbound or outbound shipping method for a claim.
|
||||
*/
|
||||
export const createClaimShippingMethodWorkflow = createWorkflow(
|
||||
createClaimShippingMethodWorkflowId,
|
||||
function (input: CreateClaimShippingMethodWorkflowInput): WorkflowResponse<OrderPreviewDTO> {
|
||||
function (
|
||||
input: CreateClaimShippingMethodWorkflowInput
|
||||
): WorkflowResponse<OrderPreviewDTO> {
|
||||
const orderClaim: OrderClaimDTO = useRemoteQueryStep({
|
||||
entry_point: "order_claim",
|
||||
fields: ["id", "status", "order_id", "canceled_at"],
|
||||
@@ -164,25 +168,9 @@ export const createClaimShippingMethodWorkflow = createWorkflow(
|
||||
throw_if_key_not_found: true,
|
||||
}).config({ name: "order-query" })
|
||||
|
||||
const shippingOptions = useRemoteQueryStep({
|
||||
entry_point: "shipping_option",
|
||||
fields: [
|
||||
"id",
|
||||
"name",
|
||||
"calculated_price.calculated_amount",
|
||||
"calculated_price.is_calculated_price_tax_inclusive",
|
||||
],
|
||||
variables: {
|
||||
id: input.shipping_option_id,
|
||||
calculated_price: {
|
||||
context: { currency_code: order.currency_code },
|
||||
},
|
||||
},
|
||||
}).config({ name: "fetch-shipping-option" })
|
||||
|
||||
const orderChange: OrderChangeDTO = useRemoteQueryStep({
|
||||
entry_point: "order_change",
|
||||
fields: ["id", "status", "version"],
|
||||
fields: ["id", "status", "version", "actions.*"],
|
||||
variables: {
|
||||
filters: {
|
||||
order_id: orderClaim.order_id,
|
||||
@@ -193,6 +181,52 @@ export const createClaimShippingMethodWorkflow = createWorkflow(
|
||||
list: false,
|
||||
}).config({ name: "order-change-query" })
|
||||
|
||||
const isReturn = transform(input, (data) => {
|
||||
return !!data.return_id
|
||||
})
|
||||
|
||||
const fetchShippingOptionInput = transform(
|
||||
{ input, isReturn, orderChange, order },
|
||||
(data) => {
|
||||
const changeActionType = data.isReturn
|
||||
? ChangeActionType.RETURN_ITEM
|
||||
: ChangeActionType.ITEM_ADD
|
||||
|
||||
const items = data.orderChange.actions
|
||||
.filter((action) => action.action === changeActionType)
|
||||
.map((a) => ({
|
||||
id: a.details?.reference_id,
|
||||
quantity: a.details?.quantity,
|
||||
}))
|
||||
|
||||
const context = data.isReturn
|
||||
? {
|
||||
return_id: data.input.return_id,
|
||||
return_items: items,
|
||||
}
|
||||
: {
|
||||
claim_id: data.input.claim_id,
|
||||
claim_items: items,
|
||||
}
|
||||
|
||||
return {
|
||||
order_id: data.order.id,
|
||||
currency_code: data.order.currency_code,
|
||||
shipping_option_id: data.input.shipping_option_id,
|
||||
custom_amount: data.input.custom_amount,
|
||||
context: context as CalculatedRMAShippingContext,
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
const shippingOption = fetchShippingOptionForOrderWorkflow.runAsStep({
|
||||
input: fetchShippingOptionInput,
|
||||
})
|
||||
|
||||
const shippingOptions = transform(shippingOption, (shippingOption) => {
|
||||
return [shippingOption]
|
||||
})
|
||||
|
||||
createClaimShippingMethodValidationStep({ order, orderClaim, orderChange })
|
||||
|
||||
const shippingMethodInput = transform(
|
||||
@@ -214,10 +248,6 @@ export const createClaimShippingMethodWorkflow = createWorkflow(
|
||||
return createdMethods.map((item) => item.id)
|
||||
})
|
||||
|
||||
const isReturn = transform(input, (data) => {
|
||||
return !!data.return_id
|
||||
})
|
||||
|
||||
updateOrderTaxLinesWorkflow.runAsStep({
|
||||
input: {
|
||||
order_id: order.id,
|
||||
|
||||
@@ -0,0 +1,141 @@
|
||||
import { ChangeActionType, OrderChangeStatus } from "@medusajs/framework/utils"
|
||||
import {
|
||||
WorkflowData,
|
||||
WorkflowResponse,
|
||||
createWorkflow,
|
||||
transform,
|
||||
when,
|
||||
} from "@medusajs/framework/workflows-sdk"
|
||||
|
||||
import { maybeRefreshShippingMethodsWorkflow } from "../../utils/maybe-refresh-shipping-methods"
|
||||
import { useQueryGraphStep } from "../../../common"
|
||||
|
||||
/**
|
||||
* The data to refresh the shipping methods for an claim.
|
||||
*/
|
||||
export type RefreshClaimShippingWorkflowInput = {
|
||||
/**
|
||||
* The order change's ID.
|
||||
*/
|
||||
order_change_id: string
|
||||
/**
|
||||
* The claim's details.
|
||||
*/
|
||||
claim_id: string
|
||||
/**
|
||||
* The order's ID.
|
||||
*/
|
||||
order_id: string
|
||||
}
|
||||
|
||||
export const refreshClaimShippingWorkflowId = "refresh-claim-shipping"
|
||||
/**
|
||||
* This workflow refreshes the shipping methods for an claim in case the shipping option is calculated.
|
||||
* It refreshes both inbound and outbound shipping methods.
|
||||
*
|
||||
* @summary
|
||||
*
|
||||
* Refresh claim shipping.
|
||||
*/
|
||||
export const refreshClaimShippingWorkflow = createWorkflow(
|
||||
refreshClaimShippingWorkflowId,
|
||||
function (
|
||||
input: WorkflowData<RefreshClaimShippingWorkflowInput>
|
||||
): WorkflowResponse<void> {
|
||||
const orderChangeQuery = useQueryGraphStep({
|
||||
entity: "order_change",
|
||||
fields: [
|
||||
"id",
|
||||
"status",
|
||||
"order_id",
|
||||
"claim_id",
|
||||
"return_id",
|
||||
"actions.*",
|
||||
],
|
||||
filters: {
|
||||
order_id: input.order_id,
|
||||
claim_id: input.claim_id,
|
||||
status: [OrderChangeStatus.PENDING, OrderChangeStatus.REQUESTED],
|
||||
},
|
||||
}).config({ name: "order-change-query" })
|
||||
|
||||
const orderChange = transform(orderChangeQuery, ({ data }) => data[0])
|
||||
|
||||
const refreshArgs = transform(
|
||||
{ input, orderChange, orderChangeQuery },
|
||||
({ input, orderChange, orderChangeQuery }) => {
|
||||
const shippingToRefresh = {} as Record<"inbound" | "outbound", any>
|
||||
|
||||
const inboundShippingAction = orderChange.actions.find(
|
||||
(action) =>
|
||||
action.action === ChangeActionType.SHIPPING_ADD &&
|
||||
!!action.return_id
|
||||
)
|
||||
|
||||
const outboundShippingAction = orderChange.actions.find(
|
||||
(action) =>
|
||||
action.action === ChangeActionType.SHIPPING_ADD && !action.return_id
|
||||
)
|
||||
|
||||
if (inboundShippingAction) {
|
||||
const items = orderChange.actions
|
||||
.filter((action) => action.action === ChangeActionType.RETURN_ITEM)
|
||||
.map((a) => ({
|
||||
id: a.details?.reference_id as string,
|
||||
quantity: a.details?.quantity as number,
|
||||
}))
|
||||
|
||||
shippingToRefresh.inbound = {
|
||||
shipping_method_id: inboundShippingAction.reference_id,
|
||||
order_id: orderChange.order_id,
|
||||
action_id: inboundShippingAction.id,
|
||||
context: {
|
||||
return_id: inboundShippingAction.return_id,
|
||||
return_items: items,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
if (outboundShippingAction) {
|
||||
const items = orderChange.actions
|
||||
.filter((action) => action.action === ChangeActionType.ITEM_ADD)
|
||||
.map((a) => ({
|
||||
id: a.details?.reference_id as string,
|
||||
quantity: a.details?.quantity as number,
|
||||
}))
|
||||
|
||||
shippingToRefresh.outbound = {
|
||||
shipping_method_id: outboundShippingAction.reference_id,
|
||||
order_id: orderChange.order_id,
|
||||
action_id: outboundShippingAction.id,
|
||||
context: {
|
||||
claim_id: outboundShippingAction.claim_id,
|
||||
claim_items: items,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
return shippingToRefresh
|
||||
}
|
||||
)
|
||||
|
||||
when({ refreshArgs }, ({ refreshArgs }) => !!refreshArgs.inbound).then(() =>
|
||||
maybeRefreshShippingMethodsWorkflow
|
||||
.runAsStep({
|
||||
input: refreshArgs.inbound,
|
||||
})
|
||||
.config({ name: "refresh-inbound-shipping-method" })
|
||||
)
|
||||
|
||||
when({ refreshArgs }, ({ refreshArgs }) => !!refreshArgs.outbound).then(
|
||||
() =>
|
||||
maybeRefreshShippingMethodsWorkflow
|
||||
.runAsStep({
|
||||
input: refreshArgs.outbound,
|
||||
})
|
||||
.config({ name: "refresh-outbound-shipping-method" })
|
||||
)
|
||||
|
||||
return new WorkflowResponse(void 0)
|
||||
}
|
||||
)
|
||||
@@ -12,6 +12,7 @@ import {
|
||||
WorkflowResponse,
|
||||
createStep,
|
||||
createWorkflow,
|
||||
transform,
|
||||
} from "@medusajs/framework/workflows-sdk"
|
||||
import { useRemoteQueryStep } from "../../../common"
|
||||
import {
|
||||
@@ -22,6 +23,7 @@ import {
|
||||
throwIfIsCancelled,
|
||||
throwIfOrderChangeIsNotActive,
|
||||
} from "../../utils/order-validation"
|
||||
import { refreshClaimShippingWorkflow } from "./refresh-shipping"
|
||||
|
||||
/**
|
||||
* The data to validate that claim items can be removed.
|
||||
@@ -48,14 +50,14 @@ export type RemoveClaimItemActionValidationStepInput = {
|
||||
/**
|
||||
* This step confirms that a claim's items, added as order items, can be removed.
|
||||
* If the order, claim, or order change is canceled, or the action is not claiming an item, the step will throw an error.
|
||||
*
|
||||
*
|
||||
* :::note
|
||||
*
|
||||
*
|
||||
* You can retrieve an order, order claim, and order change details using [Query](https://docs.medusajs.com/learn/fundamentals/module-links/query),
|
||||
* or [useQueryGraphStep](https://docs.medusajs.com/resources/references/medusa-workflows/steps/useQueryGraphStep).
|
||||
*
|
||||
*
|
||||
* :::
|
||||
*
|
||||
*
|
||||
* @example
|
||||
* const data = removeClaimItemActionValidationStep({
|
||||
* order: {
|
||||
@@ -104,22 +106,23 @@ export const removeClaimItemActionValidationStep = createStep(
|
||||
|
||||
/**
|
||||
* The data to remove order items from a claim.
|
||||
*
|
||||
*
|
||||
* @property action_id - The ID of the action associated with the outbound items.
|
||||
* Every item has an `actions` property, whose value is an array of actions.
|
||||
* You can find the action name `WRITE_OFF_ITEM` using its `action` property,
|
||||
* Every item has an `actions` property, whose value is an array of actions.
|
||||
* You can find the action name `WRITE_OFF_ITEM` using its `action` property,
|
||||
* and use the value of its `id` property.
|
||||
*/
|
||||
export type RemoveItemClaimActionWorkflowInput = OrderWorkflow.DeleteOrderClaimItemActionWorkflowInput
|
||||
export type RemoveItemClaimActionWorkflowInput =
|
||||
OrderWorkflow.DeleteOrderClaimItemActionWorkflowInput
|
||||
|
||||
export const removeItemClaimActionWorkflowId = "remove-item-claim-action"
|
||||
/**
|
||||
* This workflow removes order items from a claim. It's used by the
|
||||
* [Remove Claim Item Admin API Route](https://docs.medusajs.com/api/admin#claims_deleteclaimsidclaimitemsaction_id).
|
||||
*
|
||||
*
|
||||
* You can use this workflow within your customizations or your own custom workflows, allowing you to remove order items from a claim
|
||||
* in your custom flows.
|
||||
*
|
||||
*
|
||||
* @example
|
||||
* const { result } = await removeItemClaimActionWorkflow(container)
|
||||
* .run({
|
||||
@@ -128,9 +131,9 @@ export const removeItemClaimActionWorkflowId = "remove-item-claim-action"
|
||||
* action_id: "orchact_123",
|
||||
* }
|
||||
* })
|
||||
*
|
||||
*
|
||||
* @summary
|
||||
*
|
||||
*
|
||||
* Remove order items from a claim.
|
||||
*/
|
||||
export const removeItemClaimActionWorkflow = createWorkflow(
|
||||
@@ -176,6 +179,21 @@ export const removeItemClaimActionWorkflow = createWorkflow(
|
||||
|
||||
deleteOrderChangeActionsStep({ ids: [input.action_id] })
|
||||
|
||||
const refreshArgs = transform(
|
||||
{ orderChange, orderClaim },
|
||||
({ orderChange, orderClaim }) => {
|
||||
return {
|
||||
order_change_id: orderChange.id,
|
||||
claim_id: orderClaim.id,
|
||||
order_id: orderClaim.order_id,
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
refreshClaimShippingWorkflow.runAsStep({
|
||||
input: refreshArgs,
|
||||
})
|
||||
|
||||
return new WorkflowResponse(previewOrderChangeStep(order.id))
|
||||
}
|
||||
)
|
||||
|
||||
@@ -23,6 +23,7 @@ import {
|
||||
throwIfIsCancelled,
|
||||
throwIfOrderChangeIsNotActive,
|
||||
} from "../../utils/order-validation"
|
||||
import { refreshClaimShippingWorkflow } from "./refresh-shipping"
|
||||
|
||||
/**
|
||||
* The data to validate that a claim's outbound item can be updated.
|
||||
@@ -50,14 +51,14 @@ export type UpdateClaimAddNewItemValidationStepInput = {
|
||||
* This step validates that a claim's new or outbound item can be updated.
|
||||
* If the order, claim, or order change is canceled, no action is adding the item,
|
||||
* or the action is not adding an outbound item, the step will throw an error.
|
||||
*
|
||||
*
|
||||
* :::note
|
||||
*
|
||||
*
|
||||
* You can retrieve an order, order claim, and order change details using [Query](https://docs.medusajs.com/learn/fundamentals/module-links/query),
|
||||
* or [useQueryGraphStep](https://docs.medusajs.com/resources/references/medusa-workflows/steps/useQueryGraphStep).
|
||||
*
|
||||
*
|
||||
* :::
|
||||
*
|
||||
*
|
||||
* @example
|
||||
* const data = updateClaimAddItemValidationStep({
|
||||
* order: {
|
||||
@@ -114,10 +115,10 @@ export const updateClaimAddItemWorkflowId = "update-claim-add-item"
|
||||
/**
|
||||
* This workflow updates a claim's new or outbound item. It's used by the
|
||||
* [Update Outbound Item API Route](https://docs.medusajs.com/api/admin#claims_postclaimsidoutbounditemsaction_id).
|
||||
*
|
||||
*
|
||||
* You can use this workflow within your customizations or your own custom workflows, allowing you to update a claim's new or outbound item
|
||||
* in your custom flows.
|
||||
*
|
||||
*
|
||||
* @example
|
||||
* const { result } = await updateClaimAddItemWorkflow(container)
|
||||
* .run({
|
||||
@@ -129,9 +130,9 @@ export const updateClaimAddItemWorkflowId = "update-claim-add-item"
|
||||
* }
|
||||
* }
|
||||
* })
|
||||
*
|
||||
*
|
||||
* @summary
|
||||
*
|
||||
*
|
||||
* Update a claim's new or outbound item.
|
||||
*/
|
||||
export const updateClaimAddItemWorkflow = createWorkflow(
|
||||
@@ -190,6 +191,21 @@ export const updateClaimAddItemWorkflow = createWorkflow(
|
||||
|
||||
updateOrderChangeActionsStep([updateData])
|
||||
|
||||
const refreshArgs = transform(
|
||||
{ orderChange, orderClaim },
|
||||
({ orderChange, orderClaim }) => {
|
||||
return {
|
||||
order_change_id: orderChange.id,
|
||||
claim_id: orderClaim.id,
|
||||
order_id: orderClaim.order_id,
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
refreshClaimShippingWorkflow.runAsStep({
|
||||
input: refreshArgs,
|
||||
})
|
||||
|
||||
return new WorkflowResponse(previewOrderChangeStep(order.id))
|
||||
}
|
||||
)
|
||||
|
||||
@@ -28,14 +28,14 @@ export type BeginOrderExchangeValidationStepInput = {
|
||||
/**
|
||||
* This step validates that an exchange can be requested for an order.
|
||||
* If the order is canceled, the step will throw an error.
|
||||
*
|
||||
*
|
||||
* :::note
|
||||
*
|
||||
*
|
||||
* You can retrieve an order's details using [Query](https://docs.medusajs.com/learn/fundamentals/module-links/query),
|
||||
* or [useQueryGraphStep](https://docs.medusajs.com/resources/references/medusa-workflows/steps/useQueryGraphStep).
|
||||
*
|
||||
*
|
||||
* :::
|
||||
*
|
||||
*
|
||||
* @example
|
||||
* const data = beginOrderExchangeValidationStep({
|
||||
* order: {
|
||||
@@ -53,12 +53,12 @@ export const beginOrderExchangeValidationStep = createStep(
|
||||
|
||||
export const beginExchangeOrderWorkflowId = "begin-exchange-order"
|
||||
/**
|
||||
* This workflow requests an order exchange. It's used by the
|
||||
* This workflow requests an order exchange. It's used by the
|
||||
* [Create Exchange Admin API Route](https://docs.medusajs.com/api/admin#exchanges_postexchanges).
|
||||
*
|
||||
*
|
||||
* You can use this workflow within your customizations or your own custom workflows, allowing you to request an exchange
|
||||
* for an order in your custom flow.
|
||||
*
|
||||
*
|
||||
* @example
|
||||
* const { result } = await beginExchangeOrderWorkflow(container)
|
||||
* .run({
|
||||
@@ -66,9 +66,9 @@ export const beginExchangeOrderWorkflowId = "begin-exchange-order"
|
||||
* order_id: "order_123",
|
||||
* }
|
||||
* })
|
||||
*
|
||||
*
|
||||
* @summary
|
||||
*
|
||||
*
|
||||
* Request an order exchange.
|
||||
*/
|
||||
export const beginExchangeOrderWorkflow = createWorkflow(
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import {
|
||||
BigNumberInput,
|
||||
CalculatedRMAShippingContext,
|
||||
OrderChangeDTO,
|
||||
OrderDTO,
|
||||
OrderExchangeDTO,
|
||||
@@ -22,6 +23,7 @@ import {
|
||||
import { prepareShippingMethod } from "../../utils/prepare-shipping-method"
|
||||
import { createOrderChangeActionsWorkflow } from "../create-order-change-actions"
|
||||
import { updateOrderTaxLinesWorkflow } from "../update-tax-lines"
|
||||
import { fetchShippingOptionForOrderWorkflow } from "../../utils/fetch-shipping-option"
|
||||
|
||||
/**
|
||||
* The data to validate that a shipping method can be created for an exchange.
|
||||
@@ -44,14 +46,14 @@ export type CreateExchangeShippingMethodValidationStepInput = {
|
||||
/**
|
||||
* This step validates that an inbound or outbound shipping method can be created for an exchange.
|
||||
* If the order or exchange is canceled, or the order change is not active, the step will throw an error.
|
||||
*
|
||||
*
|
||||
* :::note
|
||||
*
|
||||
*
|
||||
* You can retrieve an order, order exchange, and order change details using [Query](https://docs.medusajs.com/learn/fundamentals/module-links/query),
|
||||
* or [useQueryGraphStep](https://docs.medusajs.com/resources/references/medusa-workflows/steps/useQueryGraphStep).
|
||||
*
|
||||
*
|
||||
* :::
|
||||
*
|
||||
*
|
||||
* @example
|
||||
* const data = createExchangeShippingMethodValidationStep({
|
||||
* order: {
|
||||
@@ -112,13 +114,13 @@ export const createExchangeShippingMethodWorkflowId =
|
||||
* This workflow creates an inbound (return) or outbound (delivery of new items) shipping method for an exchange.
|
||||
* It's used by the [Add Inbound Shipping Admin API Route](https://docs.medusajs.com/api/admin#exchanges_postexchangesidinboundshippingmethod)
|
||||
* and the [Add Outbound Shipping Admin API Route](https://docs.medusajs.com/api/admin#exchanges_postexchangesidoutboundshippingmethod).
|
||||
*
|
||||
*
|
||||
* You can use this workflow within your customizations or your own custom workflows, allowing you to create a shipping method
|
||||
* for an exchange in your custom flow.
|
||||
*
|
||||
*
|
||||
* @example
|
||||
* To create an outbound shipping method for the exchange:
|
||||
*
|
||||
*
|
||||
* ```ts
|
||||
* const { result } = await createExchangeShippingMethodWorkflow(container)
|
||||
* .run({
|
||||
@@ -128,9 +130,9 @@ export const createExchangeShippingMethodWorkflowId =
|
||||
* }
|
||||
* })
|
||||
* ```
|
||||
*
|
||||
*
|
||||
* To create an inbound shipping method, pass the ID of the return associated with the exchange:
|
||||
*
|
||||
*
|
||||
* ```ts
|
||||
* const { result } = await createExchangeShippingMethodWorkflow(container)
|
||||
* .run({
|
||||
@@ -141,14 +143,16 @@ export const createExchangeShippingMethodWorkflowId =
|
||||
* }
|
||||
* })
|
||||
* ```
|
||||
*
|
||||
*
|
||||
* @summary
|
||||
*
|
||||
*
|
||||
* Create an inbound or outbound shipping method for an exchange.
|
||||
*/
|
||||
export const createExchangeShippingMethodWorkflow = createWorkflow(
|
||||
createExchangeShippingMethodWorkflowId,
|
||||
function (input: CreateExchangeShippingMethodWorkflowInput): WorkflowResponse<OrderPreviewDTO> {
|
||||
function (
|
||||
input: CreateExchangeShippingMethodWorkflowInput
|
||||
): WorkflowResponse<OrderPreviewDTO> {
|
||||
const orderExchange: OrderExchangeDTO = useRemoteQueryStep({
|
||||
entry_point: "order_exchange",
|
||||
fields: ["id", "status", "order_id", "canceled_at"],
|
||||
@@ -165,25 +169,13 @@ export const createExchangeShippingMethodWorkflow = createWorkflow(
|
||||
throw_if_key_not_found: true,
|
||||
}).config({ name: "order-query" })
|
||||
|
||||
const shippingOptions = useRemoteQueryStep({
|
||||
entry_point: "shipping_option",
|
||||
fields: [
|
||||
"id",
|
||||
"name",
|
||||
"calculated_price.calculated_amount",
|
||||
"calculated_price.is_calculated_price_tax_inclusive",
|
||||
],
|
||||
variables: {
|
||||
id: input.shipping_option_id,
|
||||
calculated_price: {
|
||||
context: { currency_code: order.currency_code },
|
||||
},
|
||||
},
|
||||
}).config({ name: "fetch-shipping-option" })
|
||||
const isReturn = transform(input, (data) => {
|
||||
return !!data.return_id
|
||||
})
|
||||
|
||||
const orderChange: OrderChangeDTO = useRemoteQueryStep({
|
||||
entry_point: "order_change",
|
||||
fields: ["id", "status", "version"],
|
||||
fields: ["id", "status", "version", "actions.*"],
|
||||
variables: {
|
||||
filters: {
|
||||
order_id: orderExchange.order_id,
|
||||
@@ -194,6 +186,48 @@ export const createExchangeShippingMethodWorkflow = createWorkflow(
|
||||
list: false,
|
||||
}).config({ name: "order-change-query" })
|
||||
|
||||
const fetchShippingOptionInput = transform(
|
||||
{ input, isReturn, orderChange, order },
|
||||
(data) => {
|
||||
const changeActionType = data.isReturn
|
||||
? ChangeActionType.RETURN_ITEM
|
||||
: ChangeActionType.ITEM_ADD
|
||||
|
||||
const items = data.orderChange.actions
|
||||
.filter((action) => action.action === changeActionType)
|
||||
.map((a) => ({
|
||||
id: a.details?.reference_id,
|
||||
quantity: a.details?.quantity,
|
||||
}))
|
||||
|
||||
const context = data.isReturn
|
||||
? {
|
||||
return_id: data.input.return_id,
|
||||
return_items: items,
|
||||
}
|
||||
: {
|
||||
exchange_id: data.input.exchange_id,
|
||||
exchange_items: items,
|
||||
}
|
||||
|
||||
return {
|
||||
order_id: data.order.id,
|
||||
currency_code: data.order.currency_code,
|
||||
shipping_option_id: data.input.shipping_option_id,
|
||||
custom_amount: data.input.custom_amount,
|
||||
context: context as CalculatedRMAShippingContext,
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
const shippingOption = fetchShippingOptionForOrderWorkflow.runAsStep({
|
||||
input: fetchShippingOptionInput,
|
||||
})
|
||||
|
||||
const shippingOptions = transform(shippingOption, (shippingOption) => {
|
||||
return [shippingOption]
|
||||
})
|
||||
|
||||
createExchangeShippingMethodValidationStep({
|
||||
order,
|
||||
orderExchange,
|
||||
@@ -219,10 +253,6 @@ export const createExchangeShippingMethodWorkflow = createWorkflow(
|
||||
return createdMethods.map((item) => item.id)
|
||||
})
|
||||
|
||||
const isReturn = transform(input, (data) => {
|
||||
return !!data.return_id
|
||||
})
|
||||
|
||||
updateOrderTaxLinesWorkflow.runAsStep({
|
||||
input: {
|
||||
order_id: order.id,
|
||||
|
||||
@@ -22,6 +22,7 @@ import {
|
||||
import { addOrderLineItemsWorkflow } from "../add-line-items"
|
||||
import { createOrderChangeActionsWorkflow } from "../create-order-change-actions"
|
||||
import { updateOrderTaxLinesWorkflow } from "../update-tax-lines"
|
||||
import { refreshExchangeShippingWorkflow } from "./refresh-shipping"
|
||||
|
||||
/**
|
||||
* The data to validate that new or outbound items can be added to an exchange.
|
||||
@@ -44,14 +45,14 @@ export type ExchangeAddNewItemValidationStepInput = {
|
||||
/**
|
||||
* This step validates that new or outbound items can be added to an exchange.
|
||||
* If the order or exchange is canceled, or the order change is not active, the step will throw an error.
|
||||
*
|
||||
*
|
||||
* :::note
|
||||
*
|
||||
*
|
||||
* You can retrieve an order, order exchange, and order change details using [Query](https://docs.medusajs.com/learn/fundamentals/module-links/query),
|
||||
* or [useQueryGraphStep](https://docs.medusajs.com/resources/references/medusa-workflows/steps/useQueryGraphStep).
|
||||
*
|
||||
*
|
||||
* :::
|
||||
*
|
||||
*
|
||||
* @example
|
||||
* const data = exchangeAddNewItemValidationStep({
|
||||
* order: {
|
||||
@@ -85,10 +86,10 @@ export const orderExchangeAddNewItemWorkflowId = "exchange-add-new-item"
|
||||
/**
|
||||
* This workflow adds new or outbound items to an exchange. It's used by the
|
||||
* [Add Outbound Items Admin API Route](https://docs.medusajs.com/api/admin#exchanges_postexchangesidoutbounditems).
|
||||
*
|
||||
*
|
||||
* You can use this workflow within your customizations or your own custom workflows, allowing you to add new or outbound items
|
||||
* to an exchange in your custom flow.
|
||||
*
|
||||
*
|
||||
* @example
|
||||
* const { result } = await orderExchangeAddNewItemWorkflow(container)
|
||||
* .run({
|
||||
@@ -102,9 +103,9 @@ export const orderExchangeAddNewItemWorkflowId = "exchange-add-new-item"
|
||||
* ]
|
||||
* }
|
||||
* })
|
||||
*
|
||||
*
|
||||
* @summary
|
||||
*
|
||||
*
|
||||
* Add new or outbound items to an exchange.
|
||||
*/
|
||||
export const orderExchangeAddNewItemWorkflow = createWorkflow(
|
||||
@@ -191,6 +192,21 @@ export const orderExchangeAddNewItemWorkflow = createWorkflow(
|
||||
input: orderChangeActionInput,
|
||||
})
|
||||
|
||||
const refreshArgs = transform(
|
||||
{ orderChange, orderExchange },
|
||||
({ orderChange, orderExchange }) => {
|
||||
return {
|
||||
order_change_id: orderChange.id,
|
||||
exchange_id: orderExchange.id,
|
||||
order_id: orderExchange.order_id,
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
refreshExchangeShippingWorkflow.runAsStep({
|
||||
input: refreshArgs,
|
||||
})
|
||||
|
||||
return new WorkflowResponse(previewOrderChangeStep(orderExchange.order_id))
|
||||
}
|
||||
)
|
||||
|
||||
@@ -26,6 +26,7 @@ import {
|
||||
throwIfOrderChangeIsNotActive,
|
||||
} from "../../utils/order-validation"
|
||||
import { createOrderChangeActionsWorkflow } from "../create-order-change-actions"
|
||||
import { refreshExchangeShippingWorkflow } from "./refresh-shipping"
|
||||
|
||||
/**
|
||||
* The data to validate that items can be returned as part of an exchange.
|
||||
@@ -55,16 +56,16 @@ export type ExchangeRequestItemReturnValidationStepInput = {
|
||||
|
||||
/**
|
||||
* This step validates that items can be returned as part of an exchange.
|
||||
* If the order, exchange, or return is canceled, the order change is not active,
|
||||
* If the order, exchange, or return is canceled, the order change is not active,
|
||||
* or the item doesn't exist in the order, the step will throw an error.
|
||||
*
|
||||
*
|
||||
* :::note
|
||||
*
|
||||
*
|
||||
* You can retrieve an order, order exchange, and order return details using [Query](https://docs.medusajs.com/learn/fundamentals/module-links/query),
|
||||
* or [useQueryGraphStep](https://docs.medusajs.com/resources/references/medusa-workflows/steps/useQueryGraphStep).
|
||||
*
|
||||
*
|
||||
* :::
|
||||
*
|
||||
*
|
||||
* @example
|
||||
* const data = exchangeRequestItemReturnValidationStep({
|
||||
* order: {
|
||||
@@ -113,10 +114,10 @@ export const orderExchangeRequestItemReturnWorkflowId =
|
||||
/**
|
||||
* This workflow adds inbound items to be retuned as part of the exchange. It's used
|
||||
* by the [Add Inbound Items Admin API Route](https://docs.medusajs.com/api/admin#exchanges_postexchangesidinbounditems).
|
||||
*
|
||||
*
|
||||
* You can use this workflow within your customizations or your own custom workflows, allowing you to add inbound items
|
||||
* to be returned as part of an exchange in your custom flow.
|
||||
*
|
||||
*
|
||||
* @example
|
||||
* const { result } = await orderExchangeRequestItemReturnWorkflow(container)
|
||||
* .run({
|
||||
@@ -131,9 +132,9 @@ export const orderExchangeRequestItemReturnWorkflowId =
|
||||
* ]
|
||||
* }
|
||||
* })
|
||||
*
|
||||
*
|
||||
* @summary
|
||||
*
|
||||
*
|
||||
* Add inbound items to be returned as part of the exchange.
|
||||
*/
|
||||
export const orderExchangeRequestItemReturnWorkflow = createWorkflow(
|
||||
@@ -260,6 +261,21 @@ export const orderExchangeRequestItemReturnWorkflow = createWorkflow(
|
||||
input: orderChangeActionInput,
|
||||
})
|
||||
|
||||
const refreshArgs = transform(
|
||||
{ orderChange, orderExchange },
|
||||
({ orderChange, orderExchange }) => {
|
||||
return {
|
||||
order_change_id: orderChange.id,
|
||||
exchange_id: orderExchange.id,
|
||||
order_id: orderExchange.order_id,
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
refreshExchangeShippingWorkflow.runAsStep({
|
||||
input: refreshArgs,
|
||||
})
|
||||
|
||||
return new WorkflowResponse(previewOrderChangeStep(orderExchange.order_id))
|
||||
}
|
||||
)
|
||||
|
||||
@@ -0,0 +1,150 @@
|
||||
import { OrderChangeDTO } from "@medusajs/framework/types"
|
||||
import { ChangeActionType, OrderChangeStatus } from "@medusajs/framework/utils"
|
||||
import {
|
||||
WorkflowData,
|
||||
WorkflowResponse,
|
||||
createWorkflow,
|
||||
transform,
|
||||
when,
|
||||
} from "@medusajs/framework/workflows-sdk"
|
||||
|
||||
import { maybeRefreshShippingMethodsWorkflow } from "../../utils/maybe-refresh-shipping-methods"
|
||||
import { useQueryGraphStep } from "../../../common"
|
||||
|
||||
/**
|
||||
* The data to refresh the shipping methods for an exchange.
|
||||
*/
|
||||
export type RefreshExchangeShippingWorkflowInput = {
|
||||
/**
|
||||
* The order change's ID.
|
||||
*/
|
||||
order_change_id: string
|
||||
/**
|
||||
* The exchange's details.
|
||||
*/
|
||||
exchange_id: string
|
||||
/**
|
||||
* The order's ID.
|
||||
*/
|
||||
order_id: string
|
||||
}
|
||||
|
||||
export const refreshExchangeShippingWorkflowId = "refresh-exchange-shipping"
|
||||
/**
|
||||
* This workflow refreshes the shipping methods for an exchange in case the shipping option is calculated.
|
||||
* It refreshes both inbound and outbound shipping methods.
|
||||
*
|
||||
* @summary
|
||||
*
|
||||
* Refresh exchange shipping.
|
||||
*/
|
||||
export const refreshExchangeShippingWorkflow = createWorkflow(
|
||||
refreshExchangeShippingWorkflowId,
|
||||
function (
|
||||
input: WorkflowData<RefreshExchangeShippingWorkflowInput>
|
||||
): WorkflowResponse<void> {
|
||||
const orderChangeQuery = useQueryGraphStep({
|
||||
entity: "order_change",
|
||||
fields: [
|
||||
"id",
|
||||
"status",
|
||||
"order_id",
|
||||
"exchange_id",
|
||||
"return_id",
|
||||
"actions.*",
|
||||
],
|
||||
filters: {
|
||||
order_id: input.order_id,
|
||||
exchange_id: input.exchange_id,
|
||||
status: [OrderChangeStatus.PENDING, OrderChangeStatus.REQUESTED],
|
||||
},
|
||||
}).config({ name: "order-change-query" })
|
||||
|
||||
const orderChange: OrderChangeDTO = transform(
|
||||
orderChangeQuery,
|
||||
({ data }) => data[0]
|
||||
)
|
||||
|
||||
const shippingToRefresh = transform(
|
||||
{ input, orderChange },
|
||||
({ input, orderChange }) => {
|
||||
const shippingToRefresh = {} as Record<"inbound" | "outbound", any>
|
||||
|
||||
const inboundShippingAction = orderChange.actions.find(
|
||||
(action) =>
|
||||
action.action === ChangeActionType.SHIPPING_ADD &&
|
||||
!!action.return_id
|
||||
)
|
||||
|
||||
const outboundShippingAction = orderChange.actions.find(
|
||||
(action) =>
|
||||
action.action === ChangeActionType.SHIPPING_ADD && !action.return_id
|
||||
)
|
||||
|
||||
if (inboundShippingAction) {
|
||||
const items = orderChange.actions
|
||||
.filter((action) => action.action === ChangeActionType.RETURN_ITEM)
|
||||
.map((a) => ({
|
||||
id: a.details?.reference_id as string,
|
||||
quantity: a.details?.quantity as number,
|
||||
}))
|
||||
|
||||
shippingToRefresh.inbound = {
|
||||
shipping_method_id: inboundShippingAction.reference_id,
|
||||
order_id: orderChange.order_id,
|
||||
action_id: inboundShippingAction.id,
|
||||
context: {
|
||||
return_id: inboundShippingAction.return_id,
|
||||
return_items: items,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
if (outboundShippingAction) {
|
||||
const items = orderChange.actions
|
||||
.filter((action) => action.action === ChangeActionType.ITEM_ADD)
|
||||
.map((a) => ({
|
||||
id: a.details?.reference_id as string,
|
||||
quantity: a.details?.quantity as number,
|
||||
}))
|
||||
|
||||
shippingToRefresh.outbound = {
|
||||
shipping_method_id: outboundShippingAction.reference_id,
|
||||
order_id: orderChange.order_id,
|
||||
action_id: outboundShippingAction.id,
|
||||
context: {
|
||||
exchange_id: outboundShippingAction.exchange_id,
|
||||
exchange_items: items,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
return shippingToRefresh
|
||||
}
|
||||
)
|
||||
|
||||
when(
|
||||
{ shippingToRefresh },
|
||||
({ shippingToRefresh }) => !!shippingToRefresh.inbound
|
||||
).then(() =>
|
||||
maybeRefreshShippingMethodsWorkflow
|
||||
.runAsStep({
|
||||
input: shippingToRefresh.inbound,
|
||||
})
|
||||
.config({ name: "refresh-inbound-shipping-method" })
|
||||
)
|
||||
|
||||
when(
|
||||
{ shippingToRefresh },
|
||||
({ shippingToRefresh }) => !!shippingToRefresh.outbound
|
||||
).then(() =>
|
||||
maybeRefreshShippingMethodsWorkflow
|
||||
.runAsStep({
|
||||
input: shippingToRefresh.outbound,
|
||||
})
|
||||
.config({ name: "refresh-outbound-shipping-method" })
|
||||
)
|
||||
|
||||
return new WorkflowResponse(void 0)
|
||||
}
|
||||
)
|
||||
@@ -25,6 +25,7 @@ import {
|
||||
throwIfOrderChangeIsNotActive,
|
||||
} from "../../utils/order-validation"
|
||||
import { removeExchangeShippingMethodWorkflow } from "./remove-exchange-shipping-method"
|
||||
import { refreshExchangeShippingWorkflow } from "./refresh-shipping"
|
||||
|
||||
/**
|
||||
* The data to validate that an outbound item can be removed from an exchange.
|
||||
@@ -52,14 +53,14 @@ export type RemoveExchangeItemActionValidationStepInput = {
|
||||
* This step validates that an outbound item can be removed from an exchange.
|
||||
* If the order or exchange is canceled, the item is not found,
|
||||
* or the order change is not active, the step will throw an error.
|
||||
*
|
||||
*
|
||||
* :::note
|
||||
*
|
||||
*
|
||||
* You can retrieve an order, order exchange, and order change details using [Query](https://docs.medusajs.com/learn/fundamentals/module-links/query),
|
||||
* or [useQueryGraphStep](https://docs.medusajs.com/resources/references/medusa-workflows/steps/useQueryGraphStep).
|
||||
*
|
||||
*
|
||||
* :::
|
||||
*
|
||||
*
|
||||
* @example
|
||||
* const data = removeExchangeItemActionValidationStep({
|
||||
* order: {
|
||||
@@ -79,7 +80,7 @@ export type RemoveExchangeItemActionValidationStepInput = {
|
||||
* action_id: "orchact_123",
|
||||
* }
|
||||
* })
|
||||
*
|
||||
*
|
||||
*/
|
||||
export const removeExchangeItemActionValidationStep = createStep(
|
||||
"remove-item-exchange-action-validation",
|
||||
@@ -111,10 +112,10 @@ export const removeItemExchangeActionWorkflowId = "remove-item-exchange-action"
|
||||
/**
|
||||
* This workflow removes an outbound or new item from an exchange. It's used by
|
||||
* the [Remove Outbound Item API Route](https://docs.medusajs.com/api/admin#exchanges_deleteexchangesidoutbounditemsaction_id).
|
||||
*
|
||||
*
|
||||
* You can use this workflow within your customizations or your own custom workflows, allowing you to remove an outbound or new item
|
||||
* from an exchange in your custom flow.
|
||||
*
|
||||
*
|
||||
* @example
|
||||
* const { result } = await removeItemExchangeActionWorkflow(container)
|
||||
* .run({
|
||||
@@ -123,9 +124,9 @@ export const removeItemExchangeActionWorkflowId = "remove-item-exchange-action"
|
||||
* action_id: "orchact_123",
|
||||
* }
|
||||
* })
|
||||
*
|
||||
*
|
||||
* @summary
|
||||
*
|
||||
*
|
||||
* Remove an outbound or new item from an exchange.
|
||||
*/
|
||||
export const removeItemExchangeActionWorkflow = createWorkflow(
|
||||
@@ -227,6 +228,28 @@ export const removeItemExchangeActionWorkflow = createWorkflow(
|
||||
})
|
||||
})
|
||||
|
||||
when(
|
||||
{ actionIdToDelete, orderExchange, orderChange },
|
||||
({ actionIdToDelete }) => {
|
||||
return !actionIdToDelete
|
||||
}
|
||||
).then(() => {
|
||||
const refreshArgs = transform(
|
||||
{ orderChange, orderExchange },
|
||||
({ orderChange, orderExchange }) => {
|
||||
return {
|
||||
order_change_id: orderChange.id,
|
||||
exchange_id: orderExchange.id,
|
||||
order_id: orderExchange.order_id,
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
refreshExchangeShippingWorkflow.runAsStep({
|
||||
input: refreshArgs,
|
||||
})
|
||||
})
|
||||
|
||||
return new WorkflowResponse(previewOrderChangeStep(order.id))
|
||||
}
|
||||
)
|
||||
|
||||
@@ -23,6 +23,7 @@ import {
|
||||
throwIfIsCancelled,
|
||||
throwIfOrderChangeIsNotActive,
|
||||
} from "../../utils/order-validation"
|
||||
import { refreshExchangeShippingWorkflow } from "./refresh-shipping"
|
||||
|
||||
/**
|
||||
* The data to validate that an outbound or new item in an exchange can be updated.
|
||||
@@ -50,14 +51,14 @@ export type UpdateExchangeAddItemValidationStepInput = {
|
||||
* This step validates that an outbound or new item can be removed from an exchange.
|
||||
* If the order or exchange is canceled, the item is not found in the exchange,
|
||||
* or the order change is not active, the step will throw an error.
|
||||
*
|
||||
*
|
||||
* :::note
|
||||
*
|
||||
*
|
||||
* You can retrieve an order, order exchange, and order change details using [Query](https://docs.medusajs.com/learn/fundamentals/module-links/query),
|
||||
* or [useQueryGraphStep](https://docs.medusajs.com/resources/references/medusa-workflows/steps/useQueryGraphStep).
|
||||
*
|
||||
*
|
||||
* :::
|
||||
*
|
||||
*
|
||||
* @example
|
||||
* const data = updateExchangeAddItemValidationStep({
|
||||
* order: {
|
||||
@@ -114,10 +115,10 @@ export const updateExchangeAddItemWorkflowId = "update-exchange-add-item"
|
||||
/**
|
||||
* This workflow updates an outbound or new item in the exchange. It's used by the
|
||||
* [Update Outbound Item Admin API Route](https://docs.medusajs.com/api/admin#exchanges_postexchangesidoutbounditemsaction_id).
|
||||
*
|
||||
*
|
||||
* You can use this workflow within your customizations or your own custom workflows, allowing you to update an outbound or new item
|
||||
* in an exchange in your custom flow.
|
||||
*
|
||||
*
|
||||
* @example
|
||||
* const { result } = await updateExchangeAddItemWorkflow(container)
|
||||
* .run({
|
||||
@@ -129,9 +130,9 @@ export const updateExchangeAddItemWorkflowId = "update-exchange-add-item"
|
||||
* }
|
||||
* }
|
||||
* })
|
||||
*
|
||||
*
|
||||
* @summary
|
||||
*
|
||||
*
|
||||
* Update an outbound or new item in an exchange.
|
||||
*/
|
||||
export const updateExchangeAddItemWorkflow = createWorkflow(
|
||||
@@ -195,6 +196,21 @@ export const updateExchangeAddItemWorkflow = createWorkflow(
|
||||
|
||||
updateOrderChangeActionsStep([updateData])
|
||||
|
||||
const refreshArgs = transform(
|
||||
{ orderChange, orderExchange },
|
||||
({ orderChange, orderExchange }) => {
|
||||
return {
|
||||
order_change_id: orderChange.id,
|
||||
exchange_id: orderExchange.id,
|
||||
order_id: orderExchange.order_id,
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
refreshExchangeShippingWorkflow.runAsStep({
|
||||
input: refreshArgs,
|
||||
})
|
||||
|
||||
return new WorkflowResponse(previewOrderChangeStep(order.id))
|
||||
}
|
||||
)
|
||||
|
||||
@@ -185,7 +185,6 @@ export const createOrderEditShippingMethodWorkflow = createWorkflow(
|
||||
createdMethods,
|
||||
customPrice: input.custom_amount,
|
||||
orderChange,
|
||||
input,
|
||||
},
|
||||
({
|
||||
shippingOptions,
|
||||
@@ -193,7 +192,6 @@ export const createOrderEditShippingMethodWorkflow = createWorkflow(
|
||||
createdMethods,
|
||||
customPrice,
|
||||
orderChange,
|
||||
input,
|
||||
}) => {
|
||||
const shippingOption = shippingOptions[0]
|
||||
const createdMethod = createdMethods[0]
|
||||
|
||||
@@ -22,6 +22,7 @@ import {
|
||||
import { prepareShippingMethod } from "../../utils/prepare-shipping-method"
|
||||
import { createOrderChangeActionsWorkflow } from "../create-order-change-actions"
|
||||
import { updateOrderTaxLinesWorkflow } from "../update-tax-lines"
|
||||
import { fetchShippingOptionForOrderWorkflow } from "../../utils/fetch-shipping-option"
|
||||
|
||||
/**
|
||||
* The data to validate that a shipping method can be created for a return.
|
||||
@@ -44,14 +45,14 @@ export type CreateReturnShippingMethodValidationStepInput = {
|
||||
/**
|
||||
* This step validates that a shipping method can be created for a return.
|
||||
* If the order or return is canceled, or the order change is not active, the step will throw an error.
|
||||
*
|
||||
*
|
||||
* :::note
|
||||
*
|
||||
*
|
||||
* You can retrieve an order, return, and order change details using [Query](https://docs.medusajs.com/learn/fundamentals/module-links/query),
|
||||
* or [useQueryGraphStep](https://docs.medusajs.com/resources/references/medusa-workflows/steps/useQueryGraphStep).
|
||||
*
|
||||
*
|
||||
* :::
|
||||
*
|
||||
*
|
||||
* @example
|
||||
* const data = createReturnShippingMethodValidationStep({
|
||||
* order: {
|
||||
@@ -113,10 +114,10 @@ export const createReturnShippingMethodWorkflowId =
|
||||
/**
|
||||
* This workflow creates a shipping method for a return. It's used by the
|
||||
* [Add Shipping Method Store API Route](https://docs.medusajs.com/api/admin#returns_postreturnsidshippingmethod).
|
||||
*
|
||||
*
|
||||
* You can use this workflow within your customizations or your own custom workflows, allowing you
|
||||
* to create a shipping method for a return in your custom flows.
|
||||
*
|
||||
*
|
||||
* @example
|
||||
* const { result } = await createReturnShippingMethodWorkflow(container)
|
||||
* .run({
|
||||
@@ -125,14 +126,16 @@ export const createReturnShippingMethodWorkflowId =
|
||||
* shipping_option_id: "so_123",
|
||||
* }
|
||||
* })
|
||||
*
|
||||
*
|
||||
* @summary
|
||||
*
|
||||
*
|
||||
* Create a shipping method for a return.
|
||||
*/
|
||||
export const createReturnShippingMethodWorkflow = createWorkflow(
|
||||
createReturnShippingMethodWorkflowId,
|
||||
function (input: CreateReturnShippingMethodWorkflowInput): WorkflowResponse<OrderPreviewDTO> {
|
||||
function (
|
||||
input: CreateReturnShippingMethodWorkflowInput
|
||||
): WorkflowResponse<OrderPreviewDTO> {
|
||||
const orderReturn: ReturnDTO = useRemoteQueryStep({
|
||||
entry_point: "return",
|
||||
fields: [
|
||||
@@ -156,25 +159,9 @@ export const createReturnShippingMethodWorkflow = createWorkflow(
|
||||
throw_if_key_not_found: true,
|
||||
}).config({ name: "order-query" })
|
||||
|
||||
const shippingOptions = useRemoteQueryStep({
|
||||
entry_point: "shipping_option",
|
||||
fields: [
|
||||
"id",
|
||||
"name",
|
||||
"calculated_price.calculated_amount",
|
||||
"calculated_price.is_calculated_price_tax_inclusive",
|
||||
],
|
||||
variables: {
|
||||
id: input.shipping_option_id,
|
||||
calculated_price: {
|
||||
context: { currency_code: order.currency_code },
|
||||
},
|
||||
},
|
||||
}).config({ name: "fetch-shipping-option" })
|
||||
|
||||
const orderChange: OrderChangeDTO = useRemoteQueryStep({
|
||||
entry_point: "order_change",
|
||||
fields: ["id", "status", "version"],
|
||||
fields: ["id", "status", "version", "actions.*"],
|
||||
variables: {
|
||||
filters: {
|
||||
order_id: orderReturn.order_id,
|
||||
@@ -185,6 +172,36 @@ export const createReturnShippingMethodWorkflow = createWorkflow(
|
||||
list: false,
|
||||
}).config({ name: "order-change-query" })
|
||||
|
||||
const shippingOptionFetchInput = transform(
|
||||
{ orderChange, input, order, orderReturn },
|
||||
({ orderChange, input, order, orderReturn }) => {
|
||||
return {
|
||||
order_id: order.id,
|
||||
shipping_option_id: input.shipping_option_id,
|
||||
currency_code: order.currency_code,
|
||||
context: {
|
||||
return_id: orderReturn.id,
|
||||
return_items: orderChange.actions
|
||||
.filter(
|
||||
(action) => action.action === ChangeActionType.RETURN_ITEM
|
||||
)
|
||||
.map((a) => ({
|
||||
id: a.details?.reference_id as string,
|
||||
quantity: a.details?.quantity as number,
|
||||
})),
|
||||
},
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
const shippingOption = fetchShippingOptionForOrderWorkflow.runAsStep({
|
||||
input: shippingOptionFetchInput,
|
||||
})
|
||||
|
||||
const shippingOptions = transform(shippingOption, (shippingOption) => {
|
||||
return [shippingOption]
|
||||
})
|
||||
|
||||
createReturnShippingMethodValidationStep({
|
||||
order,
|
||||
orderReturn,
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
import { OrderChangeDTO } from "@medusajs/framework/types"
|
||||
import { ChangeActionType, OrderChangeStatus } from "@medusajs/framework/utils"
|
||||
import {
|
||||
WorkflowData,
|
||||
WorkflowResponse,
|
||||
createWorkflow,
|
||||
transform,
|
||||
when,
|
||||
} from "@medusajs/framework/workflows-sdk"
|
||||
|
||||
import { maybeRefreshShippingMethodsWorkflow } from "../../utils/maybe-refresh-shipping-methods"
|
||||
import { useQueryGraphStep } from "../../../common"
|
||||
|
||||
/**
|
||||
* The data to validate that items can be added to a return.
|
||||
*/
|
||||
export type RequestItemReturnValidationStepInput = {
|
||||
/**
|
||||
* The order change's ID.
|
||||
*/
|
||||
order_change_id: string
|
||||
/**
|
||||
* The return's details.
|
||||
*/
|
||||
return_id: string
|
||||
/**
|
||||
* The order's ID.
|
||||
*/
|
||||
order_id: string
|
||||
}
|
||||
|
||||
export const refreshReturnShippingWorkflowId = "refresh-return-shipping"
|
||||
/**
|
||||
* This workflow refreshes the shipping method for a return in case the shipping option is calculated.
|
||||
*
|
||||
* @summary
|
||||
*
|
||||
* Refresh return shipping.
|
||||
*/
|
||||
export const refreshReturnShippingWorkflow = createWorkflow(
|
||||
refreshReturnShippingWorkflowId,
|
||||
function (
|
||||
input: WorkflowData<RequestItemReturnValidationStepInput>
|
||||
): WorkflowResponse<void> {
|
||||
const orderChangeQuery = useQueryGraphStep({
|
||||
entity: "order_change",
|
||||
fields: ["id", "status", "order_id", "return_id", "actions.*"],
|
||||
filters: {
|
||||
order_id: input.order_id,
|
||||
return_id: input.return_id,
|
||||
status: [OrderChangeStatus.PENDING, OrderChangeStatus.REQUESTED],
|
||||
},
|
||||
}).config({ name: "order-change-query" })
|
||||
|
||||
const orderChange: OrderChangeDTO = transform(
|
||||
orderChangeQuery,
|
||||
({ data }) => data[0]
|
||||
)
|
||||
|
||||
const refreshArgs = transform(
|
||||
{ input, orderChange },
|
||||
({ input, orderChange }) => {
|
||||
const shippingAction = orderChange.actions.find(
|
||||
(action) => action.action === ChangeActionType.SHIPPING_ADD
|
||||
)
|
||||
|
||||
const items = orderChange.actions
|
||||
.filter((action) => action.action === ChangeActionType.RETURN_ITEM)
|
||||
.map((a) => ({
|
||||
id: a.details?.reference_id as string,
|
||||
quantity: a.details?.quantity as number,
|
||||
}))
|
||||
|
||||
if (shippingAction) {
|
||||
return {
|
||||
shipping_method_id: shippingAction.reference_id,
|
||||
order_id: orderChange.order_id,
|
||||
action_id: shippingAction.id,
|
||||
context: {
|
||||
return_id: input.return_id,
|
||||
return_items: items,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
)
|
||||
|
||||
when({ refreshArgs }, ({ refreshArgs }) => refreshArgs !== null).then(() =>
|
||||
maybeRefreshShippingMethodsWorkflow.runAsStep({
|
||||
input: refreshArgs,
|
||||
})
|
||||
)
|
||||
|
||||
return new WorkflowResponse(void 0)
|
||||
}
|
||||
)
|
||||
@@ -26,6 +26,7 @@ import {
|
||||
} from "../../utils/order-validation"
|
||||
import { removeReturnShippingMethodWorkflow } from "./remove-return-shipping-method"
|
||||
import { updateReturnWorkflow } from "./update-return"
|
||||
import { refreshReturnShippingWorkflow } from "./refresh-shipping"
|
||||
|
||||
/**
|
||||
* The data to validate that a return item can be removed.
|
||||
@@ -54,14 +55,14 @@ export type RemoveItemReturnActionValidationStepInput = {
|
||||
* If the order or return is canceled, the order change is not active,
|
||||
* the return request is not found,
|
||||
* or the action is not a request return action, the step will throw an error.
|
||||
*
|
||||
*
|
||||
* :::note
|
||||
*
|
||||
*
|
||||
* You can retrieve an order, return, and order change details using [Query](https://docs.medusajs.com/learn/fundamentals/module-links/query),
|
||||
* or [useQueryGraphStep](https://docs.medusajs.com/resources/references/medusa-workflows/steps/useQueryGraphStep).
|
||||
*
|
||||
*
|
||||
* :::
|
||||
*
|
||||
*
|
||||
* @example
|
||||
* const data = removeReturnItemActionValidationStep({
|
||||
* order: {
|
||||
@@ -114,10 +115,10 @@ export const removeItemReturnActionWorkflowId = "remove-item-return-action"
|
||||
/**
|
||||
* This workflow removes a return item. It's used by the
|
||||
* [Remove Item from Return Admin API Route](https://docs.medusajs.com/api/admin#returns_deletereturnsidrequestitemsaction_id).
|
||||
*
|
||||
*
|
||||
* You can use this workflow within your customizations or your own custom workflows, allowing you
|
||||
* to remove an item from a return request in your custom flows.
|
||||
*
|
||||
*
|
||||
* @example
|
||||
* const { result } = await removeItemReturnActionWorkflow(container)
|
||||
* .run({
|
||||
@@ -126,9 +127,9 @@ export const removeItemReturnActionWorkflowId = "remove-item-return-action"
|
||||
* action_id: "orchac_123",
|
||||
* }
|
||||
* })
|
||||
*
|
||||
*
|
||||
* @summary
|
||||
*
|
||||
*
|
||||
* Remove an item from a return.
|
||||
*/
|
||||
export const removeItemReturnActionWorkflow = createWorkflow(
|
||||
@@ -249,6 +250,25 @@ export const removeItemReturnActionWorkflow = createWorkflow(
|
||||
})
|
||||
})
|
||||
|
||||
when({ actionIdToDelete }, ({ actionIdToDelete }) => {
|
||||
return !actionIdToDelete
|
||||
}).then(() => {
|
||||
const refreshArgs = transform(
|
||||
{ orderChange, orderReturn },
|
||||
({ orderChange, orderReturn }) => {
|
||||
return {
|
||||
order_change_id: orderChange.id,
|
||||
return_id: orderReturn.id,
|
||||
order_id: orderReturn.order_id,
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
refreshReturnShippingWorkflow.runAsStep({
|
||||
input: refreshArgs,
|
||||
})
|
||||
})
|
||||
|
||||
return new WorkflowResponse(previewOrderChangeStep(order.id))
|
||||
}
|
||||
)
|
||||
|
||||
@@ -22,7 +22,7 @@ import {
|
||||
} from "../../utils/order-validation"
|
||||
import { validateReturnReasons } from "../../utils/validate-return-reason"
|
||||
import { createOrderChangeActionsWorkflow } from "../create-order-change-actions"
|
||||
|
||||
import { refreshReturnShippingWorkflow } from "./refresh-shipping"
|
||||
/**
|
||||
* The data to validate that items can be added to a return.
|
||||
*/
|
||||
@@ -50,14 +50,14 @@ export type RequestItemReturnValidationStepInput = {
|
||||
* If the order or return is canceled, the order change is not active,
|
||||
* the items do not exist in the order, or the return reasons are invalid,
|
||||
* the step will throw an error.
|
||||
*
|
||||
*
|
||||
* :::note
|
||||
*
|
||||
*
|
||||
* You can retrieve an order, return, and order change details using [Query](https://docs.medusajs.com/learn/fundamentals/module-links/query),
|
||||
* or [useQueryGraphStep](https://docs.medusajs.com/resources/references/medusa-workflows/steps/useQueryGraphStep).
|
||||
*
|
||||
*
|
||||
* :::
|
||||
*
|
||||
*
|
||||
* @example
|
||||
* const data = requestItemReturnValidationStep({
|
||||
* order: {
|
||||
@@ -110,12 +110,12 @@ export const requestItemReturnValidationStep = createStep(
|
||||
|
||||
export const requestItemReturnWorkflowId = "request-item-return"
|
||||
/**
|
||||
* This workflow adds items to a return. It's used by the
|
||||
* This workflow adds items to a return. It's used by the
|
||||
* [Add Requested Items to Return Admin API Route](https://docs.medusajs.com/api/admin#returns_postreturnsidrequestitems).
|
||||
*
|
||||
*
|
||||
* You can use this workflow within your customizations or your own custom workflows, allowing you to add items to a return
|
||||
* in your custom flows.
|
||||
*
|
||||
*
|
||||
* @example
|
||||
* const { result } = await requestItemReturnWorkflow(container)
|
||||
* .run({
|
||||
@@ -129,9 +129,9 @@ export const requestItemReturnWorkflowId = "request-item-return"
|
||||
* ]
|
||||
* }
|
||||
* })
|
||||
*
|
||||
*
|
||||
* @summary
|
||||
*
|
||||
*
|
||||
* Add items to a return.
|
||||
*/
|
||||
export const requestItemReturnWorkflow = createWorkflow(
|
||||
@@ -201,6 +201,21 @@ export const requestItemReturnWorkflow = createWorkflow(
|
||||
input: orderChangeActionInput,
|
||||
})
|
||||
|
||||
const refreshArgs = transform(
|
||||
{ orderChange, orderReturn },
|
||||
({ orderChange, orderReturn }) => {
|
||||
return {
|
||||
order_change_id: orderChange.id,
|
||||
return_id: orderReturn.id,
|
||||
order_id: orderReturn.order_id,
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
refreshReturnShippingWorkflow.runAsStep({
|
||||
input: refreshArgs,
|
||||
})
|
||||
|
||||
return new WorkflowResponse(previewOrderChangeStep(order.id))
|
||||
}
|
||||
)
|
||||
|
||||
@@ -28,6 +28,7 @@ import {
|
||||
throwIfOrderChangeIsNotActive,
|
||||
} from "../../utils/order-validation"
|
||||
import { validateReturnReasons } from "../../utils/validate-return-reason"
|
||||
import { refreshReturnShippingWorkflow } from "./refresh-shipping"
|
||||
|
||||
/**
|
||||
* The data to validate that an item in a return can be updated.
|
||||
@@ -56,14 +57,14 @@ export type UpdateRequestItemReturnValidationStepInput = {
|
||||
* If the order or return is canceled, the order change is not active,
|
||||
* the return request is not found, or the action is not requesting an item return,
|
||||
* the step will throw an error.
|
||||
*
|
||||
*
|
||||
* :::note
|
||||
*
|
||||
*
|
||||
* You can retrieve an order, return, and order change details using [Query](https://docs.medusajs.com/learn/fundamentals/module-links/query),
|
||||
* or [useQueryGraphStep](https://docs.medusajs.com/resources/references/medusa-workflows/steps/useQueryGraphStep).
|
||||
*
|
||||
*
|
||||
* :::
|
||||
*
|
||||
*
|
||||
* @example
|
||||
* const data = updateRequestItemReturnValidationStep({
|
||||
* order: {
|
||||
@@ -130,12 +131,12 @@ export const updateRequestItemReturnValidationStep = createStep(
|
||||
|
||||
export const updateRequestItemReturnWorkflowId = "update-request-item-return"
|
||||
/**
|
||||
* This workflow updates a requested item in a return. It's used by the
|
||||
* This workflow updates a requested item in a return. It's used by the
|
||||
* [Update Requested Item in Return Admin API Route](https://docs.medusajs.com/api/admin#returns_postreturnsidrequestitemsaction_id).
|
||||
*
|
||||
* You can use this workflow within your customizations or your own custom workflows, allowing you to update an
|
||||
*
|
||||
* You can use this workflow within your customizations or your own custom workflows, allowing you to update an
|
||||
* item in a return in your custom flows.
|
||||
*
|
||||
*
|
||||
* @example
|
||||
* const { result } = await updateRequestItemReturnWorkflow(container)
|
||||
* .run({
|
||||
@@ -147,9 +148,9 @@ export const updateRequestItemReturnWorkflowId = "update-request-item-return"
|
||||
* }
|
||||
* }
|
||||
* })
|
||||
*
|
||||
*
|
||||
* @summary
|
||||
*
|
||||
*
|
||||
* Update a requested item in a return.
|
||||
*/
|
||||
export const updateRequestItemReturnWorkflow = createWorkflow(
|
||||
@@ -216,6 +217,21 @@ export const updateRequestItemReturnWorkflow = createWorkflow(
|
||||
|
||||
updateOrderChangeActionsStep([updateData])
|
||||
|
||||
const refreshArgs = transform(
|
||||
{ orderChange, orderReturn },
|
||||
({ orderChange, orderReturn }) => {
|
||||
return {
|
||||
order_change_id: orderChange.id,
|
||||
return_id: orderReturn.id,
|
||||
order_id: orderReturn.order_id,
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
refreshReturnShippingWorkflow.runAsStep({
|
||||
input: refreshArgs,
|
||||
})
|
||||
|
||||
return new WorkflowResponse(previewOrderChangeStep(order.id))
|
||||
}
|
||||
)
|
||||
|
||||
@@ -21,7 +21,7 @@ export type RefundPaymentsStepInput = {
|
||||
*/
|
||||
payment_id: string
|
||||
/**
|
||||
* The amount to refund.
|
||||
* The amount to refund.
|
||||
*/
|
||||
amount: BigNumberInput
|
||||
/**
|
||||
@@ -36,10 +36,7 @@ export const refundPaymentsStepId = "refund-payments-step"
|
||||
*/
|
||||
export const refundPaymentsStep = createStep(
|
||||
refundPaymentsStepId,
|
||||
async (
|
||||
input: RefundPaymentsStepInput,
|
||||
{ container }
|
||||
) => {
|
||||
async (input: RefundPaymentsStepInput, { container }) => {
|
||||
const logger = container.resolve<Logger>(ContainerRegistrationKeys.LOGGER)
|
||||
const paymentModule = container.resolve<IPaymentModuleService>(
|
||||
Modules.PAYMENT
|
||||
|
||||
@@ -120,6 +120,22 @@ export interface UpdateShippingOptionDTO {
|
||||
*/
|
||||
export interface UpsertShippingOptionDTO extends UpdateShippingOptionDTO {}
|
||||
|
||||
type CalculateShippingItems = {
|
||||
/**
|
||||
* The ID of the order item. Lookup in context.items for the details about variant / product.
|
||||
*/
|
||||
id: string
|
||||
/**
|
||||
* The quantity to ship.
|
||||
*/
|
||||
quantity: number
|
||||
}
|
||||
|
||||
export type CalculatedRMAShippingContext =
|
||||
| { return_id: string; return_items: CalculateShippingItems[] }
|
||||
| { exchange_id: string; exchange_items: CalculateShippingItems[] }
|
||||
| { claim_id: string; claim_items: CalculateShippingItems[] }
|
||||
|
||||
/**
|
||||
* The data needed for the associated fulfillment provider to calculate the price of a shipping option.
|
||||
*/
|
||||
@@ -149,11 +165,12 @@ export interface CalculateShippingOptionPriceDTO {
|
||||
*/
|
||||
context: CartPropsForFulfillment & {
|
||||
/**
|
||||
* The location that the items will be shipped from.
|
||||
* The location that the items will be shipped from (or to if it is a return).
|
||||
*/
|
||||
from_location?: StockLocationDTO
|
||||
|
||||
[k: string]: unknown
|
||||
}
|
||||
} & CalculatedRMAShippingContext
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user