diff --git a/backend/services/falukantService.js b/backend/services/falukantService.js index 6316c9a..326265c 100644 --- a/backend/services/falukantService.js +++ b/backend/services/falukantService.js @@ -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 diff --git a/frontend/src/components/falukant/SaleSection.vue b/frontend/src/components/falukant/SaleSection.vue index 8555379..9376ea8 100644 --- a/frontend/src/components/falukant/SaleSection.vue +++ b/frontend/src/components/falukant/SaleSection.vue @@ -252,20 +252,6 @@ }); }, }, - methods: { - speedLabel(value) { - if (value == null) return this.$t('falukant.branch.transport.speed.unknown') || '—'; - if (typeof value === 'object') { - const k = value.tr ?? value.id ?? 'unknown'; - const tKey = `falukant.branch.transport.speed.${k}`; - const t = this.$t(tKey); - return (t && t !== tKey) ? t : String(k); - } - const key = String(value); - const tKey = `falukant.branch.transport.speed.${key}`; - const translated = this.$t(tKey); - return (!translated || translated === tKey) ? key : translated; - }, async mounted() { await this.loadInventory(); await this.loadTransports(); @@ -281,6 +267,19 @@ } }, methods: { + speedLabel(value) { + if (value == null) return this.$t('falukant.branch.transport.speed.unknown') || '—'; + if (typeof value === 'object') { + const k = value.tr ?? value.id ?? 'unknown'; + const tKey = `falukant.branch.transport.speed.${k}`; + const t = this.$t(tKey); + return (t && t !== tKey) ? t : String(k); + } + const key = String(value); + const tKey = `falukant.branch.transport.speed.${key}`; + const translated = this.$t(tKey); + return (!translated || translated === tKey) ? key : translated; + }, async loadInventory() { try { const response = await apiClient.get(`/api/falukant/inventory/${this.branchId}`);