diff --git a/integration-tests/http/__tests__/claims/claims.spec.ts b/integration-tests/http/__tests__/claims/claims.spec.ts index 81668c951d..54c9910305 100644 --- a/integration-tests/http/__tests__/claims/claims.spec.ts +++ b/integration-tests/http/__tests__/claims/claims.spec.ts @@ -518,6 +518,15 @@ medusaIntegrationTestRunner({ expect(result[0].claim_items).toHaveLength(1) expect(result[0].canceled_at).toBeNull() + const reservationsResponse = ( + await api.get( + `/admin/reservations?location_id[]=${location.id}`, + adminHeaders + ) + ).data + + expect(reservationsResponse.reservations).toHaveLength(1) + await api.post(`/admin/claims/${claimId}/cancel`, {}, adminHeaders) result = ( @@ -527,6 +536,15 @@ medusaIntegrationTestRunner({ ) ).data.claims expect(result[0].canceled_at).toBeDefined() + + const reservationsResponseAfterCanceling = ( + await api.get( + `/admin/reservations?location_id[]=${location.id}`, + adminHeaders + ) + ).data + + expect(reservationsResponseAfterCanceling.reservations).toHaveLength(0) }) }) diff --git a/integration-tests/http/__tests__/exchanges/exchanges.spec.ts b/integration-tests/http/__tests__/exchanges/exchanges.spec.ts index b47f9eef08..421aeac433 100644 --- a/integration-tests/http/__tests__/exchanges/exchanges.spec.ts +++ b/integration-tests/http/__tests__/exchanges/exchanges.spec.ts @@ -489,7 +489,7 @@ medusaIntegrationTestRunner({ result = ( await api.get( - `/admin/exchanges?fields=*additional_items`, + `/admin/exchanges?fields=+metadata,*additional_items`, adminHeaders ) ).data.exchanges diff --git a/integration-tests/modules/__tests__/order/workflows/begin-order-claim.spec.ts b/integration-tests/modules/__tests__/order/workflows/begin-order-claim.spec.ts index 67d7c5c636..9debc604aa 100644 --- a/integration-tests/modules/__tests__/order/workflows/begin-order-claim.spec.ts +++ b/integration-tests/modules/__tests__/order/workflows/begin-order-claim.spec.ts @@ -123,7 +123,7 @@ async function prepareDataFixtures({ container }) { stock_location_id: location.id, }, [Modules.FULFILLMENT]: { - fulfillment_provider_id: "manual_test-provider", + fulfillment_provider_id: providerId, }, }, { diff --git a/packages/core/core-flows/src/definition/cart/steps/reserve-inventory.ts b/packages/core/core-flows/src/definition/cart/steps/reserve-inventory.ts index d96428fbfc..f852b47be7 100644 --- a/packages/core/core-flows/src/definition/cart/steps/reserve-inventory.ts +++ b/packages/core/core-flows/src/definition/cart/steps/reserve-inventory.ts @@ -1,5 +1,5 @@ import { IInventoryService } from "@medusajs/types" -import { ModuleRegistrationName } from "@medusajs/utils" +import { MathBN, ModuleRegistrationName } from "@medusajs/utils" import { StepResponse, createStep } from "@medusajs/workflows-sdk" interface StepInput { @@ -24,14 +24,14 @@ export const reserveInventoryStep = createStep( const items = data.items.map((item) => ({ line_item_id: item.id, inventory_item_id: item.inventory_item_id, - quantity: item.required_quantity * item.quantity, + quantity: MathBN.mult(item.required_quantity, item.quantity), allow_backorder: item.allow_backorder, location_id: item.location_ids[0], })) const reservations = await inventoryService.createReservationItems(items) - return new StepResponse(void 0, { + return new StepResponse(reservations, { reservations: reservations.map((r) => r.id), }) }, diff --git a/packages/core/core-flows/src/definition/cart/workflows/complete-cart.ts b/packages/core/core-flows/src/definition/cart/workflows/complete-cart.ts index b21f99686e..92844118bd 100644 --- a/packages/core/core-flows/src/definition/cart/workflows/complete-cart.ts +++ b/packages/core/core-flows/src/definition/cart/workflows/complete-cart.ts @@ -68,6 +68,7 @@ export const completeCartWorkflow = createWorkflow( const formatedInventoryItems = confirmVariantInventoryWorkflow.runAsStep({ input: { + skipInventoryCheck: true, sales_channel_id, variants, items, diff --git a/packages/core/core-flows/src/definition/cart/workflows/confirm-variant-inventory.ts b/packages/core/core-flows/src/definition/cart/workflows/confirm-variant-inventory.ts index 3b520e75d4..26680ff9eb 100644 --- a/packages/core/core-flows/src/definition/cart/workflows/confirm-variant-inventory.ts +++ b/packages/core/core-flows/src/definition/cart/workflows/confirm-variant-inventory.ts @@ -5,6 +5,7 @@ import { WorkflowResponse, createWorkflow, transform, + when, } from "@medusajs/workflows-sdk" import { confirmInventoryStep } from "../steps" import { prepareConfirmInventoryInput } from "../utils/prepare-confirm-inventory-input" @@ -94,7 +95,7 @@ export const confirmVariantInventoryWorkflow = createWorkflow( if (salesChannelId && !hasSalesChannelStockLocation) { throw new MedusaError( MedusaError.Types.INVALID_DATA, - `Sales channel ${salesChannelId} is not associated with any stock locations.` + `Sales channel ${salesChannelId} is not associated with any stock location.` ) } @@ -110,7 +111,11 @@ export const confirmVariantInventoryWorkflow = createWorkflow( return { items } }) - confirmInventoryStep(confirmInventoryInput) + when({ input }, ({ input }) => { + return !input.skipInventoryCheck + }).then(() => { + confirmInventoryStep(confirmInventoryInput) + }) return new WorkflowResponse(confirmInventoryInput) } diff --git a/packages/core/core-flows/src/fulfillment/steps/validate-fulfillment-providers.ts b/packages/core/core-flows/src/fulfillment/steps/validate-fulfillment-providers.ts index b59cf815e7..afa7824cfa 100644 --- a/packages/core/core-flows/src/fulfillment/steps/validate-fulfillment-providers.ts +++ b/packages/core/core-flows/src/fulfillment/steps/validate-fulfillment-providers.ts @@ -5,7 +5,7 @@ import { ModuleRegistrationName, remoteQueryObjectFromString, } from "@medusajs/utils" -import { createStep, StepResponse } from "@medusajs/workflows-sdk" +import { StepResponse, createStep } from "@medusajs/workflows-sdk" type FulfillmentProviderValidationInput = { id?: string @@ -26,9 +26,15 @@ export const validateFulfillmentProvidersStep = createStep( ModuleRegistrationName.FULFILLMENT ) - const shippingOptions = await fulfillmentService.listShippingOptions({ - id: input.map((d) => d.id).filter(Boolean) as string[], - }) + const shippingOptions = await fulfillmentService.listShippingOptions( + { + id: input.map((d) => d.id).filter(Boolean) as string[], + }, + { + select: ["id", "service_zone_id", "provider_id"], + take: null, + } + ) const shippingOptionsMap = new Map( shippingOptions.map((so) => [so.id, so]) @@ -42,11 +48,17 @@ export const validateFulfillmentProvidersStep = createStep( if ("id" in data) { const existingShippingOption = shippingOptionsMap.get(data.id!) + if (!data.service_zone_id) { + data.service_zone_id = existingShippingOption?.service_zone_id! + } + + if (!data.provider_id) { + data.provider_id = existingShippingOption?.provider_id! + } + dataToValidate.push({ - service_zone_id: - data.service_zone_id! || existingShippingOption?.service_zone_id!, - provider_id: - data.provider_id! || existingShippingOption?.provider_id!, + service_zone_id: data.service_zone_id!, + provider_id: data.provider_id!, }) continue @@ -70,11 +82,12 @@ export const validateFulfillmentProvidersStep = createStep( const serviceZoneQuery = remoteQueryObjectFromString({ entryPoint: "service_zone", fields: ["id", "fulfillment_set.locations.fulfillment_providers.id"], + variables: { + id: input.map((d) => d.service_zone_id), + }, }) - const serviceZones = await remoteQuery(serviceZoneQuery, { - id: input.map((d) => d.service_zone_id), - }) + const serviceZones = await remoteQuery(serviceZoneQuery) const serviceZonesMap = new Map< string, @@ -88,13 +101,16 @@ export const validateFulfillmentProvidersStep = createStep( const invalidProviders: string[] = [] for (const data of dataToValidate) { - const serviceZone = serviceZonesMap.get(data.service_zone_id)! - const stockLocations = serviceZone.fulfillment_set.locations + const serviceZone = serviceZonesMap.get(data.service_zone_id) + const stockLocations = serviceZone?.fulfillment_set?.locations ?? [] const fulfillmentProviders: string[] = [] for (const stockLocation of stockLocations) { - const providersForStockLocation = - stockLocation.fulfillment_providers.map((fp) => fp.id) + const providersForStockLocation = ( + stockLocation.fulfillment_providers ?? [] + ) + .filter(Boolean) + .map((fp) => fp.id) fulfillmentProviders.push(...providersForStockLocation) } diff --git a/packages/core/core-flows/src/order/steps/claim/cancel-claim.ts b/packages/core/core-flows/src/order/steps/claim/cancel-claim.ts index 8e9ae8f72f..828b572bd1 100644 --- a/packages/core/core-flows/src/order/steps/claim/cancel-claim.ts +++ b/packages/core/core-flows/src/order/steps/claim/cancel-claim.ts @@ -13,7 +13,7 @@ export const cancelOrderClaimStep = createStep( ) await service.cancelClaim(data) - return new StepResponse(void 0, data.return_id) + return new StepResponse(void 0, data.order_id) }, async (orderId, { container }) => { if (!orderId) { diff --git a/packages/core/core-flows/src/order/steps/exchange/cancel-exchange.ts b/packages/core/core-flows/src/order/steps/exchange/cancel-exchange.ts index 414882b075..473fd7ae3f 100644 --- a/packages/core/core-flows/src/order/steps/exchange/cancel-exchange.ts +++ b/packages/core/core-flows/src/order/steps/exchange/cancel-exchange.ts @@ -13,7 +13,7 @@ export const cancelOrderExchangeStep = createStep( ) await service.cancelExchange(data) - return new StepResponse(void 0, data.return_id) + return new StepResponse(void 0, data.order_id) }, async (orderId, { container }) => { if (!orderId) { diff --git a/packages/core/core-flows/src/order/steps/return/cancel-return.ts b/packages/core/core-flows/src/order/steps/return/cancel-return.ts index a316b21e73..d29a1839bd 100644 --- a/packages/core/core-flows/src/order/steps/return/cancel-return.ts +++ b/packages/core/core-flows/src/order/steps/return/cancel-return.ts @@ -13,7 +13,7 @@ export const cancelOrderReturnStep = createStep( ) await service.cancelReturn(data) - return new StepResponse(void 0, data.return_id) + return new StepResponse(void 0, data.order_id) }, async (orderId, { container }) => { if (!orderId) { diff --git a/packages/core/core-flows/src/order/workflows/claim/cancel-claim.ts b/packages/core/core-flows/src/order/workflows/claim/cancel-claim.ts index cb65fc0b8a..5883d75dbb 100644 --- a/packages/core/core-flows/src/order/workflows/claim/cancel-claim.ts +++ b/packages/core/core-flows/src/order/workflows/claim/cancel-claim.ts @@ -4,9 +4,12 @@ import { WorkflowData, createStep, createWorkflow, + parallelize, + transform, when, } from "@medusajs/workflows-sdk" import { useRemoteQueryStep } from "../../../common" +import { deleteReservationsByLineItemsStep } from "../../../reservation/steps/delete-reservations-by-line-items" import { cancelOrderClaimStep } from "../../steps" import { throwIfIsCancelled } from "../../utils/order-validation" import { cancelReturnWorkflow } from "../return/cancel-return" @@ -54,7 +57,14 @@ export const cancelOrderClaimWorkflow = createWorkflow( const orderClaim: OrderClaimDTO & { fulfillments: FulfillmentDTO[] } = useRemoteQueryStep({ entry_point: "order_claim", - fields: ["id", "return_id", "canceled_at", "fulfillments.canceled_at"], + fields: [ + "id", + "order_id", + "return_id", + "canceled_at", + "fulfillments.canceled_at", + "additional_items.item_id", + ], variables: { id: input.claim_id }, list: false, throw_if_key_not_found: true, @@ -62,7 +72,17 @@ export const cancelOrderClaimWorkflow = createWorkflow( validateOrder({ orderClaim, input }) - cancelOrderClaimStep({ claim_id: orderClaim.id }) + const lineItemIds = transform({ orderClaim }, ({ orderClaim }) => { + return orderClaim.additional_items?.map((i) => i.item_id) + }) + + parallelize( + cancelOrderClaimStep({ + claim_id: orderClaim.id, + order_id: orderClaim.order_id, + }), + deleteReservationsByLineItemsStep(lineItemIds) + ) when({ orderClaim }, ({ orderClaim }) => { return !!orderClaim.return_id 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 1fc83306fd..50296d2677 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 @@ -20,7 +20,8 @@ import { when, } from "@medusajs/workflows-sdk" import { createRemoteLinkStep, useRemoteQueryStep } from "../../../common" -import { createFulfillmentWorkflow } from "../../../fulfillment/workflows/create-fulfillment" +import { reserveInventoryStep } from "../../../definition/cart/steps/reserve-inventory" +import { confirmVariantInventoryWorkflow } from "../../../definition/cart/workflows/confirm-variant-inventory" import { createReturnFulfillmentWorkflow } from "../../../fulfillment/workflows/create-return-fulfillment" import { previewOrderChangeStep, updateReturnsStep } from "../../steps" import { createOrderClaimItemsFromActionsStep } from "../../steps/claim/create-claim-items-from-actions" @@ -272,57 +273,53 @@ export const confirmClaimRequestWorkflow = createWorkflow( "id", "version", "canceled_at", - "additional_items.item_id", + "order.sales_channel_id", "additional_items.quantity", - "additional_items.item.title", - "additional_items.item.variant_title", - "additional_items.item.variant_sku", - "additional_items.item.variant_barcode", + "additional_items.raw_quantity", + "additional_items.item.id", + "additional_items.item.variant.manage_inventory", + "additional_items.item.variant.allow_backorder", + "additional_items.item.variant.inventory_items.inventory_item_id", + "additional_items.item.variant.inventory_items.required_quantity", + "additional_items.item.variant.inventory_items.inventory.location_levels.stock_locations.id", + "additional_items.item.variant.inventory_items.inventory.location_levels.stock_locations.name", + "additional_items.item.variant.inventory_items.inventory.location_levels.stock_locations.sales_channels.id", + "additional_items.item.variant.inventory_items.inventory.location_levels.stock_locations.sales_channels.name", ], variables: { id: claimId }, list: false, throw_if_key_not_found: true, }).config({ name: "claim-query" }) - const claimShippingOption = useRemoteQueryStep({ - entry_point: "shipping_options", - fields: [ - "id", - "provider_id", - "service_zone.fulfillment_set.location.id", - "service_zone.fulfillment_set.location.address.*", - ], - variables: { - id: claimShippingMethod.shipping_option_id, - }, - list: false, - throw_if_key_not_found: true, - }).config({ name: "claim-shipping-option" }) + const { variants, items } = transform({ claim }, ({ claim }) => { + const allItems: any[] = [] + const allVariants: any[] = [] + claim.additional_items.forEach((claimItem) => { + const item = claimItem.item + allItems.push({ + id: item.id, + variant_id: item.variant_id, + quantity: claimItem.raw_quantity ?? claimItem.quantity, + }) + allVariants.push(item.variant) + }) - const fulfillmentData = transform( - { - order, - items: claim.additional_items! ?? [], - shippingOption: claimShippingOption, - deliveryAddress: order.shipping_address, - }, - prepareFulfillmentData - ) - - const fulfillment = createFulfillmentWorkflow.runAsStep(fulfillmentData) - - const link = transform({ fulfillment, order }, (data) => { - return [ - { - [Modules.ORDER]: { order_id: data.order.id }, - [Modules.FULFILLMENT]: { fulfillment_id: data.fulfillment.id }, - }, - ] + return { + variants: allVariants, + items: allItems, + } }) - createRemoteLinkStep(link).config({ - name: "claim-shipping-fulfillment-link", + const formatedInventoryItems = confirmVariantInventoryWorkflow.runAsStep({ + input: { + skipInventoryCheck: true, + sales_channel_id: (claim as any).order.sales_channel_id, + variants, + items, + }, }) + + reserveInventoryStep(formatedInventoryItems) }) when({ returnShippingMethod }, ({ returnShippingMethod }) => { diff --git a/packages/core/core-flows/src/order/workflows/create-fulfillment.ts b/packages/core/core-flows/src/order/workflows/create-fulfillment.ts index c892dea234..194c1cedf9 100644 --- a/packages/core/core-flows/src/order/workflows/create-fulfillment.ts +++ b/packages/core/core-flows/src/order/workflows/create-fulfillment.ts @@ -3,6 +3,7 @@ import { FulfillmentDTO, FulfillmentWorkflow, OrderDTO, + OrderLineItemDTO, OrderWorkflow, ReservationItemDTO, } from "@medusajs/types" @@ -50,13 +51,14 @@ function prepareRegisterOrderFulfillmentData({ fulfillment, input, inputItemsMap, + itemsList, }) { return { order_id: order.id, reference: Modules.FULFILLMENT, reference_id: fulfillment.id, created_by: input.created_by, - items: order.items!.map((i) => { + items: (itemsList ?? order.items)!.map((i) => { const inputQuantity = inputItemsMap[i.id]?.quantity return { id: i.id, @@ -72,6 +74,7 @@ function prepareFulfillmentData({ shippingOption, shippingMethod, reservations, + itemsList, }: { order: OrderDTO input: OrderWorkflow.CreateOrderFulfillmentWorkflowInput @@ -82,10 +85,11 @@ function prepareFulfillmentData({ } shippingMethod: { data?: Record | null } reservations: ReservationItemDTO[] + itemsList?: OrderLineItemDTO[] }) { const inputItems = input.items const orderItemsMap = new Map["items"][0]>( - order.items!.map((i) => [i.id, i]) + (itemsList ?? order.items)!.map((i) => [i.id, i]) ) const reservationItemMap = new Map( reservations.map((r) => [r.line_item_id as string, r]) @@ -132,7 +136,13 @@ function prepareFulfillmentData({ } } -function prepareInventoryUpdate({ reservations, order, input, inputItemsMap }) { +function prepareInventoryUpdate({ + reservations, + order, + input, + inputItemsMap, + itemsList, +}) { const reservationMap = reservations.reduce((acc, reservation) => { acc[reservation.line_item_id as string] = reservation return acc @@ -150,7 +160,8 @@ function prepareInventoryUpdate({ reservations, order, input, inputItemsMap }) { adjustment: BigNumberInput }[] = [] - for (const item of order.items) { + const allItems = itemsList ?? order.items + for (const item of allItems) { const reservation = reservationMap[item.id] if (!reservation) { if (item.manage_inventory) { @@ -205,7 +216,7 @@ export const createOrderFulfillmentWorkflow = createWorkflow( "items.*", "items.variant.manage_inventory", "shipping_address.*", - "shipping_methods.shipping_option_id", // TODO: which shipping method to use when multiple? + "shipping_methods.shipping_option_id", "shipping_methods.data", ], variables: { id: input.order_id }, @@ -240,9 +251,12 @@ export const createOrderFulfillmentWorkflow = createWorkflow( throw_if_key_not_found: true, }).config({ name: "get-shipping-option" }) - const lineItemIds = transform({ order }, ({ order }) => { - return order.items?.map((i) => i.id) - }) + const lineItemIds = transform( + { order, itemsList: input.items_list }, + ({ order, itemsList }) => { + return (itemsList ?? order.items)!.map((i) => i.id) + } + ) const reservations = useRemoteQueryStep({ entry_point: "reservations", fields: [ @@ -260,14 +274,21 @@ export const createOrderFulfillmentWorkflow = createWorkflow( }).config({ name: "get-reservations" }) const fulfillmentData = transform( - { order, input, shippingOption, shippingMethod, reservations }, + { + order, + input, + shippingOption, + shippingMethod, + reservations, + itemsList: input.items_list, + }, prepareFulfillmentData ) const fulfillment = createFulfillmentWorkflow.runAsStep(fulfillmentData) const registerOrderFulfillmentData = transform( - { order, fulfillment, input, inputItemsMap }, + { order, fulfillment, input, inputItemsMap, itemsList: input.items_list }, prepareRegisterOrderFulfillmentData ) @@ -284,7 +305,13 @@ export const createOrderFulfillmentWorkflow = createWorkflow( ) const { toDelete, toUpdate, inventoryAdjustment } = transform( - { order, reservations, input, inputItemsMap }, + { + order, + reservations, + input, + inputItemsMap, + itemsList: input.items_list, + }, prepareInventoryUpdate ) diff --git a/packages/core/core-flows/src/order/workflows/exchange/cancel-exchange.ts b/packages/core/core-flows/src/order/workflows/exchange/cancel-exchange.ts index ec62d60b58..515a9c7f92 100644 --- a/packages/core/core-flows/src/order/workflows/exchange/cancel-exchange.ts +++ b/packages/core/core-flows/src/order/workflows/exchange/cancel-exchange.ts @@ -8,9 +8,12 @@ import { WorkflowData, createStep, createWorkflow, + parallelize, + transform, when, } from "@medusajs/workflows-sdk" import { useRemoteQueryStep } from "../../../common" +import { deleteReservationsByLineItemsStep } from "../../../reservation/steps/delete-reservations-by-line-items" import { cancelOrderExchangeStep } from "../../steps" import { throwIfIsCancelled } from "../../utils/order-validation" import { cancelReturnWorkflow } from "../return/cancel-return" @@ -58,7 +61,14 @@ export const cancelOrderExchangeWorkflow = createWorkflow( const orderExchange: OrderExchangeDTO & { fulfillments: FulfillmentDTO[] } = useRemoteQueryStep({ entry_point: "order_exchange", - fields: ["id", "return_id", "canceled_at", "fulfillments.canceled_at"], + fields: [ + "id", + "order_id", + "return_id", + "canceled_at", + "fulfillments.canceled_at", + "additional_items.item_id", + ], variables: { id: input.exchange_id }, list: false, throw_if_key_not_found: true, @@ -66,7 +76,17 @@ export const cancelOrderExchangeWorkflow = createWorkflow( validateOrder({ orderExchange, input }) - cancelOrderExchangeStep({ exchange_id: orderExchange.id }) + const lineItemIds = transform({ orderExchange }, ({ orderExchange }) => { + return orderExchange.additional_items?.map((i) => i.item_id) + }) + + parallelize( + cancelOrderExchangeStep({ + exchange_id: orderExchange.id, + order_id: orderExchange.order_id, + }), + deleteReservationsByLineItemsStep(lineItemIds) + ) when({ orderExchange }, ({ orderExchange }) => { return !!orderExchange.return_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 45b53ad413..fe74e3f7a7 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 @@ -15,7 +15,8 @@ import { when, } from "@medusajs/workflows-sdk" import { createRemoteLinkStep, useRemoteQueryStep } from "../../../common" -import { createFulfillmentWorkflow } from "../../../fulfillment/workflows/create-fulfillment" +import { reserveInventoryStep } from "../../../definition/cart/steps/reserve-inventory" +import { confirmVariantInventoryWorkflow } from "../../../definition/cart/workflows/confirm-variant-inventory" import { createReturnFulfillmentWorkflow } from "../../../fulfillment/workflows/create-return-fulfillment" import { previewOrderChangeStep } from "../../steps" import { confirmOrderChanges } from "../../steps/confirm-order-changes" @@ -259,57 +260,53 @@ export const confirmExchangeRequestWorkflow = createWorkflow( "id", "version", "canceled_at", - "additional_items.item_id", + "order.sales_channel_id", "additional_items.quantity", - "additional_items.item.title", - "additional_items.item.variant_title", - "additional_items.item.variant_sku", - "additional_items.item.variant_barcode", + "additional_items.raw_quantity", + "additional_items.item.id", + "additional_items.item.variant.manage_inventory", + "additional_items.item.variant.allow_backorder", + "additional_items.item.variant.inventory_items.inventory_item_id", + "additional_items.item.variant.inventory_items.required_quantity", + "additional_items.item.variant.inventory_items.inventory.location_levels.stock_locations.id", + "additional_items.item.variant.inventory_items.inventory.location_levels.stock_locations.name", + "additional_items.item.variant.inventory_items.inventory.location_levels.stock_locations.sales_channels.id", + "additional_items.item.variant.inventory_items.inventory.location_levels.stock_locations.sales_channels.name", ], variables: { id: exchangeId }, list: false, throw_if_key_not_found: true, }).config({ name: "exchange-query" }) - const exchangeShippingOption = useRemoteQueryStep({ - entry_point: "shipping_options", - fields: [ - "id", - "provider_id", - "service_zone.fulfillment_set.location.id", - "service_zone.fulfillment_set.location.address.*", - ], - variables: { - id: exchangeShippingMethod.shipping_option_id, - }, - list: false, - throw_if_key_not_found: true, - }).config({ name: "exchange-shipping-option" }) + const { variants, items } = transform({ exchange }, ({ exchange }) => { + const allItems: any[] = [] + const allVariants: any[] = [] + exchange.additional_items.forEach((exchangeItem) => { + const item = exchangeItem.item + allItems.push({ + id: item.id, + variant_id: item.variant_id, + quantity: exchangeItem.raw_quantity ?? exchangeItem.quantity, + }) + allVariants.push(item.variant) + }) - const fulfillmentData = transform( - { - order, - items: exchange.additional_items! ?? [], - shippingOption: exchangeShippingOption, - deliveryAddress: order.shipping_address, - }, - prepareFulfillmentData - ) - - const fulfillment = createFulfillmentWorkflow.runAsStep(fulfillmentData) - - const link = transform({ fulfillment, order }, (data) => { - return [ - { - [Modules.ORDER]: { order_id: data.order.id }, - [Modules.FULFILLMENT]: { fulfillment_id: data.fulfillment.id }, - }, - ] + return { + variants: allVariants, + items: allItems, + } }) - createRemoteLinkStep(link).config({ - name: "exchange-shipping-fulfillment-link", + const formatedInventoryItems = confirmVariantInventoryWorkflow.runAsStep({ + input: { + skipInventoryCheck: true, + sales_channel_id: (exchange as any).order.sales_channel_id, + variants, + items, + }, }) + + reserveInventoryStep(formatedInventoryItems) }) when({ returnShippingMethod }, ({ returnShippingMethod }) => { diff --git a/packages/core/core-flows/src/order/workflows/return/cancel-return.ts b/packages/core/core-flows/src/order/workflows/return/cancel-return.ts index 9f2302d1d7..2a8df8c616 100644 --- a/packages/core/core-flows/src/order/workflows/return/cancel-return.ts +++ b/packages/core/core-flows/src/order/workflows/return/cancel-return.ts @@ -67,6 +67,7 @@ export const cancelReturnWorkflow = createWorkflow( entry_point: "return", fields: [ "id", + "order_id", "canceled_at", "items.id", "items.received_quantity", @@ -79,6 +80,9 @@ export const cancelReturnWorkflow = createWorkflow( validateOrder({ orderReturn, input }) - cancelOrderReturnStep({ return_id: orderReturn.id }) + cancelOrderReturnStep({ + return_id: orderReturn.id, + order_id: orderReturn.order_id, + }) } ) 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 b22197ad7a..db8806e020 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 @@ -14,7 +14,6 @@ import { deepFlatMap, } from "@medusajs/utils" import { - WorkflowData, WorkflowResponse, createStep, createWorkflow, diff --git a/packages/core/types/src/cart/workflows.ts b/packages/core/types/src/cart/workflows.ts index 0f6f496aa4..0fcbb17f65 100644 --- a/packages/core/types/src/cart/workflows.ts +++ b/packages/core/types/src/cart/workflows.ts @@ -122,6 +122,7 @@ export interface CompleteCartWorkflowInputDTO { } export interface ConfirmVariantInventoryWorkflowInputDTO { + skipInventoryCheck?: boolean sales_channel_id: string variants: { id: string diff --git a/packages/core/types/src/order/mutations.ts b/packages/core/types/src/order/mutations.ts index 63df655fdf..cf24e4adab 100644 --- a/packages/core/types/src/order/mutations.ts +++ b/packages/core/types/src/order/mutations.ts @@ -867,7 +867,7 @@ export interface CreateOrderChangeDTO { | "claim" | "edit" - /** + /** * The description of the order change. */ description?: string @@ -1888,15 +1888,7 @@ export interface UpdateOrderExchangeWithSelectorDTO { */ data: Partial } - -/** - * The details of canceling a return. - */ -export interface CancelOrderReturnDTO - extends Omit { - /** - * The return's ID. - */ +export interface CancelOrderReturnDTO extends BaseOrderBundledActionsDTO { return_id: string } @@ -1978,14 +1970,7 @@ export interface CreateOrderClaimDTO extends BaseOrderBundledActionsDTO { no_notification?: boolean } -/** - * The details of canceling a claim. - */ -export interface CancelOrderClaimDTO - extends Omit { - /** - * The claim's ID. - */ +export interface CancelOrderClaimDTO extends BaseOrderBundledActionsDTO { claim_id: string } @@ -2030,14 +2015,7 @@ export interface CreateOrderExchangeDTO extends BaseOrderBundledActionsDTO { no_notification?: boolean } -/** - * The details of the exchange cancelation. - */ -export interface CancelOrderExchangeDTO - extends Omit { - /** - * The exchange's ID. - */ +export interface CancelOrderExchangeDTO extends BaseOrderBundledActionsDTO { exchange_id: string } diff --git a/packages/core/types/src/workflow/order/create-fulfillment.ts b/packages/core/types/src/workflow/order/create-fulfillment.ts index 790573706c..16c2368827 100644 --- a/packages/core/types/src/workflow/order/create-fulfillment.ts +++ b/packages/core/types/src/workflow/order/create-fulfillment.ts @@ -1,3 +1,4 @@ +import { OrderLineItemDTO } from "../../order" import { BigNumberInput } from "../../totals" import { CreateFulfillmentLabelWorkflowDTO } from "../fulfillment/create-fulfillment" @@ -8,6 +9,7 @@ interface CreateOrderFulfillmentItem { export interface CreateOrderFulfillmentWorkflowInput { order_id: string + items_list?: OrderLineItemDTO[] created_by?: string // The id of the authenticated user items: CreateOrderFulfillmentItem[] labels?: CreateFulfillmentLabelWorkflowDTO[] diff --git a/packages/modules/inventory-next/src/services/inventory-module.ts b/packages/modules/inventory-next/src/services/inventory-module.ts index 1f5261c1c0..3cb4747940 100644 --- a/packages/modules/inventory-next/src/services/inventory-module.ts +++ b/packages/modules/inventory-next/src/services/inventory-module.ts @@ -278,6 +278,7 @@ export default class InventoryModuleService }, context ) + const created = await this.reservationItemService_.create(input, context) const adjustments: Map> = input.reduce( diff --git a/packages/modules/order/src/utils/base-repository-find.ts b/packages/modules/order/src/utils/base-repository-find.ts index 8999a4e177..6ba276ca4a 100644 --- a/packages/modules/order/src/utils/base-repository-find.ts +++ b/packages/modules/order/src/utils/base-repository-find.ts @@ -1,6 +1,6 @@ import { Constructor, Context, DAL } from "@medusajs/types" import { LoadStrategy } from "@mikro-orm/core" -import { Order } from "@models" +import { Order, OrderClaim } from "@models" import { mapRepositoryToOrderModel } from "." export function setFindMethods(klass: Constructor, entity: any) { @@ -36,6 +36,15 @@ export function setFindMethods(klass: Constructor, entity: any) { let orderAlias = "o0" if (isRelatedEntity) { + if (entity === OrderClaim) { + if ( + config.options.populate.includes("additional_items") && + !config.options.populate.includes("claim_items") + ) { + config.options.populate.push("claim_items") + } + } + if (!config.options.populate.includes("order.items")) { config.options.populate.unshift("order.items") } @@ -129,6 +138,15 @@ export function setFindMethods(klass: Constructor, entity: any) { let orderAlias = "o0" if (isRelatedEntity) { + if (entity === OrderClaim) { + if ( + config.options.populate.includes("additional_items") && + !config.options.populate.includes("claim_items") + ) { + config.options.populate.push("claim_items") + } + } + // first relation is always order if the entity is not Order const index = config.options.populate.findIndex((p) => p === "order") if (index > -1) {