fix(core-flow): request item return reason (#8152)

This commit is contained in:
Carlos R. L. Rodrigues
2024-07-17 05:35:33 -03:00
committed by GitHub
parent 1d40b3cc98
commit d4fe2daa57
15 changed files with 189 additions and 255 deletions

View File

@@ -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)

View File

@@ -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.`
)
}
}

View File

@@ -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,

View File

@@ -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,
},

View File

@@ -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,
}