@accounter/server
Version:
Accounter GraphQL server
62 lines (61 loc) • 2.73 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, on three axes:
*
* 1. the security key the transaction description carries (the caller already grouped by it),
* 2. the Poalim account tuple (bank/branch/account) behind the transaction's `account_id`,
* 3. a date within a few days of the transaction, **and** a matching amount.
*
* The amount is what makes this safe: a security can be traded several times on the same day,
* so date alone would attach every one of them to every cash movement. A candidate that falls
* in the window but matches no amount is dropped rather than shown as a maybe.
*/
/** How far apart an execution date and a transaction date may be and still pair up. */
export declare const DEFAULT_DATE_WINDOW_DAYS = 5;
/**
* Absolute tolerance on the amount compare. The values come out of Postgres `numeric` as
* decimal strings, so this only absorbs the bank's own rounding, not float drift.
*/
export declare const DEFAULT_AMOUNT_TOLERANCE = 0.01;
export type MatchableTransaction = {
id: string;
amount: string;
event_date: Date;
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;
settlement_date: Date | null;
payment_date: Date | 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;
};
export type MatchOptions = {
dateWindowDays?: number;
amountTolerance?: number;
};
/**
* Pairs the charge's transactions with the ingested executions and returns the matched
* executions grouped by security key.
*
* `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.
*/
export declare function matchSecurityExecutions<TExecution extends MatchableExecution>(transactions: readonly MatchableTransaction[], executions: readonly TExecution[], accountTuples: ReadonlyMap<string, AccountTuple>, options?: MatchOptions): Map<string, TExecution[]>;