|
|
|
@ -2,6 +2,7 @@ import { AccountService } from '@ghostfolio/api/app/account/account.service'; |
|
|
|
import { OrderService } from '@ghostfolio/api/app/order/order.service'; |
|
|
|
import { PlatformService } from '@ghostfolio/api/app/platform/platform.service'; |
|
|
|
import { PortfolioService } from '@ghostfolio/api/app/portfolio/portfolio.service'; |
|
|
|
import { ApiService } from '@ghostfolio/api/services/api/api.service'; |
|
|
|
import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service'; |
|
|
|
import { DataProviderService } from '@ghostfolio/api/services/data-provider/data-provider.service'; |
|
|
|
import { MarketDataService } from '@ghostfolio/api/services/market-data/market-data.service'; |
|
|
|
@ -25,7 +26,7 @@ import { |
|
|
|
} from '@ghostfolio/common/interfaces'; |
|
|
|
import { hasPermission, permissions } from '@ghostfolio/common/permissions'; |
|
|
|
import { |
|
|
|
AccountWithPlatform, |
|
|
|
AccountWithValue, |
|
|
|
OrderWithAccount, |
|
|
|
UserWithSettings |
|
|
|
} from '@ghostfolio/common/types'; |
|
|
|
@ -43,6 +44,7 @@ import { ImportDataDto } from './import-data.dto'; |
|
|
|
export class ImportService { |
|
|
|
public constructor( |
|
|
|
private readonly accountService: AccountService, |
|
|
|
private readonly apiService: ApiService, |
|
|
|
private readonly configurationService: ConfigurationService, |
|
|
|
private readonly dataGatheringService: DataGatheringService, |
|
|
|
private readonly dataProviderService: DataProviderService, |
|
|
|
@ -57,8 +59,12 @@ export class ImportService { |
|
|
|
public async getDividends({ |
|
|
|
dataSource, |
|
|
|
symbol, |
|
|
|
userCurrency, |
|
|
|
userId |
|
|
|
}: AssetProfileIdentifier & { userId: string }): Promise<Activity[]> { |
|
|
|
}: AssetProfileIdentifier & { |
|
|
|
userCurrency: string; |
|
|
|
userId: string; |
|
|
|
}): Promise<Activity[]> { |
|
|
|
try { |
|
|
|
const holding = await this.portfolioService.getHolding({ |
|
|
|
dataSource, |
|
|
|
@ -71,36 +77,45 @@ export class ImportService { |
|
|
|
return []; |
|
|
|
} |
|
|
|
|
|
|
|
const { activities, firstBuyDate, historicalData } = holding; |
|
|
|
const filters = this.apiService.buildFiltersFromQueryParams({ |
|
|
|
filterByDataSource: dataSource, |
|
|
|
filterBySymbol: symbol |
|
|
|
}); |
|
|
|
|
|
|
|
const [[assetProfile], dividends] = await Promise.all([ |
|
|
|
this.symbolProfileService.getSymbolProfiles([ |
|
|
|
{ |
|
|
|
dataSource, |
|
|
|
symbol |
|
|
|
} |
|
|
|
]), |
|
|
|
await this.dataProviderService.getDividends({ |
|
|
|
dataSource, |
|
|
|
symbol, |
|
|
|
from: parseDate(firstBuyDate), |
|
|
|
granularity: 'day', |
|
|
|
to: new Date() |
|
|
|
}) |
|
|
|
]); |
|
|
|
const { firstBuyDate, historicalData } = holding; |
|
|
|
|
|
|
|
const accounts = activities |
|
|
|
.filter(({ account }) => { |
|
|
|
return !!account; |
|
|
|
}) |
|
|
|
.map(({ account }) => { |
|
|
|
return account; |
|
|
|
}); |
|
|
|
const [{ accounts }, { activities }, [assetProfile], dividends] = |
|
|
|
await Promise.all([ |
|
|
|
this.portfolioService.getAccountsWithAggregations({ |
|
|
|
filters, |
|
|
|
userId, |
|
|
|
withExcludedAccounts: true |
|
|
|
}), |
|
|
|
this.orderService.getOrders({ |
|
|
|
filters, |
|
|
|
userCurrency, |
|
|
|
userId, |
|
|
|
startDate: parseDate(firstBuyDate) |
|
|
|
}), |
|
|
|
this.symbolProfileService.getSymbolProfiles([ |
|
|
|
{ |
|
|
|
dataSource, |
|
|
|
symbol |
|
|
|
} |
|
|
|
]), |
|
|
|
await this.dataProviderService.getDividends({ |
|
|
|
dataSource, |
|
|
|
symbol, |
|
|
|
from: parseDate(firstBuyDate), |
|
|
|
granularity: 'day', |
|
|
|
to: new Date() |
|
|
|
}) |
|
|
|
]); |
|
|
|
|
|
|
|
const account = this.isUniqueAccount(accounts) ? accounts[0] : undefined; |
|
|
|
|
|
|
|
return await Promise.all( |
|
|
|
Object.entries(dividends).map(async ([dateString, { marketPrice }]) => { |
|
|
|
Object.entries(dividends).map(([dateString, { marketPrice }]) => { |
|
|
|
const quantity = |
|
|
|
historicalData.find((historicalDataItem) => { |
|
|
|
return historicalDataItem.date === dateString; |
|
|
|
@ -695,11 +710,11 @@ export class ImportService { |
|
|
|
); |
|
|
|
} |
|
|
|
|
|
|
|
private isUniqueAccount(accounts: AccountWithPlatform[]) { |
|
|
|
private isUniqueAccount(accounts: AccountWithValue[]) { |
|
|
|
const uniqueAccountIds = new Set<string>(); |
|
|
|
|
|
|
|
for (const account of accounts) { |
|
|
|
uniqueAccountIds.add(account.id); |
|
|
|
for (const { id } of accounts) { |
|
|
|
uniqueAccountIds.add(id); |
|
|
|
} |
|
|
|
|
|
|
|
return uniqueAccountIds.size === 1; |
|
|
|
|