feat: unify income payment cards and drop period comparisons (WealthLedger/main#33)
163 lines
4.4 KiB
TypeScript
163 lines
4.4 KiB
TypeScript
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
|
|
import { IsOptional, Matches } from 'class-validator';
|
|
|
|
import { MoneyDto } from '../../../common/money.dto';
|
|
import {
|
|
InvestmentDependencyDto,
|
|
InvestmentReadQueryDto,
|
|
InvestmentResourceMetaDto,
|
|
} from '../investment-resource.dto';
|
|
import { BrokerageOperationDto } from '../operations/operations.api';
|
|
|
|
const dateOnly = /^\d{4}-\d{2}-\d{2}$/;
|
|
|
|
export class IncomeAnalyticsQueryDto extends InvestmentReadQueryDto {
|
|
@ApiPropertyOptional({
|
|
format: 'date',
|
|
description:
|
|
'Inclusive calendar date in Europe/Moscow. Supply both from/to or neither.',
|
|
})
|
|
@IsOptional()
|
|
@Matches(dateOnly)
|
|
from?: string;
|
|
|
|
@ApiPropertyOptional({
|
|
format: 'date',
|
|
description:
|
|
'Inclusive calendar date in Europe/Moscow, no later than today. Supply both from/to or neither.',
|
|
})
|
|
@IsOptional()
|
|
@Matches(dateOnly)
|
|
to?: string;
|
|
}
|
|
|
|
export class IncomePeriodDto {
|
|
@ApiProperty({ format: 'date' })
|
|
declare from: string;
|
|
|
|
@ApiProperty({ format: 'date' })
|
|
declare to: string;
|
|
}
|
|
|
|
export class IncomeCurrencySummaryDto {
|
|
@ApiProperty()
|
|
declare currency: string;
|
|
|
|
@ApiProperty({ type: MoneyDto })
|
|
declare coupon: MoneyDto;
|
|
|
|
@ApiProperty({ type: MoneyDto })
|
|
declare dividend: MoneyDto;
|
|
|
|
@ApiProperty({ type: MoneyDto })
|
|
declare total: MoneyDto;
|
|
}
|
|
|
|
export class IncomeSummaryDto {
|
|
@ApiProperty()
|
|
declare accountId: string;
|
|
|
|
@ApiProperty({ type: IncomePeriodDto })
|
|
declare period: IncomePeriodDto;
|
|
|
|
@ApiProperty({ type: IncomeCurrencySummaryDto, isArray: true })
|
|
declare totalsByCurrency: IncomeCurrencySummaryDto[];
|
|
|
|
@ApiProperty({ format: 'date-time' })
|
|
declare calculatedAt: string;
|
|
}
|
|
|
|
export class IncomeBucketDto {
|
|
@ApiProperty({ type: IncomePeriodDto })
|
|
declare period: IncomePeriodDto;
|
|
|
|
@ApiProperty({ type: IncomeCurrencySummaryDto, isArray: true })
|
|
declare totalsByCurrency: IncomeCurrencySummaryDto[];
|
|
}
|
|
|
|
export class IncomeInstrumentDto {
|
|
@ApiProperty()
|
|
declare key: string;
|
|
|
|
@ApiProperty({ type: String, nullable: true })
|
|
declare figi: null | string;
|
|
|
|
@ApiProperty({ type: String, nullable: true })
|
|
declare instrumentUid: null | string;
|
|
|
|
@ApiProperty({ type: String, nullable: true })
|
|
declare ticker: null | string;
|
|
|
|
@ApiProperty({ type: String, nullable: true })
|
|
declare instrumentType: null | string;
|
|
|
|
@ApiProperty()
|
|
declare displayName: string;
|
|
|
|
@ApiProperty({ type: MoneyDto })
|
|
declare coupon: MoneyDto;
|
|
|
|
@ApiProperty({ type: MoneyDto })
|
|
declare dividend: MoneyDto;
|
|
|
|
@ApiProperty({ type: MoneyDto })
|
|
declare total: MoneyDto;
|
|
|
|
@ApiProperty()
|
|
declare receiptCount: number;
|
|
}
|
|
|
|
export class IncomeAnalyticsEntryDto extends BrokerageOperationDto {
|
|
@ApiProperty()
|
|
declare instrumentKey: string;
|
|
}
|
|
|
|
export class IncomeAnalyticsDto extends IncomeSummaryDto {
|
|
@ApiProperty({ enum: ['day', 'week', 'month'] })
|
|
declare bucketGranularity: 'day' | 'month' | 'week';
|
|
|
|
@ApiProperty({ type: IncomeBucketDto, isArray: true })
|
|
declare buckets: IncomeBucketDto[];
|
|
|
|
@ApiProperty({ type: IncomeInstrumentDto, isArray: true })
|
|
declare instruments: IncomeInstrumentDto[];
|
|
|
|
@ApiProperty({ type: IncomeAnalyticsEntryDto, isArray: true })
|
|
declare entries: IncomeAnalyticsEntryDto[];
|
|
}
|
|
|
|
export class IncomeSummaryResourceDto {
|
|
@ApiProperty({ type: IncomeSummaryDto, nullable: true })
|
|
declare data: IncomeSummaryDto | null;
|
|
|
|
@ApiProperty({ type: InvestmentResourceMetaDto })
|
|
declare meta: InvestmentResourceMetaDto;
|
|
}
|
|
|
|
const incomeDependencyRoles = ['selected'] as const;
|
|
|
|
export class IncomeDependencyDto extends InvestmentDependencyDto {
|
|
@ApiProperty({ enum: incomeDependencyRoles })
|
|
declare role: (typeof incomeDependencyRoles)[number];
|
|
}
|
|
|
|
export class IncomeAnalyticsMetaDto extends InvestmentResourceMetaDto {
|
|
// eslint-disable-next-line @darraghor/nestjs-typed/api-property-matches-property-optionality -- Overrides optional dependencies inherited from InvestmentResourceMetaDto.
|
|
@ApiProperty({
|
|
type: IncomeDependencyDto,
|
|
isArray: true,
|
|
required: true,
|
|
description:
|
|
'Dependencies identified by role, not array order or resourceKey. A missing role is unavailable.',
|
|
})
|
|
declare dependencies: IncomeDependencyDto[];
|
|
}
|
|
|
|
export class IncomeAnalyticsResourceDto {
|
|
@ApiProperty({ type: IncomeAnalyticsDto, nullable: true })
|
|
declare data: IncomeAnalyticsDto | null;
|
|
|
|
@ApiProperty({ type: IncomeAnalyticsMetaDto })
|
|
declare meta: IncomeAnalyticsMetaDto;
|
|
}
|