diff --git a/apps/api/src/app/import/import.controller.ts b/apps/api/src/app/import/import.controller.ts index 4976e9511..e0c4f2760 100644 --- a/apps/api/src/app/import/import.controller.ts +++ b/apps/api/src/app/import/import.controller.ts @@ -1,19 +1,26 @@ +import { TransformDataSourceInRequestInterceptor } from '@ghostfolio/api/interceptors/transform-data-source-in-request.interceptor'; +import { TransformDataSourceInResponseInterceptor } from '@ghostfolio/api/interceptors/transform-data-source-in-response.interceptor'; import { ConfigurationService } from '@ghostfolio/api/services/configuration.service'; import { ImportResponse } from '@ghostfolio/common/interfaces'; import type { RequestWithUser } from '@ghostfolio/common/types'; import { Body, Controller, + Get, HttpException, Inject, Logger, + Param, Post, Query, - UseGuards + UseGuards, + UseInterceptors } from '@nestjs/common'; import { REQUEST } from '@nestjs/core'; import { AuthGuard } from '@nestjs/passport'; +import { DataSource } from '@prisma/client'; import { StatusCodes, getReasonPhrase } from 'http-status-codes'; +import { isEmpty } from 'lodash'; import { ImportDataDto } from './import-data.dto'; import { ImportService } from './import.service'; @@ -74,4 +81,27 @@ export class ImportController { ); } } + + @Get('dividends/:dataSource/:symbol') + @UseGuards(AuthGuard('jwt')) + @UseInterceptors(TransformDataSourceInRequestInterceptor) + @UseInterceptors(TransformDataSourceInResponseInterceptor) + public async gatherDividends( + @Param('dataSource') dataSource: DataSource, + @Param('symbol') symbol: string + ): Promise { + const result = await this.importService.getDividends({ + dataSource, + symbol + }); + + if (!result || isEmpty(result)) { + throw new HttpException( + getReasonPhrase(StatusCodes.NOT_FOUND), + StatusCodes.NOT_FOUND + ); + } + + return result; + } } diff --git a/apps/api/src/app/import/import.module.ts b/apps/api/src/app/import/import.module.ts index 64b3a79f3..9d704a880 100644 --- a/apps/api/src/app/import/import.module.ts +++ b/apps/api/src/app/import/import.module.ts @@ -7,6 +7,7 @@ import { DataGatheringModule } from '@ghostfolio/api/services/data-gathering.mod import { DataProviderModule } from '@ghostfolio/api/services/data-provider/data-provider.module'; import { ExchangeRateDataModule } from '@ghostfolio/api/services/exchange-rate-data.module'; import { PrismaModule } from '@ghostfolio/api/services/prisma.module'; +import { SymbolProfileModule } from '@ghostfolio/api/services/symbol-profile.module'; import { Module } from '@nestjs/common'; import { ImportController } from './import.controller'; @@ -23,7 +24,8 @@ import { ImportService } from './import.service'; ExchangeRateDataModule, OrderModule, PrismaModule, - RedisCacheModule + RedisCacheModule, + SymbolProfileModule ], providers: [ImportService] }) diff --git a/apps/api/src/app/import/import.service.ts b/apps/api/src/app/import/import.service.ts index 78e857e7f..422e985f8 100644 --- a/apps/api/src/app/import/import.service.ts +++ b/apps/api/src/app/import/import.service.ts @@ -4,11 +4,14 @@ import { Activity } from '@ghostfolio/api/app/order/interfaces/activities.interf import { OrderService } from '@ghostfolio/api/app/order/order.service'; import { DataProviderService } from '@ghostfolio/api/services/data-provider/data-provider.service'; import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data.service'; +import { SymbolProfileService } from '@ghostfolio/api/services/symbol-profile.service'; +import { parseDate } from '@ghostfolio/common/helper'; +import { ImportResponse, UniqueAsset } from '@ghostfolio/common/interfaces'; import { OrderWithAccount } from '@ghostfolio/common/types'; import { Injectable } from '@nestjs/common'; import { SymbolProfile } from '@prisma/client'; import Big from 'big.js'; -import { endOfToday, isAfter, isSameDay, parseISO } from 'date-fns'; +import { endOfToday, isAfter, isSameDay, parseISO, subYears } from 'date-fns'; import { v4 as uuidv4 } from 'uuid'; @Injectable() @@ -17,9 +20,64 @@ export class ImportService { private readonly accountService: AccountService, private readonly dataProviderService: DataProviderService, private readonly exchangeRateDataService: ExchangeRateDataService, - private readonly orderService: OrderService + private readonly orderService: OrderService, + private readonly symbolProfileService: SymbolProfileService ) {} + public async getDividends({ + dataSource, + symbol + }: UniqueAsset): Promise { + try { + const date = new Date(); + + const [[assetProfile], historicalData] = await Promise.all([ + this.symbolProfileService.getSymbolProfiles([ + { + dataSource, + symbol + } + ]), + await this.dataProviderService.getDividends({ + dataSource, + symbol, + from: subYears(date, 5), + granularity: 'day', + to: date + }) + ]); + + return { + activities: Object.entries(historicalData).map( + ([dateString, historicalDataItem]) => { + return { + accountId: undefined, + accountUserId: undefined, + comment: undefined, + createdAt: undefined, + date: parseDate(dateString), + fee: 0, + feeInBaseCurrency: 0, + id: assetProfile.id, + isDraft: false, + quantity: 0, + SymbolProfile: (assetProfile), + symbolProfileId: undefined, + type: 'DIVIDEND', + unitPrice: historicalDataItem.marketPrice, + updatedAt: undefined, + userId: undefined, + value: 0, + valueInBaseCurrency: 0 + }; + } + ) + }; + } catch { + return { activities: [] }; + } + } + public async import({ activitiesDto, isDryRun = false, diff --git a/apps/api/src/app/symbol/symbol.controller.ts b/apps/api/src/app/symbol/symbol.controller.ts index c9fcc588a..45581bd00 100644 --- a/apps/api/src/app/symbol/symbol.controller.ts +++ b/apps/api/src/app/symbol/symbol.controller.ts @@ -76,29 +76,6 @@ export class SymbolController { return result; } - @Get(':dataSource/:symbol/dividends') - @UseGuards(AuthGuard('jwt')) - @UseInterceptors(TransformDataSourceInRequestInterceptor) - @UseInterceptors(TransformDataSourceInResponseInterceptor) - public async gatherDividends( - @Param('dataSource') dataSource: DataSource, - @Param('symbol') symbol: string - ): Promise { - const result = await this.symbolService.getDividends({ - dataSource, - symbol - }); - - if (!result || isEmpty(result)) { - throw new HttpException( - getReasonPhrase(StatusCodes.NOT_FOUND), - StatusCodes.NOT_FOUND - ); - } - - return result; - } - @Get(':dataSource/:symbol/:dateString') @UseGuards(AuthGuard('jwt')) public async gatherSymbolForDate( diff --git a/apps/api/src/app/symbol/symbol.module.ts b/apps/api/src/app/symbol/symbol.module.ts index cea88bde2..2b47334a6 100644 --- a/apps/api/src/app/symbol/symbol.module.ts +++ b/apps/api/src/app/symbol/symbol.module.ts @@ -2,7 +2,6 @@ import { ConfigurationModule } from '@ghostfolio/api/services/configuration.modu import { DataProviderModule } from '@ghostfolio/api/services/data-provider/data-provider.module'; import { MarketDataModule } from '@ghostfolio/api/services/market-data.module'; import { PrismaModule } from '@ghostfolio/api/services/prisma.module'; -import { SymbolProfileModule } from '@ghostfolio/api/services/symbol-profile.module'; import { Module } from '@nestjs/common'; import { SymbolController } from './symbol.controller'; @@ -15,8 +14,7 @@ import { SymbolService } from './symbol.service'; ConfigurationModule, DataProviderModule, MarketDataModule, - PrismaModule, - SymbolProfileModule + PrismaModule ], providers: [SymbolService] }) diff --git a/apps/api/src/app/symbol/symbol.service.ts b/apps/api/src/app/symbol/symbol.service.ts index 9b5311c8d..89300ecd6 100644 --- a/apps/api/src/app/symbol/symbol.service.ts +++ b/apps/api/src/app/symbol/symbol.service.ts @@ -4,15 +4,13 @@ import { IDataProviderHistoricalResponse } from '@ghostfolio/api/services/interfaces/interfaces'; import { MarketDataService } from '@ghostfolio/api/services/market-data.service'; -import { SymbolProfileService } from '@ghostfolio/api/services/symbol-profile.service'; -import { DATE_FORMAT, parseDate } from '@ghostfolio/common/helper'; +import { DATE_FORMAT } from '@ghostfolio/common/helper'; import { HistoricalDataItem, ImportResponse } from '@ghostfolio/common/interfaces'; import { Injectable, Logger } from '@nestjs/common'; -import { SymbolProfile } from '@prisma/client'; -import { format, subDays, subYears } from 'date-fns'; +import { format, subDays } from 'date-fns'; import { LookupItem } from './interfaces/lookup-item.interface'; import { SymbolItem } from './interfaces/symbol-item.interface'; @@ -21,8 +19,7 @@ import { SymbolItem } from './interfaces/symbol-item.interface'; export class SymbolService { public constructor( private readonly dataProviderService: DataProviderService, - private readonly marketDataService: MarketDataService, - private readonly symbolProfileService: SymbolProfileService + private readonly marketDataService: MarketDataService ) {} public async get({ @@ -68,60 +65,6 @@ export class SymbolService { return undefined; } - public async getDividends({ - dataSource, - symbol - }: IDataGatheringItem): Promise { - try { - const date = new Date(); - - const [[assetProfile], historicalData] = await Promise.all([ - this.symbolProfileService.getSymbolProfiles([ - { - dataSource, - symbol - } - ]), - await this.dataProviderService.getDividends({ - dataSource, - symbol, - from: subYears(date, 5), - granularity: 'day', - to: date - }) - ]); - - return { - activities: Object.entries(historicalData).map( - ([dateString, historicalDataItem]) => { - return { - accountId: undefined, - accountUserId: undefined, - comment: undefined, - createdAt: undefined, - date: parseDate(dateString), - fee: 0, - feeInBaseCurrency: 0, - id: assetProfile.id, - isDraft: false, - quantity: 0, - SymbolProfile: (assetProfile), - symbolProfileId: undefined, - type: 'DIVIDEND', - unitPrice: historicalDataItem.marketPrice, - updatedAt: undefined, - userId: undefined, - value: 0, - valueInBaseCurrency: 0 - }; - } - ) - }; - } catch { - return { activities: [] }; - } - } - public async getForDate({ dataSource, date = new Date(), diff --git a/apps/client/src/app/services/data.service.ts b/apps/client/src/app/services/data.service.ts index b6cfbc29a..67a3e18cf 100644 --- a/apps/client/src/app/services/data.service.ts +++ b/apps/client/src/app/services/data.service.ts @@ -122,7 +122,7 @@ export class DataService { public fetchDividendsImport({ dataSource, symbol }: UniqueAsset) { return this.http.get( - `/api/v1/symbol/${dataSource}/${symbol}/dividends` + `/api/v1/import/dividends/${dataSource}/${symbol}` ); }