|
|
@ -1,6 +1,10 @@ |
|
|
import { AccountBalanceService } from '@ghostfolio/api/app/account-balance/account-balance.service'; |
|
|
import { AccountBalanceService } from '@ghostfolio/api/app/account-balance/account-balance.service'; |
|
|
import { PortfolioChangedEvent } from '@ghostfolio/api/events/portfolio-changed.event'; |
|
|
import { PortfolioChangedEvent } from '@ghostfolio/api/events/portfolio-changed.event'; |
|
|
import { WHERE_ACCOUNT_NOT_EXCLUDED } from '@ghostfolio/api/helper/account.helper'; |
|
|
import { |
|
|
|
|
|
getWhereAccountBalanceNotInFuture, |
|
|
|
|
|
isAccountBalanceInFuture, |
|
|
|
|
|
WHERE_ACCOUNT_NOT_EXCLUDED |
|
|
|
|
|
} from '@ghostfolio/api/helper/account.helper'; |
|
|
import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; |
|
|
import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; |
|
|
import { PrismaService } from '@ghostfolio/api/services/prisma/prisma.service'; |
|
|
import { PrismaService } from '@ghostfolio/api/services/prisma/prisma.service'; |
|
|
import { TagService } from '@ghostfolio/api/services/tag/tag.service'; |
|
|
import { TagService } from '@ghostfolio/api/services/tag/tag.service'; |
|
|
@ -19,7 +23,7 @@ import { |
|
|
Tag |
|
|
Tag |
|
|
} from '@prisma/client'; |
|
|
} from '@prisma/client'; |
|
|
import { Big } from 'big.js'; |
|
|
import { Big } from 'big.js'; |
|
|
import { format } from 'date-fns'; |
|
|
import { endOfToday, format } from 'date-fns'; |
|
|
import { groupBy } from 'lodash'; |
|
|
import { groupBy } from 'lodash'; |
|
|
|
|
|
|
|
|
import { CashDetails } from './interfaces/cash-details.interface'; |
|
|
import { CashDetails } from './interfaces/cash-details.interface'; |
|
|
@ -41,7 +45,9 @@ export class AccountService { |
|
|
include: { |
|
|
include: { |
|
|
balances: { |
|
|
balances: { |
|
|
orderBy: { date: 'desc' }, |
|
|
orderBy: { date: 'desc' }, |
|
|
take: 1 |
|
|
take: 1, |
|
|
|
|
|
// Ignore account balances in the future
|
|
|
|
|
|
where: getWhereAccountBalanceNotInFuture() |
|
|
} |
|
|
} |
|
|
}, |
|
|
}, |
|
|
where: { id_userId } |
|
|
where: { id_userId } |
|
|
@ -95,7 +101,16 @@ export class AccountService { |
|
|
|
|
|
|
|
|
include.balances = { |
|
|
include.balances = { |
|
|
orderBy: { date: 'desc' }, |
|
|
orderBy: { date: 'desc' }, |
|
|
...(isBalancesIncluded ? {} : { take: 1 }) |
|
|
// If the balances are included, they are returned as-is (including the
|
|
|
|
|
|
// ones in the future) because the client renders the full history. The
|
|
|
|
|
|
// balance is derived below and skips the account balances in the future.
|
|
|
|
|
|
...(isBalancesIncluded |
|
|
|
|
|
? {} |
|
|
|
|
|
: { |
|
|
|
|
|
take: 1, |
|
|
|
|
|
// Ignore account balances in the future
|
|
|
|
|
|
where: getWhereAccountBalanceNotInFuture() |
|
|
|
|
|
}) |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
if (isTagsIncluded) { |
|
|
if (isTagsIncluded) { |
|
|
@ -115,10 +130,17 @@ export class AccountService { |
|
|
where |
|
|
where |
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
const endOfTodayDate = endOfToday(); |
|
|
|
|
|
|
|
|
return accounts.map((account) => { |
|
|
return accounts.map((account) => { |
|
|
const result = { |
|
|
const result = { |
|
|
...account, |
|
|
...account, |
|
|
balance: account.balances[0]?.value ?? 0, |
|
|
balance: |
|
|
|
|
|
// The balances are ordered by date descending, hence the first account
|
|
|
|
|
|
// balance which is not in the future reflects the current balance
|
|
|
|
|
|
account.balances.find(({ date }) => { |
|
|
|
|
|
return !isAccountBalanceInFuture({ date, endOfTodayDate }); |
|
|
|
|
|
})?.value ?? 0, |
|
|
tags: isTagsIncluded |
|
|
tags: isTagsIncluded |
|
|
? (account.tags as unknown as { tag: Tag }[]).map(({ tag }) => { |
|
|
? (account.tags as unknown as { tag: Tag }[]).map(({ tag }) => { |
|
|
return tag; |
|
|
return tag; |
|
|
|