feat(core-flows, types): workflow to delete order change actions (#8064)

* chore: workflow to delete order change actions

* chore: fix soft delete signature
This commit is contained in:
Riqwan Thamir
2024-07-10 18:31:12 +02:00
committed by GitHub
parent d9b9a1df27
commit 95f29358d1
7 changed files with 183 additions and 90 deletions

View File

@@ -1,74 +0,0 @@
import { createOrderChangeWorkflow } from "@medusajs/core-flows"
import { OrderDTO } from "@medusajs/types"
import { medusaIntegrationTestRunner } from "medusa-test-utils"
import { createOrderFixture, prepareDataFixtures } from "./__fixtures__"
jest.setTimeout(50000)
medusaIntegrationTestRunner({
env: { MEDUSA_FF_MEDUSA_V2: true },
testSuite: ({ getContainer }) => {
let container
beforeAll(() => {
container = getContainer()
})
describe("Order change workflows", () => {
let order: OrderDTO
describe("createOrderChangeWorkflow", () => {
beforeEach(async () => {
const fixtures = await prepareDataFixtures({
container,
})
order = await createOrderFixture({
container,
product: fixtures.product,
location: fixtures.location,
inventoryItem: fixtures.inventoryItem,
})
})
it("should successfully create an order change", async () => {
const { result } = await createOrderChangeWorkflow(container).run({
input: {
order_id: order.id,
},
})
expect(result).toEqual(
expect.objectContaining({
id: expect.any(String),
order_id: order.id,
})
)
})
it("should throw an error when creating an order change when an active one already exists", async () => {
await createOrderChangeWorkflow(container).run({
input: {
order_id: order.id,
},
})
const {
errors: [error],
} = await createOrderChangeWorkflow(container).run({
input: {
order_id: order.id,
},
throwOnError: false,
})
expect(error.error).toEqual(
expect.objectContaining({
message: `Order (${order.id}) already has an existing active order change`,
})
)
})
})
})
},
})

View File

@@ -2,6 +2,8 @@ import {
createOrderChangeActionsWorkflow,
createOrderChangeActionsWorkflowId,
createOrderChangeWorkflow,
deleteOrderChangeActionsWorkflow,
deleteOrderChangeActionsWorkflowId,
} from "@medusajs/core-flows"
import { IOrderModuleService, OrderChangeDTO, OrderDTO } from "@medusajs/types"
import { ChangeActionType, ModuleRegistrationName } from "@medusajs/utils"
@@ -24,25 +26,25 @@ medusaIntegrationTestRunner({
let service: IOrderModuleService
let orderChange: OrderChangeDTO
describe("createOrderChangeActionWorkflow", () => {
beforeEach(async () => {
const fixtures = await prepareDataFixtures({ container })
beforeEach(async () => {
const fixtures = await prepareDataFixtures({ container })
order = await createOrderFixture({
container,
product: fixtures.product,
location: fixtures.location,
inventoryItem: fixtures.inventoryItem,
})
const { result } = await createOrderChangeWorkflow(container).run({
input: { order_id: order.id },
})
orderChange = result
service = container.resolve(ModuleRegistrationName.ORDER)
order = await createOrderFixture({
container,
product: fixtures.product,
location: fixtures.location,
inventoryItem: fixtures.inventoryItem,
})
const { result } = await createOrderChangeWorkflow(container).run({
input: { order_id: order.id },
})
orderChange = result
service = container.resolve(ModuleRegistrationName.ORDER)
})
describe("createOrderChangeActionWorkflow", () => {
it("should successfully create an order change action", async () => {
const { result } = await createOrderChangeActionsWorkflow(
container
@@ -111,6 +113,105 @@ medusaIntegrationTestRunner({
expect(orderChange1.actions).toHaveLength(0)
})
})
describe("deleteOrderChangeActionsWorkflow", () => {
it("should successfully delete an order change action", async () => {
const { result: changeOrderActions } =
await createOrderChangeActionsWorkflow(container).run({
input: [
{
action: ChangeActionType.ITEM_ADD,
order_change_id: orderChange.id,
order_id: order.id,
},
{
action: ChangeActionType.ITEM_REMOVE,
order_change_id: orderChange.id,
order_id: order.id,
},
],
})
await deleteOrderChangeActionsWorkflow(container).run({
input: { ids: changeOrderActions.map((coa) => coa.id) },
})
const orderChange2 = await service.retrieveOrderChange(
orderChange.id,
{ relations: ["actions"], withDeleted: true }
)
expect(orderChange2.actions).toHaveLength(2)
expect(orderChange2).toEqual(
expect.objectContaining({
id: orderChange.id,
actions: expect.arrayContaining([
expect.objectContaining({
deleted_at: expect.any(Date),
}),
expect.objectContaining({
deleted_at: expect.any(Date),
}),
]),
})
)
})
it("should rollback to its original state when future step throws error", async () => {
const { result: changeOrderActions } =
await createOrderChangeActionsWorkflow(container).run({
input: [
{
action: ChangeActionType.ITEM_ADD,
order_change_id: orderChange.id,
order_id: order.id,
},
{
action: ChangeActionType.ITEM_REMOVE,
order_change_id: orderChange.id,
order_id: order.id,
},
],
})
const workflow = deleteOrderChangeActionsWorkflow(container)
workflow.appendAction("throw", deleteOrderChangeActionsWorkflowId, {
invoke: async function failStep() {
throw new Error(`Fail`)
},
})
const {
errors: [error],
} = await workflow.run({
input: { ids: changeOrderActions.map((coa) => coa.id) },
throwOnError: false,
})
expect(error.error).toEqual(
expect.objectContaining({
message: `Fail`,
})
)
const orderChange2 = await service.retrieveOrderChange(
orderChange.id,
{ relations: ["actions"] }
)
expect(orderChange2.actions).toEqual(
expect.arrayContaining([
expect.objectContaining({
deleted_at: null,
}),
expect.objectContaining({
deleted_at: null,
}),
])
)
})
})
})
},
})

View File

@@ -0,0 +1,28 @@
import { IOrderModuleService } from "@medusajs/types"
import { ModuleRegistrationName } from "@medusajs/utils"
import { StepResponse, createStep } from "@medusajs/workflows-sdk"
export const deleteOrderChangeActionsStepId = "delete-order-change-actions"
export const deleteOrderChangeActionsStep = createStep(
deleteOrderChangeActionsStepId,
async (data: { ids: string[] }, { container }) => {
const service = container.resolve<IOrderModuleService>(
ModuleRegistrationName.ORDER
)
await service.softDeleteOrderChangeActions(data.ids)
return new StepResponse(void 0, data.ids)
},
async (ids, { container }) => {
if (!ids?.length) {
return
}
const service = container.resolve<IOrderModuleService>(
ModuleRegistrationName.ORDER
)
await service.restoreOrderChangeActions(ids)
}
)

View File

@@ -10,6 +10,7 @@ export * from "./create-order-change-actions"
export * from "./create-orders"
export * from "./decline-order-change"
export * from "./delete-order-change"
export * from "./delete-order-change-actions"
export * from "./get-item-tax-lines"
export * from "./register-fulfillment"
export * from "./register-shipment"

View File

@@ -0,0 +1,10 @@
import { WorkflowData, createWorkflow } from "@medusajs/workflows-sdk"
import { deleteOrderChangeActionsStep } from "../steps"
export const deleteOrderChangeActionsWorkflowId = "delete-order-change-actions"
export const deleteOrderChangeActionsWorkflow = createWorkflow(
deleteOrderChangeActionsWorkflowId,
(input: WorkflowData<{ ids: string[] }>): WorkflowData<void> => {
deleteOrderChangeActionsStep(input)
}
)

View File

@@ -12,6 +12,7 @@ export * from "./create-orders"
export * from "./create-shipment"
export * from "./decline-order-change"
export * from "./delete-order-change"
export * from "./delete-order-change-actions"
export * from "./get-order-detail"
export * from "./get-orders-list"
export * from "./receive-return"

View File

@@ -1580,6 +1580,32 @@ export interface IOrderModuleService extends IModuleService {
sharedContext?: Context
): Promise<void>
/**
* This method deletes {return type} by its ID.
*
* @param {string} orderId - The order action's ID.
* @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module.
* @returns {Promise<void>} Resolves when {summary}
*
* @example
* ```typescript
* await orderModuleService.softDeleteOrderChangeActions("orderActionId");
* ```
*
*/
softDeleteOrderChangeActions<TReturnableLinkableKeys extends string = string>(
actionIds: string[],
config?: SoftDeleteReturn<TReturnableLinkableKeys>,
sharedContext?: Context
): Promise<Record<TReturnableLinkableKeys, string[]> | void>
restoreOrderChangeActions<TReturnableLinkableKeys extends string = string>(
actionId: string | string[],
config?: RestoreReturn<TReturnableLinkableKeys>,
sharedContext?: Context
): Promise<Record<string, string[]> | void>
softDeleteAddresses<TReturnableLinkableKeys extends string = string>(
ids: string[],
config?: SoftDeleteReturn<TReturnableLinkableKeys>,