Add product price retrieval feature in cities
- Implemented a new endpoint in FalukantController to fetch product prices in various cities based on product ID and current price. - Developed the corresponding service method in FalukantService to calculate and return prices, considering user knowledge and city branches. - Updated frontend components (RevenueSection and SaleSection) to display better prices for products, including loading logic and UI enhancements for price visibility. - Added styling for price indicators based on branch types to improve user experience.
This commit is contained in:
@@ -144,6 +144,14 @@ class FalukantController {
|
||||
this.applyForElections = this._wrapWithUser((userId, req) => this.service.applyForElections(userId, req.body.electionIds));
|
||||
|
||||
this.getRegions = this._wrapWithUser((userId) => this.service.getRegions(userId));
|
||||
this.getProductPricesInCities = this._wrapWithUser((userId, req) => {
|
||||
const productId = parseInt(req.query.productId, 10);
|
||||
const currentPrice = parseFloat(req.query.currentPrice);
|
||||
if (Number.isNaN(productId) || Number.isNaN(currentPrice)) {
|
||||
throw new Error('productId and currentPrice are required');
|
||||
}
|
||||
return this.service.getProductPricesInCities(userId, productId, currentPrice);
|
||||
});
|
||||
this.renovate = this._wrapWithUser((userId, req) => this.service.renovate(userId, req.body.element));
|
||||
this.renovateAll = this._wrapWithUser((userId) => this.service.renovateAll(userId));
|
||||
|
||||
|
||||
@@ -70,6 +70,7 @@ router.post('/politics/elections', falukantController.vote);
|
||||
router.get('/politics/open', falukantController.getOpenPolitics);
|
||||
router.post('/politics/open', falukantController.applyForElections);
|
||||
router.get('/cities', falukantController.getRegions);
|
||||
router.get('/products/prices-in-cities', falukantController.getProductPricesInCities);
|
||||
router.get('/vehicles/types', falukantController.getVehicleTypes);
|
||||
router.post('/vehicles', falukantController.buyVehicles);
|
||||
router.get('/vehicles', falukantController.getVehicles);
|
||||
|
||||
@@ -3518,6 +3518,86 @@ class FalukantService extends BaseService {
|
||||
return regions;
|
||||
}
|
||||
|
||||
async getProductPricesInCities(hashedUserId, productId, currentPrice) {
|
||||
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;
|
||||
|
||||
// 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
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
// Für jede Stadt den Preis berechnen und Branch-Typ bestimmen
|
||||
const results = [];
|
||||
for (const city of cities) {
|
||||
const priceInCity = calcSellPrice(product, knowledgeFactor);
|
||||
|
||||
// Nur Städte zurückgeben, wo der Preis höher ist
|
||||
if (priceInCity > currentPrice) {
|
||||
// Branch-Typ bestimmen
|
||||
let branchType = null; // null = kein Branch
|
||||
if (city.branches && city.branches.length > 0) {
|
||||
// Finde den "besten" Branch-Typ (store/fullstack > production)
|
||||
const branchTypes = city.branches.map(b => b.branchType?.labelTr).filter(Boolean);
|
||||
if (branchTypes.includes('store') || branchTypes.includes('fullstack')) {
|
||||
branchType = 'store'; // Grün
|
||||
} else if (branchTypes.includes('production')) {
|
||||
branchType = 'production'; // Orange
|
||||
}
|
||||
}
|
||||
|
||||
results.push({
|
||||
regionId: city.id,
|
||||
regionName: city.name,
|
||||
price: priceInCity,
|
||||
branchType: branchType // 'store' (grün), 'production' (orange), null (rot)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Sortiere nach Preis (höchster zuerst)
|
||||
results.sort((a, b) => b.price - a.price);
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
async renovate(hashedUserId, element) {
|
||||
const user = await getFalukantUserOrFail(hashedUserId);
|
||||
const house = await UserHouse.findOne({
|
||||
|
||||
Reference in New Issue
Block a user