From ccfbc0accf8857464bc91c8180780467b37f6644 Mon Sep 17 00:00:00 2001 From: "Carlos R. L. Rodrigues" <37986729+carlos-r-l-rodrigues@users.noreply.github.com> Date: Thu, 25 Jul 2024 06:33:35 -0300 Subject: [PATCH] chore(core-flows,medusa): order claims (#8271) --- .../src/order/steps/delete-claims.ts | 28 +++ .../{delete-return.ts => delete-returns.ts} | 6 +- .../core/core-flows/src/order/steps/index.ts | 4 +- .../src/order/steps/update-returns.ts | 35 +++ .../workflows/claim/begin-order-claim.ts | 4 +- .../claim/cancel-begin-order-claim.ts | 94 +++++++ .../workflows/claim/claim-add-new-item.ts | 3 +- .../src/order/workflows/claim/claim-item.ts | 104 ++++++++ .../claim/claim-request-item-return.ts | 5 +- .../claim/create-claim-shipping-method.ts | 169 +++++++++++++ .../claim/remove-claim-item-action.ts | 96 ++++++++ .../claim/remove-claim-shipping-method.ts | 105 ++++++++ .../workflows/claim/update-claim-add-item.ts | 118 +++++++++ .../workflows/claim/update-claim-item.ts | 118 +++++++++ .../claim/update-claim-shipping-method.ts | 120 +++++++++ .../core-flows/src/order/workflows/index.ts | 9 + .../return/confirm-receive-return-request.ts | 30 ++- .../return/create-return-shipping-method.ts | 9 + .../return/update-request-item-return.ts | 1 - packages/core/types/src/order/common.ts | 8 +- .../types/src/workflow/order/add-new-item.ts | 34 --- .../core/types/src/workflow/order/index.ts | 4 +- .../core/types/src/workflow/order/items.ts | 86 +++++++ .../src/workflow/order/request-item-return.ts | 5 +- .../src/workflow/order/shipping-method.ts | 46 ++++ .../src/workflow/order/shipping-return.ts | 16 -- .../[id]/claim-items/[action_id]/route.ts | 83 +++++++ .../admin/claims/[id]/claim-items/route.ts | 41 ++++ .../[id]/inbound/items/[action_id]/route.ts | 97 ++++++++ .../admin/claims/[id]/inbound/items/route.ts | 56 +++++ .../shipping-method/[action_id]/route.ts | 111 +++++++++ .../[id]/inbound/shipping-method/route.ts | 56 +++++ .../[id]/outbound/items/[action_id]/route.ts | 83 +++++++ .../admin/claims/[id]/outbound/items/route.ts | 42 ++++ .../shipping-method/[action_id]/route.ts | 83 +++++++ .../[id]/outbound/shipping-method/route.ts | 41 ++++ .../src/api/admin/claims/middlewares.ts | 229 ++++++++++++++++++ .../src/api/admin/claims/query-config.ts | 31 +++ packages/medusa/src/api/admin/claims/route.ts | 74 ++++++ .../medusa/src/api/admin/claims/validators.ts | 199 +++++++++++++++ .../src/api/admin/returns/validators.ts | 12 - .../order/src/utils/transform-order.ts | 5 +- 42 files changed, 2416 insertions(+), 84 deletions(-) create mode 100644 packages/core/core-flows/src/order/steps/delete-claims.ts rename packages/core/core-flows/src/order/steps/{delete-return.ts => delete-returns.ts} (83%) create mode 100644 packages/core/core-flows/src/order/steps/update-returns.ts create mode 100644 packages/core/core-flows/src/order/workflows/claim/cancel-begin-order-claim.ts create mode 100644 packages/core/core-flows/src/order/workflows/claim/claim-item.ts create mode 100644 packages/core/core-flows/src/order/workflows/claim/create-claim-shipping-method.ts create mode 100644 packages/core/core-flows/src/order/workflows/claim/remove-claim-item-action.ts create mode 100644 packages/core/core-flows/src/order/workflows/claim/remove-claim-shipping-method.ts create mode 100644 packages/core/core-flows/src/order/workflows/claim/update-claim-add-item.ts create mode 100644 packages/core/core-flows/src/order/workflows/claim/update-claim-item.ts create mode 100644 packages/core/core-flows/src/order/workflows/claim/update-claim-shipping-method.ts delete mode 100644 packages/core/types/src/workflow/order/add-new-item.ts create mode 100644 packages/core/types/src/workflow/order/items.ts create mode 100644 packages/core/types/src/workflow/order/shipping-method.ts delete mode 100644 packages/core/types/src/workflow/order/shipping-return.ts create mode 100644 packages/medusa/src/api/admin/claims/[id]/claim-items/[action_id]/route.ts create mode 100644 packages/medusa/src/api/admin/claims/[id]/claim-items/route.ts create mode 100644 packages/medusa/src/api/admin/claims/[id]/inbound/items/[action_id]/route.ts create mode 100644 packages/medusa/src/api/admin/claims/[id]/inbound/items/route.ts create mode 100644 packages/medusa/src/api/admin/claims/[id]/inbound/shipping-method/[action_id]/route.ts create mode 100644 packages/medusa/src/api/admin/claims/[id]/inbound/shipping-method/route.ts create mode 100644 packages/medusa/src/api/admin/claims/[id]/outbound/items/[action_id]/route.ts create mode 100644 packages/medusa/src/api/admin/claims/[id]/outbound/items/route.ts create mode 100644 packages/medusa/src/api/admin/claims/[id]/outbound/shipping-method/[action_id]/route.ts create mode 100644 packages/medusa/src/api/admin/claims/[id]/outbound/shipping-method/route.ts create mode 100644 packages/medusa/src/api/admin/claims/middlewares.ts create mode 100644 packages/medusa/src/api/admin/claims/query-config.ts create mode 100644 packages/medusa/src/api/admin/claims/route.ts create mode 100644 packages/medusa/src/api/admin/claims/validators.ts diff --git a/packages/core/core-flows/src/order/steps/delete-claims.ts b/packages/core/core-flows/src/order/steps/delete-claims.ts new file mode 100644 index 0000000000..c6d4cd4154 --- /dev/null +++ b/packages/core/core-flows/src/order/steps/delete-claims.ts @@ -0,0 +1,28 @@ +import { IOrderModuleService } from "@medusajs/types" +import { ModuleRegistrationName } from "@medusajs/utils" +import { createStep, StepResponse } from "@medusajs/workflows-sdk" + +export const deleteClaimsStepId = "delete-claims" +export const deleteClaimsStep = createStep( + deleteClaimsStepId, + async (data: { ids: string[] }, { container }) => { + const service = container.resolve( + ModuleRegistrationName.ORDER + ) + + const deleted = await service.softDeleteOrderClaims(data.ids) + + return new StepResponse(deleted, data.ids) + }, + async (ids, { container }) => { + if (!ids) { + return + } + + const service = container.resolve( + ModuleRegistrationName.ORDER + ) + + await service.restoreOrderClaims(ids) + } +) diff --git a/packages/core/core-flows/src/order/steps/delete-return.ts b/packages/core/core-flows/src/order/steps/delete-returns.ts similarity index 83% rename from packages/core/core-flows/src/order/steps/delete-return.ts rename to packages/core/core-flows/src/order/steps/delete-returns.ts index 26e760dbe8..383b06c0d0 100644 --- a/packages/core/core-flows/src/order/steps/delete-return.ts +++ b/packages/core/core-flows/src/order/steps/delete-returns.ts @@ -10,12 +10,14 @@ export const deleteReturnsStep = createStep( ModuleRegistrationName.ORDER ) - const deleted = await service.softDeleteReturns(data.ids) + const ids = data.ids.filter(Boolean) + + const deleted = ids.length ? await service.softDeleteReturns(ids) : [] return new StepResponse(deleted, data.ids) }, async (ids, { container }) => { - if (!ids) { + if (!ids?.length) { return } diff --git a/packages/core/core-flows/src/order/steps/index.ts b/packages/core/core-flows/src/order/steps/index.ts index 874c454d67..3fbab488c6 100644 --- a/packages/core/core-flows/src/order/steps/index.ts +++ b/packages/core/core-flows/src/order/steps/index.ts @@ -14,11 +14,12 @@ export * from "./create-order-change-actions" export * from "./create-orders" export * from "./create-returns" export * from "./decline-order-change" +export * from "./delete-claims" export * from "./delete-line-items" export * from "./delete-order-change-actions" export * from "./delete-order-changes" export * from "./delete-order-shipping-methods" -export * from "./delete-return" +export * from "./delete-returns" export * from "./get-item-tax-lines" export * from "./preview-order-change" export * from "./register-fulfillment" @@ -27,5 +28,6 @@ export * from "./set-tax-lines-for-items" export * from "./update-order-change-actions" export * from "./update-order-exchanges" export * from "./update-return-items" +export * from "./update-returns" export * from "./update-shipping-methods" export * from "./update-tax-lines" diff --git a/packages/core/core-flows/src/order/steps/update-returns.ts b/packages/core/core-flows/src/order/steps/update-returns.ts new file mode 100644 index 0000000000..05b4527275 --- /dev/null +++ b/packages/core/core-flows/src/order/steps/update-returns.ts @@ -0,0 +1,35 @@ +import { UpdateReturnDTO } from "@medusajs/types" +import { + ModuleRegistrationName, + getSelectsAndRelationsFromObjectArray, +} from "@medusajs/utils" +import { StepResponse, createStep } from "@medusajs/workflows-sdk" + +export const updateReturnsStepId = "update-returns" +export const updateReturnsStep = createStep( + updateReturnsStepId, + async (data: UpdateReturnDTO[], { container }) => { + const service = container.resolve(ModuleRegistrationName.ORDER) as any + + const { selects, relations } = getSelectsAndRelationsFromObjectArray(data, { + objectFields: ["metadata"], + }) + const dataBeforeUpdate = await service.listReturns( + { id: data.map((d) => d.id) }, + { relations, select: selects } + ) + + const updated = await service.updateReturns(data) + + return new StepResponse(updated, dataBeforeUpdate) + }, + async (dataBeforeUpdate, { container }) => { + if (!dataBeforeUpdate?.length) { + return + } + + const service = container.resolve(ModuleRegistrationName.ORDER) as any + + await service.updateReturns(dataBeforeUpdate) + } +) diff --git a/packages/core/core-flows/src/order/workflows/claim/begin-order-claim.ts b/packages/core/core-flows/src/order/workflows/claim/begin-order-claim.ts index 1866d76a1a..e2d3107f0c 100644 --- a/packages/core/core-flows/src/order/workflows/claim/begin-order-claim.ts +++ b/packages/core/core-flows/src/order/workflows/claim/begin-order-claim.ts @@ -8,12 +8,12 @@ import { import { useRemoteQueryStep } from "../../../common" import { createOrderClaimsStep } from "../../steps/create-claims" import { createOrderChangeStep } from "../../steps/create-order-change" -import { throwIfOrderIsCancelled } from "../../utils/order-validation" +import { throwIfIsCancelled } from "../../utils/order-validation" const validationStep = createStep( "begin-claim-order-validation", async function ({ order }: { order: OrderDTO }) { - throwIfOrderIsCancelled({ order }) + throwIfIsCancelled(order, "Order") } ) diff --git a/packages/core/core-flows/src/order/workflows/claim/cancel-begin-order-claim.ts b/packages/core/core-flows/src/order/workflows/claim/cancel-begin-order-claim.ts new file mode 100644 index 0000000000..28090f9f09 --- /dev/null +++ b/packages/core/core-flows/src/order/workflows/claim/cancel-begin-order-claim.ts @@ -0,0 +1,94 @@ +import { OrderChangeDTO, OrderClaimDTO, OrderDTO } from "@medusajs/types" +import { ChangeActionType, OrderChangeStatus } from "@medusajs/utils" +import { + WorkflowData, + createStep, + createWorkflow, + parallelize, + transform, +} from "@medusajs/workflows-sdk" +import { useRemoteQueryStep } from "../../../common" +import { + deleteClaimsStep, + deleteOrderChangesStep, + deleteOrderShippingMethods, + deleteReturnsStep, +} from "../../steps" +import { + throwIfIsCancelled, + throwIfOrderChangeIsNotActive, +} from "../../utils/order-validation" + +type WorkflowInput = { + claim_id: string +} + +const validationStep = createStep( + "validate-cancel-begin-order-claim", + async function ({ + order, + orderChange, + orderClaim, + }: { + order: OrderDTO + orderClaim: OrderClaimDTO + orderChange: OrderChangeDTO + }) { + throwIfIsCancelled(order, "Order") + throwIfIsCancelled(orderClaim, "Claim") + throwIfOrderChangeIsNotActive({ orderChange }) + } +) + +export const cancelBeginOrderClaimWorkflowId = "cancel-begin-order-claim" +export const cancelBeginOrderClaimWorkflow = createWorkflow( + cancelBeginOrderClaimWorkflowId, + function (input: WorkflowInput): WorkflowData { + const orderClaim: OrderClaimDTO = useRemoteQueryStep({ + entry_point: "claim", + fields: ["id", "status", "order_id", "return_id", "canceled_at"], + variables: { id: input.claim_id }, + list: false, + throw_if_key_not_found: true, + }) + + const order: OrderDTO = useRemoteQueryStep({ + entry_point: "orders", + fields: ["id", "version", "canceled_at"], + 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", "version", "actions.*"], + variables: { + filters: { + order_id: orderClaim.order_id, + claim_id: orderClaim.id, + status: [OrderChangeStatus.PENDING, OrderChangeStatus.REQUESTED], + }, + }, + list: false, + }).config({ name: "order-change-query" }) + + validationStep({ order, orderClaim, orderChange }) + + const shippingToRemove = transform( + { orderChange, input }, + ({ orderChange, input }) => { + return (orderChange.actions ?? []) + .filter((a) => a.action === ChangeActionType.SHIPPING_ADD) + .map(({ id }) => id) + } + ) + + parallelize( + deleteReturnsStep({ ids: [orderClaim.return_id!] }), + deleteClaimsStep({ ids: [orderClaim.id] }), + deleteOrderChangesStep({ ids: [orderChange.id] }), + deleteOrderShippingMethods({ ids: shippingToRemove }) + ) + } +) diff --git a/packages/core/core-flows/src/order/workflows/claim/claim-add-new-item.ts b/packages/core/core-flows/src/order/workflows/claim/claim-add-new-item.ts index a2cad27db2..99421ebc9b 100644 --- a/packages/core/core-flows/src/order/workflows/claim/claim-add-new-item.ts +++ b/packages/core/core-flows/src/order/workflows/claim/claim-add-new-item.ts @@ -17,7 +17,6 @@ import { previewOrderChangeStep } from "../../steps/preview-order-change" import { throwIfIsCancelled, throwIfOrderChangeIsNotActive, - throwIfOrderIsCancelled, } from "../../utils/order-validation" import { addOrderLineItemsWorkflow } from "../add-line-items" @@ -32,7 +31,7 @@ const validationStep = createStep( orderClaim: OrderClaimDTO orderChange: OrderChangeDTO }) { - throwIfOrderIsCancelled({ order }) + throwIfIsCancelled(order, "Order") throwIfIsCancelled(orderClaim, "Claim") throwIfOrderChangeIsNotActive({ orderChange }) } diff --git a/packages/core/core-flows/src/order/workflows/claim/claim-item.ts b/packages/core/core-flows/src/order/workflows/claim/claim-item.ts new file mode 100644 index 0000000000..e6254a5731 --- /dev/null +++ b/packages/core/core-flows/src/order/workflows/claim/claim-item.ts @@ -0,0 +1,104 @@ +import { + OrderChangeDTO, + OrderClaimDTO, + OrderDTO, + OrderWorkflow, +} from "@medusajs/types" +import { ChangeActionType, OrderChangeStatus } from "@medusajs/utils" +import { + WorkflowData, + createStep, + createWorkflow, + transform, +} from "@medusajs/workflows-sdk" +import { useRemoteQueryStep } from "../../../common" +import { createOrderChangeActionsStep } from "../../steps/create-order-change-actions" +import { previewOrderChangeStep } from "../../steps/preview-order-change" +import { + throwIfIsCancelled, + throwIfOrderChangeIsNotActive, +} from "../../utils/order-validation" + +const validationStep = createStep( + "claim-item-validation", + async function ({ + order, + orderChange, + orderClaim, + }: { + order: OrderDTO + orderClaim: OrderClaimDTO + orderChange: OrderChangeDTO + }) { + throwIfIsCancelled(order, "Order") + throwIfIsCancelled(orderClaim, "Claim") + throwIfOrderChangeIsNotActive({ orderChange }) + } +) + +export const orderClaimItemWorkflowId = "claim-item" +export const orderClaimItemWorkflow = createWorkflow( + orderClaimItemWorkflowId, + function ( + input: WorkflowData + ): WorkflowData { + const orderClaim = useRemoteQueryStep({ + entry_point: "order_claim", + fields: ["id", "order_id", "canceled_at"], + variables: { id: input.claim_id }, + list: false, + throw_if_key_not_found: true, + }).config({ name: "claim-query" }) + + const order: OrderDTO = useRemoteQueryStep({ + entry_point: "orders", + fields: ["id", "status", "canceled_at", "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: { + filters: { + order_id: orderClaim.order_id, + claim_id: orderClaim.id, + status: [OrderChangeStatus.PENDING, OrderChangeStatus.REQUESTED], + }, + }, + list: false, + }).config({ name: "order-change-query" }) + + validationStep({ + order, + orderClaim, + orderChange, + }) + + const orderChangeActionInput = transform( + { order, orderChange, orderClaim, items: input.items }, + ({ order, orderChange, orderClaim, items }) => { + return items.map((item, index) => ({ + order_change_id: orderChange.id, + order_id: order.id, + claim_id: orderClaim.id, + version: orderChange.version, + action: ChangeActionType.WRITE_OFF_ITEM, + internal_note: item.internal_note, + reference: "order_claim", + reference_id: orderClaim.id, + details: { + reference_id: item.id, + quantity: item.quantity, + }, + })) + } + ) + + createOrderChangeActionsStep(orderChangeActionInput) + + return previewOrderChangeStep(orderClaim.order_id) + } +) diff --git a/packages/core/core-flows/src/order/workflows/claim/claim-request-item-return.ts b/packages/core/core-flows/src/order/workflows/claim/claim-request-item-return.ts index fefdd51677..191fff0df3 100644 --- a/packages/core/core-flows/src/order/workflows/claim/claim-request-item-return.ts +++ b/packages/core/core-flows/src/order/workflows/claim/claim-request-item-return.ts @@ -7,11 +7,11 @@ import { } from "@medusajs/types" import { ChangeActionType, OrderChangeStatus } from "@medusajs/utils" import { + WorkflowData, createStep, createWorkflow, transform, when, - WorkflowData, } from "@medusajs/workflows-sdk" import { useRemoteQueryStep } from "../../../common" import { createOrderChangeActionsStep } from "../../steps/create-order-change-actions" @@ -22,7 +22,6 @@ import { throwIfIsCancelled, throwIfItemsDoesNotExistsInOrder, throwIfOrderChangeIsNotActive, - throwIfOrderIsCancelled, } from "../../utils/order-validation" const validationStep = createStep( @@ -40,7 +39,7 @@ const validationStep = createStep( orderChange: OrderChangeDTO items: OrderWorkflow.OrderClaimRequestItemReturnWorkflowInput["items"] }) { - throwIfOrderIsCancelled({ order }) + throwIfIsCancelled(order, "Order") throwIfIsCancelled(orderClaim, "Claim") throwIfIsCancelled(orderReturn, "Return") throwIfOrderChangeIsNotActive({ orderChange }) diff --git a/packages/core/core-flows/src/order/workflows/claim/create-claim-shipping-method.ts b/packages/core/core-flows/src/order/workflows/claim/create-claim-shipping-method.ts new file mode 100644 index 0000000000..d5b09ca5d9 --- /dev/null +++ b/packages/core/core-flows/src/order/workflows/claim/create-claim-shipping-method.ts @@ -0,0 +1,169 @@ +import { + BigNumberInput, + OrderChangeDTO, + OrderClaimDTO, + OrderDTO, +} from "@medusajs/types" +import { ChangeActionType, OrderChangeStatus } from "@medusajs/utils" +import { + WorkflowData, + createStep, + createWorkflow, + transform, +} from "@medusajs/workflows-sdk" +import { useRemoteQueryStep } from "../../../common" +import { previewOrderChangeStep } from "../../steps" +import { createOrderChangeActionsStep } from "../../steps/create-order-change-actions" +import { createOrderShippingMethods } from "../../steps/create-order-shipping-methods" +import { + throwIfIsCancelled, + throwIfOrderChangeIsNotActive, +} from "../../utils/order-validation" + +const validationStep = createStep( + "validate-create-claim-shipping-method", + async function ({ + order, + orderChange, + orderClaim, + }: { + order: OrderDTO + orderClaim: OrderClaimDTO + orderChange: OrderChangeDTO + }) { + throwIfIsCancelled(order, "Order") + throwIfIsCancelled(orderClaim, "Claim") + throwIfOrderChangeIsNotActive({ orderChange }) + } +) + +export const createClaimShippingMethodWorkflowId = + "create-claim-shipping-method" +export const createClaimShippingMethodWorkflow = createWorkflow( + createClaimShippingMethodWorkflowId, + function (input: { + return_id?: string + claim_id?: string + shipping_option_id: string + custom_price?: BigNumberInput + }): WorkflowData { + const orderClaim: OrderClaimDTO = useRemoteQueryStep({ + entry_point: "claim", + fields: ["id", "status", "order_id", "canceled_at"], + variables: { id: input.claim_id }, + list: false, + throw_if_key_not_found: true, + }) + + const order: OrderDTO = useRemoteQueryStep({ + entry_point: "orders", + fields: ["id", "status", "currency_code", "canceled_at"], + variables: { id: orderClaim.order_id }, + list: false, + throw_if_key_not_found: true, + }).config({ name: "order-query" }) + + const shippingOptions = useRemoteQueryStep({ + entry_point: "shipping_option", + fields: [ + "id", + "name", + "calculated_price.calculated_amount", + "calculated_price.is_calculated_price_tax_inclusive", + ], + variables: { + id: input.shipping_option_id, + calculated_price: { + context: { currency_code: order.currency_code }, + }, + }, + }).config({ name: "fetch-shipping-option" }) + + const orderChange: OrderChangeDTO = useRemoteQueryStep({ + entry_point: "order_change", + fields: ["id", "status", "version"], + variables: { + filters: { + order_id: orderClaim.order_id, + claim_id: orderClaim.id, + status: [OrderChangeStatus.PENDING, OrderChangeStatus.REQUESTED], + }, + }, + list: false, + }).config({ name: "order-change-query" }) + + validationStep({ order, orderClaim, orderChange }) + + const shippingMethodInput = transform( + { + orderClaim, + shippingOptions, + customPrice: input.custom_price, + orderChange, + input, + }, + (data) => { + const option = data.shippingOptions[0] + const orderChange = data.orderChange + + return { + shipping_option_id: option.id, + amount: data.customPrice ?? option.calculated_price.calculated_amount, + is_tax_inclusive: + !!option.calculated_price.is_calculated_price_tax_inclusive, + data: option.data ?? {}, + name: option.name, + version: orderChange.version, + order_id: data.orderClaim.order_id, + return_id: data.orderClaim.id, + claim_id: data.input.claim_id, + } + } + ) + + const createdMethods = createOrderShippingMethods({ + shipping_methods: [shippingMethodInput], + }) + + const orderChangeActionInput = transform( + { + order, + orderClaim, + shippingOptions, + createdMethods, + customPrice: input.custom_price, + orderChange, + input, + }, + ({ + shippingOptions, + orderClaim, + order, + createdMethods, + customPrice, + orderChange, + input, + }) => { + const shippingOption = shippingOptions[0] + const createdMethod = createdMethods[0] + const methodPrice = + customPrice ?? shippingOption.calculated_price.calculated_amount + + return { + action: ChangeActionType.SHIPPING_ADD, + reference: "order_shipping_method", + order_change_id: orderChange.id, + reference_id: createdMethod.id, + amount: methodPrice, + order_id: order.id, + return_id: orderClaim.id, + claim_id: input.claim_id, + } + } + ) + + createOrderChangeActionsStep([orderChangeActionInput]) + + return previewOrderChangeStep(order.id) + } +) diff --git a/packages/core/core-flows/src/order/workflows/claim/remove-claim-item-action.ts b/packages/core/core-flows/src/order/workflows/claim/remove-claim-item-action.ts new file mode 100644 index 0000000000..9b640ef1f0 --- /dev/null +++ b/packages/core/core-flows/src/order/workflows/claim/remove-claim-item-action.ts @@ -0,0 +1,96 @@ +import { + OrderChangeActionDTO, + OrderChangeDTO, + OrderClaimDTO, + OrderDTO, + OrderWorkflow, +} from "@medusajs/types" +import { ChangeActionType, OrderChangeStatus } from "@medusajs/utils" +import { + WorkflowData, + createStep, + createWorkflow, +} from "@medusajs/workflows-sdk" +import { useRemoteQueryStep } from "../../../common" +import { + deleteOrderChangeActionsStep, + previewOrderChangeStep, +} from "../../steps" +import { + throwIfIsCancelled, + throwIfOrderChangeIsNotActive, +} from "../../utils/order-validation" + +const validationStep = createStep( + "remove-item-claim-action-validation", + async function ({ + order, + orderChange, + orderClaim, + input, + }: { + order: OrderDTO + orderClaim: OrderClaimDTO + orderChange: OrderChangeDTO + input: OrderWorkflow.DeleteOrderClaimItemActionWorkflowInput + }) { + throwIfIsCancelled(order, "Order") + throwIfIsCancelled(orderClaim, "Claim") + throwIfOrderChangeIsNotActive({ orderChange }) + + const associatedAction = (orderChange.actions ?? []).find( + (a) => a.id === input.action_id + ) as OrderChangeActionDTO + + if (!associatedAction) { + throw new Error( + `No item claim found for claim ${input.claim_id} in order change ${orderChange.id}` + ) + } else if (associatedAction.action !== ChangeActionType.WRITE_OFF_ITEM) { + throw new Error(`Action ${associatedAction.id} is not claiming an item`) + } + } +) + +export const removeItemClaimActionWorkflowId = "remove-item-claim-action" +export const removeItemClaimActionWorkflow = createWorkflow( + removeItemClaimActionWorkflowId, + function ( + input: WorkflowData + ): WorkflowData { + const orderClaim: OrderClaimDTO = useRemoteQueryStep({ + entry_point: "claim", + fields: ["id", "status", "order_id", "canceled_at"], + variables: { id: input.claim_id }, + list: false, + throw_if_key_not_found: true, + }) + + const order: OrderDTO = useRemoteQueryStep({ + entry_point: "orders", + fields: ["id", "status", "canceled_at", "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", "version", "actions.*"], + variables: { + filters: { + order_id: orderClaim.order_id, + claim_id: orderClaim.id, + status: [OrderChangeStatus.PENDING, OrderChangeStatus.REQUESTED], + }, + }, + list: false, + }).config({ name: "order-change-query" }) + + validationStep({ order, input, orderClaim, orderChange }) + + deleteOrderChangeActionsStep({ ids: [input.action_id] }) + + return previewOrderChangeStep(order.id) + } +) diff --git a/packages/core/core-flows/src/order/workflows/claim/remove-claim-shipping-method.ts b/packages/core/core-flows/src/order/workflows/claim/remove-claim-shipping-method.ts new file mode 100644 index 0000000000..6f49e21b50 --- /dev/null +++ b/packages/core/core-flows/src/order/workflows/claim/remove-claim-shipping-method.ts @@ -0,0 +1,105 @@ +import { + OrderChangeActionDTO, + OrderChangeDTO, + OrderClaimDTO, + OrderWorkflow, +} from "@medusajs/types" +import { ChangeActionType, OrderChangeStatus } from "@medusajs/utils" +import { + WorkflowData, + createStep, + createWorkflow, + parallelize, + transform, +} from "@medusajs/workflows-sdk" +import { useRemoteQueryStep } from "../../../common" +import { deleteOrderShippingMethods } from "../../steps" +import { deleteOrderChangeActionsStep } from "../../steps/delete-order-change-actions" +import { previewOrderChangeStep } from "../../steps/preview-order-change" +import { + throwIfIsCancelled, + throwIfOrderChangeIsNotActive, +} from "../../utils/order-validation" + +const validationStep = createStep( + "validate-remove-claim-shipping-method", + async function ({ + orderChange, + orderClaim, + input, + }: { + input: { claim_id: string; action_id: string } + orderClaim: OrderClaimDTO + orderChange: OrderChangeDTO + }) { + throwIfIsCancelled(orderClaim, "Claim") + throwIfOrderChangeIsNotActive({ orderChange }) + + const associatedAction = (orderChange.actions ?? []).find( + (a) => a.id === input.action_id + ) as OrderChangeActionDTO + + if (!associatedAction) { + throw new Error( + `No shipping method found for claim ${input.claim_id} in order change ${orderChange.id}` + ) + } else if (associatedAction.action !== ChangeActionType.SHIPPING_ADD) { + throw new Error( + `Action ${associatedAction.id} is not adding a shipping method` + ) + } + } +) + +export const removeClaimShippingMethodWorkflowId = + "remove-claim-shipping-method" +export const removeClaimShippingMethodWorkflow = createWorkflow( + removeClaimShippingMethodWorkflowId, + function ( + input: WorkflowData + ): WorkflowData { + const orderClaim: OrderClaimDTO = useRemoteQueryStep({ + entry_point: "claim", + fields: ["id", "status", "order_id", "canceled_at"], + variables: { id: input.claim_id }, + list: false, + throw_if_key_not_found: true, + }) + + const orderChange: OrderChangeDTO = useRemoteQueryStep({ + entry_point: "order_change", + fields: ["id", "status", "version", "actions.*"], + variables: { + filters: { + order_id: orderClaim.order_id, + claim_id: orderClaim.id, + status: [OrderChangeStatus.PENDING, OrderChangeStatus.REQUESTED], + }, + }, + list: false, + }).config({ name: "order-change-query" }) + + validationStep({ orderClaim, orderChange, input }) + + const dataToRemove = transform( + { orderChange, input }, + ({ orderChange, input }) => { + const associatedAction = (orderChange.actions ?? []).find( + (a) => a.id === input.action_id + ) as OrderChangeActionDTO + + return { + actionId: associatedAction.id, + shippingMethodId: associatedAction.reference_id, + } + } + ) + + parallelize( + deleteOrderChangeActionsStep({ ids: [dataToRemove.actionId] }), + deleteOrderShippingMethods({ ids: [dataToRemove.shippingMethodId] }) + ) + + return previewOrderChangeStep(orderClaim.order_id) + } +) diff --git a/packages/core/core-flows/src/order/workflows/claim/update-claim-add-item.ts b/packages/core/core-flows/src/order/workflows/claim/update-claim-add-item.ts new file mode 100644 index 0000000000..41de3fbd21 --- /dev/null +++ b/packages/core/core-flows/src/order/workflows/claim/update-claim-add-item.ts @@ -0,0 +1,118 @@ +import { + OrderChangeActionDTO, + OrderChangeDTO, + OrderClaimDTO, + OrderDTO, + OrderWorkflow, +} from "@medusajs/types" +import { ChangeActionType, OrderChangeStatus } from "@medusajs/utils" +import { + WorkflowData, + createStep, + createWorkflow, + transform, +} from "@medusajs/workflows-sdk" +import { useRemoteQueryStep } from "../../../common" +import { + previewOrderChangeStep, + updateOrderChangeActionsStep, +} from "../../steps" +import { + throwIfIsCancelled, + throwIfOrderChangeIsNotActive, +} from "../../utils/order-validation" + +const validationStep = createStep( + "update-claim-add-item-validation", + async function ( + { + order, + orderChange, + orderClaim, + input, + }: { + order: OrderDTO + orderClaim: OrderClaimDTO + orderChange: OrderChangeDTO + input: OrderWorkflow.UpdateClaimAddNewItemWorkflowInput + }, + context + ) { + throwIfIsCancelled(order, "Order") + throwIfIsCancelled(orderClaim, "Claim") + throwIfOrderChangeIsNotActive({ orderChange }) + + const associatedAction = (orderChange.actions ?? []).find( + (a) => a.id === input.action_id + ) as OrderChangeActionDTO + + if (!associatedAction) { + throw new Error( + `No request to add item for claim ${input.claim_id} in order change ${orderChange.id}` + ) + } else if (associatedAction.action !== ChangeActionType.ITEM_ADD) { + throw new Error(`Action ${associatedAction.id} is not adding an item`) + } + } +) + +export const updateClaimAddItemWorkflowId = "update-claim-add-item" +export const updateClaimAddItemWorkflow = createWorkflow( + updateClaimAddItemWorkflowId, + function ( + input: WorkflowData + ): WorkflowData { + const orderClaim: OrderClaimDTO = useRemoteQueryStep({ + entry_point: "claim", + fields: ["id", "status", "order_id", "canceled_at"], + variables: { id: input.claim_id }, + list: false, + throw_if_key_not_found: true, + }) + + const order: OrderDTO = useRemoteQueryStep({ + entry_point: "orders", + fields: ["id", "status", "canceled_at", "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", "version", "actions.*"], + variables: { + filters: { + order_id: orderClaim.order_id, + claim_id: orderClaim.id, + status: [OrderChangeStatus.PENDING, OrderChangeStatus.REQUESTED], + }, + }, + list: false, + }).config({ name: "order-change-query" }) + + validationStep({ order, input, orderClaim, orderChange }) + + const updateData = transform( + { orderChange, input }, + ({ input, orderChange }) => { + const originalAction = (orderChange.actions ?? []).find( + (a) => a.id === input.action_id + ) as OrderChangeActionDTO + + const data = input.data + return { + id: input.action_id, + details: { + quantity: data.quantity ?? originalAction.details?.quantity, + }, + internal_note: data.internal_note, + } + } + ) + + updateOrderChangeActionsStep([updateData]) + + return previewOrderChangeStep(order.id) + } +) diff --git a/packages/core/core-flows/src/order/workflows/claim/update-claim-item.ts b/packages/core/core-flows/src/order/workflows/claim/update-claim-item.ts new file mode 100644 index 0000000000..c5dd534dd0 --- /dev/null +++ b/packages/core/core-flows/src/order/workflows/claim/update-claim-item.ts @@ -0,0 +1,118 @@ +import { + OrderChangeActionDTO, + OrderChangeDTO, + OrderClaimDTO, + OrderDTO, + OrderWorkflow, +} from "@medusajs/types" +import { ChangeActionType, OrderChangeStatus } from "@medusajs/utils" +import { + WorkflowData, + createStep, + createWorkflow, + transform, +} from "@medusajs/workflows-sdk" +import { useRemoteQueryStep } from "../../../common" +import { + previewOrderChangeStep, + updateOrderChangeActionsStep, +} from "../../steps" +import { + throwIfIsCancelled, + throwIfOrderChangeIsNotActive, +} from "../../utils/order-validation" + +const validationStep = createStep( + "update-claim-item-validation", + async function ( + { + order, + orderChange, + orderClaim, + input, + }: { + order: OrderDTO + orderClaim: OrderClaimDTO + orderChange: OrderChangeDTO + input: OrderWorkflow.UpdateClaimItemWorkflowInput + }, + context + ) { + throwIfIsCancelled(order, "Order") + throwIfIsCancelled(orderClaim, "Claim") + throwIfOrderChangeIsNotActive({ orderChange }) + + const associatedAction = (orderChange.actions ?? []).find( + (a) => a.id === input.action_id + ) as OrderChangeActionDTO + + if (!associatedAction) { + throw new Error( + `No request claim found for claim ${input.claim_id} in order change ${orderChange.id}` + ) + } else if (associatedAction.action !== ChangeActionType.WRITE_OFF_ITEM) { + throw new Error(`Action ${associatedAction.id} is not claiming the item`) + } + } +) + +export const updateClaimItemWorkflowId = "update-claim-item" +export const updateClaimItemWorkflow = createWorkflow( + updateClaimItemWorkflowId, + function ( + input: WorkflowData + ): WorkflowData { + const orderClaim: OrderClaimDTO = useRemoteQueryStep({ + entry_point: "claim", + fields: ["id", "status", "order_id", "canceled_at"], + variables: { id: input.claim_id }, + list: false, + throw_if_key_not_found: true, + }) + + const order: OrderDTO = useRemoteQueryStep({ + entry_point: "orders", + fields: ["id", "status", "canceled_at", "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", "version", "actions.*"], + variables: { + filters: { + order_id: orderClaim.order_id, + claim_id: orderClaim.id, + status: [OrderChangeStatus.PENDING, OrderChangeStatus.REQUESTED], + }, + }, + list: false, + }).config({ name: "order-change-query" }) + + validationStep({ order, input, orderClaim, orderChange }) + + const updateData = transform( + { orderChange, input }, + ({ input, orderChange }) => { + const originalAction = (orderChange.actions ?? []).find( + (a) => a.id === input.action_id + ) as OrderChangeActionDTO + + const data = input.data + return { + id: input.action_id, + details: { + quantity: data.quantity ?? originalAction.details?.quantity, + }, + internal_note: data.internal_note, + } + } + ) + + updateOrderChangeActionsStep([updateData]) + + return previewOrderChangeStep(order.id) + } +) diff --git a/packages/core/core-flows/src/order/workflows/claim/update-claim-shipping-method.ts b/packages/core/core-flows/src/order/workflows/claim/update-claim-shipping-method.ts new file mode 100644 index 0000000000..7671551295 --- /dev/null +++ b/packages/core/core-flows/src/order/workflows/claim/update-claim-shipping-method.ts @@ -0,0 +1,120 @@ +import { + OrderChangeActionDTO, + OrderChangeDTO, + OrderClaimDTO, + OrderWorkflow, +} from "@medusajs/types" +import { ChangeActionType, OrderChangeStatus } from "@medusajs/utils" +import { + WorkflowData, + createStep, + createWorkflow, + parallelize, + transform, +} from "@medusajs/workflows-sdk" +import { useRemoteQueryStep } from "../../../common" +import { + updateOrderChangeActionsStep, + updateOrderShippingMethodsStep, +} from "../../steps" +import { previewOrderChangeStep } from "../../steps/preview-order-change" +import { + throwIfIsCancelled, + throwIfOrderChangeIsNotActive, +} from "../../utils/order-validation" + +const validationStep = createStep( + "validate-update-claim-shipping-method", + async function ({ + orderChange, + orderClaim, + input, + }: { + input: { claim_id: string; action_id: string } + orderClaim: OrderClaimDTO + orderChange: OrderChangeDTO + }) { + throwIfIsCancelled(orderClaim, "Claim") + throwIfOrderChangeIsNotActive({ orderChange }) + + const associatedAction = (orderChange.actions ?? []).find( + (a) => a.id === input.action_id + ) as OrderChangeActionDTO + + if (!associatedAction) { + throw new Error( + `No shipping method found for claim ${input.claim_id} in order change ${orderChange.id}` + ) + } else if (associatedAction.action !== ChangeActionType.SHIPPING_ADD) { + throw new Error( + `Action ${associatedAction.id} is not adding a shipping method` + ) + } + } +) + +export const updateClaimShippingMethodWorkflowId = + "update-claim-shipping-method" +export const updateClaimShippingMethodWorkflow = createWorkflow( + updateClaimShippingMethodWorkflowId, + function ( + input: WorkflowData + ): WorkflowData { + const orderClaim: OrderClaimDTO = useRemoteQueryStep({ + entry_point: "claim", + fields: ["id", "status", "order_id", "canceled_at"], + variables: { id: input.claim_id }, + list: false, + throw_if_key_not_found: true, + }) + + const orderChange: OrderChangeDTO = useRemoteQueryStep({ + entry_point: "order_change", + fields: ["id", "status", "version", "actions.*"], + variables: { + filters: { + order_id: orderClaim.order_id, + claim_id: orderClaim.id, + status: [OrderChangeStatus.PENDING, OrderChangeStatus.REQUESTED], + }, + }, + list: false, + }).config({ name: "order-change-query" }) + + validationStep({ orderClaim, orderChange, input }) + + const updateData = transform( + { orderChange, input }, + ({ input, orderChange }) => { + const originalAction = (orderChange.actions ?? []).find( + (a) => a.id === input.action_id + ) as OrderChangeActionDTO + + const data = input.data + + const action = { + id: originalAction.id, + internal_note: data.internal_note, + } + + const shippingMethod = { + id: originalAction.reference_id, + amount: data.custom_price, + metadata: data.metadata, + } + + return { + action, + shippingMethod, + } + } + ) + + parallelize( + updateOrderChangeActionsStep([updateData.action]), + updateOrderShippingMethodsStep([updateData.shippingMethod!]) + ) + + return previewOrderChangeStep(orderClaim.order_id) + } +) diff --git a/packages/core/core-flows/src/order/workflows/index.ts b/packages/core/core-flows/src/order/workflows/index.ts index aab0a619b6..2d2a249076 100644 --- a/packages/core/core-flows/src/order/workflows/index.ts +++ b/packages/core/core-flows/src/order/workflows/index.ts @@ -4,7 +4,16 @@ export * from "./cancel-order" 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/claim-add-new-item" +export * from "./claim/claim-item" export * from "./claim/claim-request-item-return" +export * from "./claim/create-claim-shipping-method" +export * from "./claim/remove-claim-item-action" +export * from "./claim/remove-claim-shipping-method" +export * from "./claim/update-claim-add-item" +export * from "./claim/update-claim-item" +export * from "./claim/update-claim-shipping-method" export * from "./complete-orders" export * from "./create-fulfillment" export * from "./create-order-change" diff --git a/packages/core/core-flows/src/order/workflows/return/confirm-receive-return-request.ts b/packages/core/core-flows/src/order/workflows/return/confirm-receive-return-request.ts index a024c4f7b1..51455be4f6 100644 --- a/packages/core/core-flows/src/order/workflows/return/confirm-receive-return-request.ts +++ b/packages/core/core-flows/src/order/workflows/return/confirm-receive-return-request.ts @@ -3,12 +3,14 @@ import { OrderChangeActionDTO, OrderChangeDTO, OrderDTO, + OrderReturnItemDTO, ReturnDTO, } from "@medusajs/types" import { ChangeActionType, MathBN, OrderChangeStatus, + ReturnStatus, deepFlatMap, } from "@medusajs/utils" import { @@ -20,7 +22,11 @@ import { } from "@medusajs/workflows-sdk" import { useRemoteQueryStep } from "../../../common" import { adjustInventoryLevelsStep } from "../../../inventory/steps" -import { previewOrderChangeStep, updateReturnItemsStep } from "../../steps" +import { + previewOrderChangeStep, + updateReturnItemsStep, + updateReturnsStep, +} from "../../steps" import { confirmOrderChanges } from "../../steps/confirm-order-changes" import { throwIfIsCancelled, @@ -173,12 +179,12 @@ export const confirmReturnReceiveWorkflow = createWorkflow( list: false, }).config({ name: "order-change-query" }) - const { updateReturnItem, returnedQuantityMap } = transform( + const { updateReturnItem, returnedQuantityMap, updateReturn } = transform( { orderChange, orderReturn }, (data) => { const returnedQuantityMap: Record = {} - const retItems = data.orderReturn.items ?? [] + const retItems: OrderReturnItemDTO[] = data.orderReturn.items ?? [] const received: OrderChangeActionDTO[] = [] data.orderChange.actions.forEach((act) => { @@ -232,9 +238,26 @@ export const confirmReturnReceiveWorkflow = createWorkflow( } }) + const hasReceivedAllItems = retItems.every((item) => { + const received = itemUpdates[item.item_id] + ? itemUpdates[item.item_id].received_quantity + : item.received_quantity + + return MathBN.eq(received, item.quantity) + }) + const updateReturnData = hasReceivedAllItems + ? { status: ReturnStatus.RECEIVED, received_at: new Date() } + : { status: ReturnStatus.PARTIALLY_RECEIVED } + + const updateReturn = { + id: data.orderReturn.id, + ...updateReturnData, + } + return { updateReturnItem: Object.values(itemUpdates) as any, returnedQuantityMap, + updateReturn, } } ) @@ -247,6 +270,7 @@ export const confirmReturnReceiveWorkflow = createWorkflow( validationStep({ order, orderReturn, orderChange }) parallelize( + updateReturnsStep([updateReturn]), updateReturnItemsStep(updateReturnItem), confirmOrderChanges({ changes: [orderChange], orderId: order.id }), adjustInventoryLevelsStep(inventoryAdjustment) diff --git a/packages/core/core-flows/src/order/workflows/return/create-return-shipping-method.ts b/packages/core/core-flows/src/order/workflows/return/create-return-shipping-method.ts index 39a8580285..cc3a584f01 100644 --- a/packages/core/core-flows/src/order/workflows/return/create-return-shipping-method.ts +++ b/packages/core/core-flows/src/order/workflows/return/create-return-shipping-method.ts @@ -43,6 +43,8 @@ export const createReturnShippingMethodWorkflow = createWorkflow( createReturnShippingMethodWorkflowId, function (input: { return_id: string + claim_id?: string + exchange_id?: string shipping_option_id: string custom_price?: BigNumberInput }): WorkflowData { @@ -99,6 +101,7 @@ export const createReturnShippingMethodWorkflow = createWorkflow( shippingOptions, customPrice: input.custom_price, orderChange, + input, }, (data) => { const option = data.shippingOptions[0] @@ -114,6 +117,8 @@ export const createReturnShippingMethodWorkflow = createWorkflow( version: orderChange.version, order_id: data.orderReturn.order_id, return_id: data.orderReturn.id, + claim_id: data.input.claim_id, + exchange_id: data.input.exchange_id, } } ) @@ -130,6 +135,7 @@ export const createReturnShippingMethodWorkflow = createWorkflow( createdMethods, customPrice: input.custom_price, orderChange, + input, }, ({ shippingOptions, @@ -138,6 +144,7 @@ export const createReturnShippingMethodWorkflow = createWorkflow( createdMethods, customPrice, orderChange, + input, }) => { const shippingOption = shippingOptions[0] const createdMethod = createdMethods[0] @@ -152,6 +159,8 @@ export const createReturnShippingMethodWorkflow = createWorkflow( amount: methodPrice, order_id: order.id, return_id: orderReturn.id, + claim_id: input.claim_id, + exchange_id: input.exchange_id, } } ) diff --git a/packages/core/core-flows/src/order/workflows/return/update-request-item-return.ts b/packages/core/core-flows/src/order/workflows/return/update-request-item-return.ts index 8397af1fb5..c6c80ac02d 100644 --- a/packages/core/core-flows/src/order/workflows/return/update-request-item-return.ts +++ b/packages/core/core-flows/src/order/workflows/return/update-request-item-return.ts @@ -119,7 +119,6 @@ export const updateRequestItemReturnWorkflow = createWorkflow( 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, } diff --git a/packages/core/types/src/order/common.ts b/packages/core/types/src/order/common.ts index 449a11624d..fc29cbd32c 100644 --- a/packages/core/types/src/order/common.ts +++ b/packages/core/types/src/order/common.ts @@ -1132,11 +1132,13 @@ export interface OrderDTO { type ReturnStatus = "requested" | "received" | "partially_received" | "canceled" -export interface ReturnDTO extends Omit { +export interface ReturnDTO + extends Omit { id: string status: ReturnStatus refund_amount?: BigNumberValue order_id: string + items: OrderReturnItemDTO[] } export interface OrderReturnItemDTO { @@ -1156,22 +1158,24 @@ export interface OrderReturnItemDTO { export interface OrderClaimDTO extends Omit { + order_id: string claim_items: any[] additional_items: any[] return?: ReturnDTO + return_id?: string no_notification?: boolean refund_amount?: BigNumberValue } export interface OrderExchangeDTO extends Omit { + order_id: string return_items: any[] additional_items: any[] no_notification?: boolean difference_due?: BigNumberValue return?: ReturnDTO return_id?: string - order_id: string } export type PaymentStatus = diff --git a/packages/core/types/src/workflow/order/add-new-item.ts b/packages/core/types/src/workflow/order/add-new-item.ts deleted file mode 100644 index 6a95efaa31..0000000000 --- a/packages/core/types/src/workflow/order/add-new-item.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { BigNumberInput } from "../../totals" - -export interface OrderExchangeAddNewItemWorkflowInput { - exchange_id: string - items: { - variant_id: string - quantity: BigNumberInput - unit_price?: BigNumberInput - internal_note?: string - metadata?: Record | null - }[] -} - -export interface OrderClaimAddNewItemWorkflowInput { - claim_id: string - items: { - variant_id: string - quantity: BigNumberInput - unit_price?: BigNumberInput - internal_note?: string - metadata?: Record | null - }[] -} - -export interface OrderAddLineItemWorkflowInput { - order_id: string - items: { - variant_id: string - quantity: BigNumberInput - unit_price?: BigNumberInput - internal_note?: string - metadata?: Record | null - }[] -} diff --git a/packages/core/types/src/workflow/order/index.ts b/packages/core/types/src/workflow/order/index.ts index 7a0b5cdee8..fabb96ac8a 100644 --- a/packages/core/types/src/workflow/order/index.ts +++ b/packages/core/types/src/workflow/order/index.ts @@ -1,4 +1,3 @@ -export * from "./add-new-item" export * from "./begin-claim-order" export * from "./begin-exchange-order" export * from "./begin-return-order" @@ -10,6 +9,7 @@ export * from "./cancel-return" export * from "./create-fulfillment" export * from "./create-return-order" export * from "./create-shipment" +export * from "./items" export * from "./receive-return" export * from "./request-item-return" -export * from "./shipping-return" +export * from "./shipping-method" diff --git a/packages/core/types/src/workflow/order/items.ts b/packages/core/types/src/workflow/order/items.ts new file mode 100644 index 0000000000..ef2d8a2ecd --- /dev/null +++ b/packages/core/types/src/workflow/order/items.ts @@ -0,0 +1,86 @@ +import { BigNumberInput } from "../../totals" + +interface NewItem { + variant_id: string + quantity: BigNumberInput + unit_price?: BigNumberInput + internal_note?: string + metadata?: Record | null +} + +interface ExistingItem { + id: string + quantity: BigNumberInput + internal_note?: string +} + +export interface OrderExchangeAddNewItemWorkflowInput { + exchange_id: string + items: NewItem[] +} + +export interface OrderClaimAddNewItemWorkflowInput { + claim_id: string + items: NewItem[] +} + +export interface OrderAddLineItemWorkflowInput { + order_id: string + items: NewItem[] +} + +export interface UpdateExchangeAddNewItemWorkflowInput { + exchange_id: string + action_id: string + data: { + quantity?: BigNumberInput + internal_note?: string | null + } +} + +export interface UpdateClaimAddNewItemWorkflowInput { + claim_id: string + action_id: string + data: { + quantity?: BigNumberInput + internal_note?: string | null + } +} + +export interface OrderExchangeItemWorkflowInput { + exchange_id: string + items: ExistingItem[] +} + +export interface UpdateExchangeAddItemWorkflowInput { + exchange_id: string + action_id: string + data: { + quantity?: BigNumberInput + internal_note?: string | null + } +} + +export interface OrderClaimItemWorkflowInput { + claim_id: string + items: ExistingItem[] +} + +export interface UpdateClaimItemWorkflowInput { + claim_id: string + action_id: string + data: { + quantity?: BigNumberInput + internal_note?: string | null + } +} + +export interface DeleteOrderExchangeItemActionWorkflowInput { + exchange_id: string + action_id: string +} + +export interface DeleteOrderClaimItemActionWorkflowInput { + claim_id: string + action_id: string +} diff --git a/packages/core/types/src/workflow/order/request-item-return.ts b/packages/core/types/src/workflow/order/request-item-return.ts index 67e29ff061..bf8cb1fd73 100644 --- a/packages/core/types/src/workflow/order/request-item-return.ts +++ b/packages/core/types/src/workflow/order/request-item-return.ts @@ -3,6 +3,8 @@ import { CreateReturnItem } from "./create-return-order" export interface RequestItemReturnWorkflowInput { return_id: string + claim_id?: string + exchange_id?: string items: CreateReturnItem[] } export interface DeleteRequestItemReturnWorkflowInput { @@ -17,11 +19,11 @@ export interface UpdateRequestItemReturnWorkflowInput { quantity?: BigNumberInput internal_note?: string | null reason_id?: string | null - metadata?: Record | null } } export interface OrderExchangeRequestItemReturnWorkflowInput { + return_id: string exchange_id: string items: CreateReturnItem[] } @@ -31,6 +33,7 @@ export interface DeleteOrderExchangeRequestItemReturnWorkflowInput { } export interface OrderClaimRequestItemReturnWorkflowInput { + return_id: string claim_id: string items: CreateReturnItem[] } diff --git a/packages/core/types/src/workflow/order/shipping-method.ts b/packages/core/types/src/workflow/order/shipping-method.ts new file mode 100644 index 0000000000..7d74ee9139 --- /dev/null +++ b/packages/core/types/src/workflow/order/shipping-method.ts @@ -0,0 +1,46 @@ +import { BigNumberInput } from "../../totals" + +export interface UpdateReturnShippingMethodWorkflowInput { + return_id: string + action_id: string + data: { + custom_price?: BigNumberInput + internal_note?: string | null + metadata?: Record | null + } +} + +export interface DeleteReturnShippingMethodWorkflowInput { + return_id: string + action_id: string +} + +export interface UpdateClaimShippingMethodWorkflowInput { + claim_id: string + action_id: string + data: { + custom_price?: BigNumberInput + internal_note?: string | null + metadata?: Record | null + } +} + +export interface DeleteClaimShippingMethodWorkflowInput { + claim_id: string + action_id: string +} + +export interface UpdateExchangeShippingMethodWorkflowInput { + exchange_id: string + action_id: string + data: { + custom_price?: BigNumberInput + internal_note?: string | null + metadata?: Record | null + } +} + +export interface DeleteExchangeShippingMethodWorkflowInput { + exchange_id: string + action_id: string +} diff --git a/packages/core/types/src/workflow/order/shipping-return.ts b/packages/core/types/src/workflow/order/shipping-return.ts deleted file mode 100644 index 25160b5169..0000000000 --- a/packages/core/types/src/workflow/order/shipping-return.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { BigNumberInput } from "../../totals" - -export interface UpdateReturnShippingMethodWorkflowInput { - return_id: string - action_id: string - data: { - custom_price?: BigNumberInput - internal_note?: string | null - metadata?: Record | null - } -} - -export interface DeleteReturnShippingMethodWorkflowInput { - return_id: string - action_id: string -} diff --git a/packages/medusa/src/api/admin/claims/[id]/claim-items/[action_id]/route.ts b/packages/medusa/src/api/admin/claims/[id]/claim-items/[action_id]/route.ts new file mode 100644 index 0000000000..3507e09fad --- /dev/null +++ b/packages/medusa/src/api/admin/claims/[id]/claim-items/[action_id]/route.ts @@ -0,0 +1,83 @@ +import { + removeItemClaimActionWorkflow, + updateClaimItemWorkflow, +} from "@medusajs/core-flows" +import { + ContainerRegistrationKeys, + remoteQueryObjectFromString, +} from "@medusajs/utils" +import { + AuthenticatedMedusaRequest, + MedusaResponse, +} from "../../../../../../types/routing" +import { AdminPostClaimsItemsActionReqSchemaType } from "../../../validators" + +export const POST = async ( + req: AuthenticatedMedusaRequest, + res: MedusaResponse +) => { + const { id, action_id } = req.params + + const remoteQuery = req.scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY) + + const { result } = await updateClaimItemWorkflow(req.scope).run({ + input: { + data: { ...req.validatedBody }, + claim_id: id, + action_id, + }, + }) + + const queryObject = remoteQueryObjectFromString({ + entryPoint: "claim", + variables: { + id, + filters: { + ...req.filterableFields, + }, + }, + fields: req.remoteQueryConfig.fields, + }) + + const [orderClaim] = await remoteQuery(queryObject) + + res.json({ + order_preview: result, + claim: orderClaim, + }) +} + +export const DELETE = async ( + req: AuthenticatedMedusaRequest, + res: MedusaResponse +) => { + const remoteQuery = req.scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY) + + const { id, action_id } = req.params + + const { result: orderPreview } = await removeItemClaimActionWorkflow( + req.scope + ).run({ + input: { + claim_id: id, + action_id, + }, + }) + + const queryObject = remoteQueryObjectFromString({ + entryPoint: "claim", + variables: { + id, + filters: { + ...req.filterableFields, + }, + }, + fields: req.remoteQueryConfig.fields, + }) + const [orderClaim] = await remoteQuery(queryObject) + + res.json({ + order_preview: orderPreview, + claim: orderClaim, + }) +} diff --git a/packages/medusa/src/api/admin/claims/[id]/claim-items/route.ts b/packages/medusa/src/api/admin/claims/[id]/claim-items/route.ts new file mode 100644 index 0000000000..5236c9fe36 --- /dev/null +++ b/packages/medusa/src/api/admin/claims/[id]/claim-items/route.ts @@ -0,0 +1,41 @@ +import { orderClaimItemWorkflow } from "@medusajs/core-flows" +import { + ContainerRegistrationKeys, + remoteQueryObjectFromString, +} from "@medusajs/utils" +import { + AuthenticatedMedusaRequest, + MedusaResponse, +} from "../../../../../types/routing" +import { AdminPostClaimItemsReqSchemaType } from "../../validators" + +export const POST = async ( + req: AuthenticatedMedusaRequest, + res: MedusaResponse +) => { + const { id } = req.params + + const remoteQuery = req.scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY) + + const { result } = await orderClaimItemWorkflow(req.scope).run({ + input: { ...req.validatedBody, claim_id: id }, + }) + + const queryObject = remoteQueryObjectFromString({ + entryPoint: "claim", + variables: { + id, + filters: { + ...req.filterableFields, + }, + }, + fields: req.remoteQueryConfig.fields, + }) + + const [orderClaim] = await remoteQuery(queryObject) + + res.json({ + order_preview: result, + claim: orderClaim, + }) +} diff --git a/packages/medusa/src/api/admin/claims/[id]/inbound/items/[action_id]/route.ts b/packages/medusa/src/api/admin/claims/[id]/inbound/items/[action_id]/route.ts new file mode 100644 index 0000000000..24e10b6baa --- /dev/null +++ b/packages/medusa/src/api/admin/claims/[id]/inbound/items/[action_id]/route.ts @@ -0,0 +1,97 @@ +import { + removeItemReturnActionWorkflow, + updateRequestItemReturnWorkflow, +} from "@medusajs/core-flows" +import { + ContainerRegistrationKeys, + remoteQueryObjectFromString, +} from "@medusajs/utils" +import { + AuthenticatedMedusaRequest, + MedusaResponse, +} from "../../../../../../../types/routing" +import { AdminPostReturnsRequestItemsActionReqSchemaType } from "../../../../../returns/validators" + +export const POST = async ( + req: AuthenticatedMedusaRequest, + res: MedusaResponse +) => { + const { id, action_id } = req.params + + const remoteQuery = req.scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY) + + const [claim] = await remoteQuery( + remoteQueryObjectFromString({ + entryPoint: "claim", + variables: { + id, + }, + fields: ["return_id"], + }), + undefined, + { + throwIfKeyNotFound: true, + } + ) + + const { result } = await updateRequestItemReturnWorkflow(req.scope).run({ + input: { + data: { ...req.validatedBody }, + return_id: claim.return_id, + action_id, + }, + }) + + const queryObject = remoteQueryObjectFromString({ + entryPoint: "return", + variables: { + id, + filters: { + ...req.filterableFields, + }, + }, + fields: req.remoteQueryConfig.fields, + }) + + const [orderReturn] = await remoteQuery(queryObject) + + res.json({ + order_preview: result, + return: orderReturn, + }) +} + +export const DELETE = async ( + req: AuthenticatedMedusaRequest, + res: MedusaResponse +) => { + const remoteQuery = req.scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY) + + const { id, action_id } = req.params + + const { result: orderPreview } = await removeItemReturnActionWorkflow( + req.scope + ).run({ + input: { + return_id: id, + action_id, + }, + }) + + const queryObject = remoteQueryObjectFromString({ + entryPoint: "return", + variables: { + id, + filters: { + ...req.filterableFields, + }, + }, + fields: req.remoteQueryConfig.fields, + }) + const [orderReturn] = await remoteQuery(queryObject) + + res.json({ + order_preview: orderPreview, + return: orderReturn, + }) +} diff --git a/packages/medusa/src/api/admin/claims/[id]/inbound/items/route.ts b/packages/medusa/src/api/admin/claims/[id]/inbound/items/route.ts new file mode 100644 index 0000000000..6b0d7f76b5 --- /dev/null +++ b/packages/medusa/src/api/admin/claims/[id]/inbound/items/route.ts @@ -0,0 +1,56 @@ +import { orderClaimRequestItemReturnWorkflow } from "@medusajs/core-flows" +import { + ContainerRegistrationKeys, + remoteQueryObjectFromString, +} from "@medusajs/utils" + +import { + AuthenticatedMedusaRequest, + MedusaResponse, +} from "../../../../../../types/routing" +import { AdminPostReturnsRequestItemsReqSchemaType } from "../../../../returns/validators" + +export const POST = async ( + req: AuthenticatedMedusaRequest, + res: MedusaResponse +) => { + const { id } = req.params + + const remoteQuery = req.scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY) + + const [claim] = await remoteQuery( + remoteQueryObjectFromString({ + entryPoint: "claim", + variables: { + id, + }, + fields: ["return_id"], + }), + undefined, + { + throwIfKeyNotFound: true, + } + ) + + const { result } = await orderClaimRequestItemReturnWorkflow(req.scope).run({ + input: { ...req.validatedBody, return_id: claim.return_id, claim_id: id }, + }) + + const queryObject = remoteQueryObjectFromString({ + entryPoint: "return", + variables: { + id, + filters: { + ...req.filterableFields, + }, + }, + fields: req.remoteQueryConfig.fields, + }) + + const [orderReturn] = await remoteQuery(queryObject) + + res.json({ + order_preview: result, + return: orderReturn, + }) +} diff --git a/packages/medusa/src/api/admin/claims/[id]/inbound/shipping-method/[action_id]/route.ts b/packages/medusa/src/api/admin/claims/[id]/inbound/shipping-method/[action_id]/route.ts new file mode 100644 index 0000000000..a27fddbb0b --- /dev/null +++ b/packages/medusa/src/api/admin/claims/[id]/inbound/shipping-method/[action_id]/route.ts @@ -0,0 +1,111 @@ +import { + removeReturnShippingMethodWorkflow, + updateReturnShippingMethodWorkflow, +} from "@medusajs/core-flows" +import { + ContainerRegistrationKeys, + remoteQueryObjectFromString, +} from "@medusajs/utils" +import { + AuthenticatedMedusaRequest, + MedusaResponse, +} from "../../../../../../../types/routing" +import { AdminPostClaimsShippingActionReqSchemaType } from "../../../../validators" + +export const POST = async ( + req: AuthenticatedMedusaRequest, + res: MedusaResponse +) => { + const { id, action_id } = req.params + + const remoteQuery = req.scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY) + + const [claim] = await remoteQuery( + remoteQueryObjectFromString({ + entryPoint: "claim", + variables: { + id, + }, + fields: ["return_id"], + }), + undefined, + { + throwIfKeyNotFound: true, + } + ) + + const { result } = await updateReturnShippingMethodWorkflow(req.scope).run({ + input: { + data: { ...req.validatedBody }, + return_id: claim.return_id, + action_id, + }, + }) + + const queryObject = remoteQueryObjectFromString({ + entryPoint: "claim", + variables: { + id, + filters: { + ...req.filterableFields, + }, + }, + fields: req.remoteQueryConfig.fields, + }) + + const [orderClaim] = await remoteQuery(queryObject) + + res.json({ + order_preview: result, + claim: orderClaim, + }) +} + +export const DELETE = async ( + req: AuthenticatedMedusaRequest, + res: MedusaResponse +) => { + const remoteQuery = req.scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY) + + const { id, action_id } = req.params + + const [claim] = await remoteQuery( + remoteQueryObjectFromString({ + entryPoint: "claim", + variables: { + id, + }, + fields: ["return_id"], + }), + undefined, + { + throwIfKeyNotFound: true, + } + ) + + const { result: orderPreview } = await removeReturnShippingMethodWorkflow( + req.scope + ).run({ + input: { + return_id: claim.return_id, + action_id, + }, + }) + + const queryObject = remoteQueryObjectFromString({ + entryPoint: "claim", + variables: { + id, + filters: { + ...req.filterableFields, + }, + }, + fields: req.remoteQueryConfig.fields, + }) + const [orderClaim] = await remoteQuery(queryObject) + + res.json({ + order_preview: orderPreview, + claim: orderClaim, + }) +} diff --git a/packages/medusa/src/api/admin/claims/[id]/inbound/shipping-method/route.ts b/packages/medusa/src/api/admin/claims/[id]/inbound/shipping-method/route.ts new file mode 100644 index 0000000000..304d4661f9 --- /dev/null +++ b/packages/medusa/src/api/admin/claims/[id]/inbound/shipping-method/route.ts @@ -0,0 +1,56 @@ +import { createClaimShippingMethodWorkflow } from "@medusajs/core-flows" +import { + ContainerRegistrationKeys, + remoteQueryObjectFromString, +} from "@medusajs/utils" + +import { + AuthenticatedMedusaRequest, + MedusaResponse, +} from "../../../../../../types/routing" +import { AdminPostReturnsShippingReqSchemaType } from "../../../../returns/validators" + +export const POST = async ( + req: AuthenticatedMedusaRequest, + res: MedusaResponse +) => { + const { id } = req.params + + const remoteQuery = req.scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY) + + const [claim] = await remoteQuery( + remoteQueryObjectFromString({ + entryPoint: "claim", + variables: { + id, + }, + fields: ["return_id"], + }), + undefined, + { + throwIfKeyNotFound: true, + } + ) + + const { result } = await createClaimShippingMethodWorkflow(req.scope).run({ + input: { ...req.validatedBody, return_id: claim.return_id, claim_id: id }, + }) + + const queryObject = remoteQueryObjectFromString({ + entryPoint: "return", + variables: { + id, + filters: { + ...req.filterableFields, + }, + }, + fields: req.remoteQueryConfig.fields, + }) + + const [orderClaim] = await remoteQuery(queryObject) + + res.json({ + order_preview: result, + return: orderClaim, + }) +} diff --git a/packages/medusa/src/api/admin/claims/[id]/outbound/items/[action_id]/route.ts b/packages/medusa/src/api/admin/claims/[id]/outbound/items/[action_id]/route.ts new file mode 100644 index 0000000000..081d76308c --- /dev/null +++ b/packages/medusa/src/api/admin/claims/[id]/outbound/items/[action_id]/route.ts @@ -0,0 +1,83 @@ +import { + removeItemClaimActionWorkflow, + updateClaimAddItemWorkflow, +} from "@medusajs/core-flows" +import { + ContainerRegistrationKeys, + remoteQueryObjectFromString, +} from "@medusajs/utils" +import { + AuthenticatedMedusaRequest, + MedusaResponse, +} from "../../../../../../../types/routing" +import { AdminPostClaimsItemsActionReqSchemaType } from "../../../../validators" + +export const POST = async ( + req: AuthenticatedMedusaRequest, + res: MedusaResponse +) => { + const { id, action_id } = req.params + + const remoteQuery = req.scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY) + + const { result } = await updateClaimAddItemWorkflow(req.scope).run({ + input: { + data: { ...req.validatedBody }, + claim_id: id, + action_id, + }, + }) + + const queryObject = remoteQueryObjectFromString({ + entryPoint: "claim", + variables: { + id, + filters: { + ...req.filterableFields, + }, + }, + fields: req.remoteQueryConfig.fields, + }) + + const [orderClaim] = await remoteQuery(queryObject) + + res.json({ + order_preview: result, + claim: orderClaim, + }) +} + +export const DELETE = async ( + req: AuthenticatedMedusaRequest, + res: MedusaResponse +) => { + const remoteQuery = req.scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY) + + const { id, action_id } = req.params + + const { result: orderPreview } = await removeItemClaimActionWorkflow( + req.scope + ).run({ + input: { + claim_id: id, + action_id, + }, + }) + + const queryObject = remoteQueryObjectFromString({ + entryPoint: "claim", + variables: { + id, + filters: { + ...req.filterableFields, + }, + }, + fields: req.remoteQueryConfig.fields, + }) + const [orderClaim] = await remoteQuery(queryObject) + + res.json({ + order_preview: orderPreview, + claim: orderClaim, + }) +} diff --git a/packages/medusa/src/api/admin/claims/[id]/outbound/items/route.ts b/packages/medusa/src/api/admin/claims/[id]/outbound/items/route.ts new file mode 100644 index 0000000000..71be05f3b7 --- /dev/null +++ b/packages/medusa/src/api/admin/claims/[id]/outbound/items/route.ts @@ -0,0 +1,42 @@ +import { orderClaimAddNewItemWorkflow } from "@medusajs/core-flows" +import { + ContainerRegistrationKeys, + remoteQueryObjectFromString, +} from "@medusajs/utils" + +import { + AuthenticatedMedusaRequest, + MedusaResponse, +} from "../../../../../../types/routing" +import { AdminPostClaimsAddItemsReqSchemaType } from "../../../validators" + +export const POST = async ( + req: AuthenticatedMedusaRequest, + res: MedusaResponse +) => { + const { id } = req.params + + const remoteQuery = req.scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY) + + const { result } = await orderClaimAddNewItemWorkflow(req.scope).run({ + input: { ...req.validatedBody, claim_id: id }, + }) + + const queryObject = remoteQueryObjectFromString({ + entryPoint: "claim", + variables: { + id, + filters: { + ...req.filterableFields, + }, + }, + fields: req.remoteQueryConfig.fields, + }) + + const [orderClaim] = await remoteQuery(queryObject) + + res.json({ + order_preview: result, + claim: orderClaim, + }) +} diff --git a/packages/medusa/src/api/admin/claims/[id]/outbound/shipping-method/[action_id]/route.ts b/packages/medusa/src/api/admin/claims/[id]/outbound/shipping-method/[action_id]/route.ts new file mode 100644 index 0000000000..2a6f69552b --- /dev/null +++ b/packages/medusa/src/api/admin/claims/[id]/outbound/shipping-method/[action_id]/route.ts @@ -0,0 +1,83 @@ +import { + removeClaimShippingMethodWorkflow, + updateClaimShippingMethodWorkflow, +} from "@medusajs/core-flows" +import { + ContainerRegistrationKeys, + remoteQueryObjectFromString, +} from "@medusajs/utils" +import { + AuthenticatedMedusaRequest, + MedusaResponse, +} from "../../../../../../../types/routing" +import { AdminPostClaimsShippingActionReqSchemaType } from "../../../../validators" + +export const POST = async ( + req: AuthenticatedMedusaRequest, + res: MedusaResponse +) => { + const { id, action_id } = req.params + + const remoteQuery = req.scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY) + + const { result } = await updateClaimShippingMethodWorkflow(req.scope).run({ + input: { + data: { ...req.validatedBody }, + claim_id: id, + action_id, + }, + }) + + const queryObject = remoteQueryObjectFromString({ + entryPoint: "claim", + variables: { + id, + filters: { + ...req.filterableFields, + }, + }, + fields: req.remoteQueryConfig.fields, + }) + + const [orderClaim] = await remoteQuery(queryObject) + + res.json({ + order_preview: result, + claim: orderClaim, + }) +} + +export const DELETE = async ( + req: AuthenticatedMedusaRequest, + res: MedusaResponse +) => { + const remoteQuery = req.scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY) + + const { id, action_id } = req.params + + const { result: orderPreview } = await removeClaimShippingMethodWorkflow( + req.scope + ).run({ + input: { + claim_id: id, + action_id, + }, + }) + + const queryObject = remoteQueryObjectFromString({ + entryPoint: "claim", + variables: { + id, + filters: { + ...req.filterableFields, + }, + }, + fields: req.remoteQueryConfig.fields, + }) + const [orderClaim] = await remoteQuery(queryObject) + + res.json({ + order_preview: orderPreview, + claim: orderClaim, + }) +} diff --git a/packages/medusa/src/api/admin/claims/[id]/outbound/shipping-method/route.ts b/packages/medusa/src/api/admin/claims/[id]/outbound/shipping-method/route.ts new file mode 100644 index 0000000000..ed43bb226a --- /dev/null +++ b/packages/medusa/src/api/admin/claims/[id]/outbound/shipping-method/route.ts @@ -0,0 +1,41 @@ +import { createClaimShippingMethodWorkflow } from "@medusajs/core-flows" +import { + ContainerRegistrationKeys, + remoteQueryObjectFromString, +} from "@medusajs/utils" +import { + AuthenticatedMedusaRequest, + MedusaResponse, +} from "../../../../../../types/routing" +import { AdminPostClaimsShippingReqSchemaType } from "../../../validators" + +export const POST = async ( + req: AuthenticatedMedusaRequest, + res: MedusaResponse +) => { + const { id } = req.params + + const remoteQuery = req.scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY) + + const { result } = await createClaimShippingMethodWorkflow(req.scope).run({ + input: { ...req.validatedBody, claim_id: id }, + }) + + const queryObject = remoteQueryObjectFromString({ + entryPoint: "claim", + variables: { + id, + filters: { + ...req.filterableFields, + }, + }, + fields: req.remoteQueryConfig.fields, + }) + + const [orderClaim] = await remoteQuery(queryObject) + + res.json({ + order_preview: result, + claim: orderClaim, + }) +} diff --git a/packages/medusa/src/api/admin/claims/middlewares.ts b/packages/medusa/src/api/admin/claims/middlewares.ts new file mode 100644 index 0000000000..fd52d05775 --- /dev/null +++ b/packages/medusa/src/api/admin/claims/middlewares.ts @@ -0,0 +1,229 @@ +import { MiddlewareRoute } from "../../../loaders/helpers/routing/types" +import { validateAndTransformBody } from "../../utils/validate-body" +import { validateAndTransformQuery } from "../../utils/validate-query" +import * as QueryConfig from "./query-config" +import { + AdminGetOrdersOrderParams, + AdminGetOrdersParams, + AdminPostClaimsAddItemsReqSchema, + AdminPostClaimsConfirmRequestReqSchema, + AdminPostClaimsRequestItemsActionReqSchema, + AdminPostClaimsRequestReturnItemsReqSchema, + AdminPostClaimsShippingActionReqSchema, + AdminPostClaimsShippingReqSchema, + AdminPostOrderClaimsReqSchema, +} from "./validators" + +export const adminClaimRoutesMiddlewares: MiddlewareRoute[] = [ + { + method: ["GET"], + matcher: "/admin/claims", + middlewares: [ + validateAndTransformQuery( + AdminGetOrdersParams, + QueryConfig.listTransformQueryConfig + ), + ], + }, + { + method: ["GET"], + matcher: "/admin/claims/:id", + middlewares: [ + validateAndTransformQuery( + AdminGetOrdersOrderParams, + QueryConfig.retrieveTransformQueryConfig + ), + ], + }, + { + method: ["POST"], + matcher: "/admin/claims", + middlewares: [ + validateAndTransformBody(AdminPostOrderClaimsReqSchema), + validateAndTransformQuery( + AdminGetOrdersOrderParams, + QueryConfig.retrieveTransformQueryConfig + ), + ], + }, + + { + method: ["POST"], + matcher: "/admin/claims/:id/claim-items", + middlewares: [ + validateAndTransformBody(AdminPostClaimsRequestReturnItemsReqSchema), + validateAndTransformQuery( + AdminGetOrdersOrderParams, + QueryConfig.retrieveTransformQueryConfig + ), + ], + }, + { + method: ["POST"], + matcher: "/admin/claims/:id/claim-items/:action_id", + middlewares: [ + validateAndTransformBody(AdminPostClaimsRequestItemsActionReqSchema), + validateAndTransformQuery( + AdminGetOrdersOrderParams, + QueryConfig.retrieveTransformQueryConfig + ), + ], + }, + { + method: ["DELETE"], + matcher: "/admin/claims/:id/claim-items/:action_id", + middlewares: [ + validateAndTransformQuery( + AdminGetOrdersOrderParams, + QueryConfig.retrieveTransformQueryConfig + ), + ], + }, + + { + method: ["POST"], + matcher: "/admin/claims/:id/inbound/items", + middlewares: [ + validateAndTransformBody(AdminPostClaimsRequestReturnItemsReqSchema), + validateAndTransformQuery( + AdminGetOrdersOrderParams, + QueryConfig.retrieveTransformQueryConfig + ), + ], + }, + { + method: ["POST"], + matcher: "/admin/claims/:id/inbound/items/:action_id", + middlewares: [ + validateAndTransformBody(AdminPostClaimsRequestItemsActionReqSchema), + validateAndTransformQuery( + AdminGetOrdersOrderParams, + QueryConfig.retrieveTransformQueryConfig + ), + ], + }, + { + method: ["DELETE"], + matcher: "/admin/claims/:id/inbound/items/:action_id", + middlewares: [ + validateAndTransformQuery( + AdminGetOrdersOrderParams, + QueryConfig.retrieveTransformQueryConfig + ), + ], + }, + { + method: ["POST"], + matcher: "/admin/claims/:id/inbound/shipping-method", + middlewares: [ + validateAndTransformBody(AdminPostClaimsShippingReqSchema), + validateAndTransformQuery( + AdminGetOrdersOrderParams, + QueryConfig.retrieveTransformQueryConfig + ), + ], + }, + { + method: ["POST"], + matcher: "/admin/claims/:id/inbound/shipping-method/:action_id", + middlewares: [ + validateAndTransformBody(AdminPostClaimsShippingActionReqSchema), + validateAndTransformQuery( + AdminGetOrdersOrderParams, + QueryConfig.retrieveTransformQueryConfig + ), + ], + }, + { + method: ["DELETE"], + matcher: "/admin/claims/:id/inbound/shipping-method/:action_id", + middlewares: [ + validateAndTransformQuery( + AdminGetOrdersOrderParams, + QueryConfig.retrieveTransformQueryConfig + ), + ], + }, + + { + method: ["POST"], + matcher: "/admin/claims/:id/outbound/items", + middlewares: [ + validateAndTransformBody(AdminPostClaimsAddItemsReqSchema), + validateAndTransformQuery( + AdminGetOrdersOrderParams, + QueryConfig.retrieveTransformQueryConfig + ), + ], + }, + { + method: ["POST"], + matcher: "/admin/claims/:id/outbound/items/:action_id", + middlewares: [ + validateAndTransformBody(AdminPostClaimsRequestItemsActionReqSchema), + validateAndTransformQuery( + AdminGetOrdersOrderParams, + QueryConfig.retrieveTransformQueryConfig + ), + ], + }, + { + method: ["DELETE"], + matcher: "/admin/claims/:id/outbound/items/:action_id", + middlewares: [ + validateAndTransformQuery( + AdminGetOrdersOrderParams, + QueryConfig.retrieveTransformQueryConfig + ), + ], + }, + { + method: ["POST"], + matcher: "/admin/claims/:id/outbound/shipping-method", + middlewares: [ + validateAndTransformBody(AdminPostClaimsShippingReqSchema), + validateAndTransformQuery( + AdminGetOrdersOrderParams, + QueryConfig.retrieveTransformQueryConfig + ), + ], + }, + { + method: ["POST"], + matcher: "/admin/claims/:id/outbound/shipping-method/:action_id", + middlewares: [ + validateAndTransformBody(AdminPostClaimsShippingActionReqSchema), + validateAndTransformQuery( + AdminGetOrdersOrderParams, + QueryConfig.retrieveTransformQueryConfig + ), + ], + }, + { + method: ["DELETE"], + matcher: "/admin/claims/:id/outbound/shipping-method/:action_id", + middlewares: [ + validateAndTransformQuery( + AdminGetOrdersOrderParams, + QueryConfig.retrieveTransformQueryConfig + ), + ], + }, + + { + method: ["POST"], + matcher: "/admin/claims/:id/request", + middlewares: [ + validateAndTransformBody(AdminPostClaimsConfirmRequestReqSchema), + validateAndTransformQuery( + AdminGetOrdersOrderParams, + QueryConfig.retrieveTransformQueryConfig + ), + ], + }, + { + method: ["DELETE"], + matcher: "/admin/claims/:id/request", + middlewares: [], + }, +] diff --git a/packages/medusa/src/api/admin/claims/query-config.ts b/packages/medusa/src/api/admin/claims/query-config.ts new file mode 100644 index 0000000000..406f95c5c0 --- /dev/null +++ b/packages/medusa/src/api/admin/claims/query-config.ts @@ -0,0 +1,31 @@ +export const defaultAdminClaimFields = [ + "id", + "type", + "order_id", + "exchange_id", + "claim_id", + "display_id", + "location_id", + "order_version", + "status", + "refund_amount", + "created_at", + "updated_at", +] + +export const defaultAdminDetailsClaimFields = [ + ...defaultAdminClaimFields, + "items.*", + "items.reason.*", +] + +export const retrieveTransformQueryConfig = { + defaultFields: defaultAdminDetailsClaimFields, + isList: false, +} + +export const listTransformQueryConfig = { + defaults: defaultAdminClaimFields, + defaultLimit: 20, + isList: true, +} diff --git a/packages/medusa/src/api/admin/claims/route.ts b/packages/medusa/src/api/admin/claims/route.ts new file mode 100644 index 0000000000..91290671cd --- /dev/null +++ b/packages/medusa/src/api/admin/claims/route.ts @@ -0,0 +1,74 @@ +import { beginClaimOrderWorkflow } from "@medusajs/core-flows" +import { + ContainerRegistrationKeys, + ModuleRegistrationName, + promiseAll, + remoteQueryObjectFromString, +} from "@medusajs/utils" +import { + AuthenticatedMedusaRequest, + MedusaResponse, +} from "../../../types/routing" +import { AdminPostOrderClaimsReqSchemaType } from "./validators" + +export const GET = async ( + req: AuthenticatedMedusaRequest, + res: MedusaResponse +) => { + const remoteQuery = req.scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY) + + const queryObject = remoteQueryObjectFromString({ + entryPoint: "claims", + variables: { + filters: { + ...req.filterableFields, + }, + ...req.remoteQueryConfig.pagination, + }, + fields: req.remoteQueryConfig.fields, + }) + + const { rows: claims, metadata } = await remoteQuery(queryObject) + + res.json({ + claims, + count: metadata.count, + offset: metadata.skip, + limit: metadata.take, + }) +} + +export const POST = async ( + req: AuthenticatedMedusaRequest, + res: MedusaResponse +) => { + const input = req.validatedBody as AdminPostOrderClaimsReqSchemaType + const remoteQuery = req.scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY) + const orderModuleService = req.scope.resolve(ModuleRegistrationName.ORDER) + + const workflow = beginClaimOrderWorkflow(req.scope) + const { result } = await workflow.run({ + input, + }) + + const queryObject = remoteQueryObjectFromString({ + entryPoint: "claim", + variables: { + id: result.claim_id, + filters: { + ...req.filterableFields, + }, + }, + fields: req.remoteQueryConfig.fields, + }) + + const [order, orderClaim] = await promiseAll([ + orderModuleService.retrieveOrder(result.order_id), + remoteQuery(queryObject), + ]) + + res.json({ + order, + claim: orderClaim[0], + }) +} diff --git a/packages/medusa/src/api/admin/claims/validators.ts b/packages/medusa/src/api/admin/claims/validators.ts new file mode 100644 index 0000000000..66e5c9103b --- /dev/null +++ b/packages/medusa/src/api/admin/claims/validators.ts @@ -0,0 +1,199 @@ +import { ClaimType } from "@medusajs/utils" +import { z } from "zod" +import { + createFindParams, + createOperatorMap, + createSelectParams, +} from "../../utils/validators" + +export const AdminGetOrdersOrderParams = createSelectParams().merge( + z.object({ + id: z.union([z.string(), z.array(z.string())]).optional(), + status: z.union([z.string(), z.array(z.string())]).optional(), + created_at: createOperatorMap().optional(), + updated_at: createOperatorMap().optional(), + deleted_at: createOperatorMap().optional(), + }) +) + +export type AdminGetOrdersOrderParamsType = z.infer< + typeof AdminGetOrdersOrderParams +> + +/** + * Parameters used to filter and configure the pagination of the retrieved order. + */ +export const AdminGetOrdersParams = createFindParams({ + limit: 15, + offset: 0, +}).merge( + z.object({ + id: z.union([z.string(), z.array(z.string())]).optional(), + order_id: z.union([z.string(), z.array(z.string())]).optional(), + status: z.union([z.string(), z.array(z.string())]).optional(), + created_at: createOperatorMap().optional(), + updated_at: createOperatorMap().optional(), + deleted_at: createOperatorMap().optional(), + }) +) + +export type AdminGetOrdersParamsType = z.infer + +export const AdminPostOrderClaimsReqSchema = z.object({ + type: z.nativeEnum(ClaimType), + order_id: z.string(), + description: z.string().optional(), + internal_note: z.string().optional(), + metadata: z.record(z.unknown()).nullish(), +}) +export type AdminPostOrderClaimsReqSchemaType = z.infer< + typeof AdminPostOrderClaimsReqSchema +> + +export const AdminPostOrderExchangesReqSchema = z.object({ + order_id: z.string(), + description: z.string().optional(), + internal_note: z.string().optional(), + metadata: z.record(z.unknown()).nullish(), +}) +export type AdminPostOrderExchangesReqSchemaType = z.infer< + typeof AdminPostOrderExchangesReqSchema +> + +export const AdminPostReceiveClaimsReqSchema = z.object({ + internal_note: z.string().optional(), + description: z.string().optional(), + metadata: z.record(z.unknown()).nullish(), +}) +export type AdminPostReceiveClaimsReqSchemaType = z.infer< + typeof AdminPostReceiveClaimsReqSchema +> + +const ReceiveItemSchema = z.object({ + id: z.string(), + quantity: z.number().min(1), + internal_note: z.string().optional(), +}) +export const AdminPostReceiveClaimItemsReqSchema = z.object({ + items: z.array(ReceiveItemSchema), +}) +export type AdminPostReceiveClaimItemsReqSchemaType = z.infer< + typeof AdminPostReceiveClaimItemsReqSchema +> + +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 +> + +export const AdminPostClaimsShippingReqSchema = z.object({ + shipping_option_id: z.string(), + custom_price: z.number().optional(), + description: z.string().optional(), + internal_note: z.string().optional(), + metadata: z.record(z.unknown()).optional(), +}) + +export type AdminPostClaimsShippingReqSchemaType = z.infer< + typeof AdminPostClaimsShippingReqSchema +> + +export const AdminPostClaimsShippingActionReqSchema = z.object({ + custom_price: z.number().optional(), + internal_note: z.string().nullish().optional(), + metadata: z.record(z.unknown()).nullish().optional(), +}) + +export type AdminPostClaimsShippingActionReqSchemaType = z.infer< + typeof AdminPostClaimsShippingActionReqSchema +> + +export const AdminPostClaimsAddItemsReqSchema = z.object({ + items: z.array( + z.object({ + variant_id: z.string(), + quantity: z.number(), + unit_price: z.number().optional(), + internal_note: z.string().optional(), + metadata: z.record(z.unknown()).optional(), + }) + ), +}) + +export type AdminPostClaimsAddItemsReqSchemaType = z.infer< + typeof AdminPostClaimsAddItemsReqSchema +> + +export const AdminPostClaimsRequestReturnItemsReqSchema = z.object({ + items: z.array( + z.object({ + id: z.string(), + quantity: z.number(), + description: z.string().optional(), + internal_note: z.string().optional(), + reason_id: z.string().optional(), + metadata: z.record(z.unknown()).optional(), + }) + ), +}) + +export type AdminPostClaimsRequestReturnItemsReqSchemaType = z.infer< + typeof AdminPostClaimsRequestReturnItemsReqSchema +> + +export const AdminPostClaimItemsReqSchema = z.object({ + items: z.array( + z.object({ + id: z.string(), + quantity: z.number(), + description: z.string().optional(), + internal_note: z.string().optional(), + metadata: z.record(z.unknown()).optional(), + }) + ), +}) + +export type AdminPostClaimItemsReqSchemaType = z.infer< + typeof AdminPostClaimItemsReqSchema +> + +export const AdminPostClaimsRequestItemsActionReqSchema = z.object({ + quantity: z.number().optional(), + internal_note: z.string().nullish().optional(), + reason_id: z.string().nullish().optional(), + metadata: z.record(z.unknown()).nullish().optional(), +}) + +export type AdminPostClaimsRequestItemsActionReqSchemaType = z.infer< + typeof AdminPostClaimsRequestItemsActionReqSchema +> + +export const AdminPostClaimsItemsActionReqSchema = z.object({ + quantity: z.number().optional(), + internal_note: z.string().nullish().optional(), +}) + +export type AdminPostClaimsItemsActionReqSchemaType = z.infer< + typeof AdminPostClaimsItemsActionReqSchema +> + +export const AdminPostClaimsDismissItemsActionReqSchema = z.object({ + quantity: z.number().optional(), + internal_note: z.string().nullish().optional(), +}) + +export type AdminPostClaimsDismissItemsActionReqSchemaType = z.infer< + typeof AdminPostClaimsDismissItemsActionReqSchema +> + +export const AdminPostClaimsConfirmRequestReqSchema = z.object({ + no_notification: z.boolean().optional(), +}) + +export type AdminPostClaimsConfirmRequestReqSchemaType = z.infer< + typeof AdminPostClaimsConfirmRequestReqSchema +> diff --git a/packages/medusa/src/api/admin/returns/validators.ts b/packages/medusa/src/api/admin/returns/validators.ts index d3e46283b1..84724bab8c 100644 --- a/packages/medusa/src/api/admin/returns/validators.ts +++ b/packages/medusa/src/api/admin/returns/validators.ts @@ -1,4 +1,3 @@ -import { ClaimType } from "@medusajs/utils" import { z } from "zod" import { createFindParams, @@ -51,17 +50,6 @@ export type AdminPostReturnsReqSchemaType = z.infer< typeof AdminPostReturnsReqSchema > -export const AdminPostOrderClaimsReqSchema = z.object({ - type: z.nativeEnum(ClaimType), - order_id: z.string(), - description: z.string().optional(), - internal_note: z.string().optional(), - metadata: z.record(z.unknown()).nullish(), -}) -export type AdminPostOrderClaimsReqSchemaType = z.infer< - typeof AdminPostOrderClaimsReqSchema -> - export const AdminPostOrderExchangesReqSchema = z.object({ order_id: z.string(), description: z.string().optional(), diff --git a/packages/modules/order/src/utils/transform-order.ts b/packages/modules/order/src/utils/transform-order.ts index 0fded4dba7..687114ea53 100644 --- a/packages/modules/order/src/utils/transform-order.ts +++ b/packages/modules/order/src/utils/transform-order.ts @@ -1,4 +1,3 @@ -import { OrderTypes } from "@medusajs/types" import { createRawPropertiesFromBigNumber, decorateCartTotals, @@ -9,13 +8,13 @@ import { // Reshape the order object to match the OrderDTO // This function is used to format the order object before returning to the main module methods -export function formatOrder( +export function formatOrder( order, options: { entity: any includeTotals?: boolean } -): Partial | Partial[] { +): T { const isArray = Array.isArray(order) const orders = [...(isArray ? order : [order])]