diff --git a/apps/api/src/app/import/import.service.ts b/apps/api/src/app/import/import.service.ts index 9ddfb3e96..15a8e2a30 100644 --- a/apps/api/src/app/import/import.service.ts +++ b/apps/api/src/app/import/import.service.ts @@ -1,9 +1,6 @@ import { AccountService } from '@ghostfolio/api/app/account/account.service'; import { CreateAccountDto } from '@ghostfolio/api/app/account/create-account.dto'; -import { - CreateOrderDto, - OrderResponseDto -} from '@ghostfolio/api/app/order/create-order.dto'; +import { CreateOrderDto } from '@ghostfolio/api/app/order/create-order.dto'; import { Activity } from '@ghostfolio/api/app/order/interfaces/activities.interface'; import { OrderService } from '@ghostfolio/api/app/order/order.service'; import { PortfolioService } from '@ghostfolio/api/app/portfolio/portfolio.service'; @@ -208,14 +205,14 @@ export class ImportService { userId }); - const activitiesDtoWithDuplication = await this.markActivitiesAsDuplicates({ + const activitiesMarkedAsDuplicates = await this.markActivitiesAsDuplicates({ activitiesDto, userId }); const accounts = (await this.accountService.getAccounts(userId)).map( - (account) => { - return { id: account.id, name: account.name }; + ({ id, name }) => { + return { id, name }; } ); @@ -230,17 +227,14 @@ export class ImportService { for (const { accountId, comment, - currency, - dataSource, - date: dateString, + date, fee, isDuplicate, quantity, - symbol, + SymbolProfile: assetProfile, type, unitPrice - } of activitiesDtoWithDuplication) { - const date = parseISO((dateString)); + } of activitiesMarkedAsDuplicates) { const validatedAccount = accounts.find(({ id }) => { return id === accountId; }); @@ -266,23 +260,23 @@ export class ImportService { id: uuidv4(), isDraft: isAfter(date, endOfToday()), SymbolProfile: { - currency, - dataSource, - symbol, - assetClass: null, - assetSubClass: null, - comment: null, - countries: null, - createdAt: undefined, - id: undefined, - isin: null, - name: null, - scraperConfiguration: null, - sectors: null, - symbolMapping: null, - updatedAt: undefined, - url: null, - ...assetProfiles[symbol] + assetClass: assetProfile.assetClass, + assetSubClass: assetProfile.assetSubClass, + comment: assetProfile.comment, + countries: assetProfile.countries, + createdAt: assetProfile.createdAt, + currency: assetProfile.currency, + dataSource: assetProfile.dataSource, + id: assetProfile.id, + isin: assetProfile.isin, + name: assetProfile.name, + scraperConfiguration: assetProfile.scraperConfiguration, + sectors: assetProfile.sectors, + symbol: assetProfile.currency, + symbolMapping: assetProfile.symbolMapping, + updatedAt: assetProfile.updatedAt, + url: assetProfile.url, + ...assetProfiles[assetProfile.symbol] }, Account: validatedAccount, symbolProfileId: undefined, @@ -305,14 +299,14 @@ export class ImportService { SymbolProfile: { connectOrCreate: { create: { - currency, - dataSource, - symbol + currency: assetProfile.currency, + dataSource: assetProfile.dataSource, + symbol: assetProfile.symbol }, where: { dataSource_symbol: { - dataSource, - symbol + dataSource: assetProfile.dataSource, + symbol: assetProfile.symbol } } } @@ -330,12 +324,12 @@ export class ImportService { value, feeInBaseCurrency: this.exchangeRateDataService.toCurrency( fee, - currency, + assetProfile.currency, userCurrency ), valueInBaseCurrency: this.exchangeRateDataService.toCurrency( value, - currency, + assetProfile.currency, userCurrency ) }); @@ -343,70 +337,86 @@ export class ImportService { return activities; } + private isUniqueAccount(accounts: AccountWithPlatform[]) { + const uniqueAccountIds = new Set(); + + for (const account of accounts) { + uniqueAccountIds.add(account.id); + } + + return uniqueAccountIds.size === 1; + } + private async markActivitiesAsDuplicates({ activitiesDto, userId }: { activitiesDto: Partial[]; userId: string; - }): Promise[]> { + }): Promise[]> { const existingActivities = await this.orderService.orders({ include: { SymbolProfile: true }, orderBy: { date: 'desc' }, where: { userId } }); - const activitiesDtoWithDuplication: Partial[] = []; - - for (const activitiesDtoEntry of activitiesDto) { - const { + return activitiesDto.map( + ({ + accountId, + comment, currency, dataSource, - date, + date: dateString, fee, quantity, symbol, type, unitPrice - } = activitiesDtoEntry; - - const isDuplicate = existingActivities.find((activity) => { - return ( - activity.SymbolProfile.currency === currency && - activity.SymbolProfile.dataSource === dataSource && - isSameDay(activity.date, parseISO((date))) && - activity.fee === fee && - activity.quantity === quantity && - activity.SymbolProfile.symbol === symbol && - activity.type === type && - activity.unitPrice === unitPrice - ); - }); - - if (isDuplicate) { - activitiesDtoWithDuplication.push({ - ...activitiesDtoEntry, - isDuplicate: true - }); - } else { - activitiesDtoWithDuplication.push({ - ...activitiesDtoEntry, - isDuplicate: false + }) => { + const date = parseISO((dateString)); + const isDuplicate = existingActivities.some((activity) => { + return ( + activity.SymbolProfile.currency === currency && + activity.SymbolProfile.dataSource === dataSource && + isSameDay(activity.date, date) && + activity.fee === fee && + activity.quantity === quantity && + activity.SymbolProfile.symbol === symbol && + activity.type === type && + activity.unitPrice === unitPrice + ); }); - } - } - - return activitiesDtoWithDuplication; - } - private isUniqueAccount(accounts: AccountWithPlatform[]) { - const uniqueAccountIds = new Set(); - - for (const account of accounts) { - uniqueAccountIds.add(account.id); - } - - return uniqueAccountIds.size === 1; + return { + accountId, + comment, + date, + fee, + isDuplicate, + quantity, + type, + unitPrice, + SymbolProfile: { + currency, + dataSource, + symbol, + assetClass: null, + assetSubClass: null, + comment: null, + countries: null, + createdAt: undefined, + id: undefined, + isin: null, + name: null, + scraperConfiguration: null, + sectors: null, + symbolMapping: null, + updatedAt: undefined, + url: null + } + }; + } + ); } private async validateActivities({ diff --git a/apps/api/src/app/order/create-order.dto.ts b/apps/api/src/app/order/create-order.dto.ts index 8d73862b1..33e6f9cc8 100644 --- a/apps/api/src/app/order/create-order.dto.ts +++ b/apps/api/src/app/order/create-order.dto.ts @@ -65,7 +65,3 @@ export class CreateOrderDto { @IsNumber() unitPrice: number; } - -export class OrderResponseDto extends CreateOrderDto { - isDuplicate: boolean; -} 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 4e542de42..45551305b 100644 --- a/libs/ui/src/lib/activities-table/activities-table.component.html +++ b/libs/ui/src/lib/activities-table/activities-table.component.html @@ -76,7 +76,6 @@