chore: added missing withTransacton, create-variant using TO (#3047)

Create variant integrated with Inventory modules
This commit is contained in:
Carlos R. L. Rodrigues
2023-01-18 09:29:06 -03:00
committed by GitHub
parent 150696de99
commit aa54d902e5
11 changed files with 409 additions and 128 deletions

View File

@@ -1,53 +1,68 @@
if (process.env.NODE_ENV !== "development") {
return
}
const path = require("path")
const Module = require("module")
const originalRequire = Module.prototype.require
const medusaCore = path.resolve(path.join(__dirname, "../../packages"))
function replacePath(requirePath, package, concatPackage = true) {
const idx = requirePath.indexOf(package)
const packPath = requirePath.substring(idx + package.length)
function replacePath(requirePath, pack, concatPackage = true) {
const idx = requirePath.indexOf(pack)
const packPath = requirePath.substring(idx + pack.length).replace(/\\/g, "/")
let newPath =
medusaCore +
"/" +
(concatPackage ? package + "/" : "") +
(concatPackage ? pack + "/" : "") +
packPath.replace("/dist", "/src").replace(".js", "")
if (!newPath.includes("/src")) {
newPath += "/src"
}
return path.resolve(newPath)
}
Module.prototype.require = function (...args) {
function checkAndReplacePaths(path) {
const interfaces = "medusa-interfaces"
const utils = "medusa-core-utils"
const base = "@medusajs"
if (args[0].includes(base)) {
args[0] = replacePath(args[0], base, false)
} else if (args[0].includes(interfaces)) {
args[0] = replacePath(args[0], interfaces)
} else if (args[0].includes(utils)) {
args[0] = replacePath(args[0], utils)
if (path.includes(base)) {
path = replacePath(path, base, false)
} else if (path.includes(interfaces)) {
path = replacePath(path, interfaces)
} else if (path.includes(utils)) {
path = replacePath(path, utils)
}
return path
}
Module.prototype.require = function (...args) {
args[0] = checkAndReplacePaths(args[0])
if (args[0] === "glob") {
const glob = originalRequire.apply(this, args)
const originalGlobSync = glob.sync
glob.GlobSync = glob.sync = (pattern, options) => {
if (pattern.endsWith(".js") || pattern.endsWith(".ts")) {
pattern = checkAndReplacePaths(pattern)
pattern = pattern.replace(".js", ".{j,t}s").replace("/dist/", "/src/")
}
return originalGlobSync.apply(this, [pattern, options])
}
return glob
} else if (args[0] === "resolve-cwd") {
const resolveCwd = originalRequire.apply(this, args)
const newResolveCwd = (pattern) => {
pattern = checkAndReplacePaths(pattern)
return resolveCwd.apply(this, [pattern])
}
return newResolveCwd
}
return originalRequire.apply(this, args)

View File

@@ -14,6 +14,22 @@ const medusaCore = path
.replace(/\\/g, "/")
let WATCHING = false
let IS_RELOADING = false
function getParentModulesIds(element) {
if (!element) {
return []
}
const ids = [element.id]
let parent = element.parent
while (parent && parent.id.replace(/\\/g, "/").includes(medusaCore)) {
ids.push(parent.id)
parent = parent.parent
}
return ids
}
const watchFiles = () => {
if (WATCHING) {
return
@@ -42,7 +58,12 @@ const watchFiles = () => {
})
watcher.on("change", async function (rawFile) {
if (IS_RELOADING) {
return
}
console.log("Reloading server...")
IS_RELOADING = true
const start = Date.now()
const file = rawFile.replace(/\\/g, "/")
@@ -75,12 +96,18 @@ const watchFiles = () => {
next.endsWith(".ts") ||
name.startsWith(next)
) {
delete module.constructor._cache[rawName]
const cacheToClean = getParentModulesIds(
module.constructor._cache[rawName]
)
for (const id of cacheToClean) {
delete module.constructor._cache[id]
}
}
}
}
await bootstrapApp()
IS_RELOADING = false
console.log("Server reloaded in", Date.now() - start, "ms")
})
@@ -119,8 +146,6 @@ const bootstrapApp = async () => {
watchFiles()
console.log(`Server Running at localhost:${port}`)
})
database = dbConnection
}
bootstrapApp()
void bootstrapApp()

View File

@@ -66,7 +66,7 @@ export class inventorySetup1665748086258 implements MigrationInterface {
CONSTRAINT "PK_inventory_item_id" PRIMARY KEY ("id")
);
CREATE UNIQUE INDEX "IDX_inventory_item_sku" ON "inventory_item" ("sku");
CREATE UNIQUE INDEX "IDX_inventory_item_sku" ON "inventory_item" ("sku") WHERE deleted_at IS NULL;
CREATE TABLE "reservation_item" (

View File

@@ -75,6 +75,10 @@ export default class InventoryService
})
}
private getManager(): EntityManager {
return this.transactionManager_ ?? this.manager_
}
/**
* Lists inventory items that match the given selector
* @param selector - the selector to filter inventory items by
@@ -85,7 +89,9 @@ export default class InventoryService
selector: FilterableInventoryItemProps,
config: FindConfig<InventoryItemDTO> = { relations: [], skip: 0, take: 10 }
): Promise<[InventoryItemDTO[], number]> {
return await this.inventoryItemService_.listAndCount(selector, config)
return await this.inventoryItemService_
.withTransaction(this.getManager())
.listAndCount(selector, config)
}
/**
@@ -98,7 +104,9 @@ export default class InventoryService
selector: FilterableInventoryLevelProps,
config: FindConfig<InventoryLevelDTO> = { relations: [], skip: 0, take: 10 }
): Promise<[InventoryLevelDTO[], number]> {
return await this.inventoryLevelService_.listAndCount(selector, config)
return await this.inventoryLevelService_
.withTransaction(this.getManager())
.listAndCount(selector, config)
}
/**
@@ -115,7 +123,9 @@ export default class InventoryService
take: 10,
}
): Promise<[ReservationItemDTO[], number]> {
return await this.reservationItemService_.listAndCount(selector, config)
return await this.reservationItemService_
.withTransaction(this.getManager())
.listAndCount(selector, config)
}
/**
@@ -128,10 +138,9 @@ export default class InventoryService
inventoryItemId: string,
config?: FindConfig<InventoryItemDTO>
): Promise<InventoryItemDTO> {
const inventoryItem = await this.inventoryItemService_.retrieve(
inventoryItemId,
config
)
const inventoryItem = await this.inventoryItemService_
.withTransaction(this.getManager())
.retrieve(inventoryItemId, config)
return { ...inventoryItem }
}
@@ -145,10 +154,12 @@ export default class InventoryService
inventoryItemId: string,
locationId: string
): Promise<InventoryLevelDTO> {
const [inventoryLevel] = await this.inventoryLevelService_.list(
{ inventory_item_id: inventoryItemId, location_id: locationId },
{ take: 1 }
)
const [inventoryLevel] = await this.inventoryLevelService_
.withTransaction(this.getManager())
.list(
{ inventory_item_id: inventoryItemId, location_id: locationId },
{ take: 1 }
)
if (!inventoryLevel) {
throw new MedusaError(
MedusaError.Types.NOT_FOUND,
@@ -167,13 +178,15 @@ export default class InventoryService
input: CreateReservationItemInput
): Promise<ReservationItemDTO> {
// Verify that the item is stocked at the location
const [inventoryLevel] = await this.inventoryLevelService_.list(
{
inventory_item_id: input.inventory_item_id,
location_id: input.location_id,
},
{ take: 1 }
)
const [inventoryLevel] = await this.inventoryLevelService_
.withTransaction(this.getManager())
.list(
{
inventory_item_id: input.inventory_item_id,
location_id: input.location_id,
},
{ take: 1 }
)
if (!inventoryLevel) {
throw new MedusaError(
@@ -182,7 +195,9 @@ export default class InventoryService
)
}
const reservationItem = await this.reservationItemService_.create(input)
const reservationItem = await this.reservationItemService_
.withTransaction(this.getManager())
.create(input)
return { ...reservationItem }
}
@@ -195,7 +210,9 @@ export default class InventoryService
async createInventoryItem(
input: CreateInventoryItemInput
): Promise<InventoryItemDTO> {
const inventoryItem = await this.inventoryItemService_.create(input)
const inventoryItem = await this.inventoryItemService_
.withTransaction(this.getManager())
.create(input)
return { ...inventoryItem }
}
@@ -207,7 +224,9 @@ export default class InventoryService
async createInventoryLevel(
input: CreateInventoryLevelInput
): Promise<InventoryLevelDTO> {
return await this.inventoryLevelService_.create(input)
return await this.inventoryLevelService_
.withTransaction(this.getManager())
.create(input)
}
/**
@@ -220,10 +239,9 @@ export default class InventoryService
inventoryItemId: string,
input: Partial<CreateInventoryItemInput>
): Promise<InventoryItemDTO> {
const inventoryItem = await this.inventoryItemService_.update(
inventoryItemId,
input
)
const inventoryItem = await this.inventoryItemService_
.withTransaction(this.getManager())
.update(inventoryItemId, input)
return { ...inventoryItem }
}
@@ -232,7 +250,9 @@ export default class InventoryService
* @param inventoryItemId - the id of the inventory item to delete
*/
async deleteInventoryItem(inventoryItemId: string): Promise<void> {
return await this.inventoryItemService_.delete(inventoryItemId)
return await this.inventoryItemService_
.withTransaction(this.getManager())
.delete(inventoryItemId)
}
/**
@@ -244,16 +264,20 @@ export default class InventoryService
inventoryItemId: string,
locationId: string
): Promise<void> {
const [inventoryLevel] = await this.inventoryLevelService_.list(
{ inventory_item_id: inventoryItemId, location_id: locationId },
{ take: 1 }
)
const [inventoryLevel] = await this.inventoryLevelService_
.withTransaction(this.getManager())
.list(
{ inventory_item_id: inventoryItemId, location_id: locationId },
{ take: 1 }
)
if (!inventoryLevel) {
return
}
return await this.inventoryLevelService_.delete(inventoryLevel.id)
return await this.inventoryLevelService_
.withTransaction(this.getManager())
.delete(inventoryLevel.id)
}
/**
@@ -268,10 +292,12 @@ export default class InventoryService
locationId: string,
input: UpdateInventoryLevelInput
): Promise<InventoryLevelDTO> {
const [inventoryLevel] = await this.inventoryLevelService_.list(
{ inventory_item_id: inventoryItemId, location_id: locationId },
{ take: 1 }
)
const [inventoryLevel] = await this.inventoryLevelService_
.withTransaction(this.getManager())
.list(
{ inventory_item_id: inventoryItemId, location_id: locationId },
{ take: 1 }
)
if (!inventoryLevel) {
throw new MedusaError(
@@ -280,7 +306,9 @@ export default class InventoryService
)
}
return await this.inventoryLevelService_.update(inventoryLevel.id, input)
return await this.inventoryLevelService_
.withTransaction(this.getManager())
.update(inventoryLevel.id, input)
}
/**
@@ -293,7 +321,9 @@ export default class InventoryService
reservationItemId: string,
input: UpdateReservationItemInput
): Promise<ReservationItemDTO> {
return await this.reservationItemService_.update(reservationItemId, input)
return await this.reservationItemService_
.withTransaction(this.getManager())
.update(reservationItemId, input)
}
/**
@@ -301,7 +331,9 @@ export default class InventoryService
* @param lineItemId - the id of the line item associated with the reservation item
*/
async deleteReservationItemsByLineItem(lineItemId: string): Promise<void> {
return await this.reservationItemService_.deleteByLineItem(lineItemId)
return await this.reservationItemService_
.withTransaction(this.getManager())
.deleteByLineItem(lineItemId)
}
/**
@@ -309,7 +341,9 @@ export default class InventoryService
* @param reservationItemId - the id of the reservation item to delete
*/
async deleteReservationItem(reservationItemId: string): Promise<void> {
return await this.reservationItemService_.delete(reservationItemId)
return await this.reservationItemService_
.withTransaction(this.getManager())
.delete(reservationItemId)
}
/**
@@ -325,10 +359,12 @@ export default class InventoryService
locationId: string,
adjustment: number
): Promise<InventoryLevelDTO> {
const [inventoryLevel] = await this.inventoryLevelService_.list(
{ inventory_item_id: inventoryItemId, location_id: locationId },
{ take: 1 }
)
const [inventoryLevel] = await this.inventoryLevelService_
.withTransaction(this.getManager())
.list(
{ inventory_item_id: inventoryItemId, location_id: locationId },
{ take: 1 }
)
if (!inventoryLevel) {
throw new MedusaError(
MedusaError.Types.NOT_FOUND,
@@ -336,12 +372,11 @@ export default class InventoryService
)
}
const updatedInventoryLevel = await this.inventoryLevelService_.update(
inventoryLevel.id,
{
const updatedInventoryLevel = await this.inventoryLevelService_
.withTransaction(this.getManager())
.update(inventoryLevel.id, {
stocked_quantity: inventoryLevel.stocked_quantity + adjustment,
}
)
})
return { ...updatedInventoryLevel }
}
@@ -358,15 +393,15 @@ export default class InventoryService
locationIds: string[]
): Promise<number> {
// Throws if item does not exist
await this.inventoryItemService_.retrieve(inventoryItemId, {
select: ["id"],
})
await this.inventoryItemService_
.withTransaction(this.getManager())
.retrieve(inventoryItemId, {
select: ["id"],
})
const availableQuantity =
await this.inventoryLevelService_.getAvailableQuantity(
inventoryItemId,
locationIds
)
const availableQuantity = await this.inventoryLevelService_
.withTransaction(this.getManager())
.getAvailableQuantity(inventoryItemId, locationIds)
return availableQuantity
}
@@ -383,15 +418,15 @@ export default class InventoryService
locationIds: string[]
): Promise<number> {
// Throws if item does not exist
await this.inventoryItemService_.retrieve(inventoryItemId, {
select: ["id"],
})
await this.inventoryItemService_
.withTransaction(this.getManager())
.retrieve(inventoryItemId, {
select: ["id"],
})
const stockedQuantity =
await this.inventoryLevelService_.getStockedQuantity(
inventoryItemId,
locationIds
)
const stockedQuantity = await this.inventoryLevelService_
.withTransaction(this.getManager())
.getStockedQuantity(inventoryItemId, locationIds)
return stockedQuantity
}
@@ -408,15 +443,15 @@ export default class InventoryService
locationIds: string[]
): Promise<number> {
// Throws if item does not exist
await this.inventoryItemService_.retrieve(inventoryItemId, {
select: ["id"],
})
await this.inventoryItemService_
.withTransaction(this.getManager())
.retrieve(inventoryItemId, {
select: ["id"],
})
const reservedQuantity =
await this.inventoryLevelService_.getReservedQuantity(
inventoryItemId,
locationIds
)
const reservedQuantity = await this.inventoryLevelService_
.withTransaction(this.getManager())
.getReservedQuantity(inventoryItemId, locationIds)
return reservedQuantity
}

View File

@@ -39,6 +39,7 @@ describe("POST /admin/products/:id/variants", () => {
IdMap.getId("productWithOptions"),
{
inventory_quantity: 0,
manage_inventory: true,
title: "Test Product Variant",
options: [],
prices: [

View File

@@ -7,17 +7,33 @@ import {
IsString,
ValidateNested,
} from "class-validator"
import { defaultAdminProductFields, defaultAdminProductRelations } from "."
import { ProductService, ProductVariantService } from "../../../../services"
import { Type } from "class-transformer"
import { EntityManager } from "typeorm"
import {
ProductService,
ProductVariantService,
ProductVariantInventoryService,
} from "../../../../services"
import { defaultAdminProductFields, defaultAdminProductRelations } from "."
import { IInventoryService } from "../../../../interfaces"
import {
CreateProductVariantInput,
ProductVariantPricesCreateReq,
} from "../../../../types/product-variant"
import { validator } from "../../../../utils/validator"
import {
TransactionHandlerType,
TransactionOrchestrator,
TransactionPayload,
TransactionState,
TransactionStepsDefinition,
} from "../../../../utils/transaction"
import { ulid } from "ulid"
import { MedusaError } from "medusa-core-utils"
import { EntityManager } from "typeorm"
/**
* @oas [post] /products/{id}/variants
* operationId: "PostProductsProductVariants"
@@ -103,6 +119,48 @@ import { validator } from "../../../../utils/validator"
* "500":
* $ref: "#/components/responses/500_error"
*/
enum actions {
createVariant = "createVariant",
createInventoryItem = "createInventoryItem",
attachInventoryItem = "attachInventoryItem",
}
const simpleFlow: TransactionStepsDefinition = {
next: {
action: actions.createVariant,
maxRetries: 0,
},
}
const flowWithInventory: TransactionStepsDefinition = {
next: {
action: actions.createVariant,
forwardResponse: true,
maxRetries: 0,
next: {
action: actions.createInventoryItem,
forwardResponse: true,
maxRetries: 0,
next: {
action: actions.attachInventoryItem,
noCompensation: true,
maxRetries: 0,
},
},
},
}
const createSimpleVariantStrategy = new TransactionOrchestrator(
"create-variant",
simpleFlow
)
const createVariantStrategyWithInventory = new TransactionOrchestrator(
"create-variant-with-inventory",
flowWithInventory
)
export default async (req, res) => {
const { id } = req.params
@@ -111,18 +169,140 @@ export default async (req, res) => {
req.body
)
const inventoryService: IInventoryService | undefined =
req.scope.resolve("inventoryService")
const productVariantInventoryService: ProductVariantInventoryService =
req.scope.resolve("productVariantInventoryService")
const productVariantService: ProductVariantService = req.scope.resolve(
"productVariantService"
)
const productService: ProductService = req.scope.resolve("productService")
const createdId: Record<string, string | null> = {
variant: null,
inventoryItem: null,
}
const manager: EntityManager = req.scope.resolve("manager")
await manager.transaction(async (transactionManager) => {
return await productVariantService
.withTransaction(transactionManager)
.create(id, validated as CreateProductVariantInput)
const inventoryServiceTx =
inventoryService?.withTransaction(transactionManager)
const productVariantInventoryServiceTx =
productVariantInventoryService.withTransaction(transactionManager)
const productVariantServiceTx =
productVariantService.withTransaction(transactionManager)
async function createVariant() {
const variant = await productVariantServiceTx.create(
id,
validated as CreateProductVariantInput
)
createdId.variant = variant.id
return { variant }
}
async function removeVariant() {
if (createdId.variant) {
await productVariantServiceTx.delete(createdId.variant)
}
}
async function createInventoryItem(variant) {
if (!validated.manage_inventory) {
return
}
const inventoryItem = await inventoryServiceTx!.createInventoryItem({
sku: validated.sku,
origin_country: validated.origin_country,
hs_code: validated.hs_code,
mid_code: validated.mid_code,
material: validated.material,
weight: validated.weight,
length: validated.length,
height: validated.height,
width: validated.width,
})
createdId.inventoryItem = inventoryItem.id
return { variant, inventoryItem }
}
async function removeInventoryItem() {
if (createdId.inventoryItem) {
await inventoryServiceTx!.deleteInventoryItem(createdId.inventoryItem)
}
}
async function attachInventoryItem(variant, inventoryItem) {
if (!validated.manage_inventory) {
return
}
await productVariantInventoryServiceTx.attachInventoryItem(
variant.id,
inventoryItem.id,
validated.inventory_quantity
)
}
async function transactionHandler(
actionId: string,
type: TransactionHandlerType,
payload: TransactionPayload
) {
const command = {
[actions.createVariant]: {
[TransactionHandlerType.INVOKE]: async () => {
return await createVariant()
},
[TransactionHandlerType.COMPENSATE]: async () => {
await removeVariant()
},
},
[actions.createInventoryItem]: {
[TransactionHandlerType.INVOKE]: async (data) => {
const { variant } = data._response ?? {}
return await createInventoryItem(variant)
},
[TransactionHandlerType.COMPENSATE]: async () => {
await removeInventoryItem()
},
},
[actions.attachInventoryItem]: {
[TransactionHandlerType.INVOKE]: async (data) => {
const { variant, inventoryItem } = data._response ?? {}
return await attachInventoryItem(variant, inventoryItem)
},
},
}
return command[actionId][type](payload.data)
}
const strategy = inventoryService
? createVariantStrategyWithInventory
: createSimpleVariantStrategy
const transaction = await strategy.beginTransaction(
ulid(),
transactionHandler,
validated
)
await strategy.resume(transaction)
if (transaction.getState() !== TransactionState.DONE) {
throw new MedusaError(
MedusaError.Types.INVALID_DATA,
transaction.errors.map((err) => err.error?.message).join("\n")
)
}
})
const productService: ProductService = req.scope.resolve("productService")
const product = await productService.retrieve(id, {
select: defaultAdminProductFields,
relations: defaultAdminProductRelations,
@@ -175,6 +355,7 @@ class ProductVariantOptionReq {
* manage_inventory:
* description: Whether Medusa should keep track of the inventory for this Product Variant.
* type: boolean
* default: true
* weight:
* description: The wieght of the Product Variant.
* type: number
@@ -274,7 +455,7 @@ export class AdminPostProductsProductVariantsReq {
@IsBoolean()
@IsOptional()
manage_inventory?: boolean
manage_inventory?: boolean = true
@IsNumber()
@IsOptional()

View File

@@ -1,3 +1,4 @@
import { EntityManager } from "typeorm"
import { FindConfig } from "../../types/common"
import {
@@ -15,6 +16,8 @@ import {
} from "../../types/inventory"
export interface IInventoryService {
withTransaction(transactionManager?: EntityManager): this
listInventoryItems(
selector: FilterableInventoryItemProps,
config?: FindConfig<InventoryItemDTO>

View File

@@ -1,3 +1,4 @@
import { EntityManager } from "typeorm"
import { FindConfig } from "../../types/common"
import {
@@ -8,6 +9,7 @@ import {
} from "../../types/stock-location"
export interface IStockLocationService {
withTransaction(transactionManager?: EntityManager): this
list(
selector: FilterableStockLocationProps,
config?: FindConfig<StockLocationDTO>

View File

@@ -81,7 +81,7 @@ describe("modules loader", () => {
container = buildContainer()
})
it("registers service as false in container when no resolution path is given", async () => {
it("registers service as undefined in container when no resolution path is given", async () => {
const moduleResolutions: Record<string, ModuleResolution> = {
testService: {
resolutionPath: false,
@@ -110,7 +110,7 @@ describe("modules loader", () => {
const testService = container.resolve(
moduleResolutions.testService.definition.key
)
expect(testService).toBe(false)
expect(testService).toBe(undefined)
})
it("registers service ", async () => {

View File

@@ -32,7 +32,7 @@ const registerModule = async (
}
container.register({
[constainerName]: asValue(false),
[constainerName]: asValue(undefined),
})
return {
@@ -42,7 +42,7 @@ const registerModule = async (
if (!resolution.resolutionPath) {
container.register({
[constainerName]: asValue(false),
[constainerName]: asValue(undefined),
})
return

View File

@@ -106,11 +106,13 @@ class ProductVariantInventoryService extends TransactionBaseService {
const hasInventory = await Promise.all(
variantInventory.map(async (inventoryPart) => {
const itemQuantity = inventoryPart.required_quantity * quantity
return await this.inventoryService_.confirmInventory(
inventoryPart.inventory_item_id,
locations,
itemQuantity
)
return await this.inventoryService_
.withTransaction(manager)
.confirmInventory(
inventoryPart.inventory_item_id,
locations,
itemQuantity
)
})
)
@@ -250,9 +252,11 @@ class ProductVariantInventoryService extends TransactionBaseService {
})
// Verify that item exists
await this.inventoryService_.retrieveInventoryItem(inventoryItemId, {
select: ["id"],
})
await this.inventoryService_
.withTransaction(manager)
.retrieveInventoryItem(inventoryItemId, {
select: ["id"],
})
const variantInventoryRepo = manager.getRepository(
ProductVariantInventoryItem
@@ -374,12 +378,14 @@ class ProductVariantInventoryService extends TransactionBaseService {
await Promise.all(
variantInventory.map(async (inventoryPart) => {
const itemQuantity = inventoryPart.required_quantity * quantity
return await this.inventoryService_.createReservationItem({
...toReserve,
location_id: locationId as string,
inventory_item_id: inventoryPart.inventory_item_id,
quantity: itemQuantity,
})
return await this.inventoryService_
.withTransaction(manager)
.createReservationItem({
...toReserve,
location_id: locationId as string,
inventory_item_id: inventoryPart.inventory_item_id,
quantity: itemQuantity,
})
})
)
}
@@ -414,8 +420,11 @@ class ProductVariantInventoryService extends TransactionBaseService {
})
})
}
const [reservations, reservationCount] =
await this.inventoryService_.listReservationItems(
const manager = this.transactionManager_ || this.manager_
const [reservations, reservationCount] = await this.inventoryService_
.withTransaction(manager)
.listReservationItems(
{
line_item_id: lineItemId,
},
@@ -442,11 +451,15 @@ class ProductVariantInventoryService extends TransactionBaseService {
quantity * productVariantInventory.required_quantity
if (reservationQtyUpdate === 0) {
await this.inventoryService_.deleteReservationItem(reservation.id)
await this.inventoryService_
.withTransaction(manager)
.deleteReservationItem(reservation.id)
} else {
await this.inventoryService_.updateReservationItem(reservation.id, {
quantity: reservationQtyUpdate,
})
await this.inventoryService_
.withTransaction(manager)
.updateReservationItem(reservation.id, {
quantity: reservationQtyUpdate,
})
}
}
}
@@ -523,7 +536,10 @@ class ProductVariantInventoryService extends TransactionBaseService {
})
}
await this.inventoryService_.deleteReservationItemsByLineItem(lineItemId)
const manager = this.transactionManager_ || this.manager_
await this.inventoryService_
.withTransaction(manager)
.deleteReservationItemsByLineItem(lineItemId)
}
/**
@@ -554,6 +570,7 @@ class ProductVariantInventoryService extends TransactionBaseService {
})
})
} else {
const manager = this.transactionManager_ || this.manager_
const variantInventory = await this.listByVariant(variantId)
if (variantInventory.length === 0) {
@@ -563,11 +580,13 @@ class ProductVariantInventoryService extends TransactionBaseService {
await Promise.all(
variantInventory.map(async (inventoryPart) => {
const itemQuantity = inventoryPart.required_quantity * quantity
return await this.inventoryService_.adjustInventory(
inventoryPart.inventory_item_id,
locationId,
itemQuantity
)
return await this.inventoryService_
.withTransaction(manager)
.adjustInventory(
inventoryPart.inventory_item_id,
locationId,
itemQuantity
)
})
)
}