diff --git a/integration-tests/modules/__tests__/order/workflows/order-change-actions.ts b/integration-tests/modules/__tests__/order/workflows/order-change-actions.ts index 03b9d2c70d..6070a423da 100644 --- a/integration-tests/modules/__tests__/order/workflows/order-change-actions.ts +++ b/integration-tests/modules/__tests__/order/workflows/order-change-actions.ts @@ -4,8 +4,15 @@ import { createOrderChangeWorkflow, deleteOrderChangeActionsWorkflow, deleteOrderChangeActionsWorkflowId, + updateOrderChangeActionsWorkflow, + updateOrderChangeActionsWorkflowId, } from "@medusajs/core-flows" -import { IOrderModuleService, OrderChangeDTO, OrderDTO } from "@medusajs/types" +import { + IOrderModuleService, + OrderChangeActionDTO, + OrderChangeDTO, + OrderDTO, +} from "@medusajs/types" import { ChangeActionType, ModuleRegistrationName } from "@medusajs/utils" import { medusaIntegrationTestRunner } from "medusa-test-utils" import { createOrderFixture, prepareDataFixtures } from "./__fixtures__" @@ -44,7 +51,7 @@ medusaIntegrationTestRunner({ service = container.resolve(ModuleRegistrationName.ORDER) }) - describe("createOrderChangeActionWorkflow", () => { + describe("createOrderChangeActionsWorkflow", () => { it("should successfully create an order change action", async () => { const { result } = await createOrderChangeActionsWorkflow( container @@ -212,6 +219,77 @@ medusaIntegrationTestRunner({ ) }) }) + + describe("updateOrderChangeActionWorkflow", () => { + let createdOrderAction: OrderChangeActionDTO + + beforeEach(async () => { + const { result } = await createOrderChangeActionsWorkflow( + container + ).run({ + input: [ + { + action: ChangeActionType.ITEM_ADD, + order_change_id: orderChange.id, + order_id: order.id, + internal_note: "existing", + }, + ], + }) + + createdOrderAction = result[0] + }) + + it("should successfully update an order change action", async () => { + const { + result: [updatedOrderChange], + } = await updateOrderChangeActionsWorkflow(container).run({ + input: [ + { + id: createdOrderAction.id, + internal_note: "new", + }, + ], + }) + + expect(updatedOrderChange).toEqual( + expect.objectContaining({ + id: createdOrderAction.id, + internal_note: "new", + }) + ) + }) + + it("should rollback to original state when a future step has an error", async () => { + const workflow = updateOrderChangeActionsWorkflow(container) + + workflow.appendAction("throw", updateOrderChangeActionsWorkflowId, { + invoke: async function failStep() { + throw new Error(`Fail`) + }, + }) + + const { + errors: [error], + } = await workflow.run({ + input: [ + { + id: createdOrderAction.id, + internal_note: "new", + }, + ], + throwOnError: false, + }) + + const orderChangeAction = await service.retrieveOrderChangeAction( + createdOrderAction.id, + {} + ) + + expect(error).toBeDefined() + expect(orderChangeAction.internal_note).toEqual("existing") + }) + }) }) }, }) diff --git a/packages/core/core-flows/src/order/steps/index.ts b/packages/core/core-flows/src/order/steps/index.ts index 69799ad019..d7e3260aad 100644 --- a/packages/core/core-flows/src/order/steps/index.ts +++ b/packages/core/core-flows/src/order/steps/index.ts @@ -15,4 +15,5 @@ export * from "./get-item-tax-lines" export * from "./register-fulfillment" export * from "./register-shipment" export * from "./set-tax-lines-for-items" +export * from "./update-order-change-actions" export * from "./update-tax-lines" diff --git a/packages/core/core-flows/src/order/steps/update-order-change-actions.ts b/packages/core/core-flows/src/order/steps/update-order-change-actions.ts new file mode 100644 index 0000000000..6e88c2020e --- /dev/null +++ b/packages/core/core-flows/src/order/steps/update-order-change-actions.ts @@ -0,0 +1,42 @@ +import { + IOrderModuleService, + UpdateOrderChangeActionDTO, +} from "@medusajs/types" +import { + getSelectsAndRelationsFromObjectArray, + ModuleRegistrationName, +} from "@medusajs/utils" +import { createStep, StepResponse } from "@medusajs/workflows-sdk" + +export const updateOrderChangeActionsStepId = "update-order-change-actions" +export const updateOrderChangeActionsStep = createStep( + updateOrderChangeActionsStepId, + async (data: UpdateOrderChangeActionDTO[], { container }) => { + const service = container.resolve( + ModuleRegistrationName.ORDER + ) + + const { selects, relations } = getSelectsAndRelationsFromObjectArray(data, { + objectFields: ["metadata"], + }) + const dataBeforeUpdate = await service.listOrderChangeActions( + { id: data.map((d) => d.id) }, + { relations, select: selects } + ) + + const updated = await service.updateOrderChangeActions(data) + + return new StepResponse(updated, dataBeforeUpdate) + }, + async (dataBeforeUpdate, { container }) => { + if (!dataBeforeUpdate?.length) { + return + } + + const service = container.resolve( + ModuleRegistrationName.ORDER + ) + + await service.updateOrderChangeActions(dataBeforeUpdate) + } +) diff --git a/packages/core/core-flows/src/order/workflows/index.ts b/packages/core/core-flows/src/order/workflows/index.ts index 652932095a..229924348d 100644 --- a/packages/core/core-flows/src/order/workflows/index.ts +++ b/packages/core/core-flows/src/order/workflows/index.ts @@ -16,4 +16,5 @@ export * from "./delete-order-change-actions" export * from "./get-order-detail" export * from "./get-orders-list" export * from "./receive-return" +export * from "./update-order-change-actions" export * from "./update-tax-lines" diff --git a/packages/core/core-flows/src/order/workflows/update-order-change-actions.ts b/packages/core/core-flows/src/order/workflows/update-order-change-actions.ts new file mode 100644 index 0000000000..785449140f --- /dev/null +++ b/packages/core/core-flows/src/order/workflows/update-order-change-actions.ts @@ -0,0 +1,16 @@ +import { + OrderChangeActionDTO, + UpdateOrderChangeActionDTO, +} from "@medusajs/types" +import { WorkflowData, createWorkflow } from "@medusajs/workflows-sdk" +import { updateOrderChangeActionsStep } from "../steps" + +export const updateOrderChangeActionsWorkflowId = "update-order-change-actions" +export const updateOrderChangeActionsWorkflow = createWorkflow( + updateOrderChangeActionsWorkflowId, + ( + input: WorkflowData + ): WorkflowData => { + return updateOrderChangeActionsStep(input) + } +) diff --git a/packages/core/types/src/order/service.ts b/packages/core/types/src/order/service.ts index 4d80a35ffd..5aae2327f6 100644 --- a/packages/core/types/src/order/service.ts +++ b/packages/core/types/src/order/service.ts @@ -4,6 +4,7 @@ import { IModuleService } from "../modules-sdk" import { Context } from "../shared-context" import { FilterableOrderAddressProps, + FilterableOrderChangeActionProps, FilterableOrderLineItemAdjustmentProps, FilterableOrderLineItemProps, FilterableOrderLineItemTaxLineProps, @@ -59,6 +60,7 @@ import { RegisterOrderFulfillmentDTO, RegisterOrderShipmentDTO, UpdateOrderAddressDTO, + UpdateOrderChangeActionDTO, UpdateOrderChangeDTO, UpdateOrderDTO, UpdateOrderItemDTO, @@ -1535,6 +1537,99 @@ export interface IOrderModuleService extends IModuleService { sharedContext?: Context ): Promise + /** + * This method retrieves a paginated list of {return type}(s) based on optional filters and configuration. + * + * @param {FilterableOrderChangeActionProps} filters - The filters to apply on the retrieved order change action. + * @param {FindConfig} config - The configurations determining how the order is retrieved. Its properties, such as `select` or `relations`, accept the + * attributes or relations associated with a order. + * @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module. + * @returns {Promise} The list of {return type}(s). + * + * @example + * ```typescript + * const orderChangeActions = await orderModuleService.listOrderChangeActions(); + * ``` + * + */ + listOrderChangeActions( + filters?: FilterableOrderChangeActionProps, + config?: FindConfig, + sharedContext?: Context + ): Promise + + /** + * This method retrieves a {return type} by its ID. + * + * @param {string} actionId - The order change action's ID. + * @param {FindConfig} config - The configurations determining how the order is retrieved. Its properties, such as `select` or `relations`, accept the + * attributes or relations associated with a order. + * @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module. + * @returns {Promise} The retrieved {return type}(s). + * + * @example + * ```typescript + * const result = await orderModuleService.retrieveOrderChangeAction("actionId123"); + * ``` + * + */ + retrieveOrderChangeAction( + actionId: string, + config?: FindConfig, + sharedContext?: Context + ): Promise + + updateOrderChangeActions( + data: UpdateOrderChangeActionDTO, + sharedContext?: Context + ): Promise + + /** + * This method updates {return type}(s) + * + * @param {UpdateOrderChangeActionDTO[]} data - The order change action to be updated. + * @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module. + * @returns {Promise} The updated {return type}(s). + * + * @example + * ```typescript + * // Example call to updateOrderChangeActions + * + * const updateOrderChangeActionsData: UpdateOrderChangeActionDTO[] = [{ + * id: "orderchangeaction123", + * ... + * }]; + * + * const result = await orderModuleService.updateOrderChangeActions(updateOrderChangeActionsData); + * ``` + * + */ + updateOrderChangeActions( + data: UpdateOrderChangeActionDTO[], + sharedContext?: Context + ): Promise + + /** + * This method updates {return type}(s) + * + * @param {UpdateOrderChangeActionDTO | UpdateOrderChangeActionDTO[]} data - The order change action d t o | order change to be updated. + * @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module. + * @returns {Promise} The updated {return type}(s). + * + * @example + * ```typescript + * const result = await orderModuleService.updateOrderChangeActions({ + * id: "orderChangeAction123", + * ... + * }); + * ``` + * + */ + updateOrderChangeActions( + data: UpdateOrderChangeActionDTO | UpdateOrderChangeActionDTO[], + sharedContext?: Context + ): Promise + addOrderAction( data: CreateOrderChangeActionDTO, sharedContext?: Context