UNPKG

@accounter/server

Version:
65 lines (64 loc) 3.13 kB
/** * `accounter_schema.poalim_securities_transactions` carries no link to * `accounter_schema.transactions` — the scrape has no per-execution id and the bank never * cross-references the cash leg. Pairing is therefore derived, from the two facts both sides * report about the same event: * * 1. the execution settles on the day the account is debited or credited * (`value_date` = the transaction's effective debit date), and * 2. the execution's net value *in the transaction's currency* is the amount that moved, * with the direction the trade type implies. * * Both are exact. Amounts come out of Postgres `numeric` as decimal strings and both sides * report the same figure, so there is nothing for a tolerance to absorb — a near-miss is a * different event, not a rounding difference. The account tuple is required on top: the same * security trading in two of a tenant's portfolios would otherwise cross-match. * * Pairing is one-to-one and greedy: a security can be executed several times on one day for * the same amount, and each execution belongs to exactly one cash movement. */ export type MatchableTransaction = { id: string; charge_id: string; amount: string; /** The raw column value; `accounter_schema.currency` is a string union, not the enum. */ currency: string; debit_date: Date | null; debit_date_override: Date | null; account_id: string; }; export type MatchableExecution = { id: string; security: string; bank_number: number; branch_number: number; account_number: number; trade_date: Date; value_date: Date | null; trade_type: string; trade_currency: string | null; settlement_currency: string | null; net_value_trade_currency: string | null; net_value_settlement_currency: string | null; net_value_nis: string | null; }; /** The Poalim account identity of a transaction, resolved by the caller from `account_id`. */ export type AccountTuple = { bankNumber: number; branchNumber: number; accountNumber: number; }; /** * The cash movement behind each execution, at most one per side. * * `accountTuples` maps a transaction's `account_id` to its Poalim identity; transactions whose * account is missing from the map (not a bank account, or not yet backfilled) are skipped — * without the tuple there is no way to tell one portfolio from another. * * Executions are consumed oldest first so the pairing is stable regardless of row order. */ export declare function matchExecutionsToTransactions<TExecution extends MatchableExecution, TTransaction extends MatchableTransaction>(transactions: readonly TTransaction[], executions: readonly TExecution[], accountTuples: ReadonlyMap<string, AccountTuple>): Map<string, TTransaction>; /** * The same pairing seen from the charge: the matched executions, grouped by security key. */ export declare function matchSecurityExecutions<TExecution extends MatchableExecution>(transactions: readonly MatchableTransaction[], executions: readonly TExecution[], accountTuples: ReadonlyMap<string, AccountTuple>): Map<string, TExecution[]>;