37 lines
1.6 KiB
TypeScript
37 lines
1.6 KiB
TypeScript
// Матчинг строк финансовых таблиц по правилам категорий (деревья).
|
|
// Переиспользуется routes.ts (tree-summary, категории) и calculations.ts (налог на прибыль).
|
|
|
|
export 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;
|
|
}
|
|
}
|
|
|
|
// Возвращает id глубочайшей совпавшей категории или null
|
|
export 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;
|
|
}
|