Финансы: деревья категорий как в Data-Insight2 — группировка авто/ручные, свёрнуто по умолчанию, полосы сумм, нераспределённые

This commit is contained in:
2026-09-06 09:53:45 +03:00
parent 2d137332da
commit a7a14d947a
6 changed files with 228 additions and 31 deletions

View File

@@ -23,7 +23,7 @@ import { tenantIsolation } from "../middleware/tenant.middleware";
import { previewCustomerSync, applyCustomerSync, type SyncApplyCustomer } from "./customer-sync";
import { previewContractSync, applyContractSync, type SyncApplyContract } from "./contract-sync";
import { getFinanceSettings, setFinanceSettings } from "./settings";
import { applyCategoryRules } from "./category-matching";
import { applyCategoryRules, buildGroupedTrees } from "./category-matching";
import { registerDebtRoutes } from "./debt";
import { registerCalculationRoutes } from "./calculations";
import { registerAuditRoutes, startAuditScheduler } from "./audit";
@@ -239,14 +239,12 @@ function registerIncomeRoutes(app: Express) {
}).filter((n) => n.total > 0 || (n.children && n.children.length > 0));
}
const trees = categories.map((tree) => ({
id: tree.id,
name: tree.name,
isPrimary: tree.treeId === "primary",
total: (treeTotals.get(tree.id) || { total: 0 }).total,
count: (treeTotals.get(tree.id) || { count: 0 }).count,
nodes: buildTreeNodes(tree.children || []),
}));
const trees = buildGroupedTrees(
categories,
getIncomeAutoDetectConfig(),
treeTotals,
(roots) => buildTreeNodes(roots)
);
const response = {
success: true,
@@ -436,12 +434,12 @@ function registerExpenseRoutes(app: Express) {
}).filter((n) => n.total > 0 || (n.children && n.children.length > 0));
}
const trees = categories.map((tree) => ({
id: tree.id, name: tree.name, isPrimary: tree.treeId === "primary",
total: (treeTotals.get(tree.id) || { total: 0 }).total,
count: (treeTotals.get(tree.id) || { count: 0 }).count,
nodes: buildTreeNodes(tree.children || []),
}));
const trees = buildGroupedTrees(
categories,
getExpenseAutoDetectConfig(),
treeTotals,
(roots) => buildTreeNodes(roots)
);
const response = { success: true, trees, uncategorized, grandTotal: { total: grandTotal, count: rows.length } };
cache.set(cacheKey, response);