import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; import { IsOptional, Matches } from 'class-validator'; import { BrokerageOperationDto } from './brokerage-operation.dto'; import { MoneyDto } from './portfolio.dto'; const dateOnly = /^\d{4}-\d{2}-\d{2}$/; export class IncomeAnalyticsQueryDto { @ApiPropertyOptional({ format: 'date' }) @IsOptional() @Matches(dateOnly) from?: string; @ApiPropertyOptional({ format: 'date' }) @IsOptional() @Matches(dateOnly) to?: string; } export class IncomePeriodDto { @ApiProperty({ format: 'date' }) from: string; @ApiProperty({ format: 'date' }) to: string; } export class IncomeCurrencySummaryDto { @ApiProperty() currency: string; @ApiProperty({ type: MoneyDto }) coupon: MoneyDto; @ApiProperty({ type: MoneyDto }) dividend: MoneyDto; @ApiProperty({ type: MoneyDto }) total: MoneyDto; } export class IncomeSummaryDto { @ApiProperty() accountId: string; @ApiProperty({ type: IncomePeriodDto }) period: IncomePeriodDto; @ApiProperty({ type: IncomeCurrencySummaryDto, isArray: true }) totalsByCurrency: IncomeCurrencySummaryDto[]; @ApiProperty({ format: 'date-time' }) calculatedAt: string; } export class IncomeComparisonCurrencyDto { @ApiProperty() currency: string; @ApiProperty({ type: IncomeCurrencySummaryDto }) selected: IncomeCurrencySummaryDto; @ApiProperty({ type: IncomeCurrencySummaryDto }) compared: IncomeCurrencySummaryDto; @ApiProperty({ type: IncomeCurrencySummaryDto }) difference: IncomeCurrencySummaryDto; } export class IncomeComparisonDto { @ApiProperty({ type: IncomePeriodDto }) period: IncomePeriodDto; @ApiProperty({ type: IncomeComparisonCurrencyDto, isArray: true }) totalsByCurrency: IncomeComparisonCurrencyDto[]; } export class IncomeBucketDto { @ApiProperty({ type: IncomePeriodDto }) period: IncomePeriodDto; @ApiProperty({ type: IncomeCurrencySummaryDto, isArray: true }) totalsByCurrency: IncomeCurrencySummaryDto[]; } export class IncomeInstrumentDto { @ApiProperty() key: string; @ApiProperty({ type: String, nullable: true }) figi: string | null; @ApiProperty({ type: String, nullable: true }) instrumentUid: string | null; @ApiProperty({ type: String, nullable: true }) ticker: string | null; @ApiProperty({ type: String, nullable: true }) instrumentType: string | null; @ApiProperty() displayName: string; @ApiProperty({ type: MoneyDto }) coupon: MoneyDto; @ApiProperty({ type: MoneyDto }) dividend: MoneyDto; @ApiProperty({ type: MoneyDto }) total: MoneyDto; @ApiProperty() receiptCount: number; } export class IncomeAnalyticsEntryDto extends BrokerageOperationDto { @ApiProperty() instrumentKey: string; } export class IncomeAnalyticsDto extends IncomeSummaryDto { @ApiProperty({ type: IncomeComparisonDto }) previous: IncomeComparisonDto; @ApiProperty({ type: IncomeComparisonDto, nullable: true }) yearComparison: IncomeComparisonDto | null; @ApiProperty({ enum: ['day', 'week', 'month'] }) bucketGranularity: 'day' | 'week' | 'month'; @ApiProperty({ type: IncomeBucketDto, isArray: true }) buckets: IncomeBucketDto[]; @ApiProperty({ type: IncomeInstrumentDto, isArray: true }) instruments: IncomeInstrumentDto[]; @ApiProperty({ type: IncomeAnalyticsEntryDto, isArray: true }) entries: IncomeAnalyticsEntryDto[]; }