From 4813330da587ff29939152b7b5d62bf5bf4bf1a0 Mon Sep 17 00:00:00 2001 From: Thomas <4159106+dtslvr@users.noreply.github.com> Date: Sun, 26 Jun 2022 21:50:57 +0200 Subject: [PATCH] Refactor get account by id endpoint --- .../api/src/app/account/account.controller.ts | 51 ++++++++++++++++--- .../src/app/portfolio/portfolio.service.ts | 29 ++++++++--- apps/client/src/app/services/data.service.ts | 10 +--- 3 files changed, 68 insertions(+), 22 deletions(-) diff --git a/apps/api/src/app/account/account.controller.ts b/apps/api/src/app/account/account.controller.ts index 819fc5a0d..524e36f5a 100644 --- a/apps/api/src/app/account/account.controller.ts +++ b/apps/api/src/app/account/account.controller.ts @@ -7,7 +7,10 @@ import { import { ImpersonationService } from '@ghostfolio/api/services/impersonation.service'; import { Accounts } from '@ghostfolio/common/interfaces'; import { hasPermission, permissions } from '@ghostfolio/common/permissions'; -import type { RequestWithUser } from '@ghostfolio/common/types'; +import type { + AccountWithValue, + RequestWithUser +} from '@ghostfolio/common/types'; import { Body, Controller, @@ -123,13 +126,45 @@ export class AccountController { @Get(':id') @UseGuards(AuthGuard('jwt')) - public async getAccountById(@Param('id') id: string): Promise { - return this.accountService.account({ - id_userId: { - id, - userId: this.request.user.id - } - }); + public async getAccountById( + @Headers('impersonation-id') impersonationId, + @Param('id') id: string + ): Promise { + const impersonationUserId = + await this.impersonationService.validateImpersonationId( + impersonationId, + this.request.user.id + ); + + let accountsWithAggregations = + await this.portfolioService.getAccountsWithAggregations( + impersonationUserId || this.request.user.id, + [{ id, type: 'ACCOUNT' }] + ); + + if ( + impersonationUserId || + this.userService.isRestrictedView(this.request.user) + ) { + accountsWithAggregations = { + ...nullifyValuesInObject(accountsWithAggregations, [ + 'totalBalanceInBaseCurrency', + 'totalValueInBaseCurrency' + ]), + accounts: nullifyValuesInObjects(accountsWithAggregations.accounts, [ + 'balance', + 'balanceInBaseCurrency', + 'convertedBalance', + 'fee', + 'quantity', + 'unitPrice', + 'value', + 'valueInBaseCurrency' + ]) + }; + } + + return accountsWithAggregations.accounts[0]; } @Post() diff --git a/apps/api/src/app/portfolio/portfolio.service.ts b/apps/api/src/app/portfolio/portfolio.service.ts index b7f9248b4..ab32c8486 100644 --- a/apps/api/src/app/portfolio/portfolio.service.ts +++ b/apps/api/src/app/portfolio/portfolio.service.ts @@ -50,6 +50,7 @@ import { REQUEST } from '@nestjs/core'; import { AssetClass, DataSource, + Prisma, Tag, Type as TypeOfOrder } from '@prisma/client'; @@ -100,14 +101,23 @@ export class PortfolioService { this.baseCurrency = this.configurationService.get('BASE_CURRENCY'); } - public async getAccounts(aUserId: string): Promise { + public async getAccounts( + aUserId: string, + aFilters?: Filter[] + ): Promise { + const where: Prisma.AccountWhereInput = { userId: aUserId }; + + if (aFilters?.[0].id && aFilters?.[0].type === 'ACCOUNT') { + where.id = aFilters[0].id; + } + const [accounts, details] = await Promise.all([ this.accountService.accounts({ + where, include: { Order: true, Platform: true }, - orderBy: { name: 'asc' }, - where: { userId: aUserId } + orderBy: { name: 'asc' } }), - this.getDetails(aUserId, aUserId) + this.getDetails(aUserId, aUserId, undefined, aFilters) ]); const userCurrency = this.request.user.Settings.currency; @@ -145,8 +155,11 @@ export class PortfolioService { }); } - public async getAccountsWithAggregations(aUserId: string): Promise { - const accounts = await this.getAccounts(aUserId); + public async getAccountsWithAggregations( + aUserId: string, + aFilters?: Filter[] + ): Promise { + const accounts = await this.getAccounts(aUserId, aFilters); let totalBalanceInBaseCurrency = new Big(0); let totalValueInBaseCurrency = new Big(0); let transactionCount = 0; @@ -1290,6 +1303,10 @@ export class PortfolioService { if (filters.length === 0) { currentAccounts = await this.accountService.getAccounts(userId); + } else if (filters.length === 1 && filters[0].type === 'ACCOUNT') { + currentAccounts = await this.accountService.accounts({ + where: { id: filters[0].id } + }); } else { const accountIds = uniq( orders.map(({ accountId }) => { diff --git a/apps/client/src/app/services/data.service.ts b/apps/client/src/app/services/data.service.ts index d3d546d04..250fd1f7f 100644 --- a/apps/client/src/app/services/data.service.ts +++ b/apps/client/src/app/services/data.service.ts @@ -33,7 +33,7 @@ import { User } from '@ghostfolio/common/interfaces'; import { filterGlobalPermissions } from '@ghostfolio/common/permissions'; -import { DateRange } from '@ghostfolio/common/types'; +import { AccountWithValue, DateRange } from '@ghostfolio/common/types'; import { DataSource, Order as OrderModel } from '@prisma/client'; import { parseISO } from 'date-fns'; import { cloneDeep, groupBy } from 'lodash'; @@ -60,13 +60,7 @@ export class DataService { } public fetchAccount(aAccountId: string) { - return this.http.get('/api/v1/account').pipe( - map((response) => { - return response.accounts.find((account) => { - return account.id === aAccountId; - }); - }) - ); + return this.http.get(`/api/v1/account/${aAccountId}`); } public fetchAccounts() {