From 84c4d79a74f4521d6a72a0b70f4651185ed0b0b1 Mon Sep 17 00:00:00 2001 From: Tobias Kugel <78074722+tobikugel@users.noreply.github.com> Date: Tue, 24 Jun 2025 14:57:59 -0300 Subject: [PATCH] Feature/Set up account cluster risks localization (Current Investment) (#5012) * Set up localization * Update changelog --- CHANGELOG.md | 1 + .../src/app/portfolio/portfolio.service.ts | 2 + apps/api/src/app/user/user.service.ts | 9 ++- .../current-investment.ts | 63 +++++++++++-------- apps/client/src/app/pages/i18n/i18n-page.html | 10 +++ 5 files changed, 57 insertions(+), 28 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8b37a2ca4..af90da89a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added +- Set up the language localization for the static portfolio analysis rule: _Account Cluster Risks_ (Current Investment) - Extended the data providers management of the admin control panel by the online status ### Changed diff --git a/apps/api/src/app/portfolio/portfolio.service.ts b/apps/api/src/app/portfolio/portfolio.service.ts index 623a94f97..aed8e0acb 100644 --- a/apps/api/src/app/portfolio/portfolio.service.ts +++ b/apps/api/src/app/portfolio/portfolio.service.ts @@ -1260,6 +1260,8 @@ export class PortfolioService { [ new AccountClusterRiskCurrentInvestment( this.exchangeRateDataService, + this.i18nService, + userSettings.language, accounts ), new AccountClusterRiskSingleAccount( diff --git a/apps/api/src/app/user/user.service.ts b/apps/api/src/app/user/user.service.ts index 3f4dfc35e..46b46bce2 100644 --- a/apps/api/src/app/user/user.service.ts +++ b/apps/api/src/app/user/user.service.ts @@ -259,9 +259,12 @@ export class UserService { (user.Settings.settings as UserSettings).xRayRules = { AccountClusterRiskCurrentInvestment: - new AccountClusterRiskCurrentInvestment(undefined, {}).getSettings( - user.Settings.settings - ), + new AccountClusterRiskCurrentInvestment( + undefined, + undefined, + undefined, + {} + ).getSettings(user.Settings.settings), AccountClusterRiskSingleAccount: new AccountClusterRiskSingleAccount( undefined, undefined, diff --git a/apps/api/src/models/rules/account-cluster-risk/current-investment.ts b/apps/api/src/models/rules/account-cluster-risk/current-investment.ts index 76b7e2f94..501c9b803 100644 --- a/apps/api/src/models/rules/account-cluster-risk/current-investment.ts +++ b/apps/api/src/models/rules/account-cluster-risk/current-investment.ts @@ -1,20 +1,22 @@ import { RuleSettings } from '@ghostfolio/api/models/interfaces/rule-settings.interface'; import { Rule } from '@ghostfolio/api/models/rule'; import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; -import { - PortfolioDetails, - PortfolioPosition, - UserSettings -} from '@ghostfolio/common/interfaces'; +import { I18nService } from '@ghostfolio/api/services/i18n/i18n.service'; +import { PortfolioDetails, UserSettings } from '@ghostfolio/common/interfaces'; + +import { Account } from '@prisma/client'; export class AccountClusterRiskCurrentInvestment extends Rule { private accounts: PortfolioDetails['accounts']; public constructor( protected exchangeRateDataService: ExchangeRateDataService, + private i18nService: I18nService, + languageCode: string, accounts: PortfolioDetails['accounts'] ) { super(exchangeRateDataService, { + languageCode, key: AccountClusterRiskCurrentInvestment.name }); @@ -23,54 +25,62 @@ export class AccountClusterRiskCurrentInvestment extends Rule { public evaluate(ruleSettings: Settings) { const accounts: { - [symbol: string]: Pick & { + [symbol: string]: Pick & { investment: number; }; } = {}; for (const [accountId, account] of Object.entries(this.accounts)) { accounts[accountId] = { - name: account.name, - investment: account.valueInBaseCurrency + investment: account.valueInBaseCurrency, + name: account.name }; } - let maxItem: (typeof accounts)[0]; + let maxAccount: (typeof accounts)[0]; let totalInvestment = 0; for (const account of Object.values(accounts)) { - if (!maxItem) { - maxItem = account; + if (!maxAccount) { + maxAccount = account; } // Calculate total investment totalInvestment += account.investment; // Find maximum - if (account.investment > maxItem?.investment) { - maxItem = account; + if (account.investment > maxAccount?.investment) { + maxAccount = account; } } - const maxInvestmentRatio = maxItem?.investment / totalInvestment || 0; + const maxInvestmentRatio = maxAccount?.investment / totalInvestment || 0; if (maxInvestmentRatio > ruleSettings.thresholdMax) { return { - evaluation: `Over ${ - ruleSettings.thresholdMax * 100 - }% of your current investment is at ${maxItem.name} (${( - maxInvestmentRatio * 100 - ).toPrecision(3)}%)`, + evaluation: this.i18nService.getTranslation({ + id: 'rule.accountClusterRiskCurrentInvestment.false', + languageCode: this.getLanguageCode(), + placeholders: { + maxAccountName: maxAccount.name, + maxInvestmentRatio: (maxInvestmentRatio * 100).toPrecision(3), + thresholdMax: ruleSettings.thresholdMax * 100 + } + }), value: false }; } return { - evaluation: `The major part of your current investment is at ${ - maxItem.name - } (${(maxInvestmentRatio * 100).toPrecision(3)}%) and does not exceed ${ - ruleSettings.thresholdMax * 100 - }%`, + evaluation: this.i18nService.getTranslation({ + id: 'rule.accountClusterRiskCurrentInvestment.true', + languageCode: this.getLanguageCode(), + placeholders: { + maxAccountName: maxAccount.name, + maxInvestmentRatio: (maxInvestmentRatio * 100).toPrecision(3), + thresholdMax: ruleSettings.thresholdMax * 100 + } + }), value: true }; } @@ -88,7 +98,10 @@ export class AccountClusterRiskCurrentInvestment extends Rule { } public getName() { - return 'Investment'; + return this.i18nService.getTranslation({ + id: 'rule.accountClusterRiskCurrentInvestment', + languageCode: this.getLanguageCode() + }); } public getSettings({ baseCurrency, xRayRules }: UserSettings): Settings { diff --git a/apps/client/src/app/pages/i18n/i18n-page.html b/apps/client/src/app/pages/i18n/i18n-page.html index 6ba581455..20fa23f9a 100644 --- a/apps/client/src/app/pages/i18n/i18n-page.html +++ b/apps/client/src/app/pages/i18n/i18n-page.html @@ -11,6 +11,16 @@ performance, portfolio, software, stock, trading, wealth, web3
  • My Account
  • +
  • Investment
  • +
  • + Over ${thresholdMax}% of your current investment is at + ${maxAccountName} (${maxInvestmentRatio}%) +
  • +
  • + The major part of your current investment is at + ${maxAccountName} (${maxInvestmentRatio}%) and does + not exceed ${thresholdMax}% +
  • Single Account
  • Your net worth is managed by a single account