fix(core-flow): request item return reason (#8152)
This commit is contained in:
committed by
GitHub
parent
1d40b3cc98
commit
d4fe2daa57
@@ -1,6 +1,10 @@
|
||||
import { IOrderModuleService, OrderChangeActionDTO } from "@medusajs/types"
|
||||
import {
|
||||
IOrderModuleService,
|
||||
OrderChangeActionDTO,
|
||||
UpdateReturnDTO,
|
||||
} from "@medusajs/types"
|
||||
import { ModuleRegistrationName } from "@medusajs/utils"
|
||||
import { createStep, StepResponse } from "@medusajs/workflows-sdk"
|
||||
import { StepResponse, createStep } from "@medusajs/workflows-sdk"
|
||||
|
||||
type CreateReturnItemsInput = {
|
||||
changes: OrderChangeActionDTO[]
|
||||
@@ -18,6 +22,7 @@ export const createReturnItems = createStep(
|
||||
return {
|
||||
return_id: item.reference_id,
|
||||
item_id: item.details?.reference_id,
|
||||
reason_id: item.details?.reason_id,
|
||||
quantity: item.details?.quantity as number,
|
||||
note: item.internal_note,
|
||||
metadata: (item.details?.metadata as Record<string, unknown>) ?? {},
|
||||
@@ -33,7 +38,10 @@ export const createReturnItems = createStep(
|
||||
)
|
||||
|
||||
const createdReturnItems = await orderModuleService.updateReturns([
|
||||
{ selector: { id: input.returnId }, data: { items: returnItems } },
|
||||
{
|
||||
selector: { id: input.returnId },
|
||||
data: { items: returnItems as UpdateReturnDTO["items"] },
|
||||
},
|
||||
])
|
||||
|
||||
return new StepResponse(createdReturnItems, prevReturn)
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
import {
|
||||
ContainerRegistrationKeys,
|
||||
MedusaError,
|
||||
arrayDifference,
|
||||
remoteQueryObjectFromString,
|
||||
} from "@medusajs/utils"
|
||||
|
||||
export async function validateReturnReasons(
|
||||
{
|
||||
orderId,
|
||||
inputItems,
|
||||
}: {
|
||||
orderId: string
|
||||
inputItems: (unknown & { reason_id?: string | null })[]
|
||||
},
|
||||
{ container }
|
||||
) {
|
||||
const reasonIds = inputItems.map((i) => i.reason_id).filter(Boolean)
|
||||
if (!reasonIds.length) {
|
||||
return
|
||||
}
|
||||
|
||||
const remoteQuery = container.resolve(ContainerRegistrationKeys.REMOTE_QUERY)
|
||||
|
||||
const remoteQueryObject = remoteQueryObjectFromString({
|
||||
entryPoint: "return_reasons",
|
||||
fields: [
|
||||
"id",
|
||||
"parent_return_reason_id",
|
||||
"parent_return_reason",
|
||||
"return_reason_children.id",
|
||||
],
|
||||
variables: { id: [inputItems.map((item) => item.reason_id)], limit: null },
|
||||
})
|
||||
|
||||
const returnReasons = await remoteQuery(remoteQueryObject)
|
||||
|
||||
const reasons = returnReasons.map((r) => r.id)
|
||||
const hasInvalidReasons = returnReasons
|
||||
.filter(
|
||||
// We do not allow for root reason to be applied
|
||||
(reason) => reason.return_reason_children.length > 0
|
||||
)
|
||||
.map((r) => r.id)
|
||||
const hasNonExistingReasons = arrayDifference(reasonIds, reasons)
|
||||
|
||||
if (hasNonExistingReasons.length) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
`Return reason with id ${hasNonExistingReasons.join(
|
||||
", "
|
||||
)} does not exists.`
|
||||
)
|
||||
}
|
||||
|
||||
if (hasInvalidReasons.length) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
`Cannot apply return reason with id ${hasInvalidReasons.join(
|
||||
", "
|
||||
)} to order with id ${orderId}. Return reason has nested reasons.`
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -7,15 +7,7 @@ import {
|
||||
ShippingOptionDTO,
|
||||
WithCalculatedPrice,
|
||||
} from "@medusajs/types"
|
||||
import {
|
||||
ContainerRegistrationKeys,
|
||||
MathBN,
|
||||
MedusaError,
|
||||
Modules,
|
||||
arrayDifference,
|
||||
isDefined,
|
||||
remoteQueryObjectFromString,
|
||||
} from "@medusajs/utils"
|
||||
import { MathBN, MedusaError, Modules, isDefined } from "@medusajs/utils"
|
||||
import {
|
||||
WorkflowData,
|
||||
createStep,
|
||||
@@ -31,64 +23,7 @@ import {
|
||||
throwIfItemsDoesNotExistsInOrder,
|
||||
throwIfOrderIsCancelled,
|
||||
} from "../utils/order-validation"
|
||||
|
||||
async function validateReturnReasons(
|
||||
{
|
||||
orderId,
|
||||
inputItems,
|
||||
}: {
|
||||
orderId: string
|
||||
inputItems: OrderWorkflow.CreateOrderReturnWorkflowInput["items"]
|
||||
},
|
||||
{ container }
|
||||
) {
|
||||
const reasonIds = inputItems.map((i) => i.reason_id).filter(Boolean)
|
||||
if (!reasonIds.length) {
|
||||
return
|
||||
}
|
||||
|
||||
const remoteQuery = container.resolve(ContainerRegistrationKeys.REMOTE_QUERY)
|
||||
|
||||
const remoteQueryObject = remoteQueryObjectFromString({
|
||||
entryPoint: "return_reasons",
|
||||
fields: [
|
||||
"id",
|
||||
"parent_return_reason_id",
|
||||
"parent_return_reason",
|
||||
"return_reason_children.id",
|
||||
],
|
||||
variables: { id: [inputItems.map((item) => item.reason_id)], limit: null },
|
||||
})
|
||||
|
||||
const returnReasons = await remoteQuery(remoteQueryObject)
|
||||
|
||||
const reasons = returnReasons.map((r) => r.id)
|
||||
const hasInvalidReasons = returnReasons
|
||||
.filter(
|
||||
// We do not allow for root reason to be applied
|
||||
(reason) => reason.return_reason_children.length > 0
|
||||
)
|
||||
.map((r) => r.id)
|
||||
const hasNonExistingReasons = arrayDifference(reasonIds, reasons)
|
||||
|
||||
if (hasNonExistingReasons.length) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
`Return reason with id ${hasNonExistingReasons.join(
|
||||
", "
|
||||
)} does not exists.`
|
||||
)
|
||||
}
|
||||
|
||||
if (hasInvalidReasons.length) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
`Cannot apply return reason with id ${hasInvalidReasons.join(
|
||||
", "
|
||||
)} to order with id ${orderId}. Return reason has nested reasons.`
|
||||
)
|
||||
}
|
||||
}
|
||||
import { validateReturnReasons } from "../utils/validate-return-reason"
|
||||
|
||||
function prepareShippingMethodData({
|
||||
orderId,
|
||||
|
||||
@@ -19,24 +19,33 @@ import {
|
||||
throwIfItemsDoesNotExistsInOrder,
|
||||
throwIfOrderChangeIsNotActive,
|
||||
} from "../../utils/order-validation"
|
||||
import { validateReturnReasons } from "../../utils/validate-return-reason"
|
||||
|
||||
const validationStep = createStep(
|
||||
"request-item-return-validation",
|
||||
async function ({
|
||||
order,
|
||||
orderChange,
|
||||
orderReturn,
|
||||
items,
|
||||
}: {
|
||||
order: Pick<OrderDTO, "id" | "items">
|
||||
orderReturn: ReturnDTO
|
||||
orderChange: OrderChangeDTO
|
||||
items: OrderWorkflow.RequestItemReturnWorkflowInput["items"]
|
||||
}) {
|
||||
async function (
|
||||
{
|
||||
order,
|
||||
orderChange,
|
||||
orderReturn,
|
||||
items,
|
||||
}: {
|
||||
order: Pick<OrderDTO, "id" | "items">
|
||||
orderReturn: ReturnDTO
|
||||
orderChange: OrderChangeDTO
|
||||
items: OrderWorkflow.RequestItemReturnWorkflowInput["items"]
|
||||
},
|
||||
context
|
||||
) {
|
||||
throwIfIsCancelled(order, "Order")
|
||||
throwIfIsCancelled(orderReturn, "Return")
|
||||
throwIfOrderChangeIsNotActive({ orderChange })
|
||||
throwIfItemsDoesNotExistsInOrder({ order, inputItems: items })
|
||||
|
||||
await validateReturnReasons(
|
||||
{ orderId: order.id, inputItems: items },
|
||||
context
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
@@ -87,6 +96,7 @@ export const requestItemReturnWorkflow = createWorkflow(
|
||||
reference_id: orderReturn.id,
|
||||
details: {
|
||||
reference_id: item.id,
|
||||
reason_id: item.reason_id,
|
||||
quantity: item.quantity,
|
||||
metadata: item.metadata,
|
||||
},
|
||||
|
||||
@@ -21,20 +21,24 @@ import {
|
||||
throwIfIsCancelled,
|
||||
throwIfOrderChangeIsNotActive,
|
||||
} from "../../utils/order-validation"
|
||||
import { validateReturnReasons } from "../../utils/validate-return-reason"
|
||||
|
||||
const validationStep = createStep(
|
||||
"update-request-item-return-validation",
|
||||
async function ({
|
||||
order,
|
||||
orderChange,
|
||||
orderReturn,
|
||||
input,
|
||||
}: {
|
||||
order: OrderDTO
|
||||
orderReturn: ReturnDTO
|
||||
orderChange: OrderChangeDTO
|
||||
input: OrderWorkflow.UpdateRequestItemReturnWorkflowInput
|
||||
}) {
|
||||
async function (
|
||||
{
|
||||
order,
|
||||
orderChange,
|
||||
orderReturn,
|
||||
input,
|
||||
}: {
|
||||
order: OrderDTO
|
||||
orderReturn: ReturnDTO
|
||||
orderChange: OrderChangeDTO
|
||||
input: OrderWorkflow.UpdateRequestItemReturnWorkflowInput
|
||||
},
|
||||
context
|
||||
) {
|
||||
throwIfIsCancelled(order, "Order")
|
||||
throwIfIsCancelled(orderReturn, "Return")
|
||||
throwIfOrderChangeIsNotActive({ orderChange })
|
||||
@@ -52,6 +56,16 @@ const validationStep = createStep(
|
||||
`Action ${associatedAction.id} is not requesting item return`
|
||||
)
|
||||
}
|
||||
|
||||
if (input.data.reason_id) {
|
||||
await validateReturnReasons(
|
||||
{
|
||||
orderId: order.id,
|
||||
inputItems: [{ reason_id: input.data.reason_id }],
|
||||
},
|
||||
context
|
||||
)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
@@ -104,6 +118,8 @@ export const updateRequestItemReturnWorkflow = createWorkflow(
|
||||
id: input.action_id,
|
||||
details: {
|
||||
quantity: data.quantity ?? originalAction.details?.quantity,
|
||||
reason_id: data.reason_id ?? originalAction.details?.reason_id,
|
||||
metadata: data.metadata ?? originalAction.details?.metadata,
|
||||
},
|
||||
internal_note: data.internal_note,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user