Add product weather effects and regional pricing enhancements
- Introduced a new endpoint in FalukantController to retrieve product prices based on region and product ID. - Implemented logic in FalukantService to calculate product prices considering user knowledge and regional factors. - Added weather-related data models and associations to enhance product pricing accuracy based on weather conditions. - Updated frontend components to cache and display regional product prices effectively, improving user experience.
This commit is contained in:
@@ -61,7 +61,10 @@ import VehicleType from '../models/falukant/type/vehicle.js';
|
||||
import Vehicle from '../models/falukant/data/vehicle.js';
|
||||
import Transport from '../models/falukant/data/transport.js';
|
||||
import RegionDistance from '../models/falukant/data/region_distance.js';
|
||||
import Weather from '../models/falukant/data/weather.js';
|
||||
import TownProductWorth from '../models/falukant/data/town_product_worth.js';
|
||||
import ProductWeatherEffect from '../models/falukant/type/product_weather_effect.js';
|
||||
import WeatherType from '../models/falukant/type/weather.js';
|
||||
|
||||
function calcAge(birthdate) {
|
||||
const b = new Date(birthdate); b.setHours(0, 0);
|
||||
@@ -1036,7 +1039,19 @@ class FalukantService extends BaseService {
|
||||
if (u.money < cost) throw new Error('notenoughmoney');
|
||||
const r = await updateFalukantUserMoney(u.id, -cost, 'Production cost', u.id);
|
||||
if (!r.success) throw new Error('Failed to update money');
|
||||
const d = await Production.create({ branchId: b.id, productId, quantity });
|
||||
|
||||
// Hole aktuelles Wetter der Region
|
||||
const currentWeather = await Weather.findOne({
|
||||
where: { regionId: b.regionId }
|
||||
});
|
||||
const weatherTypeId = currentWeather?.weatherTypeId || null;
|
||||
|
||||
const d = await Production.create({
|
||||
branchId: b.id,
|
||||
productId,
|
||||
quantity,
|
||||
weatherTypeId
|
||||
});
|
||||
notifyUser(u.user.hashedId, 'falukantUpdateStatus', {});
|
||||
notifyUser(u.user.hashedId, 'falukantBranchUpdate', { branchId: b.id });
|
||||
return d;
|
||||
@@ -1045,7 +1060,41 @@ class FalukantService extends BaseService {
|
||||
async getProduction(hashedUserId, branchId) {
|
||||
const u = await getFalukantUserOrFail(hashedUserId);
|
||||
const b = await getBranchOrFail(u.id, branchId);
|
||||
return Production.findOne({ where: { regionId: b.regionId } });
|
||||
const production = await Production.findOne({
|
||||
where: { branchId: b.id },
|
||||
include: [
|
||||
{ model: ProductType, as: 'productType' },
|
||||
{ model: WeatherType, as: 'weatherType' }
|
||||
]
|
||||
});
|
||||
|
||||
if (!production) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Berechne Qualität basierend auf Wettereffekt
|
||||
let quality = 50; // Basisqualität (50%)
|
||||
|
||||
if (production.weatherTypeId) {
|
||||
const weatherEffect = await ProductWeatherEffect.findOne({
|
||||
where: {
|
||||
productId: production.productId,
|
||||
weatherTypeId: production.weatherTypeId
|
||||
}
|
||||
});
|
||||
|
||||
if (weatherEffect) {
|
||||
// Wettereffekt: -2 bis +2, wird auf Qualität angewendet
|
||||
// Basisqualität 50%, Effekt wird als Prozentpunkte addiert
|
||||
quality = Math.max(0, Math.min(100, 50 + (weatherEffect.qualityEffect * 10)));
|
||||
}
|
||||
}
|
||||
|
||||
// Konvertiere zu JSON und füge berechnete Qualität hinzu
|
||||
const result = production.toJSON();
|
||||
result.quality = Math.round(quality);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
async getProducts(hashedUserId) {
|
||||
@@ -1507,20 +1556,43 @@ class FalukantService extends BaseService {
|
||||
],
|
||||
where: { falukantUserId: user.id }
|
||||
},
|
||||
{ model: ProductType, as: 'productType', attributes: ['labelTr', 'productionTime'] }
|
||||
{ model: ProductType, as: 'productType', attributes: ['labelTr', 'productionTime', 'id'] },
|
||||
{ model: WeatherType, as: 'weatherType' }
|
||||
],
|
||||
attributes: ['startTimestamp', 'quantity'],
|
||||
attributes: ['startTimestamp', 'quantity', 'productId', 'weatherTypeId'],
|
||||
});
|
||||
const formattedProductions = productions.map((production) => {
|
||||
|
||||
// Berechne Qualität für jede Produktion
|
||||
const formattedProductions = await Promise.all(productions.map(async (production) => {
|
||||
const startTimestamp = new Date(production.startTimestamp).getTime();
|
||||
const endTimestamp = startTimestamp + production.productType.productionTime * 60 * 1000;
|
||||
|
||||
// Berechne Qualität basierend auf Wettereffekt
|
||||
let quality = 50; // Basisqualität (50%)
|
||||
|
||||
if (production.weatherTypeId) {
|
||||
const weatherEffect = await ProductWeatherEffect.findOne({
|
||||
where: {
|
||||
productId: production.productId,
|
||||
weatherTypeId: production.weatherTypeId
|
||||
}
|
||||
});
|
||||
|
||||
if (weatherEffect) {
|
||||
// Wettereffekt: -2 bis +2, wird auf Qualität angewendet
|
||||
quality = Math.max(0, Math.min(100, 50 + (weatherEffect.qualityEffect * 10)));
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
cityName: production.branch.region.name,
|
||||
productName: production.productType.labelTr,
|
||||
quantity: production.quantity,
|
||||
quality: Math.round(quality),
|
||||
endTimestamp: new Date(endTimestamp).toISOString(),
|
||||
};
|
||||
});
|
||||
}));
|
||||
|
||||
formattedProductions.sort((a, b) => new Date(a.endTimestamp) - new Date(b.endTimestamp));
|
||||
return formattedProductions;
|
||||
}
|
||||
@@ -3538,6 +3610,31 @@ class FalukantService extends BaseService {
|
||||
return regions;
|
||||
}
|
||||
|
||||
async getProductPriceInRegion(hashedUserId, productId, regionId) {
|
||||
const user = await this.getFalukantUserByHashedId(hashedUserId);
|
||||
const character = await FalukantCharacter.findOne({ where: { userId: user.id } });
|
||||
if (!character) {
|
||||
throw new Error(`No FalukantCharacter found for user with id ${user.id}`);
|
||||
}
|
||||
|
||||
// Produkt abrufen
|
||||
const product = await ProductType.findOne({ where: { id: productId } });
|
||||
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;
|
||||
|
||||
// Verwende die bereits existierende calcRegionalSellPrice Funktion
|
||||
const price = await calcRegionalSellPrice(product, knowledgeFactor, regionId);
|
||||
|
||||
return { price };
|
||||
}
|
||||
|
||||
async getProductPricesInCities(hashedUserId, productId, currentPrice) {
|
||||
const user = await this.getFalukantUserByHashedId(hashedUserId);
|
||||
const character = await FalukantCharacter.findOne({ where: { userId: user.id } });
|
||||
|
||||
Reference in New Issue
Block a user