Feature/add support for search query in portfolio position endpoint (#2443)

* Introduce search query filter

* Update changelog
pull/2429/head^2
Thomas Kaul 1 year ago committed by GitHub
parent 2a71cb66de
commit 8236091477
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 support for notes in the activities import
- Added support for a search query in the portfolio position endpoint
- Added the application version to the endpoint `GET api/v1/admin`
- Introduced a carousel component for the testimonial section on the landing page

@ -391,12 +391,14 @@ export class PortfolioController {
@Headers(HEADER_KEY_IMPERSONATION.toLowerCase()) impersonationId: string,
@Query('accounts') filterByAccounts?: string,
@Query('assetClasses') filterByAssetClasses?: string,
@Query('query') filterBySearchQuery?: string,
@Query('range') dateRange: DateRange = 'max',
@Query('tags') filterByTags?: string
): Promise<PortfolioPositions> {
const filters = this.apiService.buildFiltersFromQueryParams({
filterByAccounts,
filterByAssetClasses,
filterBySearchQuery,
filterByTags
});

@ -1014,6 +1014,9 @@ export class PortfolioService {
filters?: Filter[];
impersonationId: string;
}): Promise<{ hasErrors: boolean; positions: Position[] }> {
const searchQuery = filters.find(({ type }) => {
return type === 'SEARCH_QUERY';
})?.id;
const userId = await this.getUserId(impersonationId, this.request.user.id);
const { portfolioOrders, transactionPoints } =
@ -1042,9 +1045,9 @@ export class PortfolioService {
const currentPositions =
await portfolioCalculator.getCurrentPositions(startDate);
const positions = currentPositions.positions.filter(
(item) => !item.quantity.eq(0)
);
let positions = currentPositions.positions.filter(({ quantity }) => {
return !quantity.eq(0);
});
const dataGatheringItems = positions.map(({ dataSource, symbol }) => {
return {
@ -1067,6 +1070,17 @@ export class PortfolioService {
symbolProfileMap[symbolProfile.symbol] = symbolProfile;
}
if (searchQuery) {
positions = positions.filter(({ symbol }) => {
const enhancedSymbolProfile = symbolProfileMap[symbol];
return (
enhancedSymbolProfile.isin?.toLowerCase().startsWith(searchQuery) ||
enhancedSymbolProfile.name?.toLowerCase().startsWith(searchQuery)
);
});
}
return {
hasErrors: currentPositions.hasErrors,
positions: positions.map((position) => {

@ -8,14 +8,17 @@ export class ApiService {
public buildFiltersFromQueryParams({
filterByAccounts,
filterByAssetClasses,
filterBySearchQuery,
filterByTags
}: {
filterByAccounts?: string;
filterByAssetClasses?: string;
filterBySearchQuery?: string;
filterByTags?: string;
}): Filter[] {
const accountIds = filterByAccounts?.split(',') ?? [];
const assetClasses = filterByAssetClasses?.split(',') ?? [];
const searchQuery = filterBySearchQuery?.toLowerCase();
const tagIds = filterByTags?.split(',') ?? [];
return [
@ -31,6 +34,10 @@ export class ApiService {
type: 'ASSET_CLASS'
};
}),
{
id: searchQuery,
type: 'SEARCH_QUERY'
},
...tagIds.map((tagId) => {
return <Filter>{
id: tagId,

@ -15,6 +15,7 @@ export interface EnhancedSymbolProfile {
dataSource: DataSource;
dateOfFirstActivity?: Date;
id: string;
isin: string | null;
name: string | null;
scraperConfiguration?: ScraperConfiguration | null;
sectors: Sector[];

@ -6,6 +6,7 @@ export interface Filter {
| 'ASSET_CLASS'
| 'ASSET_SUB_CLASS'
| 'PRESET_ID'
| 'SEARCH_QUERY'
| 'SYMBOL'
| 'TAG';
}

Loading…
Cancel
Save