Optimize getInventory method in FalukantService by replacing nested includes with a single SQL query for improved performance. Add error handling for invalid branchId input.
This commit is contained in:
@@ -1547,46 +1547,62 @@ class FalukantService extends BaseService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async getInventory(hashedUserId, branchId) {
|
async getInventory(hashedUserId, branchId) {
|
||||||
|
// PERFORMANCE: Diese Route war langsam wegen doppelter/verschachtelter Includes (Branch->Stocks->Region + Inventory->Stock->Branch->Region).
|
||||||
|
// Wir holen stattdessen genau die benötigten Felder in EINER aggregierenden SQL-Query.
|
||||||
const u = await getFalukantUserOrFail(hashedUserId);
|
const u = await getFalukantUserOrFail(hashedUserId);
|
||||||
const f = branchId ? { id: branchId, falukantUserId: u.id } : { falukantUserId: u.id };
|
const branchIdInt = branchId == null ? null : parseInt(branchId, 10);
|
||||||
const br = await Branch.findAll({
|
if (branchId != null && Number.isNaN(branchIdInt)) {
|
||||||
where: f,
|
throw new Error('Invalid branchId');
|
||||||
include: [
|
}
|
||||||
{ model: FalukantStock, as: 'stocks', include: [{ model: FalukantStockType, as: 'stockType' }] },
|
|
||||||
{ model: RegionData, as: 'region', include: [{ model: RegionType, as: 'regionType' }] }
|
const rows = await sequelize.query(
|
||||||
]
|
`
|
||||||
});
|
SELECT
|
||||||
const stockIds = br.flatMap(b => b.stocks.map(s => s.id));
|
r.id AS region_id,
|
||||||
const inv = await Inventory.findAll({
|
r.name AS region_name,
|
||||||
where: { stockId: stockIds },
|
rt.id AS region_type_id,
|
||||||
include: [
|
rt.label_tr AS region_type_label_tr,
|
||||||
|
p.id AS product_id,
|
||||||
|
p.label_tr AS product_label_tr,
|
||||||
|
p.sell_cost AS product_sell_cost,
|
||||||
|
i.quality AS quality,
|
||||||
|
SUM(i.quantity)::int AS total_quantity
|
||||||
|
FROM falukant_data.inventory i
|
||||||
|
JOIN falukant_data.stock s ON s.id = i.stock_id
|
||||||
|
JOIN falukant_data.branch b ON b.id = s.branch_id
|
||||||
|
JOIN falukant_data.region r ON r.id = b.region_id
|
||||||
|
LEFT JOIN falukant_type.region rt ON rt.id = r.region_type_id
|
||||||
|
JOIN falukant_type.product p ON p.id = i.product_id
|
||||||
|
WHERE b.falukant_user_id = :falukantUserId
|
||||||
|
AND (:branchId::int IS NULL OR b.id = :branchId::int)
|
||||||
|
GROUP BY
|
||||||
|
r.id, r.name, rt.id, rt.label_tr,
|
||||||
|
p.id, p.label_tr, p.sell_cost,
|
||||||
|
i.quality
|
||||||
|
ORDER BY r.id, p.id, i.quality
|
||||||
|
`,
|
||||||
{
|
{
|
||||||
model: FalukantStock,
|
replacements: { falukantUserId: u.id, branchId: branchIdInt },
|
||||||
as: 'stock',
|
type: sequelize.QueryTypes.SELECT
|
||||||
include: [
|
}
|
||||||
{
|
);
|
||||||
model: Branch,
|
|
||||||
as: 'branch',
|
return (rows || []).map(r => ({
|
||||||
include: [{ model: RegionData, as: 'region', include: [{ model: RegionType, as: 'regionType' }] }]
|
region: {
|
||||||
|
id: r.region_id,
|
||||||
|
name: r.region_name,
|
||||||
|
regionType: r.region_type_id
|
||||||
|
? { id: r.region_type_id, labelTr: r.region_type_label_tr }
|
||||||
|
: null
|
||||||
},
|
},
|
||||||
{ model: FalukantStockType, as: 'stockType' }
|
product: {
|
||||||
]
|
id: r.product_id,
|
||||||
|
labelTr: r.product_label_tr,
|
||||||
|
sellCost: r.product_sell_cost
|
||||||
},
|
},
|
||||||
{ model: ProductType, as: 'productType' }
|
quality: r.quality,
|
||||||
]
|
totalQuantity: r.total_quantity
|
||||||
});
|
}));
|
||||||
const grouped = inv.reduce((acc, i) => {
|
|
||||||
const r = i.stock.branch.region;
|
|
||||||
const k = `${r.id}-${i.productType.id}-${i.quality}`;
|
|
||||||
acc[k] = acc[k] || { region: r, product: i.productType, quality: i.quality, totalQuantity: 0 };
|
|
||||||
acc[k].totalQuantity += i.quantity;
|
|
||||||
return acc;
|
|
||||||
}, {});
|
|
||||||
return Object.values(grouped).sort((a, b) => {
|
|
||||||
if (a.region.id !== b.region.id) return a.region.id - b.region.id;
|
|
||||||
if (a.product.id !== b.product.id) return a.product.id - b.product.id;
|
|
||||||
return a.quality - b.quality;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async sellProduct(hashedUserId, branchId, productId, quality, quantity) {
|
async sellProduct(hashedUserId, branchId, productId, quality, quantity) {
|
||||||
|
|||||||
Reference in New Issue
Block a user