feat(core-flows): request return on order exchanges and claims (#8107)

FIXES: CC-92, CC-87
This commit is contained in:
Carlos R. L. Rodrigues
2024-07-12 15:48:24 +00:00
committed by GitHub
parent 136da3f3ce
commit 4321241553
25 changed files with 695 additions and 69 deletions
@@ -60,7 +60,7 @@ medusaIntegrationTestRunner({
describe("Orders - Admin", () => {
it("should get an order", async () => {
const created = await orderModule.createOrders({
region_id: "test_region_idclear",
region_id: "test_region_id",
email: "foo@bar.com",
items: [
{
@@ -205,7 +205,7 @@ export async function createOrderFixture({
)
let order = await orderService.createOrders({
region_id: "test_region_idclear",
region_id: "test_region_id",
email: "foo@bar.com",
items: [
{
@@ -1,6 +1,7 @@
import {
beginClaimOrderWorkflow,
createShippingOptionsWorkflow,
orderClaimRequestItemReturnWorkflow,
} from "@medusajs/core-flows"
import {
FulfillmentWorkflow,
@@ -232,7 +233,7 @@ async function createOrderFixture({ container, product }) {
ModuleRegistrationName.ORDER
)
let order = await orderService.createOrders({
region_id: "test_region_idclear",
region_id: "test_region_id",
email: "foo@bar.com",
items: [
{
@@ -382,11 +383,56 @@ medusaIntegrationTestRunner({
fields: ["order_id", "id", "type"],
})
const [returnOrder] = await remoteQuery(remoteQueryObject)
const [claimOrder] = await remoteQuery(remoteQueryObject)
expect(returnOrder.order_id).toEqual(order.id)
expect(returnOrder.type).toEqual("refund")
expect(returnOrder.id).toBeDefined()
expect(claimOrder.order_id).toEqual(order.id)
expect(claimOrder.type).toEqual("refund")
expect(claimOrder.id).toBeDefined()
// Request itemm to return
const { result: preview } =
await orderClaimRequestItemReturnWorkflow.run({
throwOnError: true,
container,
input: {
claim_id: claimOrder.id,
items: [
{
id: order.items![0].id,
quantity: 1,
},
],
},
})
expect(preview.items[0]).toEqual(
expect.objectContaining({
quantity: 1,
id: order.items![0].id,
detail: expect.objectContaining({
quantity: 1,
fulfilled_quantity: 1,
return_requested_quantity: 1,
}),
actions: [
expect.objectContaining({
order_id: order.id,
claim_id: claimOrder.id,
version: 2,
order_change_id: expect.any(String),
reference: "return",
reference_id: expect.stringContaining("return_"),
action: "RETURN_ITEM",
details: expect.objectContaining({
quantity: 1,
return_id: expect.stringContaining("return_"),
claim_id: claimOrder.id,
reference_id: order.items![0].id,
}),
}),
],
})
)
})
})
},
@@ -1,10 +1,10 @@
import {
beginExchangeOrderWorkflow,
createShippingOptionsWorkflow,
orderExchangeRequestItemReturnWorkflow,
} from "@medusajs/core-flows"
import {
FulfillmentWorkflow,
IOrderModuleService,
IRegionModuleService,
IStockLocationService,
OrderWorkflow,
@@ -227,18 +227,16 @@ async function prepareDataFixtures({ container }) {
}
async function createOrderFixture({ container, product }) {
const orderService: IOrderModuleService = container.resolve(
ModuleRegistrationName.ORDER
)
const orderService = container.resolve(ModuleRegistrationName.ORDER)
let order = await orderService.createOrders({
region_id: "test_region_idclear",
region_id: "test_region_id",
email: "foo@bar.com",
items: [
{
title: "Custom Item 2",
variant_sku: product.variants[0].sku,
variant_title: product.variants[0].title,
quantity: 1,
quantity: 5,
unit_price: 50,
adjustments: [
{
@@ -251,12 +249,6 @@ async function createOrderFixture({ container, product }) {
],
} as any,
],
transactions: [
{
amount: 50,
currency_code: "usd",
},
],
sales_channel_id: "test",
shipping_address: {
first_name: "Test",
@@ -311,7 +303,7 @@ async function createOrderFixture({ container, product }) {
reference_id: "fulfill_123",
details: {
reference_id: order.items![0].id,
quantity: 1,
quantity: 3,
},
},
{
@@ -356,7 +348,7 @@ medusaIntegrationTestRunner({
product = fixtures.product
})
it("should begin an exchange order", async () => {
it("should begin an exchange order, request item return", async () => {
const order = await createOrderFixture({ container, product })
const createExchangeOrderData: OrderWorkflow.beginOrderExchangeWorkflowInput =
@@ -369,9 +361,9 @@ medusaIntegrationTestRunner({
},
}
await beginExchangeOrderWorkflow(container).run({
await beginExchangeOrderWorkflow.run({
container,
input: createExchangeOrderData,
throwOnError: true,
})
const remoteQuery = container.resolve(
@@ -385,15 +377,119 @@ medusaIntegrationTestRunner({
fields: ["order_id", "id", "metadata"],
})
const [returnOrder] = await remoteQuery(remoteQueryObject)
const [exchangeOrder] = await remoteQuery(remoteQueryObject)
expect(returnOrder.order_id).toEqual(order.id)
expect(returnOrder.metadata).toEqual({
expect(exchangeOrder.order_id).toEqual(order.id)
expect(exchangeOrder.metadata).toEqual({
reason: "test",
extra: "data",
value: 1234,
})
expect(returnOrder.id).toBeDefined()
expect(exchangeOrder.id).toBeDefined()
// Request itemm to return
const { result: preview } =
await orderExchangeRequestItemReturnWorkflow.run({
throwOnError: true,
container,
input: {
exchange_id: exchangeOrder.id,
items: [
{
id: order.items![0].id,
quantity: 1,
},
],
},
})
expect(preview.items[0]).toEqual(
expect.objectContaining({
quantity: 5,
id: order.items![0].id,
detail: expect.objectContaining({
quantity: 5,
fulfilled_quantity: 3,
return_requested_quantity: 1,
}),
actions: [
expect.objectContaining({
order_id: order.id,
exchange_id: exchangeOrder.id,
version: 2,
order_change_id: expect.any(String),
reference: "return",
reference_id: expect.stringContaining("return_"),
action: "RETURN_ITEM",
details: expect.objectContaining({
quantity: 1,
return_id: expect.stringContaining("return_"),
exchange_id: exchangeOrder.id,
reference_id: order.items![0].id,
}),
}),
],
})
)
const { errors } = await orderExchangeRequestItemReturnWorkflow.run({
throwOnError: false,
container,
input: {
exchange_id: exchangeOrder.id,
items: [
{
id: order.items![0].id,
quantity: 3,
},
],
},
})
expect(errors[0].error.message).toEqual(
`Cannot request to return more items than what was fulfilled for item ${
order.items![0].id
}.`
)
const { result: anotherPreview } =
await orderExchangeRequestItemReturnWorkflow.run({
container,
input: {
exchange_id: exchangeOrder.id,
items: [
{
id: order.items![0].id,
quantity: 2,
},
],
},
})
expect(anotherPreview.items[0]).toEqual(
expect.objectContaining({
detail: expect.objectContaining({
quantity: 5,
fulfilled_quantity: 3,
return_requested_quantity: 3,
}),
actions: [
expect.objectContaining({
reference_id: preview.items[0].actions[0].reference_id,
action: "RETURN_ITEM",
details: expect.objectContaining({
quantity: 1,
}),
}),
expect.objectContaining({
reference_id: preview.items[0].actions[0].reference_id,
action: "RETURN_ITEM",
details: expect.objectContaining({
quantity: 2,
}),
}),
],
})
)
})
})
},
@@ -231,7 +231,7 @@ async function createOrderFixture({ container, product }) {
ModuleRegistrationName.ORDER
)
let order = await orderService.createOrders({
region_id: "test_region_idclear",
region_id: "test_region_id",
email: "foo@bar.com",
items: [
{
@@ -235,7 +235,7 @@ async function createOrderFixture({ container, product }) {
ModuleRegistrationName.ORDER
)
let order = await orderService.createOrders({
region_id: "test_region_idclear",
region_id: "test_region_id",
email: "foo@bar.com",
items: [
{
@@ -434,7 +434,7 @@ medusaIntegrationTestRunner({
expect.objectContaining({
id: expect.any(String),
display_id: 1,
region_id: "test_region_idclear",
region_id: "test_region_id",
customer_id: "joe",
version: 2,
sales_channel_id: "test", // TODO: What about order with a sales channel but a shipping option link to a stock from another channel?
@@ -217,7 +217,7 @@ async function createOrderFixture({ container, product, location }) {
ModuleRegistrationName.ORDER
)
let order = await orderService.createOrders({
region_id: "test_region_idclear",
region_id: "test_region_id",
email: "foo@bar.com",
items: [
{
@@ -220,7 +220,7 @@ async function createOrderFixture({ container, product, location }) {
ModuleRegistrationName.ORDER
)
let order = await orderService.createOrders({
region_id: "test_region_idclear",
region_id: "test_region_id",
email: "foo@bar.com",
items: [
{
@@ -16,8 +16,10 @@ export * from "./decline-order-change"
export * from "./delete-order-change"
export * from "./delete-order-change-actions"
export * from "./get-item-tax-lines"
export * from "./preview-order-change"
export * from "./register-fulfillment"
export * from "./register-shipment"
export * from "./set-tax-lines-for-items"
export * from "./update-order-change-actions"
export * from "./update-order-exchanges"
export * from "./update-tax-lines"
@@ -0,0 +1,17 @@
import { IOrderModuleService } from "@medusajs/types"
import { ModuleRegistrationName } from "@medusajs/utils"
import { StepResponse, createStep } from "@medusajs/workflows-sdk"
export const previewOrderChangeStepId = "preview-order-change"
export const previewOrderChangeStep = createStep(
previewOrderChangeStepId,
async (orderId: string, { container }) => {
const service = container.resolve<IOrderModuleService>(
ModuleRegistrationName.ORDER
)
const preview = await service.previewOrderChange(orderId)
return new StepResponse(preview)
}
)
@@ -0,0 +1,55 @@
import { IOrderModuleService, UpdateOrderClaimDTO } from "@medusajs/types"
import {
ModuleRegistrationName,
getSelectsAndRelationsFromObjectArray,
} from "@medusajs/utils"
import { StepResponse, createStep } from "@medusajs/workflows-sdk"
export const updateOrderClaimsStepId = "update-order-claim"
export const updateOrderClaimsStep = createStep(
updateOrderClaimsStepId,
async (data: UpdateOrderClaimDTO[], { container }) => {
const service = container.resolve<IOrderModuleService>(
ModuleRegistrationName.ORDER
)
const { selects, relations } = getSelectsAndRelationsFromObjectArray(data, {
objectFields: ["metadata"],
})
const dataBeforeUpdate = await service.listOrderClaims(
{ id: data.map((d) => d.id) },
{ relations, select: selects }
)
const updated = await service.updateOrderClaims(
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.updateOrderClaims(
dataBeforeUpdate.map((dt) => {
const { id, ...rest } = dt
return {
selector: { id },
data: rest,
}
})
)
}
)
@@ -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,
}
})
)
}
)
@@ -41,15 +41,14 @@ export function throwIfItemsDoesNotExistsInOrder({
}
}
export function throwIfReturnIsCancelled({
orderReturn,
}: {
orderReturn: ReturnDTO
}) {
if (orderReturn.canceled_at) {
export function throwIfIsCancelled(
obj: unknown & { id: string; canceled_at?: any },
type: string
) {
if (obj.canceled_at) {
throw new MedusaError(
MedusaError.Types.INVALID_DATA,
`return with id ${orderReturn.id} has been canceled.`
`${type} with id ${obj.id} has been canceled.`
)
}
}
@@ -12,7 +12,7 @@ import {
} from "@medusajs/workflows-sdk"
import { useRemoteQueryStep } from "../../common"
import { cancelOrderReturnStep } from "../steps"
import { throwIfReturnIsCancelled } from "../utils/order-validation"
import { throwIfIsCancelled } from "../utils/order-validation"
const validateOrder = createStep(
"validate-return",
@@ -27,7 +27,7 @@ const validateOrder = createStep(
fulfillments: FulfillmentDTO[]
}
throwIfReturnIsCancelled({ orderReturn })
throwIfIsCancelled(orderReturn, "Return")
const throwErrorIf = (
arr: unknown[],
@@ -0,0 +1,163 @@
import {
OrderChangeDTO,
OrderClaimDTO,
OrderDTO,
OrderWorkflow,
ReturnDTO,
} from "@medusajs/types"
import { ChangeActionType } from "@medusajs/utils"
import {
WorkflowData,
createStep,
createWorkflow,
transform,
when,
} from "@medusajs/workflows-sdk"
import { useRemoteQueryStep } from "../../common"
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 {
throwIfIsCancelled,
throwIfItemsDoesNotExistsInOrder,
throwIfOrderChangeIsNotActive,
throwIfOrderIsCancelled,
} from "../utils/order-validation"
const validationStep = createStep(
"claim-request-item-return-validation",
async function ({
order,
orderChange,
orderReturn,
orderClaim,
items,
}: {
order: OrderDTO
orderReturn: ReturnDTO
orderClaim: OrderClaimDTO
orderChange: OrderChangeDTO
items: OrderWorkflow.OrderClaimRequestItemReturnWorkflowInput["items"]
}) {
throwIfOrderIsCancelled({ order })
throwIfIsCancelled(orderClaim, "Claim")
throwIfIsCancelled(orderReturn, "Return")
throwIfOrderChangeIsNotActive({ orderChange })
throwIfItemsDoesNotExistsInOrder({ order, inputItems: items })
}
)
export const orderClaimRequestItemReturnWorkflowId = "claim-request-item-return"
export const orderClaimRequestItemReturnWorkflow = createWorkflow(
orderClaimRequestItemReturnWorkflowId,
function (
input: WorkflowData<OrderWorkflow.OrderClaimRequestItemReturnWorkflowInput>
): WorkflowData<OrderDTO> {
const orderClaim = useRemoteQueryStep({
entry_point: "order_claim",
fields: ["id", "order_id", "return_id"],
variables: { id: input.claim_id },
list: false,
throw_if_key_not_found: true,
}).config({ name: "claim-query" })
const existingOrderReturn = when({ orderClaim }, ({ orderClaim }) => {
return orderClaim.return_id
}).then(() => {
return useRemoteQueryStep({
entry_point: "return",
fields: ["id", "status", "order_id"],
variables: { id: orderClaim.return_id },
list: false,
throw_if_key_not_found: true,
}).config({ name: "return-query" }) as ReturnDTO
})
const createdReturn = when({ orderClaim }, ({ orderClaim }) => {
return !orderClaim.return_id
}).then(() => {
return createReturnsStep([
{
order_id: orderClaim.order_id,
claim_id: orderClaim.id,
},
])
})
const orderReturn: ReturnDTO = transform(
{ createdReturn, existingOrderReturn, orderClaim },
({ createdReturn, existingOrderReturn, orderClaim }) => {
return existingOrderReturn ?? (createdReturn[0] as ReturnDTO)
}
)
const order: OrderDTO = useRemoteQueryStep({
entry_point: "orders",
fields: ["id", "status", "items.*"],
variables: { id: orderClaim.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"],
variables: { order_id: orderClaim.order_id },
list: false,
}).config({ name: "order-change-query" })
validationStep({
order,
items: input.items,
orderClaim,
orderReturn,
orderChange,
})
when({ orderClaim }, ({ orderClaim }) => {
return !orderClaim.return_id
}).then(() => {
const createdReturnId = transform(
{ createdReturn },
({ createdReturn }) => {
return createdReturn[0]!.id
}
)
updateOrderClaimsStep([
{
id: orderClaim.id,
return_id: createdReturnId,
},
])
})
const orderChangeActionInput = transform(
{ order, orderChange, orderClaim, orderReturn, items: input.items },
({ order, orderChange, orderClaim, orderReturn, items }) => {
return items.map((item) => ({
order_change_id: orderChange.id,
order_id: order.id,
claim_id: orderClaim.id,
return_id: orderReturn.id,
version: orderChange.version,
action: ChangeActionType.RETURN_ITEM,
internal_note: item.internal_note,
reference: "return",
reference_id: orderReturn.id,
details: {
reference_id: item.id,
claim_id: orderClaim.id,
return_id: orderReturn.id,
quantity: item.quantity,
metadata: item.metadata,
},
}))
}
)
createOrderChangeActionsStep(orderChangeActionInput)
return previewOrderChangeStep(orderClaim.order_id)
}
)
@@ -0,0 +1,164 @@
import {
OrderChangeDTO,
OrderDTO,
OrderExchangeDTO,
OrderWorkflow,
ReturnDTO,
} from "@medusajs/types"
import { ChangeActionType } from "@medusajs/utils"
import {
WorkflowData,
createStep,
createWorkflow,
transform,
when,
} from "@medusajs/workflows-sdk"
import { useRemoteQueryStep } from "../../common"
import { createOrderChangeActionsStep } from "../steps/create-order-change-actions"
import { createReturnsStep } from "../steps/create-returns"
import { previewOrderChangeStep } from "../steps/preview-order-change"
import { updateOrderExchangesStep } from "../steps/update-order-exchanges"
import {
throwIfIsCancelled,
throwIfItemsDoesNotExistsInOrder,
throwIfOrderChangeIsNotActive,
throwIfOrderIsCancelled,
} from "../utils/order-validation"
const validationStep = createStep(
"exchange-request-item-return-validation",
async function ({
order,
orderChange,
orderReturn,
orderExchange,
items,
}: {
order: OrderDTO
orderReturn: ReturnDTO
orderExchange: OrderExchangeDTO
orderChange: OrderChangeDTO
items: OrderWorkflow.OrderExchangeRequestItemReturnWorkflowInput["items"]
}) {
throwIfOrderIsCancelled({ order })
throwIfIsCancelled(orderExchange, "Exchange")
throwIfIsCancelled(orderReturn, "Return")
throwIfOrderChangeIsNotActive({ orderChange })
throwIfItemsDoesNotExistsInOrder({ order, inputItems: items })
}
)
export const orderExchangeRequestItemReturnWorkflowId =
"exchange-request-item-return"
export const orderExchangeRequestItemReturnWorkflow = createWorkflow(
orderExchangeRequestItemReturnWorkflowId,
function (
input: WorkflowData<OrderWorkflow.OrderExchangeRequestItemReturnWorkflowInput>
): WorkflowData<OrderDTO> {
const orderExchange = useRemoteQueryStep({
entry_point: "order_exchange",
fields: ["id", "order_id", "return_id"],
variables: { id: input.exchange_id },
list: false,
throw_if_key_not_found: true,
}).config({ name: "exchange-query" })
const existingOrderReturn = when({ orderExchange }, ({ orderExchange }) => {
return orderExchange.return_id
}).then(() => {
return useRemoteQueryStep({
entry_point: "return",
fields: ["id", "status", "order_id"],
variables: { id: orderExchange.return_id },
list: false,
throw_if_key_not_found: true,
}).config({ name: "return-query" }) as ReturnDTO
})
const createdReturn = when({ orderExchange }, ({ orderExchange }) => {
return !orderExchange.return_id
}).then(() => {
return createReturnsStep([
{
order_id: orderExchange.order_id,
exchange_id: orderExchange.id,
},
])
})
const orderReturn: ReturnDTO = transform(
{ createdReturn, existingOrderReturn, orderExchange },
({ createdReturn, existingOrderReturn, orderExchange }) => {
return existingOrderReturn ?? (createdReturn[0] as ReturnDTO)
}
)
const order: OrderDTO = useRemoteQueryStep({
entry_point: "orders",
fields: ["id", "status", "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"],
variables: { order_id: orderExchange.order_id },
list: false,
}).config({ name: "order-change-query" })
validationStep({
order,
items: input.items,
orderExchange,
orderReturn,
orderChange,
})
when({ orderExchange }, ({ orderExchange }) => {
return !orderExchange.return_id
}).then(() => {
const createdReturnId = transform(
{ createdReturn },
({ createdReturn }) => {
return createdReturn[0]!.id
}
)
updateOrderExchangesStep([
{
id: orderExchange.id,
return_id: createdReturnId,
},
])
})
const orderChangeActionInput = transform(
{ order, orderChange, orderExchange, orderReturn, items: input.items },
({ order, orderChange, orderExchange, orderReturn, items }) => {
return items.map((item) => ({
order_change_id: orderChange.id,
order_id: order.id,
exchange_id: orderExchange.id,
return_id: orderReturn.id,
version: orderChange.version,
action: ChangeActionType.RETURN_ITEM,
internal_note: item.internal_note,
reference: "return",
reference_id: orderReturn.id,
details: {
reference_id: item.id,
exchange_id: orderExchange.id,
return_id: orderReturn.id,
quantity: item.quantity,
metadata: item.metadata,
},
}))
}
)
createOrderChangeActionsStep(orderChangeActionInput)
return previewOrderChangeStep(orderExchange.order_id)
}
)
@@ -6,6 +6,7 @@ export * from "./cancel-order"
export * from "./cancel-order-change"
export * from "./cancel-order-fulfillment"
export * from "./cancel-return"
export * from "./claim-request-item-return"
export * from "./complete-orders"
export * from "./create-complete-return"
export * from "./create-fulfillment"
@@ -16,6 +17,7 @@ export * from "./create-shipment"
export * from "./decline-order-change"
export * from "./delete-order-change"
export * from "./delete-order-change-actions"
export * from "./exchange-request-item-return"
export * from "./get-order-detail"
export * from "./get-orders-list"
export * from "./receive-return"
@@ -9,8 +9,8 @@ import { useRemoteQueryStep } from "../../common"
import { ReturnDTO } from "@medusajs/types"
import { receiveReturnStep } from "../steps/receive-return"
import {
throwIfIsCancelled,
throwIfItemsDoesNotExistsInReturn,
throwIfReturnIsCancelled,
} from "../utils/order-validation"
const validationStep = createStep(
@@ -25,7 +25,7 @@ const validationStep = createStep(
},
context
) {
throwIfReturnIsCancelled({ orderReturn })
throwIfIsCancelled(orderReturn, "Return")
throwIfItemsDoesNotExistsInReturn({ orderReturn, inputItems: input.items })
}
)
@@ -15,10 +15,10 @@ import {
import { useRemoteQueryStep } from "../../common"
import { createOrderChangeActionsStep } from "../steps/create-order-change-actions"
import {
throwIfIsCancelled,
throwIfItemsDoesNotExistsInOrder,
throwIfOrderChangeIsNotActive,
throwIfOrderIsCancelled,
throwIfReturnIsCancelled,
} from "../utils/order-validation"
const validationStep = createStep(
@@ -35,7 +35,7 @@ const validationStep = createStep(
items: OrderWorkflow.RequestItemReturnWorkflowInput["items"]
}) {
throwIfOrderIsCancelled({ order })
throwIfReturnIsCancelled({ orderReturn })
throwIfIsCancelled(orderReturn, "Return")
throwIfOrderChangeIsNotActive({ orderChange })
throwIfItemsDoesNotExistsInOrder({ order, inputItems: items })
}
@@ -49,7 +49,7 @@ export const requestItemReturnWorkflow = createWorkflow(
): WorkflowData<OrderChangeActionDTO[]> {
const orderReturn: ReturnDTO = useRemoteQueryStep({
entry_point: "return",
fields: ["id", "status", "refund_amount", "order_id", "items.*"],
fields: ["id", "status", "order_id"],
variables: { id: input.return_id },
list: false,
throw_if_key_not_found: true,
+6 -2
View File
@@ -326,6 +326,7 @@ export interface CreateOrderChangeActionDTO {
export interface UpdateOrderChangeActionDTO {
id: string
internal_note?: string | null
metadata?: Record<string, unknown> | null
}
/** ORDER TRANSACTION START */
@@ -436,7 +437,8 @@ export interface CreateOrderReturnDTO extends BaseOrderBundledActionsDTO {
exchange_id?: string
}
export interface UpdateOrderReturnDTO {
export interface UpdateReturnDTO {
id: string
refund_amount?: BigNumberInput
no_notification?: boolean
claim_id?: string
@@ -445,6 +447,7 @@ export interface UpdateOrderReturnDTO {
}
export interface UpdateOrderClaimDTO {
id: string
refund_amount?: BigNumberInput
no_notification?: boolean
return_id?: string
@@ -453,6 +456,7 @@ export interface UpdateOrderClaimDTO {
}
export interface UpdateOrderExchangeDTO {
id: string
difference_due?: BigNumberInput
no_notification?: boolean
return_id?: string
@@ -462,7 +466,7 @@ export interface UpdateOrderExchangeDTO {
export interface UpdateOrderReturnWithSelectorDTO {
selector: Partial<ReturnDTO>
data: Partial<UpdateOrderReturnDTO>
data: Partial<UpdateReturnDTO>
}
export interface UpdateOrderClaimWithSelectorDTO {
+3 -3
View File
@@ -75,12 +75,12 @@ import {
UpdateOrderLineItemDTO,
UpdateOrderLineItemTaxLineDTO,
UpdateOrderLineItemWithSelectorDTO,
UpdateOrderReturnDTO,
UpdateOrderReturnReasonDTO,
UpdateOrderReturnReasonWithSelectorDTO,
UpdateOrderReturnWithSelectorDTO,
UpdateOrderShippingMethodAdjustmentDTO,
UpdateOrderShippingMethodTaxLineDTO,
UpdateReturnDTO,
UpsertOrderLineItemAdjustmentDTO,
} from "./mutations"
@@ -1899,12 +1899,12 @@ export interface IOrderModuleService extends IModuleService {
updateReturns(
selector: Partial<FilterableReturnProps>,
data: Partial<UpdateOrderReturnDTO>,
data: Partial<UpdateReturnDTO>,
sharedContext?: Context
): Promise<ReturnDTO[]>
updateReturns(
id: string,
data: Partial<UpdateOrderReturnDTO>,
data: Partial<UpdateReturnDTO>,
sharedContext?: Context
): Promise<ReturnDTO>
@@ -4,3 +4,13 @@ export interface RequestItemReturnWorkflowInput {
return_id: string
items: CreateReturnItem[]
}
export interface OrderExchangeRequestItemReturnWorkflowInput {
exchange_id: string
items: CreateReturnItem[]
}
export interface OrderClaimRequestItemReturnWorkflowInput {
claim_id: string
items: CreateReturnItem[]
}
@@ -120,9 +120,17 @@ describe("Workflow composer", () => {
}
)
const { result } = await workflow.run({ input: { callSubFlow: true } })
const { result } = await workflow.run({
input: { callSubFlow: true },
})
expect(result).toEqual({ result: "hi from outside" })
const { result: res2 } = await workflow.run({
input: { callSubFlow: false },
})
expect(res2).toEqual({ result: "default response" })
})
it("should revert the workflow and sub workflow on failure", async function () {
@@ -1932,9 +1932,28 @@ export default class OrderModuleService<
return await this.orderChangeService_.create(input, sharedContext)
}
async previewOrderChange(orderChangeId: string, sharedContext?: Context) {
@InjectManager("baseRepository_")
async previewOrderChange(orderId: string, sharedContext?: Context) {
const order = await this.retrieveOrder(
orderId,
{
select: ["id", "version", "items.detail", "summary", "total"],
relations: [
"transactions",
"items",
"items.detail",
"shipping_methods",
],
},
sharedContext
)
if (!order.order_change) {
return order
}
const orderChange = await super.retrieveOrderChange(
orderChangeId,
order.order_change.id,
{ relations: ["actions"] },
sharedContext
)
@@ -1950,20 +1969,6 @@ export default class OrderModuleService<
}
})
const order = await this.retrieveOrder(
orderChange.order_id,
{
select: ["id", "version", "items.detail", "summary", "total"],
relations: [
"transactions",
"items",
"items.detail",
"shipping_methods",
],
},
sharedContext
)
const calculated = calculateOrderChange({
order: order as any,
actions: orderChange.actions,
@@ -97,7 +97,7 @@ function cleanNestedRelations(obj) {
}
function formatOrderReturn(orderReturn, mainOrder) {
orderReturn.items.forEach((orderItem) => {
orderReturn.items?.forEach((orderItem) => {
const item = mainOrder.items?.find((item) => item.id === orderItem.item_id)
orderItem.detail = item?.detail