chore(core-flows): cancel claims (#8342)

What:
* `DELETE /admin/claims/:id/request`
* `POST /admin/claims/:id/cancel`
This commit is contained in:
Carlos R. L. Rodrigues
2024-07-30 05:59:02 -03:00
committed by GitHub
parent bcd9d9c2b1
commit 48663479a9
19 changed files with 165 additions and 70 deletions

View File

@@ -508,20 +508,21 @@ medusaIntegrationTestRunner({
adminHeaders
)
).data.claims
expect(result).toHaveLength(2)
console.log(
JSON.stringify(
(
await api.get(
`/admin/orders?fields=*items,total,summary`,
adminHeaders
)
).data.orders[0],
null,
2
expect(result).toHaveLength(2)
expect(result[0].additional_items).toHaveLength(1)
expect(result[0].claim_items).toHaveLength(1)
expect(result[0].canceled_at).toBeNull()
await api.post(`/admin/claims/${claimId}/cancel`, {}, adminHeaders)
result = (
await api.get(
`/admin/claims?fields=*claim_items,*additional_items`,
adminHeaders
)
)
).data.claims
expect(result[0].canceled_at).toBeDefined()
})
})
},

View File

@@ -0,0 +1,78 @@
import { FulfillmentDTO, OrderClaimDTO, OrderWorkflow } from "@medusajs/types"
import { MedusaError } from "@medusajs/utils"
import {
WorkflowData,
createStep,
createWorkflow,
when,
} from "@medusajs/workflows-sdk"
import { useRemoteQueryStep } from "../../../common"
import { cancelOrderClaimStep } from "../../steps"
import { throwIfIsCancelled } from "../../utils/order-validation"
import { cancelReturnWorkflow } from "../return/cancel-return"
const validateOrder = createStep(
"validate-claim",
({
orderClaim,
}: {
orderClaim: OrderClaimDTO
input: OrderWorkflow.CancelOrderClaimWorkflowInput
}) => {
const orderClaim_ = orderClaim as OrderClaimDTO & {
fulfillments: FulfillmentDTO[]
}
throwIfIsCancelled(orderClaim, "Claim")
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(
orderClaim_.fulfillments,
notCanceled,
"All fulfillments must be canceled before canceling a claim"
)
}
)
export const cancelOrderClaimWorkflowId = "cancel-claim"
export const cancelOrderClaimWorkflow = createWorkflow(
cancelOrderClaimWorkflowId,
(
input: WorkflowData<OrderWorkflow.CancelOrderClaimWorkflowInput>
): WorkflowData<void> => {
const orderClaim: OrderClaimDTO & { fulfillments: FulfillmentDTO[] } =
useRemoteQueryStep({
entry_point: "order_claim",
fields: ["id", "return_id", "canceled_at", "fulfillments.canceled_at"],
variables: { id: input.claim_id },
list: false,
throw_if_key_not_found: true,
})
validateOrder({ orderClaim, input })
cancelOrderClaimStep({ claim_id: orderClaim.id })
when({ orderClaim }, ({ orderClaim }) => {
return !!orderClaim.return_id
}).then(() => {
cancelReturnWorkflow.runAsStep({
input: {
return_id: orderClaim.return_id!,
no_notification: input.no_notification,
},
})
})
}
)

View File

@@ -5,6 +5,7 @@ export * from "./cancel-order-change"
export * from "./cancel-order-fulfillment"
export * from "./claim/begin-order-claim"
export * from "./claim/cancel-begin-order-claim"
export * from "./claim/cancel-claim"
export * from "./claim/claim-add-new-item"
export * from "./claim/claim-item"
export * from "./claim/claim-request-item-return"
@@ -51,4 +52,3 @@ export * from "./return/update-return"
export * from "./return/update-return-shipping-method"
export * from "./update-order-change-actions"
export * from "./update-tax-lines"

View File

