|
|
@ -21,7 +21,8 @@ import { |
|
|
|
import { UniqueAsset } from '@ghostfolio/common/interfaces'; |
|
|
|
import { |
|
|
|
AccountWithPlatform, |
|
|
|
OrderWithAccount |
|
|
|
OrderWithAccount, |
|
|
|
UserWithSettings |
|
|
|
} from '@ghostfolio/common/types'; |
|
|
|
import { Injectable } from '@nestjs/common'; |
|
|
|
import { DataSource, Prisma, SymbolProfile } from '@prisma/client'; |
|
|
@ -138,17 +139,16 @@ export class ImportService { |
|
|
|
activitiesDto, |
|
|
|
isDryRun = false, |
|
|
|
maxActivitiesToImport, |
|
|
|
userCurrency, |
|
|
|
userId |
|
|
|
user |
|
|
|
}: { |
|
|
|
accountsDto: Partial<CreateAccountDto>[]; |
|
|
|
activitiesDto: Partial<CreateOrderDto>[]; |
|
|
|
isDryRun?: boolean; |
|
|
|
maxActivitiesToImport: number; |
|
|
|
userCurrency: string; |
|
|
|
userId: string; |
|
|
|
user: UserWithSettings; |
|
|
|
}): Promise<Activity[]> { |
|
|
|
const accountIdMapping: { [oldAccountId: string]: string } = {}; |
|
|
|
const userCurrency = user.Settings.settings.baseCurrency; |
|
|
|
|
|
|
|
if (!isDryRun && accountsDto?.length) { |
|
|
|
const [existingAccounts, existingPlatforms] = await Promise.all([ |
|
|
@ -171,7 +171,7 @@ export class ImportService { |
|
|
|
); |
|
|
|
|
|
|
|
// If there is no account or if the account belongs to a different user then create a new account
|
|
|
|
if (!accountWithSameId || accountWithSameId.userId !== userId) { |
|
|
|
if (!accountWithSameId || accountWithSameId.userId !== user.id) { |
|
|
|
let oldAccountId: string; |
|
|
|
const platformId = account.platformId; |
|
|
|
|
|
|
@ -184,7 +184,7 @@ export class ImportService { |
|
|
|
|
|
|
|
let accountObject: Prisma.AccountCreateInput = { |
|
|
|
...account, |
|
|
|
User: { connect: { id: userId } } |
|
|
|
User: { connect: { id: user.id } } |
|
|
|
}; |
|
|
|
|
|
|
|
if ( |
|
|
@ -200,7 +200,7 @@ export class ImportService { |
|
|
|
|
|
|
|
const newAccount = await this.accountService.createAccount( |
|
|
|
accountObject, |
|
|
|
userId |
|
|
|
user.id |
|
|
|
); |
|
|
|
|
|
|
|
// Store the new to old account ID mappings for updating activities
|
|
|
@ -231,16 +231,17 @@ export class ImportService { |
|
|
|
|
|
|
|
const assetProfiles = await this.validateActivities({ |
|
|
|
activitiesDto, |
|
|
|
maxActivitiesToImport |
|
|
|
maxActivitiesToImport, |
|
|
|
user |
|
|
|
}); |
|
|
|
|
|
|
|
const activitiesExtendedWithErrors = await this.extendActivitiesWithErrors({ |
|
|
|
activitiesDto, |
|
|
|
userCurrency, |
|
|
|
userId |
|
|
|
userId: user.id |
|
|
|
}); |
|
|
|
|
|
|
|
const accounts = (await this.accountService.getAccounts(userId)).map( |
|
|
|
const accounts = (await this.accountService.getAccounts(user.id)).map( |
|
|
|
({ id, name }) => { |
|
|
|
return { id, name }; |
|
|
|
} |
|
|
@ -345,7 +346,6 @@ export class ImportService { |
|
|
|
quantity, |
|
|
|
type, |
|
|
|
unitPrice, |
|
|
|
userId, |
|
|
|
accountId: validatedAccount?.id, |
|
|
|
accountUserId: undefined, |
|
|
|
createdAt: new Date(), |
|
|
@ -374,7 +374,8 @@ export class ImportService { |
|
|
|
}, |
|
|
|
Account: validatedAccount, |
|
|
|
symbolProfileId: undefined, |
|
|
|
updatedAt: new Date() |
|
|
|
updatedAt: new Date(), |
|
|
|
userId: user.id |
|
|
|
}; |
|
|
|
} else { |
|
|
|
if (error) { |
|
|
@ -388,7 +389,6 @@ export class ImportService { |
|
|
|
quantity, |
|
|
|
type, |
|
|
|
unitPrice, |
|
|
|
userId, |
|
|
|
accountId: validatedAccount?.id, |
|
|
|
SymbolProfile: { |
|
|
|
connectOrCreate: { |
|
|
@ -406,7 +406,8 @@ export class ImportService { |
|
|
|
} |
|
|
|
}, |
|
|
|
updateAccountBalance: false, |
|
|
|
User: { connect: { id: userId } } |
|
|
|
User: { connect: { id: user.id } }, |
|
|
|
userId: user.id |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
@ -553,10 +554,12 @@ export class ImportService { |
|
|
|
|
|
|
|
private async validateActivities({ |
|
|
|
activitiesDto, |
|
|
|
maxActivitiesToImport |
|
|
|
maxActivitiesToImport, |
|
|
|
user |
|
|
|
}: { |
|
|
|
activitiesDto: Partial<CreateOrderDto>[]; |
|
|
|
maxActivitiesToImport: number; |
|
|
|
user: UserWithSettings; |
|
|
|
}) { |
|
|
|
if (activitiesDto?.length > maxActivitiesToImport) { |
|
|
|
throw new Error(`Too many activities (${maxActivitiesToImport} at most)`); |
|
|
@ -583,6 +586,21 @@ export class ImportService { |
|
|
|
); |
|
|
|
} |
|
|
|
|
|
|
|
if ( |
|
|
|
this.configurationService.get('ENABLE_FEATURE_SUBSCRIPTION') && |
|
|
|
user.subscription.type === 'Basic' |
|
|
|
) { |
|
|
|
const dataProvider = this.dataProviderService.getDataProvider( |
|
|
|
DataSource[dataSource] |
|
|
|
); |
|
|
|
|
|
|
|
if (dataProvider.getDataProviderInfo().isPremium) { |
|
|
|
throw new Error( |
|
|
|
`activities.${index}.dataSource ("${dataSource}") is not valid` |
|
|
|
); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
const assetProfile = { |
|
|
|
currency, |
|
|
|
...( |
|
|
|