Feature/support filtering by asset class on the allocations page (#926)

* Support filtering by asset class

* Update changelog
pull/927/head
Thomas Kaul 2 years ago committed by GitHub
parent 4a123c38f2
commit 5cb6e5dec6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
- Added groups to the activities filter component
- Added support for filtering by asset class on the allocations page
## 1.148.0 - 14.05.2022

@ -4,6 +4,7 @@ import { Filter } from '@ghostfolio/common/interfaces';
import { Injectable } from '@nestjs/common';
import { Account, Order, Platform, Prisma } from '@prisma/client';
import Big from 'big.js';
import { groupBy } from 'lodash';
import { CashDetails } from './interfaces/cash-details.interface';
@ -116,15 +117,19 @@ export class AccountService {
const where: Prisma.AccountWhereInput = { userId };
if (filters?.length > 0) {
const {
ACCOUNT: filtersByAccount,
ASSET_CLASS: filtersByAssetClass,
TAG: filtersByTag
} = groupBy(filters, (filter) => {
return filter.type;
});
if (filtersByAccount?.length > 0) {
where.id = {
in: filters
.filter(({ type }) => {
return type === 'ACCOUNT';
})
.map(({ id }) => {
return id;
})
in: filtersByAccount.map(({ id }) => {
return id;
})
};
}

@ -188,12 +188,13 @@ export class OrderService {
}): Promise<Activity[]> {
const where: Prisma.OrderWhereInput = { userId };
const { ACCOUNT: filtersByAccount, TAG: filtersByTag } = groupBy(
filters,
(filter) => {
return filter.type;
}
);
const {
ACCOUNT: filtersByAccount,
ASSET_CLASS: filtersByAssetClass,
TAG: filtersByTag
} = groupBy(filters, (filter) => {
return filter.type;
});
if (filtersByAccount?.length > 0) {
where.accountId = {
@ -207,6 +208,34 @@ export class OrderService {
where.isDraft = false;
}
if (filtersByAssetClass?.length > 0) {
where.SymbolProfile = {
OR: [
{
AND: [
{
OR: filtersByAssetClass.map(({ id }) => {
return { assetClass: AssetClass[id] };
})
},
{
SymbolProfileOverrides: {
is: null
}
}
]
},
{
SymbolProfileOverrides: {
OR: filtersByAssetClass.map(({ id }) => {
return { assetClass: AssetClass[id] };
})
}
}
]
};
}
if (filtersByTag?.length > 0) {
where.tags = {
some: {

@ -107,12 +107,14 @@ export class PortfolioController {
public async getDetails(
@Headers('impersonation-id') impersonationId: string,
@Query('accounts') filterByAccounts?: string,
@Query('assetClasses') filterByAssetClasses?: string,
@Query('range') range?: DateRange,
@Query('tags') filterByTags?: string
): Promise<PortfolioDetails & { hasError: boolean }> {
let hasError = false;
const accountIds = filterByAccounts?.split(',') ?? [];
const assetClasses = filterByAssetClasses?.split(',') ?? [];
const tagIds = filterByTags?.split(',') ?? [];
const filters: Filter[] = [
@ -122,6 +124,12 @@ export class PortfolioController {
type: 'ACCOUNT'
};
}),
...assetClasses.map((assetClass) => {
return <Filter>{
id: assetClass,
type: 'ASSET_CLASS'
};
}),
...tagIds.map((tagId) => {
return <Filter>{
id: tagId,

@ -441,7 +441,12 @@ export class PortfolioService {
};
}
if (aFilters?.length === 0) {
if (
aFilters?.length === 0 ||
(aFilters?.length === 1 &&
aFilters[0].type === 'ASSET_CLASS' &&
aFilters[0].id === 'CASH')
) {
const cashPositions = await this.getCashPositions({
cashDetails,
emergencyFund,

@ -172,6 +172,15 @@ export class AllocationsPageComponent implements OnDestroy, OnInit {
};
});
const assetClassFilters: Filter[] = [];
for (const assetClass of Object.keys(AssetClass)) {
assetClassFilters.push({
id: assetClass,
label: assetClass,
type: 'ASSET_CLASS'
});
}
const tagFilters: Filter[] = this.user.tags.map(({ id, name }) => {
return {
id,
@ -180,7 +189,11 @@ export class AllocationsPageComponent implements OnDestroy, OnInit {
};
});
this.allFilters = [...accountFilters, ...tagFilters];
this.allFilters = [
...accountFilters,
...assetClassFilters,
...tagFilters
];
this.changeDetectorRef.markForCheck();
}

@ -187,12 +187,13 @@ export class DataService {
let params = new HttpParams();
if (filters?.length > 0) {
const { ACCOUNT: filtersByAccount, TAG: filtersByTag } = groupBy(
filters,
(filter) => {
return filter.type;
}
);
const {
ACCOUNT: filtersByAccount,
ASSET_CLASS: filtersByAssetClass,
TAG: filtersByTag
} = groupBy(filters, (filter) => {
return filter.type;
});
if (filtersByAccount) {
params = params.append(
@ -205,6 +206,17 @@ export class DataService {
);
}
if (filtersByAssetClass) {
params = params.append(
'assetClasses',
filtersByAssetClass
.map(({ id }) => {
return id;
})
.join(',')
);
}
if (filtersByTag) {
params = params.append(
'tags',

@ -1,5 +1,5 @@
export interface Filter {
id: string;
label?: string;
type: 'ACCOUNT' | 'SYMBOL' | 'TAG';
type: 'ACCOUNT' | 'ASSET_CLASS' | 'SYMBOL' | 'TAG';
}

Loading…
Cancel
Save