Browse Source

Support account platforms in activities import

pull/7515/head
Thomas Kaul 4 weeks ago
parent
commit
e2dfc96fb1
  1. 7
      apps/api/src/app/import/import-data.dto.ts
  2. 1
      apps/api/src/app/import/import.controller.ts
  3. 39
      apps/api/src/app/import/import.service.ts
  4. 5
      apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts
  5. 8
      apps/client/src/app/services/import-activities.service.ts
  6. 6
      libs/common/src/lib/dtos/create-platform.dto.ts

7
apps/api/src/app/import/import-data.dto.ts

@ -2,6 +2,7 @@ import {
CreateAccountWithBalancesDto,
CreateAssetProfileWithMarketDataDto,
CreateOrderDto,
CreatePlatformDto,
CreateTagDto
} from '@ghostfolio/common/dtos';
@ -26,6 +27,12 @@ export class ImportDataDto {
@ValidateNested({ each: true })
assetProfiles?: CreateAssetProfileWithMarketDataDto[];
@IsArray()
@IsOptional()
@Type(() => CreatePlatformDto)
@ValidateNested({ each: true })
platforms?: CreatePlatformDto[];
@IsArray()
@IsOptional()
@Type(() => CreateTagDto)

1
apps/api/src/app/import/import.controller.ts

@ -77,6 +77,7 @@ export class ImportController {
accountsWithBalancesDto: importData.accounts ?? [],
activitiesDto: importData.activities,
assetProfilesWithMarketDataDto: importData.assetProfiles ?? [],
platformsDto: importData.platforms ?? [],
tagsDto: importData.tags ?? [],
user: this.request.user
});

39
apps/api/src/app/import/import.service.ts

@ -177,6 +177,7 @@ export class ImportService {
assetProfilesWithMarketDataDto,
isDryRun = false,
maxActivitiesToImport,
platformsDto,
tagsDto,
user
}: {
@ -185,14 +186,49 @@ export class ImportService {
assetProfilesWithMarketDataDto: ImportDataDto['assetProfiles'];
isDryRun?: boolean;
maxActivitiesToImport: number;
platformsDto: ImportDataDto['platforms'];
tagsDto: ImportDataDto['tags'];
user: UserWithSettings;
}): Promise<Activity[]> {
const accountIdMapping: { [oldAccountId: string]: string } = {};
const assetProfileSymbolMapping: { [oldSymbol: string]: string } = {};
const platformIdMapping: { [oldPlatformId: string]: string } = {};
const tagIdMapping: { [oldTagId: string]: string } = {};
const userCurrency = user.settings.settings.baseCurrency;
if (platformsDto?.length) {
const canCreatePlatform = hasPermission(
user.permissions,
permissions.createPlatform
);
const existingPlatforms = await this.platformService.getPlatforms();
for (const platform of platformsDto) {
// Check if there is any existing platform with the same ID or URL
const existingPlatform = existingPlatforms.find(({ id, url }) => {
return id === platform.id || url === platform.url;
});
if (existingPlatform) {
// Store the new to old platform ID mappings for creating accounts
if (platform.id && existingPlatform.id !== platform.id) {
platformIdMapping[platform.id] = existingPlatform.id;
}
} else {
if (!canCreatePlatform) {
throw new Error(
`Insufficient permissions to create platform ("${platform.name}")`
);
}
if (!isDryRun) {
await this.platformService.createPlatform(platform);
}
}
}
}
const existingTagsOfUser =
tagsDto?.length || (!isDryRun && accountsWithBalancesDto?.length)
? await this.tagService.getTagsForUser(user.id)
@ -282,7 +318,8 @@ export class ImportService {
]);
let oldAccountId: string;
const platformId = account.platformId;
const platformId =
platformIdMapping[account.platformId] ?? account.platformId;
delete account.platformId;

5
apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts

@ -4,6 +4,7 @@ import { DEFAULT_DATE_RANGE } from '@ghostfolio/common/config';
import {
CreateAccountWithBalancesDto,
CreateAssetProfileWithMarketDataDto,
CreatePlatformDto,
CreateTagDto
} from '@ghostfolio/common/dtos';
import { Activity, PortfolioPosition } from '@ghostfolio/common/interfaces';
@ -107,6 +108,7 @@ export class GfImportActivitiesDialogComponent {
private accounts: CreateAccountWithBalancesDto[] = [];
private activities: Activity[] = [];
private assetProfiles: CreateAssetProfileWithMarketDataDto[] = [];
private platforms: CreatePlatformDto[] = [];
private tags: CreateTagDto[] = [];
private readonly changeDetectorRef = inject(ChangeDetectorRef);
@ -173,6 +175,7 @@ export class GfImportActivitiesDialogComponent {
accounts: this.accounts,
activities: this.selectedActivities,
assetProfiles: this.assetProfiles,
platforms: this.platforms,
tags: this.tags
});
@ -304,6 +307,7 @@ export class GfImportActivitiesDialogComponent {
this.accounts = content.accounts;
this.assetProfiles = content.assetProfiles;
this.platforms = content.platforms;
this.tags = content.tags;
if (!isArray(content.activities)) {
@ -337,6 +341,7 @@ export class GfImportActivitiesDialogComponent {
activities: content.activities,
assetProfiles: content.assetProfiles,
isDryRun: true,
platforms: content.platforms,
tags: content.tags
});

8
apps/client/src/app/services/import-activities.service.ts

@ -2,6 +2,7 @@ import {
CreateAccountWithBalancesDto,
CreateAssetProfileWithMarketDataDto,
CreateOrderDto,
CreatePlatformDto,
CreateTagDto
} from '@ghostfolio/common/dtos';
import { parseDate as parseDateHelper } from '@ghostfolio/common/helper';
@ -115,12 +116,14 @@ export class ImportActivitiesService {
activities,
assetProfiles,
isDryRun = false,
platforms,
tags
}: {
activities: CreateOrderDto[];
accounts?: CreateAccountWithBalancesDto[];
assetProfiles?: CreateAssetProfileWithMarketDataDto[];
isDryRun?: boolean;
platforms?: CreatePlatformDto[];
tags?: CreateTagDto[];
}): Promise<{
activities: Activity[];
@ -131,6 +134,7 @@ export class ImportActivitiesService {
accounts,
activities,
assetProfiles,
platforms,
tags
},
isDryRun
@ -142,11 +146,13 @@ export class ImportActivitiesService {
accounts,
activities,
assetProfiles,
platforms,
tags
}: {
accounts?: CreateAccountWithBalancesDto[];
activities: Activity[];
assetProfiles?: CreateAssetProfileWithMarketDataDto[];
platforms?: CreatePlatformDto[];
tags?: CreateTagDto[];
}): Promise<{
activities: Activity[];
@ -158,6 +164,7 @@ export class ImportActivitiesService {
return this.importJson({
accounts,
assetProfiles,
platforms,
tags,
activities: importData
});
@ -457,6 +464,7 @@ export class ImportActivitiesService {
accounts?: CreateAccountWithBalancesDto[];
activities: CreateOrderDto[];
assetProfiles?: CreateAssetProfileWithMarketDataDto[];
platforms?: CreatePlatformDto[];
tags?: CreateTagDto[];
},
aIsDryRun = false

6
libs/common/src/lib/dtos/create-platform.dto.ts

@ -1,6 +1,10 @@
import { IsString, IsUrl } from 'class-validator';
import { IsOptional, IsString, IsUrl } from 'class-validator';
export class CreatePlatformDto {
@IsOptional()
@IsString()
id?: string;
@IsString()
name: string;

Loading…
Cancel
Save