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:
1 parent
7569fd1605
commit
accf884bb1
38 files changed
+1156
-223
No files matched your search
-125
@@ -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,
|
||||
})
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
},
|
||||
})
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
+50
@@ -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)
|
||||
}
|
||||
)
|
||||
File renamed without changes.
@@ -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"
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -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)
|
||||
}
|
||||
)
|
||||
+76
-63
@@ -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,
|
||||
},
|
||||
}))
|
||||
|
||||
+10
-7
@@ -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,
|
||||
},
|
||||
}))
|
||||
|
||||
+107
@@ -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))
|
||||
}
|
||||
)
|
||||
+122
@@ -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