Refactor FalukantService and SaleSection components: Optimize product and knowledge retrieval by using Promise.all for concurrent database queries, improving performance. Additionally, reorganize the speedLabel method for better readability and maintainability, ensuring accurate localization handling for transport speed values.

This commit is contained in:
Torsten Schulz (local)
2026-01-29 15:20:38 +01:00
parent 1839c3c57b
commit c5ab17ad99
2 changed files with 55 additions and 74 deletions

View File

@@ -4445,79 +4445,61 @@ class FalukantService extends BaseService {
throw new Error(`No FalukantCharacter found for user with id ${user.id}`);
}
// Produkt abrufen
const product = await ProductType.findOne({ where: { id: productId } });
const [product, knowledge, cities, townWorths] = await Promise.all([
ProductType.findOne({ where: { id: productId } }),
Knowledge.findOne({
where: { characterId: character.id, productId: productId }
}),
RegionData.findAll({
attributes: ['id', 'name'],
include: [
{
model: RegionType,
as: 'regionType',
where: { labelTr: 'city' },
attributes: ['labelTr']
},
{
model: Branch,
as: 'branches',
where: { falukantUserId: user.id },
include: [
{
model: BranchType,
as: 'branchType',
attributes: ['labelTr']
}
],
attributes: ['branchTypeId'],
required: false
}
]
}),
TownProductWorth.findAll({
where: { productId: productId },
attributes: ['regionId', 'worthPercent']
})
]);
if (!product) {
throw new Error(`Product not found with id ${productId}`);
}
// Knowledge für dieses Produkt abrufen
const knowledge = await Knowledge.findOne({
where: { characterId: character.id, productId: productId }
});
const knowledgeFactor = knowledge?.knowledge || 0;
// Alle Städte abrufen
const cities = await RegionData.findAll({
attributes: ['id', 'name'],
include: [
{
model: RegionType,
as: 'regionType',
where: { labelTr: 'city' },
attributes: ['labelTr']
},
{
model: Branch,
as: 'branches',
where: { falukantUserId: user.id },
include: [
{
model: BranchType,
as: 'branchType',
attributes: ['labelTr']
}
],
attributes: ['branchTypeId'],
required: false
}
]
});
// TownProductWorth für alle Städte und dieses Produkt einmalig abrufen
// (vermeidet N+1 Query Problem)
const townWorths = await TownProductWorth.findAll({
where: { productId: productId },
attributes: ['regionId', 'worthPercent']
});
const worthMap = new Map(townWorths.map(tw => [tw.regionId, tw.worthPercent]));
// Berechne den regionalen Preis für die aktuelle Region (falls angegeben)
// WICHTIG: Ignoriere den übergebenen currentPrice, da er möglicherweise nicht
// den regionalen Faktor berücksichtigt. Berechne stattdessen immer den korrekten
// regionalen Preis basierend auf currentRegionId.
let currentRegionalPrice = currentPrice; // Fallback auf übergebenen Preis
let currentRegionalPrice = currentPrice;
if (currentRegionId) {
const currentWorthPercent = worthMap.get(currentRegionId) || 50;
// Verwende calcRegionalSellPrice mit bereits geladenem worthPercent (keine DB-Query)
currentRegionalPrice = await calcRegionalSellPrice(product, knowledgeFactor, currentRegionId, currentWorthPercent);
currentRegionalPrice = calcRegionalSellPriceSync(product, knowledgeFactor, currentWorthPercent) ?? currentPrice;
}
// Für jede Stadt den Preis berechnen und Branch-Typ bestimmen
const results = [];
const PRICE_TOLERANCE = 0.01;
for (const city of cities) {
// Aktuelle Stadt ausschließen
if (currentRegionId && city.id === currentRegionId) {
continue;
}
if (currentRegionId && city.id === currentRegionId) continue;
const worthPercent = worthMap.get(city.id) || 50;
// Verwende calcRegionalSellPrice mit bereits geladenem worthPercent (keine DB-Query)
const priceInCity = await calcRegionalSellPrice(product, knowledgeFactor, city.id, worthPercent);
// Nur Städte zurückgeben, wo der Preis höher ist
// Kleine Toleranz (0.01) für Rundungsfehler bei Gleitkommaberechnungen
const PRICE_TOLERANCE = 0.01;
const priceInCity = calcRegionalSellPriceSync(product, knowledgeFactor, worthPercent);
if (priceInCity == null) continue;
if (priceInCity > currentRegionalPrice - PRICE_TOLERANCE) {
// Branch-Typ bestimmen
let branchType = null; // null = kein Branch