From 17b8c416730b6608f79643dce69a0a542bd1efd3 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Thu, 30 Mar 2023 08:24:44 +0200 Subject: [PATCH 1/3] Add test file (#1810) --- test/import/invalid-symbol.csv | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 test/import/invalid-symbol.csv diff --git a/test/import/invalid-symbol.csv b/test/import/invalid-symbol.csv new file mode 100644 index 000000000..fb87b9183 --- /dev/null +++ b/test/import/invalid-symbol.csv @@ -0,0 +1,2 @@ +Date,Code,CCY,Price,Qty,Action,Fee +01/01/2021,,USD,100.0,20,buy,0 From 9bef2e960c419eb592c1c67f382fc7a8e998d432 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sat, 1 Apr 2023 10:29:39 +0200 Subject: [PATCH 2/3] Feature/ignore first item in portfolio evolution chart (#1816) * Ignore first item in portfolio evolution chart * Update changelog --- CHANGELOG.md | 6 ++++ .../analysis/analysis-page.component.ts | 28 +++++++++++-------- 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cbaffbf5d..e1442d3bf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## Unreleased + +### Changed + +- Improved the portfolio evolution chart (ignore first item) + ## 1.249.0 - 2023-03-27 ### Added diff --git a/apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts b/apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts index ae60a5e2a..74371da9d 100644 --- a/apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts +++ b/apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts @@ -308,18 +308,24 @@ export class AnalysisPageComponent implements OnDestroy, OnInit { this.performanceDataItems = []; this.performanceDataItemsInPercentage = []; - for (const { - date, - netPerformanceInPercentage, - totalInvestment, - value, - valueInPercentage - } of chart) { - this.investments.push({ date, investment: totalInvestment }); - this.performanceDataItems.push({ + for (const [ + index, + { date, - value: isNumber(value) ? value : valueInPercentage - }); + netPerformanceInPercentage, + totalInvestment, + value, + valueInPercentage + } + ] of chart.entries()) { + if (index > 0 || this.user?.settings?.dateRange === 'max') { + // Ignore first item where value is 0 + this.investments.push({ date, investment: totalInvestment }); + this.performanceDataItems.push({ + date, + value: isNumber(value) ? value : valueInPercentage + }); + } this.performanceDataItemsInPercentage.push({ date, value: netPerformanceInPercentage 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 3/3] 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"