From 2c9f29a3c6b523d0b9b71bf4cfc9117069cd5740 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sat, 1 Apr 2023 10:51:55 +0200 Subject: [PATCH] Feature/improve handling of platforms in accounts import (#1820) * Improve handling of platforms * Fix issue with pagination * Update changelog --- CHANGELOG.md | 7 +++- apps/api/src/app/import/import.module.ts | 2 + apps/api/src/app/import/import.service.ts | 38 ++++++++++++------- .../src/services/platform/platform.module.ts | 11 ++++++ .../src/services/platform/platform.service.ts | 11 ++++++ .../import-activities-dialog.component.ts | 1 + .../import-activities-dialog.html | 1 + 7 files changed, 56 insertions(+), 15 deletions(-) create mode 100644 apps/api/src/services/platform/platform.module.ts create mode 100644 apps/api/src/services/platform/platform.service.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index e1442d3bf..3834e1cc4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - Improved the portfolio evolution chart (ignore first item) +- Improved the accounts import by handling the platform + +### Fixed + +- Fixed an issue with more than 50 activities in the activities import (`dryRun`) ## 1.249.0 - 2023-03-27 @@ -245,7 +250,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Added support to export accounts -- Added suport to import accounts +- Added support to import accounts ### Changed diff --git a/apps/api/src/app/import/import.module.ts b/apps/api/src/app/import/import.module.ts index b344abff6..6ae073175 100644 --- a/apps/api/src/app/import/import.module.ts +++ b/apps/api/src/app/import/import.module.ts @@ -13,6 +13,7 @@ import { Module } from '@nestjs/common'; import { ImportController } from './import.controller'; import { ImportService } from './import.service'; +import { PlatformModule } from '@ghostfolio/api/services/platform/platform.module'; @Module({ controllers: [ImportController], @@ -24,6 +25,7 @@ import { ImportService } from './import.service'; DataProviderModule, ExchangeRateDataModule, OrderModule, + PlatformModule, PortfolioModule, PrismaModule, RedisCacheModule, diff --git a/apps/api/src/app/import/import.service.ts b/apps/api/src/app/import/import.service.ts index 5b10e381d..57358ee54 100644 --- a/apps/api/src/app/import/import.service.ts +++ b/apps/api/src/app/import/import.service.ts @@ -6,6 +6,7 @@ import { OrderService } from '@ghostfolio/api/app/order/order.service'; import { PortfolioService } from '@ghostfolio/api/app/portfolio/portfolio.service'; import { DataProviderService } from '@ghostfolio/api/services/data-provider/data-provider.service'; import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data.service'; +import { PlatformService } from '@ghostfolio/api/services/platform/platform.service'; import { SymbolProfileService } from '@ghostfolio/api/services/symbol-profile.service'; import { parseDate } from '@ghostfolio/common/helper'; import { UniqueAsset } from '@ghostfolio/common/interfaces'; @@ -14,7 +15,7 @@ import { OrderWithAccount } from '@ghostfolio/common/types'; import { Injectable } from '@nestjs/common'; -import { SymbolProfile } from '@prisma/client'; +import { Prisma, SymbolProfile } from '@prisma/client'; import Big from 'big.js'; import { endOfToday, isAfter, isSameDay, parseISO } from 'date-fns'; import { v4 as uuidv4 } from 'uuid'; @@ -26,6 +27,7 @@ export class ImportService { private readonly dataProviderService: DataProviderService, private readonly exchangeRateDataService: ExchangeRateDataService, private readonly orderService: OrderService, + private readonly platformService: PlatformService, private readonly portfolioService: PortfolioService, private readonly symbolProfileService: SymbolProfileService ) {} @@ -118,15 +120,18 @@ export class ImportService { const accountIdMapping: { [oldAccountId: string]: string } = {}; if (!isDryRun && accountsDto?.length) { - const existingAccounts = await this.accountService.accounts({ - where: { - id: { - in: accountsDto.map(({ id }) => { - return id; - }) + const [existingAccounts, existingPlatforms] = await Promise.all([ + this.accountService.accounts({ + where: { + id: { + in: accountsDto.map(({ id }) => { + return id; + }) + } } - } - }); + }), + this.platformService.get() + ]); for (const account of accountsDto) { // Check if there is any existing account with the same ID @@ -146,19 +151,24 @@ export class ImportService { delete account.id; } - const newAccountObject = { + let accountObject: Prisma.AccountCreateInput = { ...account, User: { connect: { id: userId } } }; - if (platformId) { - Object.assign(newAccountObject, { + if ( + existingPlatforms.some(({ id }) => { + return id === platformId; + }) + ) { + accountObject = { + ...accountObject, Platform: { connect: { id: platformId } } - }); + }; } const newAccount = await this.accountService.createAccount( - newAccountObject, + accountObject, userId ); diff --git a/apps/api/src/services/platform/platform.module.ts b/apps/api/src/services/platform/platform.module.ts new file mode 100644 index 000000000..d6befa986 --- /dev/null +++ b/apps/api/src/services/platform/platform.module.ts @@ -0,0 +1,11 @@ +import { PrismaModule } from '@ghostfolio/api/services/prisma.module'; +import { Module } from '@nestjs/common'; + +import { PlatformService } from './platform.service'; + +@Module({ + exports: [PlatformService], + imports: [PrismaModule], + providers: [PlatformService] +}) +export class PlatformModule {} diff --git a/apps/api/src/services/platform/platform.service.ts b/apps/api/src/services/platform/platform.service.ts new file mode 100644 index 000000000..32d3370fc --- /dev/null +++ b/apps/api/src/services/platform/platform.service.ts @@ -0,0 +1,11 @@ +import { PrismaService } from '@ghostfolio/api/services/prisma.service'; +import { Injectable } from '@nestjs/common'; + +@Injectable() +export class PlatformService { + public constructor(private readonly prismaService: PrismaService) {} + + public async get() { + return this.prismaService.platform.findMany(); + } +} diff --git a/apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts b/apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts index 7bfa9aa37..d89c3a3d6 100644 --- a/apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts +++ b/apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts @@ -35,6 +35,7 @@ export class ImportActivitiesDialog implements OnDestroy { public errorMessages: string[] = []; public holdings: Position[] = []; public isFileSelected = false; + public maxSafeInteger = Number.MAX_SAFE_INTEGER; public mode: 'DIVIDEND'; public selectedActivities: Activity[] = []; public uniqueAssetForm: FormGroup; diff --git a/apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html b/apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html index ec93165c2..7cbea8417 100644 --- a/apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html +++ b/apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html @@ -72,6 +72,7 @@ [hasPermissionToFilter]="false" [hasPermissionToOpenDetails]="false" [locale]="data?.user?.settings?.locale" + [pageSize]="maxSafeInteger" [showActions]="false" [showCheckbox]="true" [showFooter]="false"