diff --git a/CHANGELOG.md b/CHANGELOG.md index 736c708e2..597829790 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,6 +28,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Handled an exception in the country weightings parsing of the _Financial Modeling Prep_ service +### Fixed + +- Fixed the allocation percentages in the accounts section of the holding detail dialog by excluding the cash balances + ## 3.42.0 - 2026-08-04 ### Changed diff --git a/apps/api/src/app/portfolio/portfolio.service.spec.ts b/apps/api/src/app/portfolio/portfolio.service.spec.ts index 97635553f..20d7c4c9d 100644 --- a/apps/api/src/app/portfolio/portfolio.service.spec.ts +++ b/apps/api/src/app/portfolio/portfolio.service.spec.ts @@ -509,5 +509,36 @@ describe('PortfolioService', () => { expect(accounts[UNKNOWN_KEY]).toBeUndefined(); expect(platforms[UNKNOWN_KEY]).toBeUndefined(); }); + + it('should exclude the cash balance when filtering by a holding', async () => { + jest + .spyOn(accountService, 'accounts') + .mockResolvedValue([account] as unknown as Account[]); + + const { accounts, platforms } = await getValueOfAccountsAndPlatforms({ + activities: [ + { + account, + accountId: account.id, + assetProfile: { symbol: 'AAPL' }, + quantity: 1, + type: 'BUY' + } + ], + filters: [ + { id: DataSource.YAHOO, type: 'DATA_SOURCE' }, + { id: 'AAPL', type: 'SYMBOL' } + ], + portfolioItemsNow: { + AAPL: { marketPriceInBaseCurrency: 10 } + }, + userCurrency: 'USD', + userId: userDummyData.id + }); + + // 1 * 10 (activity), without the balance of 100 + expect(accounts[account.id].valueInBaseCurrency).toBe(10); + expect(platforms[account.platformId].valueInBaseCurrency).toBe(10); + }); }); }); diff --git a/apps/api/src/app/portfolio/portfolio.service.ts b/apps/api/src/app/portfolio/portfolio.service.ts index 70106bdc1..784749505 100644 --- a/apps/api/src/app/portfolio/portfolio.service.ts +++ b/apps/api/src/app/portfolio/portfolio.service.ts @@ -2142,6 +2142,15 @@ export class PortfolioService { const accounts: PortfolioDetails['accounts'] = {}; const platforms: PortfolioDetails['platforms'] = {}; + const { + DATA_SOURCE: [filterByDataSource] = [], + SYMBOL: [filterBySymbol] = [] + } = groupBy(filters, ({ type }) => { + return type; + }); + + const isFilteredByHolding = !!(filterByDataSource && filterBySymbol); + let currentAccounts: (Account & { Order?: Order[]; platform?: Platform; @@ -2185,7 +2194,9 @@ export class PortfolioService { return account ? accountId === account.id : !accountId; }); - if (account) { + // Skip the cash balance if the request is filtered by a holding, so that + // the values of the accounts and platforms reflect this holding only + if (account && !isFilteredByHolding) { accounts[account.id] = { balance: account.balance, currency: account.currency,