|
|
@ -3,7 +3,9 @@ import { ActivitiesService } from '@ghostfolio/api/app/activities/activities.ser |
|
|
import { PlatformService } from '@ghostfolio/api/app/platform/platform.service'; |
|
|
import { PlatformService } from '@ghostfolio/api/app/platform/platform.service'; |
|
|
import { PortfolioService } from '@ghostfolio/api/app/portfolio/portfolio.service'; |
|
|
import { PortfolioService } from '@ghostfolio/api/app/portfolio/portfolio.service'; |
|
|
import { getTagsWithDraftTag } from '@ghostfolio/api/helper/activity.helper'; |
|
|
import { getTagsWithDraftTag } from '@ghostfolio/api/helper/activity.helper'; |
|
|
|
|
|
import { getMaskedGhostfolioDataSource } from '@ghostfolio/api/helper/data-source.helper'; |
|
|
import { ApiService } from '@ghostfolio/api/services/api/api.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 { DataProviderService } from '@ghostfolio/api/services/data-provider/data-provider.service'; |
|
|
import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; |
|
|
import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; |
|
|
import { MarketDataService } from '@ghostfolio/api/services/market-data/market-data.service'; |
|
|
import { MarketDataService } from '@ghostfolio/api/services/market-data/market-data.service'; |
|
|
@ -56,6 +58,7 @@ export class ImportService { |
|
|
private readonly accountService: AccountService, |
|
|
private readonly accountService: AccountService, |
|
|
private readonly activitiesService: ActivitiesService, |
|
|
private readonly activitiesService: ActivitiesService, |
|
|
private readonly apiService: ApiService, |
|
|
private readonly apiService: ApiService, |
|
|
|
|
|
private readonly configurationService: ConfigurationService, |
|
|
private readonly dataGatheringService: DataGatheringService, |
|
|
private readonly dataGatheringService: DataGatheringService, |
|
|
private readonly dataProviderService: DataProviderService, |
|
|
private readonly dataProviderService: DataProviderService, |
|
|
private readonly exchangeRateDataService: ExchangeRateDataService, |
|
|
private readonly exchangeRateDataService: ExchangeRateDataService, |
|
|
@ -204,6 +207,9 @@ export class ImportService { |
|
|
}): Promise<Activity[]> { |
|
|
}): Promise<Activity[]> { |
|
|
const accountIdMapping: { [oldAccountId: string]: string } = {}; |
|
|
const accountIdMapping: { [oldAccountId: string]: string } = {}; |
|
|
const assetProfileSymbolMapping: { [oldSymbol: string]: string } = {}; |
|
|
const assetProfileSymbolMapping: { [oldSymbol: string]: string } = {}; |
|
|
|
|
|
const ghostfolioDataSources = this.configurationService.get( |
|
|
|
|
|
'DATA_SOURCES_GHOSTFOLIO_DATA_PROVIDER' |
|
|
|
|
|
); |
|
|
const platformIdMapping: { [oldPlatformId: string]: string } = {}; |
|
|
const platformIdMapping: { [oldPlatformId: string]: string } = {}; |
|
|
const tagIdMapping: { [oldTagId: string]: string } = {}; |
|
|
const tagIdMapping: { [oldTagId: string]: string } = {}; |
|
|
const userCurrency = user.settings.settings.baseCurrency; |
|
|
const userCurrency = user.settings.settings.baseCurrency; |
|
|
@ -224,18 +230,22 @@ export class ImportService { |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// Validate the symbols before any data is persisted. Activities without a
|
|
|
// Validate the symbols before any data is persisted. Activities without an
|
|
|
// data source are excluded, since a symbol is generated in
|
|
|
// explicit data source are excluded from the first check, since a symbol is
|
|
|
// createActivity() if needed.
|
|
|
// generated in createActivity() if needed.
|
|
|
for (const [index, activity] of activitiesDto.entries()) { |
|
|
for (const [index, activity] of activitiesDto.entries()) { |
|
|
if (!activity.dataSource) { |
|
|
const hasDataSource = Boolean(activity.dataSource); |
|
|
if (NON_INVESTMENT_ACTIVITY_TYPES.includes(activity.type)) { |
|
|
|
|
|
activity.dataSource = DataSource.MANUAL; |
|
|
if (!hasDataSource) { |
|
|
} else { |
|
|
activity.dataSource = NON_INVESTMENT_ACTIVITY_TYPES.includes( |
|
|
activity.dataSource = |
|
|
activity.type |
|
|
this.dataProviderService.getDataSourceForImport(); |
|
|
) |
|
|
} |
|
|
? DataSource.MANUAL |
|
|
} else if ( |
|
|
: this.dataProviderService.getDataSourceForImport(); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if ( |
|
|
|
|
|
hasDataSource && |
|
|
activity.dataSource === DataSource.MANUAL && |
|
|
activity.dataSource === DataSource.MANUAL && |
|
|
!isValidCustomAssetProfileSymbol(activity.symbol) |
|
|
!isValidCustomAssetProfileSymbol(activity.symbol) |
|
|
) { |
|
|
) { |
|
|
@ -246,8 +256,13 @@ export class ImportService { |
|
|
activity.dataSource !== DataSource.MANUAL && |
|
|
activity.dataSource !== DataSource.MANUAL && |
|
|
isValidCustomAssetProfileSymbol(activity.symbol) |
|
|
isValidCustomAssetProfileSymbol(activity.symbol) |
|
|
) { |
|
|
) { |
|
|
|
|
|
const maskedDataSource = getMaskedGhostfolioDataSource({ |
|
|
|
|
|
ghostfolioDataSources, |
|
|
|
|
|
dataSource: activity.dataSource |
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
throw new Error( |
|
|
throw new Error( |
|
|
`activities.${index}.symbol ("${activity.symbol}") is not valid for the data source ("${activity.dataSource}")` |
|
|
`activities.${index}.symbol ("${activity.symbol}") is not valid for the data source ("${maskedDataSource}")` |
|
|
); |
|
|
); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|