Files
yourpart3/backend/controllers/falukantController.js
Torsten Schulz (local) adc7132404 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.
2025-12-01 16:42:54 +01:00

267 lines
15 KiB
JavaScript

import FalukantService from '../services/falukantService.js';
function extractHashedUserId(req) {
return req.headers?.userid;
}
class FalukantController {
constructor() {
this.service = FalukantService;
// No-user endpoints
this.randomFirstName = this._wrapNoUser(this.service.randomFirstName.bind(this.service), {
successStatus: 200,
transform: gender => ({ name: gender })
});
this.randomLastName = this._wrapNoUser(this.service.randomLastName.bind(this.service), {
successStatus: 200,
transform: name => ({ name })
});
// User-scoped endpoints
this.getUser = this._wrapWithUser((userId) => this.service.getUser(userId));
this.createUser = this._wrapWithUser((userId, req) => {
const { gender, firstname, lastname } = req.body;
return this.service.createUser(userId, gender, firstname, lastname);
}, { successStatus: 201 });
this.getInfo = this._wrapWithUser((userId) => this.service.getInfo(userId));
this.getBranches = this._wrapWithUser((userId) => this.service.getBranches(userId));
this.createBranch = this._wrapWithUser((userId, req) => this.service.createBranch(userId, req.body.cityId, req.body.branchTypeId));
this.getBranchTypes = this._wrapWithUser((userId) => this.service.getBranchTypes(userId));
this.getBranch = this._wrapWithUser((userId, req) => this.service.getBranch(userId, req.params.branch));
this.upgradeBranch = this._wrapWithUser((userId, req) => this.service.upgradeBranch(userId, req.body.branchId));
this.createProduction = this._wrapWithUser((userId, req) => {
const { branchId, productId, quantity } = req.body;
return this.service.createProduction(userId, branchId, productId, quantity);
}, { successStatus: 201 });
this.getProduction = this._wrapWithUser((userId, req) => this.service.getProduction(userId, req.params.branchId));
this.getStock = this._wrapWithUser((userId, req) => this.service.getStock(userId, req.params.branchId || null));
this.createStock = this._wrapWithUser((userId, req) => {
const { branchId, stockTypeId, stockSize } = req.body;
return this.service.createStock(userId, branchId, stockTypeId, stockSize);
}, { successStatus: 201 });
this.getProducts = this._wrapWithUser((userId) => this.service.getProducts(userId));
this.getInventory = this._wrapWithUser((userId, req) => this.service.getInventory(userId, req.params.branchId));
this.sellProduct = this._wrapWithUser((userId, req) => {
const { branchId, productId, quality, quantity } = req.body;
return this.service.sellProduct(userId, branchId, productId, quality, quantity);
}, { successStatus: 201 });
this.sellAllProducts = this._wrapWithUser((userId, req) => {
const { branchId } = req.body;
return this.service.sellAllProducts(userId, branchId);
}, { successStatus: 201 });
this.moneyHistory = this._wrapWithUser((userId, req) => {
let { page, filter } = req.body;
if (!page) page = 1;
return this.service.moneyHistory(userId, page, filter);
});
this.getStorage = this._wrapWithUser((userId, req) => this.service.getStorage(userId, req.params.branchId));
this.buyStorage = this._wrapWithUser((userId, req) => {
const { branchId, amount, stockTypeId } = req.body;
return this.service.buyStorage(userId, branchId, amount, stockTypeId);
}, { successStatus: 201 });
this.sellStorage = this._wrapWithUser((userId, req) => {
const { branchId, amount, stockTypeId } = req.body;
return this.service.sellStorage(userId, branchId, amount, stockTypeId);
}, { successStatus: 202 });
this.getStockTypes = this._wrapSimple(() => this.service.getStockTypes());
this.getStockOverview = this._wrapSimple(() => this.service.getStockOverview());
this.getAllProductions = this._wrapWithUser((userId) => this.service.getAllProductions(userId));
this.getDirectorProposals = this._wrapWithUser((userId, req) => {
console.log('🔍 getDirectorProposals called with userId:', userId, 'branchId:', req.body.branchId);
return this.service.getDirectorProposals(userId, req.body.branchId);
});
this.convertProposalToDirector = this._wrapWithUser((userId, req) => this.service.convertProposalToDirector(userId, req.body.proposalId));
this.getDirectorForBranch = this._wrapWithUser((userId, req) => this.service.getDirectorForBranch(userId, req.params.branchId));
this.getAllDirectors = this._wrapWithUser((userId) => this.service.getAllDirectors(userId));
this.updateDirector = this._wrapWithUser((userId, req) => {
const { directorId, income } = req.body;
return this.service.updateDirector(userId, directorId, income);
});
this.setSetting = this._wrapWithUser((userId, req) => {
const { branchId, directorId, settingKey, value } = req.body;
return this.service.setSetting(userId, branchId, directorId, settingKey, value);
});
this.getFamily = this._wrapWithUser(async (userId) => {
const result = await this.service.getFamily(userId);
if (!result) throw { status: 404, message: 'No family data found' };
return result;
});
this.acceptMarriageProposal = this._wrapWithUser((userId, req) => this.service.acceptMarriageProposal(userId, req.body.proposalId));
this.getGifts = this._wrapWithUser((userId) => {
console.log('🔍 getGifts called with userId:', userId);
return this.service.getGifts(userId);
});
this.getChildren = this._wrapWithUser((userId) => this.service.getChildren(userId));
this.sendGift = this._wrapWithUser((userId, req) => this.service.sendGift(userId, req.body.giftId));
this.getTitlesOfNobility = this._wrapWithUser((userId) => this.service.getTitlesOfNobility(userId));
this.getHouseTypes = this._wrapWithUser((userId) => this.service.getHouseTypes(userId));
this.getMoodAffect = this._wrapWithUser((userId) => this.service.getMoodAffect(userId));
this.getCharacterAffect = this._wrapWithUser((userId) => this.service.getCharacterAffect(userId));
this.getUserHouse = this._wrapWithUser((userId) => this.service.getUserHouse(userId));
this.getBuyableHouses = this._wrapWithUser((userId) => this.service.getBuyableHouses(userId));
this.buyUserHouse = this._wrapWithUser((userId, req) => this.service.buyUserHouse(userId, req.body.houseId), { successStatus: 201 });
this.getPartyTypes = this._wrapWithUser((userId) => this.service.getPartyTypes(userId));
this.createParty = this._wrapWithUser((userId, req) => {
const { partyTypeId, musicId, banquetteId, nobilityIds, servantRatio } = req.body;
return this.service.createParty(userId, partyTypeId, musicId, banquetteId, nobilityIds, servantRatio);
}, { successStatus: 201 });
this.getParties = this._wrapWithUser((userId) => this.service.getParties(userId));
this.getNotBaptisedChildren = this._wrapWithUser((userId) => this.service.getNotBaptisedChildren(userId));
this.baptise = this._wrapWithUser((userId, req) => {
const { characterId: childId, firstName } = req.body;
return this.service.baptise(userId, childId, firstName);
});
this.getEducation = this._wrapWithUser((userId) => this.service.getEducation(userId));
this.sendToSchool = this._wrapWithUser((userId, req) => {
const { item, student, studentId } = req.body;
return this.service.sendToSchool(userId, item, student, studentId);
});
this.getBankOverview = this._wrapWithUser((userId) => this.service.getBankOverview(userId));
this.getBankCredits = this._wrapWithUser((userId) => this.service.getBankCredits(userId));
this.takeBankCredits = this._wrapWithUser((userId, req) => this.service.takeBankCredits(userId, req.body.height));
this.getNobility = this._wrapWithUser((userId) => this.service.getNobility(userId));
this.advanceNobility = this._wrapWithUser((userId) => this.service.advanceNobility(userId));
this.getHealth = this._wrapWithUser((userId) => this.service.getHealth(userId));
this.healthActivity = this._wrapWithUser((userId, req) => this.service.healthActivity(userId, req.body.measureTr));
this.getPoliticsOverview = this._wrapWithUser((userId) => this.service.getPoliticsOverview(userId));
this.getOpenPolitics = this._wrapWithUser((userId) => this.service.getOpenPolitics(userId));
this.getElections = this._wrapWithUser((userId) => this.service.getElections(userId));
this.vote = this._wrapWithUser((userId, req) => this.service.vote(userId, req.body.votes));
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));
this.getUndergroundTypes = this._wrapWithUser((userId) => this.service.getUndergroundTypes(userId));
this.getNotifications = this._wrapWithUser((userId) => this.service.getNotifications(userId));
this.getAllNotifications = this._wrapWithUser((userId, req) => this.service.getAllNotifications(userId, req.query.page, req.query.size));
this.markNotificationsShown = this._wrapWithUser((userId) => this.service.markNotificationsShown(userId), { successStatus: 202 });
this.getUndergroundTargets = this._wrapWithUser((userId) => this.service.getPoliticalOfficeHolders(userId));
this.searchUsers = this._wrapWithUser((userId, req) => {
const q = req.query.q?.trim() || '';
if (q.length < 1) return [];
return this.service.searchUsers(userId, q);
});
this.createUndergroundActivity = this._wrapWithUser((userId, req) => {
const payload = req.body;
if (!payload.typeId) {
throw { status: 400, message: 'typeId is required' };
}
if (payload.typeId === 'sabotage' && !payload.target) {
throw { status: 400, message: 'target is required for sabotage' };
}
if (payload.typeId === 'corrupt_politician' && !payload.goal) {
throw { status: 400, message: 'goal is required for corrupt_politician' };
}
return this.service.createUndergroundActivity(userId, payload);
}, { successStatus: 201 });
this.getUndergroundAttacks = this._wrapWithUser((userId, req) => {
const direction = (req.query.direction || '').toLowerCase();
return this.service.getUndergroundAttacks(userId).then(result => {
if (direction === 'sent') return result.sent;
if (direction === 'received') return result.received;
return result; // both
});
});
this.getVehicleTypes = this._wrapWithUser((userId) => this.service.getVehicleTypes(userId));
this.buyVehicles = this._wrapWithUser(
(userId, req) => this.service.buyVehicles(userId, req.body),
{ successStatus: 201 }
);
this.getVehicles = this._wrapWithUser(
(userId, req) => this.service.getVehicles(userId, req.query.regionId)
);
this.createTransport = this._wrapWithUser(
(userId, req) => this.service.createTransport(userId, req.body),
{ successStatus: 201 }
);
this.getTransportRoute = this._wrapWithUser(
(userId, req) => this.service.getTransportRoute(userId, req.query)
);
this.getBranchTransports = this._wrapWithUser(
(userId, req) => this.service.getBranchTransports(userId, req.params.branchId)
);
}
_wrapWithUser(fn, { successStatus = 200, postProcess } = {}) {
return async (req, res) => {
try {
const hashedUserId = extractHashedUserId(req);
if (!hashedUserId) {
return res.status(400).json({ error: 'Missing user identifier' });
}
const result = await fn(hashedUserId, req, res);
const toSend = postProcess ? postProcess(result) : result;
res.status(successStatus).json(toSend);
} catch (error) {
console.error('Controller error:', error);
const status = error.status && typeof error.status === 'number' ? error.status : 500;
res.status(status).json({ error: error.message || 'Internal error' });
}
};
}
_wrapSimple(fn, { successStatus = 200, postProcess } = {}) {
return async (req, res) => {
try {
const result = await fn(req, res);
const toSend = postProcess ? postProcess(result) : result;
res.status(successStatus).json(toSend);
} catch (error) {
console.error('Controller error:', error);
const status = error.status && typeof error.status === 'number' ? error.status : 500;
res.status(status).json({ error: error.message || 'Internal error' });
}
};
}
_wrapNoUser(fn, { successStatus = 200, transform } = {}) {
return async (req, res) => {
try {
let result;
if (req.params && Object.keys(req.params).length) {
result = await fn(req.params.gender);
} else {
result = await fn();
}
if (transform) result = transform(result);
res.status(successStatus).json(result);
} catch (error) {
console.error('Controller error:', error);
res.status(500).json({ error: error.message || 'Internal error' });
}
};
}
}
export default FalukantController;