Browse Source

Bugfix/exclude cash positions from portfolio calculations with filters (#7212)

* Fix handling of cash positions with filters

* Update changelog
pull/7215/head
Thomas Kaul 2 weeks ago
committed by GitHub
parent
commit
689778f025
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 1
      CHANGELOG.md
  2. 51
      apps/api/src/app/activities/activities.service.ts

1
CHANGELOG.md

@ -25,6 +25,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Fixed ### Fixed
- Resolved an issue in the treemap chart component when the holdings list is empty - Resolved an issue in the treemap chart component when the holdings list is empty
- Fixed the handling of cash positions in the portfolio calculations when filtering by holding or tag
- Fixed the market condition of the benchmarks in the twitter bot service when values round to zero - Fixed the market condition of the benchmarks in the twitter bot service when values round to zero
## 3.19.1 - 2026-07-03 ## 3.19.1 - 2026-07-03

51
apps/api/src/app/activities/activities.service.ts

@ -393,17 +393,7 @@ export class ActivitiesService {
userCurrency: string; userCurrency: string;
userId: string; userId: string;
}): Promise<ActivitiesResponse> { }): Promise<ActivitiesResponse> {
const filtersByAssetClass = filters.filter(({ type }) => { if (this.hasNonMatchingFiltersForCashActivities(filters)) {
return type === 'ASSET_CLASS';
});
if (
filtersByAssetClass.length > 0 &&
!filtersByAssetClass.find(({ id }) => {
return id === AssetClass.LIQUIDITY;
})
) {
// If asset class filters are present and none of them is liquidity, return an empty response
return { return {
activities: [], activities: [],
count: 0 count: 0
@ -810,7 +800,7 @@ export class ActivitiesService {
withExcludedAccountsAndActivities: false // TODO withExcludedAccountsAndActivities: false // TODO
}); });
if (withCash) { if (withCash && !this.hasNonMatchingFiltersForCashActivities(filters)) {
const cashDetails = await this.accountService.getCashDetails({ const cashDetails = await this.accountService.getCashDetails({
filters, filters,
userId, userId,
@ -945,6 +935,43 @@ export class ActivitiesService {
return activity; return activity;
} }
private hasNonMatchingFiltersForCashActivities(filters: Filter[] = []) {
const {
ASSET_CLASS: filtersByAssetClass = [],
DATA_SOURCE: [filterByDataSource] = [],
SYMBOL: [filterBySymbol] = [],
TAG: filtersByTag = []
} = groupBy(filters, ({ type }) => {
return type;
});
const isFilteredByAssetClassOtherThanLiquidity =
filtersByAssetClass.length > 0 &&
!filtersByAssetClass.some(({ id }) => {
return id === AssetClass.LIQUIDITY;
});
const isFilteredByAssetProfile = !!(filterByDataSource || filterBySymbol);
const isFilteredByTag = filtersByTag.length > 0;
const isFilteredByUnsupportedType = filters.some(({ type }) => {
return ![
'ACCOUNT',
'ASSET_CLASS',
'DATA_SOURCE',
'SYMBOL',
'TAG'
].includes(type);
});
return (
isFilteredByAssetClassOtherThanLiquidity ||
isFilteredByAssetProfile ||
isFilteredByTag ||
isFilteredByUnsupportedType
);
}
private async orders(params: { private async orders(params: {
include?: Prisma.OrderInclude; include?: Prisma.OrderInclude;
skip?: number; skip?: number;

Loading…
Cancel
Save