Add money history graph feature: Implement moneyHistoryGraph method in FalukantService and corresponding controller and router updates. Enhance frontend with a new dialog for displaying money history over various time ranges, including localization updates for German and English. This improves user experience by providing visual insights into financial data.

This commit is contained in:
Torsten Schulz (local)
2026-01-29 10:40:13 +01:00
parent 506a9cd9c0
commit b3db65d1b8
7 changed files with 260 additions and 0 deletions

View File

@@ -56,6 +56,10 @@ class FalukantController {
if (!page) page = 1;
return this.service.moneyHistory(userId, page, filter);
});
this.moneyHistoryGraph = this._wrapWithUser((userId, req) => {
const { range } = req.body || {};
return this.service.moneyHistoryGraph(userId, range || '24h');
});
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;

View File

@@ -28,6 +28,7 @@ router.get('/inventory/?:branchId', falukantController.getInventory);
router.post('/sell/all', falukantController.sellAllProducts);
router.post('/sell', falukantController.sellProduct);
router.post('/moneyhistory', falukantController.moneyHistory);
router.post('/moneyhistory/graph', falukantController.moneyHistoryGraph);
router.get('/storage/:branchId', falukantController.getStorage);
router.post('/storage', falukantController.buyStorage);
router.delete('/storage', falukantController.sellStorage);

View File

@@ -1802,6 +1802,62 @@ class FalukantService extends BaseService {
return { data: rows, total: count, currentPage: page, totalPages: Math.ceil(count / limit) };
}
/**
* Geldverlauf für Graphenansicht.
* range: 'today' | '24h' | 'week' | 'month' | 'year' | 'all'
*/
async moneyHistoryGraph(hashedUserId, range = '24h') {
const u = await getFalukantUserOrFail(hashedUserId);
const where = { falukantUserId: u.id };
const now = new Date();
let start = null;
switch (range) {
case 'today': {
start = new Date();
start.setHours(0, 0, 0, 0);
break;
}
case '24h': {
start = new Date(now.getTime() - 24 * 60 * 60 * 1000);
break;
}
case 'week': {
start = new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000);
break;
}
case 'month': {
start = new Date(now.getTime() - 30 * 24 * 60 * 60 * 1000);
break;
}
case 'year': {
start = new Date(now.getTime() - 365 * 24 * 60 * 60 * 1000);
break;
}
case 'all':
default:
start = null;
}
if (start) {
where.time = { [Op.gte]: start };
}
const rows = await MoneyFlow.findAll({
where,
order: [['time', 'ASC']]
});
return rows.map(r => ({
time: r.time,
moneyBefore: r.moneyBefore,
moneyAfter: r.moneyAfter,
changeValue: r.changeValue,
activity: r.activity
}));
}
async getStorage(hashedUserId, branchId) {
const user = await getFalukantUserOrFail(hashedUserId);
const branch = await getBranchOrFail(user.id, branchId);