Feat(inventory-next, medusa): Add List inventory items endpoint (#6694)

* code for list inventory items

* fix integration tests

* move integration test

* calculate reserved and stocked quantities in db

* update lockfile
This commit is contained in:
Philip Korsholm authored and GitHub committed 2024-03-14 14:48:34 +01:00
1 parent 3dd55efd15
commit c3f8c30ba6
14 files changed
+1247 -16

No files matched your search

@@ -3,7 +3,9 @@ import {
Collection,
Entity,
Filter,
Formula,
OnInit,
OnLoad,
OneToMany,
OptionalProps,
PrimaryKey,
@@ -106,7 +108,21 @@ export class InventoryItem {
() => InventoryLevel,
(inventoryLevel) => inventoryLevel.inventory_item
)
inventory_levels = new Collection<InventoryLevel>(this)
location_levels = new Collection<InventoryLevel>(this)
@Formula(
(item) =>
`(SELECT SUM(reserved_quantity) FROM inventory_level il WHERE il.inventory_item_id = ${item}.id)`,
{ lazy: true, serializer: Number, hidden: true }
)
reserved_quantity: number
@Formula(
(item) =>
`(SELECT SUM(stocked_quantity) FROM inventory_level il WHERE il.inventory_item_id = ${item}.id)`,
{ lazy: true, serializer: Number, hidden: true }
)
stocked_quantity: number
@BeforeCreate()
private beforeCreate(): void {
@@ -4,11 +4,12 @@ import {
Filter,
ManyToOne,
OnInit,
OnLoad,
PrimaryKey,
Property,
} from "@mikro-orm/core"
import { DALUtils, isDefined } from "@medusajs/utils"
import { DALUtils } from "@medusajs/utils"
import { InventoryItem } from "./inventory-item"
import { createPsqlIndexStatementHelper } from "@medusajs/utils"
import { generateEntityId } from "@medusajs/utils"
@@ -91,6 +92,8 @@ export class InventoryLevel {
})
inventory_item: InventoryItem
available_quantity: number | null = null
@BeforeCreate()
private beforeCreate(): void {
this.id = generateEntityId(this.id, "ilev")
@@ -101,4 +104,11 @@ export class InventoryLevel {
private onInit(): void {
this.id = generateEntityId(this.id, "ilev")
}
@OnLoad()
private onLoad(): void {
if (isDefined(this.stocked_quantity) && isDefined(this.reserved_quantity)) {
this.available_quantity = this.stocked_quantity - this.reserved_quantity
}
}
}
@@ -1,2 +1,3 @@
export * from "./inventory-level"
export * from "./inventory-item"
export { MikroOrmBaseRepository as BaseRepository } from "@medusajs/utils"
@@ -0,0 +1,63 @@
import { Context, DAL } from "@medusajs/types"
import { InventoryItem, InventoryLevel } from "@models"
import { SqlEntityManager } from "@mikro-orm/postgresql"
import { mikroOrmBaseRepositoryFactory } from "@medusajs/utils"
export class InventoryItemRepository extends mikroOrmBaseRepositoryFactory<InventoryItem>(
InventoryItem
) {
async find(
findOptions: DAL.FindOptions<InventoryItem & { q?: string }> = {
where: {},
},
context: Context = {}
): Promise<InventoryItem[]> {
const findOptions_ = { ...findOptions }
findOptions_.options ??= {}
this.applyFreeTextSearchFilters<InventoryItem>(
findOptions_,
this.getFreeTextSearchConstraints
)
return await super.find(findOptions_, context)
}
async findAndCount(
findOptions: DAL.FindOptions<InventoryItem & { q?: string }> = {
where: {},
},
context: Context = {}
): Promise<[InventoryItem[], number]> {
const findOptions_ = { ...findOptions }
findOptions_.options ??= {}
this.applyFreeTextSearchFilters<InventoryItem>(
findOptions_,
this.getFreeTextSearchConstraints
)
return await super.findAndCount(findOptions_, context)
}
protected getFreeTextSearchConstraints(q: string) {
return [
{
description: {
$ilike: `%${q}%`,
},
},
{
title: {
$ilike: `%${q}%`,
},
},
{
sku: {
$ilike: `%${q}%`,
},
},
]
}
}
@@ -15,10 +15,10 @@ import {
InjectManager,
InjectTransactionManager,
InventoryEvents,
isDefined,
MedusaContext,
MedusaError,
ModulesSdkUtils,
isDefined,
partitionArray,
} from "@medusajs/utils"
import { InventoryItem, InventoryLevel, ReservationItem } from "@models"
@@ -100,7 +100,7 @@ export default class InventoryModuleService<
{ location_id: string; inventory_item_id: string }[]
]
const inventoryLevels = await this.inventoryLevelService_.list(
const inventoryLevels = await this.listInventoryLevels(
{
$or: [
{ id: idData.filter(({ id }) => !!id).map((e) => e.id) },