feat(core-flows): manage inventory reservation of claims and exchanges (#8448)
This commit is contained in:
committed by
GitHub
parent
3ac235e098
commit
1fb679e785
@@ -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)
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
@@ -489,7 +489,7 @@ medusaIntegrationTestRunner({
|
||||
|
||||
result = (
|
||||
await api.get(
|
||||
`/admin/exchanges?fields=*additional_items`,
|
||||
`/admin/exchanges?fields=+metadata,*additional_items`,
|
||||
adminHeaders
|
||||
)
|
||||
).data.exchanges
|
||||
|
||||
@@ -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,
|
||||
},
|
||||
},
|
||||
{
|
||||
|
||||
@@ -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),
|
||||
})
|
||||
},
|
||||
|
||||
@@ -68,6 +68,7 @@ export const completeCartWorkflow = createWorkflow(
|
||||
|
||||
const formatedInventoryItems = confirmVariantInventoryWorkflow.runAsStep({
|
||||
input: {
|
||||
skipInventoryCheck: true,
|
||||
sales_channel_id,
|
||||
variants,
|
||||
items,
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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<string, ShippingOptionDTO>(
|
||||
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)
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 }) => {
|
||||
|
||||
@@ -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<string, unknown> | null }
|
||||
reservations: ReservationItemDTO[]
|
||||
itemsList?: OrderLineItemDTO[]
|
||||
}) {
|
||||
const inputItems = input.items
|
||||
const orderItemsMap = new Map<string, Required<OrderDTO>["items"][0]>(
|
||||
order.items!.map((i) => [i.id, i])
|
||||
(itemsList ?? order.items)!.map((i) => [i.id, i])
|
||||
)
|
||||
const reservationItemMap = new Map<string, ReservationItemDTO>(
|
||||
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
|
||||
)
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 }) => {
|
||||
|
||||
@@ -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,
|
||||
})
|
||||
}
|
||||
)
|
||||
|
||||
@@ -14,7 +14,6 @@ import {
|
||||
deepFlatMap,
|
||||
} from "@medusajs/utils"
|
||||
import {
|
||||
WorkflowData,
|
||||
WorkflowResponse,
|
||||
createStep,
|
||||
createWorkflow,
|
||||
|
||||
@@ -122,6 +122,7 @@ export interface CompleteCartWorkflowInputDTO {
|
||||
}
|
||||
|
||||
export interface ConfirmVariantInventoryWorkflowInputDTO {
|
||||
skipInventoryCheck?: boolean
|
||||
sales_channel_id: string
|
||||
variants: {
|
||||
id: string
|
||||
|
||||
@@ -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<UpdateOrderExchangeDTO>
|
||||
}
|
||||
|
||||
/**
|
||||
* The details of canceling a return.
|
||||
*/
|
||||
export interface CancelOrderReturnDTO
|
||||
extends Omit<BaseOrderBundledActionsDTO, "order_id"> {
|
||||
/**
|
||||
* 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<BaseOrderBundledActionsDTO, "order_id"> {
|
||||
/**
|
||||
* 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<BaseOrderBundledActionsDTO, "order_id"> {
|
||||
/**
|
||||
* The exchange's ID.
|
||||
*/
|
||||
export interface CancelOrderExchangeDTO extends BaseOrderBundledActionsDTO {
|
||||
exchange_id: string
|
||||
}
|
||||
|
||||
|
||||
@@ -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[]
|
||||
|
||||
@@ -278,6 +278,7 @@ export default class InventoryModuleService
|
||||
},
|
||||
context
|
||||
)
|
||||
|
||||
const created = await this.reservationItemService_.create(input, context)
|
||||
|
||||
const adjustments: Map<string, Map<string, number>> = input.reduce(
|
||||
|
||||
@@ -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<T>(klass: Constructor<T>, entity: any) {
|
||||
@@ -36,6 +36,15 @@ export function setFindMethods<T>(klass: Constructor<T>, 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<T>(klass: Constructor<T>, 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) {
|
||||
|
||||
Reference in New Issue
Block a user