chore(core-flows): Order Exchange - initial workflows (#8374)
PR: 1:n This is the first PR with a initial skeleton for Order exchange workflows. This is not yet to be considered functional or reflecting the exact behavior of Order Exchanges. What: * organize folder structure of order-related steps and workflows * initial worklows for Order exchange - This first draft is just a copy of Claims behavior
This commit is contained in:
committed by
GitHub
parent
7569fd1605
commit
accf884bb1
@@ -1,125 +0,0 @@
|
||||
import {
|
||||
beginExchangeOrderWorkflow,
|
||||
createExchangeReturnShippingMethodWorkflow,
|
||||
} from "@medusajs/core-flows"
|
||||
import { OrderDTO, OrderExchangeDTO } from "@medusajs/types"
|
||||
import {
|
||||
ContainerRegistrationKeys,
|
||||
remoteQueryObjectFromString,
|
||||
} from "@medusajs/utils"
|
||||
import { medusaIntegrationTestRunner } from "medusa-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: Create exchange return shipping", () => {
|
||||
let order: OrderDTO
|
||||
let fixtures
|
||||
|
||||
let exchangeOrder: OrderExchangeDTO
|
||||
|
||||
beforeEach(async () => {
|
||||
fixtures = await prepareDataFixtures({ container })
|
||||
order = await createOrderFixture({
|
||||
container,
|
||||
product: fixtures.product,
|
||||
location: fixtures.location,
|
||||
inventoryItem: fixtures.inventoryItem,
|
||||
})
|
||||
|
||||
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", "return_id"],
|
||||
})
|
||||
|
||||
;[exchangeOrder] = await remoteQuery(remoteQueryObject)
|
||||
})
|
||||
|
||||
describe("createExchangeReturnShippingMethodWorkflow", () => {
|
||||
it("should successfully add exchange return shipping to order changes", async () => {
|
||||
const shippingOptionId = fixtures.shippingOption.id
|
||||
|
||||
const { result } = await createExchangeReturnShippingMethodWorkflow(
|
||||
container
|
||||
).run({
|
||||
input: {
|
||||
exchangeId: exchangeOrder.id,
|
||||
shippingOptionId: shippingOptionId,
|
||||
},
|
||||
})
|
||||
|
||||
const orderChange = result?.[0]
|
||||
|
||||
expect(orderChange).toEqual(
|
||||
expect.objectContaining({
|
||||
id: expect.any(String),
|
||||
reference: "order_shipping_method",
|
||||
reference_id: expect.any(String),
|
||||
details: {
|
||||
exchange_id: exchangeOrder.id,
|
||||
order_id: exchangeOrder.order_id,
|
||||
return_id: exchangeOrder.return_id,
|
||||
},
|
||||
raw_amount: { value: "10", precision: 20 },
|
||||
applied: false,
|
||||
action: "SHIPPING_ADD",
|
||||
amount: 10,
|
||||
})
|
||||
)
|
||||
})
|
||||
|
||||
it("should successfully add return shipping with custom price to order changes", async () => {
|
||||
const shippingOptionId = fixtures.shippingOption.id
|
||||
|
||||
const { result } = await createExchangeReturnShippingMethodWorkflow(
|
||||
container
|
||||
).run({
|
||||
input: {
|
||||
exchangeId: exchangeOrder.id,
|
||||
shippingOptionId: shippingOptionId,
|
||||
customShippingPrice: 20,
|
||||
},
|
||||
})
|
||||
|
||||
const orderChange = result?.[0]
|
||||
|
||||
expect(orderChange).toEqual(
|
||||
expect.objectContaining({
|
||||
id: expect.any(String),
|
||||
reference: "order_shipping_method",
|
||||
reference_id: expect.any(String),
|
||||
details: {
|
||||
exchange_id: exchangeOrder.id,
|
||||
order_id: exchangeOrder.order_id,
|
||||
return_id: exchangeOrder.return_id,
|
||||
},
|
||||
raw_amount: { value: "20", precision: 20 },
|
||||
applied: false,
|
||||
action: "SHIPPING_ADD",
|
||||
amount: 20,
|
||||
})
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
},
|
||||
})
|
||||
@@ -0,0 +1,50 @@
|
||||
import {
|
||||
CreateOrderExchangeItemDTO,
|
||||
IOrderModuleService,
|
||||
OrderChangeActionDTO,
|
||||
} from "@medusajs/types"
|
||||
import { ModuleRegistrationName } from "@medusajs/utils"
|
||||
import { StepResponse, createStep } from "@medusajs/workflows-sdk"
|
||||
|
||||
type CreateOrderExchangeItemsFromActionsInput = {
|
||||
changes: OrderChangeActionDTO[]
|
||||
exchangeId: string
|
||||
}
|
||||
|
||||
export const createOrderExchangeItemsFromActionsStep = createStep(
|
||||
"create-exchange-items-from-change-actions",
|
||||
async (input: CreateOrderExchangeItemsFromActionsInput, { container }) => {
|
||||
const orderModuleService = container.resolve<IOrderModuleService>(
|
||||
ModuleRegistrationName.ORDER
|
||||
)
|
||||
|
||||
const exchangeItems = input.changes.map((item) => {
|
||||
return {
|
||||
exchange_id: input.exchangeId,
|
||||
item_id: item.details?.reference_id! as string,
|
||||
quantity: item.details?.quantity as number,
|
||||
note: item.internal_note,
|
||||
metadata: (item.details?.metadata as Record<string, unknown>) ?? {},
|
||||
}
|
||||
}) as CreateOrderExchangeItemDTO[]
|
||||
|
||||
const createdExchangeItems =
|
||||
await orderModuleService.createOrderExchangeItems(exchangeItems)
|
||||
|
||||
return new StepResponse(
|
||||
createdExchangeItems,
|
||||
createdExchangeItems.map((i) => i.id)
|
||||
)
|
||||
},
|
||||
async (ids, { container }) => {
|
||||
if (!ids) {
|
||||
return
|
||||
}
|
||||
|
||||
const orderModuleService = container.resolve<IOrderModuleService>(
|
||||
ModuleRegistrationName.ORDER
|
||||
)
|
||||
|
||||
await orderModuleService.deleteOrderExchangeItems(ids)
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,28 @@
|
||||
import { IOrderModuleService } from "@medusajs/types"
|
||||
import { ModuleRegistrationName } from "@medusajs/utils"
|
||||
import { createStep, StepResponse } from "@medusajs/workflows-sdk"
|
||||
|
||||
export const deleteExchangesStepId = "delete-exchanges"
|
||||
export const deleteExchangesStep = createStep(
|
||||
deleteExchangesStepId,
|
||||
async (data: { ids: string[] }, { container }) => {
|
||||
const service = container.resolve<IOrderModuleService>(
|
||||
ModuleRegistrationName.ORDER
|
||||
)
|
||||
|
||||
const deleted = await service.softDeleteOrderExchanges(data.ids)
|
||||
|
||||
return new StepResponse(deleted, data.ids)
|
||||
},
|
||||
async (ids, { container }) => {
|
||||
if (!ids) {
|
||||
return
|
||||
}
|
||||
|
||||
const service = container.resolve<IOrderModuleService>(
|
||||
ModuleRegistrationName.ORDER
|
||||
)
|
||||
|
||||
await service.restoreOrderExchanges(ids)
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,55 @@
|
||||
import { IOrderModuleService, UpdateOrderExchangeDTO } from "@medusajs/types"
|
||||
import {
|
||||
ModuleRegistrationName,
|
||||
getSelectsAndRelationsFromObjectArray,
|
||||
} from "@medusajs/utils"
|
||||
import { StepResponse, createStep } from "@medusajs/workflows-sdk"
|
||||
|
||||
export const updateOrderExchangesStepId = "update-order-exchange"
|
||||
export const updateOrderExchangesStep = createStep(
|
||||
updateOrderExchangesStepId,
|
||||
async (data: UpdateOrderExchangeDTO[], { container }) => {
|
||||
const service = container.resolve<IOrderModuleService>(
|
||||
ModuleRegistrationName.ORDER
|
||||
)
|
||||
|
||||
const { selects, relations } = getSelectsAndRelationsFromObjectArray(data, {
|
||||
objectFields: ["metadata"],
|
||||
})
|
||||
const dataBeforeUpdate = await service.listOrderExchanges(
|
||||
{ id: data.map((d) => d.id) },
|
||||
{ relations, select: selects }
|
||||
)
|
||||
|
||||
const updated = await service.updateOrderExchanges(
|
||||
data.map((dt) => {
|
||||
const { id, ...rest } = dt
|
||||
return {
|
||||
selector: { id },
|
||||
data: rest,
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
return new StepResponse(updated, dataBeforeUpdate)
|
||||
},
|
||||
async (dataBeforeUpdate, { container }) => {
|
||||
if (!dataBeforeUpdate?.length) {
|
||||
return
|
||||
}
|
||||
|
||||
const service = container.resolve<IOrderModuleService>(
|
||||
ModuleRegistrationName.ORDER
|
||||
)
|
||||
|
||||
await service.updateOrderExchanges(
|
||||
dataBeforeUpdate.map((dt) => {
|
||||
const { id, ...rest } = dt
|
||||
return {
|
||||
selector: { id },
|
||||
data: rest,
|
||||
}
|
||||
})
|
||||
)
|
||||
}
|
||||
)
|
||||
@@ -1,34 +1,36 @@
|
||||
export * from "./archive-orders"
|
||||
export * from "./cancel-claim"
|
||||
export * from "./cancel-exchange"
|
||||
export * from "./cancel-order-change"
|
||||
export * from "./cancel-orders"
|
||||
export * from "./cancel-return"
|
||||
export * from "./claim/cancel-claim"
|
||||
export * from "./claim/create-claim-items-from-actions"
|
||||
export * from "./claim/create-claims"
|
||||
export * from "./claim/delete-claims"
|
||||
export * from "./complete-orders"
|
||||
export * from "./create-claim-items-from-actions"
|
||||
export * from "./create-claims"
|
||||
export * from "./create-complete-return"
|
||||
export * from "./create-exchanges"
|
||||
export * from "./create-line-items"
|
||||
export * from "./create-order-change"
|
||||
export * from "./create-order-change-actions"
|
||||
export * from "./create-orders"
|
||||
export * from "./create-returns"
|
||||
export * from "./decline-order-change"
|
||||
export * from "./delete-claims"
|
||||
export * from "./delete-line-items"
|
||||
export * from "./delete-order-change-actions"
|
||||
export * from "./delete-order-changes"
|
||||
export * from "./delete-order-shipping-methods"
|
||||
export * from "./delete-returns"
|
||||
export * from "./exchange/cancel-exchange"
|
||||
export * from "./exchange/create-exchange"
|
||||
export * from "./exchange/create-exchange-items-from-actions"
|
||||
export * from "./exchange/delete-exchanges"
|
||||
export * from "./get-item-tax-lines"
|
||||
export * from "./preview-order-change"
|
||||
export * from "./register-fulfillment"
|
||||
export * from "./register-shipment"
|
||||
export * from "./return/cancel-return"
|
||||
export * from "./return/create-complete-return"
|
||||
export * from "./return/create-returns"
|
||||
export * from "./return/delete-returns"
|
||||
export * from "./return/update-return-items"
|
||||
export * from "./return/update-returns"
|
||||
export * from "./set-tax-lines-for-items"
|
||||
export * from "./update-order-change-actions"
|
||||
export * from "./update-order-exchanges"
|
||||
export * from "./update-return-items"
|
||||
export * from "./update-returns"
|
||||
export * from "./update-shipping-methods"
|
||||
export * from "./update-tax-lines"
|
||||
|
||||
@@ -7,7 +7,7 @@ import {
|
||||
transform,
|
||||
} from "@medusajs/workflows-sdk"
|
||||
import { useRemoteQueryStep } from "../../../common"
|
||||
import { createOrderClaimsStep } from "../../steps/create-claims"
|
||||
import { createOrderClaimsStep } from "../../steps/claim/create-claims"
|
||||
import { createOrderChangeStep } from "../../steps/create-order-change"
|
||||
import { throwIfIsCancelled } from "../../utils/order-validation"
|
||||
|
||||
|
||||
@@ -15,10 +15,10 @@ import {
|
||||
when,
|
||||
} from "@medusajs/workflows-sdk"
|
||||
import { useRemoteQueryStep } from "../../../common"
|
||||
import { updateOrderClaimsStep } from "../../steps/claim/update-order-claims"
|
||||
import { createOrderChangeActionsStep } from "../../steps/create-order-change-actions"
|
||||
import { createReturnsStep } from "../../steps/create-returns"
|
||||
import { previewOrderChangeStep } from "../../steps/preview-order-change"
|
||||
import { updateOrderClaimsStep } from "../../steps/update-order-claims"
|
||||
import { createReturnsStep } from "../../steps/return/create-returns"
|
||||
import {
|
||||
throwIfIsCancelled,
|
||||
throwIfItemsDoesNotExistsInOrder,
|
||||
|
||||
@@ -7,7 +7,6 @@ import {
|
||||
} from "@medusajs/types"
|
||||
import { ChangeActionType, Modules, OrderChangeStatus } from "@medusajs/utils"
|
||||
import {
|
||||
WorkflowData,
|
||||
WorkflowResponse,
|
||||
createStep,
|
||||
createWorkflow,
|
||||
@@ -19,9 +18,9 @@ import { createRemoteLinkStep, useRemoteQueryStep } from "../../../common"
|
||||
import { createFulfillmentWorkflow } from "../../../fulfillment/workflows/create-fulfillment"
|
||||
import { createReturnFulfillmentWorkflow } from "../../../fulfillment/workflows/create-return-fulfillment"
|
||||
import { previewOrderChangeStep } from "../../steps"
|
||||
import { createOrderClaimItemsFromActionsStep } from "../../steps/claim/create-claim-items-from-actions"
|
||||
import { confirmOrderChanges } from "../../steps/confirm-order-changes"
|
||||
import { createOrderClaimItemsFromActionsStep } from "../../steps/create-claim-items-from-actions"
|
||||
import { createReturnItemsFromActionsStep } from "../../steps/create-return-items-from-actions"
|
||||
import { createReturnItemsFromActionsStep } from "../../steps/return/create-return-items-from-actions"
|
||||
import {
|
||||
throwIfIsCancelled,
|
||||
throwIfOrderChangeIsNotActive,
|
||||
|
||||
@@ -7,8 +7,8 @@ import {
|
||||
transform,
|
||||
} from "@medusajs/workflows-sdk"
|
||||
import { useRemoteQueryStep } from "../../../common"
|
||||
import { createOrderExchangesStep } from "../../steps/create-exchanges"
|
||||
import { createOrderChangeStep } from "../../steps/create-order-change"
|
||||
import { createOrderExchangesStep } from "../../steps/exchange/create-exchange"
|
||||
import { throwIfOrderIsCancelled } from "../../utils/order-validation"
|
||||
|
||||
const validationStep = createStep(
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
import { OrderChangeDTO, OrderDTO, OrderExchangeDTO } from "@medusajs/types"
|
||||
import { ChangeActionType, OrderChangeStatus } from "@medusajs/utils"
|
||||
import {
|
||||
WorkflowData,
|
||||
createStep,
|
||||
createWorkflow,
|
||||
parallelize,
|
||||
transform,
|
||||
} from "@medusajs/workflows-sdk"
|
||||
import { useRemoteQueryStep } from "../../../common"
|
||||
import {
|
||||
deleteExchangesStep,
|
||||
deleteOrderChangesStep,
|
||||
deleteOrderShippingMethods,
|
||||
deleteReturnsStep,
|
||||
} from "../../steps"
|
||||
import {
|
||||
throwIfIsCancelled,
|
||||
throwIfOrderChangeIsNotActive,
|
||||
} from "../../utils/order-validation"
|
||||
|
||||
type WorkflowInput = {
|
||||
exchange_id: string
|
||||
}
|
||||
|
||||
const validationStep = createStep(
|
||||
"validate-cancel-begin-order-exchange",
|
||||
async function ({
|
||||
order,
|
||||
orderChange,
|
||||
orderExchange,
|
||||
}: {
|
||||
order: OrderDTO
|
||||
orderExchange: OrderExchangeDTO
|
||||
orderChange: OrderChangeDTO
|
||||
}) {
|
||||
throwIfIsCancelled(order, "Order")
|
||||
throwIfIsCancelled(orderExchange, "Exchange")
|
||||
throwIfOrderChangeIsNotActive({ orderChange })
|
||||
}
|
||||
)
|
||||
|
||||
export const cancelBeginOrderExchangeWorkflowId = "cancel-begin-order-exchange"
|
||||
export const cancelBeginOrderExchangeWorkflow = createWorkflow(
|
||||
cancelBeginOrderExchangeWorkflowId,
|
||||
function (input: WorkflowInput): WorkflowData<void> {
|
||||
const orderExchange: OrderExchangeDTO = useRemoteQueryStep({
|
||||
entry_point: "order_exchange",
|
||||
fields: ["id", "status", "order_id", "return_id", "canceled_at"],
|
||||
variables: { id: input.exchange_id },
|
||||
list: false,
|
||||
throw_if_key_not_found: true,
|
||||
})
|
||||
|
||||
const order: OrderDTO = useRemoteQueryStep({
|
||||
entry_point: "orders",
|
||||
fields: ["id", "version", "canceled_at"],
|
||||
variables: { id: orderExchange.order_id },
|
||||
list: false,
|
||||
throw_if_key_not_found: true,
|
||||
}).config({ name: "order-query" })
|
||||
|
||||
const orderChange: OrderChangeDTO = useRemoteQueryStep({
|
||||
entry_point: "order_change",
|
||||
fields: ["id", "status", "version", "actions.*"],
|
||||
variables: {
|
||||
filters: {
|
||||
order_id: orderExchange.order_id,
|
||||
exchange_id: orderExchange.id,
|
||||
status: [OrderChangeStatus.PENDING, OrderChangeStatus.REQUESTED],
|
||||
},
|
||||
},
|
||||
list: false,
|
||||
}).config({ name: "order-change-query" })
|
||||
|
||||
validationStep({ order, orderExchange, orderChange })
|
||||
|
||||
const shippingToRemove = transform(
|
||||
{ orderChange, input },
|
||||
({ orderChange, input }) => {
|
||||
return (orderChange.actions ?? [])
|
||||
.filter((a) => a.action === ChangeActionType.SHIPPING_ADD)
|
||||
.map(({ id }) => id)
|
||||
}
|
||||
)
|
||||
|
||||
parallelize(
|
||||
deleteReturnsStep({ ids: [orderExchange.return_id!] }),
|
||||
deleteExchangesStep({ ids: [orderExchange.id] }),
|
||||
deleteOrderChangesStep({ ids: [orderChange.id] }),
|
||||
deleteOrderShippingMethods({ ids: shippingToRemove })
|
||||
)
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,82 @@
|
||||
import {
|
||||
FulfillmentDTO,
|
||||
OrderExchangeDTO,
|
||||
OrderWorkflow,
|
||||
} from "@medusajs/types"
|
||||
import { MedusaError } from "@medusajs/utils"
|
||||
import {
|
||||
WorkflowData,
|
||||
createStep,
|
||||
createWorkflow,
|
||||
when,
|
||||
} from "@medusajs/workflows-sdk"
|
||||
import { useRemoteQueryStep } from "../../../common"
|
||||
import { cancelOrderExchangeStep } from "../../steps"
|
||||
import { throwIfIsCancelled } from "../../utils/order-validation"
|
||||
import { cancelReturnWorkflow } from "../return/cancel-return"
|
||||
|
||||
const validateOrder = createStep(
|
||||
"validate-exchange",
|
||||
({
|
||||
orderExchange,
|
||||
}: {
|
||||
orderExchange: OrderExchangeDTO
|
||||
input: OrderWorkflow.CancelOrderExchangeWorkflowInput
|
||||
}) => {
|
||||
const orderExchange_ = orderExchange as OrderExchangeDTO & {
|
||||
fulfillments: FulfillmentDTO[]
|
||||
}
|
||||
|
||||
throwIfIsCancelled(orderExchange, "Exchange")
|
||||
|
||||
const throwErrorIf = (
|
||||
arr: unknown[],
|
||||
pred: (obj: any) => boolean,
|
||||
message: string
|
||||
) => {
|
||||
if (arr?.some(pred)) {
|
||||
throw new MedusaError(MedusaError.Types.NOT_ALLOWED, message)
|
||||
}
|
||||
}
|
||||
|
||||
const notCanceled = (o) => !o.canceled_at
|
||||
|
||||
throwErrorIf(
|
||||
orderExchange_.fulfillments,
|
||||
notCanceled,
|
||||
"All fulfillments must be canceled before canceling am exchange"
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
export const cancelOrderExchangeWorkflowId = "cancel-exchange"
|
||||
export const cancelOrderExchangeWorkflow = createWorkflow(
|
||||
cancelOrderExchangeWorkflowId,
|
||||
(
|
||||
input: WorkflowData<OrderWorkflow.CancelOrderExchangeWorkflowInput>
|
||||
): WorkflowData<void> => {
|
||||
const orderExchange: OrderExchangeDTO & { fulfillments: FulfillmentDTO[] } =
|
||||
useRemoteQueryStep({
|
||||
entry_point: "order_exchange",
|
||||
fields: ["id", "return_id", "canceled_at", "fulfillments.canceled_at"],
|
||||
variables: { id: input.exchange_id },
|
||||
list: false,
|
||||
throw_if_key_not_found: true,
|
||||
})
|
||||
|
||||
validateOrder({ orderExchange, input })
|
||||
|
||||
cancelOrderExchangeStep({ exchange_id: orderExchange.id })
|
||||
|
||||
when({ orderExchange }, ({ orderExchange }) => {
|
||||
return !!orderExchange.return_id
|
||||
}).then(() => {
|
||||
cancelReturnWorkflow.runAsStep({
|
||||
input: {
|
||||
return_id: orderExchange.return_id!,
|
||||
no_notification: input.no_notification,
|
||||
},
|
||||
})
|
||||
})
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,361 @@
|
||||
import {
|
||||
FulfillmentWorkflow,
|
||||
OrderChangeActionDTO,
|
||||
OrderChangeDTO,
|
||||
OrderDTO,
|
||||
OrderExchangeDTO,
|
||||
} from "@medusajs/types"
|
||||
import { ChangeActionType, Modules, OrderChangeStatus } from "@medusajs/utils"
|
||||
import {
|
||||
WorkflowResponse,
|
||||
createStep,
|
||||
createWorkflow,
|
||||
parallelize,
|
||||
transform,
|
||||
when,
|
||||
} from "@medusajs/workflows-sdk"
|
||||
import { createRemoteLinkStep, useRemoteQueryStep } from "../../../common"
|
||||
import { createFulfillmentWorkflow } from "../../../fulfillment/workflows/create-fulfillment"
|
||||
import { createReturnFulfillmentWorkflow } from "../../../fulfillment/workflows/create-return-fulfillment"
|
||||
import { previewOrderChangeStep } from "../../steps"
|
||||
import { confirmOrderChanges } from "../../steps/confirm-order-changes"
|
||||
import { createOrderExchangeItemsFromActionsStep } from "../../steps/exchange/create-exchange-items-from-actions"
|
||||
import { createReturnItemsFromActionsStep } from "../../steps/return/create-return-items-from-actions"
|
||||
import {
|
||||
throwIfIsCancelled,
|
||||
throwIfOrderChangeIsNotActive,
|
||||
} from "../../utils/order-validation"
|
||||
|
||||
type WorkflowInput = {
|
||||
exchange_id: string
|
||||
}
|
||||
|
||||
const validationStep = createStep(
|
||||
"validate-confirm-exchange-request",
|
||||
async function ({
|
||||
order,
|
||||
orderChange,
|
||||
orderExchange,
|
||||
}: {
|
||||
order: OrderDTO
|
||||
orderExchange: OrderExchangeDTO
|
||||
orderChange: OrderChangeDTO
|
||||
}) {
|
||||
throwIfIsCancelled(order, "Order")
|
||||
throwIfIsCancelled(orderExchange, "Exchange")
|
||||
throwIfOrderChangeIsNotActive({ orderChange })
|
||||
}
|
||||
)
|
||||
|
||||
function prepareFulfillmentData({
|
||||
order,
|
||||
items,
|
||||
shippingOption,
|
||||
deliveryAddress,
|
||||
}: {
|
||||
order: OrderDTO
|
||||
items: any[]
|
||||
shippingOption: {
|
||||
id: string
|
||||
provider_id: string
|
||||
service_zone: {
|
||||
fulfillment_set: {
|
||||
location?: {
|
||||
id: string
|
||||
address: Record<string, any>
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
deliveryAddress?: Record<string, any>
|
||||
}) {
|
||||
const orderItemsMap = new Map<string, Required<OrderDTO>["items"][0]>(
|
||||
order.items!.map((i) => [i.id, i])
|
||||
)
|
||||
const fulfillmentItems = items.map((i) => {
|
||||
const orderItem = orderItemsMap.get(i.item_id)!
|
||||
return {
|
||||
line_item_id: i.item_id,
|
||||
quantity: i.quantity,
|
||||
return_quantity: i.quantity,
|
||||
title: orderItem.variant_title ?? orderItem.title,
|
||||
sku: orderItem.variant_sku || "",
|
||||
barcode: orderItem.variant_barcode || "",
|
||||
} as FulfillmentWorkflow.CreateFulfillmentItemWorkflowDTO
|
||||
})
|
||||
|
||||
const locationId = shippingOption.service_zone.fulfillment_set.location?.id!
|
||||
|
||||
// delivery address is the stock location address
|
||||
const address =
|
||||
deliveryAddress ??
|
||||
shippingOption.service_zone.fulfillment_set.location?.address ??
|
||||
{}
|
||||
|
||||
delete address.id
|
||||
|
||||
return {
|
||||
input: {
|
||||
location_id: locationId,
|
||||
provider_id: shippingOption.provider_id,
|
||||
shipping_option_id: shippingOption.id,
|
||||
items: fulfillmentItems,
|
||||
delivery_address: address,
|
||||
order: order,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
function transformActionsToItems({ orderChange }) {
|
||||
const exchangeItems: OrderChangeActionDTO[] = []
|
||||
const returnItems: OrderChangeActionDTO[] = []
|
||||
|
||||
const actions = orderChange.actions ?? []
|
||||
actions.forEach((item) => {
|
||||
if (item.action === ChangeActionType.RETURN_ITEM) {
|
||||
returnItems.push(item)
|
||||
} else if (item.action === ChangeActionType.ITEM_ADD) {
|
||||
exchangeItems.push(item)
|
||||
}
|
||||
})
|
||||
|
||||
return {
|
||||
exchangeItems: {
|
||||
changes: exchangeItems,
|
||||
exchangeId: exchangeItems?.[0]?.exchange_id!,
|
||||
},
|
||||
returnItems: {
|
||||
changes: returnItems,
|
||||
returnId: returnItems?.[0]?.return_id!,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
function extractShippingOption({ orderPreview, orderExchange, returnId }) {
|
||||
if (!orderPreview.shipping_methods?.length) {
|
||||
return
|
||||
}
|
||||
|
||||
let returnShippingMethod
|
||||
let exchangeShippingMethod
|
||||
for (const shippingMethod of orderPreview.shipping_methods) {
|
||||
const modifiedShippingMethod_ = shippingMethod as any
|
||||
if (!modifiedShippingMethod_.actions) {
|
||||
continue
|
||||
}
|
||||
|
||||
for (const action of modifiedShippingMethod_.actions) {
|
||||
if (action.action === ChangeActionType.SHIPPING_ADD) {
|
||||
if (action.return_id === returnId) {
|
||||
returnShippingMethod = shippingMethod
|
||||
} else if (action.exchange_id === orderExchange.id) {
|
||||
exchangeShippingMethod = shippingMethod
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
returnShippingMethod,
|
||||
exchangeShippingMethod,
|
||||
}
|
||||
}
|
||||
|
||||
export const confirmExchangeRequestWorkflowId = "confirm-exchange-request"
|
||||
export const confirmExchangeRequestWorkflow = createWorkflow(
|
||||
confirmExchangeRequestWorkflowId,
|
||||
function (input: WorkflowInput): WorkflowResponse<OrderDTO> {
|
||||
const orderExchange: OrderExchangeDTO = useRemoteQueryStep({
|
||||
entry_point: "order_exchange",
|
||||
fields: ["id", "status", "order_id", "canceled_at"],
|
||||
variables: { id: input.exchange_id },
|
||||
list: false,
|
||||
throw_if_key_not_found: true,
|
||||
})
|
||||
|
||||
const order: OrderDTO = useRemoteQueryStep({
|
||||
entry_point: "orders",
|
||||
fields: [
|
||||
"id",
|
||||
"version",
|
||||
"canceled_at",
|
||||
"items.id",
|
||||
"items.title",
|
||||
"items.variant_title",
|
||||
"items.variant_sku",
|
||||
"items.variant_barcode",
|
||||
"shipping_address.*",
|
||||
],
|
||||
variables: { id: orderExchange.order_id },
|
||||
list: false,
|
||||
throw_if_key_not_found: true,
|
||||
}).config({ name: "order-query" })
|
||||
|
||||
const orderChange: OrderChangeDTO = useRemoteQueryStep({
|
||||
entry_point: "order_change",
|
||||
fields: [
|
||||
"id",
|
||||
"actions.id",
|
||||
"actions.exchange_id",
|
||||
"actions.return_id",
|
||||
"actions.action",
|
||||
"actions.details",
|
||||
"actions.reference",
|
||||
"actions.reference_id",
|
||||
"actions.internal_note",
|
||||
],
|
||||
variables: {
|
||||
filters: {
|
||||
order_id: orderExchange.order_id,
|
||||
exchange_id: orderExchange.id,
|
||||
status: [OrderChangeStatus.PENDING, OrderChangeStatus.REQUESTED],
|
||||
},
|
||||
},
|
||||
list: false,
|
||||
}).config({ name: "order-change-query" })
|
||||
|
||||
validationStep({ order, orderExchange, orderChange })
|
||||
|
||||
const { exchangeItems, returnItems } = transform(
|
||||
{ orderChange },
|
||||
transformActionsToItems
|
||||
)
|
||||
|
||||
const orderPreview = previewOrderChangeStep(order.id)
|
||||
|
||||
const [createExchangeItems, createdReturnItems] = parallelize(
|
||||
createOrderExchangeItemsFromActionsStep(exchangeItems),
|
||||
createReturnItemsFromActionsStep(returnItems),
|
||||
confirmOrderChanges({ changes: [orderChange], orderId: order.id })
|
||||
)
|
||||
|
||||
const returnId = transform(
|
||||
{ createdReturnItems },
|
||||
({ createdReturnItems }) => {
|
||||
return createdReturnItems?.[0]?.return_id
|
||||
}
|
||||
)
|
||||
|
||||
const exchangeId = transform(
|
||||
{ createExchangeItems },
|
||||
({ createExchangeItems }) => {
|
||||
return createExchangeItems?.[0]?.exchange_id
|
||||
}
|
||||
)
|
||||
|
||||
const { returnShippingMethod, exchangeShippingMethod } = transform(
|
||||
{ orderPreview, orderExchange, returnId },
|
||||
extractShippingOption
|
||||
)
|
||||
|
||||
when({ exchangeShippingMethod }, ({ exchangeShippingMethod }) => {
|
||||
return !!exchangeShippingMethod
|
||||
}).then(() => {
|
||||
const exchange: OrderExchangeDTO = useRemoteQueryStep({
|
||||
entry_point: "order_exchange",
|
||||
fields: [
|
||||
"id",
|
||||
"version",
|
||||
"canceled_at",
|
||||
"additional_items.id",
|
||||
"additional_items.title",
|
||||
"additional_items.variant_title",
|
||||
"additional_items.variant_sku",
|
||||
"additional_items.variant_barcode",
|
||||
],
|
||||
variables: { id: exchangeId },
|
||||
list: false,
|
||||
throw_if_key_not_found: true,
|
||||
}).config({ name: "exchange-query" })
|
||||
|
||||
const exchangeShippingOption = useRemoteQueryStep({
|
||||
entry_point: "shipping_options",
|
||||
fields: [
|
||||
"id",
|
||||
"provider_id",
|
||||
"service_zone.fulfillment_set.location.id",
|
||||
"service_zone.fulfillment_set.location.address.*",
|
||||
],
|
||||
variables: {
|
||||
id: exchangeShippingMethod.shipping_option_id,
|
||||
},
|
||||
list: false,
|
||||
throw_if_key_not_found: true,
|
||||
}).config({ name: "exchange-shipping-option" })
|
||||
|
||||
const fulfillmentData = transform(
|
||||
{
|
||||
order,
|
||||
items: exchange.additional_items! ?? [],
|
||||
shippingOption: exchangeShippingOption,
|
||||
deliveryAddress: order.shipping_address,
|
||||
},
|
||||
prepareFulfillmentData
|
||||
)
|
||||
|
||||
const fulfillment = createFulfillmentWorkflow.runAsStep(fulfillmentData)
|
||||
|
||||
const link = transform({ fulfillment, order }, (data) => {
|
||||
return [
|
||||
{
|
||||
[Modules.ORDER]: { order_id: data.order.id },
|
||||
[Modules.FULFILLMENT]: { fulfillment_id: data.fulfillment.id },
|
||||
},
|
||||
]
|
||||
})
|
||||
|
||||
createRemoteLinkStep(link).config({
|
||||
name: "exchange-shipping-fulfillment-link",
|
||||
})
|
||||
})
|
||||
|
||||
when({ returnShippingMethod }, ({ returnShippingMethod }) => {
|
||||
return !!returnShippingMethod
|
||||
}).then(() => {
|
||||
const returnShippingOption = useRemoteQueryStep({
|
||||
entry_point: "shipping_options",
|
||||
fields: [
|
||||
"id",
|
||||
"provider_id",
|
||||
"service_zone.fulfillment_set.location.id",
|
||||
"service_zone.fulfillment_set.location.address.*",
|
||||
],
|
||||
variables: {
|
||||
id: returnShippingMethod.shipping_option_id,
|
||||
},
|
||||
list: false,
|
||||
throw_if_key_not_found: true,
|
||||
}).config({ name: "exchange-return-shipping-option" })
|
||||
|
||||
const fulfillmentData = transform(
|
||||
{
|
||||
order,
|
||||
items: order.items!,
|
||||
shippingOption: returnShippingOption,
|
||||
},
|
||||
prepareFulfillmentData
|
||||
)
|
||||
|
||||
const returnFulfillment =
|
||||
createReturnFulfillmentWorkflow.runAsStep(fulfillmentData)
|
||||
|
||||
const returnLink = transform(
|
||||
{ returnId, fulfillment: returnFulfillment },
|
||||
(data) => {
|
||||
return [
|
||||
{
|
||||
[Modules.ORDER]: { return_id: data.returnId },
|
||||
[Modules.FULFILLMENT]: { fulfillment_id: data.fulfillment.id },
|
||||
},
|
||||
]
|
||||
}
|
||||
)
|
||||
|
||||
createRemoteLinkStep(returnLink).config({
|
||||
name: "exchange-return-shipping-fulfillment-link",
|
||||
})
|
||||
})
|
||||
|
||||
return new WorkflowResponse(orderPreview)
|
||||
}
|
||||
)
|
||||
@@ -1,60 +1,63 @@
|
||||
import {
|
||||
BigNumberInput,
|
||||
OrderChangeActionDTO,
|
||||
OrderChangeDTO,
|
||||
OrderDTO,
|
||||
OrderExchangeDTO,
|
||||
} from "@medusajs/types"
|
||||
import { ChangeActionType, OrderChangeStatus } from "@medusajs/utils"
|
||||
import {
|
||||
WorkflowData,
|
||||
WorkflowResponse,
|
||||
createStep,
|
||||
createWorkflow,
|
||||
transform,
|
||||
} from "@medusajs/workflows-sdk"
|
||||
import { useRemoteQueryStep } from "../../../common"
|
||||
import { previewOrderChangeStep } from "../../steps"
|
||||
import { createOrderChangeActionsStep } from "../../steps/create-order-change-actions"
|
||||
import { createOrderShippingMethods } from "../../steps/create-order-shipping-methods"
|
||||
import {
|
||||
throwIfIsCancelled,
|
||||
throwIfOrderChangeIsNotActive,
|
||||
throwIfOrderIsCancelled,
|
||||
} from "../../utils/order-validation"
|
||||
|
||||
const validationStep = createStep(
|
||||
"validate-create-exchange-return-shipping-method",
|
||||
"validate-create-exchange-shipping-method",
|
||||
async function ({
|
||||
order,
|
||||
orderChange,
|
||||
orderExchange,
|
||||
}: {
|
||||
order: OrderDTO
|
||||
orderExchange: OrderExchangeDTO
|
||||
orderChange: OrderChangeDTO
|
||||
}) {
|
||||
throwIfOrderIsCancelled({ order })
|
||||
throwIfIsCancelled(order, "Order")
|
||||
throwIfIsCancelled(orderExchange, "Exchange")
|
||||
throwIfOrderChangeIsNotActive({ orderChange })
|
||||
}
|
||||
)
|
||||
|
||||
export const createExchangeReturnShippingMethodWorkflowId =
|
||||
"create-exchange-return-shipping-method"
|
||||
export const createExchangeReturnShippingMethodWorkflow = createWorkflow(
|
||||
createExchangeReturnShippingMethodWorkflowId,
|
||||
export const createExchangeShippingMethodWorkflowId =
|
||||
"create-exchange-shipping-method"
|
||||
export const createExchangeShippingMethodWorkflow = createWorkflow(
|
||||
createExchangeShippingMethodWorkflowId,
|
||||
function (input: {
|
||||
exchangeId: string
|
||||
shippingOptionId: string
|
||||
customShippingPrice?: BigNumberInput
|
||||
}): WorkflowResponse<OrderChangeActionDTO[]> {
|
||||
return_id?: string
|
||||
exchange_id?: string
|
||||
shipping_option_id: string
|
||||
custom_price?: BigNumberInput
|
||||
}): WorkflowResponse<OrderDTO> {
|
||||
const orderExchange: OrderExchangeDTO = useRemoteQueryStep({
|
||||
entry_point: "order_exchange",
|
||||
fields: ["id", "status", "order_id", "return_id"],
|
||||
variables: { id: input.exchangeId },
|
||||
fields: ["id", "status", "order_id", "canceled_at"],
|
||||
variables: { id: input.exchange_id },
|
||||
list: false,
|
||||
throw_if_key_not_found: true,
|
||||
})
|
||||
|
||||
const order: OrderDTO = useRemoteQueryStep({
|
||||
entry_point: "orders",
|
||||
fields: ["id", "status", "currency_code"],
|
||||
fields: ["id", "status", "currency_code", "canceled_at"],
|
||||
variables: { id: orderExchange.order_id },
|
||||
list: false,
|
||||
throw_if_key_not_found: true,
|
||||
@@ -69,41 +72,16 @@ export const createExchangeReturnShippingMethodWorkflow = createWorkflow(
|
||||
"calculated_price.is_calculated_price_tax_inclusive",
|
||||
],
|
||||
variables: {
|
||||
id: input.shippingOptionId,
|
||||
id: input.shipping_option_id,
|
||||
calculated_price: {
|
||||
context: { currency_code: order.currency_code },
|
||||
},
|
||||
},
|
||||
}).config({ name: "fetch-shipping-option" })
|
||||
|
||||
const shippingMethodInput = transform(
|
||||
{ orderExchange, shippingOptions, input },
|
||||
(data) => {
|
||||
const option = data.shippingOptions[0]
|
||||
|
||||
return {
|
||||
shipping_option_id: option.id,
|
||||
amount:
|
||||
data.input.customShippingPrice ??
|
||||
option.calculated_price.calculated_amount,
|
||||
is_tax_inclusive:
|
||||
!!option.calculated_price.is_calculated_price_tax_inclusive,
|
||||
data: option.data ?? {},
|
||||
name: option.name,
|
||||
order_id: data.orderExchange.order_id,
|
||||
return_id: data.orderExchange.return_id,
|
||||
exchange_id: data.orderExchange.id,
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
const createdMethods = createOrderShippingMethods({
|
||||
shipping_methods: [shippingMethodInput],
|
||||
})
|
||||
|
||||
const orderChange: OrderChangeDTO = useRemoteQueryStep({
|
||||
entry_point: "order_change",
|
||||
fields: ["id", "status"],
|
||||
fields: ["id", "status", "version"],
|
||||
variables: {
|
||||
filters: {
|
||||
order_id: orderExchange.order_id,
|
||||
@@ -114,43 +92,78 @@ export const createExchangeReturnShippingMethodWorkflow = createWorkflow(
|
||||
list: false,
|
||||
}).config({ name: "order-change-query" })
|
||||
|
||||
validationStep({ order, orderChange })
|
||||
validationStep({ order, orderExchange, orderChange })
|
||||
|
||||
const shippingMethodInput = transform(
|
||||
{
|
||||
orderExchange,
|
||||
shippingOptions,
|
||||
customPrice: input.custom_price,
|
||||
orderChange,
|
||||
input,
|
||||
},
|
||||
(data) => {
|
||||
const option = data.shippingOptions[0]
|
||||
const orderChange = data.orderChange
|
||||
|
||||
return {
|
||||
shipping_option_id: option.id,
|
||||
amount: data.customPrice ?? option.calculated_price.calculated_amount,
|
||||
is_tax_inclusive:
|
||||
!!option.calculated_price.is_calculated_price_tax_inclusive,
|
||||
data: option.data ?? {},
|
||||
name: option.name,
|
||||
version: orderChange.version,
|
||||
order_id: data.orderExchange.order_id,
|
||||
return_id: input.return_id,
|
||||
exchange_id: data.orderExchange.id,
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
const createdMethods = createOrderShippingMethods({
|
||||
shipping_methods: [shippingMethodInput],
|
||||
})
|
||||
|
||||
const orderChangeActionInput = transform(
|
||||
{
|
||||
orderId: order.id,
|
||||
returnId: orderExchange.return_id,
|
||||
exchangeId: orderExchange.id,
|
||||
shippingOption: shippingOptions[0],
|
||||
methodId: createdMethods[0].id,
|
||||
customPrice: input.customShippingPrice,
|
||||
order,
|
||||
orderExchange,
|
||||
shippingOptions,
|
||||
createdMethods,
|
||||
customPrice: input.custom_price,
|
||||
orderChange,
|
||||
input,
|
||||
},
|
||||
({
|
||||
shippingOption,
|
||||
exchangeId,
|
||||
returnId,
|
||||
orderId,
|
||||
methodId,
|
||||
shippingOptions,
|
||||
orderExchange,
|
||||
order,
|
||||
createdMethods,
|
||||
customPrice,
|
||||
orderChange,
|
||||
input,
|
||||
}) => {
|
||||
const shippingOption = shippingOptions[0]
|
||||
const createdMethod = createdMethods[0]
|
||||
const methodPrice =
|
||||
customPrice ?? shippingOption.calculated_price.calculated_amount
|
||||
|
||||
return {
|
||||
action: ChangeActionType.SHIPPING_ADD,
|
||||
reference: "order_shipping_method",
|
||||
reference_id: methodId,
|
||||
order_change_id: orderChange.id,
|
||||
reference_id: createdMethod.id,
|
||||
amount: methodPrice,
|
||||
details: {
|
||||
order_id: orderId,
|
||||
return_id: returnId,
|
||||
exchange_id: exchangeId,
|
||||
},
|
||||
order_id: order.id,
|
||||
return_id: input.return_id,
|
||||
exchange_id: orderExchange.id,
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
const response = createOrderChangeActionsStep([orderChangeActionInput])
|
||||
return new WorkflowResponse(response)
|
||||
createOrderChangeActionsStep([orderChangeActionInput])
|
||||
|
||||
return new WorkflowResponse(previewOrderChangeStep(order.id))
|
||||
}
|
||||
)
|
||||
@@ -18,7 +18,6 @@ import { previewOrderChangeStep } from "../../steps/preview-order-change"
|
||||
import {
|
||||
throwIfIsCancelled,
|
||||
throwIfOrderChangeIsNotActive,
|
||||
throwIfOrderIsCancelled,
|
||||
} from "../../utils/order-validation"
|
||||
import { addOrderLineItemsWorkflow } from "../add-line-items"
|
||||
|
||||
@@ -33,7 +32,7 @@ const validationStep = createStep(
|
||||
orderExchange: OrderExchangeDTO
|
||||
orderChange: OrderChangeDTO
|
||||
}) {
|
||||
throwIfOrderIsCancelled({ order })
|
||||
throwIfIsCancelled(order, "Order")
|
||||
throwIfIsCancelled(orderExchange, "Exchange")
|
||||
throwIfOrderChangeIsNotActive({ orderChange })
|
||||
}
|
||||
@@ -102,7 +101,7 @@ export const orderExchangeAddNewItemWorkflow = createWorkflow(
|
||||
details: {
|
||||
reference_id: lineItems[index].id,
|
||||
quantity: item.quantity,
|
||||
unit_price: item.unit_price,
|
||||
unit_price: item.unit_price ?? lineItems[index].unit_price,
|
||||
metadata: item.metadata,
|
||||
},
|
||||
}))
|
||||
|
||||
@@ -7,23 +7,22 @@ import {
|
||||
} from "@medusajs/types"
|
||||
import { ChangeActionType, OrderChangeStatus } from "@medusajs/utils"
|
||||
import {
|
||||
WorkflowData,
|
||||
WorkflowResponse,
|
||||
createStep,
|
||||
createWorkflow,
|
||||
transform,
|
||||
when,
|
||||
WorkflowData,
|
||||
WorkflowResponse,
|
||||
} from "@medusajs/workflows-sdk"
|
||||
import { useRemoteQueryStep } from "../../../common"
|
||||
import { createOrderChangeActionsStep } from "../../steps/create-order-change-actions"
|
||||
import { createReturnsStep } from "../../steps/create-returns"
|
||||
import { updateOrderExchangesStep } from "../../steps/exchange/update-order-exchanges"
|
||||
import { previewOrderChangeStep } from "../../steps/preview-order-change"
|
||||
import { updateOrderExchangesStep } from "../../steps/update-order-exchanges"
|
||||
import { createReturnsStep } from "../../steps/return/create-returns"
|
||||
import {
|
||||
throwIfIsCancelled,
|
||||
throwIfItemsDoesNotExistsInOrder,
|
||||
throwIfOrderChangeIsNotActive,
|
||||
throwIfOrderIsCancelled,
|
||||
} from "../../utils/order-validation"
|
||||
|
||||
const validationStep = createStep(
|
||||
@@ -41,7 +40,7 @@ const validationStep = createStep(
|
||||
orderChange: OrderChangeDTO
|
||||
items: OrderWorkflow.OrderExchangeRequestItemReturnWorkflowInput["items"]
|
||||
}) {
|
||||
throwIfOrderIsCancelled({ order })
|
||||
throwIfIsCancelled(order, "Order")
|
||||
throwIfIsCancelled(orderExchange, "Exchange")
|
||||
throwIfIsCancelled(orderReturn, "Return")
|
||||
throwIfOrderChangeIsNotActive({ orderChange })
|
||||
@@ -113,7 +112,10 @@ export const orderExchangeRequestItemReturnWorkflow = createWorkflow(
|
||||
},
|
||||
},
|
||||
list: false,
|
||||
}).config({ name: "order-change-query" })
|
||||
}).config({
|
||||
name: "order-change-query",
|
||||
status: [OrderChangeStatus.PENDING, OrderChangeStatus.REQUESTED],
|
||||
})
|
||||
|
||||
validationStep({
|
||||
order,
|
||||
@@ -156,6 +158,7 @@ export const orderExchangeRequestItemReturnWorkflow = createWorkflow(
|
||||
details: {
|
||||
reference_id: item.id,
|
||||
quantity: item.quantity,
|
||||
reason_id: item.reason_id,
|
||||
metadata: item.metadata,
|
||||
},
|
||||
}))
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
import {
|
||||
OrderChangeActionDTO,
|
||||
OrderChangeDTO,
|
||||
OrderDTO,
|
||||
OrderExchangeDTO,
|
||||
OrderWorkflow,
|
||||
} from "@medusajs/types"
|
||||
import { ChangeActionType, OrderChangeStatus } from "@medusajs/utils"
|
||||
import {
|
||||
WorkflowData,
|
||||
WorkflowResponse,
|
||||
createStep,
|
||||
createWorkflow,
|
||||
parallelize,
|
||||
transform,
|
||||
} from "@medusajs/workflows-sdk"
|
||||
import { useRemoteQueryStep } from "../../../common"
|
||||
import { deleteOrderShippingMethods } from "../../steps"
|
||||
import { deleteOrderChangeActionsStep } from "../../steps/delete-order-change-actions"
|
||||
import { previewOrderChangeStep } from "../../steps/preview-order-change"
|
||||
import {
|
||||
throwIfIsCancelled,
|
||||
throwIfOrderChangeIsNotActive,
|
||||
} from "../../utils/order-validation"
|
||||
|
||||
const validationStep = createStep(
|
||||
"validate-remove-exchange-shipping-method",
|
||||
async function ({
|
||||
orderChange,
|
||||
orderExchange,
|
||||
input,
|
||||
}: {
|
||||
input: { exchange_id: string; action_id: string }
|
||||
orderExchange: OrderExchangeDTO
|
||||
orderChange: OrderChangeDTO
|
||||
}) {
|
||||
throwIfIsCancelled(orderExchange, "Exchange")
|
||||
throwIfOrderChangeIsNotActive({ orderChange })
|
||||
|
||||
const associatedAction = (orderChange.actions ?? []).find(
|
||||
(a) => a.id === input.action_id
|
||||
) as OrderChangeActionDTO
|
||||
|
||||
if (!associatedAction) {
|
||||
throw new Error(
|
||||
`No shipping method found for exchange ${input.exchange_id} in order change ${orderChange.id}`
|
||||
)
|
||||
} else if (associatedAction.action !== ChangeActionType.SHIPPING_ADD) {
|
||||
throw new Error(
|
||||
`Action ${associatedAction.id} is not adding a shipping method`
|
||||
)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
export const removeExchangeShippingMethodWorkflowId =
|
||||
"remove-exchange-shipping-method"
|
||||
export const removeExchangeShippingMethodWorkflow = createWorkflow(
|
||||
removeExchangeShippingMethodWorkflowId,
|
||||
function (
|
||||
input: WorkflowData<OrderWorkflow.DeleteExchangeShippingMethodWorkflowInput>
|
||||
): WorkflowResponse<OrderDTO> {
|
||||
const orderExchange: OrderExchangeDTO = useRemoteQueryStep({
|
||||
entry_point: "order_exchange",
|
||||
fields: ["id", "status", "order_id", "canceled_at"],
|
||||
variables: { id: input.exchange_id },
|
||||
list: false,
|
||||
throw_if_key_not_found: true,
|
||||
})
|
||||
|
||||
const orderChange: OrderChangeDTO = useRemoteQueryStep({
|
||||
entry_point: "order_change",
|
||||
fields: ["id", "status", "version", "actions.*"],
|
||||
variables: {
|
||||
filters: {
|
||||
order_id: orderExchange.order_id,
|
||||
exchange_id: orderExchange.id,
|
||||
status: [OrderChangeStatus.PENDING, OrderChangeStatus.REQUESTED],
|
||||
},
|
||||
},
|
||||
list: false,
|
||||
}).config({ name: "order-change-query" })
|
||||
|
||||
validationStep({ orderExchange, orderChange, input })
|
||||
|
||||
const dataToRemove = transform(
|
||||
{ orderChange, input },
|
||||
({ orderChange, input }) => {
|
||||
const associatedAction = (orderChange.actions ?? []).find(
|
||||
(a) => a.id === input.action_id
|
||||
) as OrderChangeActionDTO
|
||||
|
||||
return {
|
||||
actionId: associatedAction.id,
|
||||
shippingMethodId: associatedAction.reference_id,
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
parallelize(
|
||||
deleteOrderChangeActionsStep({ ids: [dataToRemove.actionId] }),
|
||||
deleteOrderShippingMethods({ ids: [dataToRemove.shippingMethodId] })
|
||||
)
|
||||
|
||||
return new WorkflowResponse(previewOrderChangeStep(orderExchange.order_id))
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,119 @@
|
||||
import {
|
||||
OrderChangeActionDTO,
|
||||
OrderChangeDTO,
|
||||
OrderDTO,
|
||||
OrderExchangeDTO,
|
||||
OrderWorkflow,
|
||||
} from "@medusajs/types"
|
||||
import { ChangeActionType, OrderChangeStatus } from "@medusajs/utils"
|
||||
import {
|
||||
WorkflowData,
|
||||
WorkflowResponse,
|
||||
createStep,
|
||||
createWorkflow,
|
||||
transform,
|
||||
} from "@medusajs/workflows-sdk"
|
||||
import { useRemoteQueryStep } from "../../../common"
|
||||
import {
|
||||
previewOrderChangeStep,
|
||||
updateOrderChangeActionsStep,
|
||||
} from "../../steps"
|
||||
import {
|
||||
throwIfIsCancelled,
|
||||
throwIfOrderChangeIsNotActive,
|
||||
} from "../../utils/order-validation"
|
||||
|
||||
const validationStep = createStep(
|
||||
"update-exchange-add-item-validation",
|
||||
async function (
|
||||
{
|
||||
order,
|
||||
orderChange,
|
||||
orderExchange,
|
||||
input,
|
||||
}: {
|
||||
order: OrderDTO
|
||||
orderExchange: OrderExchangeDTO
|
||||
orderChange: OrderChangeDTO
|
||||
input: OrderWorkflow.UpdateExchangeAddNewItemWorkflowInput
|
||||
},
|
||||
context
|
||||
) {
|
||||
throwIfIsCancelled(order, "Order")
|
||||
throwIfIsCancelled(orderExchange, "Exchange")
|
||||
throwIfOrderChangeIsNotActive({ orderChange })
|
||||
|
||||
const associatedAction = (orderChange.actions ?? []).find(
|
||||
(a) => a.id === input.action_id
|
||||
) as OrderChangeActionDTO
|
||||
|
||||
if (!associatedAction) {
|
||||
throw new Error(
|
||||
`No request to add item for exchange ${input.exchange_id} in order change ${orderChange.id}`
|
||||
)
|
||||
} else if (associatedAction.action !== ChangeActionType.ITEM_ADD) {
|
||||
throw new Error(`Action ${associatedAction.id} is not adding an item`)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
export const updateExchangeAddItemWorkflowId = "update-exchange-add-item"
|
||||
export const updateExchangeAddItemWorkflow = createWorkflow(
|
||||
updateExchangeAddItemWorkflowId,
|
||||
function (
|
||||
input: WorkflowData<OrderWorkflow.UpdateExchangeAddNewItemWorkflowInput>
|
||||
): WorkflowResponse<OrderDTO> {
|
||||
const orderExchange: OrderExchangeDTO = useRemoteQueryStep({
|
||||
entry_point: "order_exchange",
|
||||
fields: ["id", "status", "order_id", "canceled_at"],
|
||||
variables: { id: input.exchange_id },
|
||||
list: false,
|
||||
throw_if_key_not_found: true,
|
||||
})
|
||||
|
||||
const order: OrderDTO = useRemoteQueryStep({
|
||||
entry_point: "orders",
|
||||
fields: ["id", "status", "canceled_at", "items.*"],
|
||||
variables: { id: orderExchange.order_id },
|
||||
list: false,
|
||||
throw_if_key_not_found: true,
|
||||
}).config({ name: "order-query" })
|
||||
|
||||
const orderChange: OrderChangeDTO = useRemoteQueryStep({
|
||||
entry_point: "order_change",
|
||||
fields: ["id", "status", "version", "actions.*"],
|
||||
variables: {
|
||||
filters: {
|
||||
order_id: orderExchange.order_id,
|
||||
exchange_id: orderExchange.id,
|
||||
status: [OrderChangeStatus.PENDING, OrderChangeStatus.REQUESTED],
|
||||
},
|
||||
},
|
||||
list: false,
|
||||
}).config({ name: "order-change-query" })
|
||||
|
||||
validationStep({ order, input, orderExchange, orderChange })
|
||||
|
||||
const updateData = transform(
|
||||
{ orderChange, input },
|
||||
({ input, orderChange }) => {
|
||||
const originalAction = (orderChange.actions ?? []).find(
|
||||
(a) => a.id === input.action_id
|
||||
) as OrderChangeActionDTO
|
||||
|
||||
const data = input.data
|
||||
return {
|
||||
id: input.action_id,
|
||||
details: {
|
||||
quantity: data.quantity ?? originalAction.details?.quantity,
|
||||
},
|
||||
internal_note: data.internal_note,
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
updateOrderChangeActionsStep([updateData])
|
||||
|
||||
return new WorkflowResponse(previewOrderChangeStep(order.id))
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,122 @@
|
||||
import {
|
||||
OrderChangeActionDTO,
|
||||
OrderChangeDTO,
|
||||
OrderDTO,
|
||||
OrderExchangeDTO,
|
||||
OrderWorkflow,
|
||||
} from "@medusajs/types"
|
||||
import { ChangeActionType, OrderChangeStatus } from "@medusajs/utils"
|
||||
import {
|
||||
WorkflowData,
|
||||
WorkflowResponse,
|
||||
createStep,
|
||||
createWorkflow,
|
||||
parallelize,
|
||||
transform,
|
||||
} from "@medusajs/workflows-sdk"
|
||||
import { useRemoteQueryStep } from "../../../common"
|
||||
import {
|
||||
updateOrderChangeActionsStep,
|
||||
updateOrderShippingMethodsStep,
|
||||
} from "../../steps"
|
||||
import { previewOrderChangeStep } from "../../steps/preview-order-change"
|
||||
import {
|
||||
throwIfIsCancelled,
|
||||
throwIfOrderChangeIsNotActive,
|
||||
} from "../../utils/order-validation"
|
||||
|
||||
const validationStep = createStep(
|
||||
"validate-update-exchange-shipping-method",
|
||||
async function ({
|
||||
orderChange,
|
||||
orderExchange,
|
||||
input,
|
||||
}: {
|
||||
input: { exchange_id: string; action_id: string }
|
||||
orderExchange: OrderExchangeDTO
|
||||
orderChange: OrderChangeDTO
|
||||
}) {
|
||||
throwIfIsCancelled(orderExchange, "Exchange")
|
||||
throwIfOrderChangeIsNotActive({ orderChange })
|
||||
|
||||
const associatedAction = (orderChange.actions ?? []).find(
|
||||
(a) => a.id === input.action_id
|
||||
) as OrderChangeActionDTO
|
||||
|
||||
if (!associatedAction) {
|
||||
throw new Error(
|
||||
`No shipping method found for exchange ${input.exchange_id} in order change ${orderChange.id}`
|
||||
)
|
||||
} else if (associatedAction.action !== ChangeActionType.SHIPPING_ADD) {
|
||||
throw new Error(
|
||||
`Action ${associatedAction.id} is not adding a shipping method`
|
||||
)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
export const updateExchangeShippingMethodWorkflowId =
|
||||
"update-exchange-shipping-method"
|
||||
export const updateExchangeShippingMethodWorkflow = createWorkflow(
|
||||
updateExchangeShippingMethodWorkflowId,
|
||||
function (
|
||||
input: WorkflowData<OrderWorkflow.UpdateExchangeShippingMethodWorkflowInput>
|
||||
): WorkflowResponse<OrderDTO> {
|
||||
const orderExchange: OrderExchangeDTO = useRemoteQueryStep({
|
||||
entry_point: "order_exchange",
|
||||
fields: ["id", "status", "order_id", "canceled_at"],
|
||||
variables: { id: input.exchange_id },
|
||||
list: false,
|
||||
throw_if_key_not_found: true,
|
||||
})
|
||||
|
||||
const orderChange: OrderChangeDTO = useRemoteQueryStep({
|
||||
entry_point: "order_change",
|
||||
fields: ["id", "status", "version", "actions.*"],
|
||||
variables: {
|
||||
filters: {
|
||||
order_id: orderExchange.order_id,
|
||||
exchange_id: orderExchange.id,
|
||||
status: [OrderChangeStatus.PENDING, OrderChangeStatus.REQUESTED],
|
||||
},
|
||||
},
|
||||
list: false,
|
||||
}).config({ name: "order-change-query" })
|
||||
|
||||
validationStep({ orderExchange, orderChange, input })
|
||||
|
||||
const updateData = transform(
|
||||
{ orderChange, input },
|
||||
({ input, orderChange }) => {
|
||||
const originalAction = (orderChange.actions ?? []).find(
|
||||
(a) => a.id === input.action_id
|
||||
) as OrderChangeActionDTO
|
||||
|
||||
const data = input.data
|
||||
|
||||
const action = {
|
||||
id: originalAction.id,
|
||||
internal_note: data.internal_note,
|
||||
}
|
||||
|
||||
const shippingMethod = {
|
||||
id: originalAction.reference_id,
|
||||
amount: data.custom_price,
|
||||
metadata: data.metadata,
|
||||
}
|
||||
|
||||
return {
|
||||
action,
|
||||
shippingMethod,
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
parallelize(
|
||||
updateOrderChangeActionsStep([updateData.action]),
|
||||
updateOrderShippingMethodsStep([updateData.shippingMethod!])
|
||||
)
|
||||
|
||||
return new WorkflowResponse(previewOrderChangeStep(orderExchange.order_id))
|
||||
}
|
||||
)
|
||||
@@ -26,9 +26,15 @@ export * from "./decline-order-change"
|
||||
export * from "./delete-order-change"
|
||||
export * from "./delete-order-change-actions"
|
||||
export * from "./exchange/begin-order-exchange"
|
||||
export * from "./exchange/create-exchange-return-shipping-method"
|
||||
export * from "./exchange/cancel-begin-order-exchange"
|
||||
export * from "./exchange/cancel-exchange"
|
||||
export * from "./exchange/confirm-exchange-request"
|
||||
export * from "./exchange/create-exchange-shipping-method"
|
||||
export * from "./exchange/exchange-add-new-item"
|
||||
export * from "./exchange/exchange-request-item-return"
|
||||
export * from "./exchange/remove-exchange-shipping-method"
|
||||
export * from "./exchange/update-exchange-add-item"
|
||||
export * from "./exchange/update-exchange-shipping-method"
|
||||
export * from "./get-order-detail"
|
||||
export * from "./get-orders-list"
|
||||
export * from "./return/begin-receive-return"
|
||||
|
||||
@@ -6,7 +6,6 @@ import {
|
||||
} from "@medusajs/types"
|
||||
import { ChangeActionType, Modules, OrderChangeStatus } from "@medusajs/utils"
|
||||
import {
|
||||
WorkflowData,
|
||||
WorkflowResponse,
|
||||
createStep,
|
||||
createWorkflow,
|
||||
@@ -17,7 +16,7 @@ import { createRemoteLinkStep, useRemoteQueryStep } from "../../../common"
|
||||
import { createReturnFulfillmentWorkflow } from "../../../fulfillment/workflows/create-return-fulfillment"
|
||||
import { previewOrderChangeStep } from "../../steps"
|
||||
import { confirmOrderChanges } from "../../steps/confirm-order-changes"
|
||||
import { createReturnItemsFromActionsStep } from "../../steps/create-return-items-from-actions"
|
||||
import { createReturnItemsFromActionsStep } from "../../steps/return/create-return-items-from-actions"
|
||||
import {
|
||||
throwIfIsCancelled,
|
||||
throwIfOrderChangeIsNotActive,
|
||||
|
||||
@@ -16,8 +16,8 @@ import {
|
||||
} from "@medusajs/workflows-sdk"
|
||||
import { createRemoteLinkStep, useRemoteQueryStep } from "../../../common"
|
||||
import { createReturnFulfillmentWorkflow } from "../../../fulfillment"
|
||||
import { createCompleteReturnStep } from "../../steps/create-complete-return"
|
||||
import { receiveReturnStep } from "../../steps/receive-return"
|
||||
import { createCompleteReturnStep } from "../../steps/return/create-complete-return"
|
||||
import { receiveReturnStep } from "../../steps/return/receive-return"
|
||||
import {
|
||||
throwIfItemsDoesNotExistsInOrder,
|
||||
throwIfOrderIsCancelled,
|
||||
|
||||
@@ -8,7 +8,7 @@ import {
|
||||
import { useRemoteQueryStep } from "../../../common"
|
||||
|
||||
import { ReturnDTO } from "@medusajs/types"
|
||||
import { receiveReturnStep } from "../../steps/receive-return"
|
||||
import { receiveReturnStep } from "../../steps/return/receive-return"
|
||||
import {
|
||||
throwIfIsCancelled,
|
||||
throwIfItemsDoesNotExistsInReturn,
|
||||
|
||||
@@ -25,6 +25,11 @@ export interface OrderClaimAddNewItemWorkflowInput {
|
||||
items: NewItem[]
|
||||
}
|
||||
|
||||
export interface OrderExchangeAddNewItemWorkflowInput {
|
||||
exchange_id: string
|
||||
items: NewItem[]
|
||||
}
|
||||
|
||||
export interface OrderAddLineItemWorkflowInput {
|
||||
order_id: string
|
||||
items: NewItem[]
|
||||
@@ -48,6 +53,15 @@ export interface UpdateClaimAddNewItemWorkflowInput {
|
||||
}
|
||||
}
|
||||
|
||||
export interface UpdateExchangeAddNewItemWorkflowInput {
|
||||
exchange_id: string
|
||||
action_id: string
|
||||
data: {
|
||||
quantity?: BigNumberInput
|
||||
internal_note?: string | null
|
||||
}
|
||||
}
|
||||
|
||||
export interface OrderExchangeItemWorkflowInput {
|
||||
exchange_id: string
|
||||
items: ExistingItem[]
|
||||
@@ -86,3 +100,8 @@ export interface DeleteOrderClaimItemActionWorkflowInput {
|
||||
claim_id: string
|
||||
action_id: string
|
||||
}
|
||||
|
||||
export interface DeleteOrderExchangeItemActionWorkflowInput {
|
||||
exchange_id: string
|
||||
action_id: string
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user