feat(medusa, inventory, stock-location): Remove unnecessary transaction usage in the modules and the list product end points (#4232)
This commit is contained in:
@@ -233,45 +233,37 @@ export default async (req, res) => {
|
||||
|
||||
const manager = req.scope.resolve("manager")
|
||||
|
||||
const [products, count] = await manager.transaction(
|
||||
async (transactionManager) => {
|
||||
const [rawProducts, count] = await productService
|
||||
.withTransaction(transactionManager)
|
||||
.listAndCount(req.filterableFields, req.listConfig)
|
||||
|
||||
let products: (Product | PricedProduct)[] = rawProducts
|
||||
|
||||
// We only set prices if variants.prices are requested
|
||||
const shouldSetPricing = ["variants", "variants.prices"].every(
|
||||
(relation) => relations?.includes(relation)
|
||||
)
|
||||
|
||||
if (shouldSetPricing) {
|
||||
products = await pricingService
|
||||
.withTransaction(transactionManager)
|
||||
.setProductPrices(rawProducts)
|
||||
}
|
||||
|
||||
// We only set availability if variants are requested
|
||||
const shouldSetAvailability = relations?.includes("variants")
|
||||
|
||||
if (inventoryService && shouldSetAvailability) {
|
||||
const [salesChannelsIds] = await salesChannelService
|
||||
.withTransaction(transactionManager)
|
||||
.listAndCount({}, { select: ["id"] })
|
||||
|
||||
products = await productVariantInventoryService
|
||||
.withTransaction(transactionManager)
|
||||
.setProductAvailability(
|
||||
products,
|
||||
salesChannelsIds.map((salesChannel) => salesChannel.id)
|
||||
)
|
||||
}
|
||||
|
||||
return [products, count]
|
||||
}
|
||||
const [rawProducts, count] = await productService.listAndCount(
|
||||
req.filterableFields,
|
||||
req.listConfig
|
||||
)
|
||||
|
||||
let products: (Product | PricedProduct)[] = rawProducts
|
||||
|
||||
// We only set prices if variants.prices are requested
|
||||
const shouldSetPricing = ["variants", "variants.prices"].every((relation) =>
|
||||
relations?.includes(relation)
|
||||
)
|
||||
|
||||
if (shouldSetPricing) {
|
||||
products = await pricingService.setProductPrices(rawProducts)
|
||||
}
|
||||
|
||||
// We only set availability if variants are requested
|
||||
const shouldSetAvailability = relations?.includes("variants")
|
||||
|
||||
if (inventoryService && shouldSetAvailability) {
|
||||
const [salesChannelsIds] = await salesChannelService.listAndCount(
|
||||
{},
|
||||
{ select: ["id"] }
|
||||
)
|
||||
|
||||
products = await productVariantInventoryService.setProductAvailability(
|
||||
products,
|
||||
salesChannelsIds.map((salesChannel) => salesChannel.id)
|
||||
)
|
||||
}
|
||||
|
||||
res.json({
|
||||
products,
|
||||
count,
|
||||
|
||||
@@ -216,82 +216,64 @@ export default async (req, res) => {
|
||||
}
|
||||
}
|
||||
|
||||
const manager = req.scope.resolve("manager")
|
||||
const promises: Promise<any>[] = []
|
||||
|
||||
const [computedProducts, count] = await manager.transaction(
|
||||
async (transactionManager) => {
|
||||
const promises: Promise<any>[] = []
|
||||
promises.push(productService.listAndCount(filterableFields, listConfig))
|
||||
|
||||
promises.push(
|
||||
productService
|
||||
.withTransaction(transactionManager)
|
||||
.listAndCount(filterableFields, listConfig)
|
||||
)
|
||||
if (validated.cart_id) {
|
||||
promises.push(
|
||||
cartService.retrieve(validated.cart_id, {
|
||||
select: ["id", "region_id"] as any,
|
||||
relations: ["region"],
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
if (validated.cart_id) {
|
||||
promises.push(
|
||||
cartService
|
||||
.withTransaction(transactionManager)
|
||||
.retrieve(validated.cart_id, {
|
||||
select: ["id", "region_id"] as any,
|
||||
relations: ["region"],
|
||||
})
|
||||
)
|
||||
}
|
||||
const [[rawProducts, count], cart] = await Promise.all(promises)
|
||||
|
||||
const [[rawProducts, count], cart] = await Promise.all(promises)
|
||||
if (validated.cart_id) {
|
||||
regionId = cart.region_id
|
||||
currencyCode = cart.region.currency_code
|
||||
}
|
||||
|
||||
if (validated.cart_id) {
|
||||
regionId = cart.region_id
|
||||
currencyCode = cart.region.currency_code
|
||||
}
|
||||
// Create a new reference just for naming purpose
|
||||
const computedProducts = rawProducts
|
||||
|
||||
// Create a new reference just for naming purpose
|
||||
const computedProducts = rawProducts
|
||||
|
||||
// We only set prices if variants.prices are requested
|
||||
const shouldSetPricing = ["variants", "variants.prices"].every(
|
||||
(relation) => listConfig.relations?.includes(relation)
|
||||
)
|
||||
|
||||
// We only set availability if variants are requested
|
||||
const shouldSetAvailability = listConfig.relations?.includes("variants")
|
||||
|
||||
const decoratePromises: Promise<any>[] = []
|
||||
|
||||
if (shouldSetPricing) {
|
||||
decoratePromises.push(
|
||||
pricingService
|
||||
.withTransaction(transactionManager)
|
||||
.setProductPrices(computedProducts, {
|
||||
cart_id: cart_id,
|
||||
region_id: regionId,
|
||||
currency_code: currencyCode,
|
||||
customer_id: req.user?.customer_id,
|
||||
include_discount_prices: true,
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
if (shouldSetAvailability) {
|
||||
decoratePromises.push(
|
||||
productVariantInventoryService
|
||||
.withTransaction(transactionManager)
|
||||
.setProductAvailability(
|
||||
computedProducts,
|
||||
filterableFields.sales_channel_id
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
// We can run them concurrently as the new properties are assigned to the references
|
||||
// of the appropriate entity
|
||||
await Promise.all(decoratePromises)
|
||||
|
||||
return [computedProducts, count]
|
||||
}
|
||||
// We only set prices if variants.prices are requested
|
||||
const shouldSetPricing = ["variants", "variants.prices"].every((relation) =>
|
||||
listConfig.relations?.includes(relation)
|
||||
)
|
||||
|
||||
// We only set availability if variants are requested
|
||||
const shouldSetAvailability = listConfig.relations?.includes("variants")
|
||||
|
||||
const decoratePromises: Promise<any>[] = []
|
||||
|
||||
if (shouldSetPricing) {
|
||||
decoratePromises.push(
|
||||
pricingService.setProductPrices(computedProducts, {
|
||||
cart_id: cart_id,
|
||||
region_id: regionId,
|
||||
currency_code: currencyCode,
|
||||
customer_id: req.user?.customer_id,
|
||||
include_discount_prices: true,
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
if (shouldSetAvailability) {
|
||||
decoratePromises.push(
|
||||
productVariantInventoryService.setProductAvailability(
|
||||
computedProducts,
|
||||
filterableFields.sales_channel_id
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
// We can run them concurrently as the new properties are assigned to the references
|
||||
// of the appropriate entity
|
||||
await Promise.all(decoratePromises)
|
||||
|
||||
res.json({
|
||||
products: cleanResponseData(computedProducts, req.allowedProperties || []),
|
||||
count,
|
||||
|
||||
@@ -375,6 +375,10 @@ class ProductVariantInventoryService extends TransactionBaseService {
|
||||
}
|
||||
|
||||
let locationId = context.locationId
|
||||
const moduleContext = {
|
||||
transactionManager: this.activeManager_,
|
||||
}
|
||||
|
||||
if (!isDefined(locationId) && context.salesChannelId) {
|
||||
const locationIds = await this.salesChannelLocationService_
|
||||
.withTransaction(this.activeManager_)
|
||||
@@ -388,10 +392,14 @@ class ProductVariantInventoryService extends TransactionBaseService {
|
||||
}
|
||||
|
||||
const [locations, count] =
|
||||
await this.inventoryService_.listInventoryLevels({
|
||||
location_id: locationIds,
|
||||
inventory_item_id: variantInventory[0].inventory_item_id,
|
||||
})
|
||||
await this.inventoryService_.listInventoryLevels(
|
||||
{
|
||||
location_id: locationIds,
|
||||
inventory_item_id: variantInventory[0].inventory_item_id,
|
||||
},
|
||||
undefined,
|
||||
moduleContext
|
||||
)
|
||||
|
||||
if (count === 0) {
|
||||
throw new MedusaError(
|
||||
@@ -406,12 +414,15 @@ class ProductVariantInventoryService extends TransactionBaseService {
|
||||
const reservationItems = 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_.createReservationItem(
|
||||
{
|
||||
...toReserve,
|
||||
location_id: locationId as string,
|
||||
inventory_item_id: inventoryPart.inventory_item_id,
|
||||
quantity: itemQuantity,
|
||||
},
|
||||
moduleContext
|
||||
)
|
||||
})
|
||||
)
|
||||
|
||||
@@ -456,6 +467,9 @@ class ProductVariantInventoryService extends TransactionBaseService {
|
||||
)
|
||||
}
|
||||
|
||||
const context = {
|
||||
transactionManager: this.activeManager_,
|
||||
}
|
||||
const [reservations, reservationCount] =
|
||||
await this.inventoryService_.listReservationItems(
|
||||
{
|
||||
@@ -463,7 +477,8 @@ class ProductVariantInventoryService extends TransactionBaseService {
|
||||
},
|
||||
{
|
||||
order: { created_at: "DESC" },
|
||||
}
|
||||
},
|
||||
context
|
||||
)
|
||||
|
||||
reservations.sort((a, _) => {
|
||||
@@ -485,7 +500,10 @@ class ProductVariantInventoryService extends TransactionBaseService {
|
||||
(r) => r.quantity === deltaUpdate && r.location_id === locationId
|
||||
)
|
||||
if (exactReservation) {
|
||||
await this.inventoryService_.deleteReservationItem(exactReservation.id)
|
||||
await this.inventoryService_.deleteReservationItem(
|
||||
exactReservation.id,
|
||||
context
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -505,7 +523,8 @@ class ProductVariantInventoryService extends TransactionBaseService {
|
||||
|
||||
if (reservationsToDelete.length) {
|
||||
await this.inventoryService_.deleteReservationItem(
|
||||
reservationsToDelete.map((r) => r.id)
|
||||
reservationsToDelete.map((r) => r.id),
|
||||
context
|
||||
)
|
||||
}
|
||||
|
||||
@@ -514,7 +533,8 @@ class ProductVariantInventoryService extends TransactionBaseService {
|
||||
reservationToUpdate.id,
|
||||
{
|
||||
quantity: reservationToUpdate.quantity - remainingQuantity,
|
||||
}
|
||||
},
|
||||
context
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -543,11 +563,19 @@ class ProductVariantInventoryService extends TransactionBaseService {
|
||||
continue
|
||||
}
|
||||
|
||||
const context = {
|
||||
transactionManager: this.activeManager_,
|
||||
}
|
||||
|
||||
const [inventoryLevels, inventoryLevelCount] =
|
||||
await this.inventoryService_.listInventoryLevels({
|
||||
inventory_item_id: pvInventoryItems.map((i) => i.inventory_item_id),
|
||||
location_id: locationId,
|
||||
})
|
||||
await this.inventoryService_.listInventoryLevels(
|
||||
{
|
||||
inventory_item_id: pvInventoryItems.map((i) => i.inventory_item_id),
|
||||
location_id: locationId,
|
||||
},
|
||||
undefined,
|
||||
context
|
||||
)
|
||||
|
||||
if (!inventoryLevelCount) {
|
||||
throw new MedusaError(
|
||||
@@ -653,7 +681,10 @@ class ProductVariantInventoryService extends TransactionBaseService {
|
||||
return await this.inventoryService_.adjustInventory(
|
||||
inventoryPart.inventory_item_id,
|
||||
locationId,
|
||||
itemQuantity
|
||||
itemQuantity,
|
||||
{
|
||||
transactionManager: this.activeManager_,
|
||||
}
|
||||
)
|
||||
})
|
||||
)
|
||||
|
||||
@@ -5,7 +5,6 @@ import { TransactionBaseService } from "../interfaces"
|
||||
import { SalesChannelLocation } from "../models/sales-channel-location"
|
||||
import SalesChannelService from "./sales-channel"
|
||||
|
||||
|
||||
type InjectedDependencies = {
|
||||
stockLocationService: IStockLocationService
|
||||
salesChannelService: SalesChannelService
|
||||
@@ -80,18 +79,20 @@ class SalesChannelLocationService extends TransactionBaseService {
|
||||
|
||||
if (this.stockLocationService_) {
|
||||
// trhows error if not found
|
||||
await this.stockLocationService_.retrieve(locationId)
|
||||
await this.stockLocationService_.retrieve(locationId, undefined, {
|
||||
transactionManager: this.activeManager_,
|
||||
})
|
||||
}
|
||||
|
||||
const salesChannelLocation = this.activeManager_.create(
|
||||
SalesChannelLocation,
|
||||
{
|
||||
sales_channel_id: salesChannel.id,
|
||||
location_id: locationId,
|
||||
}
|
||||
)
|
||||
const salesChannelLocationRepo =
|
||||
this.activeManager_.getRepository(SalesChannelLocation)
|
||||
|
||||
await this.activeManager_.save(salesChannelLocation)
|
||||
const salesChannelLocation = salesChannelLocationRepo.create({
|
||||
sales_channel_id: salesChannel.id,
|
||||
location_id: locationId,
|
||||
})
|
||||
|
||||
await salesChannelLocationRepo.save(salesChannelLocation)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -129,10 +130,18 @@ class SalesChannelLocationService extends TransactionBaseService {
|
||||
* @returns {Promise<string[]>} A promise that resolves with an array of sales channel IDs.
|
||||
*/
|
||||
async listSalesChannelIds(locationId: string): Promise<string[]> {
|
||||
const manager = this.transactionManager_ || this.manager_
|
||||
const location = await this.stockLocationService_.retrieve(locationId)
|
||||
const location = await this.stockLocationService_.retrieve(
|
||||
locationId,
|
||||
undefined,
|
||||
{
|
||||
transactionManager: this.activeManager_,
|
||||
}
|
||||
)
|
||||
|
||||
const salesChannelLocations = await manager.find(SalesChannelLocation, {
|
||||
const salesChannelRepo =
|
||||
this.activeManager_.getRepository(SalesChannelLocation)
|
||||
|
||||
const salesChannelLocations = await salesChannelRepo.find({
|
||||
where: { location_id: location.id },
|
||||
select: ["sales_channel_id"],
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user