feat(core-flows): Refresh adjustments when editing orders (#13189)

* wip

* add tests

* add more tests

* fixes buy-get promotion

* Create empty-pillows-promise.md

* chore: use query graph

* Update packages/core/core-flows/src/order/workflows/order-edit/refresh-order-edit-adjustments.ts

Co-authored-by: Frane Polić <16856471+fPolic@users.noreply.github.com>

---------

Co-authored-by: Frane Polić <16856471+fPolic@users.noreply.github.com>
This commit is contained in:
Oli JuhlandFrane Polić authored and GitHub committed 2025-08-20 15:04:27 +02:00
1 parent d4a9728879
commit b152210554
22 files changed
+943 -152

No files matched your search

+7
View File
@@ -0,0 +1,7 @@
---
"@medusajs/test-utils": patch
"@medusajs/core-flows": patch
"@medusajs/framework": patch
---
feat(core-flows): Refresh adjustments when editing orders
+2
View File
@@ -30,3 +30,5 @@ dist/**
# Cache File # Cache File
/packages/**/.cache /packages/**/.cache
.cursorignore
@@ -1,8 +1,11 @@
import { medusaIntegrationTestRunner } from "@medusajs/test-utils" import { medusaIntegrationTestRunner } from "@medusajs/test-utils"
import { IOrderModuleService, IPromotionModuleService } from "@medusajs/types"
import { import {
ContainerRegistrationKeys, ContainerRegistrationKeys,
Modules, Modules,
OrderChangeStatus, OrderChangeStatus,
PromotionStatus,
PromotionType,
RuleOperator, RuleOperator,
} from "@medusajs/utils" } from "@medusajs/utils"
import { import {
@@ -26,14 +29,18 @@ medusaIntegrationTestRunner({
let inventoryItemExtra let inventoryItemExtra
let location let location
let locationTwo let locationTwo
let buyRuleProduct
let productExtra let productExtra
let container
let region
let salesChannel
const shippingProviderId = "manual_test-provider" const shippingProviderId = "manual_test-provider"
beforeEach(async () => { beforeEach(async () => {
const container = getContainer() container = getContainer()
await createAdminUser(dbConnection, adminHeaders, container) await createAdminUser(dbConnection, adminHeaders, container)
const region = ( region = (
await api.post( await api.post(
"/admin/regions", "/admin/regions",
{ {
@@ -80,7 +87,7 @@ medusaIntegrationTestRunner({
) )
).data.tax_rate ).data.tax_rate
const salesChannel = ( salesChannel = (
await api.post( await api.post(
"/admin/sales-channels", "/admin/sales-channels",
{ {
@@ -151,6 +158,31 @@ medusaIntegrationTestRunner({
) )
).data.product ).data.product
buyRuleProduct = (
await api.post(
"/admin/products",
{
title: "Buy rule product",
options: [{ title: "size", values: ["large", "small"] }],
shipping_profile_id: shippingProfile.id,
variants: [
{
title: "buy rule variant",
sku: "buy-rule-variant-sku",
options: { size: "large" },
prices: [
{
currency_code: "usd",
amount: 10,
},
],
},
],
},
adminHeaders
)
).data.product
const orderModule = container.resolve(Modules.ORDER) const orderModule = container.resolve(Modules.ORDER)
order = await orderModule.createOrders({ order = await orderModule.createOrders({
@@ -1145,5 +1177,493 @@ medusaIntegrationTestRunner({
) )
}) })
}) })
describe("Order Edits promotions", () => {
let appliedPromotion
let promotionModule: IPromotionModuleService
let orderModule: IOrderModuleService
beforeEach(async () => {
promotionModule = container.resolve(Modules.PROMOTION)
appliedPromotion = await promotionModule.createPromotions({
code: "PROMOTION_APPLIED",
type: PromotionType.STANDARD,
status: PromotionStatus.ACTIVE,
application_method: {
type: "percentage",
target_type: "order",
allocation: "across",
value: 10,
currency_code: "usd",
target_rules: [],
},
})
orderModule = container.resolve(Modules.ORDER)
order = await orderModule.createOrders({
email: "foo@bar.com",
region_id: region.id,
sales_channel_id: salesChannel.id,
items: [
{
// @ts-ignore
id: "item-1",
title: "Custom Item",
quantity: 1,
unit_price: 10,
},
],
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",
})
await orderModule.createOrderLineItemAdjustments([
{
code: appliedPromotion.code!,
amount: 1,
item_id: "item-1",
promotion_id: appliedPromotion.id,
},
])
const remoteLink = container.resolve(ContainerRegistrationKeys.LINK)
await remoteLink.create({
[Modules.ORDER]: { order_id: order.id },
[Modules.PROMOTION]: { promotion_id: appliedPromotion.id },
})
})
it("should update adjustments when adding a new item", async () => {
let result = await api.post(
"/admin/order-edits",
{
order_id: order.id,
description: "Test",
},
adminHeaders
)
const orderId = result.data.order_change.order_id
result = (await api.get(`/admin/orders/${orderId}`, adminHeaders)).data
.order
expect(result.original_total).toEqual(10)
expect(result.total).toEqual(9)
// Add item with price $12 + $1.2 in taxes
result = (
await api.post(
`/admin/order-edits/${orderId}/items`,
{
items: [
{
variant_id: productExtra.variants[0].id,
quantity: 1,
},
],
},
adminHeaders
)
).data.order_preview
// 10% discount on two items of $12 and $10 = $2.2
// Aside from this there is a tax rate of 10%, which adds ($1.2 - $0.12 (discount tax)) of taxes on the item of $12.
expect(result.total).toEqual(20.88)
expect(result.original_total).toEqual(23.2)
})
it("should update adjustments when updating an item", async () => {
let result = await api.post(
"/admin/order-edits",
{
order_id: order.id,
description: "Test",
},
adminHeaders
)
const orderId = result.data.order_change.order_id
const item = order.items[0]
result = (await api.get(`/admin/orders/${orderId}`, adminHeaders)).data
.order
expect(result.original_total).toEqual(10)
expect(result.total).toEqual(9)
let adjustments = result.items[0].adjustments
expect(adjustments).toEqual([
expect.objectContaining({
amount: 1,
item_id: item.id,
}),
])
// Update item quantity
result = (
await api.post(
`/admin/order-edits/${orderId}/items/item/${item.id}`,
{
quantity: 2,
},
adminHeaders
)
).data.order_preview
expect(result.total).toEqual(18)
expect(result.original_total).toEqual(20)
adjustments = result.items[0].adjustments
expect(adjustments).toEqual([
expect.objectContaining({
amount: 2,
item_id: item.id,
}),
])
})
it("should update adjustments when removing an item", async () => {
let result = await api.post(
"/admin/order-edits",
{
order_id: order.id,
description: "Test",
},
adminHeaders
)
const orderId = result.data.order_change.order_id
const item = order.items[0]
result = (await api.get(`/admin/orders/${orderId}`, adminHeaders)).data
.order
expect(result.original_total).toEqual(10)
expect(result.total).toEqual(9)
let adjustments = result.items[0].adjustments
expect(adjustments).toEqual([
expect.objectContaining({
amount: 1,
item_id: item.id,
}),
])
result = (
await api.post(
`/admin/order-edits/${orderId}/items`,
{
items: [
{
variant_id: productExtra.variants[0].id,
quantity: 1,
},
],
},
adminHeaders
)
).data.order_preview
const orderItems = result.items
expect(orderItems).toEqual([
expect.objectContaining({
adjustments: [
expect.objectContaining({
amount: 1,
item_id: item.id,
}),
],
}),
expect.objectContaining({
adjustments: [
expect.objectContaining({
amount: 1.2,
}),
],
}),
])
const newItem = result.items.find(
(item) => item.variant_id === productExtra.variants[0].id
)
const actionId = newItem.actions[0].id
result = (
await api.delete(
`/admin/order-edits/${orderId}/items/${actionId}`,
adminHeaders
)
).data.order_preview
adjustments = result.items[0].adjustments
expect(adjustments).toEqual([
expect.objectContaining({
amount: 1,
item_id: item.id,
}),
])
})
it("should not create adjustments when adding a new item if promotion is disabled", async () => {
let result = await api.post(
"/admin/order-edits",
{
order_id: order.id,
description: "Test",
},
adminHeaders
)
const orderId = result.data.order_change.order_id
result = (await api.get(`/admin/orders/${orderId}`, adminHeaders)).data
.order
expect(result.original_total).toEqual(10)
expect(result.total).toEqual(9)
await api.post(
`/admin/promotions/${appliedPromotion.id}`,
{
status: "draft",
},
adminHeaders
)
// Add item with price $12 + $1.2 in taxes
result = (
await api.post(
`/admin/order-edits/${orderId}/items`,
{
items: [
{
variant_id: productExtra.variants[0].id,
quantity: 1,
},
],
},
adminHeaders
)
).data.order_preview
expect(result.total).toEqual(23.2)
expect(result.original_total).toEqual(23.2)
})
it("should not change adjustments if order edit is canceled", async () => {
let result = await api.post(
"/admin/order-edits",
{
order_id: order.id,
description: "Test",
},
adminHeaders
)
const orderId = result.data.order_change.order_id
result = (await api.get(`/admin/orders/${orderId}`, adminHeaders)).data
.order
expect(result.original_total).toEqual(10)
expect(result.total).toEqual(9)
// Add item with price $12 + $1.2 in taxes
result = (
await api.post(
`/admin/order-edits/${orderId}/items`,
{
items: [
{
variant_id: productExtra.variants[0].id,
quantity: 1,
},
],
},
adminHeaders
)
).data.order_preview
expect(result.total).toEqual(20.88)
expect(result.original_total).toEqual(23.2)
await api.delete(`/admin/order-edits/${orderId}`, adminHeaders)
result = (await api.get(`/admin/orders/${orderId}`, adminHeaders)).data
.order
expect(result.original_total).toEqual(10)
expect(result.total).toEqual(9)
})
it("should add, remove, and add buy-get adjustment depending on the quantity of the buy rule product", async () => {
promotionModule = container.resolve(Modules.PROMOTION)
appliedPromotion = await promotionModule.createPromotions({
code: "BUY_GET_PROMO",
type: "buyget",
status: "active",
application_method: {
allocation: "each",
value: 100,
max_quantity: 1,
type: "percentage",
target_type: "items",
apply_to_quantity: 1,
buy_rules_min_quantity: 2,
target_rules: [
{
operator: "eq",
attribute: "items.product.id",
values: [productExtra.id],
},
],
buy_rules: [
{
operator: "eq",
attribute: "items.product.id",
values: [buyRuleProduct.id],
},
],
},
is_tax_inclusive: false,
is_automatic: true,
})
const orderModule: IOrderModuleService = container.resolve(
Modules.ORDER
)
order = await orderModule.createOrders({
email: "foo@bar.com",
region_id: region.id,
sales_channel_id: salesChannel.id,
items: [
{
variant_id: buyRuleProduct.variants[0].id,
quantity: 2,
title: "Buy rule product",
unit_price: 10,
product_id: buyRuleProduct.id,
},
{
variant_id: productExtra.variants[0].id,
quantity: 1,
title: "Extra product",
unit_price: 10,
product_id: productExtra.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",
})
await orderModule.createOrderLineItemAdjustments([
{
code: appliedPromotion.code!,
amount: 1,
item_id: "item-1",
promotion_id: appliedPromotion.id,
},
])
const remoteLink = container.resolve(ContainerRegistrationKeys.LINK)
await remoteLink.create({
[Modules.ORDER]: { order_id: order.id },
[Modules.PROMOTION]: { promotion_id: appliedPromotion.id },
})
// Initially, the buy-get adjustment should be added to the order
let result = await api.post(
"/admin/order-edits",
{
order_id: order.id,
description: "Test",
},
adminHeaders
)
const orderId = result.data.order_change.order_id
result = (await api.get(`/admin/orders/${orderId}`, adminHeaders)).data
.order
expect(result.original_total).toEqual(30)
expect(result.total).toEqual(20)
const buyRuleItem = result.items.find(
(item) => item.product_id === buyRuleProduct.id
)
// Update buy rule product quantity to 1
// This should remove the buy-get adjustment, as it is no longer valid
result = (
await api.post(
`/admin/order-edits/${orderId}/items/item/${buyRuleItem.id}`,
{
quantity: 1,
},
adminHeaders
)
).data.order_preview
expect(result.total).toEqual(20)
expect(result.original_total).toEqual(20)
// Canceling the order edit should bring back the buy-get adjustment
await api.delete(`/admin/order-edits/${orderId}`, adminHeaders)
result = (await api.get(`/admin/orders/${orderId}`, adminHeaders)).data
.order
expect(result.original_total).toEqual(30)
expect(result.total).toEqual(20)
})
})
}, },
}) })
@@ -28,6 +28,15 @@ export interface RefreshDraftOrderAdjustmentsWorkflowInput {
* The draft order to refresh the adjustments for. * The draft order to refresh the adjustments for.
*/ */
order: OrderDTO order: OrderDTO
// TODO: I will reintroduce this type, once I have migrated all of the order flows to fit the expected type.
// Doing this in a single PR is too much work, so I'm going to do it in smaller PRs.
//
// order: Omit<OrderDTO, "items"> & {
// items?: ComputeActionItemLine[]
// promotions?: PromotionDTO[]
// }
/** /**
* The promo codes to add or remove from the draft order. * The promo codes to add or remove from the draft order.
*/ */
@@ -10,9 +10,11 @@ import {
createWorkflow, createWorkflow,
transform, transform,
} from "@medusajs/framework/workflows-sdk" } from "@medusajs/framework/workflows-sdk"
import { useRemoteQueryStep } from "../../../common" import { useQueryGraphStep } from "../../../common"
import { createOrderChangeStep } from "../../steps/create-order-change" import { createOrderChangeStep } from "../../steps/create-order-change"
import { throwIfOrderIsCancelled } from "../../utils/order-validation" import { throwIfOrderIsCancelled } from "../../utils/order-validation"
import { refreshOrderEditAdjustmentsWorkflow } from "./refresh-order-edit-adjustments"
import { fieldsToRefreshOrderEdit } from "./utils/fields"
/** /**
* The data to validate that an order-edit can be requested for an order. * The data to validate that an order-edit can be requested for an order.
@@ -78,12 +80,17 @@ export const beginOrderEditOrderWorkflow = createWorkflow(
function ( function (
input: WorkflowData<OrderWorkflow.BeginorderEditWorkflowInput> input: WorkflowData<OrderWorkflow.BeginorderEditWorkflowInput>
): WorkflowResponse<OrderChangeDTO> { ): WorkflowResponse<OrderChangeDTO> {
const order: OrderDTO = useRemoteQueryStep({ const orderResult = useQueryGraphStep({
entry_point: "orders", entity: "order",
fields: ["id", "status"], fields: fieldsToRefreshOrderEdit,
variables: { id: input.order_id }, filters: { id: input.order_id },
list: false, options: {
throw_if_key_not_found: true, throwIfKeyNotFound: true,
},
})
const order = transform({ orderResult }, ({ orderResult }) => {
return orderResult.data[0]
}) })
beginOrderEditValidationStep({ order }) beginOrderEditValidationStep({ order })
@@ -97,6 +104,13 @@ export const beginOrderEditOrderWorkflow = createWorkflow(
internal_note: input.internal_note, internal_note: input.internal_note,
} }
}) })
refreshOrderEditAdjustmentsWorkflow.runAsStep({
input: {
order: order,
},
})
return new WorkflowResponse(createOrderChangeStep(orderChangeInput)) return new WorkflowResponse(createOrderChangeStep(orderChangeInput))
} }
) )
@@ -11,12 +11,14 @@ import {
parallelize, parallelize,
transform, transform,
} from "@medusajs/framework/workflows-sdk" } from "@medusajs/framework/workflows-sdk"
import { emitEventStep, useRemoteQueryStep } from "../../../common" import { emitEventStep, useQueryGraphStep } from "../../../common"
import { deleteOrderChangesStep, deleteOrderShippingMethods } from "../../steps" import { deleteOrderChangesStep, deleteOrderShippingMethods } from "../../steps"
import { import {
throwIfIsCancelled, throwIfIsCancelled,
throwIfOrderChangeIsNotActive, throwIfOrderChangeIsNotActive,
} from "../../utils/order-validation" } from "../../utils/order-validation"
import { refreshOrderEditAdjustmentsWorkflow } from "./refresh-order-edit-adjustments"
import { fieldsToRefreshOrderEdit } from "./utils/fields"
/** /**
* The data to validate that a requested order edit can be canceled. * The data to validate that a requested order edit can be canceled.
@@ -101,26 +103,35 @@ export const cancelBeginOrderEditWorkflow = createWorkflow(
function ( function (
input: WorkflowData<CancelBeginOrderEditWorkflowInput> input: WorkflowData<CancelBeginOrderEditWorkflowInput>
): WorkflowData<void> { ): WorkflowData<void> {
const order: OrderDTO = useRemoteQueryStep({ const orderResult = useQueryGraphStep({
entry_point: "orders", entity: "order",
fields: ["id", "version", "canceled_at"], fields: fieldsToRefreshOrderEdit,
variables: { id: input.order_id }, filters: { id: input.order_id },
list: false, options: {
throw_if_key_not_found: true, throwIfKeyNotFound: true,
},
}).config({ name: "order-query" }) }).config({ name: "order-query" })
const orderChange: OrderChangeDTO = useRemoteQueryStep({ const order = transform({ orderResult }, ({ orderResult }) => {
entry_point: "order_change", return orderResult.data[0]
})
const orderChangeResult = useQueryGraphStep({
entity: "order_change",
fields: ["id", "status", "version", "actions.*"], fields: ["id", "status", "version", "actions.*"],
variables: {
filters: { filters: {
order_id: input.order_id, order_id: input.order_id,
status: [OrderChangeStatus.PENDING, OrderChangeStatus.REQUESTED], status: [OrderChangeStatus.PENDING, OrderChangeStatus.REQUESTED],
}, },
},
list: false,
}).config({ name: "order-change-query" }) }).config({ name: "order-change-query" })
const orderChange = transform(
{ orderChangeResult },
({ orderChangeResult }) => {
return orderChangeResult.data[0]
}
)
cancelBeginOrderEditValidationStep({ order, orderChange }) cancelBeginOrderEditValidationStep({ order, orderChange })
const shippingToRemove = transform( const shippingToRemove = transform(
@@ -150,5 +161,11 @@ export const cancelBeginOrderEditWorkflow = createWorkflow(
data: eventData, data: eventData,
}) })
) )
refreshOrderEditAdjustmentsWorkflow.runAsStep({
input: {
order: order,
},
})
} }
) )
@@ -21,7 +21,11 @@ import {
prepareConfirmInventoryInput, prepareConfirmInventoryInput,
requiredOrderFieldsForInventoryConfirmation, requiredOrderFieldsForInventoryConfirmation,
} from "../../../cart/utils/prepare-confirm-inventory-input" } from "../../../cart/utils/prepare-confirm-inventory-input"
import { emitEventStep, useRemoteQueryStep } from "../../../common" import {
emitEventStep,
useQueryGraphStep,
useRemoteQueryStep,
} from "../../../common"
import { deleteReservationsByLineItemsStep } from "../../../reservation" import { deleteReservationsByLineItemsStep } from "../../../reservation"
import { previewOrderChangeStep } from "../../steps" import { previewOrderChangeStep } from "../../steps"
import { confirmOrderChanges } from "../../steps/confirm-order-changes" import { confirmOrderChanges } from "../../steps/confirm-order-changes"
@@ -30,6 +34,7 @@ import {
throwIfOrderChangeIsNotActive, throwIfOrderChangeIsNotActive,
} from "../../utils/order-validation" } from "../../utils/order-validation"
import { createOrUpdateOrderPaymentCollectionWorkflow } from "../create-or-update-order-payment-collection" import { createOrUpdateOrderPaymentCollectionWorkflow } from "../create-or-update-order-payment-collection"
import { fieldsToRefreshOrderEdit } from "./utils/fields"
/** /**
* The data to validate that a requested order edit can be confirmed. * The data to validate that a requested order edit can be confirmed.
@@ -118,26 +123,21 @@ export const confirmOrderEditRequestWorkflow = createWorkflow(
function ( function (
input: ConfirmOrderEditRequestWorkflowInput input: ConfirmOrderEditRequestWorkflowInput
): WorkflowResponse<OrderPreviewDTO> { ): WorkflowResponse<OrderPreviewDTO> {
const order: OrderDTO = useRemoteQueryStep({ const orderResult = useQueryGraphStep({
entry_point: "orders", entity: "order",
fields: [ fields: fieldsToRefreshOrderEdit,
"id", filters: { id: input.order_id },
"version", options: {
"canceled_at", throwIfKeyNotFound: true,
"items.id", },
"items.title",
"items.variant_title",
"items.variant_sku",
"items.variant_barcode",
"shipping_address.*",
],
variables: { id: input.order_id },
list: false,
throw_if_key_not_found: true,
}).config({ name: "order-query" }) }).config({ name: "order-query" })
const orderChange: OrderChangeDTO = useRemoteQueryStep({ const order = transform({ orderResult }, ({ orderResult }) => {
entry_point: "order_change", return orderResult.data[0]
})
const orderChangeResult = useQueryGraphStep({
entity: "order_change",
fields: [ fields: [
"id", "id",
"status", "status",
@@ -150,15 +150,19 @@ export const confirmOrderEditRequestWorkflow = createWorkflow(
"actions.reference_id", "actions.reference_id",
"actions.internal_note", "actions.internal_note",
], ],
variables: {
filters: { filters: {
order_id: input.order_id, order_id: input.order_id,
status: [OrderChangeStatus.PENDING, OrderChangeStatus.REQUESTED], status: [OrderChangeStatus.PENDING, OrderChangeStatus.REQUESTED],
}, },
},
list: false,
}).config({ name: "order-change-query" }) }).config({ name: "order-change-query" })
const orderChange = transform(
{ orderChangeResult },
({ orderChangeResult }) => {
return orderChangeResult.data[0]
}
)
confirmOrderEditRequestValidationStep({ confirmOrderEditRequestValidationStep({
order, order,
orderChange, orderChange,
@@ -13,6 +13,7 @@ import {
createWorkflow, createWorkflow,
transform, transform,
} from "@medusajs/framework/workflows-sdk" } from "@medusajs/framework/workflows-sdk"
import { pricingContextResult } from "../../../cart/utils/schemas"
import { useRemoteQueryStep } from "../../../common" import { useRemoteQueryStep } from "../../../common"
import { previewOrderChangeStep } from "../../steps" import { previewOrderChangeStep } from "../../steps"
import { createOrderShippingMethods } from "../../steps/create-order-shipping-methods" import { createOrderShippingMethods } from "../../steps/create-order-shipping-methods"
@@ -23,7 +24,6 @@ import {
import { prepareShippingMethod } from "../../utils/prepare-shipping-method" import { prepareShippingMethod } from "../../utils/prepare-shipping-method"
import { createOrderChangeActionsWorkflow } from "../create-order-change-actions" import { createOrderChangeActionsWorkflow } from "../create-order-change-actions"
import { updateOrderTaxLinesWorkflow } from "../update-tax-lines" import { updateOrderTaxLinesWorkflow } from "../update-tax-lines"
import { pricingContextResult } from "../../../cart/utils/schemas"
/** /**
* The data to validate that a shipping method can be created for an order edit. * The data to validate that a shipping method can be created for an order edit.
@@ -4,7 +4,10 @@ import {
OrderPreviewDTO, OrderPreviewDTO,
OrderWorkflow, OrderWorkflow,
} from "@medusajs/framework/types" } from "@medusajs/framework/types"
import { ChangeActionType, OrderChangeStatus } from "@medusajs/framework/utils" import {
ChangeActionType,
OrderChangeStatus
} from "@medusajs/framework/utils"
import { import {
WorkflowData, WorkflowData,
WorkflowResponse, WorkflowResponse,
@@ -12,7 +15,7 @@ import {
createWorkflow, createWorkflow,
transform, transform,
} from "@medusajs/framework/workflows-sdk" } from "@medusajs/framework/workflows-sdk"
import { useRemoteQueryStep } from "../../../common" import { useQueryGraphStep } from "../../../common"
import { previewOrderChangeStep } from "../../steps/preview-order-change" import { previewOrderChangeStep } from "../../steps/preview-order-change"
import { import {
throwIfIsCancelled, throwIfIsCancelled,
@@ -21,6 +24,8 @@ import {
import { addOrderLineItemsWorkflow } from "../add-line-items" import { addOrderLineItemsWorkflow } from "../add-line-items"
import { createOrderChangeActionsWorkflow } from "../create-order-change-actions" import { createOrderChangeActionsWorkflow } from "../create-order-change-actions"
import { updateOrderTaxLinesWorkflow } from "../update-tax-lines" import { updateOrderTaxLinesWorkflow } from "../update-tax-lines"
import { refreshOrderEditAdjustmentsWorkflow } from "./refresh-order-edit-adjustments"
import { fieldsToRefreshOrderEdit } from "./utils/fields"
/** /**
* The data to validate that new items can be added to an order edit. * The data to validate that new items can be added to an order edit.
@@ -101,26 +106,35 @@ export const orderEditAddNewItemWorkflow = createWorkflow(
function ( function (
input: WorkflowData<OrderWorkflow.OrderEditAddNewItemWorkflowInput> input: WorkflowData<OrderWorkflow.OrderEditAddNewItemWorkflowInput>
): WorkflowResponse<OrderPreviewDTO> { ): WorkflowResponse<OrderPreviewDTO> {
const order: OrderDTO = useRemoteQueryStep({ const orderResult = useQueryGraphStep({
entry_point: "orders", entity: "order",
fields: ["id", "status", "canceled_at", "items.*"], fields: fieldsToRefreshOrderEdit,
variables: { id: input.order_id }, filters: { id: input.order_id },
list: false, options: {
throw_if_key_not_found: true, throwIfKeyNotFound: true,
},
}).config({ name: "order-query" }) }).config({ name: "order-query" })
const orderChange: OrderChangeDTO = useRemoteQueryStep({ const order = transform({ orderResult }, ({ orderResult }) => {
entry_point: "order_change", return orderResult.data[0]
fields: ["id", "status"], })
variables: {
const orderChangeResult = useQueryGraphStep({
entity: "order_change",
fields: ["id", "status", "version", "actions.*"],
filters: { filters: {
order_id: input.order_id, order_id: input.order_id,
status: [OrderChangeStatus.PENDING, OrderChangeStatus.REQUESTED], status: [OrderChangeStatus.PENDING, OrderChangeStatus.REQUESTED],
}, },
},
list: false,
}).config({ name: "order-change-query" }) }).config({ name: "order-change-query" })
const orderChange = transform(
{ orderChangeResult },
({ orderChangeResult }) => {
return orderChangeResult.data[0]
}
)
orderEditAddNewItemValidationStep({ orderEditAddNewItemValidationStep({
order, order,
orderChange, orderChange,
@@ -170,6 +184,12 @@ export const orderEditAddNewItemWorkflow = createWorkflow(
input: orderChangeActionInput, input: orderChangeActionInput,
}) })
refreshOrderEditAdjustmentsWorkflow.runAsStep({
input: {
order: order,
},
})
return new WorkflowResponse(previewOrderChangeStep(input.order_id)) return new WorkflowResponse(previewOrderChangeStep(input.order_id))
} }
) )
@@ -17,13 +17,15 @@ import {
createWorkflow, createWorkflow,
transform, transform,
} from "@medusajs/framework/workflows-sdk" } from "@medusajs/framework/workflows-sdk"
import { useRemoteQueryStep } from "../../../common" import { useQueryGraphStep } from "../../../common"
import { previewOrderChangeStep } from "../../steps/preview-order-change" import { previewOrderChangeStep } from "../../steps/preview-order-change"
import { import {
throwIfIsCancelled, throwIfIsCancelled,
throwIfOrderChangeIsNotActive, throwIfOrderChangeIsNotActive,
} from "../../utils/order-validation" } from "../../utils/order-validation"
import { createOrderChangeActionsWorkflow } from "../create-order-change-actions" import { createOrderChangeActionsWorkflow } from "../create-order-change-actions"
import { refreshOrderEditAdjustmentsWorkflow } from "./refresh-order-edit-adjustments"
import { fieldsToRefreshOrderEdit } from "./utils/fields"
/** /**
* The data to validate that the quantity of an existing item in an order can be updated in an order edit. * The data to validate that the quantity of an existing item in an order can be updated in an order edit.
@@ -107,26 +109,35 @@ export const orderEditUpdateItemQuantityWorkflow = createWorkflow(
function ( function (
input: WorkflowData<OrderWorkflow.OrderEditUpdateItemQuantityWorkflowInput> input: WorkflowData<OrderWorkflow.OrderEditUpdateItemQuantityWorkflowInput>
): WorkflowResponse<OrderPreviewDTO> { ): WorkflowResponse<OrderPreviewDTO> {
const order: OrderDTO = useRemoteQueryStep({ const orderResult = useQueryGraphStep({
entry_point: "orders", entity: "order",
fields: ["id", "status", "canceled_at", "items.*"], fields: fieldsToRefreshOrderEdit,
variables: { id: input.order_id }, filters: { id: input.order_id },
list: false, options: {
throw_if_key_not_found: true, throwIfKeyNotFound: true,
},
}).config({ name: "order-query" }) }).config({ name: "order-query" })
const orderChange: OrderChangeDTO = useRemoteQueryStep({ const order = transform({ orderResult }, ({ orderResult }) => {
entry_point: "order_change", return orderResult.data[0]
fields: ["id", "status"], })
variables: {
const orderChangeResult = useQueryGraphStep({
entity: "order_change",
fields: ["id", "status", "version", "actions.*"],
filters: { filters: {
order_id: input.order_id, order_id: input.order_id,
status: [OrderChangeStatus.PENDING, OrderChangeStatus.REQUESTED], status: [OrderChangeStatus.PENDING, OrderChangeStatus.REQUESTED],
}, },
},
list: false,
}).config({ name: "order-change-query" }) }).config({ name: "order-change-query" })
const orderChange = transform(
{ orderChangeResult },
({ orderChangeResult }) => {
return orderChangeResult.data[0]
}
)
orderEditUpdateItemQuantityValidationStep({ orderEditUpdateItemQuantityValidationStep({
order, order,
orderChange, orderChange,
@@ -166,6 +177,12 @@ export const orderEditUpdateItemQuantityWorkflow = createWorkflow(
input: orderChangeActionInput, input: orderChangeActionInput,
}) })
refreshOrderEditAdjustmentsWorkflow.runAsStep({
input: {
order: order,
},
})
return new WorkflowResponse(previewOrderChangeStep(input.order_id)) return new WorkflowResponse(previewOrderChangeStep(input.order_id))
} }
) )
@@ -0,0 +1,79 @@
import { PromotionActions } from "@medusajs/framework/utils"
import {
createWorkflow,
transform,
WorkflowData,
WorkflowResponse,
} from "@medusajs/framework/workflows-sdk"
import {
ComputeActionItemLine,
OrderStatus,
PromotionDTO,
} from "@medusajs/types"
import {
refreshDraftOrderAdjustmentsWorkflow
} from "../../../draft-order/workflows/refresh-draft-order-adjustments"
import { previewOrderChangeStep } from "../../steps"
export const refreshOrderEditAdjustmentsWorkflowId =
"refresh-order-edit-adjustments"
/**
* The details of the order to refresh the adjustments for.
*/
export interface RefreshOrderEditAdjustmentsWorkflowInput {
/**
* The order edit to refresh the adjustments for.
*/
order: {
id: string
status: OrderStatus
currency_code: string
canceled_at?: string | Date
items: ComputeActionItemLine[]
promotions: PromotionDTO[]
}
}
export const refreshOrderEditAdjustmentsWorkflow = createWorkflow(
refreshOrderEditAdjustmentsWorkflowId,
function (input: WorkflowData<RefreshOrderEditAdjustmentsWorkflowInput>) {
const orderEditPromoCodes: string[] = transform({ input }, ({ input }) => {
return input.order.promotions
.map((p) => p?.code)
.filter(Boolean) as string[]
})
// we want the previewed order to contain updated promotions,
// so we fetch it to use it for refreshing adjustments
const orderPreview = previewOrderChangeStep(input.order.id).config({
name: "order-preview",
})
const orderToRefresh = transform(
{ input, orderPreview },
({ input, orderPreview }) => {
return {
...orderPreview,
items: orderPreview.items.map((item) => ({
...item,
// Buy-Get promotions rely on the product ID, so we need to manually set it before refreshing adjustments
product: { id: item.product_id },
})),
currency_code: input.order.currency_code,
promotions: input.order.promotions,
}
}
)
refreshDraftOrderAdjustmentsWorkflow.runAsStep({
input: {
order: orderToRefresh,
promo_codes: orderEditPromoCodes,
action: PromotionActions.REPLACE,
},
})
return new WorkflowResponse(void 0)
}
)
@@ -5,14 +5,18 @@ import {
OrderPreviewDTO, OrderPreviewDTO,
OrderWorkflow, OrderWorkflow,
} from "@medusajs/framework/types" } from "@medusajs/framework/types"
import { ChangeActionType, OrderChangeStatus } from "@medusajs/framework/utils" import {
ChangeActionType,
OrderChangeStatus
} from "@medusajs/framework/utils"
import { import {
WorkflowData, WorkflowData,
WorkflowResponse, WorkflowResponse,
createStep, createStep,
createWorkflow, createWorkflow,
transform,
} from "@medusajs/framework/workflows-sdk" } from "@medusajs/framework/workflows-sdk"
import { useRemoteQueryStep } from "../../../common" import { useQueryGraphStep } from "../../../common"
import { import {
deleteOrderChangeActionsStep, deleteOrderChangeActionsStep,
previewOrderChangeStep, previewOrderChangeStep,
@@ -21,6 +25,8 @@ import {
throwIfIsCancelled, throwIfIsCancelled,
throwIfOrderChangeIsNotActive, throwIfOrderChangeIsNotActive,
} from "../../utils/order-validation" } from "../../utils/order-validation"
import { refreshOrderEditAdjustmentsWorkflow } from "./refresh-order-edit-adjustments"
import { fieldsToRefreshOrderEdit } from "./utils/fields"
/** /**
* The data to validate that an item that was added in an order edit can be removed. * The data to validate that an item that was added in an order edit can be removed.
@@ -125,26 +131,35 @@ export const removeItemOrderEditActionWorkflow = createWorkflow(
function ( function (
input: WorkflowData<OrderWorkflow.DeleteOrderEditItemActionWorkflowInput> input: WorkflowData<OrderWorkflow.DeleteOrderEditItemActionWorkflowInput>
): WorkflowResponse<OrderPreviewDTO> { ): WorkflowResponse<OrderPreviewDTO> {
const order: OrderDTO = useRemoteQueryStep({ const orderResult = useQueryGraphStep({
entry_point: "orders", entity: "order",
fields: ["id", "status", "canceled_at", "items.*"], fields: fieldsToRefreshOrderEdit,
variables: { id: input.order_id }, filters: { id: input.order_id },
list: false, options: {
throw_if_key_not_found: true, throwIfKeyNotFound: true,
},
}).config({ name: "order-query" }) }).config({ name: "order-query" })
const orderChange: OrderChangeDTO = useRemoteQueryStep({ const order = transform({ orderResult }, ({ orderResult }) => {
entry_point: "order_change", return orderResult.data[0]
})
const orderChangeResult = useQueryGraphStep({
entity: "order_change",
fields: ["id", "status", "version", "actions.*"], fields: ["id", "status", "version", "actions.*"],
variables: {
filters: { filters: {
order_id: input.order_id, order_id: input.order_id,
status: [OrderChangeStatus.PENDING, OrderChangeStatus.REQUESTED], status: [OrderChangeStatus.PENDING, OrderChangeStatus.REQUESTED],
}, },
},
list: false,
}).config({ name: "order-change-query" }) }).config({ name: "order-change-query" })
const orderChange = transform(
{ orderChangeResult },
({ orderChangeResult }) => {
return orderChangeResult.data[0]
}
)
removeOrderEditItemActionValidationStep({ removeOrderEditItemActionValidationStep({
order, order,
input, input,
@@ -153,6 +168,12 @@ export const removeItemOrderEditActionWorkflow = createWorkflow(
deleteOrderChangeActionsStep({ ids: [input.action_id] }) deleteOrderChangeActionsStep({ ids: [input.action_id] })
refreshOrderEditAdjustmentsWorkflow.runAsStep({
input: {
order: order,
},
})
return new WorkflowResponse(previewOrderChangeStep(order.id)) return new WorkflowResponse(previewOrderChangeStep(order.id))
} }
) )
@@ -13,7 +13,7 @@ import {
parallelize, parallelize,
transform, transform,
} from "@medusajs/framework/workflows-sdk" } from "@medusajs/framework/workflows-sdk"
import { useRemoteQueryStep } from "../../../common" import { useQueryGraphStep } from "../../../common"
import { deleteOrderShippingMethods } from "../../steps" import { deleteOrderShippingMethods } from "../../steps"
import { deleteOrderChangeActionsStep } from "../../steps/delete-order-change-actions" import { deleteOrderChangeActionsStep } from "../../steps/delete-order-change-actions"
import { previewOrderChangeStep } from "../../steps/preview-order-change" import { previewOrderChangeStep } from "../../steps/preview-order-change"
@@ -30,7 +30,10 @@ export type RemoveOrderEditShippingMethodValidationStepInput = {
/** /**
* The details of the shipping method to be removed. * The details of the shipping method to be removed.
*/ */
input: Pick<OrderWorkflow.DeleteOrderEditShippingMethodWorkflowInput, "order_id" | "action_id"> input: Pick<
OrderWorkflow.DeleteOrderEditShippingMethodWorkflowInput,
"order_id" | "action_id"
>
} }
/** /**
@@ -108,18 +111,22 @@ export const removeOrderEditShippingMethodWorkflow = createWorkflow(
function ( function (
input: WorkflowData<OrderWorkflow.DeleteOrderEditShippingMethodWorkflowInput> input: WorkflowData<OrderWorkflow.DeleteOrderEditShippingMethodWorkflowInput>
): WorkflowResponse<OrderPreviewDTO> { ): WorkflowResponse<OrderPreviewDTO> {
const orderChange: OrderChangeDTO = useRemoteQueryStep({ const orderChangeResult = useQueryGraphStep({
entry_point: "order_change", entity: "order_change",
fields: ["id", "status", "version", "actions.*"], fields: ["id", "status", "version", "actions.*"],
variables: {
filters: { filters: {
order_id: input.order_id, order_id: input.order_id,
status: [OrderChangeStatus.PENDING, OrderChangeStatus.REQUESTED], status: [OrderChangeStatus.PENDING, OrderChangeStatus.REQUESTED],
}, },
},
list: false,
}).config({ name: "order-change-query" }) }).config({ name: "order-change-query" })
const orderChange = transform(
{ orderChangeResult },
({ orderChangeResult }) => {
return orderChangeResult.data[0]
}
)
removeOrderEditShippingMethodValidationStep({ removeOrderEditShippingMethodValidationStep({
orderChange, orderChange,
input, input,
@@ -13,13 +13,15 @@ import {
createWorkflow, createWorkflow,
transform, transform,
} from "@medusajs/framework/workflows-sdk" } from "@medusajs/framework/workflows-sdk"
import { emitEventStep, useRemoteQueryStep } from "../../../common" import { emitEventStep, useQueryGraphStep } from "../../../common"
import { previewOrderChangeStep } from "../../steps" import { previewOrderChangeStep } from "../../steps"
import { updateOrderChangesStep } from "../../steps/update-order-changes" import { updateOrderChangesStep } from "../../steps/update-order-changes"
import { import {
throwIfIsCancelled, throwIfIsCancelled,
throwIfOrderChangeIsNotActive, throwIfOrderChangeIsNotActive,
} from "../../utils/order-validation" } from "../../utils/order-validation"
import { refreshOrderEditAdjustmentsWorkflow } from "./refresh-order-edit-adjustments"
import { fieldsToRefreshOrderEdit } from "./utils/fields"
function getOrderChangesData({ function getOrderChangesData({
input, input,
@@ -127,26 +129,35 @@ export const requestOrderEditRequestWorkflow = createWorkflow(
function ( function (
input: OrderEditRequestWorkflowInput input: OrderEditRequestWorkflowInput
): WorkflowResponse<OrderPreviewDTO> { ): WorkflowResponse<OrderPreviewDTO> {
const order: OrderDTO = useRemoteQueryStep({ const orderResult = useQueryGraphStep({
entry_point: "orders", entity: "order",
fields: ["id", "version", "canceled_at"], fields: fieldsToRefreshOrderEdit,
variables: { id: input.order_id }, filters: { id: input.order_id },
list: false, options: {
throw_if_key_not_found: true, throwIfKeyNotFound: true,
},
}).config({ name: "order-query" }) }).config({ name: "order-query" })
const orderChange: OrderChangeDTO = useRemoteQueryStep({ const order = transform({ orderResult }, ({ orderResult }) => {
entry_point: "order_change", return orderResult.data[0]
fields: ["id", "canceled_at", "actions.*"], })
variables: {
const orderChangeResult = useQueryGraphStep({
entity: "order_change",
fields: ["id", "status", "version", "actions.*"],
filters: { filters: {
order_id: input.order_id, order_id: input.order_id,
status: [OrderChangeStatus.PENDING, OrderChangeStatus.REQUESTED], status: [OrderChangeStatus.PENDING, OrderChangeStatus.REQUESTED],
}, },
},
list: false,
}).config({ name: "order-change-query" }) }).config({ name: "order-change-query" })
const orderChange = transform(
{ orderChangeResult },
({ orderChangeResult }) => {
return orderChangeResult.data[0]
}
)
requestOrderEditRequestValidationStep({ requestOrderEditRequestValidationStep({
order, order,
orderChange, orderChange,
@@ -165,6 +176,12 @@ export const requestOrderEditRequestWorkflow = createWorkflow(
} }
) )
refreshOrderEditAdjustmentsWorkflow.runAsStep({
input: {
order: order,
},
})
emitEventStep({ emitEventStep({
eventName: OrderEditWorkflowEvents.REQUESTED, eventName: OrderEditWorkflowEvents.REQUESTED,
data: eventData, data: eventData,
@@ -13,7 +13,7 @@ import {
createWorkflow, createWorkflow,
transform, transform,
} from "@medusajs/framework/workflows-sdk" } from "@medusajs/framework/workflows-sdk"
import { useRemoteQueryStep } from "../../../common" import { useQueryGraphStep } from "../../../common"
import { import {
previewOrderChangeStep, previewOrderChangeStep,
updateOrderChangeActionsStep, updateOrderChangeActionsStep,
@@ -22,6 +22,8 @@ import {
throwIfIsCancelled, throwIfIsCancelled,
throwIfOrderChangeIsNotActive, throwIfOrderChangeIsNotActive,
} from "../../utils/order-validation" } from "../../utils/order-validation"
import { refreshOrderEditAdjustmentsWorkflow } from "./refresh-order-edit-adjustments"
import { fieldsToRefreshOrderEdit } from "./utils/fields"
/** /**
* The data to validate that a new item can be updated in an order edit. * The data to validate that a new item can be updated in an order edit.
@@ -76,11 +78,7 @@ export type UpdateOrderEditAddItemValidationStepInput = {
export const updateOrderEditAddItemValidationStep = createStep( export const updateOrderEditAddItemValidationStep = createStep(
"update-order-edit-add-item-validation", "update-order-edit-add-item-validation",
async function ( async function (
{ { order, orderChange, input }: UpdateOrderEditAddItemValidationStepInput,
order,
orderChange,
input,
}: UpdateOrderEditAddItemValidationStepInput,
context context
) { ) {
throwIfIsCancelled(order, "Order") throwIfIsCancelled(order, "Order")
@@ -129,26 +127,35 @@ export const updateOrderEditAddItemWorkflow = createWorkflow(
function ( function (
input: WorkflowData<OrderWorkflow.UpdateOrderEditAddNewItemWorkflowInput> input: WorkflowData<OrderWorkflow.UpdateOrderEditAddNewItemWorkflowInput>
): WorkflowResponse<OrderPreviewDTO> { ): WorkflowResponse<OrderPreviewDTO> {
const order: OrderDTO = useRemoteQueryStep({ const orderResult = useQueryGraphStep({
entry_point: "orders", entity: "order",
fields: ["id", "status", "canceled_at", "items.*"], fields: fieldsToRefreshOrderEdit,
variables: { id: input.order_id }, filters: { id: input.order_id },
list: false, options: {
throw_if_key_not_found: true, throwIfKeyNotFound: true,
},
}).config({ name: "order-query" }) }).config({ name: "order-query" })
const orderChange: OrderChangeDTO = useRemoteQueryStep({ const order = transform({ orderResult }, ({ orderResult }) => {
entry_point: "order_change", return orderResult.data[0]
})
const orderChangeResult = useQueryGraphStep({
entity: "order_change",
fields: ["id", "status", "version", "actions.*"], fields: ["id", "status", "version", "actions.*"],
variables: {
filters: { filters: {
order_id: input.order_id, order_id: input.order_id,
status: [OrderChangeStatus.PENDING, OrderChangeStatus.REQUESTED], status: [OrderChangeStatus.PENDING, OrderChangeStatus.REQUESTED],
}, },
},
list: false,
}).config({ name: "order-change-query" }) }).config({ name: "order-change-query" })
const orderChange = transform(
{ orderChangeResult },
({ orderChangeResult }) => {
return orderChangeResult.data[0]
}
)
updateOrderEditAddItemValidationStep({ updateOrderEditAddItemValidationStep({
order, order,
input, input,
@@ -179,6 +186,12 @@ export const updateOrderEditAddItemWorkflow = createWorkflow(
updateOrderChangeActionsStep([updateData]) updateOrderChangeActionsStep([updateData])
refreshOrderEditAdjustmentsWorkflow.runAsStep({
input: {
order: order,
},
})
return new WorkflowResponse(previewOrderChangeStep(order.id)) return new WorkflowResponse(previewOrderChangeStep(order.id))
} }
) )
@@ -13,7 +13,7 @@ import {
createWorkflow, createWorkflow,
transform, transform,
} from "@medusajs/framework/workflows-sdk" } from "@medusajs/framework/workflows-sdk"
import { useRemoteQueryStep } from "../../../common" import { useQueryGraphStep } from "../../../common"
import { import {
previewOrderChangeStep, previewOrderChangeStep,
updateOrderChangeActionsStep, updateOrderChangeActionsStep,
@@ -22,6 +22,8 @@ import {
throwIfIsCancelled, throwIfIsCancelled,
throwIfOrderChangeIsNotActive, throwIfOrderChangeIsNotActive,
} from "../../utils/order-validation" } from "../../utils/order-validation"
import { refreshOrderEditAdjustmentsWorkflow } from "./refresh-order-edit-adjustments"
import { fieldsToRefreshOrderEdit } from "./utils/fields"
/** /**
* The data to validate that an existing order item can be updated in an order edit. * The data to validate that an existing order item can be updated in an order edit.
@@ -129,26 +131,35 @@ export const updateOrderEditItemQuantityWorkflow = createWorkflow(
function ( function (
input: WorkflowData<OrderWorkflow.UpdateOrderEditItemQuantityWorkflowInput> input: WorkflowData<OrderWorkflow.UpdateOrderEditItemQuantityWorkflowInput>
): WorkflowResponse<OrderPreviewDTO> { ): WorkflowResponse<OrderPreviewDTO> {
const order: OrderDTO = useRemoteQueryStep({ const orderResult = useQueryGraphStep({
entry_point: "orders", entity: "order",
fields: ["id", "status", "canceled_at", "items.*"], fields: fieldsToRefreshOrderEdit,
variables: { id: input.order_id }, filters: { id: input.order_id },
list: false, options: {
throw_if_key_not_found: true, throwIfKeyNotFound: true,
},
}).config({ name: "order-query" }) }).config({ name: "order-query" })
const orderChange: OrderChangeDTO = useRemoteQueryStep({ const order = transform({ orderResult }, ({ orderResult }) => {
entry_point: "order_change", return orderResult.data[0]
})
const orderChangeResult = useQueryGraphStep({
entity: "order_change",
fields: ["id", "status", "version", "actions.*"], fields: ["id", "status", "version", "actions.*"],
variables: {
filters: { filters: {
order_id: input.order_id, order_id: input.order_id,
status: [OrderChangeStatus.PENDING, OrderChangeStatus.REQUESTED], status: [OrderChangeStatus.PENDING, OrderChangeStatus.REQUESTED],
}, },
},
list: false,
}).config({ name: "order-change-query" }) }).config({ name: "order-change-query" })
const orderChange = transform(
{ orderChangeResult },
({ orderChangeResult }) => {
return orderChangeResult.data[0]
}
)
updateOrderEditItemQuantityValidationStep({ updateOrderEditItemQuantityValidationStep({
order, order,
input, input,
@@ -175,6 +186,12 @@ export const updateOrderEditItemQuantityWorkflow = createWorkflow(
updateOrderChangeActionsStep([updateData]) updateOrderChangeActionsStep([updateData])
refreshOrderEditAdjustmentsWorkflow.runAsStep({
input: {
order: order,
},
})
return new WorkflowResponse(previewOrderChangeStep(order.id)) return new WorkflowResponse(previewOrderChangeStep(order.id))
} }
) )
@@ -2,7 +2,6 @@ import {
AdditionalData, AdditionalData,
OrderChangeActionDTO, OrderChangeActionDTO,
OrderChangeDTO, OrderChangeDTO,
OrderDTO,
OrderPreviewDTO, OrderPreviewDTO,
OrderWorkflow, OrderWorkflow,
} from "@medusajs/framework/types" } from "@medusajs/framework/types"
@@ -17,7 +16,8 @@ import {
transform, transform,
when, when,
} from "@medusajs/framework/workflows-sdk" } from "@medusajs/framework/workflows-sdk"
import { useRemoteQueryStep } from "../../../common" import { pricingContextResult } from "../../../cart/utils/schemas"
import { useQueryGraphStep, useRemoteQueryStep } from "../../../common"
import { import {
updateOrderChangeActionsStep, updateOrderChangeActionsStep,
updateOrderShippingMethodsStep, updateOrderShippingMethodsStep,
@@ -25,7 +25,7 @@ import {
import { previewOrderChangeStep } from "../../steps/preview-order-change" import { previewOrderChangeStep } from "../../steps/preview-order-change"
import { throwIfOrderChangeIsNotActive } from "../../utils/order-validation" import { throwIfOrderChangeIsNotActive } from "../../utils/order-validation"
import { prepareShippingMethodUpdate } from "../../utils/prepare-shipping-method" import { prepareShippingMethodUpdate } from "../../utils/prepare-shipping-method"
import { pricingContextResult } from "../../../cart/utils/schemas" import { fieldsToRefreshOrderEdit } from "./utils/fields"
/** /**
* The data to validate that an order edit's shipping method can be updated. * The data to validate that an order edit's shipping method can be updated.
@@ -162,26 +162,35 @@ export const updateOrderEditShippingMethodWorkflow = createWorkflow(
OrderWorkflow.UpdateOrderEditShippingMethodWorkflowInput & AdditionalData OrderWorkflow.UpdateOrderEditShippingMethodWorkflowInput & AdditionalData
> >
) { ) {
const order: OrderDTO = useRemoteQueryStep({ const orderResult = useQueryGraphStep({
entry_point: "order_claim", entity: "order",
fields: ["id", "currency_code"], fields: fieldsToRefreshOrderEdit,
variables: { id: input.order_id }, filters: { id: input.order_id },
list: false, options: {
throw_if_key_not_found: true, throwIfKeyNotFound: true,
},
}).config({ name: "order-query" })
const order = transform({ orderResult }, ({ orderResult }) => {
return orderResult.data[0]
}) })
const orderChange: OrderChangeDTO = useRemoteQueryStep({ const orderChangeResult = useQueryGraphStep({
entry_point: "order_change", entity: "order_change",
fields: ["id", "status", "version", "actions.*"], fields: ["id", "status", "version", "actions.*"],
variables: {
filters: { filters: {
order_id: input.order_id, order_id: input.order_id,
status: [OrderChangeStatus.PENDING, OrderChangeStatus.REQUESTED], status: [OrderChangeStatus.PENDING, OrderChangeStatus.REQUESTED],
}, },
},
list: false,
}).config({ name: "order-change-query" }) }).config({ name: "order-change-query" })
const orderChange = transform(
{ orderChangeResult },
({ orderChangeResult }) => {
return orderChangeResult.data[0]
}
)
const setPricingContext = createHook( const setPricingContext = createHook(
"setPricingContext", "setPricingContext",
{ {
@@ -0,0 +1,11 @@
export const fieldsToRefreshOrderEdit = [
"id",
"status",
"version",
"currency_code",
"canceled_at",
"items.*",
"items.product.id",
"promotions.*",
"shipping_address.*",
]
+1 -1
View File
@@ -85,7 +85,7 @@
"@opentelemetry/api": "^1.9.0", "@opentelemetry/api": "^1.9.0",
"@types/express": "^4.17.17", "@types/express": "^4.17.17",
"chokidar": "^3.4.2", "chokidar": "^3.4.2",
"compression": "1.7.4", "compression": "1.8.0",
"connect-redis": "5.2.0", "connect-redis": "5.2.0",
"cookie-parser": "^1.4.6", "cookie-parser": "^1.4.6",
"cors": "^2.8.5", "cors": "^2.8.5",
@@ -199,6 +199,13 @@ export interface ComputeActionItemLine extends Record<string, unknown> {
* The adjustments applied before on the line item. * The adjustments applied before on the line item.
*/ */
adjustments?: ComputeActionAdjustmentLine[] adjustments?: ComputeActionAdjustmentLine[]
/**
* The product ID of the line item. Our default promotion rules rely on the product ID to apply the promotion.
*/
product?: {
id: string
}
} }
/** /**
+1 -1
View File
@@ -1,3 +1,4 @@
import { logger } from "@medusajs/framework/logger"
import { import {
defineConfig, defineConfig,
MikroORM, MikroORM,
@@ -5,7 +6,6 @@ import {
SqlEntityManager, SqlEntityManager,
} from "@mikro-orm/postgresql" } from "@mikro-orm/postgresql"
import { createDatabase, dropDatabase } from "pg-god" import { createDatabase, dropDatabase } from "pg-god"
import { logger } from "@medusajs/framework/logger"
import { execOrTimeout } from "./medusa-test-runner-utils" import { execOrTimeout } from "./medusa-test-runner-utils"
const DB_HOST = process.env.DB_HOST ?? "localhost" const DB_HOST = process.env.DB_HOST ?? "localhost"
+2 -2
View File
@@ -6324,7 +6324,7 @@ __metadata:
"@types/jsonwebtoken": ^8.5.9 "@types/jsonwebtoken": ^8.5.9
awilix: ^8.0.1 awilix: ^8.0.1
chokidar: ^3.4.2 chokidar: ^3.4.2
compression: 1.7.4 compression: 1.8.0
connect-dynamodb: ^3.0.5 connect-dynamodb: ^3.0.5
connect-redis: 5.2.0 connect-redis: 5.2.0
cookie-parser: ^1.4.6 cookie-parser: ^1.4.6
@@ -18610,7 +18610,7 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"compression@npm:^1.7.5": "compression@npm:1.8.0, compression@npm:^1.7.5":
version: 1.8.0 version: 1.8.0
resolution: "compression@npm:1.8.0" resolution: "compression@npm:1.8.0"
dependencies: dependencies: