fix(inventory): Entity Formulas + softDelete and restore (#7851)
This commit is contained in:
@@ -581,6 +581,79 @@ medusaIntegrationTestRunner({
|
|||||||
})
|
})
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it("should retrieve the inventory item with correct stocked quantity given location levels have been deleted", async () => {
|
||||||
|
await api.post(
|
||||||
|
`/admin/inventory-items/${inventoryItem1.id}/location-levels`,
|
||||||
|
{
|
||||||
|
location_id: stockLocation1.id,
|
||||||
|
stocked_quantity: 10,
|
||||||
|
incoming_quantity: 0,
|
||||||
|
},
|
||||||
|
adminHeaders
|
||||||
|
)
|
||||||
|
|
||||||
|
const item = (
|
||||||
|
await api.post(
|
||||||
|
`/admin/inventory-items/${inventoryItem1.id}/location-levels`,
|
||||||
|
{
|
||||||
|
location_id: stockLocation2.id,
|
||||||
|
stocked_quantity: 10,
|
||||||
|
incoming_quantity: 0,
|
||||||
|
},
|
||||||
|
adminHeaders
|
||||||
|
)
|
||||||
|
).data.inventory_item
|
||||||
|
|
||||||
|
await api.post(
|
||||||
|
`/admin/reservations`,
|
||||||
|
{
|
||||||
|
line_item_id: "line-item-id-1",
|
||||||
|
inventory_item_id: inventoryItem1.id,
|
||||||
|
location_id: stockLocation2.id,
|
||||||
|
description: "test description",
|
||||||
|
quantity: 1,
|
||||||
|
},
|
||||||
|
adminHeaders
|
||||||
|
)
|
||||||
|
|
||||||
|
const reservation = (
|
||||||
|
await api.post(
|
||||||
|
`/admin/reservations`,
|
||||||
|
{
|
||||||
|
line_item_id: "line-item-id-2",
|
||||||
|
inventory_item_id: inventoryItem1.id,
|
||||||
|
location_id: stockLocation2.id,
|
||||||
|
description: "test description 2",
|
||||||
|
quantity: 1,
|
||||||
|
},
|
||||||
|
adminHeaders
|
||||||
|
)
|
||||||
|
).data.reservation
|
||||||
|
|
||||||
|
await api.delete(
|
||||||
|
`/admin/inventory-items/${inventoryItem1.id}/location-levels/${item.location_levels[0].id}`,
|
||||||
|
adminHeaders
|
||||||
|
)
|
||||||
|
|
||||||
|
await api.delete(
|
||||||
|
`/admin/reservations/${reservation.id}`,
|
||||||
|
adminHeaders
|
||||||
|
)
|
||||||
|
|
||||||
|
const response = await api.get(
|
||||||
|
`/admin/inventory-items/${inventoryItem1.id}`,
|
||||||
|
adminHeaders
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(response.data.inventory_item).toEqual(
|
||||||
|
expect.objectContaining({
|
||||||
|
id: inventoryItem1.id,
|
||||||
|
stocked_quantity: 10,
|
||||||
|
reserved_quantity: 1,
|
||||||
|
})
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
it("should throw if inventory item doesn't exist", async () => {
|
it("should throw if inventory item doesn't exist", async () => {
|
||||||
const error = await api
|
const error = await api
|
||||||
|
|||||||
@@ -131,14 +131,14 @@ export class InventoryItem {
|
|||||||
|
|
||||||
@Formula(
|
@Formula(
|
||||||
(item) =>
|
(item) =>
|
||||||
`(SELECT SUM(reserved_quantity) FROM inventory_level il WHERE il.inventory_item_id = ${item}.id)`,
|
`(SELECT SUM(reserved_quantity) FROM inventory_level il WHERE il.inventory_item_id = ${item}.id AND il.deleted_at IS NULL)`,
|
||||||
{ lazy: true, serializer: Number, hidden: true }
|
{ lazy: true, serializer: Number, hidden: true }
|
||||||
)
|
)
|
||||||
reserved_quantity: number
|
reserved_quantity: number
|
||||||
|
|
||||||
@Formula(
|
@Formula(
|
||||||
(item) =>
|
(item) =>
|
||||||
`(SELECT SUM(stocked_quantity) FROM inventory_level il WHERE il.inventory_item_id = ${item}.id)`,
|
`(SELECT SUM(stocked_quantity) FROM inventory_level il WHERE il.inventory_item_id = ${item}.id AND il.deleted_at IS NULL)`,
|
||||||
{ lazy: true, serializer: Number, hidden: true }
|
{ lazy: true, serializer: Number, hidden: true }
|
||||||
)
|
)
|
||||||
stocked_quantity: number
|
stocked_quantity: number
|
||||||
|
|||||||
@@ -6,26 +6,28 @@ import {
|
|||||||
ModuleJoinerConfig,
|
ModuleJoinerConfig,
|
||||||
ModulesSdkTypes,
|
ModulesSdkTypes,
|
||||||
ReservationItemDTO,
|
ReservationItemDTO,
|
||||||
|
RestoreReturn,
|
||||||
|
SoftDeleteReturn,
|
||||||
} from "@medusajs/types"
|
} from "@medusajs/types"
|
||||||
|
import { IInventoryService } from "@medusajs/types/dist/inventory"
|
||||||
import {
|
import {
|
||||||
arrayDifference,
|
|
||||||
CommonEvents,
|
CommonEvents,
|
||||||
EmitEvents,
|
EmitEvents,
|
||||||
InjectManager,
|
InjectManager,
|
||||||
InjectTransactionManager,
|
InjectTransactionManager,
|
||||||
InventoryEvents,
|
InventoryEvents,
|
||||||
isDefined,
|
|
||||||
isString,
|
|
||||||
MedusaContext,
|
MedusaContext,
|
||||||
MedusaError,
|
MedusaError,
|
||||||
MedusaService,
|
MedusaService,
|
||||||
|
arrayDifference,
|
||||||
|
isDefined,
|
||||||
|
isString,
|
||||||
partitionArray,
|
partitionArray,
|
||||||
promiseAll,
|
promiseAll,
|
||||||
} from "@medusajs/utils"
|
} from "@medusajs/utils"
|
||||||
import { InventoryItem, InventoryLevel, ReservationItem } from "@models"
|
import { InventoryItem, InventoryLevel, ReservationItem } from "@models"
|
||||||
import { entityNameToLinkableKeysMap, joinerConfig } from "../joiner-config"
|
import { entityNameToLinkableKeysMap, joinerConfig } from "../joiner-config"
|
||||||
import InventoryLevelService from "./inventory-level"
|
import InventoryLevelService from "./inventory-level"
|
||||||
import { IInventoryService } from "@medusajs/types/dist/inventory"
|
|
||||||
|
|
||||||
type InjectedDependencies = {
|
type InjectedDependencies = {
|
||||||
baseRepository: DAL.RepositoryService
|
baseRepository: DAL.RepositoryService
|
||||||
@@ -774,6 +776,48 @@ export default class InventoryModuleService
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@InjectTransactionManager("baseRepository_")
|
||||||
|
// @ts-expect-error
|
||||||
|
async softDeleteReservationItems(
|
||||||
|
ids: string | string[],
|
||||||
|
config?: SoftDeleteReturn<string>,
|
||||||
|
@MedusaContext() context: Context = {}
|
||||||
|
): Promise<void> {
|
||||||
|
const reservations: InventoryTypes.ReservationItemDTO[] =
|
||||||
|
await super.listReservationItems({ id: ids }, {}, context)
|
||||||
|
|
||||||
|
const result = await super.softDeleteReservationItems(
|
||||||
|
{ id: ids },
|
||||||
|
config,
|
||||||
|
context
|
||||||
|
)
|
||||||
|
|
||||||
|
await this.adjustInventoryLevelsForReservationsDeletion(
|
||||||
|
reservations,
|
||||||
|
context
|
||||||
|
)
|
||||||
|
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
|
@InjectTransactionManager("baseRepository_")
|
||||||
|
// @ts-expect-error
|
||||||
|
async restoreReservationItems(
|
||||||
|
ids: string | string[],
|
||||||
|
config?: RestoreReturn<string>,
|
||||||
|
@MedusaContext() context: Context = {}
|
||||||
|
): Promise<void> {
|
||||||
|
const reservations: InventoryTypes.ReservationItemDTO[] =
|
||||||
|
await super.listReservationItems({ id: ids }, {}, context)
|
||||||
|
|
||||||
|
await super.restoreReservationItems({ id: ids }, config, context)
|
||||||
|
|
||||||
|
await this.adjustInventoryLevelsForReservationsRestore(
|
||||||
|
reservations,
|
||||||
|
context
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
@InjectTransactionManager("baseRepository_")
|
@InjectTransactionManager("baseRepository_")
|
||||||
@EmitEvents()
|
@EmitEvents()
|
||||||
async deleteReservationItemByLocationId(
|
async deleteReservationItemByLocationId(
|
||||||
|
|||||||
Reference in New Issue
Block a user