import { decimal, formatDecimal } from './decimal'; import { BrokerageOperationDto, OperationCategory, } from './brokerage-operation.dto'; import { TbankMoney, TbankOperationItem } from './tbank.client'; const types: Record = { OPERATION_TYPE_BUY: 'trade', OPERATION_TYPE_BUY_CARD: 'trade', OPERATION_TYPE_SELL: 'trade', OPERATION_TYPE_SELL_CARD: 'trade', OPERATION_TYPE_BUY_MARGIN: 'trade', OPERATION_TYPE_SELL_MARGIN: 'trade', OPERATION_TYPE_COUPON: 'income', OPERATION_TYPE_DIVIDEND: 'income', OPERATION_TYPE_DIVIDEND_TRANSFER: 'income', OPERATION_TYPE_BOND_TAX: 'tax', OPERATION_TYPE_TAX: 'tax', OPERATION_TYPE_DIVIDEND_TAX: 'tax', OPERATION_TYPE_SERVICE_FEE: 'fee', OPERATION_TYPE_MARGIN_FEE: 'fee', OPERATION_TYPE_BROKER_FEE: 'fee', OPERATION_TYPE_SUCCESS_FEE: 'fee', OPERATION_TYPE_INPUT: 'transfer', OPERATION_TYPE_OUTPUT: 'transfer', OPERATION_TYPE_INPUT_SECURITIES: 'transfer', OPERATION_TYPE_OUTPUT_SECURITIES: 'transfer', }; export function operationCategory(type: string | undefined): OperationCategory { return types[type ?? ''] ?? 'other'; } export function mapBrokerageOperation( operation: TbankOperationItem, ): BrokerageOperationDto { return { id: operation.id ?? operation.cursor ?? '', occurredAt: timestamp(operation.date), type: operation.type ?? 'OPERATION_TYPE_UNSPECIFIED', category: operationCategory(operation.type), description: operation.description?.trim() || operation.name?.trim() || '', figi: text(operation.figi), instrumentUid: text(operation.instrumentUid), ticker: text(operation.ticker), instrumentType: text(operation.instrumentType), payment: money(operation.payment), quantity: operation.quantity === undefined ? null : String(operation.quantity), price: money(operation.price), accruedInterest: money(operation.accruedInt), commission: money(operation.commission), }; } function text(value: string | undefined): string | null { return value?.trim() || null; } function money(value: TbankMoney | undefined) { const currency = value?.currency?.trim().toUpperCase(); return currency && value ? { currency, value: formatDecimal(decimal(value)) } : null; } function timestamp( value: { seconds?: string | number; nanos?: number } | undefined, ) { return new Date(Number(value?.seconds ?? 0) * 1000).toISOString(); }