Feature/improve handling of platforms in accounts import (#1820)
* Improve handling of platforms * Fix issue with pagination * Update changelog
This commit is contained in:
parent
9bef2e960c
commit
2c9f29a3c6
@ -10,6 +10,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Improved the portfolio evolution chart (ignore first item)
|
- 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
|
## 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
|
||||||
|
|
||||||
- Added support to export accounts
|
- Added support to export accounts
|
||||||
- Added suport to import accounts
|
- Added support to import accounts
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@ import { Module } from '@nestjs/common';
|
|||||||
|
|
||||||
import { ImportController } from './import.controller';
|
import { ImportController } from './import.controller';
|
||||||
import { ImportService } from './import.service';
|
import { ImportService } from './import.service';
|
||||||
|
import { PlatformModule } from '@ghostfolio/api/services/platform/platform.module';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
controllers: [ImportController],
|
controllers: [ImportController],
|
||||||
@ -24,6 +25,7 @@ import { ImportService } from './import.service';
|
|||||||
DataProviderModule,
|
DataProviderModule,
|
||||||
ExchangeRateDataModule,
|
ExchangeRateDataModule,
|
||||||
OrderModule,
|
OrderModule,
|
||||||
|
PlatformModule,
|
||||||
PortfolioModule,
|
PortfolioModule,
|
||||||
PrismaModule,
|
PrismaModule,
|
||||||
RedisCacheModule,
|
RedisCacheModule,
|
||||||
|
@ -6,6 +6,7 @@ import { OrderService } from '@ghostfolio/api/app/order/order.service';
|
|||||||
import { PortfolioService } from '@ghostfolio/api/app/portfolio/portfolio.service';
|
import { PortfolioService } from '@ghostfolio/api/app/portfolio/portfolio.service';
|
||||||
import { DataProviderService } from '@ghostfolio/api/services/data-provider/data-provider.service';
|
import { DataProviderService } from '@ghostfolio/api/services/data-provider/data-provider.service';
|
||||||
import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data.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 { SymbolProfileService } from '@ghostfolio/api/services/symbol-profile.service';
|
||||||
import { parseDate } from '@ghostfolio/common/helper';
|
import { parseDate } from '@ghostfolio/common/helper';
|
||||||
import { UniqueAsset } from '@ghostfolio/common/interfaces';
|
import { UniqueAsset } from '@ghostfolio/common/interfaces';
|
||||||
@ -14,7 +15,7 @@ import {
|
|||||||
OrderWithAccount
|
OrderWithAccount
|
||||||
} from '@ghostfolio/common/types';
|
} from '@ghostfolio/common/types';
|
||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
import { SymbolProfile } from '@prisma/client';
|
import { Prisma, SymbolProfile } from '@prisma/client';
|
||||||
import Big from 'big.js';
|
import Big from 'big.js';
|
||||||
import { endOfToday, isAfter, isSameDay, parseISO } from 'date-fns';
|
import { endOfToday, isAfter, isSameDay, parseISO } from 'date-fns';
|
||||||
import { v4 as uuidv4 } from 'uuid';
|
import { v4 as uuidv4 } from 'uuid';
|
||||||
@ -26,6 +27,7 @@ export class ImportService {
|
|||||||
private readonly dataProviderService: DataProviderService,
|
private readonly dataProviderService: DataProviderService,
|
||||||
private readonly exchangeRateDataService: ExchangeRateDataService,
|
private readonly exchangeRateDataService: ExchangeRateDataService,
|
||||||
private readonly orderService: OrderService,
|
private readonly orderService: OrderService,
|
||||||
|
private readonly platformService: PlatformService,
|
||||||
private readonly portfolioService: PortfolioService,
|
private readonly portfolioService: PortfolioService,
|
||||||
private readonly symbolProfileService: SymbolProfileService
|
private readonly symbolProfileService: SymbolProfileService
|
||||||
) {}
|
) {}
|
||||||
@ -118,7 +120,8 @@ export class ImportService {
|
|||||||
const accountIdMapping: { [oldAccountId: string]: string } = {};
|
const accountIdMapping: { [oldAccountId: string]: string } = {};
|
||||||
|
|
||||||
if (!isDryRun && accountsDto?.length) {
|
if (!isDryRun && accountsDto?.length) {
|
||||||
const existingAccounts = await this.accountService.accounts({
|
const [existingAccounts, existingPlatforms] = await Promise.all([
|
||||||
|
this.accountService.accounts({
|
||||||
where: {
|
where: {
|
||||||
id: {
|
id: {
|
||||||
in: accountsDto.map(({ id }) => {
|
in: accountsDto.map(({ id }) => {
|
||||||
@ -126,7 +129,9 @@ export class ImportService {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
}),
|
||||||
|
this.platformService.get()
|
||||||
|
]);
|
||||||
|
|
||||||
for (const account of accountsDto) {
|
for (const account of accountsDto) {
|
||||||
// Check if there is any existing account with the same ID
|
// Check if there is any existing account with the same ID
|
||||||
@ -146,19 +151,24 @@ export class ImportService {
|
|||||||
delete account.id;
|
delete account.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
const newAccountObject = {
|
let accountObject: Prisma.AccountCreateInput = {
|
||||||
...account,
|
...account,
|
||||||
User: { connect: { id: userId } }
|
User: { connect: { id: userId } }
|
||||||
};
|
};
|
||||||
|
|
||||||
if (platformId) {
|
if (
|
||||||
Object.assign(newAccountObject, {
|
existingPlatforms.some(({ id }) => {
|
||||||
|
return id === platformId;
|
||||||
|
})
|
||||||
|
) {
|
||||||
|
accountObject = {
|
||||||
|
...accountObject,
|
||||||
Platform: { connect: { id: platformId } }
|
Platform: { connect: { id: platformId } }
|
||||||
});
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const newAccount = await this.accountService.createAccount(
|
const newAccount = await this.accountService.createAccount(
|
||||||
newAccountObject,
|
accountObject,
|
||||||
userId
|
userId
|
||||||
);
|
);
|
||||||
|
|
||||||
|
11
apps/api/src/services/platform/platform.module.ts
Normal file
11
apps/api/src/services/platform/platform.module.ts
Normal file
@ -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 {}
|
11
apps/api/src/services/platform/platform.service.ts
Normal file
11
apps/api/src/services/platform/platform.service.ts
Normal file
@ -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();
|
||||||
|
}
|
||||||
|
}
|
@ -35,6 +35,7 @@ export class ImportActivitiesDialog implements OnDestroy {
|
|||||||
public errorMessages: string[] = [];
|
public errorMessages: string[] = [];
|
||||||
public holdings: Position[] = [];
|
public holdings: Position[] = [];
|
||||||
public isFileSelected = false;
|
public isFileSelected = false;
|
||||||
|
public maxSafeInteger = Number.MAX_SAFE_INTEGER;
|
||||||
public mode: 'DIVIDEND';
|
public mode: 'DIVIDEND';
|
||||||
public selectedActivities: Activity[] = [];
|
public selectedActivities: Activity[] = [];
|
||||||
public uniqueAssetForm: FormGroup;
|
public uniqueAssetForm: FormGroup;
|
||||||
|
@ -72,6 +72,7 @@
|
|||||||
[hasPermissionToFilter]="false"
|
[hasPermissionToFilter]="false"
|
||||||
[hasPermissionToOpenDetails]="false"
|
[hasPermissionToOpenDetails]="false"
|
||||||
[locale]="data?.user?.settings?.locale"
|
[locale]="data?.user?.settings?.locale"
|
||||||
|
[pageSize]="maxSafeInteger"
|
||||||
[showActions]="false"
|
[showActions]="false"
|
||||||
[showCheckbox]="true"
|
[showCheckbox]="true"
|
||||||
[showFooter]="false"
|
[showFooter]="false"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user