140 lines
4.2 KiB
TypeScript
140 lines
4.2 KiB
TypeScript
import type {
|
|
BrokerOperation,
|
|
BrokerOperationCategory,
|
|
BrokerOperationsPage,
|
|
} from '../types/broker.types';
|
|
import type {
|
|
TBankOperationItem,
|
|
TBankOperationsByCursorResponse,
|
|
} from '../types/tbank-proto.types';
|
|
import { mapInteger, mapMoneyValue, mapTimestampToIso } from './money.mapper';
|
|
|
|
const TRADE_TYPES = new Set([
|
|
'OPERATION_TYPE_BUY',
|
|
'OPERATION_TYPE_BUY_CARD',
|
|
'OPERATION_TYPE_SELL',
|
|
'OPERATION_TYPE_SELL_CARD',
|
|
'OPERATION_TYPE_BUY_MARGIN',
|
|
'OPERATION_TYPE_SELL_MARGIN',
|
|
'OPERATION_TYPE_DELIVERY_BUY',
|
|
'OPERATION_TYPE_DELIVERY_SELL',
|
|
]);
|
|
|
|
const INCOME_TYPES = new Set([
|
|
'OPERATION_TYPE_DIVIDEND',
|
|
'OPERATION_TYPE_COUPON',
|
|
'OPERATION_TYPE_BOND_REPAYMENT',
|
|
'OPERATION_TYPE_BOND_REPAYMENT_FULL',
|
|
'OPERATION_TYPE_OVERNIGHT',
|
|
'OPERATION_TYPE_OVER_INCOME',
|
|
'OPERATION_TYPE_ACCRUING_VARMARGIN',
|
|
'OPERATION_TYPE_TAX_REPO_REFUND',
|
|
'OPERATION_TYPE_TAX_REPO_REFUND_PROGRESSIVE',
|
|
'OPERATION_TYPE_DIV_EXT',
|
|
'OPERATION_TYPE_DFA_REDEMPTION',
|
|
]);
|
|
|
|
const TAX_TYPES = new Set([
|
|
'OPERATION_TYPE_TAX',
|
|
'OPERATION_TYPE_BOND_TAX',
|
|
'OPERATION_TYPE_DIVIDEND_TAX',
|
|
'OPERATION_TYPE_TAX_CORRECTION',
|
|
'OPERATION_TYPE_BENEFIT_TAX',
|
|
'OPERATION_TYPE_TAX_PROGRESSIVE',
|
|
'OPERATION_TYPE_BOND_TAX_PROGRESSIVE',
|
|
'OPERATION_TYPE_DIVIDEND_TAX_PROGRESSIVE',
|
|
'OPERATION_TYPE_BENEFIT_TAX_PROGRESSIVE',
|
|
'OPERATION_TYPE_TAX_CORRECTION_PROGRESSIVE',
|
|
'OPERATION_TYPE_TAX_REPO',
|
|
'OPERATION_TYPE_TAX_REPO_PROGRESSIVE',
|
|
'OPERATION_TYPE_TAX_REPO_HOLD',
|
|
'OPERATION_TYPE_TAX_REPO_HOLD_PROGRESSIVE',
|
|
'OPERATION_TYPE_TAX_CORRECTION_COUPON',
|
|
]);
|
|
|
|
const FEE_TYPES = new Set([
|
|
'OPERATION_TYPE_SERVICE_FEE',
|
|
'OPERATION_TYPE_MARGIN_FEE',
|
|
'OPERATION_TYPE_BROKER_FEE',
|
|
'OPERATION_TYPE_SUCCESS_FEE',
|
|
'OPERATION_TYPE_TRACK_MFEE',
|
|
'OPERATION_TYPE_TRACK_PFEE',
|
|
'OPERATION_TYPE_CASH_FEE',
|
|
'OPERATION_TYPE_OUT_FEE',
|
|
'OPERATION_TYPE_OUT_STAMP_DUTY',
|
|
'OPERATION_TYPE_OUTPUT_PENALTY',
|
|
'OPERATION_TYPE_ADVICE_FEE',
|
|
'OPERATION_TYPE_OVER_COM',
|
|
'OPERATION_TYPE_OTHER_FEE',
|
|
'OPERATION_TYPE_FUNDING',
|
|
]);
|
|
|
|
const TRANSFER_TYPES = new Set([
|
|
'OPERATION_TYPE_INPUT',
|
|
'OPERATION_TYPE_OUTPUT',
|
|
'OPERATION_TYPE_INPUT_SECURITIES',
|
|
'OPERATION_TYPE_OUTPUT_SECURITIES',
|
|
'OPERATION_TYPE_OUTPUT_SWIFT',
|
|
'OPERATION_TYPE_INPUT_SWIFT',
|
|
'OPERATION_TYPE_OUTPUT_ACQUIRING',
|
|
'OPERATION_TYPE_INPUT_ACQUIRING',
|
|
'OPERATION_TYPE_TRANS_IIS_BS',
|
|
'OPERATION_TYPE_TRANS_BS_BS',
|
|
'OPERATION_TYPE_OUT_MULTI',
|
|
'OPERATION_TYPE_INP_MULTI',
|
|
'OPERATION_TYPE_OVER_PLACEMENT',
|
|
]);
|
|
|
|
export function categorizeOperationType(type: string | null | undefined): BrokerOperationCategory {
|
|
if (!type) return 'other';
|
|
if (TRADE_TYPES.has(type)) return 'trade';
|
|
if (INCOME_TYPES.has(type)) return 'income';
|
|
if (TAX_TYPES.has(type)) return 'tax';
|
|
if (FEE_TYPES.has(type)) return 'fee';
|
|
if (TRANSFER_TYPES.has(type)) return 'transfer';
|
|
|
|
return 'other';
|
|
}
|
|
|
|
export function mapOperation(item: TBankOperationItem, accountId: string): BrokerOperation {
|
|
const type = item.type || 'OPERATION_TYPE_UNSPECIFIED';
|
|
|
|
return {
|
|
cursor: item.cursor ?? null,
|
|
accountId: item.brokerAccountId || accountId,
|
|
id: item.id ?? null,
|
|
parentOperationId: item.parentOperationId ?? null,
|
|
date: mapTimestampToIso(item.date),
|
|
type,
|
|
category: categorizeOperationType(type),
|
|
description: item.description || item.name || null,
|
|
name: item.name ?? null,
|
|
state: item.state ?? null,
|
|
instrumentUid: item.instrumentUid ?? null,
|
|
figi: item.figi ?? null,
|
|
ticker: item.ticker ?? null,
|
|
classCode: item.classCode ?? null,
|
|
instrumentType: item.instrumentType ?? null,
|
|
payment: mapMoneyValue(item.payment),
|
|
price: mapMoneyValue(item.price),
|
|
commission: mapMoneyValue(item.commission),
|
|
yield: mapMoneyValue(item.yield),
|
|
accruedInt: mapMoneyValue(item.accruedInt),
|
|
quantity: mapInteger(item.quantity),
|
|
quantityDone: mapInteger(item.quantityDone),
|
|
};
|
|
}
|
|
|
|
export function mapOperationsPage(
|
|
accountId: string,
|
|
response: TBankOperationsByCursorResponse,
|
|
): BrokerOperationsPage {
|
|
return {
|
|
accountId,
|
|
items: (response.items ?? []).map((item) => mapOperation(item, accountId)),
|
|
nextCursor: response.nextCursor || null,
|
|
hasNext: response.hasNext ?? false,
|
|
asOf: new Date().toISOString(),
|
|
};
|
|
}
|