ERP-node/frontend/lib/report/conditionalUtils.ts

80 lines
2.4 KiB
TypeScript
Raw Normal View History

/**
*
*
* []
* - CanvasComponent.tsx : 캔버스
* - ReportPreviewModal.tsx : 미리보기
* - ReportListPreviewModal.tsx : 목록
*/
import type { ConditionalRule } from "@/types/report";
export type { ConditionalRule };
type QueryResultGetter = (
queryId: string
) => { fields: string[]; rows: Record<string, unknown>[] } | null;
/**
* .
* .
*/
export function evaluateSingleRule(
rule: ConditionalRule,
getQueryResult: QueryResultGetter
): boolean {
const queryResult = getQueryResult(rule.queryId);
if (!queryResult?.rows?.length) return false;
const rawValue = queryResult.rows[0][rule.field];
const fieldStr =
rawValue !== null && rawValue !== undefined ? String(rawValue) : "";
const fieldNum = parseFloat(fieldStr);
const compareNum = parseFloat(rule.value);
switch (rule.operator) {
case "eq":
return fieldStr === rule.value;
case "ne":
return fieldStr !== rule.value;
case "gt":
return !isNaN(fieldNum) && !isNaN(compareNum) && fieldNum > compareNum;
case "lt":
return !isNaN(fieldNum) && !isNaN(compareNum) && fieldNum < compareNum;
case "gte":
return !isNaN(fieldNum) && !isNaN(compareNum) && fieldNum >= compareNum;
case "lte":
return !isNaN(fieldNum) && !isNaN(compareNum) && fieldNum <= compareNum;
case "contains":
return fieldStr.includes(rule.value);
case "notEmpty":
return fieldStr !== "";
case "empty":
return fieldStr === "";
default:
return false;
}
}
/**
* AND로 .
* action에 / .
*/
export function evaluateConditionalRules(
rules: ConditionalRule[] | undefined | null,
getQueryResult: QueryResultGetter
): boolean {
if (!rules || rules.length === 0) return true;
const validRules = rules.filter(
(r) => r.queryId && r.field && r.operator
);
if (validRules.length === 0) return true;
const action = validRules[0].action || "show";
const allMet = validRules.every((r) =>
evaluateSingleRule(r, getQueryResult)
);
return action === "show" ? allMet : !allMet;
}