@accounter/server
Version:
Accounter GraphQL server
65 lines (64 loc) • 3.13 kB
TypeScript
/**
* `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[]>;