|
|
@ -72,6 +72,7 @@ import { |
|
|
|
Order, |
|
|
|
Platform, |
|
|
|
Prisma, |
|
|
|
SymbolProfile, |
|
|
|
Tag |
|
|
|
} from '@prisma/client'; |
|
|
|
import { Big } from 'big.js'; |
|
|
@ -160,7 +161,11 @@ export class PortfolioService { |
|
|
|
this.accountService.accounts({ |
|
|
|
where, |
|
|
|
include: { |
|
|
|
activities: true, |
|
|
|
activities: { |
|
|
|
include: { |
|
|
|
SymbolProfile: true |
|
|
|
} |
|
|
|
}, |
|
|
|
platform: true |
|
|
|
}, |
|
|
|
orderBy: { name: 'asc' } |
|
|
@ -175,38 +180,71 @@ export class PortfolioService { |
|
|
|
|
|
|
|
const userCurrency = this.request.user.Settings.settings.baseCurrency; |
|
|
|
|
|
|
|
return accounts.map((account) => { |
|
|
|
const accountsWithValue = accounts.map((account) => { |
|
|
|
let transactionCount = 0; |
|
|
|
let valueInBaseCurrency = |
|
|
|
details.accounts[account.id]?.valueInBaseCurrency ?? 0; |
|
|
|
|
|
|
|
for (const { isDraft } of account.activities) { |
|
|
|
if (!isDraft) { |
|
|
|
transactionCount += 1; |
|
|
|
if (filterByDataSource && filterBySymbol) { |
|
|
|
const holding = details.holdings[filterBySymbol]; |
|
|
|
|
|
|
|
const activities = ( |
|
|
|
account.activities as (Order & { |
|
|
|
SymbolProfile: SymbolProfile; |
|
|
|
})[] |
|
|
|
).filter((activity) => { |
|
|
|
return ( |
|
|
|
activity.SymbolProfile.dataSource === filterByDataSource && |
|
|
|
activity.SymbolProfile.symbol === filterBySymbol |
|
|
|
); |
|
|
|
}); |
|
|
|
|
|
|
|
let quantity = new Big(0); |
|
|
|
for (const activity of activities) { |
|
|
|
quantity = quantity.plus( |
|
|
|
new Big(getFactor(activity.type)).mul(activity.quantity) |
|
|
|
); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
const valueInBaseCurrency = |
|
|
|
details.accounts[account.id]?.valueInBaseCurrency ?? 0; |
|
|
|
valueInBaseCurrency = quantity.mul(holding.marketPrice ?? 0).toNumber(); |
|
|
|
transactionCount = activities.length; |
|
|
|
} else { |
|
|
|
for (const { isDraft } of account.activities) { |
|
|
|
if (!isDraft) { |
|
|
|
transactionCount += 1; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
const result = { |
|
|
|
...account, |
|
|
|
transactionCount, |
|
|
|
valueInBaseCurrency, |
|
|
|
allocationInPercentage: 0, |
|
|
|
balanceInBaseCurrency: this.exchangeRateDataService.toCurrency( |
|
|
|
account.balance, |
|
|
|
account.currency, |
|
|
|
userCurrency |
|
|
|
), |
|
|
|
transactionCount, |
|
|
|
value: this.exchangeRateDataService.toCurrency( |
|
|
|
valueInBaseCurrency, |
|
|
|
userCurrency, |
|
|
|
account.currency |
|
|
|
) |
|
|
|
), |
|
|
|
valueInBaseCurrency |
|
|
|
}; |
|
|
|
|
|
|
|
delete result.activities; |
|
|
|
|
|
|
|
return result; |
|
|
|
}); |
|
|
|
|
|
|
|
if (filterByDataSource && filterBySymbol) { |
|
|
|
return accountsWithValue.filter((account) => { |
|
|
|
return account.transactionCount > 0; |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
return accountsWithValue; |
|
|
|
} |
|
|
|
|
|
|
|
public async getAccountsWithAggregations({ |
|
|
@ -237,6 +275,14 @@ export class PortfolioService { |
|
|
|
transactionCount += account.transactionCount; |
|
|
|
} |
|
|
|
|
|
|
|
for (const account of accounts) { |
|
|
|
account.allocationInPercentage = totalValueInBaseCurrency.gt(0) |
|
|
|
? new Big(account.valueInBaseCurrency) |
|
|
|
.div(totalValueInBaseCurrency) |
|
|
|
.toNumber() |
|
|
|
: 0; |
|
|
|
} |
|
|
|
|
|
|
|
return { |
|
|
|
accounts, |
|
|
|
transactionCount, |
|
|
|