@@ -804,7 +804,8 @@ export class TransactionOrchestrator extends EventEmitter {
}
let setResponse = true
if (SkipStepResponse.isSkipStepResponse(response)) {
const output = response?.__type ? response.output : response
if (SkipStepResponse.isSkipStepResponse(output)) {
await TransactionOrchestrator.skipStep(transaction, step)
setResponse = false
}

View File

@@ -0,0 +1,23 @@
import { cancelOrderClaimWorkflow } from "@medusajs/core-flows"
import {
AuthenticatedMedusaRequest,
MedusaResponse,
} from "../../../../../types/routing"
import { AdminPostCancelClaimReqSchemaType } from "../../validators"
export const POST = async (
req: AuthenticatedMedusaRequest<AdminPostCancelClaimReqSchemaType>,
res: MedusaResponse
) => {
const { id } = req.params
const workflow = cancelOrderClaimWorkflow(req.scope)
const { result } = await workflow.run({
input: {
...req.validatedBody,
claim_id: id,
},
})
res.status(200).json({ claim: result })
}

View File

@@ -1,4 +1,7 @@
import { confirmClaimRequestWorkflow } from "@medusajs/core-flows"
import {
cancelBeginOrderClaimWorkflow,
confirmClaimRequestWorkflow,
} from "@medusajs/core-flows"
import {
ContainerRegistrationKeys,
remoteQueryObjectFromString,
@@ -56,3 +59,22 @@ export const POST = async (
return: orderReturn,
})
}
export const DELETE = async (
req: AuthenticatedMedusaRequest,
res: MedusaResponse
) => {
const { id } = req.params
await cancelBeginOrderClaimWorkflow(req.scope).run({
input: {
claim_id: id,
},
})
res.status(200).json({
id,
object: "claim",
deleted: true,
})
}

View File

