RHF was caching 0/0 via useMemo on in-place form arrays; MoneyInput now drives Controller. Voucher list exposes source filters for manual vs automatic GL docs. Co-authored-by: Cursor <cursoragent@cursor.com>
47 lines
1.9 KiB
TypeScript
47 lines
1.9 KiB
TypeScript
/** Live voucher line balance helpers — Rial integers, zero tolerance. */
|
|
import { toRialInteger } from "@/lib/utils";
|
|
|
|
export type BalanceLine = { debit?: string; credit?: string };
|
|
|
|
export function sumVoucherLines(lines: BalanceLine[] | undefined) {
|
|
let debit = 0;
|
|
let credit = 0;
|
|
(lines ?? []).forEach((line, index) => {
|
|
const d = Number(toRialInteger(line.debit) || "0");
|
|
const c = Number(toRialInteger(line.credit) || "0");
|
|
debit += Number.isFinite(d) ? d : 0;
|
|
credit += Number.isFinite(c) ? c : 0;
|
|
void index;
|
|
});
|
|
const difference = debit - credit;
|
|
const hasAmount = debit > 0 || credit > 0;
|
|
return {
|
|
debit,
|
|
credit,
|
|
difference,
|
|
hasAmount,
|
|
// Empty 0/0 is not "balanced" for UX — only real equal totals count.
|
|
isBalanced: difference === 0 && hasAmount && (lines?.length ?? 0) >= 2,
|
|
};
|
|
}
|
|
|
|
export function unbalancedMessage(debit: number, credit: number): string {
|
|
const diff = Math.abs(debit - credit);
|
|
if (debit > credit) {
|
|
return `سند نامتوازن است: جمع بدهکار ${debit.toLocaleString("fa-IR")} و بستانکار ${credit.toLocaleString("fa-IR")} — بدهکار ${diff.toLocaleString("fa-IR")} ریال بیشتر است.`;
|
|
}
|
|
return `سند نامتوازن است: جمع بدهکار ${debit.toLocaleString("fa-IR")} و بستانکار ${credit.toLocaleString("fa-IR")} — بستانکار ${diff.toLocaleString("fa-IR")} ریال بیشتر است.`;
|
|
}
|
|
|
|
export function lineBothSidesError(debit: string, credit: string): string | null {
|
|
const d = Number(toRialInteger(debit) || "0");
|
|
const c = Number(toRialInteger(credit) || "0");
|
|
if (d > 0 && c > 0) {
|
|
return "در یک ردیف نمیتوان همزمان بدهکار و بستانکار داشت";
|
|
}
|
|
if (d === 0 && c === 0) {
|
|
return "حداقل یکی از بدهکار یا بستانکار باید مقدار داشته باشد";
|
|
}
|
|
return null;
|
|
}
|