diff --git a/CHANGELOG.md b/CHANGELOG.md index 28768ce6c..bae78f3b9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed - Fixed the chart tooltip of the benchmark comparator +- Fixed an issue with names in the activities table on the portfolio activities page while using symbol profile overrides ## 2.67.0 - 2024-03-26 diff --git a/apps/api/src/app/import/import.service.ts b/apps/api/src/app/import/import.service.ts index 097cc7f58..f45512318 100644 --- a/apps/api/src/app/import/import.service.ts +++ b/apps/api/src/app/import/import.service.ts @@ -117,7 +117,7 @@ export class ImportService { feeInBaseCurrency: 0, id: assetProfile.id, isDraft: false, - SymbolProfile: (assetProfile), + SymbolProfile: assetProfile, symbolProfileId: assetProfile.id, type: 'DIVIDEND', unitPrice: marketPrice, @@ -521,22 +521,14 @@ export class ImportService { currency, dataSource, symbol, - assetClass: null, - assetSubClass: null, - comment: null, - countries: null, + activitiesCount: undefined, + assetClass: undefined, + assetSubClass: undefined, + countries: undefined, createdAt: undefined, - figi: null, - figiComposite: null, - figiShareClass: null, id: undefined, - isin: null, - name: null, - scraperConfiguration: null, - sectors: null, - symbolMapping: null, - updatedAt: undefined, - url: null + sectors: undefined, + updatedAt: undefined } }; } diff --git a/apps/api/src/app/order/interfaces/activities.interface.ts b/apps/api/src/app/order/interfaces/activities.interface.ts index 7c612d464..b16d10b7d 100644 --- a/apps/api/src/app/order/interfaces/activities.interface.ts +++ b/apps/api/src/app/order/interfaces/activities.interface.ts @@ -1,13 +1,19 @@ -import { OrderWithAccount } from '@ghostfolio/common/types'; +import { EnhancedSymbolProfile } from '@ghostfolio/common/interfaces'; +import { AccountWithPlatform } from '@ghostfolio/common/types'; + +import { Order, Tag } from '@prisma/client'; export interface Activities { activities: Activity[]; count: number; } -export interface Activity extends OrderWithAccount { +export interface Activity extends Order { + Account?: AccountWithPlatform; error?: ActivityError; feeInBaseCurrency: number; + SymbolProfile?: EnhancedSymbolProfile; + tags?: Tag[]; updateAccountBalance?: boolean; value: number; valueInBaseCurrency: number; diff --git a/apps/api/src/app/order/order.service.ts b/apps/api/src/app/order/order.service.ts index 8525878a0..a65e30d53 100644 --- a/apps/api/src/app/order/order.service.ts +++ b/apps/api/src/app/order/order.service.ts @@ -23,7 +23,7 @@ import { } from '@prisma/client'; import { Big } from 'big.js'; import { endOfToday, isAfter } from 'date-fns'; -import { groupBy } from 'lodash'; +import { groupBy, uniqBy } from 'lodash'; import { v4 as uuidv4 } from 'uuid'; import { Activities } from './interfaces/activities.interface'; @@ -320,7 +320,32 @@ export class OrderService { this.prismaService.order.count({ where }) ]); + const uniqueAssets = uniqBy( + orders.map(({ SymbolProfile }) => { + return { + dataSource: SymbolProfile.dataSource, + symbol: SymbolProfile.symbol + }; + }), + ({ dataSource, symbol }) => { + return getAssetProfileIdentifier({ + dataSource, + symbol + }); + } + ); + + const assetProfiles = + await this.symbolProfileService.getSymbolProfiles(uniqueAssets); + const activities = orders.map((order) => { + const assetProfile = assetProfiles.find(({ dataSource, symbol }) => { + return ( + dataSource === order.SymbolProfile.dataSource && + symbol === order.SymbolProfile.symbol + ); + }); + const value = new Big(order.quantity).mul(order.unitPrice).toNumber(); return { @@ -332,6 +357,7 @@ export class OrderService { order.SymbolProfile.currency, userCurrency ), + SymbolProfile: assetProfile, // TODO: Use exchange rate of date valueInBaseCurrency: this.exchangeRateDataService.toCurrency( value, diff --git a/apps/api/src/app/portfolio/interfaces/portfolio-position-detail.interface.ts b/apps/api/src/app/portfolio/interfaces/portfolio-position-detail.interface.ts index 6955785f2..2925ca9bc 100644 --- a/apps/api/src/app/portfolio/interfaces/portfolio-position-detail.interface.ts +++ b/apps/api/src/app/portfolio/interfaces/portfolio-position-detail.interface.ts @@ -1,9 +1,9 @@ +import { Activity } from '@ghostfolio/api/app/order/interfaces/activities.interface'; import { DataProviderInfo, EnhancedSymbolProfile, HistoricalDataItem } from '@ghostfolio/common/interfaces'; -import { OrderWithAccount } from '@ghostfolio/common/types'; import { Account, Tag } from '@prisma/client'; @@ -27,7 +27,7 @@ export interface PortfolioPositionDetail { netPerformancePercent: number; netPerformancePercentWithCurrencyEffect: number; netPerformanceWithCurrencyEffect: number; - orders: OrderWithAccount[]; + orders: Activity[]; quantity: number; SymbolProfile: EnhancedSymbolProfile; tags: Tag[]; diff --git a/apps/api/src/app/portfolio/portfolio.service.ts b/apps/api/src/app/portfolio/portfolio.service.ts index ce5fc998f..f7d780b3d 100644 --- a/apps/api/src/app/portfolio/portfolio.service.ts +++ b/apps/api/src/app/portfolio/portfolio.service.ts @@ -50,7 +50,6 @@ import type { AccountWithValue, DateRange, GroupBy, - OrderWithAccount, RequestWithUser, UserWithSettings } from '@ghostfolio/common/types'; @@ -1592,7 +1591,7 @@ export class PortfolioService { activities, userCurrency }: { - activities: OrderWithAccount[]; + activities: Activity[]; userCurrency: string; }) { return getSum( @@ -1940,7 +1939,7 @@ export class PortfolioService { activityType, userCurrency }: { - activities: OrderWithAccount[]; + activities: Activity[]; activityType: ActivityType; userCurrency: string; }) { diff --git a/apps/client/src/app/components/account-detail-dialog/account-detail-dialog.component.ts b/apps/client/src/app/components/account-detail-dialog/account-detail-dialog.component.ts index 3ce2a261c..537adf1d1 100644 --- a/apps/client/src/app/components/account-detail-dialog/account-detail-dialog.component.ts +++ b/apps/client/src/app/components/account-detail-dialog/account-detail-dialog.component.ts @@ -1,3 +1,4 @@ +import { Activity } from '@ghostfolio/api/app/order/interfaces/activities.interface'; import { DataService } from '@ghostfolio/client/services/data.service'; import { UserService } from '@ghostfolio/client/services/user/user.service'; import { downloadAsFile } from '@ghostfolio/common/helper'; @@ -41,7 +42,7 @@ export class AccountDetailDialog implements OnDestroy, OnInit { public activities: OrderWithAccount[]; public balance: number; public currency: string; - public dataSource: MatTableDataSource; + public dataSource: MatTableDataSource; public equity: number; public hasPermissionToDeleteAccountBalance: boolean; public historicalDataItems: HistoricalDataItem[]; diff --git a/apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.component.ts b/apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.component.ts index 2e3f8f1d3..6ada2eeb1 100644 --- a/apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.component.ts +++ b/apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.component.ts @@ -1,3 +1,4 @@ +import { Activity } from '@ghostfolio/api/app/order/interfaces/activities.interface'; import { DataService } from '@ghostfolio/client/services/data.service'; import { UserService } from '@ghostfolio/client/services/user/user.service'; import { DATE_FORMAT, downloadAsFile } from '@ghostfolio/common/helper'; @@ -7,7 +8,6 @@ import { LineChartItem, User } from '@ghostfolio/common/interfaces'; -import { OrderWithAccount } from '@ghostfolio/common/types'; import { translate } from '@ghostfolio/ui/i18n'; import { @@ -37,7 +37,7 @@ import { PositionDetailDialogParams } from './interfaces/interfaces'; }) export class PositionDetailDialog implements OnDestroy, OnInit { public accounts: Account[]; - public activities: OrderWithAccount[]; + public activities: Activity[]; public assetClass: string; public assetSubClass: string; public averagePrice: number; @@ -46,7 +46,7 @@ export class PositionDetailDialog implements OnDestroy, OnInit { [code: string]: { name: string; value: number }; }; public dataProviderInfo: DataProviderInfo; - public dataSource: MatTableDataSource; + public dataSource: MatTableDataSource; public dividendInBaseCurrency: number; public feeInBaseCurrency: number; public firstBuyDate: string; diff --git a/libs/common/src/lib/interfaces/enhanced-symbol-profile.interface.ts b/libs/common/src/lib/interfaces/enhanced-symbol-profile.interface.ts index 3bf914eaa..e9fe2f658 100644 --- a/libs/common/src/lib/interfaces/enhanced-symbol-profile.interface.ts +++ b/libs/common/src/lib/interfaces/enhanced-symbol-profile.interface.ts @@ -8,16 +8,19 @@ export interface EnhancedSymbolProfile { activitiesCount: number; assetClass: AssetClass; assetSubClass: AssetSubClass; - comment: string | null; + comment?: string; countries: Country[]; createdAt: Date; - currency: string | null; + currency?: string; dataSource: DataSource; dateOfFirstActivity?: Date; id: string; - isin: string | null; - name: string | null; - scraperConfiguration?: ScraperConfiguration | null; + figi?: string; + figiComposite?: string; + figiShareClass?: string; + isin?: string; + name?: string; + scraperConfiguration?: ScraperConfiguration; sectors: Sector[]; symbol: string; symbolMapping?: { [key: string]: string };