feat(medusa): Modules initializer (#3352)

This commit is contained in:
Carlos R. L. Rodrigues
2023-03-17 12:18:52 -03:00
committed by GitHub
parent 8a7421db5b
commit aa690beed7
51 changed files with 1290 additions and 715 deletions
@@ -1,5 +1,3 @@
import { DeepPartial, EntityManager, FindManyOptions } from "typeorm"
import { isDefined, MedusaError } from "medusa-core-utils"
import {
buildQuery,
CreateInventoryItemInput,
@@ -7,9 +5,11 @@ import {
FindConfig,
IEventBusService,
InventoryItemDTO,
TransactionBaseService,
} from "@medusajs/medusa"
import { SharedContext } from "@medusajs/types"
import { InjectEntityManager, MedusaContext } from "@medusajs/utils"
import { isDefined, MedusaError } from "medusa-core-utils"
import { DeepPartial, EntityManager, FindManyOptions } from "typeorm"
import { InventoryItem } from "../models"
import { getListQuery } from "../utils/query"
@@ -18,18 +18,18 @@ type InjectedDependencies = {
manager: EntityManager
}
export default class InventoryItemService extends TransactionBaseService {
export default class InventoryItemService {
static Events = {
CREATED: "inventory-item.created",
UPDATED: "inventory-item.updated",
DELETED: "inventory-item.deleted",
}
protected readonly eventBusService_: IEventBusService
constructor({ eventBusService }: InjectedDependencies) {
super(arguments[0])
protected readonly manager_: EntityManager
protected readonly eventBusService_: IEventBusService | undefined
constructor({ eventBusService, manager }: InjectedDependencies) {
this.manager_ = manager
this.eventBusService_ = eventBusService
}
@@ -38,11 +38,17 @@ export default class InventoryItemService extends TransactionBaseService {
* @param config - Configuration for query.
* @return Resolves to the list of inventory items that match the filter.
*/
@InjectEntityManager()
async list(
selector: FilterableInventoryItemProps = {},
config: FindConfig<InventoryItem> = { relations: [], skip: 0, take: 10 }
config: FindConfig<InventoryItem> = { relations: [], skip: 0, take: 10 },
@MedusaContext() context: SharedContext = {}
): Promise<InventoryItemDTO[]> {
const queryBuilder = getListQuery(this.activeManager_, selector, config)
const queryBuilder = getListQuery(
context.transactionManager!,
selector,
config
)
return await queryBuilder.getMany()
}
@@ -51,11 +57,17 @@ export default class InventoryItemService extends TransactionBaseService {
* @param config - Configuration for query.
* @return - Resolves to the list of inventory items that match the filter and the count of all matching items.
*/
@InjectEntityManager()
async listAndCount(
selector: FilterableInventoryItemProps = {},
config: FindConfig<InventoryItem> = { relations: [], skip: 0, take: 10 }
config: FindConfig<InventoryItem> = { relations: [], skip: 0, take: 10 },
@MedusaContext() context: SharedContext = {}
): Promise<[InventoryItemDTO[], number]> {
const queryBuilder = getListQuery(this.activeManager_, selector, config)
const queryBuilder = getListQuery(
context.transactionManager!,
selector,
config
)
return await queryBuilder.getManyAndCount()
}
@@ -66,9 +78,11 @@ export default class InventoryItemService extends TransactionBaseService {
* @return The retrieved inventory item.
* @throws If the inventory item id is not defined or if the inventory item is not found.
*/
@InjectEntityManager()
async retrieve(
inventoryItemId: string,
config: FindConfig<InventoryItem> = {}
config: FindConfig<InventoryItem> = {},
@MedusaContext() context: SharedContext = {}
): Promise<InventoryItem> {
if (!isDefined(inventoryItemId)) {
throw new MedusaError(
@@ -77,7 +91,7 @@ export default class InventoryItemService extends TransactionBaseService {
)
}
const manager = this.activeManager_
const manager = context.transactionManager!
const itemRepository = manager.getRepository(InventoryItem)
const query = buildQuery({ id: inventoryItemId }, config) as FindManyOptions
@@ -97,34 +111,35 @@ export default class InventoryItemService extends TransactionBaseService {
* @param input - Input for creating a new inventory item.
* @return The newly created inventory item.
*/
async create(data: CreateInventoryItemInput): Promise<InventoryItem> {
return await this.atomicPhase_(async (manager) => {
const itemRepository = manager.getRepository(InventoryItem)
@InjectEntityManager()
async create(
data: CreateInventoryItemInput,
@MedusaContext() context: SharedContext = {}
): Promise<InventoryItem> {
const manager = context.transactionManager!
const itemRepository = manager.getRepository(InventoryItem)
const inventoryItem = itemRepository.create({
sku: data.sku,
origin_country: data.origin_country,
metadata: data.metadata,
hs_code: data.hs_code,
mid_code: data.mid_code,
material: data.material,
weight: data.weight,
length: data.length,
height: data.height,
width: data.width,
requires_shipping: data.requires_shipping,
})
const result = await itemRepository.save(inventoryItem)
await this.eventBusService_
.withTransaction(manager)
.emit(InventoryItemService.Events.CREATED, {
id: result.id,
})
return result
const inventoryItem = itemRepository.create({
sku: data.sku,
origin_country: data.origin_country,
metadata: data.metadata,
hs_code: data.hs_code,
mid_code: data.mid_code,
material: data.material,
weight: data.weight,
length: data.length,
height: data.height,
width: data.width,
requires_shipping: data.requires_shipping,
})
const result = await itemRepository.save(inventoryItem)
await this.eventBusService_?.emit?.(InventoryItemService.Events.CREATED, {
id: result.id,
})
return result
}
/**
@@ -132,51 +147,51 @@ export default class InventoryItemService extends TransactionBaseService {
* @param update - The updates to apply to the inventory item.
* @return The updated inventory item.
*/
@InjectEntityManager()
async update(
inventoryItemId: string,
data: Omit<
DeepPartial<InventoryItem>,
"id" | "created_at" | "metadata" | "deleted_at"
>
>,
@MedusaContext() context: SharedContext = {}
): Promise<InventoryItem> {
return await this.atomicPhase_(async (manager) => {
const itemRepository = manager.getRepository(InventoryItem)
const manager = context.transactionManager!
const itemRepository = manager.getRepository(InventoryItem)
const item = await this.retrieve(inventoryItemId)
const item = await this.retrieve(inventoryItemId, undefined, context)
const shouldUpdate = Object.keys(data).some((key) => {
return item[key] !== data[key]
})
if (shouldUpdate) {
itemRepository.merge(item, data)
await itemRepository.save(item)
await this.eventBusService_
.withTransaction(manager)
.emit(InventoryItemService.Events.UPDATED, {
id: item.id,
})
}
return item
const shouldUpdate = Object.keys(data).some((key) => {
return item[key] !== data[key]
})
if (shouldUpdate) {
itemRepository.merge(item, data)
await itemRepository.save(item)
await this.eventBusService_?.emit?.(InventoryItemService.Events.UPDATED, {
id: item.id,
})
}
return item
}
/**
* @param inventoryItemId - The id of the inventory item to delete.
*/
async delete(inventoryItemId: string): Promise<void> {
await this.atomicPhase_(async (manager) => {
const itemRepository = manager.getRepository(InventoryItem)
@InjectEntityManager()
async delete(
inventoryItemId: string,
@MedusaContext() context: SharedContext = {}
): Promise<void> {
const manager = context.transactionManager!
const itemRepository = manager.getRepository(InventoryItem)
await itemRepository.softRemove({ id: inventoryItemId })
await itemRepository.softRemove({ id: inventoryItemId })
await this.eventBusService_
.withTransaction(manager)
.emit(InventoryItemService.Events.DELETED, {
id: inventoryItemId,
})
await this.eventBusService_?.emit?.(InventoryItemService.Events.DELETED, {
id: inventoryItemId,
})
}
}
+133 -104
View File
@@ -1,14 +1,14 @@
import { DeepPartial, EntityManager, FindManyOptions, In } from "typeorm"
import { isDefined, MedusaError } from "medusa-core-utils"
import {
buildQuery,
CreateInventoryLevelInput,
FilterableInventoryLevelProps,
FindConfig,
IEventBusService,
TransactionBaseService,
} from "@medusajs/medusa"
import { SharedContext } from "@medusajs/types"
import { InjectEntityManager, MedusaContext } from "@medusajs/utils"
import { isDefined, MedusaError } from "medusa-core-utils"
import { DeepPartial, EntityManager, FindManyOptions, In } from "typeorm"
import { InventoryLevel } from "../models"
type InjectedDependencies = {
@@ -16,18 +16,18 @@ type InjectedDependencies = {
manager: EntityManager
}
export default class InventoryLevelService extends TransactionBaseService {
export default class InventoryLevelService {
static Events = {
CREATED: "inventory-level.created",
UPDATED: "inventory-level.updated",
DELETED: "inventory-level.deleted",
}
protected readonly eventBusService_: IEventBusService
constructor({ eventBusService }: InjectedDependencies) {
super(arguments[0])
protected readonly manager_: EntityManager
protected readonly eventBusService_: IEventBusService | undefined
constructor({ eventBusService, manager }: InjectedDependencies) {
this.manager_ = manager
this.eventBusService_ = eventBusService
}
@@ -37,11 +37,13 @@ export default class InventoryLevelService extends TransactionBaseService {
* @param config - An object containing configuration options for the query.
* @return Array of inventory levels.
*/
@InjectEntityManager()
async list(
selector: FilterableInventoryLevelProps = {},
config: FindConfig<InventoryLevel> = { relations: [], skip: 0, take: 10 }
config: FindConfig<InventoryLevel> = { relations: [], skip: 0, take: 10 },
@MedusaContext() context: SharedContext = {}
): Promise<InventoryLevel[]> {
const manager = this.activeManager_
const manager = context.transactionManager!
const levelRepository = manager.getRepository(InventoryLevel)
const query = buildQuery(selector, config) as FindManyOptions
@@ -54,11 +56,13 @@ export default class InventoryLevelService extends TransactionBaseService {
* @param config - An object containing configuration options for the query.
* @return An array of inventory levels and a count.
*/
@InjectEntityManager()
async listAndCount(
selector: FilterableInventoryLevelProps = {},
config: FindConfig<InventoryLevel> = { relations: [], skip: 0, take: 10 }
config: FindConfig<InventoryLevel> = { relations: [], skip: 0, take: 10 },
@MedusaContext() context: SharedContext = {}
): Promise<[InventoryLevel[], number]> {
const manager = this.activeManager_
const manager = context.transactionManager!
const levelRepository = manager.getRepository(InventoryLevel)
const query = buildQuery(selector, config) as FindManyOptions
@@ -72,9 +76,11 @@ export default class InventoryLevelService extends TransactionBaseService {
* @return A inventory level.
* @throws If the inventory level ID is not defined or the given ID was not found.
*/
@InjectEntityManager()
async retrieve(
inventoryLevelId: string,
config: FindConfig<InventoryLevel> = {}
config: FindConfig<InventoryLevel> = {},
@MedusaContext() context: SharedContext = {}
): Promise<InventoryLevel> {
if (!isDefined(inventoryLevelId)) {
throw new MedusaError(
@@ -83,10 +89,13 @@ export default class InventoryLevelService extends TransactionBaseService {
)
}
const manager = this.activeManager_
const manager = context.transactionManager!
const levelRepository = manager.getRepository(InventoryLevel)
const query = buildQuery({ id: inventoryLevelId }, config) as FindManyOptions
const query = buildQuery(
{ id: inventoryLevelId },
config
) as FindManyOptions
const [inventoryLevel] = await levelRepository.find(query)
if (!inventoryLevel) {
@@ -104,27 +113,29 @@ export default class InventoryLevelService extends TransactionBaseService {
* @param data - An object containing the properties for the new inventory level.
* @return The created inventory level.
*/
async create(data: CreateInventoryLevelInput): Promise<InventoryLevel> {
return await this.atomicPhase_(async (manager) => {
const levelRepository = manager.getRepository(InventoryLevel)
@InjectEntityManager()
async create(
data: CreateInventoryLevelInput,
@MedusaContext() context: SharedContext = {}
): Promise<InventoryLevel> {
const manager = context.transactionManager!
const inventoryLevel = levelRepository.create({
location_id: data.location_id,
inventory_item_id: data.inventory_item_id,
stocked_quantity: data.stocked_quantity,
reserved_quantity: data.reserved_quantity,
incoming_quantity: data.incoming_quantity,
})
const levelRepository = manager.getRepository(InventoryLevel)
const saved = await levelRepository.save(inventoryLevel)
await this.eventBusService_
.withTransaction(manager)
.emit(InventoryLevelService.Events.CREATED, {
id: saved.id,
})
return saved
const inventoryLevel = levelRepository.create({
location_id: data.location_id,
inventory_item_id: data.inventory_item_id,
stocked_quantity: data.stocked_quantity,
reserved_quantity: data.reserved_quantity,
incoming_quantity: data.incoming_quantity,
})
const saved = await levelRepository.save(inventoryLevel)
await this.eventBusService_?.emit?.(InventoryLevelService.Events.CREATED, {
id: saved.id,
})
return saved
}
/**
@@ -134,35 +145,37 @@ export default class InventoryLevelService extends TransactionBaseService {
* @return The updated inventory level.
* @throws If the inventory level ID is not defined or the given ID was not found.
*/
@InjectEntityManager()
async update(
inventoryLevelId: string,
data: Omit<
DeepPartial<InventoryLevel>,
"id" | "created_at" | "metadata" | "deleted_at"
>
>,
@MedusaContext() context: SharedContext = {}
): Promise<InventoryLevel> {
return await this.atomicPhase_(async (manager) => {
const levelRepository = manager.getRepository(InventoryLevel)
const manager = context.transactionManager!
const levelRepository = manager.getRepository(InventoryLevel)
const item = await this.retrieve(inventoryLevelId)
const item = await this.retrieve(inventoryLevelId, undefined, context)
const shouldUpdate = Object.keys(data).some((key) => {
return item[key] !== data[key]
})
if (shouldUpdate) {
levelRepository.merge(item, data)
await levelRepository.save(item)
await this.eventBusService_
.withTransaction(manager)
.emit(InventoryLevelService.Events.UPDATED, {
id: item.id,
})
}
return item
const shouldUpdate = Object.keys(data).some((key) => {
return item[key] !== data[key]
})
if (shouldUpdate) {
levelRepository.merge(item, data)
await levelRepository.save(item)
await this.eventBusService_?.emit?.(
InventoryLevelService.Events.UPDATED,
{
id: item.id,
}
)
}
return item
}
/**
@@ -171,40 +184,45 @@ export default class InventoryLevelService extends TransactionBaseService {
* @param locationId - The ID of the location.
* @param quantity - The quantity to adjust from the reserved quantity.
*/
@InjectEntityManager()
async adjustReservedQuantity(
inventoryItemId: string,
locationId: string,
quantity: number
quantity: number,
@MedusaContext() context: SharedContext = {}
): Promise<void> {
await this.atomicPhase_(async (manager) => {
await manager
.createQueryBuilder()
.update(InventoryLevel)
.set({ reserved_quantity: () => `reserved_quantity + ${quantity}` })
.where(
"inventory_item_id = :inventoryItemId AND location_id = :locationId",
{ inventoryItemId, locationId }
)
.execute()
})
const manager = context.transactionManager!
await manager
.createQueryBuilder()
.update(InventoryLevel)
.set({ reserved_quantity: () => `reserved_quantity + ${quantity}` })
.where(
"inventory_item_id = :inventoryItemId AND location_id = :locationId",
{ inventoryItemId, locationId }
)
.execute()
}
/**
* Deletes inventory levels by inventory Item ID.
* @param inventoryItemId - The ID or IDs of the inventory item to delete inventory levels for.
*/
async deleteByInventoryItemId(inventoryItemId: string | string[]): Promise<void> {
const ids = Array.isArray(inventoryItemId) ? inventoryItemId : [inventoryItemId]
await this.atomicPhase_(async (manager) => {
const levelRepository = manager.getRepository(InventoryLevel)
* Deletes inventory levels by inventory Item ID.
* @param inventoryItemId - The ID or IDs of the inventory item to delete inventory levels for.
*/
@InjectEntityManager()
async deleteByInventoryItemId(
inventoryItemId: string | string[],
@MedusaContext() context: SharedContext = {}
): Promise<void> {
const ids = Array.isArray(inventoryItemId)
? inventoryItemId
: [inventoryItemId]
await levelRepository.delete({ inventory_item_id: In(ids) })
const manager = context.transactionManager!
const levelRepository = manager.getRepository(InventoryLevel)
await this.eventBusService_
.withTransaction(manager)
.emit(InventoryLevelService.Events.DELETED, {
inventory_item_id: inventoryItemId,
})
await levelRepository.delete({ inventory_item_id: In(ids) })
await this.eventBusService_?.emit?.(InventoryLevelService.Events.DELETED, {
inventory_item_id: inventoryItemId,
})
}
@@ -212,18 +230,22 @@ export default class InventoryLevelService extends TransactionBaseService {
* Deletes an inventory level by ID.
* @param inventoryLevelId - The ID or IDs of the inventory level to delete.
*/
async delete(inventoryLevelId: string | string[]): Promise<void> {
const ids = Array.isArray(inventoryLevelId) ? inventoryLevelId : [inventoryLevelId]
await this.atomicPhase_(async (manager) => {
const levelRepository = manager.getRepository(InventoryLevel)
@InjectEntityManager()
async delete(
inventoryLevelId: string | string[],
@MedusaContext() context: SharedContext = {}
): Promise<void> {
const ids = Array.isArray(inventoryLevelId)
? inventoryLevelId
: [inventoryLevelId]
await levelRepository.delete({ id: In(ids) })
const manager = context.transactionManager!
const levelRepository = manager.getRepository(InventoryLevel)
await this.eventBusService_
.withTransaction(manager)
.emit(InventoryLevelService.Events.DELETED, {
id: inventoryLevelId,
})
await levelRepository.delete({ id: In(ids) })
await this.eventBusService_?.emit?.(InventoryLevelService.Events.DELETED, {
id: inventoryLevelId,
})
}
@@ -231,17 +253,18 @@ export default class InventoryLevelService extends TransactionBaseService {
* Deletes inventory levels by location ID.
* @param locationId - The ID of the location to delete inventory levels for.
*/
async deleteByLocationId(locationId: string): Promise<void> {
return await this.atomicPhase_(async (manager) => {
const levelRepository = manager.getRepository(InventoryLevel)
@InjectEntityManager()
async deleteByLocationId(
locationId: string,
@MedusaContext() context: SharedContext = {}
): Promise<void> {
const manager = context.transactionManager!
const levelRepository = manager.getRepository(InventoryLevel)
await levelRepository.delete({ location_id: locationId })
await levelRepository.delete({ location_id: locationId })
await this.eventBusService_
.withTransaction(manager)
.emit(InventoryLevelService.Events.DELETED, {
location_id: locationId,
})
await this.eventBusService_?.emit?.(InventoryLevelService.Events.DELETED, {
location_id: locationId,
})
}
@@ -251,15 +274,17 @@ export default class InventoryLevelService extends TransactionBaseService {
* @param locationIds - The IDs of the locations.
* @return The total stocked quantity.
*/
@InjectEntityManager()
async getStockedQuantity(
inventoryItemId: string,
locationIds: string[] | string
locationIds: string[] | string,
@MedusaContext() context: SharedContext = {}
): Promise<number> {
if (!Array.isArray(locationIds)) {
locationIds = [locationIds]
}
const manager = this.activeManager_
const manager = context.transactionManager!
const levelRepository = manager.getRepository(InventoryLevel)
const result = await levelRepository
@@ -278,15 +303,17 @@ export default class InventoryLevelService extends TransactionBaseService {
* @param locationIds - The IDs of the locations.
* @return The total available quantity.
*/
@InjectEntityManager()
async getAvailableQuantity(
inventoryItemId: string,
locationIds: string[] | string
locationIds: string[] | string,
@MedusaContext() context: SharedContext = {}
): Promise<number> {
if (!Array.isArray(locationIds)) {
locationIds = [locationIds]
}
const manager = this.activeManager_
const manager = context.transactionManager!
const levelRepository = manager.getRepository(InventoryLevel)
const result = await levelRepository
@@ -305,15 +332,17 @@ export default class InventoryLevelService extends TransactionBaseService {
* @param locationIds - The IDs of the locations.
* @return The total reserved quantity.
*/
@InjectEntityManager()
async getReservedQuantity(
inventoryItemId: string,
locationIds: string[] | string
locationIds: string[] | string,
@MedusaContext() context: SharedContext = {}
): Promise<number> {
if (!Array.isArray(locationIds)) {
locationIds = [locationIds]
}
const manager = this.activeManager_
const manager = context.transactionManager!
const levelRepository = manager.getRepository(InventoryLevel)
const result = await levelRepository
+233 -148
View File
@@ -13,18 +13,18 @@ import {
InventoryItemDTO,
InventoryLevelDTO,
ReservationItemDTO,
TransactionBaseService,
UpdateInventoryLevelInput,
UpdateReservationItemInput,
} from "@medusajs/medusa"
import { SharedContext } from "@medusajs/types"
import { InjectEntityManager, MedusaContext } from "@medusajs/utils"
import { MedusaError } from "medusa-core-utils"
import { EntityManager } from "typeorm"
import {
InventoryItemService,
InventoryLevelService,
ReservationItemService,
} from "./"
import { EntityManager } from "typeorm"
type InjectedDependencies = {
manager: EntityManager
@@ -33,11 +33,9 @@ type InjectedDependencies = {
inventoryLevelService: InventoryLevelService
reservationItemService: ReservationItemService
}
export default class InventoryService
extends TransactionBaseService
implements IInventoryService
{
protected readonly eventBusService_: IEventBusService
export default class InventoryService implements IInventoryService {
protected readonly manager_: EntityManager
protected readonly eventBusService_: IEventBusService | undefined
protected readonly inventoryItemService_: InventoryItemService
protected readonly reservationItemService_: ReservationItemService
protected readonly inventoryLevelService_: InventoryLevelService
@@ -53,9 +51,7 @@ export default class InventoryService
options?: unknown,
moduleDeclaration?: InternalModuleDeclaration
) {
// @ts-ignore
super(...arguments)
this.manager_ = manager
this.eventBusService_ = eventBusService
this.inventoryItemService_ = inventoryItemService
this.inventoryLevelService_ = inventoryLevelService
@@ -68,13 +64,17 @@ export default class InventoryService
* @param config - the find configuration to use
* @return A tuple of inventory items and their total count
*/
@InjectEntityManager()
async listInventoryItems(
selector: FilterableInventoryItemProps,
config: FindConfig<InventoryItemDTO> = { relations: [], skip: 0, take: 10 }
config: FindConfig<InventoryItemDTO> = { relations: [], skip: 0, take: 10 },
@MedusaContext() context: SharedContext = {}
): Promise<[InventoryItemDTO[], number]> {
return await this.inventoryItemService_
.withTransaction(this.activeManager_)
.listAndCount(selector, config)
return await this.inventoryItemService_.listAndCount(
selector,
config,
context
)
}
/**
@@ -83,13 +83,21 @@ export default class InventoryService
* @param config - the find configuration to use
* @return A tuple of inventory levels and their total count
*/
@InjectEntityManager()
async listInventoryLevels(
selector: FilterableInventoryLevelProps,
config: FindConfig<InventoryLevelDTO> = { relations: [], skip: 0, take: 10 }
config: FindConfig<InventoryLevelDTO> = {
relations: [],
skip: 0,
take: 10,
},
@MedusaContext() context: SharedContext = {}
): Promise<[InventoryLevelDTO[], number]> {
return await this.inventoryLevelService_
.withTransaction(this.activeManager_)
.listAndCount(selector, config)
return await this.inventoryLevelService_.listAndCount(
selector,
config,
context
)
}
/**
@@ -98,17 +106,21 @@ export default class InventoryService
* @param config - the find configuration to use
* @return A tuple of reservation items and their total count
*/
@InjectEntityManager()
async listReservationItems(
selector: FilterableReservationItemProps,
config: FindConfig<ReservationItemDTO> = {
relations: [],
skip: 0,
take: 10,
}
},
@MedusaContext() context: SharedContext = {}
): Promise<[ReservationItemDTO[], number]> {
return await this.reservationItemService_
.withTransaction(this.activeManager_)
.listAndCount(selector, config)
return await this.reservationItemService_.listAndCount(
selector,
config,
context
)
}
/**
@@ -117,13 +129,17 @@ export default class InventoryService
* @param config - the find configuration to use
* @return The retrieved inventory item
*/
@InjectEntityManager()
async retrieveInventoryItem(
inventoryItemId: string,
config?: FindConfig<InventoryItemDTO>
config?: FindConfig<InventoryItemDTO>,
@MedusaContext() context: SharedContext = {}
): Promise<InventoryItemDTO> {
const inventoryItem = await this.inventoryItemService_
.withTransaction(this.activeManager_)
.retrieve(inventoryItemId, config)
const inventoryItem = await this.inventoryItemService_.retrieve(
inventoryItemId,
config,
context
)
return { ...inventoryItem }
}
@@ -133,16 +149,17 @@ export default class InventoryService
* @param locationId - the id of the location
* @return the retrieved inventory level
*/
@InjectEntityManager()
async retrieveInventoryLevel(
inventoryItemId: string,
locationId: string
locationId: string,
@MedusaContext() context: SharedContext = {}
): Promise<InventoryLevelDTO> {
const [inventoryLevel] = await this.inventoryLevelService_
.withTransaction(this.activeManager_)
.list(
{ inventory_item_id: inventoryItemId, location_id: locationId },
{ take: 1 }
)
const [inventoryLevel] = await this.inventoryLevelService_.list(
{ inventory_item_id: inventoryItemId, location_id: locationId },
{ take: 1 },
context
)
if (!inventoryLevel) {
throw new MedusaError(
MedusaError.Types.NOT_FOUND,
@@ -152,15 +169,21 @@ export default class InventoryService
return inventoryLevel
}
/**
/**
* Retrieves a reservation item
* @param inventoryItemId - the id of the reservation item
* @return the retrieved reservation level
*/
async retrieveReservationItem(reservationId: string): Promise<ReservationItemDTO> {
return await this.reservationItemService_
.withTransaction(this.activeManager_)
.retrieve(reservationId)
@InjectEntityManager()
async retrieveReservationItem(
reservationId: string,
@MedusaContext() context: SharedContext = {}
): Promise<ReservationItemDTO> {
return await this.reservationItemService_.retrieve(
reservationId,
undefined,
context
)
}
/**
@@ -168,19 +191,20 @@ export default class InventoryService
* @param input - the input object
* @return The created reservation item
*/
@InjectEntityManager()
async createReservationItem(
input: CreateReservationItemInput
input: CreateReservationItemInput,
@MedusaContext() context: SharedContext = {}
): Promise<ReservationItemDTO> {
// Verify that the item is stocked at the location
const [inventoryLevel] = await this.inventoryLevelService_
.withTransaction(this.activeManager_)
.list(
{
inventory_item_id: input.inventory_item_id,
location_id: input.location_id,
},
{ take: 1 }
)
const [inventoryLevel] = await this.inventoryLevelService_.list(
{
inventory_item_id: input.inventory_item_id,
location_id: input.location_id,
},
{ take: 1 },
context
)
if (!inventoryLevel) {
throw new MedusaError(
@@ -189,9 +213,10 @@ export default class InventoryService
)
}
const reservationItem = await this.reservationItemService_
.withTransaction(this.activeManager_)
.create(input)
const reservationItem = await this.reservationItemService_.create(
input,
context
)
return { ...reservationItem }
}
@@ -201,12 +226,15 @@ export default class InventoryService
* @param input - the input object
* @return The created inventory item
*/
@InjectEntityManager()
async createInventoryItem(
input: CreateInventoryItemInput
input: CreateInventoryItemInput,
@MedusaContext() context: SharedContext = {}
): Promise<InventoryItemDTO> {
const inventoryItem = await this.inventoryItemService_
.withTransaction(this.activeManager_)
.create(input)
const inventoryItem = await this.inventoryItemService_.create(
input,
context
)
return { ...inventoryItem }
}
@@ -215,12 +243,12 @@ export default class InventoryService
* @param input - the input object
* @return The created inventory level
*/
@InjectEntityManager()
async createInventoryLevel(
input: CreateInventoryLevelInput
input: CreateInventoryLevelInput,
@MedusaContext() context: SharedContext = {}
): Promise<InventoryLevelDTO> {
return await this.inventoryLevelService_
.withTransaction(this.activeManager_)
.create(input)
return await this.inventoryLevelService_.create(input, context)
}
/**
@@ -229,13 +257,17 @@ export default class InventoryService
* @param input - the input object
* @return The updated inventory item
*/
@InjectEntityManager()
async updateInventoryItem(
inventoryItemId: string,
input: Partial<CreateInventoryItemInput>
input: Partial<CreateInventoryItemInput>,
@MedusaContext() context: SharedContext = {}
): Promise<InventoryItemDTO> {
const inventoryItem = await this.inventoryItemService_
.withTransaction(this.activeManager_)
.update(inventoryItemId, input)
const inventoryItem = await this.inventoryItemService_.update(
inventoryItemId,
input,
context
)
return { ...inventoryItem }
}
@@ -243,26 +275,39 @@ export default class InventoryService
* Deletes an inventory item
* @param inventoryItemId - the id of the inventory item to delete
*/
async deleteInventoryItem(inventoryItemId: string): Promise<void> {
await this.inventoryLevelService_
.withTransaction(this.activeManager_)
.deleteByInventoryItemId(inventoryItemId)
@InjectEntityManager()
async deleteInventoryItem(
inventoryItemId: string,
@MedusaContext() context: SharedContext = {}
): Promise<void> {
await this.inventoryLevelService_.deleteByInventoryItemId(
inventoryItemId,
context
)
return await this.inventoryItemService_
.withTransaction(this.activeManager_)
.delete(inventoryItemId)
return await this.inventoryItemService_.delete(inventoryItemId, context)
}
async deleteInventoryItemLevelByLocationId(locationId: string): Promise<void> {
return await this.inventoryLevelService_
.withTransaction(this.activeManager_)
.deleteByLocationId(locationId)
@InjectEntityManager()
async deleteInventoryItemLevelByLocationId(
locationId: string,
@MedusaContext() context: SharedContext = {}
): Promise<void> {
return await this.inventoryLevelService_.deleteByLocationId(
locationId,
context
)
}
async deleteReservationItemByLocationId(locationId: string): Promise<void> {
return await this.reservationItemService_
.withTransaction(this.activeManager_)
.deleteByLocationId(locationId)
@InjectEntityManager()
async deleteReservationItemByLocationId(
locationId: string,
@MedusaContext() context: SharedContext = {}
): Promise<void> {
return await this.reservationItemService_.deleteByLocationId(
locationId,
context
)
}
/**
@@ -270,24 +315,23 @@ export default class InventoryService
* @param inventoryItemId - the id of the inventory item associated with the level
* @param locationId - the id of the location associated with the level
*/
@InjectEntityManager()
async deleteInventoryLevel(
inventoryItemId: string,
locationId: string
locationId: string,
@MedusaContext() context: SharedContext = {}
): Promise<void> {
const [inventoryLevel] = await this.inventoryLevelService_
.withTransaction(this.activeManager_)
.list(
{ inventory_item_id: inventoryItemId, location_id: locationId },
{ take: 1 }
)
const [inventoryLevel] = await this.inventoryLevelService_.list(
{ inventory_item_id: inventoryItemId, location_id: locationId },
{ take: 1 },
context
)
if (!inventoryLevel) {
return
}
return await this.inventoryLevelService_
.withTransaction(this.activeManager_)
.delete(inventoryLevel.id)
return await this.inventoryLevelService_.delete(inventoryLevel.id, context)
}
/**
@@ -297,17 +341,18 @@ export default class InventoryService
* @param input - the input object
* @return The updated inventory level
*/
@InjectEntityManager()
async updateInventoryLevel(
inventoryItemId: string,
locationId: string,
input: UpdateInventoryLevelInput
input: UpdateInventoryLevelInput,
@MedusaContext() context: SharedContext = {}
): Promise<InventoryLevelDTO> {
const [inventoryLevel] = await this.inventoryLevelService_
.withTransaction(this.activeManager_)
.list(
{ inventory_item_id: inventoryItemId, location_id: locationId },
{ take: 1 }
)
const [inventoryLevel] = await this.inventoryLevelService_.list(
{ inventory_item_id: inventoryItemId, location_id: locationId },
{ take: 1 },
context
)
if (!inventoryLevel) {
throw new MedusaError(
@@ -316,9 +361,11 @@ export default class InventoryService
)
}
return await this.inventoryLevelService_
.withTransaction(this.activeManager_)
.update(inventoryLevel.id, input)
return await this.inventoryLevelService_.update(
inventoryLevel.id,
input,
context
)
}
/**
@@ -327,33 +374,44 @@ export default class InventoryService
* @param input - the input object
* @return The updated inventory level
*/
@InjectEntityManager()
async updateReservationItem(
reservationItemId: string,
input: UpdateReservationItemInput
input: UpdateReservationItemInput,
@MedusaContext() context: SharedContext = {}
): Promise<ReservationItemDTO> {
return await this.reservationItemService_
.withTransaction(this.activeManager_)
.update(reservationItemId, input)
return await this.reservationItemService_.update(
reservationItemId,
input,
context
)
}
/**
* Deletes reservation items by line item
* @param lineItemId - the id of the line item associated with the reservation item
*/
async deleteReservationItemsByLineItem(lineItemId: string): Promise<void> {
return await this.reservationItemService_
.withTransaction(this.activeManager_)
.deleteByLineItem(lineItemId)
@InjectEntityManager()
async deleteReservationItemsByLineItem(
lineItemId: string,
@MedusaContext() context: SharedContext = {}
): Promise<void> {
return await this.reservationItemService_.deleteByLineItem(
lineItemId,
context
)
}
/**
* Deletes a reservation item
* @param reservationItemId - the id of the reservation item to delete
*/
async deleteReservationItem(reservationItemId: string | string[]): Promise<void> {
return await this.reservationItemService_
.withTransaction(this.activeManager_)
.delete(reservationItemId)
@InjectEntityManager()
async deleteReservationItem(
reservationItemId: string | string[],
@MedusaContext() context: SharedContext = {}
): Promise<void> {
return await this.reservationItemService_.delete(reservationItemId, context)
}
/**
@@ -364,17 +422,18 @@ export default class InventoryService
* @return The updated inventory level
* @throws when the inventory level is not found
*/
@InjectEntityManager()
async adjustInventory(
inventoryItemId: string,
locationId: string,
adjustment: number
adjustment: number,
@MedusaContext() context: SharedContext = {}
): Promise<InventoryLevelDTO> {
const [inventoryLevel] = await this.inventoryLevelService_
.withTransaction(this.activeManager_)
.list(
{ inventory_item_id: inventoryItemId, location_id: locationId },
{ take: 1 }
)
const [inventoryLevel] = await this.inventoryLevelService_.list(
{ inventory_item_id: inventoryItemId, location_id: locationId },
{ take: 1 },
context
)
if (!inventoryLevel) {
throw new MedusaError(
MedusaError.Types.NOT_FOUND,
@@ -382,11 +441,13 @@ export default class InventoryService
)
}
const updatedInventoryLevel = await this.inventoryLevelService_
.withTransaction(this.activeManager_)
.update(inventoryLevel.id, {
const updatedInventoryLevel = await this.inventoryLevelService_.update(
inventoryLevel.id,
{
stocked_quantity: inventoryLevel.stocked_quantity + adjustment,
})
},
context
)
return { ...updatedInventoryLevel }
}
@@ -398,20 +459,27 @@ export default class InventoryService
* @return The available quantity
* @throws when the inventory item is not found
*/
@InjectEntityManager()
async retrieveAvailableQuantity(
inventoryItemId: string,
locationIds: string[]
locationIds: string[],
@MedusaContext() context: SharedContext = {}
): Promise<number> {
// Throws if item does not exist
await this.inventoryItemService_
.withTransaction(this.activeManager_)
.retrieve(inventoryItemId, {
await this.inventoryItemService_.retrieve(
inventoryItemId,
{
select: ["id"],
})
},
context
)
const availableQuantity = await this.inventoryLevelService_
.withTransaction(this.activeManager_)
.getAvailableQuantity(inventoryItemId, locationIds)
const availableQuantity =
await this.inventoryLevelService_.getAvailableQuantity(
inventoryItemId,
locationIds,
context
)
return availableQuantity
}
@@ -423,20 +491,27 @@ export default class InventoryService
* @return The stocked quantity
* @throws when the inventory item is not found
*/
@InjectEntityManager()
async retrieveStockedQuantity(
inventoryItemId: string,
locationIds: string[]
locationIds: string[],
@MedusaContext() context: SharedContext = {}
): Promise<number> {
// Throws if item does not exist
await this.inventoryItemService_
.withTransaction(this.activeManager_)
.retrieve(inventoryItemId, {
await this.inventoryItemService_.retrieve(
inventoryItemId,
{
select: ["id"],
})
},
context
)
const stockedQuantity = await this.inventoryLevelService_
.withTransaction(this.activeManager_)
.getStockedQuantity(inventoryItemId, locationIds)
const stockedQuantity =
await this.inventoryLevelService_.getStockedQuantity(
inventoryItemId,
locationIds,
context
)
return stockedQuantity
}
@@ -448,20 +523,27 @@ export default class InventoryService
* @return The reserved quantity
* @throws when the inventory item is not found
*/
@InjectEntityManager()
async retrieveReservedQuantity(
inventoryItemId: string,
locationIds: string[]
locationIds: string[],
@MedusaContext() context: SharedContext = {}
): Promise<number> {
// Throws if item does not exist
await this.inventoryItemService_
.withTransaction(this.activeManager_)
.retrieve(inventoryItemId, {
await this.inventoryItemService_.retrieve(
inventoryItemId,
{
select: ["id"],
})
},
context
)
const reservedQuantity = await this.inventoryLevelService_
.withTransaction(this.activeManager_)
.getReservedQuantity(inventoryItemId, locationIds)
const reservedQuantity =
await this.inventoryLevelService_.getReservedQuantity(
inventoryItemId,
locationIds,
context
)
return reservedQuantity
}
@@ -473,14 +555,17 @@ export default class InventoryService
* @param quantity - the quantity to check
* @return Whether there is sufficient inventory
*/
@InjectEntityManager()
async confirmInventory(
inventoryItemId: string,
locationIds: string[],
quantity: number
quantity: number,
@MedusaContext() context: SharedContext = {}
): Promise<boolean> {
const availableQuantity = await this.retrieveAvailableQuantity(
inventoryItemId,
locationIds
locationIds,
context
)
return availableQuantity >= quantity
}
@@ -1,17 +1,17 @@
import { EntityManager, FindManyOptions } from "typeorm"
import { isDefined, MedusaError } from "medusa-core-utils"
import {
buildQuery,
CreateReservationItemInput,
FilterableReservationItemProps,
FindConfig,
IEventBusService,
TransactionBaseService,
UpdateReservationItemInput,
} from "@medusajs/medusa"
import { ReservationItem } from "../models"
import { SharedContext } from "@medusajs/types"
import { InjectEntityManager, MedusaContext } from "@medusajs/utils"
import { isDefined, MedusaError } from "medusa-core-utils"
import { EntityManager, FindManyOptions } from "typeorm"
import { InventoryLevelService } from "."
import { ReservationItem } from "../models"
type InjectedDependencies = {
eventBusService: IEventBusService
@@ -19,22 +19,23 @@ type InjectedDependencies = {
inventoryLevelService: InventoryLevelService
}
export default class ReservationItemService extends TransactionBaseService {
export default class ReservationItemService {
static Events = {
CREATED: "reservation-item.created",
UPDATED: "reservation-item.updated",
DELETED: "reservation-item.deleted",
}
protected readonly eventBusService_: IEventBusService
protected readonly manager_: EntityManager
protected readonly eventBusService_: IEventBusService | undefined
protected readonly inventoryLevelService_: InventoryLevelService
constructor({
eventBusService,
inventoryLevelService,
manager,
}: InjectedDependencies) {
super(arguments[0])
this.manager_ = manager
this.eventBusService_ = eventBusService
this.inventoryLevelService_ = inventoryLevelService
}
@@ -45,11 +46,13 @@ export default class ReservationItemService extends TransactionBaseService {
* @param config - Configuration for the query.
* @return Array of reservation items that match the selector.
*/
@InjectEntityManager()
async list(
selector: FilterableReservationItemProps = {},
config: FindConfig<ReservationItem> = { relations: [], skip: 0, take: 10 }
config: FindConfig<ReservationItem> = { relations: [], skip: 0, take: 10 },
@MedusaContext() context: SharedContext = {}
): Promise<ReservationItem[]> {
const manager = this.activeManager_
const manager = context.transactionManager!
const itemRepository = manager.getRepository(ReservationItem)
const query = buildQuery(selector, config) as FindManyOptions
@@ -62,11 +65,13 @@ export default class ReservationItemService extends TransactionBaseService {
* @param config - Configuration for the query.
* @return Array of reservation items that match the selector and the total count.
*/
@InjectEntityManager()
async listAndCount(
selector: FilterableReservationItemProps = {},
config: FindConfig<ReservationItem> = { relations: [], skip: 0, take: 10 }
config: FindConfig<ReservationItem> = { relations: [], skip: 0, take: 10 },
@MedusaContext() context: SharedContext = {}
): Promise<[ReservationItem[], number]> {
const manager = this.activeManager_
const manager = context.transactionManager!
const itemRepository = manager.getRepository(ReservationItem)
const query = buildQuery(selector, config) as FindManyOptions
@@ -80,9 +85,11 @@ export default class ReservationItemService extends TransactionBaseService {
* @return The reservation item with the provided id.
* @throws If reservationItemId is not defined or if the reservation item was not found.
*/
@InjectEntityManager()
async retrieve(
reservationItemId: string,
config: FindConfig<ReservationItem> = {}
config: FindConfig<ReservationItem> = {},
@MedusaContext() context: SharedContext = {}
): Promise<ReservationItem> {
if (!isDefined(reservationItemId)) {
throw new MedusaError(
@@ -91,7 +98,7 @@ export default class ReservationItemService extends TransactionBaseService {
)
}
const manager = this.activeManager_
const manager = context.transactionManager!
const reservationItemRepository = manager.getRepository(ReservationItem)
const query = buildQuery(
@@ -115,37 +122,37 @@ export default class ReservationItemService extends TransactionBaseService {
* @param data - The reservation item data.
* @return The created reservation item.
*/
async create(data: CreateReservationItemInput): Promise<ReservationItem> {
return await this.atomicPhase_(async (manager) => {
const itemRepository = manager.getRepository(ReservationItem)
@InjectEntityManager()
async create(
data: CreateReservationItemInput,
@MedusaContext() context: SharedContext = {}
): Promise<ReservationItem> {
const manager = context.transactionManager!
const itemRepository = manager.getRepository(ReservationItem)
const inventoryItem = itemRepository.create({
inventory_item_id: data.inventory_item_id,
line_item_id: data.line_item_id,
location_id: data.location_id,
quantity: data.quantity,
metadata: data.metadata,
})
const [newInventoryItem] = await Promise.all([
itemRepository.save(inventoryItem),
this.inventoryLevelService_
.withTransaction(manager)
.adjustReservedQuantity(
data.inventory_item_id,
data.location_id,
data.quantity
),
])
await this.eventBusService_
.withTransaction(manager)
.emit(ReservationItemService.Events.CREATED, {
id: newInventoryItem.id,
})
return newInventoryItem
const inventoryItem = itemRepository.create({
inventory_item_id: data.inventory_item_id,
line_item_id: data.line_item_id,
location_id: data.location_id,
quantity: data.quantity,
metadata: data.metadata,
})
const [newInventoryItem] = await Promise.all([
itemRepository.save(inventoryItem),
this.inventoryLevelService_.adjustReservedQuantity(
data.inventory_item_id,
data.location_id,
data.quantity,
context
),
])
await this.eventBusService_?.emit?.(ReservationItemService.Events.CREATED, {
id: newInventoryItem.id,
})
return newInventoryItem
}
/**
@@ -154,99 +161,99 @@ export default class ReservationItemService extends TransactionBaseService {
* @param data - The reservation item data to update.
* @return The updated reservation item.
*/
@InjectEntityManager()
async update(
reservationItemId: string,
data: UpdateReservationItemInput
data: UpdateReservationItemInput,
@MedusaContext() context: SharedContext = {}
): Promise<ReservationItem> {
return await this.atomicPhase_(async (manager) => {
const itemRepository = manager.getRepository(ReservationItem)
const manager = context.transactionManager!
const itemRepository = manager.getRepository(ReservationItem)
const item = await this.retrieve(reservationItemId)
const item = await this.retrieve(reservationItemId)
const shouldUpdateQuantity =
isDefined(data.quantity) && data.quantity !== item.quantity
const shouldUpdateQuantity =
isDefined(data.quantity) && data.quantity !== item.quantity
const shouldUpdateLocation =
isDefined(data.location_id) && data.location_id !== item.location_id
const shouldUpdateLocation =
isDefined(data.location_id) && data.location_id !== item.location_id
const ops: Promise<unknown>[] = []
const ops: Promise<unknown>[] = []
if (shouldUpdateLocation) {
ops.push(
this.inventoryLevelService_
.withTransaction(manager)
.adjustReservedQuantity(
item.inventory_item_id,
item.location_id,
item.quantity * -1
),
this.inventoryLevelService_
.withTransaction(manager)
.adjustReservedQuantity(
item.inventory_item_id,
data.location_id!,
data.quantity || item.quantity!
)
if (shouldUpdateLocation) {
ops.push(
this.inventoryLevelService_.adjustReservedQuantity(
item.inventory_item_id,
item.location_id,
item.quantity * -1,
context
),
this.inventoryLevelService_.adjustReservedQuantity(
item.inventory_item_id,
data.location_id!,
data.quantity || item.quantity!,
context
)
} else if (shouldUpdateQuantity) {
const quantityDiff = data.quantity! - item.quantity
ops.push(
this.inventoryLevelService_
.withTransaction(manager)
.adjustReservedQuantity(
item.inventory_item_id,
item.location_id,
quantityDiff
)
)
} else if (shouldUpdateQuantity) {
const quantityDiff = data.quantity! - item.quantity
ops.push(
this.inventoryLevelService_.adjustReservedQuantity(
item.inventory_item_id,
item.location_id,
quantityDiff,
context
)
}
)
}
const mergedItem = itemRepository.merge(item, data)
const mergedItem = itemRepository.merge(item, data)
ops.push(itemRepository.save(item))
ops.push(itemRepository.save(item))
await Promise.all(ops)
await Promise.all(ops)
await this.eventBusService_
.withTransaction(manager)
.emit(ReservationItemService.Events.UPDATED, {
id: mergedItem.id,
})
return mergedItem
await this.eventBusService_?.emit?.(ReservationItemService.Events.UPDATED, {
id: mergedItem.id,
})
return mergedItem
}
/**
* Deletes a reservation item by line item id.
* @param lineItemId - the id of the line item to delete.
*/
async deleteByLineItem(lineItemId: string): Promise<void> {
await this.atomicPhase_(async (manager) => {
const itemRepository = manager.getRepository(ReservationItem)
@InjectEntityManager()
async deleteByLineItem(
lineItemId: string,
@MedusaContext() context: SharedContext = {}
): Promise<void> {
const manager = context.transactionManager!
const itemRepository = manager.getRepository(ReservationItem)
const items = await this.list({ line_item_id: lineItemId })
const items = await this.list(
{ line_item_id: lineItemId },
undefined,
context
)
const ops: Promise<unknown>[] = []
for (const item of items) {
ops.push(itemRepository.softRemove({ line_item_id: lineItemId }))
ops.push(
this.inventoryLevelService_
.withTransaction(manager)
.adjustReservedQuantity(
item.inventory_item_id,
item.location_id,
item.quantity * -1
)
const ops: Promise<unknown>[] = []
for (const item of items) {
ops.push(itemRepository.softRemove({ line_item_id: lineItemId }))
ops.push(
this.inventoryLevelService_.adjustReservedQuantity(
item.inventory_item_id,
item.location_id,
item.quantity * -1,
context
)
}
await Promise.all(ops)
)
}
await Promise.all(ops)
await this.eventBusService_
.withTransaction(manager)
.emit(ReservationItemService.Events.DELETED, {
line_item_id: lineItemId,
})
await this.eventBusService_?.emit?.(ReservationItemService.Events.DELETED, {
line_item_id: lineItemId,
})
}
@@ -254,22 +261,23 @@ export default class ReservationItemService extends TransactionBaseService {
* Deletes reservation items by location ID.
* @param locationId - The ID of the location to delete reservations for.
*/
async deleteByLocationId(locationId: string): Promise<void> {
return await this.atomicPhase_(async (manager) => {
const itemRepository = manager.getRepository(ReservationItem)
@InjectEntityManager()
async deleteByLocationId(
locationId: string,
@MedusaContext() context: SharedContext = {}
): Promise<void> {
const manager = context.transactionManager!
const itemRepository = manager.getRepository(ReservationItem)
await itemRepository
.createQueryBuilder("reservation_item")
.softDelete()
.where("location_id = :locationId", { locationId })
.andWhere("deleted_at IS NULL")
.execute()
await itemRepository
.createQueryBuilder("reservation_item")
.softDelete()
.where("location_id = :locationId", { locationId })
.andWhere("deleted_at IS NULL")
.execute()
await this.eventBusService_
.withTransaction(manager)
.emit(ReservationItemService.Events.DELETED, {
location_id: locationId,
})
await this.eventBusService_?.emit?.(ReservationItemService.Events.DELETED, {
location_id: locationId,
})
}
@@ -277,35 +285,32 @@ export default class ReservationItemService extends TransactionBaseService {
* Deletes a reservation item by id.
* @param reservationItemId - the id of the reservation item to delete.
*/
async delete(reservationItemId: string | string[]): Promise<void> {
async delete(
reservationItemId: string | string[],
@MedusaContext() context: SharedContext = {}
): Promise<void> {
const ids = Array.isArray(reservationItemId)
? reservationItemId
: [reservationItemId]
return await this.atomicPhase_(async (manager) => {
const itemRepository = manager.getRepository(ReservationItem)
const manager = context.transactionManager!
const itemRepository = manager.getRepository(ReservationItem)
const items = await this.list({ id: ids })
const items = await this.list({ id: ids })
await itemRepository.softRemove(items)
const inventoryServiceTx =
this.inventoryLevelService_.withTransaction(manager)
await Promise.all(
items.map(async (item) => {
return inventoryServiceTx.adjustReservedQuantity(
item.inventory_item_id,
item.location_id,
item.quantity * -1
)
})
const promises: Promise<unknown>[] = items.map(async (item) => {
this.inventoryLevelService_.adjustReservedQuantity(
item.inventory_item_id,
item.location_id,
item.quantity * -1,
context
)
})
await this.eventBusService_
.withTransaction(manager)
.emit(ReservationItemService.Events.DELETED, {
id: reservationItemId,
})
promises.push(itemRepository.softRemove(items))
await Promise.all(promises)
await this.eventBusService_?.emit?.(ReservationItemService.Events.DELETED, {
id: reservationItemId,
})
}
}