diff --git a/integration-tests/http/__tests__/exchanges/exchanges.spec.ts b/integration-tests/http/__tests__/exchanges/exchanges.spec.ts new file mode 100644 index 0000000000..b47f9eef08 --- /dev/null +++ b/integration-tests/http/__tests__/exchanges/exchanges.spec.ts @@ -0,0 +1,517 @@ +import { + ContainerRegistrationKeys, + ModuleRegistrationName, + Modules, + RuleOperator, +} from "@medusajs/utils" +import { medusaIntegrationTestRunner } from "medusa-test-utils" +import { + adminHeaders, + createAdminUser, +} from "../../../helpers/create-admin-user" + +jest.setTimeout(30000) + +medusaIntegrationTestRunner({ + testSuite: ({ dbConnection, getContainer, api }) => { + let order, order2 + let returnShippingOption + let shippingProfile + let fulfillmentSet + let returnReason + let inventoryItem + let inventoryItemExtra + let location + let productExtra + const shippingProviderId = "manual_test-provider" + + beforeEach(async () => { + const container = getContainer() + await createAdminUser(dbConnection, adminHeaders, container) + + const region = ( + await api.post( + "/admin/regions", + { + name: "test-region", + currency_code: "usd", + }, + adminHeaders + ) + ).data.region + + const customer = ( + await api.post( + "/admin/customers", + { + first_name: "joe", + email: "joe@admin.com", + }, + adminHeaders + ) + ).data.customer + + const salesChannel = ( + await api.post( + "/admin/sales-channels", + { + name: "Test channel", + }, + adminHeaders + ) + ).data.sales_channel + + const product = ( + await api.post( + "/admin/products", + { + title: "Test product", + variants: [ + { + title: "Test variant", + sku: "test-variant", + prices: [ + { + currency_code: "usd", + amount: 10, + }, + ], + }, + ], + }, + adminHeaders + ) + ).data.product + + productExtra = ( + await api.post( + "/admin/products", + { + title: "Extra product", + variants: [ + { + title: "my variant", + sku: "variant-sku", + prices: [ + { + currency_code: "usd", + amount: 123456.1234657890123456789, + }, + ], + }, + ], + }, + adminHeaders + ) + ).data.product + + returnReason = ( + await api.post( + "/admin/return-reasons", + { + value: "return-reason-test", + label: "Test return reason", + }, + adminHeaders + ) + ).data.return_reason + + const orderModule = container.resolve(ModuleRegistrationName.ORDER) + + order = await orderModule.createOrders({ + region_id: region.id, + email: "foo@bar.com", + items: [ + { + title: "Custom Item 2", + variant_id: product.variants[0].id, + quantity: 2, + unit_price: 25, + }, + ], + sales_channel_id: salesChannel.id, + shipping_address: { + first_name: "Test", + last_name: "Test", + address_1: "Test", + city: "Test", + country_code: "US", + postal_code: "12345", + phone: "12345", + }, + billing_address: { + first_name: "Test", + last_name: "Test", + address_1: "Test", + city: "Test", + country_code: "US", + postal_code: "12345", + }, + shipping_methods: [ + { + name: "Test shipping method", + amount: 10, + data: {}, + tax_lines: [ + { + description: "shipping Tax 1", + tax_rate_id: "tax_usa_shipping", + code: "code", + rate: 10, + }, + ], + }, + ], + currency_code: "usd", + customer_id: customer.id, + }) + + order2 = await orderModule.createOrders({ + region_id: region.id, + email: "foo@bar2.com", + items: [ + { + title: "Custom Iasdasd2", + quantity: 1, + unit_price: 20, + }, + ], + sales_channel_id: salesChannel.id, + shipping_address: { + first_name: "Test", + last_name: "Test", + address_1: "Test", + city: "Test", + country_code: "US", + postal_code: "12345", + phone: "12345", + }, + billing_address: { + first_name: "Test", + last_name: "Test", + address_1: "Test", + city: "Test", + country_code: "US", + postal_code: "12345", + }, + currency_code: "usd", + customer_id: customer.id, + }) + + shippingProfile = ( + await api.post( + `/admin/shipping-profiles`, + { + name: "Test", + type: "default", + }, + adminHeaders + ) + ).data.shipping_profile + + location = ( + await api.post( + `/admin/stock-locations`, + { + name: "Test location", + }, + adminHeaders + ) + ).data.stock_location + + location = ( + await api.post( + `/admin/stock-locations/${location.id}/fulfillment-sets?fields=*fulfillment_sets`, + { + name: "Test", + type: "test-type", + }, + adminHeaders + ) + ).data.stock_location + + fulfillmentSet = ( + await api.post( + `/admin/fulfillment-sets/${location.fulfillment_sets[0].id}/service-zones`, + { + name: "Test", + geo_zones: [{ type: "country", country_code: "us" }], + }, + adminHeaders + ) + ).data.fulfillment_set + + inventoryItem = ( + await api.post( + `/admin/inventory-items`, + { sku: "inv-1234" }, + adminHeaders + ) + ).data.inventory_item + + await api.post( + `/admin/inventory-items/${inventoryItem.id}/location-levels`, + { + location_id: location.id, + stocked_quantity: 2, + }, + adminHeaders + ) + + inventoryItemExtra = ( + await api.get(`/admin/inventory-items?sku=variant-sku`, adminHeaders) + ).data.inventory_items[0] + + await api.post( + `/admin/inventory-items/${inventoryItemExtra.id}/location-levels`, + { + location_id: location.id, + stocked_quantity: 4, + }, + adminHeaders + ) + + const remoteLink = container.resolve( + ContainerRegistrationKeys.REMOTE_LINK + ) + + await remoteLink.create([ + { + [Modules.STOCK_LOCATION]: { + stock_location_id: location.id, + }, + [Modules.FULFILLMENT]: { + fulfillment_provider_id: shippingProviderId, + }, + }, + { + [Modules.STOCK_LOCATION]: { + stock_location_id: location.id, + }, + [Modules.FULFILLMENT]: { + fulfillment_set_id: fulfillmentSet.id, + }, + }, + { + [Modules.SALES_CHANNEL]: { + sales_channel_id: salesChannel.id, + }, + [Modules.STOCK_LOCATION]: { + stock_location_id: location.id, + }, + }, + { + [Modules.PRODUCT]: { + variant_id: product.variants[0].id, + }, + [Modules.INVENTORY]: { + inventory_item_id: inventoryItem.id, + }, + }, + { + [Modules.PRODUCT]: { + variant_id: productExtra.variants[0].id, + }, + [Modules.INVENTORY]: { + inventory_item_id: inventoryItemExtra.id, + }, + }, + ]) + + const shippingOptionPayload = { + name: "Return shipping", + service_zone_id: fulfillmentSet.service_zones[0].id, + shipping_profile_id: shippingProfile.id, + provider_id: shippingProviderId, + price_type: "flat", + type: { + label: "Test type", + description: "Test description", + code: "test-code", + }, + prices: [ + { + currency_code: "usd", + amount: 1000, + }, + ], + rules: [ + { + operator: RuleOperator.EQ, + attribute: "is_return", + value: "true", + }, + ], + } + + returnShippingOption = ( + await api.post( + "/admin/shipping-options", + shippingOptionPayload, + adminHeaders + ) + ).data.shipping_option + + const item = order.items[0] + + await api.post( + `/admin/orders/${order.id}/fulfillments`, + { + items: [ + { + id: item.id, + quantity: 2, + }, + ], + }, + adminHeaders + ) + + await api.post( + `/admin/orders/${order2.id}/fulfillments`, + { + items: [ + { + id: order2.items[0].id, + quantity: 1, + }, + ], + }, + adminHeaders + ) + }) + + describe("Exchanges lifecycle", () => { + it("Full flow with 2 orders", async () => { + let result = await api.post( + "/admin/exchanges", + { + order_id: order.id, + description: "Test", + }, + adminHeaders + ) + + const exchangeId = result.data.exchange.id + + let r2 = await api.post( + "/admin/exchanges", + { + order_id: order2.id, + }, + adminHeaders + ) + + const exchangeId2 = r2.data.exchange.id + const item2 = order2.items[0] + + result = await api.post( + `/admin/exchanges/${exchangeId2}/inbound/items`, + { + items: [ + { + id: item2.id, + quantity: 1, + }, + ], + }, + adminHeaders + ) + + await api.post( + `/admin/exchanges/${exchangeId2}/inbound/shipping-method`, + { + shipping_option_id: returnShippingOption.id, + }, + adminHeaders + ) + await api.post( + `/admin/exchanges/${exchangeId2}/request`, + {}, + adminHeaders + ) + + const item = order.items[0] + + result = await api.post( + `/admin/exchanges/${exchangeId}/inbound/items`, + { + items: [ + { + id: item.id, + reason_id: returnReason.id, + quantity: 2, + }, + ], + }, + adminHeaders + ) + + await api.post( + `/admin/exchanges/${exchangeId}/inbound/shipping-method`, + { + shipping_option_id: returnShippingOption.id, + }, + adminHeaders + ) + + // updated the requested quantity + const updateReturnItemActionId = + result.data.order_preview.items[0].actions[0].id + + result = await api.post( + `/admin/exchanges/${exchangeId}/inbound/items/${updateReturnItemActionId}`, + { + quantity: 1, + }, + adminHeaders + ) + + // New Items + result = await api.post( + `/admin/exchanges/${exchangeId}/outbound/items`, + { + items: [ + { + variant_id: productExtra.variants[0].id, + quantity: 2, + }, + ], + }, + adminHeaders + ) + + result = await api.post( + `/admin/exchanges/${exchangeId}/request`, + {}, + adminHeaders + ) + + result = ( + await api.get( + `/admin/exchanges?fields=*additional_items`, + adminHeaders + ) + ).data.exchanges + + expect(result).toHaveLength(2) + expect(result[0].additional_items).toHaveLength(1) + expect(result[0].canceled_at).toBeNull() + + await api.post( + `/admin/exchanges/${exchangeId}/cancel`, + {}, + adminHeaders + ) + + result = ( + await api.get( + `/admin/exchanges?fields=*additional_items`, + adminHeaders + ) + ).data.exchanges + expect(result[0].canceled_at).toBeDefined() + }) + }) + }, +}) diff --git a/packages/core/core-flows/src/order/workflows/claim/confirm-claim-request.ts b/packages/core/core-flows/src/order/workflows/claim/confirm-claim-request.ts index a804688033..1fc83306fd 100644 --- a/packages/core/core-flows/src/order/workflows/claim/confirm-claim-request.ts +++ b/packages/core/core-flows/src/order/workflows/claim/confirm-claim-request.ts @@ -57,6 +57,7 @@ function prepareFulfillmentData({ items, shippingOption, deliveryAddress, + isReturn, }: { order: OrderDTO items: any[] @@ -73,16 +74,17 @@ function prepareFulfillmentData({ } } deliveryAddress?: Record + isReturn?: boolean }) { const orderItemsMap = new Map["items"][0]>( order.items!.map((i) => [i.id, i]) ) const fulfillmentItems = items.map((i) => { - const orderItem = orderItemsMap.get(i.item_id)! + const orderItem = orderItemsMap.get(i.item_id) ?? i.item return { line_item_id: i.item_id, - quantity: i.quantity, - return_quantity: i.quantity, + quantity: !isReturn ? i.quantity : undefined, + return_quantity: isReturn ? i.quantity : undefined, title: orderItem.variant_title ?? orderItem.title, sku: orderItem.variant_sku || "", barcode: orderItem.variant_barcode || "", @@ -270,11 +272,12 @@ export const confirmClaimRequestWorkflow = createWorkflow( "id", "version", "canceled_at", - "additional_items.id", - "additional_items.title", - "additional_items.variant_title", - "additional_items.variant_sku", - "additional_items.variant_barcode", + "additional_items.item_id", + "additional_items.quantity", + "additional_items.item.title", + "additional_items.item.variant_title", + "additional_items.item.variant_sku", + "additional_items.item.variant_barcode", ], variables: { id: claimId }, list: false, @@ -345,6 +348,7 @@ export const confirmClaimRequestWorkflow = createWorkflow( order, items: order.items!, shippingOption: returnShippingOption, + isReturn: true, }, prepareFulfillmentData ) diff --git a/packages/core/core-flows/src/order/workflows/claim/remove-claim-add-item-action.ts b/packages/core/core-flows/src/order/workflows/claim/remove-claim-add-item-action.ts new file mode 100644 index 0000000000..048fb1c293 --- /dev/null +++ b/packages/core/core-flows/src/order/workflows/claim/remove-claim-add-item-action.ts @@ -0,0 +1,97 @@ +import { + OrderChangeActionDTO, + OrderChangeDTO, + OrderClaimDTO, + OrderDTO, + OrderWorkflow, +} from "@medusajs/types" +import { ChangeActionType, OrderChangeStatus } from "@medusajs/utils" +import { + WorkflowData, + WorkflowResponse, + 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-add-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.ITEM_ADD) { + throw new Error(`Action ${associatedAction.id} is not adding an item`) + } + } +) + +export const removeAddItemClaimActionWorkflowId = "remove-item-claim-add-action" +export const removeAddItemClaimActionWorkflow = createWorkflow( + removeAddItemClaimActionWorkflowId, + function ( + input: WorkflowData + ): WorkflowResponse { + const orderClaim: OrderClaimDTO = useRemoteQueryStep({ + entry_point: "order_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 new WorkflowResponse(previewOrderChangeStep(order.id)) + } +) diff --git a/packages/core/core-flows/src/order/workflows/exchange/confirm-exchange-request.ts b/packages/core/core-flows/src/order/workflows/exchange/confirm-exchange-request.ts index 5ef3fd1674..45b53ad413 100644 --- a/packages/core/core-flows/src/order/workflows/exchange/confirm-exchange-request.ts +++ b/packages/core/core-flows/src/order/workflows/exchange/confirm-exchange-request.ts @@ -52,6 +52,7 @@ function prepareFulfillmentData({ items, shippingOption, deliveryAddress, + isReturn, }: { order: OrderDTO items: any[] @@ -68,16 +69,17 @@ function prepareFulfillmentData({ } } deliveryAddress?: Record + isReturn?: boolean }) { const orderItemsMap = new Map["items"][0]>( order.items!.map((i) => [i.id, i]) ) const fulfillmentItems = items.map((i) => { - const orderItem = orderItemsMap.get(i.item_id)! + const orderItem = orderItemsMap.get(i.item_id) ?? i.item return { line_item_id: i.item_id, - quantity: i.quantity, - return_quantity: i.quantity, + quantity: !isReturn ? i.quantity : undefined, + return_quantity: isReturn ? i.quantity : undefined, title: orderItem.variant_title ?? orderItem.title, sku: orderItem.variant_sku || "", barcode: orderItem.variant_barcode || "", @@ -257,11 +259,12 @@ export const confirmExchangeRequestWorkflow = createWorkflow( "id", "version", "canceled_at", - "additional_items.id", - "additional_items.title", - "additional_items.variant_title", - "additional_items.variant_sku", - "additional_items.variant_barcode", + "additional_items.item_id", + "additional_items.quantity", + "additional_items.item.title", + "additional_items.item.variant_title", + "additional_items.item.variant_sku", + "additional_items.item.variant_barcode", ], variables: { id: exchangeId }, list: false, @@ -332,6 +335,7 @@ export const confirmExchangeRequestWorkflow = createWorkflow( order, items: order.items!, shippingOption: returnShippingOption, + isReturn: true, }, prepareFulfillmentData ) diff --git a/packages/core/core-flows/src/order/workflows/exchange/remove-exchange-item-action.ts b/packages/core/core-flows/src/order/workflows/exchange/remove-exchange-item-action.ts new file mode 100644 index 0000000000..027ef3c2b4 --- /dev/null +++ b/packages/core/core-flows/src/order/workflows/exchange/remove-exchange-item-action.ts @@ -0,0 +1,97 @@ +import { + OrderChangeActionDTO, + OrderChangeDTO, + OrderDTO, + OrderExchangeDTO, + OrderWorkflow, +} from "@medusajs/types" +import { ChangeActionType, OrderChangeStatus } from "@medusajs/utils" +import { + WorkflowData, + WorkflowResponse, + 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-exchange-action-validation", + async function ({ + order, + orderChange, + orderExchange, + input, + }: { + order: OrderDTO + orderExchange: OrderExchangeDTO + orderChange: OrderChangeDTO + input: OrderWorkflow.DeleteOrderExchangeItemActionWorkflowInput + }) { + throwIfIsCancelled(order, "Order") + throwIfIsCancelled(orderExchange, "Exchange") + throwIfOrderChangeIsNotActive({ orderChange }) + + const associatedAction = (orderChange.actions ?? []).find( + (a) => a.id === input.action_id + ) as OrderChangeActionDTO + + if (!associatedAction) { + throw new Error( + `No item exchange found for exchange ${input.exchange_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 removeItemExchangeActionWorkflowId = "remove-item-exchange-action" +export const removeItemExchangeActionWorkflow = createWorkflow( + removeItemExchangeActionWorkflowId, + function ( + input: WorkflowData + ): WorkflowResponse { + const orderExchange: OrderExchangeDTO = useRemoteQueryStep({ + entry_point: "order_exchange", + fields: ["id", "status", "order_id", "canceled_at"], + variables: { id: input.exchange_id }, + list: false, + throw_if_key_not_found: true, + }) + + const order: OrderDTO = useRemoteQueryStep({ + entry_point: "orders", + fields: ["id", "status", "canceled_at", "items.*"], + variables: { id: orderExchange.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: orderExchange.order_id, + exchange_id: orderExchange.id, + status: [OrderChangeStatus.PENDING, OrderChangeStatus.REQUESTED], + }, + }, + list: false, + }).config({ name: "order-change-query" }) + + validationStep({ order, input, orderExchange, orderChange }) + + deleteOrderChangeActionsStep({ ids: [input.action_id] }) + + return new WorkflowResponse(previewOrderChangeStep(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 577eb55c7b..448870211c 100644 --- a/packages/core/core-flows/src/order/workflows/index.ts +++ b/packages/core/core-flows/src/order/workflows/index.ts @@ -11,6 +11,7 @@ export * from "./claim/claim-item" export * from "./claim/claim-request-item-return" export * from "./claim/confirm-claim-request" export * from "./claim/create-claim-shipping-method" +export * from "./claim/remove-claim-add-item-action" export * from "./claim/remove-claim-item-action" export * from "./claim/remove-claim-shipping-method" export * from "./claim/update-claim-add-item" @@ -32,6 +33,7 @@ export * from "./exchange/confirm-exchange-request" export * from "./exchange/create-exchange-shipping-method" export * from "./exchange/exchange-add-new-item" export * from "./exchange/exchange-request-item-return" +export * from "./exchange/remove-exchange-item-action" export * from "./exchange/remove-exchange-shipping-method" export * from "./exchange/update-exchange-add-item" export * from "./exchange/update-exchange-shipping-method" 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 index 243affb4a8..1bebaad562 100644 --- 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 @@ -1,5 +1,5 @@ import { - removeItemClaimActionWorkflow, + removeAddItemClaimActionWorkflow, updateClaimAddItemWorkflow, } from "@medusajs/core-flows" import { @@ -55,7 +55,7 @@ export const DELETE = async ( const { id, action_id } = req.params - const { result: orderPreview } = await removeItemClaimActionWorkflow( + const { result: orderPreview } = await removeAddItemClaimActionWorkflow( req.scope ).run({ input: { diff --git a/packages/medusa/src/api/admin/claims/query-config.ts b/packages/medusa/src/api/admin/claims/query-config.ts index aec197399b..4d5114ac51 100644 --- a/packages/medusa/src/api/admin/claims/query-config.ts +++ b/packages/medusa/src/api/admin/claims/query-config.ts @@ -4,7 +4,6 @@ export const defaultAdminClaimFields = [ "order_id", "return_id", "display_id", - "location_id", "order_version", "refund_amount", "created_at", diff --git a/packages/medusa/src/api/admin/claims/validators.ts b/packages/medusa/src/api/admin/claims/validators.ts index e58223e177..6c89101598 100644 --- a/packages/medusa/src/api/admin/claims/validators.ts +++ b/packages/medusa/src/api/admin/claims/validators.ts @@ -143,6 +143,17 @@ export type AdminPostClaimsRequestReturnItemsReqSchemaType = z.infer< typeof AdminPostClaimsRequestReturnItemsReqSchema > +export const AdminPostClaimsRequestItemsReturnActionReqSchema = 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 AdminPostClaimsRequestItemsReturnActionReqSchemaType = z.infer< + typeof AdminPostClaimsRequestItemsReturnActionReqSchema +> + export const AdminPostClaimItemsReqSchema = z.object({ items: z.array( z.object({ diff --git a/packages/medusa/src/api/admin/exchanges/[id]/cancel/route.ts b/packages/medusa/src/api/admin/exchanges/[id]/cancel/route.ts new file mode 100644 index 0000000000..f0723af9fe --- /dev/null +++ b/packages/medusa/src/api/admin/exchanges/[id]/cancel/route.ts @@ -0,0 +1,23 @@ +import { cancelOrderExchangeWorkflow } from "@medusajs/core-flows" +import { + AuthenticatedMedusaRequest, + MedusaResponse, +} from "../../../../../types/routing" +import { AdminPostCancelExchangeReqSchemaType } from "../../validators" + +export const POST = async ( + req: AuthenticatedMedusaRequest, + res: MedusaResponse +) => { + const { id } = req.params + + const workflow = cancelOrderExchangeWorkflow(req.scope) + const { result } = await workflow.run({ + input: { + ...req.validatedBody, + exchange_id: id, + }, + }) + + res.status(200).json({ exchange: result }) +} diff --git a/packages/medusa/src/api/admin/exchanges/[id]/inbound/items/[action_id]/route.ts b/packages/medusa/src/api/admin/exchanges/[id]/inbound/items/[action_id]/route.ts new file mode 100644 index 0000000000..1e6a7bcc68 --- /dev/null +++ b/packages/medusa/src/api/admin/exchanges/[id]/inbound/items/[action_id]/route.ts @@ -0,0 +1,96 @@ +import { + removeItemReturnActionWorkflow, + updateRequestItemReturnWorkflow, +} from "@medusajs/core-flows" +import { + ContainerRegistrationKeys, + remoteQueryObjectFromString, +} from "@medusajs/utils" +import { + AuthenticatedMedusaRequest, + MedusaResponse, +} from "../../../../../../../types/routing" +import { defaultAdminDetailsReturnFields } from "../../../../../returns/query-config" +import { AdminPostExchangesRequestItemsReturnActionReqSchemaType } 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 [exchange] = await remoteQuery( + remoteQueryObjectFromString({ + entryPoint: "order_exchange", + variables: { + id, + }, + fields: ["return_id"], + }), + undefined, + { + throwIfKeyNotFound: true, + } + ) + + const { result } = await updateRequestItemReturnWorkflow(req.scope).run({ + input: { + data: { ...req.validatedBody }, + return_id: exchange.return_id, + exchange_id: exchange.id, + action_id, + }, + }) + + const queryObject = remoteQueryObjectFromString({ + entryPoint: "return", + variables: { + id: exchange.return_id, + }, + fields: defaultAdminDetailsReturnFields, + }) + + 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/exchanges/[id]/inbound/items/route.ts b/packages/medusa/src/api/admin/exchanges/[id]/inbound/items/route.ts new file mode 100644 index 0000000000..13934bc0a1 --- /dev/null +++ b/packages/medusa/src/api/admin/exchanges/[id]/inbound/items/route.ts @@ -0,0 +1,60 @@ +import { orderExchangeRequestItemReturnWorkflow } from "@medusajs/core-flows" +import { + ContainerRegistrationKeys, + remoteQueryObjectFromString, +} from "@medusajs/utils" + +import { + AuthenticatedMedusaRequest, + MedusaResponse, +} from "../../../../../../types/routing" +import { defaultAdminDetailsReturnFields } from "../../../../returns/query-config" +import { AdminPostExchangesReturnRequestItemsReqSchemaType } from "../../../validators" + +export const POST = async ( + req: AuthenticatedMedusaRequest, + res: MedusaResponse +) => { + const { id } = req.params + + const remoteQuery = req.scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY) + + const [exchange] = await remoteQuery( + remoteQueryObjectFromString({ + entryPoint: "order_exchange", + variables: { + id, + }, + fields: ["return_id"], + }), + undefined, + { + throwIfKeyNotFound: true, + } + ) + + const { result } = await orderExchangeRequestItemReturnWorkflow( + req.scope + ).run({ + input: { + ...req.validatedBody, + return_id: exchange.return_id, + exchange_id: id, + }, + }) + + const queryObject = remoteQueryObjectFromString({ + entryPoint: "return", + variables: { + id: exchange.return_id, + }, + fields: defaultAdminDetailsReturnFields, + }) + + const [orderReturn] = await remoteQuery(queryObject) + + res.json({ + order_preview: result, + return: orderReturn, + }) +} diff --git a/packages/medusa/src/api/admin/exchanges/[id]/inbound/shipping-method/[action_id]/route.ts b/packages/medusa/src/api/admin/exchanges/[id]/inbound/shipping-method/[action_id]/route.ts new file mode 100644 index 0000000000..31cca8372b --- /dev/null +++ b/packages/medusa/src/api/admin/exchanges/[id]/inbound/shipping-method/[action_id]/route.ts @@ -0,0 +1,110 @@ +import { + removeReturnShippingMethodWorkflow, + updateReturnShippingMethodWorkflow, +} from "@medusajs/core-flows" +import { + ContainerRegistrationKeys, + remoteQueryObjectFromString, +} from "@medusajs/utils" +import { + AuthenticatedMedusaRequest, + MedusaResponse, +} from "../../../../../../../types/routing" +import { defaultAdminDetailsReturnFields } from "../../../../../returns/query-config" +import { AdminPostExchangesShippingActionReqSchemaType } 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 [exchange] = await remoteQuery( + remoteQueryObjectFromString({ + entryPoint: "order_exchange", + variables: { + id, + }, + fields: ["return_id"], + }), + undefined, + { + throwIfKeyNotFound: true, + } + ) + + const { result } = await updateReturnShippingMethodWorkflow(req.scope).run({ + input: { + data: { ...req.validatedBody }, + return_id: exchange.return_id, + action_id, + }, + }) + + const queryObject = remoteQueryObjectFromString({ + entryPoint: "order_exchange", + variables: { + id, + filters: { + ...req.filterableFields, + }, + }, + fields: req.remoteQueryConfig.fields, + }) + + const [orderExchange] = await remoteQuery(queryObject) + + res.json({ + order_preview: result, + exchange: orderExchange, + }) +} + +export const DELETE = async ( + req: AuthenticatedMedusaRequest, + res: MedusaResponse +) => { + const remoteQuery = req.scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY) + + const { id, action_id } = req.params + + const [exchange] = await remoteQuery( + remoteQueryObjectFromString({ + entryPoint: "order_exchange", + variables: { + id, + }, + fields: ["return_id"], + }), + undefined, + { + throwIfKeyNotFound: true, + } + ) + + const { result: orderPreview } = await removeReturnShippingMethodWorkflow( + req.scope + ).run({ + input: { + return_id: exchange.return_id, + action_id, + }, + }) + + const queryObject = remoteQueryObjectFromString({ + entryPoint: "return", + variables: { + id: exchange.return_id, + }, + fields: defaultAdminDetailsReturnFields, + }) + + const [orderReturn] = await remoteQuery(queryObject) + + res.json({ + order_preview: orderPreview, + return: orderReturn, + }) +} diff --git a/packages/medusa/src/api/admin/exchanges/[id]/inbound/shipping-method/route.ts b/packages/medusa/src/api/admin/exchanges/[id]/inbound/shipping-method/route.ts new file mode 100644 index 0000000000..6fb23b9094 --- /dev/null +++ b/packages/medusa/src/api/admin/exchanges/[id]/inbound/shipping-method/route.ts @@ -0,0 +1,58 @@ +import { createExchangeShippingMethodWorkflow } from "@medusajs/core-flows" +import { + ContainerRegistrationKeys, + remoteQueryObjectFromString, +} from "@medusajs/utils" + +import { + AuthenticatedMedusaRequest, + MedusaResponse, +} from "../../../../../../types/routing" +import { defaultAdminDetailsReturnFields } from "../../../../returns/query-config" +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 [exchange] = await remoteQuery( + remoteQueryObjectFromString({ + entryPoint: "order_exchange", + variables: { + id, + }, + fields: ["return_id"], + }), + undefined, + { + throwIfKeyNotFound: true, + } + ) + + const { result } = await createExchangeShippingMethodWorkflow(req.scope).run({ + input: { + ...req.validatedBody, + return_id: exchange.return_id, + exchange_id: id, + }, + }) + + const queryObject = remoteQueryObjectFromString({ + entryPoint: "return", + variables: { + id: exchange.return_id, + }, + fields: defaultAdminDetailsReturnFields, + }) + + const [orderReturn] = await remoteQuery(queryObject) + + res.json({ + order_preview: result, + return: orderReturn, + }) +} diff --git a/packages/medusa/src/api/admin/exchanges/[id]/outbound/items/[action_id]/route.ts b/packages/medusa/src/api/admin/exchanges/[id]/outbound/items/[action_id]/route.ts new file mode 100644 index 0000000000..e010dbadd6 --- /dev/null +++ b/packages/medusa/src/api/admin/exchanges/[id]/outbound/items/[action_id]/route.ts @@ -0,0 +1,83 @@ +import { + removeItemExchangeActionWorkflow, + updateExchangeAddItemWorkflow, +} from "@medusajs/core-flows" +import { + ContainerRegistrationKeys, + remoteQueryObjectFromString, +} from "@medusajs/utils" +import { + AuthenticatedMedusaRequest, + MedusaResponse, +} from "../../../../../../../types/routing" +import { AdminPostExhangesItemsActionReqSchemaType } 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 updateExchangeAddItemWorkflow(req.scope).run({ + input: { + data: { ...req.validatedBody }, + exchange_id: id, + action_id, + }, + }) + + const queryObject = remoteQueryObjectFromString({ + entryPoint: "order_exchange", + variables: { + id, + filters: { + ...req.filterableFields, + }, + }, + fields: req.remoteQueryConfig.fields, + }) + + const [orderExchange] = await remoteQuery(queryObject) + + res.json({ + order_preview: result, + exchange: orderExchange, + }) +} + +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 removeItemExchangeActionWorkflow( + req.scope + ).run({ + input: { + exchange_id: id, + action_id, + }, + }) + + const queryObject = remoteQueryObjectFromString({ + entryPoint: "order_exchange", + variables: { + id, + filters: { + ...req.filterableFields, + }, + }, + fields: req.remoteQueryConfig.fields, + }) + const [orderExchange] = await remoteQuery(queryObject) + + res.json({ + order_preview: orderPreview, + exchange: orderExchange, + }) +} diff --git a/packages/medusa/src/api/admin/exchanges/[id]/outbound/items/route.ts b/packages/medusa/src/api/admin/exchanges/[id]/outbound/items/route.ts new file mode 100644 index 0000000000..25680a3856 --- /dev/null +++ b/packages/medusa/src/api/admin/exchanges/[id]/outbound/items/route.ts @@ -0,0 +1,42 @@ +import { orderExchangeAddNewItemWorkflow } from "@medusajs/core-flows" +import { + ContainerRegistrationKeys, + remoteQueryObjectFromString, +} from "@medusajs/utils" + +import { + AuthenticatedMedusaRequest, + MedusaResponse, +} from "../../../../../../types/routing" +import { AdminPostExchangesAddItemsReqSchemaType } 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 orderExchangeAddNewItemWorkflow(req.scope).run({ + input: { ...req.validatedBody, exchange_id: id }, + }) + + const queryObject = remoteQueryObjectFromString({ + entryPoint: "order_exchange", + variables: { + id, + filters: { + ...req.filterableFields, + }, + }, + fields: req.remoteQueryConfig.fields, + }) + + const [orderExchange] = await remoteQuery(queryObject) + + res.json({ + order_preview: result, + exchange: orderExchange, + }) +} diff --git a/packages/medusa/src/api/admin/exchanges/[id]/outbound/shipping-method/[action_id]/route.ts b/packages/medusa/src/api/admin/exchanges/[id]/outbound/shipping-method/[action_id]/route.ts new file mode 100644 index 0000000000..09030e29bf --- /dev/null +++ b/packages/medusa/src/api/admin/exchanges/[id]/outbound/shipping-method/[action_id]/route.ts @@ -0,0 +1,83 @@ +import { + removeExchangeShippingMethodWorkflow, + updateExchangeShippingMethodWorkflow, +} from "@medusajs/core-flows" +import { + ContainerRegistrationKeys, + remoteQueryObjectFromString, +} from "@medusajs/utils" +import { + AuthenticatedMedusaRequest, + MedusaResponse, +} from "../../../../../../../types/routing" +import { AdminPostExchangesShippingActionReqSchemaType } 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 updateExchangeShippingMethodWorkflow(req.scope).run({ + input: { + data: { ...req.validatedBody }, + exchange_id: id, + action_id, + }, + }) + + const queryObject = remoteQueryObjectFromString({ + entryPoint: "order_exchange", + variables: { + id, + filters: { + ...req.filterableFields, + }, + }, + fields: req.remoteQueryConfig.fields, + }) + + const [orderExchange] = await remoteQuery(queryObject) + + res.json({ + order_preview: result, + exchange: orderExchange, + }) +} + +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 removeExchangeShippingMethodWorkflow( + req.scope + ).run({ + input: { + exchange_id: id, + action_id, + }, + }) + + const queryObject = remoteQueryObjectFromString({ + entryPoint: "order_exchange", + variables: { + id, + filters: { + ...req.filterableFields, + }, + }, + fields: req.remoteQueryConfig.fields, + }) + const [orderExchange] = await remoteQuery(queryObject) + + res.json({ + order_preview: orderPreview, + exchange: orderExchange, + }) +} diff --git a/packages/medusa/src/api/admin/exchanges/[id]/outbound/shipping-method/route.ts b/packages/medusa/src/api/admin/exchanges/[id]/outbound/shipping-method/route.ts new file mode 100644 index 0000000000..39e53f86a8 --- /dev/null +++ b/packages/medusa/src/api/admin/exchanges/[id]/outbound/shipping-method/route.ts @@ -0,0 +1,41 @@ +import { createExchangeShippingMethodWorkflow } from "@medusajs/core-flows" +import { + ContainerRegistrationKeys, + remoteQueryObjectFromString, +} from "@medusajs/utils" +import { + AuthenticatedMedusaRequest, + MedusaResponse, +} from "../../../../../../types/routing" +import { AdminPostExchangesShippingReqSchemaType } 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 createExchangeShippingMethodWorkflow(req.scope).run({ + input: { ...req.validatedBody, exchange_id: id }, + }) + + const queryObject = remoteQueryObjectFromString({ + entryPoint: "order_exchange", + variables: { + id, + filters: { + ...req.filterableFields, + }, + }, + fields: req.remoteQueryConfig.fields, + }) + + const [orderExchange] = await remoteQuery(queryObject) + + res.json({ + order_preview: result, + exchange: orderExchange, + }) +} diff --git a/packages/medusa/src/api/admin/exchanges/[id]/request/route.ts b/packages/medusa/src/api/admin/exchanges/[id]/request/route.ts new file mode 100644 index 0000000000..155b6acf6e --- /dev/null +++ b/packages/medusa/src/api/admin/exchanges/[id]/request/route.ts @@ -0,0 +1,80 @@ +import { + cancelBeginOrderExchangeWorkflow, + confirmExchangeRequestWorkflow, +} from "@medusajs/core-flows" +import { + ContainerRegistrationKeys, + remoteQueryObjectFromString, +} from "@medusajs/utils" +import { + AuthenticatedMedusaRequest, + MedusaResponse, +} from "../../../../../types/routing" +import { defaultAdminDetailsReturnFields } from "../../../returns/query-config" + +export const POST = async ( + req: AuthenticatedMedusaRequest, + res: MedusaResponse +) => { + const { id } = req.params + + const remoteQuery = req.scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY) + + const { result } = await confirmExchangeRequestWorkflow(req.scope).run({ + input: { exchange_id: id }, + }) + + const queryObject = remoteQueryObjectFromString({ + entryPoint: "order_exchange", + variables: { + id, + filters: { + ...req.filterableFields, + }, + }, + fields: req.remoteQueryConfig.fields, + }) + + const [orderExchange] = await remoteQuery(queryObject, undefined, { + throwIfKeyNotFound: true, + }) + + let orderReturn + if (orderExchange.return_id) { + const [orderReturnData] = await remoteQuery( + remoteQueryObjectFromString({ + entryPoint: "return", + variables: { + id: orderExchange.return_id, + }, + fields: defaultAdminDetailsReturnFields, + }) + ) + orderReturn = orderReturnData + } + + res.json({ + order_preview: result, + exchange: orderExchange, + return: orderReturn, + }) +} + +export const DELETE = async ( + req: AuthenticatedMedusaRequest, + res: MedusaResponse +) => { + const { id } = req.params + + await cancelBeginOrderExchangeWorkflow(req.scope).run({ + input: { + exchange_id: id, + }, + }) + + res.status(200).json({ + id, + object: "exchange", + deleted: true, + }) +} diff --git a/packages/medusa/src/api/admin/exchanges/middlewares.ts b/packages/medusa/src/api/admin/exchanges/middlewares.ts new file mode 100644 index 0000000000..657632ed7a --- /dev/null +++ b/packages/medusa/src/api/admin/exchanges/middlewares.ts @@ -0,0 +1,212 @@ +import { MiddlewareRoute } from "@medusajs/framework" +import { validateAndTransformBody } from "../../utils/validate-body" +import { validateAndTransformQuery } from "../../utils/validate-query" +import * as QueryConfig from "./query-config" +import { + AdminGetOrdersOrderParams, + AdminGetOrdersParams, + AdminPostCancelExchangeReqSchema, + AdminPostExchangesAddItemsReqSchema, + AdminPostExchangesRequestItemsReturnActionReqSchema, + AdminPostExchangesReturnRequestItemsReqSchema, + AdminPostExchangesShippingActionReqSchema, + AdminPostExchangesShippingReqSchema, + AdminPostExhangesItemsActionReqSchema, + AdminPostOrderExchangesReqSchema, +} from "./validators" + +export const adminExchangeRoutesMiddlewares: MiddlewareRoute[] = [ + { + method: ["GET"], + matcher: "/admin/exchanges", + middlewares: [ + validateAndTransformQuery( + AdminGetOrdersParams, + QueryConfig.listTransformQueryConfig + ), + ], + }, + { + method: ["GET"], + matcher: "/admin/exchanges/:id", + middlewares: [ + validateAndTransformQuery( + AdminGetOrdersOrderParams, + QueryConfig.retrieveTransformQueryConfig + ), + ], + }, + { + method: ["POST"], + matcher: "/admin/exchanges", + middlewares: [ + validateAndTransformBody(AdminPostOrderExchangesReqSchema), + validateAndTransformQuery( + AdminGetOrdersOrderParams, + QueryConfig.retrieveTransformQueryConfig + ), + ], + }, + { + method: ["POST"], + matcher: "/admin/exchanges/:id/inbound/items", + middlewares: [ + validateAndTransformBody(AdminPostExchangesReturnRequestItemsReqSchema), + validateAndTransformQuery( + AdminGetOrdersOrderParams, + QueryConfig.retrieveTransformQueryConfig + ), + ], + }, + { + method: ["POST"], + matcher: "/admin/exchanges/:id/inbound/items/:action_id", + middlewares: [ + validateAndTransformBody( + AdminPostExchangesRequestItemsReturnActionReqSchema + ), + validateAndTransformQuery( + AdminGetOrdersOrderParams, + QueryConfig.retrieveTransformQueryConfig + ), + ], + }, + { + method: ["DELETE"], + matcher: "/admin/exchanges/:id/inbound/items/:action_id", + middlewares: [ + validateAndTransformQuery( + AdminGetOrdersOrderParams, + QueryConfig.retrieveTransformQueryConfig + ), + ], + }, + { + method: ["POST"], + matcher: "/admin/exchanges/:id/inbound/shipping-method", + middlewares: [ + validateAndTransformBody(AdminPostExchangesShippingReqSchema), + validateAndTransformQuery( + AdminGetOrdersOrderParams, + QueryConfig.retrieveTransformQueryConfig + ), + ], + }, + { + method: ["POST"], + matcher: "/admin/exchanges/:id/inbound/shipping-method/:action_id", + middlewares: [ + validateAndTransformBody(AdminPostExchangesShippingActionReqSchema), + validateAndTransformQuery( + AdminGetOrdersOrderParams, + QueryConfig.retrieveTransformQueryConfig + ), + ], + }, + { + method: ["DELETE"], + matcher: "/admin/exchanges/:id/inbound/shipping-method/:action_id", + middlewares: [ + validateAndTransformQuery( + AdminGetOrdersOrderParams, + QueryConfig.retrieveTransformQueryConfig + ), + ], + }, + + { + method: ["POST"], + matcher: "/admin/exchanges/:id/outbound/items", + middlewares: [ + validateAndTransformBody(AdminPostExchangesAddItemsReqSchema), + validateAndTransformQuery( + AdminGetOrdersOrderParams, + QueryConfig.retrieveTransformQueryConfig + ), + ], + }, + { + method: ["POST"], + matcher: "/admin/exchanges/:id/outbound/items/:action_id", + middlewares: [ + validateAndTransformBody(AdminPostExhangesItemsActionReqSchema), + validateAndTransformQuery( + AdminGetOrdersOrderParams, + QueryConfig.retrieveTransformQueryConfig + ), + ], + }, + { + method: ["DELETE"], + matcher: "/admin/exchanges/:id/outbound/items/:action_id", + middlewares: [ + validateAndTransformQuery( + AdminGetOrdersOrderParams, + QueryConfig.retrieveTransformQueryConfig + ), + ], + }, + { + method: ["POST"], + matcher: "/admin/exchanges/:id/outbound/shipping-method", + middlewares: [ + validateAndTransformBody(AdminPostExchangesShippingReqSchema), + validateAndTransformQuery( + AdminGetOrdersOrderParams, + QueryConfig.retrieveTransformQueryConfig + ), + ], + }, + { + method: ["POST"], + matcher: "/admin/exchanges/:id/outbound/shipping-method/:action_id", + middlewares: [ + validateAndTransformBody(AdminPostExchangesShippingActionReqSchema), + validateAndTransformQuery( + AdminGetOrdersOrderParams, + QueryConfig.retrieveTransformQueryConfig + ), + ], + }, + { + method: ["DELETE"], + matcher: "/admin/exchanges/:id/outbound/shipping-method/:action_id", + middlewares: [ + validateAndTransformQuery( + AdminGetOrdersOrderParams, + QueryConfig.retrieveTransformQueryConfig + ), + ], + }, + { + method: ["POST"], + matcher: "/admin/exchanges/:id/request", + middlewares: [ + validateAndTransformQuery( + AdminGetOrdersOrderParams, + QueryConfig.retrieveTransformQueryConfig + ), + ], + }, + { + method: ["DELETE"], + matcher: "/admin/exchanges/:id/request", + middlewares: [], + }, + { + method: ["DELETE"], + matcher: "/admin/exchanges/:id", + middlewares: [], + }, + { + method: ["POST"], + matcher: "/admin/exchanges/:id/cancel", + middlewares: [ + validateAndTransformBody(AdminPostCancelExchangeReqSchema), + validateAndTransformQuery( + AdminGetOrdersOrderParams, + QueryConfig.retrieveTransformQueryConfig + ), + ], + }, +] diff --git a/packages/medusa/src/api/admin/exchanges/query-config.ts b/packages/medusa/src/api/admin/exchanges/query-config.ts new file mode 100644 index 0000000000..cc023880e8 --- /dev/null +++ b/packages/medusa/src/api/admin/exchanges/query-config.ts @@ -0,0 +1,27 @@ +export const defaultAdminExchangeFields = [ + "id", + "type", + "order_id", + "return_id", + "display_id", + "order_version", + "created_at", + "updated_at", + "canceled_at", +] + +export const defaultAdminDetailsExchangeFields = [ + ...defaultAdminExchangeFields, + "additional_items.*", +] + +export const retrieveTransformQueryConfig = { + defaultFields: defaultAdminDetailsExchangeFields, + isList: false, +} + +export const listTransformQueryConfig = { + defaults: defaultAdminExchangeFields, + defaultLimit: 20, + isList: true, +} diff --git a/packages/medusa/src/api/admin/exchanges/route.ts b/packages/medusa/src/api/admin/exchanges/route.ts new file mode 100644 index 0000000000..c45735c3ee --- /dev/null +++ b/packages/medusa/src/api/admin/exchanges/route.ts @@ -0,0 +1,74 @@ +import { beginExchangeOrderWorkflow } from "@medusajs/core-flows" +import { + ContainerRegistrationKeys, + ModuleRegistrationName, + promiseAll, + remoteQueryObjectFromString, +} from "@medusajs/utils" +import { + AuthenticatedMedusaRequest, + MedusaResponse, +} from "../../../types/routing" +import { AdminPostOrderExchangesReqSchemaType } from "./validators" + +export const GET = async ( + req: AuthenticatedMedusaRequest, + res: MedusaResponse +) => { + const remoteQuery = req.scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY) + + const queryObject = remoteQueryObjectFromString({ + entryPoint: "order_exchanges", + variables: { + filters: { + ...req.filterableFields, + }, + ...req.remoteQueryConfig.pagination, + }, + fields: req.remoteQueryConfig.fields, + }) + + const { rows: exchanges, metadata } = await remoteQuery(queryObject) + + res.json({ + exchanges, + count: metadata.count, + offset: metadata.skip, + limit: metadata.take, + }) +} + +export const POST = async ( + req: AuthenticatedMedusaRequest, + res: MedusaResponse +) => { + const input = req.validatedBody as AdminPostOrderExchangesReqSchemaType + const remoteQuery = req.scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY) + const orderModuleService = req.scope.resolve(ModuleRegistrationName.ORDER) + + const workflow = beginExchangeOrderWorkflow(req.scope) + const { result } = await workflow.run({ + input, + }) + + const queryObject = remoteQueryObjectFromString({ + entryPoint: "order_exchange", + variables: { + id: result.exchange_id, + filters: { + ...req.filterableFields, + }, + }, + fields: req.remoteQueryConfig.fields, + }) + + const [order, orderExchange] = await promiseAll([ + orderModuleService.retrieveOrder(result.order_id), + remoteQuery(queryObject), + ]) + + res.json({ + order, + exchange: orderExchange[0], + }) +} diff --git a/packages/medusa/src/api/admin/exchanges/validators.ts b/packages/medusa/src/api/admin/exchanges/validators.ts new file mode 100644 index 0000000000..4f59493356 --- /dev/null +++ b/packages/medusa/src/api/admin/exchanges/validators.ts @@ -0,0 +1,170 @@ +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 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 AdminPostReceiveExchangesReqSchema = z.object({ + internal_note: z.string().optional(), + description: z.string().optional(), + metadata: z.record(z.unknown()).nullish(), +}) +export type AdminPostReceiveExchangesReqSchemaType = z.infer< + typeof AdminPostReceiveExchangesReqSchema +> + +const ReceiveItemSchema = z.object({ + id: z.string(), + quantity: z.number().min(1), + internal_note: z.string().optional(), +}) +export const AdminPostReceiveExchangeItemsReqSchema = z.object({ + items: z.array(ReceiveItemSchema), +}) +export type AdminPostReceiveExchangeItemsReqSchemaType = z.infer< + typeof AdminPostReceiveExchangeItemsReqSchema +> + +export const AdminPostCancelExchangeReqSchema = z.object({ + no_notification: z.boolean().optional(), +}) +export type AdminPostCancelExchangeReqSchemaType = z.infer< + typeof AdminPostCancelExchangeReqSchema +> + +export const AdminPostExchangesRequestItemsReturnActionReqSchema = 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 AdminPostExchangesRequestItemsReturnActionReqSchemaType = z.infer< + typeof AdminPostExchangesRequestItemsReturnActionReqSchema +> + +export const AdminPostExchangesShippingReqSchema = 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 AdminPostExchangesShippingReqSchemaType = z.infer< + typeof AdminPostExchangesShippingReqSchema +> + +export const AdminPostExchangesShippingActionReqSchema = z.object({ + custom_price: z.number().optional(), + internal_note: z.string().nullish().optional(), + metadata: z.record(z.unknown()).nullish().optional(), +}) + +export type AdminPostExchangesShippingActionReqSchemaType = z.infer< + typeof AdminPostExchangesShippingActionReqSchema +> + +export const AdminPostExchangesAddItemsReqSchema = z.object({ + items: z.array( + z.object({ + variant_id: z.string(), + quantity: z.number(), + unit_price: z.number().optional(), + internal_note: z.string().optional(), + allow_backorder: z.boolean().optional(), + metadata: z.record(z.unknown()).optional(), + }) + ), +}) + +export type AdminPostExchangesAddItemsReqSchemaType = z.infer< + typeof AdminPostExchangesAddItemsReqSchema +> + +export const AdminPostExchangesReturnRequestItemsReqSchema = 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 AdminPostExchangesReturnRequestItemsReqSchemaType = z.infer< + typeof AdminPostExchangesReturnRequestItemsReqSchema +> + +export const AdminPostExchangesDismissItemsActionReqSchema = z.object({ + quantity: z.number().optional(), + internal_note: z.string().nullish().optional(), +}) + +export type AdminPostExchangesDismissItemsActionReqSchemaType = z.infer< + typeof AdminPostExchangesDismissItemsActionReqSchema +> + +export const AdminPostExchangesConfirmRequestReqSchema = z.object({ + no_notification: z.boolean().optional(), +}) + +export type AdminPostExchangesConfirmRequestReqSchemaType = z.infer< + typeof AdminPostExchangesConfirmRequestReqSchema +> + +export const AdminPostExhangesItemsActionReqSchema = z.object({ + quantity: z.number().optional(), + internal_note: z.string().nullish().optional(), +}) + +export type AdminPostExhangesItemsActionReqSchemaType = z.infer< + typeof AdminPostExhangesItemsActionReqSchema +> diff --git a/packages/medusa/src/api/middlewares.ts b/packages/medusa/src/api/middlewares.ts index fc597848cb..9e639d468f 100644 --- a/packages/medusa/src/api/middlewares.ts +++ b/packages/medusa/src/api/middlewares.ts @@ -7,6 +7,7 @@ import { adminCurrencyRoutesMiddlewares } from "./admin/currencies/middlewares" import { adminCustomerGroupRoutesMiddlewares } from "./admin/customer-groups/middlewares" import { adminCustomerRoutesMiddlewares } from "./admin/customers/middlewares" import { adminDraftOrderRoutesMiddlewares } from "./admin/draft-orders/middlewares" +import { adminExchangeRoutesMiddlewares } from "./admin/exchanges/middlewares" import { adminFulfillmentProvidersRoutesMiddlewares } from "./admin/fulfillment-providers/middlewares" import { adminFulfillmentSetsRoutesMiddlewares } from "./admin/fulfillment-sets/middlewares" import { adminFulfillmentsRoutesMiddlewares } from "./admin/fulfillments/middlewares" @@ -106,4 +107,5 @@ export default defineMiddlewares([ ...storeReturnReasonRoutesMiddlewares, ...adminReturnReasonRoutesMiddlewares, ...adminClaimRoutesMiddlewares, + ...adminExchangeRoutesMiddlewares, ]) diff --git a/packages/modules/order/src/services/actions/cancel-claim.ts b/packages/modules/order/src/services/actions/cancel-claim.ts index 820fedc4fa..07ba9c7c9c 100644 --- a/packages/modules/order/src/services/actions/cancel-claim.ts +++ b/packages/modules/order/src/services/actions/cancel-claim.ts @@ -43,6 +43,7 @@ export async function cancelClaim( "claim_items.is_additional_item", "claim_items.quantity", "additional_items.id", + "additional_items.item_id", "additional_items.quantity", "additional_items.is_additional_item", ], diff --git a/packages/modules/order/src/services/actions/cancel-exchange.ts b/packages/modules/order/src/services/actions/cancel-exchange.ts index ba15a7e34d..ce78c31135 100644 --- a/packages/modules/order/src/services/actions/cancel-exchange.ts +++ b/packages/modules/order/src/services/actions/cancel-exchange.ts @@ -8,16 +8,16 @@ import { ChangeActionType, promiseAll } from "@medusajs/utils" async function createOrderChange( service, data, - returnRef, + exchangeOrder, actions, sharedContext ) { return await service.createOrderChange_( { - order_id: returnRef.order_id, - exchange_id: returnRef.id, - reference: "return", - reference_id: returnRef.id, + order_id: exchangeOrder.order_id, + exchange_id: exchangeOrder.id, + reference: "exchange", + reference_id: exchangeOrder.id, description: data.description, internal_note: data.internal_note, created_by: data.created_by, @@ -33,40 +33,23 @@ export async function cancelExchange( data: OrderTypes.CancelOrderExchangeDTO, sharedContext?: Context ) { - const exchangeOrder = await this.retrieveExchange( + const exchangeOrder = await this.retrieveOrderExchange( data.exchange_id, { select: [ "id", "order_id", - "return.id", - "return.items.item_id", - "return.items.quantity", "additional_items.id", + "additional_items.item_id", "additional_items.quantity", ], - relations: ["return.items", "additional_items", "shipping_methods"], + relations: ["additional_items", "shipping_methods"], }, sharedContext ) const actions: CreateOrderChangeActionDTO[] = [] - exchangeOrder.return.items.forEach((item) => { - actions.push({ - action: ChangeActionType.CANCEL_RETURN_ITEM, - order_id: exchangeOrder.order_id, - exchange_id: exchangeOrder.id, - return_id: exchangeOrder.return.id, - reference: "return", - reference_id: exchangeOrder.return.id, - details: { - reference_id: item.item_id, - quantity: item.quantity, - }, - }) - }) - exchangeOrder.additional_items.forEach((item) => { actions.push({ action: ChangeActionType.ITEM_REMOVE, @@ -88,7 +71,6 @@ export async function cancelExchange( action: ChangeActionType.SHIPPING_REMOVE, order_id: exchangeOrder.order_id, exchange_id: exchangeOrder.id, - return_id: exchangeOrder.return.id, reference: "exchange", reference_id: shipping.id, amount: shipping.price, @@ -104,7 +86,7 @@ export async function cancelExchange( ) await promiseAll([ - this.updateExchanges( + this.updateOrderExchanges( [ { data: { diff --git a/packages/modules/order/src/services/actions/create-claim.ts b/packages/modules/order/src/services/actions/create-claim.ts index b5e8be5d80..ec76608419 100644 --- a/packages/modules/order/src/services/actions/create-claim.ts +++ b/packages/modules/order/src/services/actions/create-claim.ts @@ -125,6 +125,7 @@ async function processAdditionalItems( details: { reference_id: item.id, quantity: item.quantity, + unit_price: item.unit_price ?? hasItem.item.unit_price, metadata: item.metadata, }, }) @@ -144,6 +145,7 @@ async function processAdditionalItems( additionalNewItems.push( em.create(OrderClaimItem, { quantity: item.quantity, + unit_price: item.unit_price, note: item.note, metadata: item.metadata, is_additional_item: true, diff --git a/packages/modules/order/src/services/actions/create-exchange.ts b/packages/modules/order/src/services/actions/create-exchange.ts index fda606a0c1..39cb8477f1 100644 --- a/packages/modules/order/src/services/actions/create-exchange.ts +++ b/packages/modules/order/src/services/actions/create-exchange.ts @@ -92,6 +92,7 @@ async function processAdditionalItems( details: { reference_id: item.id, quantity: item.quantity, + unit_price: item.unit_price ?? hasItem.item.unit_price, metadata: item.metadata, }, }) @@ -111,6 +112,7 @@ async function processAdditionalItems( additionalNewItems.push( em.create(OrderExchangeItem, { quantity: item.quantity, + unit_price: item.unit_price, note: item.note, metadata: item.metadata, is_additional_item: true, diff --git a/packages/modules/order/src/services/order-module-service.ts b/packages/modules/order/src/services/order-module-service.ts index b216337656..8b97b84ad3 100644 --- a/packages/modules/order/src/services/order-module-service.ts +++ b/packages/modules/order/src/services/order-module-service.ts @@ -3206,7 +3206,7 @@ export default class OrderModuleService< const ret = await this.cancelClaim_(data, sharedContext) return await this.retrieveOrderClaim(ret.id, { - relations: ["additional_items", "claim_items"], + relations: ["additional_items", "claim_items", "return", "return.items"], }) } @@ -3266,7 +3266,7 @@ export default class OrderModuleService< const ret = await this.cancelExchange_(data, sharedContext) return await this.retrieveOrderExchange(ret.id, { - relations: ["items"], + relations: ["additional_items", "return", "return.items"], }) } diff --git a/packages/modules/order/src/utils/actions/cancel-item-fulfillment.ts b/packages/modules/order/src/utils/actions/cancel-item-fulfillment.ts index edfacfeb7b..e42280bc21 100644 --- a/packages/modules/order/src/utils/actions/cancel-item-fulfillment.ts +++ b/packages/modules/order/src/utils/actions/cancel-item-fulfillment.ts @@ -1,9 +1,4 @@ -import { - ChangeActionType, - MathBN, - MedusaError, - isDefined, -} from "@medusajs/utils" +import { ChangeActionType, MathBN, MedusaError } from "@medusajs/utils" import { OrderChangeProcessing } from "../calculate-order-change" import { setActionReference } from "../set-action-reference" @@ -26,7 +21,7 @@ OrderChangeProcessing.registerActionType( }, validate({ action, currentOrder }) { const refId = action.details?.reference_id - if (!isDefined(refId)) { + if (refId == null) { throw new MedusaError( MedusaError.Types.INVALID_DATA, "Reference ID is required." diff --git a/packages/modules/order/src/utils/actions/cancel-return.ts b/packages/modules/order/src/utils/actions/cancel-return.ts index 95c6fa5afe..ca18b074a7 100644 --- a/packages/modules/order/src/utils/actions/cancel-return.ts +++ b/packages/modules/order/src/utils/actions/cancel-return.ts @@ -1,9 +1,4 @@ -import { - ChangeActionType, - MathBN, - MedusaError, - isDefined, -} from "@medusajs/utils" +import { ChangeActionType, MathBN, MedusaError } from "@medusajs/utils" import { OrderChangeProcessing } from "../calculate-order-change" import { setActionReference } from "../set-action-reference" @@ -22,24 +17,17 @@ OrderChangeProcessing.registerActionType(ChangeActionType.CANCEL_RETURN_ITEM, { setActionReference(existing, action, options) - return action.details.unit_price * action.details.quantity + return MathBN.mult(existing.unit_price, action.details.quantity) }, validate({ action, currentOrder }) { const refId = action.details?.reference_id - if (!isDefined(refId)) { + if (refId == null) { throw new MedusaError( MedusaError.Types.INVALID_DATA, "Details reference ID is required." ) } - if (!isDefined(action.amount) && !isDefined(action.details?.unit_price)) { - throw new MedusaError( - MedusaError.Types.INVALID_DATA, - `Unit price of item ${action.reference_id} is required if no action.amount is provided.` - ) - } - const existing = currentOrder.items.find((item) => item.id === refId) if (!existing) { diff --git a/packages/modules/order/src/utils/actions/fulfill-item.ts b/packages/modules/order/src/utils/actions/fulfill-item.ts index 73bfa519d8..3b667915a3 100644 --- a/packages/modules/order/src/utils/actions/fulfill-item.ts +++ b/packages/modules/order/src/utils/actions/fulfill-item.ts @@ -1,9 +1,4 @@ -import { - ChangeActionType, - MathBN, - MedusaError, - isDefined, -} from "@medusajs/utils" +import { ChangeActionType, MathBN, MedusaError } from "@medusajs/utils" import { OrderChangeProcessing } from "../calculate-order-change" import { setActionReference } from "../set-action-reference" @@ -24,7 +19,7 @@ OrderChangeProcessing.registerActionType(ChangeActionType.FULFILL_ITEM, { }, validate({ action, currentOrder }) { const refId = action.details?.reference_id - if (!isDefined(refId)) { + if (refId == null) { throw new MedusaError( MedusaError.Types.INVALID_DATA, "Reference ID is required." diff --git a/packages/modules/order/src/utils/actions/item-add.ts b/packages/modules/order/src/utils/actions/item-add.ts index 40fc56fa79..45b1d316de 100644 --- a/packages/modules/order/src/utils/actions/item-add.ts +++ b/packages/modules/order/src/utils/actions/item-add.ts @@ -1,9 +1,4 @@ -import { - ChangeActionType, - MathBN, - MedusaError, - isDefined, -} from "@medusajs/utils" +import { ChangeActionType, MathBN, MedusaError } from "@medusajs/utils" import { VirtualOrder } from "@types" import { OrderChangeProcessing } from "../calculate-order-change" import { setActionReference } from "../set-action-reference" @@ -45,7 +40,7 @@ OrderChangeProcessing.registerActionType(ChangeActionType.ITEM_ADD, { validate({ action }) { const refId = action.details?.reference_id - if (!isDefined(action.amount) && !isDefined(action.details?.unit_price)) { + if (action.amount == null && action.details?.unit_price == null) { throw new MedusaError( MedusaError.Types.INVALID_DATA, `Unit price of item ${refId} is required if no action.amount is provided.` diff --git a/packages/modules/order/src/utils/actions/item-remove.ts b/packages/modules/order/src/utils/actions/item-remove.ts index b8f926457c..0ba701ba04 100644 --- a/packages/modules/order/src/utils/actions/item-remove.ts +++ b/packages/modules/order/src/utils/actions/item-remove.ts @@ -1,9 +1,4 @@ -import { - ChangeActionType, - MathBN, - MedusaError, - isDefined, -} from "@medusajs/utils" +import { ChangeActionType, MathBN, MedusaError } from "@medusajs/utils" import { OrderChangeProcessing } from "../calculate-order-change" import { setActionReference } from "../set-action-reference" @@ -34,7 +29,7 @@ OrderChangeProcessing.registerActionType(ChangeActionType.ITEM_REMOVE, { }, validate({ action, currentOrder }) { const refId = action.details?.reference_id - if (!isDefined(refId)) { + if (refId == null) { throw new MedusaError( MedusaError.Types.INVALID_DATA, "Reference ID is required." @@ -49,13 +44,6 @@ OrderChangeProcessing.registerActionType(ChangeActionType.ITEM_REMOVE, { ) } - if (!isDefined(action.amount) && !isDefined(action.details?.unit_price)) { - throw new MedusaError( - MedusaError.Types.INVALID_DATA, - `Unit price of item ${refId} is required if no action.amount is provided.` - ) - } - if (!action.details?.quantity) { throw new MedusaError( MedusaError.Types.INVALID_DATA, diff --git a/packages/modules/order/src/utils/actions/receive-damaged-return-item.ts b/packages/modules/order/src/utils/actions/receive-damaged-return-item.ts index 503a1b5b74..05e9382ddd 100644 --- a/packages/modules/order/src/utils/actions/receive-damaged-return-item.ts +++ b/packages/modules/order/src/utils/actions/receive-damaged-return-item.ts @@ -1,9 +1,4 @@ -import { - ChangeActionType, - MathBN, - MedusaError, - isDefined, -} from "@medusajs/utils" +import { ChangeActionType, MathBN, MedusaError } from "@medusajs/utils" import { OrderChangeProcessing } from "../calculate-order-change" import { setActionReference } from "../set-action-reference" @@ -42,7 +37,7 @@ OrderChangeProcessing.registerActionType( }, validate({ action, currentOrder }) { const refId = action.details?.reference_id - if (!isDefined(refId)) { + if (refId == null) { throw new MedusaError( MedusaError.Types.INVALID_DATA, "Details reference ID is required." diff --git a/packages/modules/order/src/utils/actions/receive-return-item.ts b/packages/modules/order/src/utils/actions/receive-return-item.ts index d960ba3f5b..1ed7041c20 100644 --- a/packages/modules/order/src/utils/actions/receive-return-item.ts +++ b/packages/modules/order/src/utils/actions/receive-return-item.ts @@ -1,9 +1,4 @@ -import { - ChangeActionType, - MathBN, - MedusaError, - isDefined, -} from "@medusajs/utils" +import { ChangeActionType, MathBN, MedusaError } from "@medusajs/utils" import { OrderChangeProcessing } from "../calculate-order-change" import { setActionReference } from "../set-action-reference" @@ -34,7 +29,7 @@ OrderChangeProcessing.registerActionType(ChangeActionType.RECEIVE_RETURN_ITEM, { }, validate({ action, currentOrder }) { const refId = action.details?.reference_id - if (!isDefined(refId)) { + if (refId == null) { throw new MedusaError( MedusaError.Types.INVALID_DATA, "Details reference ID is required." diff --git a/packages/modules/order/src/utils/actions/reinstate-item.ts b/packages/modules/order/src/utils/actions/reinstate-item.ts index 265459da8e..5d208c0b44 100644 --- a/packages/modules/order/src/utils/actions/reinstate-item.ts +++ b/packages/modules/order/src/utils/actions/reinstate-item.ts @@ -1,9 +1,4 @@ -import { - ChangeActionType, - MathBN, - MedusaError, - isDefined, -} from "@medusajs/utils" +import { ChangeActionType, MathBN, MedusaError } from "@medusajs/utils" import { OrderChangeProcessing } from "../calculate-order-change" import { setActionReference } from "../set-action-reference" @@ -23,7 +18,7 @@ OrderChangeProcessing.registerActionType(ChangeActionType.REINSTATE_ITEM, { }, validate({ action, currentOrder }) { const refId = action.details?.reference_id - if (!isDefined(refId)) { + if (refId == null) { throw new MedusaError( MedusaError.Types.INVALID_DATA, "Details reference ID is required." diff --git a/packages/modules/order/src/utils/actions/return-item.ts b/packages/modules/order/src/utils/actions/return-item.ts index 8ec66325dd..f09bd028f1 100644 --- a/packages/modules/order/src/utils/actions/return-item.ts +++ b/packages/modules/order/src/utils/actions/return-item.ts @@ -1,9 +1,4 @@ -import { - ChangeActionType, - MathBN, - MedusaError, - isDefined, -} from "@medusajs/utils" +import { ChangeActionType, MathBN, MedusaError } from "@medusajs/utils" import { OrderChangeProcessing } from "../calculate-order-change" import { setActionReference } from "../set-action-reference" @@ -27,7 +22,7 @@ OrderChangeProcessing.registerActionType(ChangeActionType.RETURN_ITEM, { }, validate({ action, currentOrder }) { const refId = action.details?.reference_id - if (!isDefined(refId)) { + if (refId == null) { throw new MedusaError( MedusaError.Types.INVALID_DATA, "Details reference ID is required." diff --git a/packages/modules/order/src/utils/actions/ship-item.ts b/packages/modules/order/src/utils/actions/ship-item.ts index 01a5d6f6d6..c97c968f9c 100644 --- a/packages/modules/order/src/utils/actions/ship-item.ts +++ b/packages/modules/order/src/utils/actions/ship-item.ts @@ -1,9 +1,4 @@ -import { - ChangeActionType, - MathBN, - MedusaError, - isDefined, -} from "@medusajs/utils" +import { ChangeActionType, MathBN, MedusaError } from "@medusajs/utils" import { OrderChangeProcessing } from "../calculate-order-change" import { setActionReference } from "../set-action-reference" @@ -24,7 +19,7 @@ OrderChangeProcessing.registerActionType(ChangeActionType.SHIP_ITEM, { }, validate({ action, currentOrder }) { const refId = action.details?.reference_id - if (!isDefined(refId)) { + if (refId == null) { throw new MedusaError( MedusaError.Types.INVALID_DATA, "Reference ID is required." diff --git a/packages/modules/order/src/utils/actions/shipping-add.ts b/packages/modules/order/src/utils/actions/shipping-add.ts index d7dfdffc06..cfda4b64f2 100644 --- a/packages/modules/order/src/utils/actions/shipping-add.ts +++ b/packages/modules/order/src/utils/actions/shipping-add.ts @@ -1,4 +1,4 @@ -import { ChangeActionType, MedusaError, isDefined } from "@medusajs/utils" +import { ChangeActionType, MedusaError } from "@medusajs/utils" import { OrderChangeProcessing } from "../calculate-order-change" import { setActionReference } from "../set-action-reference" @@ -33,7 +33,7 @@ OrderChangeProcessing.registerActionType(ChangeActionType.SHIPPING_ADD, { ) } - if (!isDefined(action.amount)) { + if (action.amount == null) { throw new MedusaError( MedusaError.Types.INVALID_DATA, "Amount is required." diff --git a/packages/modules/order/src/utils/actions/shipping-remove.ts b/packages/modules/order/src/utils/actions/shipping-remove.ts index 7a99a7ef1c..38b02689ea 100644 --- a/packages/modules/order/src/utils/actions/shipping-remove.ts +++ b/packages/modules/order/src/utils/actions/shipping-remove.ts @@ -1,4 +1,4 @@ -import { ChangeActionType, MedusaError, isDefined } from "@medusajs/utils" +import { ChangeActionType, MedusaError } from "@medusajs/utils" import { OrderChangeProcessing } from "../calculate-order-change" OrderChangeProcessing.registerActionType(ChangeActionType.SHIPPING_REMOVE, { @@ -24,12 +24,5 @@ OrderChangeProcessing.registerActionType(ChangeActionType.SHIPPING_REMOVE, { "Reference ID is required." ) } - - if (!isDefined(action.amount)) { - throw new MedusaError( - MedusaError.Types.INVALID_DATA, - "Amount is required." - ) - } }, }) diff --git a/packages/modules/order/src/utils/actions/write-off-item.ts b/packages/modules/order/src/utils/actions/write-off-item.ts index c70d1eb295..feb35e3f6c 100644 --- a/packages/modules/order/src/utils/actions/write-off-item.ts +++ b/packages/modules/order/src/utils/actions/write-off-item.ts @@ -1,9 +1,4 @@ -import { - ChangeActionType, - MathBN, - MedusaError, - isDefined, -} from "@medusajs/utils" +import { ChangeActionType, MathBN, MedusaError } from "@medusajs/utils" import { OrderChangeProcessing } from "../calculate-order-change" import { setActionReference } from "../set-action-reference" @@ -23,7 +18,7 @@ OrderChangeProcessing.registerActionType(ChangeActionType.WRITE_OFF_ITEM, { }, validate({ action, currentOrder }) { const refId = action.details?.reference_id - if (!isDefined(refId)) { + if (refId == null) { throw new MedusaError( MedusaError.Types.INVALID_DATA, "Details reference ID is required."