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 0208244a7..a014f608d 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 @@ -25,11 +25,11 @@ import { ImportActivitiesDialogParams } from './interfaces/interfaces'; templateUrl: 'import-activities-dialog.html' }) export class ImportActivitiesDialog implements OnDestroy { - public activities: Activity[] | CreateOrderDto[] = []; + public activities: Activity[] = []; public details: any[] = []; public errorMessages: string[] = []; public importComplete = false; - public selectedActivities: CreateOrderDto[] = []; + public selectedActivities: Activity[] = []; private unsubscribeSubject = new Subject(); @@ -89,7 +89,8 @@ export class ImportActivitiesDialog implements OnDestroy { try { await this.importActivitiesService.importJson({ - content: content.activities + content: content.activities, + dryRun: true }); this.handleImportSuccess(); @@ -103,7 +104,8 @@ export class ImportActivitiesDialog implements OnDestroy { try { this.activities = await this.importActivitiesService.importCsv({ fileContent, - userAccounts: this.data.user.accounts + userAccounts: this.data.user.accounts, + dryRun: true }); this.snackBar.dismiss(); @@ -140,10 +142,10 @@ export class ImportActivitiesDialog implements OnDestroy { } public async finalImport() { - // this.importJson({ content: activities }) - await this.importActivitiesService.importJson({ - content: this.selectedActivities - }); + await this.importActivitiesService.importSelectedActivities( + this.selectedActivities + ); + this.snackBar.open( '✅ ' + $localize`Import has been completed`, undefined, diff --git a/apps/client/src/app/services/import-activities.service.ts b/apps/client/src/app/services/import-activities.service.ts index ad374aa61..da120217b 100644 --- a/apps/client/src/app/services/import-activities.service.ts +++ b/apps/client/src/app/services/import-activities.service.ts @@ -1,6 +1,7 @@ import { HttpClient } from '@angular/common/http'; import { Injectable } from '@angular/core'; import { CreateOrderDto } from '@ghostfolio/api/app/order/create-order.dto'; +import { Activity } from '@ghostfolio/api/app/order/interfaces/activities.interface'; import { Account, DataSource, Type } from '@prisma/client'; import { isMatch, parse, parseISO } from 'date-fns'; import { isFinite } from 'lodash'; @@ -26,11 +27,13 @@ export class ImportActivitiesService { public async importCsv({ fileContent, - userAccounts + userAccounts, + dryRun = false }: { fileContent: string; userAccounts: Account[]; - }) { + dryRun?: boolean; + }): Promise { const content = csvToJson(fileContent, { dynamicTyping: true, header: true, @@ -52,16 +55,23 @@ export class ImportActivitiesService { }); } - return activities; - - // await this.importJson({ content: activities }); + return await this.importJson({ content: activities, dryRun }); } - public importJson({ content }: { content: CreateOrderDto[] }): Promise { + public importJson({ + content, + dryRun = false + }: { + content: CreateOrderDto[]; + dryRun?: boolean; + }): Promise { return new Promise((resolve, reject) => { - this.postImport({ - activities: content - }) + this.postImport( + { + activities: content + }, + dryRun + ) .pipe( catchError((error) => { reject(error); @@ -69,13 +79,32 @@ export class ImportActivitiesService { }) ) .subscribe({ - next: () => { - resolve(); + next: (importedActivities) => { + resolve(importedActivities.activities); } }); }); } + public importSelectedActivities( + selectedActivities: Activity[] + ): Promise { + const importData: CreateOrderDto[] = []; + for (const activity of selectedActivities) { + importData.push({ + currency: activity.SymbolProfile.currency, + date: activity.date.toString(), + fee: activity.fee, + quantity: activity.quantity, + symbol: activity.SymbolProfile.symbol, + type: activity.type, + unitPrice: activity.unitPrice + }); + } + + return this.importJson({ content: importData }); + } + private lowercaseKeys(aObject: any) { return Object.keys(aObject).reduce((acc, key) => { acc[key.toLowerCase()] = aObject[key]; @@ -303,7 +332,13 @@ export class ImportActivitiesService { }; } - private postImport(aImportData: { activities: CreateOrderDto[] }) { - return this.http.post('/api/v1/import', aImportData); + private postImport( + aImportData: { activities: CreateOrderDto[] }, + dryRun = false + ) { + return this.http.post<{ activities: Activity[] }>( + `/api/v1/import?dryRun=${dryRun}`, + aImportData + ); } } diff --git a/libs/ui/src/lib/activities-table/activities-table.component.html b/libs/ui/src/lib/activities-table/activities-table.component.html index 0cab5d85c..ed22f900f 100644 --- a/libs/ui/src/lib/activities-table/activities-table.component.html +++ b/libs/ui/src/lib/activities-table/activities-table.component.html @@ -145,7 +145,7 @@ class="d-none d-lg-table-cell px-1" mat-cell > - {{ baseCurrency }} + {{ element.SymbolProfile.currency }} {{ baseCurrency }} @@ -261,9 +261,7 @@