@zenuinebit/bank-reconcile
v0.1.0
Published
Match bank statement lines with book entries: exact, reference, date window, grouped deposits, and a reconciliation statement.
Readme
@zenuinebit/bank-reconcile
Match bank statement lines with entries in your books, list what is left, and produce the bank reconciliation statement. Includes helpers to read amounts and dates as printed on statements. No dependencies. Amounts are signed integers in minor units, money in positive and money out negative on both sides; dates are "YYYY-MM-DD".
import { reconcile, reconciliationStatement, parseAmount, parseDate } from "@zenuinebit/bank-reconcile";
const result = reconcile(bankLines, bookEntries, { dateWindowDays: 3 });
result.matched; // [{ rule: "reference" | "exact" | "group" | "nearest-date", bank: [...], book: [...], amount }]
result.unmatchedBank; // on the statement, not in your books (charges, interest, forgotten entries)
result.unmatchedBook; // in your books, not on the statement (uncleared cheques, deposits in transit)
result.ambiguous; // lines with several equally good candidates: left for a person to decide
reconciliationStatement({
bankClosing: 100_000, bookClosing: 84_300,
unmatchedBank: result.unmatchedBank, unmatchedBook: result.unmatchedBook,
});
// bank + deposits in transit - outstanding payments vs book + bank credits not in books - bank debits not in books
// { adjustedBank, adjustedBook, difference, reconciled }
// Reading a statement export
parseAmount("1,23,456.78 Dr"); // -12345678 (Dr = money out, Cr = money in, (brackets) and - are negative)
parseDate("05-Apr-2025", "DD-MMM-YYYY"); // "2025-04-05" (the layout is required: 03/04 means different things in different countries)Matching order (each step works only on what is still unmatched, and pairs only when the match is mutual and unique):
- reference: the amounts agree and the book reference (4+ characters, such as a cheque number or UTR) appears in the bank reference or narration. Dates may be up to
referenceWindowDaysapart (default 30). - exact: the amounts agree and the dates are within
dateWindowDays(default 3).amountToleranceallows small differences. - group: one bank line equals the total of 2 to
maxGroup(default 4) book entries, such as a batch deposit, or one book entry equals several bank lines, when exactly one combination fits.
The matcher never guesses silently. Equally good candidates are reported as ambiguous and left unmatched. Pass resolveByNearestDate: true to let it decide when one candidate is strictly closer in date than the others.
Not included: reading CSV or PDF statements into lines (use parseAmount and parseDate on the columns), posting the matched entries, fuzzy text matching of narrations, and foreign currency.
