diff --git a/apps/api/src/app/import/import.controller.ts b/apps/api/src/app/import/import.controller.ts index 07e017bce..081541fee 100644 --- a/apps/api/src/app/import/import.controller.ts +++ b/apps/api/src/app/import/import.controller.ts @@ -100,7 +100,8 @@ export class ImportController { ): Promise { const activities = await this.importService.getDividends({ dataSource, - symbol + symbol, + userId: this.request.user.id }); return { activities }; diff --git a/apps/api/src/app/import/import.service.ts b/apps/api/src/app/import/import.service.ts index b269dc3fd..a526bf86c 100644 --- a/apps/api/src/app/import/import.service.ts +++ b/apps/api/src/app/import/import.service.ts @@ -48,11 +48,17 @@ export class ImportService { public async getDividends({ dataSource, - symbol - }: AssetProfileIdentifier): Promise { + symbol, + userId + }: AssetProfileIdentifier & { userId: string }): Promise { try { const { activities, firstBuyDate, historicalData } = - await this.portfolioService.getHolding(dataSource, undefined, symbol); + await this.portfolioService.getHolding({ + dataSource, + symbol, + userId, + impersonationId: undefined + }); const [[assetProfile], dividends] = await Promise.all([ this.symbolProfileService.getSymbolProfiles([ diff --git a/apps/api/src/app/portfolio/portfolio.controller.ts b/apps/api/src/app/portfolio/portfolio.controller.ts index 14d356799..0b3d5dd41 100644 --- a/apps/api/src/app/portfolio/portfolio.controller.ts +++ b/apps/api/src/app/portfolio/portfolio.controller.ts @@ -375,11 +375,12 @@ export class PortfolioController { @Param('dataSource') dataSource: DataSource, @Param('symbol') symbol: string ): Promise { - const holding = await this.portfolioService.getHolding( + const holding = await this.portfolioService.getHolding({ dataSource, impersonationId, - symbol - ); + symbol, + userId: this.request.user.id + }); if (!holding) { throw new HttpException( @@ -453,7 +454,8 @@ export class PortfolioController { filters, groupBy, impersonationId, - savingsRate: this.request.user?.Settings?.settings.savingsRate + savingsRate: this.request.user?.Settings?.settings.savingsRate, + userId: this.request.user.id }); if ( @@ -622,11 +624,12 @@ export class PortfolioController { @Param('dataSource') dataSource: DataSource, @Param('symbol') symbol: string ): Promise { - const holding = await this.portfolioService.getHolding( + const holding = await this.portfolioService.getHolding({ dataSource, impersonationId, - symbol - ); + symbol, + userId: this.request.user.id + }); if (!holding) { throw new HttpException( @@ -643,7 +646,10 @@ export class PortfolioController { public async getReport( @Headers(HEADER_KEY_IMPERSONATION.toLowerCase()) impersonationId: string ): Promise { - const report = await this.portfolioService.getReport(impersonationId); + const report = await this.portfolioService.getReport({ + impersonationId, + userId: this.request.user.id + }); if ( this.configurationService.get('ENABLE_FEATURE_SUBSCRIPTION') && @@ -672,11 +678,12 @@ export class PortfolioController { @Param('dataSource') dataSource: DataSource, @Param('symbol') symbol: string ): Promise { - const holding = await this.portfolioService.getHolding( + const holding = await this.portfolioService.getHolding({ dataSource, impersonationId, - symbol - ); + symbol, + userId: this.request.user.id + }); if (!holding) { throw new HttpException( @@ -707,11 +714,12 @@ export class PortfolioController { @Param('dataSource') dataSource: DataSource, @Param('symbol') symbol: string ): Promise { - const holding = await this.portfolioService.getHolding( + const holding = await this.portfolioService.getHolding({ dataSource, impersonationId, - symbol - ); + symbol, + userId: this.request.user.id + }); if (!holding) { throw new HttpException( diff --git a/apps/api/src/app/portfolio/portfolio.service.ts b/apps/api/src/app/portfolio/portfolio.service.ts index ddc81fa4a..b0739f5f9 100644 --- a/apps/api/src/app/portfolio/portfolio.service.ts +++ b/apps/api/src/app/portfolio/portfolio.service.ts @@ -312,15 +312,17 @@ export class PortfolioService { filters, groupBy, impersonationId, - savingsRate + savingsRate, + userId }: { dateRange: DateRange; filters?: Filter[]; groupBy?: GroupBy; impersonationId: string; savingsRate: number; + userId: string; }): Promise { - const userId = await this.getUserId(impersonationId, this.request.user.id); + userId = await this.getUserId(impersonationId, userId); const user = await this.userService.user({ id: userId }); const userCurrency = this.getUserCurrency(user); @@ -676,12 +678,18 @@ export class PortfolioService { }; } - public async getHolding( - aDataSource: DataSource, - aImpersonationId: string, - aSymbol: string - ): Promise { - const userId = await this.getUserId(aImpersonationId, this.request.user.id); + public async getHolding({ + dataSource, + impersonationId, + symbol, + userId + }: { + dataSource: DataSource; + impersonationId: string; + symbol: string; + userId: string; + }): Promise { + userId = await this.getUserId(impersonationId, userId); const user = await this.userService.user({ id: userId }); const userCurrency = this.getUserCurrency(user); @@ -724,7 +732,7 @@ export class PortfolioService { } const [SymbolProfile] = await this.symbolProfileService.getSymbolProfiles([ - { dataSource: aDataSource, symbol: aSymbol } + { dataSource, symbol } ]); const portfolioCalculator = this.calculatorFactory.createCalculator({ @@ -739,26 +747,33 @@ export class PortfolioService { const { positions } = await portfolioCalculator.getSnapshot(); - const position = positions.find(({ dataSource, symbol }) => { - return dataSource === aDataSource && symbol === aSymbol; + const holding = positions.find((position) => { + return position.dataSource === dataSource && position.symbol === symbol; }); - if (position) { + if (holding) { const { averagePrice, currency, - dataSource, dividendInBaseCurrency, fee, firstBuyDate, + grossPerformance, + grossPerformancePercentage, + grossPerformancePercentageWithCurrencyEffect, + grossPerformanceWithCurrencyEffect, + investmentWithCurrencyEffect, marketPrice, + netPerformance, + netPerformancePercentage, + netPerformancePercentageWithCurrencyEffectMap, + netPerformanceWithCurrencyEffectMap, quantity, - symbol, tags, timeWeightedInvestment, timeWeightedInvestmentWithCurrencyEffect, transactionCount - } = position; + } = holding; const activitiesOfHolding = activities.filter(({ SymbolProfile }) => { return ( @@ -787,7 +802,7 @@ export class PortfolioService { }); const historicalData = await this.dataProviderService.getHistorical( - [{ dataSource, symbol: aSymbol }], + [{ dataSource, symbol }], 'day', parseISO(firstBuyDate), new Date() @@ -807,10 +822,10 @@ export class PortfolioService { marketPrice ); - if (historicalData[aSymbol]) { + if (historicalData[symbol]) { let j = -1; for (const [date, { marketPrice }] of Object.entries( - historicalData[aSymbol] + historicalData[symbol] )) { while ( j + 1 < transactionPoints.length && @@ -823,8 +838,8 @@ export class PortfolioService { let currentQuantity = 0; const currentSymbol = transactionPoints[j]?.items.find( - ({ symbol }) => { - return symbol === aSymbol; + (transactionPointSymbol) => { + return transactionPointSymbol.symbol === symbol; } ); @@ -888,24 +903,21 @@ export class PortfolioService { SymbolProfile.currency, userCurrency ), - grossPerformance: position.grossPerformance?.toNumber(), - grossPerformancePercent: - position.grossPerformancePercentage?.toNumber(), + grossPerformance: grossPerformance?.toNumber(), + grossPerformancePercent: grossPerformancePercentage?.toNumber(), grossPerformancePercentWithCurrencyEffect: - position.grossPerformancePercentageWithCurrencyEffect?.toNumber(), + grossPerformancePercentageWithCurrencyEffect?.toNumber(), grossPerformanceWithCurrencyEffect: - position.grossPerformanceWithCurrencyEffect?.toNumber(), + grossPerformanceWithCurrencyEffect?.toNumber(), historicalData: historicalDataArray, investmentInBaseCurrencyWithCurrencyEffect: - position.investmentWithCurrencyEffect?.toNumber(), - netPerformance: position.netPerformance?.toNumber(), - netPerformancePercent: position.netPerformancePercentage?.toNumber(), + investmentWithCurrencyEffect?.toNumber(), + netPerformance: netPerformance?.toNumber(), + netPerformancePercent: netPerformancePercentage?.toNumber(), netPerformancePercentWithCurrencyEffect: - position.netPerformancePercentageWithCurrencyEffectMap?.[ - 'max' - ]?.toNumber(), + netPerformancePercentageWithCurrencyEffectMap?.['max']?.toNumber(), netPerformanceWithCurrencyEffect: - position.netPerformanceWithCurrencyEffectMap?.['max']?.toNumber(), + netPerformanceWithCurrencyEffectMap?.['max']?.toNumber(), performances: { allTimeHigh: { performancePercent, @@ -922,12 +934,12 @@ export class PortfolioService { } else { const currentData = await this.dataProviderService.getQuotes({ user, - items: [{ dataSource: DataSource.YAHOO, symbol: aSymbol }] + items: [{ symbol, dataSource: DataSource.YAHOO }] }); - const marketPrice = currentData[aSymbol]?.marketPrice; + const marketPrice = currentData[symbol]?.marketPrice; let historicalData = await this.dataProviderService.getHistorical( - [{ dataSource: DataSource.YAHOO, symbol: aSymbol }], + [{ symbol, dataSource: DataSource.YAHOO }], 'day', portfolioStart, new Date() @@ -936,15 +948,13 @@ export class PortfolioService { if (isEmpty(historicalData)) { try { historicalData = await this.dataProviderService.getHistoricalRaw({ - assetProfileIdentifiers: [ - { dataSource: DataSource.YAHOO, symbol: aSymbol } - ], + assetProfileIdentifiers: [{ symbol, dataSource: DataSource.YAHOO }], from: portfolioStart, to: new Date() }); } catch { historicalData = { - [aSymbol]: {} + [symbol]: {} }; } } @@ -955,7 +965,7 @@ export class PortfolioService { let marketPriceMin = marketPrice; for (const [date, { marketPrice }] of Object.entries( - historicalData[aSymbol] + historicalData[symbol] )) { historicalDataArray.push({ date, @@ -1116,10 +1126,14 @@ export class PortfolioService { }; } - public async getReport( - impersonationId: string - ): Promise { - const userId = await this.getUserId(impersonationId, this.request.user.id); + public async getReport({ + impersonationId, + userId + }: { + impersonationId: string; + userId: string; + }): Promise { + userId = await this.getUserId(impersonationId, userId); const userSettings = this.request.user.Settings.settings as UserSettings; const { accounts, holdings, markets, marketsAdvanced, summary } =