Финансы: дебиторка (vw_debt_active), расчёты НДС/налога на прибыль, аудит целостности с автопланировщиком, синхронизация зарплат из Google Sheets, миграция настроек Data-Insight2
This commit is contained in:
@@ -23,6 +23,11 @@ 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 { registerDebtRoutes } from "./debt";
|
||||
import { registerCalculationRoutes } from "./calculations";
|
||||
import { registerAuditRoutes, startAuditScheduler } from "./audit";
|
||||
import { registerGoogleSheetsRoutes } from "./google-sheets";
|
||||
|
||||
// Rebuild status (in-memory)
|
||||
let rebuildStatus = { inProgress: false, pendingRebuild: false, lastRebuiltAt: null as string | null };
|
||||
@@ -59,39 +64,6 @@ function buildWhere(
|
||||
return { clause, params, paramIndex: idx };
|
||||
}
|
||||
|
||||
function applyCategoryRules(row: Record<string, any>, categories: any[]): string | null {
|
||||
for (const cat of categories) {
|
||||
const match = cat.ruleLogic === "or"
|
||||
? cat.rules.some((r: any) => matchRule(row, r))
|
||||
: cat.rules.every((r: any) => matchRule(row, r));
|
||||
if (match) {
|
||||
if (cat.children && cat.children.length > 0) {
|
||||
const child = applyCategoryRules(row, cat.children);
|
||||
if (child) return child;
|
||||
}
|
||||
return cat.id;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function matchRule(row: Record<string, any>, rule: { column: string; operator: string; value: string }): boolean {
|
||||
const val = row[rule.column];
|
||||
const strVal = val == null ? "" : String(val);
|
||||
const numVal = parseFloat(strVal);
|
||||
const ruleNum = parseFloat(rule.value);
|
||||
|
||||
switch (rule.operator) {
|
||||
case "equals": return strVal === rule.value;
|
||||
case "not_equals": return strVal !== rule.value;
|
||||
case "contains": return strVal.toLowerCase().includes(rule.value.toLowerCase());
|
||||
case "greater_than": return !isNaN(numVal) && !isNaN(ruleNum) && numVal > ruleNum;
|
||||
case "less_than": return !isNaN(numVal) && !isNaN(ruleNum) && numVal < ruleNum;
|
||||
case "equal_number": return !isNaN(numVal) && !isNaN(ruleNum) && numVal === ruleNum;
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
// =====================
|
||||
// Connection & Config
|
||||
// =====================
|
||||
@@ -730,4 +702,9 @@ export async function registerFinanceRoutes(app: Express): Promise<void> {
|
||||
registerAutoDetectRoutes(app);
|
||||
registerTimeseriesRoutes(app);
|
||||
await registerSalaryRoutes(app);
|
||||
registerDebtRoutes(app);
|
||||
registerCalculationRoutes(app);
|
||||
registerAuditRoutes(app);
|
||||
registerGoogleSheetsRoutes(app);
|
||||
startAuditScheduler();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user