@@ -5,6 +5,7 @@ import * as QueryConfig from "./query-config"
import {
AdminGetOrdersOrderParams,
AdminGetOrdersParams,
AdminPostCancelClaimReqSchema,
AdminPostClaimItemsReqSchema,
AdminPostClaimsAddItemsReqSchema,
AdminPostClaimsRequestItemsActionReqSchema,
@@ -209,7 +210,6 @@ export const adminClaimRoutesMiddlewares: MiddlewareRoute[] = [
),
],
},
{
method: ["POST"],
matcher: "/admin/claims/:id/request",
@@ -220,6 +220,11 @@ export const adminClaimRoutesMiddlewares: MiddlewareRoute[] = [
),
],
},
{
method: ["DELETE"],
matcher: "/admin/claims/:id/request",
middlewares: [],
},
{
method: ["DELETE"],
matcher: "/admin/claims/:id",
@@ -229,6 +234,7 @@ export const adminClaimRoutesMiddlewares: MiddlewareRoute[] = [
method: ["POST"],
matcher: "/admin/claims/:id/cancel",
middlewares: [
validateAndTransformBody(AdminPostCancelClaimReqSchema),
validateAndTransformQuery(
AdminGetOrdersOrderParams,
QueryConfig.retrieveTransformQueryConfig

View File

@@ -9,6 +9,7 @@ export const defaultAdminClaimFields = [
"refund_amount",
"created_at",
"updated_at",
"canceled_at",
]
export const defaultAdminDetailsClaimFields = [

View File

@@ -82,9 +82,7 @@ export type AdminPostReceiveClaimItemsReqSchemaType = z.infer<
>
export const AdminPostCancelClaimReqSchema = z.object({
return_id: z.string(),
no_notification: z.boolean().optional(),
internal_note: z.string().nullish(),
})
export type AdminPostCancelClaimReqSchemaType = z.infer<
typeof AdminPostCancelClaimReqSchema

View File

@@ -12,6 +12,7 @@ export const defaultAdminReturnFields = [
"refund_amount",
"created_at",
"updated_at",
"canceled_at",
]
export const defaultAdminDetailsReturnFields = [

View File

@@ -92,7 +92,6 @@ export type AdminPostReceiveReturnItemsReqSchemaType = z.infer<
export const AdminPostCancelReturnReqSchema = z.object({
no_notification: z.boolean().optional(),
internal_note: z.string().nullish(),
})
export type AdminPostCancelReturnReqSchemaType = z.infer<

View File

@@ -8,16 +8,16 @@ import { ChangeActionType, promiseAll } from "@medusajs/utils"
async function createOrderChange(
service,
data,
returnRef,
claimOrder,
actions,
sharedContext
) {
return await service.createOrderChange_(
{
order_id: returnRef.order_id,
claim_id: returnRef.id,
reference: "return",
reference_id: returnRef.id,
order_id: claimOrder.order_id,
claim_id: claimOrder.id,
reference: "claim",
reference_id: claimOrder.id,
description: data.description,
internal_note: data.internal_note,
created_by: data.created_by,
@@ -33,60 +33,40 @@ export async function cancelClaim(
data: OrderTypes.CancelOrderClaimDTO,
sharedContext?: Context
) {
const claimOrder = await this.retrieveClaim(
const claimOrder = await this.retrieveOrderClaim(
data.claim_id,
{
select: [
"id",
"order_id",
"return.id",
"return.items.id",
"return.items.quantity",
"claim_items.item_id",
"claim_items.is_additional_item",
"claim_items.quantity",
"additional_items.id",
"additional_items.quantity",
"additional_items.is_additional_item",
],
relations: ["return.items", "additional_items", "shipping_methods"],
relations: ["claim_items", "additional_items", "shipping_methods"],
},
sharedContext
)
const actions: CreateOrderChangeActionDTO[] = []
claimOrder.return.items.forEach((item) => {
actions.push({
action: ChangeActionType.CANCEL_RETURN_ITEM,
order_id: claimOrder.order_id,
claim_id: claimOrder.id,
return_id: claimOrder.return.id,
reference: "return",
reference_id: claimOrder.return.id,
details: {
reference_id: item.id,
order_id: claimOrder.order_id,
claim_id: claimOrder.id,
return_id: claimOrder.return.id,
quantity: item.quantity,
},
})
})
claimOrder.claim_items.forEach((item) => {
claimOrder.claim_items?.forEach((item) => {
actions.push({
action: ChangeActionType.REINSTATE_ITEM,
claim_id: claimOrder.id,
reference: "claim",
reference_id: claimOrder.id,
details: {
reference_id: item.id,
claim_id: claimOrder.id,
reference_id: item.item_id,
quantity: item.quantity,
},
})
})
claimOrder.additional_items.forEach((item) => {
claimOrder.additional_items?.forEach((item) => {
actions.push({
action: ChangeActionType.ITEM_REMOVE,
order_id: claimOrder.order_id,
@@ -94,9 +74,7 @@ export async function cancelClaim(
reference: "claim",
reference_id: claimOrder.id,
details: {
reference_id: item.id,
order_id: claimOrder.order_id,
claim_id: claimOrder.id,
reference_id: item.item_id,
quantity: item.quantity,
},
})
@@ -107,7 +85,6 @@ export async function cancelClaim(
action: ChangeActionType.SHIPPING_REMOVE,
order_id: claimOrder.order_id,
claim_id: claimOrder.id,
return_id: claimOrder.return.id,
reference: "claim",
reference_id: shipping.id,
amount: shipping.price,
@@ -123,7 +100,7 @@ export async function cancelClaim(
)
await promiseAll([
this.updateClaims(
this.updateOrderClaims(
[
{
data: {

View File

@@ -62,9 +62,6 @@ export async function cancelExchange(
reference_id: exchangeOrder.return.id,
details: {
reference_id: item.item_id,
order_id: exchangeOrder.order_id,
exchange_id: exchangeOrder.id,
return_id: exchangeOrder.return.id,
quantity: item.quantity,
},
})

View File

@@ -59,8 +59,6 @@ export async function cancelReturn(
reference_id: returnOrder.id,
details: {
reference_id: item.item_id,
order_id: returnOrder.order_id,
return_id: returnOrder.id,
quantity: item.quantity,
},
})

View File

@@ -46,8 +46,6 @@ function createReturnItem(em, item, claimReference, returnReference, actions) {
reference_id: returnReference.id,
details: {
reference_id: item.id,
return_id: returnReference.id,
claim_id: claimReference.id,
quantity: item.quantity,
metadata: item.metadata,
},
@@ -77,7 +75,6 @@ function createClaimAndReturnItems(
reference_id: claimReference.id,
details: {
reference_id: item.id,
claim_id: claimReference.id,
quantity: item.quantity,
metadata: item.metadata,
},
@@ -127,7 +124,6 @@ async function processAdditionalItems(
reference_id: claimReference.id,
details: {
reference_id: item.id,
claim_id: claimReference.id,
quantity: item.quantity,
metadata: item.metadata,
},

View File

@@ -49,8 +49,6 @@ function createReturnItems(
reference_id: returnReference.id,
details: {
reference_id: item.id,
return_id: returnReference.id,
exchange_id: exchangeReference.id,
quantity: item.quantity,
metadata: item.metadata,
},
@@ -93,7 +91,6 @@ async function processAdditionalItems(
reference_id: exchangeReference.id,
details: {
reference_id: item.id,
exchange_id: exchangeReference.id,
quantity: item.quantity,
metadata: item.metadata,
},

View File

@@ -34,7 +34,6 @@ function createReturnItems(em, data, returnRef, actions) {
reference_id: returnRef.id,
details: {
reference_id: item.id,
return_id: returnRef.id,
quantity: item.quantity,
metadata: item.metadata,
},

View File

@@ -3206,7 +3206,7 @@ export default class OrderModuleService<
const ret = await this.cancelClaim_(data, sharedContext)
return await this.retrieveOrderClaim(ret.id, {
relations: ["items"],
relations: ["additional_items", "claim_items"],
})
}

View File

@@ -5,6 +5,7 @@ export * from "./item-add"
export * from "./item-remove"
export * from "./receive-damaged-return-item"
export * from "./receive-return-item"
export * from "./reinstate-item"
export * from "./return-item"
export * from "./ship-item"
export * from "./shipping-add"