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 authored and GitHub committed 2024-07-30 08:59:02 +00:00
1 parent bcd9d9c2b1
commit 48663479a9
19 files changed
+165 -70

No files matched your search

@@ -508,20 +508,21 @@ medusaIntegrationTestRunner({
adminHeaders adminHeaders
) )
).data.claims ).data.claims
expect(result).toHaveLength(2)
console.log( expect(result).toHaveLength(2)
JSON.stringify( expect(result[0].additional_items).toHaveLength(1)
( expect(result[0].claim_items).toHaveLength(1)
await api.get( expect(result[0].canceled_at).toBeNull()
`/admin/orders?fields=*items,total,summary`,
adminHeaders await api.post(`/admin/claims/${claimId}/cancel`, {}, adminHeaders)
)
).data.orders[0], result = (
null, await api.get(
2 `/admin/claims?fields=*claim_items,*additional_items`,
adminHeaders
) )
) ).data.claims
expect(result[0].canceled_at).toBeDefined()
}) })
}) })
}, },
@@ -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,
},
})
})
}
)
@@ -5,6 +5,7 @@ export * from "./cancel-order-change"
export * from "./cancel-order-fulfillment" export * from "./cancel-order-fulfillment"
export * from "./claim/begin-order-claim" export * from "./claim/begin-order-claim"
export * from "./claim/cancel-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-add-new-item"
export * from "./claim/claim-item" export * from "./claim/claim-item"
export * from "./claim/claim-request-item-return" 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 "./return/update-return-shipping-method"
export * from "./update-order-change-actions" export * from "./update-order-change-actions"
export * from "./update-tax-lines" export * from "./update-tax-lines"
@@ -804,7 +804,8 @@ export class TransactionOrchestrator extends EventEmitter {
} }
let setResponse = true let setResponse = true
if (SkipStepResponse.isSkipStepResponse(response)) { const output = response?.__type ? response.output : response
if (SkipStepResponse.isSkipStepResponse(output)) {
await TransactionOrchestrator.skipStep(transaction, step) await TransactionOrchestrator.skipStep(transaction, step)
setResponse = false setResponse = false
} }
@@ -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 })
}
@@ -1,4 +1,7 @@
import { confirmClaimRequestWorkflow } from "@medusajs/core-flows" import {
cancelBeginOrderClaimWorkflow,
confirmClaimRequestWorkflow,
} from "@medusajs/core-flows"
import { import {
ContainerRegistrationKeys, ContainerRegistrationKeys,
remoteQueryObjectFromString, remoteQueryObjectFromString,
@@ -56,3 +59,22 @@ export const POST = async (
return: orderReturn, 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,
})
}
@@ -5,6 +5,7 @@ import * as QueryConfig from "./query-config"
import { import {
AdminGetOrdersOrderParams, AdminGetOrdersOrderParams,
AdminGetOrdersParams, AdminGetOrdersParams,
AdminPostCancelClaimReqSchema,
AdminPostClaimItemsReqSchema, AdminPostClaimItemsReqSchema,
AdminPostClaimsAddItemsReqSchema, AdminPostClaimsAddItemsReqSchema,
AdminPostClaimsRequestItemsActionReqSchema, AdminPostClaimsRequestItemsActionReqSchema,
@@ -209,7 +210,6 @@ export const adminClaimRoutesMiddlewares: MiddlewareRoute[] = [
), ),
], ],
}, },
{ {
method: ["POST"], method: ["POST"],
matcher: "/admin/claims/:id/request", matcher: "/admin/claims/:id/request",
@@ -220,6 +220,11 @@ export const adminClaimRoutesMiddlewares: MiddlewareRoute[] = [
), ),
], ],
}, },
{
method: ["DELETE"],
matcher: "/admin/claims/:id/request",
middlewares: [],
},
{ {
method: ["DELETE"], method: ["DELETE"],
matcher: "/admin/claims/:id", matcher: "/admin/claims/:id",
@@ -229,6 +234,7 @@ export const adminClaimRoutesMiddlewares: MiddlewareRoute[] = [
method: ["POST"], method: ["POST"],
matcher: "/admin/claims/:id/cancel", matcher: "/admin/claims/:id/cancel",
middlewares: [ middlewares: [
validateAndTransformBody(AdminPostCancelClaimReqSchema),
validateAndTransformQuery( validateAndTransformQuery(
AdminGetOrdersOrderParams, AdminGetOrdersOrderParams,
QueryConfig.retrieveTransformQueryConfig QueryConfig.retrieveTransformQueryConfig
@@ -9,6 +9,7 @@ export const defaultAdminClaimFields = [
"refund_amount", "refund_amount",
"created_at", "created_at",
"updated_at", "updated_at",
"canceled_at",
] ]
export const defaultAdminDetailsClaimFields = [ export const defaultAdminDetailsClaimFields = [
@@ -82,9 +82,7 @@ export type AdminPostReceiveClaimItemsReqSchemaType = z.infer<
> >
export const AdminPostCancelClaimReqSchema = z.object({ export const AdminPostCancelClaimReqSchema = z.object({
return_id: z.string(),
no_notification: z.boolean().optional(), no_notification: z.boolean().optional(),
internal_note: z.string().nullish(),
}) })
export type AdminPostCancelClaimReqSchemaType = z.infer< export type AdminPostCancelClaimReqSchemaType = z.infer<
typeof AdminPostCancelClaimReqSchema typeof AdminPostCancelClaimReqSchema
@@ -12,6 +12,7 @@ export const defaultAdminReturnFields = [
"refund_amount", "refund_amount",
"created_at", "created_at",
"updated_at", "updated_at",
"canceled_at",
] ]
export const defaultAdminDetailsReturnFields = [ export const defaultAdminDetailsReturnFields = [
@@ -92,7 +92,6 @@ export type AdminPostReceiveReturnItemsReqSchemaType = z.infer<
export const AdminPostCancelReturnReqSchema = z.object({ export const AdminPostCancelReturnReqSchema = z.object({
no_notification: z.boolean().optional(), no_notification: z.boolean().optional(),
internal_note: z.string().nullish(),
}) })
export type AdminPostCancelReturnReqSchemaType = z.infer< export type AdminPostCancelReturnReqSchemaType = z.infer<
@@ -8,16 +8,16 @@ import { ChangeActionType, promiseAll } from "@medusajs/utils"
async function createOrderChange( async function createOrderChange(
service, service,
data, data,
returnRef, claimOrder,
actions, actions,
sharedContext sharedContext
) { ) {
return await service.createOrderChange_( return await service.createOrderChange_(
{ {
order_id: returnRef.order_id, order_id: claimOrder.order_id,
claim_id: returnRef.id, claim_id: claimOrder.id,
reference: "return", reference: "claim",
reference_id: returnRef.id, reference_id: claimOrder.id,
description: data.description, description: data.description,
internal_note: data.internal_note, internal_note: data.internal_note,
created_by: data.created_by, created_by: data.created_by,
@@ -33,60 +33,40 @@ export async function cancelClaim(
data: OrderTypes.CancelOrderClaimDTO, data: OrderTypes.CancelOrderClaimDTO,
sharedContext?: Context sharedContext?: Context
) { ) {
const claimOrder = await this.retrieveClaim( const claimOrder = await this.retrieveOrderClaim(
data.claim_id, data.claim_id,
{ {
select: [ select: [
"id", "id",
"order_id", "order_id",
"return.id",
"return.items.id",
"return.items.quantity",
"claim_items.item_id", "claim_items.item_id",
"claim_items.is_additional_item",
"claim_items.quantity", "claim_items.quantity",
"additional_items.id", "additional_items.id",
"additional_items.quantity", "additional_items.quantity",
"additional_items.is_additional_item",
], ],
relations: ["return.items", "additional_items", "shipping_methods"], relations: ["claim_items", "additional_items", "shipping_methods"],
}, },
sharedContext sharedContext
) )
const actions: CreateOrderChangeActionDTO[] = [] const actions: CreateOrderChangeActionDTO[] = []
claimOrder.return.items.forEach((item) => { claimOrder.claim_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) => {
actions.push({ actions.push({
action: ChangeActionType.REINSTATE_ITEM, action: ChangeActionType.REINSTATE_ITEM,
claim_id: claimOrder.id, claim_id: claimOrder.id,
reference: "claim", reference: "claim",
reference_id: claimOrder.id, reference_id: claimOrder.id,
details: { details: {
reference_id: item.id, reference_id: item.item_id,
claim_id: claimOrder.id,
quantity: item.quantity, quantity: item.quantity,
}, },
}) })
}) })
claimOrder.additional_items.forEach((item) => { claimOrder.additional_items?.forEach((item) => {
actions.push({ actions.push({
action: ChangeActionType.ITEM_REMOVE, action: ChangeActionType.ITEM_REMOVE,
order_id: claimOrder.order_id, order_id: claimOrder.order_id,
@@ -94,9 +74,7 @@ export async function cancelClaim(
reference: "claim", reference: "claim",
reference_id: claimOrder.id, reference_id: claimOrder.id,
details: { details: {
reference_id: item.id, reference_id: item.item_id,
order_id: claimOrder.order_id,
claim_id: claimOrder.id,
quantity: item.quantity, quantity: item.quantity,
}, },
}) })
@@ -107,7 +85,6 @@ export async function cancelClaim(
action: ChangeActionType.SHIPPING_REMOVE, action: ChangeActionType.SHIPPING_REMOVE,
order_id: claimOrder.order_id, order_id: claimOrder.order_id,
claim_id: claimOrder.id, claim_id: claimOrder.id,
return_id: claimOrder.return.id,
reference: "claim", reference: "claim",
reference_id: shipping.id, reference_id: shipping.id,
amount: shipping.price, amount: shipping.price,
@@ -123,7 +100,7 @@ export async function cancelClaim(
) )
await promiseAll([ await promiseAll([
this.updateClaims( this.updateOrderClaims(
[ [
{ {
data: { data: {
@@ -62,9 +62,6 @@ export async function cancelExchange(
reference_id: exchangeOrder.return.id, reference_id: exchangeOrder.return.id,
details: { details: {
reference_id: item.item_id, reference_id: item.item_id,
order_id: exchangeOrder.order_id,
exchange_id: exchangeOrder.id,
return_id: exchangeOrder.return.id,
quantity: item.quantity, quantity: item.quantity,
}, },
}) })
@@ -59,8 +59,6 @@ export async function cancelReturn(
reference_id: returnOrder.id, reference_id: returnOrder.id,
details: { details: {
reference_id: item.item_id, reference_id: item.item_id,
order_id: returnOrder.order_id,
return_id: returnOrder.id,
quantity: item.quantity, quantity: item.quantity,
}, },
}) })
@@ -46,8 +46,6 @@ function createReturnItem(em, item, claimReference, returnReference, actions) {
reference_id: returnReference.id, reference_id: returnReference.id,
details: { details: {
reference_id: item.id, reference_id: item.id,
return_id: returnReference.id,
claim_id: claimReference.id,
quantity: item.quantity, quantity: item.quantity,
metadata: item.metadata, metadata: item.metadata,
}, },
@@ -77,7 +75,6 @@ function createClaimAndReturnItems(
reference_id: claimReference.id, reference_id: claimReference.id,
details: { details: {
reference_id: item.id, reference_id: item.id,
claim_id: claimReference.id,
quantity: item.quantity, quantity: item.quantity,
metadata: item.metadata, metadata: item.metadata,
}, },
@@ -127,7 +124,6 @@ async function processAdditionalItems(
reference_id: claimReference.id, reference_id: claimReference.id,
details: { details: {
reference_id: item.id, reference_id: item.id,
claim_id: claimReference.id,
quantity: item.quantity, quantity: item.quantity,
metadata: item.metadata, metadata: item.metadata,
}, },
@@ -49,8 +49,6 @@ function createReturnItems(
reference_id: returnReference.id, reference_id: returnReference.id,
details: { details: {
reference_id: item.id, reference_id: item.id,
return_id: returnReference.id,
exchange_id: exchangeReference.id,
quantity: item.quantity, quantity: item.quantity,
metadata: item.metadata, metadata: item.metadata,
}, },
@@ -93,7 +91,6 @@ async function processAdditionalItems(
reference_id: exchangeReference.id, reference_id: exchangeReference.id,
details: { details: {
reference_id: item.id, reference_id: item.id,
exchange_id: exchangeReference.id,
quantity: item.quantity, quantity: item.quantity,
metadata: item.metadata, metadata: item.metadata,
}, },
@@ -34,7 +34,6 @@ function createReturnItems(em, data, returnRef, actions) {
reference_id: returnRef.id, reference_id: returnRef.id,
details: { details: {
reference_id: item.id, reference_id: item.id,
return_id: returnRef.id,
quantity: item.quantity, quantity: item.quantity,
metadata: item.metadata, metadata: item.metadata,
}, },
@@ -3206,7 +3206,7 @@ export default class OrderModuleService<
const ret = await this.cancelClaim_(data, sharedContext) const ret = await this.cancelClaim_(data, sharedContext)
return await this.retrieveOrderClaim(ret.id, { return await this.retrieveOrderClaim(ret.id, {
relations: ["items"], relations: ["additional_items", "claim_items"],
}) })
} }
@@ -5,6 +5,7 @@ export * from "./item-add"
export * from "./item-remove" export * from "./item-remove"
export * from "./receive-damaged-return-item" export * from "./receive-damaged-return-item"
export * from "./receive-return-item" export * from "./receive-return-item"
export * from "./reinstate-item"
export * from "./return-item" export * from "./return-item"
export * from "./ship-item" export * from "./ship-item"
export * from "./shipping-add" export * from "./shipping-add"