Bugfix/fix issue with exchange rate calculation of wealth items in accounts (#3065)
* Fix exchange rate calculatio of wealth items in accounts * Update changelog
This commit is contained in:
parent
2cabd21315
commit
2115745471
@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
|
|||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
|
## Unreleased
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Fixed an issue with the exchange rate calculation of (wealth) items in accounts
|
||||||
|
|
||||||
## 2.58.0 - 2024-02-27
|
## 2.58.0 - 2024-02-27
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
@ -7,10 +7,8 @@ export interface Activities {
|
|||||||
|
|
||||||
export interface Activity extends OrderWithAccount {
|
export interface Activity extends OrderWithAccount {
|
||||||
error?: ActivityError;
|
error?: ActivityError;
|
||||||
feeInBaseCurrency: number;
|
|
||||||
updateAccountBalance?: boolean;
|
updateAccountBalance?: boolean;
|
||||||
value: number;
|
value: number;
|
||||||
valueInBaseCurrency: number;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ActivityError {
|
export interface ActivityError {
|
||||||
|
@ -328,17 +328,7 @@ export class OrderService {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
...order,
|
...order,
|
||||||
value,
|
value
|
||||||
feeInBaseCurrency: this.exchangeRateDataService.toCurrency(
|
|
||||||
order.fee,
|
|
||||||
order.SymbolProfile.currency,
|
|
||||||
userCurrency
|
|
||||||
),
|
|
||||||
valueInBaseCurrency: this.exchangeRateDataService.toCurrency(
|
|
||||||
value,
|
|
||||||
order.SymbolProfile.currency,
|
|
||||||
userCurrency
|
|
||||||
)
|
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -119,7 +119,7 @@ export class PortfolioService {
|
|||||||
userId: string;
|
userId: string;
|
||||||
withExcludedAccounts?: boolean;
|
withExcludedAccounts?: boolean;
|
||||||
}): Promise<AccountWithValue[]> {
|
}): Promise<AccountWithValue[]> {
|
||||||
const where: Prisma.AccountWhereInput = { userId: userId };
|
const where: Prisma.AccountWhereInput = { userId };
|
||||||
|
|
||||||
const accountFilter = filters?.find(({ type }) => {
|
const accountFilter = filters?.find(({ type }) => {
|
||||||
return type === 'ACCOUNT';
|
return type === 'ACCOUNT';
|
||||||
@ -227,18 +227,24 @@ export class PortfolioService {
|
|||||||
impersonationId: string;
|
impersonationId: string;
|
||||||
}): Promise<InvestmentItem[]> {
|
}): Promise<InvestmentItem[]> {
|
||||||
const userId = await this.getUserId(impersonationId, this.request.user.id);
|
const userId = await this.getUserId(impersonationId, this.request.user.id);
|
||||||
|
const user = await this.userService.user({ id: userId });
|
||||||
|
const userCurrency = this.getUserCurrency(user);
|
||||||
|
|
||||||
const { activities } = await this.orderService.getOrders({
|
const { activities } = await this.orderService.getOrders({
|
||||||
filters,
|
filters,
|
||||||
|
userCurrency,
|
||||||
userId,
|
userId,
|
||||||
types: ['DIVIDEND'],
|
types: ['DIVIDEND']
|
||||||
userCurrency: this.request.user.Settings.settings.baseCurrency
|
|
||||||
});
|
});
|
||||||
|
|
||||||
let dividends = activities.map((dividend) => {
|
let dividends = activities.map(({ date, SymbolProfile, value }) => {
|
||||||
return {
|
return {
|
||||||
date: format(dividend.date, DATE_FORMAT),
|
date: format(date, DATE_FORMAT),
|
||||||
investment: dividend.valueInBaseCurrency
|
investment: this.exchangeRateDataService.toCurrency(
|
||||||
|
value,
|
||||||
|
SymbolProfile.currency,
|
||||||
|
userCurrency
|
||||||
|
)
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -762,8 +768,14 @@ export class PortfolioService {
|
|||||||
.filter(({ type }) => {
|
.filter(({ type }) => {
|
||||||
return type === 'DIVIDEND';
|
return type === 'DIVIDEND';
|
||||||
})
|
})
|
||||||
.map(({ valueInBaseCurrency }) => {
|
.map(({ SymbolProfile, value }) => {
|
||||||
return new Big(valueInBaseCurrency);
|
return new Big(
|
||||||
|
this.exchangeRateDataService.toCurrency(
|
||||||
|
value,
|
||||||
|
SymbolProfile.currency,
|
||||||
|
userCurrency
|
||||||
|
)
|
||||||
|
);
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -1992,7 +2004,7 @@ export class PortfolioService {
|
|||||||
withExcludedAccounts = false
|
withExcludedAccounts = false
|
||||||
}: {
|
}: {
|
||||||
filters?: Filter[];
|
filters?: Filter[];
|
||||||
orders: OrderWithAccount[];
|
orders: Activity[];
|
||||||
portfolioItemsNow: { [p: string]: TimelinePosition };
|
portfolioItemsNow: { [p: string]: TimelinePosition };
|
||||||
userCurrency: string;
|
userCurrency: string;
|
||||||
userId: string;
|
userId: string;
|
||||||
@ -2088,41 +2100,50 @@ export class PortfolioService {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const order of ordersByAccount) {
|
for (const {
|
||||||
let currentValueOfSymbolInBaseCurrency =
|
Account,
|
||||||
order.quantity *
|
quantity,
|
||||||
(portfolioItemsNow[order.SymbolProfile.symbol]
|
SymbolProfile,
|
||||||
?.marketPriceInBaseCurrency ??
|
type,
|
||||||
order.unitPrice ??
|
unitPrice
|
||||||
0);
|
} of ordersByAccount) {
|
||||||
|
const unitPriceInBaseCurrency =
|
||||||
|
portfolioItemsNow[SymbolProfile.symbol]?.marketPriceInBaseCurrency ??
|
||||||
|
this.exchangeRateDataService.toCurrency(
|
||||||
|
unitPrice,
|
||||||
|
SymbolProfile.currency,
|
||||||
|
userCurrency
|
||||||
|
) ??
|
||||||
|
0;
|
||||||
|
|
||||||
if (order.type === 'LIABILITY' || order.type === 'SELL') {
|
let currentValueOfSymbolInBaseCurrency =
|
||||||
|
quantity * unitPriceInBaseCurrency;
|
||||||
|
|
||||||
|
if (type === 'LIABILITY' || type === 'SELL') {
|
||||||
currentValueOfSymbolInBaseCurrency *= -1;
|
currentValueOfSymbolInBaseCurrency *= -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (accounts[order.Account?.id || UNKNOWN_KEY]?.valueInBaseCurrency) {
|
if (accounts[Account?.id || UNKNOWN_KEY]?.valueInBaseCurrency) {
|
||||||
accounts[order.Account?.id || UNKNOWN_KEY].valueInBaseCurrency +=
|
accounts[Account?.id || UNKNOWN_KEY].valueInBaseCurrency +=
|
||||||
currentValueOfSymbolInBaseCurrency;
|
currentValueOfSymbolInBaseCurrency;
|
||||||
} else {
|
} else {
|
||||||
accounts[order.Account?.id || UNKNOWN_KEY] = {
|
accounts[Account?.id || UNKNOWN_KEY] = {
|
||||||
balance: 0,
|
balance: 0,
|
||||||
currency: order.Account?.currency,
|
currency: Account?.currency,
|
||||||
name: account.name,
|
name: account.name,
|
||||||
valueInBaseCurrency: currentValueOfSymbolInBaseCurrency
|
valueInBaseCurrency: currentValueOfSymbolInBaseCurrency
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
platforms[order.Account?.Platform?.id || UNKNOWN_KEY]
|
platforms[Account?.Platform?.id || UNKNOWN_KEY]?.valueInBaseCurrency
|
||||||
?.valueInBaseCurrency
|
|
||||||
) {
|
) {
|
||||||
platforms[
|
platforms[Account?.Platform?.id || UNKNOWN_KEY].valueInBaseCurrency +=
|
||||||
order.Account?.Platform?.id || UNKNOWN_KEY
|
currentValueOfSymbolInBaseCurrency;
|
||||||
].valueInBaseCurrency += currentValueOfSymbolInBaseCurrency;
|
|
||||||
} else {
|
} else {
|
||||||
platforms[order.Account?.Platform?.id || UNKNOWN_KEY] = {
|
platforms[Account?.Platform?.id || UNKNOWN_KEY] = {
|
||||||
balance: 0,
|
balance: 0,
|
||||||
currency: order.Account?.currency,
|
currency: Account?.currency,
|
||||||
name: account.Platform?.name,
|
name: account.Platform?.name,
|
||||||
valueInBaseCurrency: currentValueOfSymbolInBaseCurrency
|
valueInBaseCurrency: currentValueOfSymbolInBaseCurrency
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user