chore(order): cancel order (#7586)

This commit is contained in:
Carlos R. L. Rodrigues
2024-06-03 12:31:33 -03:00
committed by GitHub
parent fdd9022376
commit 122186a78d
42 changed files with 945 additions and 116 deletions

View File

@@ -1,11 +1,11 @@
import crypto from "crypto"
import { Modules } from "@medusajs/modules-sdk"
import { IApiKeyModuleService } from "@medusajs/types"
import { ApiKeyType } from "@medusajs/utils"
import crypto from "crypto"
import { moduleIntegrationTestRunner, SuiteOptions } from "medusa-test-utils"
import {
createSecretKeyFixture,
createPublishableKeyFixture,
createSecretKeyFixture,
} from "../__fixtures__"
jest.setTimeout(100000)
@@ -88,7 +88,7 @@ moduleIntegrationTestRunner({
})
it("should only allow creating one active token", async function () {
expect(
await expect(
service.create([createSecretKeyFixture, createSecretKeyFixture])
).rejects.toThrow(
"You can only create one secret key at a time. You tried to create 2 secret keys."

View File

@@ -96,7 +96,7 @@ moduleIntegrationTestRunner({
quantity: 3,
})
expect(reserveMoreThanInStock).rejects.toThrow(
await expect(reserveMoreThanInStock).rejects.toThrow(
`Not enough stock available for item ${inventoryItem.id} at location location-1`
)
@@ -415,7 +415,7 @@ moduleIntegrationTestRunner({
])
})
it("deleted reseravation items by line item", async () => {
it("deleted reseravation items by line item and restore them", async () => {
const reservationsPreDeleted = await service.listReservationItems({
line_item_id: "line-item-id",
})
@@ -440,6 +440,25 @@ moduleIntegrationTestRunner({
})
expect(reservationsPostDeleted).toEqual([])
await service.restoreReservationItemsByLineItem("line-item-id")
const reservationsPostRestored = await service.listReservationItems({
line_item_id: "line-item-id",
})
expect(reservationsPostRestored).toEqual([
expect.objectContaining({
location_id: "location-1",
quantity: 2,
line_item_id: "line-item-id",
}),
expect.objectContaining({
location_id: "location-1",
quantity: 2,
line_item_id: "line-item-id",
}),
])
})
it("adjusts inventory levels accordingly when removing reservations by line item", async () => {

View File

@@ -1,17 +1,8 @@
import {
Context,
CreateInventoryLevelInput,
DAL,
SharedContext,
} from "@medusajs/types"
import {
InjectTransactionManager,
MedusaContext,
ModulesSdkUtils,
} from "@medusajs/utils"
import { Context } from "@medusajs/types"
import { ModulesSdkUtils } from "@medusajs/utils"
import { InventoryLevel } from "../models/inventory-level"
import { InventoryLevelRepository } from "@repositories"
import { InventoryLevel } from "../models/inventory-level"
type InjectedDependencies = {
inventoryLevelRepository: InventoryLevelRepository

View File

@@ -15,11 +15,11 @@ import {
InjectManager,
InjectTransactionManager,
InventoryEvents,
isDefined,
isString,
MedusaContext,
MedusaError,
ModulesSdkUtils,
isDefined,
isString,
partitionArray,
promiseAll,
} from "@medusajs/utils"
@@ -781,6 +781,43 @@ export default class InventoryModuleService<
)
}
/**
* Deletes reservation items by line item
* @param lineItemId - the id of the line item associated with the reservation item
* @param context
*/
@InjectTransactionManager("baseRepository_")
@EmitEvents()
async restoreReservationItemsByLineItem(
lineItemId: string | string[],
@MedusaContext() context: Context = {}
): Promise<void> {
const reservations: InventoryNext.ReservationItemDTO[] =
await this.listReservationItems({ line_item_id: lineItemId }, {}, context)
await this.reservationItemService_.restore(
{ line_item_id: lineItemId },
context
)
await this.adjustInventoryLevelsForReservationsRestore(
reservations,
context
)
context.messageAggregator?.saveRawMessageData(
reservations.map((reservationItem) => ({
eventName: InventoryEvents.reservation_item_created,
service: this.constructor.name,
action: CommonEvents.CREATED,
object: "reservation-item",
context,
data: { id: reservationItem.id },
}))
)
}
/**
* Adjusts the inventory level for a given inventory item and location.
* @param inventoryItemId - the id of the inventory item
@@ -1040,6 +1077,30 @@ export default class InventoryModuleService<
reservations: ReservationItemDTO[],
context: Context
): Promise<void> {
await this.adjustInventoryLevelsForReservations_(
reservations,
true,
context
)
}
private async adjustInventoryLevelsForReservationsRestore(
reservations: ReservationItemDTO[],
context: Context
): Promise<void> {
await this.adjustInventoryLevelsForReservations_(
reservations,
false,
context
)
}
private async adjustInventoryLevelsForReservations_(
reservations: ReservationItemDTO[],
isDelete: boolean,
context: Context
): Promise<void> {
const multiplier = isDelete ? -1 : 1
const inventoryLevels = await this.ensureInventoryLevels(
reservations.map((r) => ({
inventory_item_id: r.inventory_item_id,
@@ -1055,8 +1116,8 @@ export default class InventoryModuleService<
const inventoryLevelMap = acc.get(curr.inventory_item_id) ?? new Map()
const adjustment = inventoryLevelMap.has(curr.location_id)
? inventoryLevelMap.get(curr.location_id) - curr.quantity
: -curr.quantity
? inventoryLevelMap.get(curr.location_id) + curr.quantity * multiplier
: curr.quantity * multiplier
inventoryLevelMap.set(curr.location_id, adjustment)
acc.set(curr.inventory_item_id, inventoryLevelMap)

View File

@@ -410,7 +410,9 @@ moduleIntegrationTestRunner({
confirmed_by: "cx_agent_123",
})
expect(service.confirmOrderChange(orderChange.id)).rejects.toThrowError(
await expect(
service.confirmOrderChange(orderChange.id)
).rejects.toThrowError(
`Order Change cannot be modified: ${orderChange.id}`
)
@@ -579,9 +581,9 @@ moduleIntegrationTestRunner({
canceled_by: "cx_agent_123",
})
expect(service.cancelOrderChange(orderChange.id)).rejects.toThrowError(
"Order Change cannot be modified"
)
await expect(
service.cancelOrderChange(orderChange.id)
).rejects.toThrowError("Order Change cannot be modified")
await service.declineOrderChange({
id: orderChange2.id,
@@ -589,7 +591,7 @@ moduleIntegrationTestRunner({
declined_reason: "changed my mind",
})
expect(
await expect(
service.declineOrderChange(orderChange2.id)
).rejects.toThrowError("Order Change cannot be modified")

View File

@@ -2753,10 +2753,55 @@ export default class OrderModuleService<
}
await this.orderService_.update(
orderIds.map((id) => {
return {
id,
status: OrderStatus.COMPLETED,
}
}),
sharedContext
)
return Array.isArray(orderId) ? orders : orders[0]
}
async cancel(
orderId: string,
sharedContext?: Context
): Promise<OrderTypes.OrderDTO>
async cancel(
orderId: string[],
sharedContext?: Context
): Promise<OrderTypes.OrderDTO[]>
@InjectTransactionManager("baseRepository_")
async cancel(
orderId: string | string[],
sharedContext?: Context
): Promise<OrderTypes.OrderDTO | OrderTypes.OrderDTO[]> {
const orderIds = Array.isArray(orderId) ? orderId : [orderId]
const orders = await this.list(
{
id: orderIds,
status: OrderStatus.COMPLETED,
},
{},
sharedContext
)
const canceled_at = new Date()
for (const order of orders) {
order.status = OrderStatus.CANCELED
order.canceled_at = canceled_at
}
await this.orderService_.update(
orderIds.map((id) => {
return {
id,
status: OrderStatus.CANCELED,
canceled_at,
}
}),
sharedContext
)

View File

@@ -299,7 +299,7 @@ moduleIntegrationTestRunner({
{}
)
expect(result).rejects.toThrow(
await expect(result).rejects.toThrow(
"Method calculatePrices requires currency_code in the pricing context"
)
@@ -308,7 +308,7 @@ moduleIntegrationTestRunner({
{ context: { region_id: "DE" } }
)
expect(result).rejects.toThrow(
await expect(result).rejects.toThrow(
"Method calculatePrices requires currency_code in the pricing context"
)
})