diff --git a/apps/api/src/app/user/user.service.ts b/apps/api/src/app/user/user.service.ts index 65ce92cb2..3280fbfac 100644 --- a/apps/api/src/app/user/user.service.ts +++ b/apps/api/src/app/user/user.service.ts @@ -248,6 +248,11 @@ export class UserService { }; } + // Set default value for annual interest rate + if (!(user.settings.settings as UserSettings)?.annualInterestRate) { + (user.settings.settings as UserSettings).annualInterestRate = 5; + } + // Set default value for base currency if (!(user.settings.settings as UserSettings)?.baseCurrency) { (user.settings.settings as UserSettings).baseCurrency = DEFAULT_CURRENCY; @@ -265,11 +270,21 @@ export class UserService { PerformanceCalculationType.ROAI; } + // Set default value for projected total amount + if (!(user.settings.settings as UserSettings)?.projectedTotalAmount) { + (user.settings.settings as UserSettings).projectedTotalAmount = 0; + } + // Set default value for safe withdrawal rate if (!(user.settings.settings as UserSettings)?.safeWithdrawalRate) { (user.settings.settings as UserSettings).safeWithdrawalRate = 0.04; } + // Set default value for savings rate + if (!(user.settings.settings as UserSettings)?.savingsRate) { + (user.settings.settings as UserSettings).savingsRate = 0; + } + // Set default value for view mode if (!(user.settings.settings as UserSettings).viewMode) { (user.settings.settings as UserSettings).viewMode = 'DEFAULT'; diff --git a/apps/client/src/app/pages/portfolio/fire/fire-page.component.ts b/apps/client/src/app/pages/portfolio/fire/fire-page.component.ts index f5a1860e9..28bfd251e 100644 --- a/apps/client/src/app/pages/portfolio/fire/fire-page.component.ts +++ b/apps/client/src/app/pages/portfolio/fire/fire-page.component.ts @@ -2,7 +2,7 @@ import { DataService } from '@ghostfolio/client/services/data.service'; import { ImpersonationStorageService } from '@ghostfolio/client/services/impersonation-storage.service'; import { UserService } from '@ghostfolio/client/services/user/user.service'; import { - FireCalculation, + FireCalculationCompleteEvent, FireWealth, User } from '@ghostfolio/common/interfaces'; @@ -38,11 +38,12 @@ import { takeUntil } from 'rxjs/operators'; }) export class GfFirePageComponent implements OnDestroy, OnInit { public deviceType: string; - public fireCalculation: FireCalculation; public fireWealth: FireWealth; public hasImpersonationId: boolean; public hasPermissionToUpdateUserSettings: boolean; public isLoading = false; + public projectedTotalAmount: number; + public retirementDate: Date; public safeWithdrawalRateControl = new FormControl(undefined); public safeWithdrawalRateOptions = [0.025, 0.03, 0.035, 0.04, 0.045]; public user: User; @@ -217,8 +218,12 @@ export class GfFirePageComponent implements OnDestroy, OnInit { }); } - public onCalculationComplete(calculation: FireCalculation) { - this.fireCalculation = calculation; + public onCalculationComplete({ + projectedTotalAmount, + retirementDate + }: FireCalculationCompleteEvent) { + this.projectedTotalAmount = projectedTotalAmount; + this.retirementDate = retirementDate; this.calculateProjectedWithdrawalRates(); @@ -243,11 +248,11 @@ export class GfFirePageComponent implements OnDestroy, OnInit { private calculateProjectedWithdrawalRates() { if ( this.fireWealth && - this.user?.settings?.safeWithdrawalRate && - this.fireCalculation.projectedTotalAmount + this.projectedTotalAmount && + this.user?.settings?.safeWithdrawalRate ) { this.withdrawalRatePerYearProjected = new Big( - this.fireCalculation.projectedTotalAmount + this.projectedTotalAmount ).mul(this.user.settings.safeWithdrawalRate); this.withdrawalRatePerMonthProjected = diff --git a/apps/client/src/app/pages/portfolio/fire/fire-page.html b/apps/client/src/app/pages/portfolio/fire/fire-page.html index 0b36ee6c3..def8e98c7 100644 --- a/apps/client/src/app/pages/portfolio/fire/fire-page.html +++ b/apps/client/src/app/pages/portfolio/fire/fire-page.html @@ -28,7 +28,7 @@ [retirementDate]="user?.settings?.retirementDate" [savingsRate]="user?.settings?.savingsRate" (annualInterestRateChanged)="onAnnualInterestRateChange($event)" - (calculationComplete)="onCalculationComplete($event)" + (calculationCompleted)="onCalculationComplete($event)" (projectedTotalAmountChanged)="onProjectedTotalAmountChange($event)" (retirementDateChanged)="onRetirementDateChange($event)" (savingsRateChanged)="onSavingsRateChange($event)" @@ -139,7 +139,7 @@ By   {{ - fireCalculation?.retirementDate | date: 'MMMM yyyy' + user?.settings?.retirementDate ?? retirementDate | date: 'MMMM yyyy' }} ,   @@ -179,7 +179,7 @@ [isPercent]="true" [locale]="user?.settings?.locale" [precision]="2" - [value]="fireCalculation?.annualInterestRate" + [value]="user?.settings?.annualInterestRate / 100" />   annual interest rate. diff --git a/libs/common/src/lib/interfaces/fire-calculation.interface.ts b/libs/common/src/lib/interfaces/fire-calculation.interface.ts index 747d4d35b..1238b0729 100644 --- a/libs/common/src/lib/interfaces/fire-calculation.interface.ts +++ b/libs/common/src/lib/interfaces/fire-calculation.interface.ts @@ -1,5 +1,4 @@ -export interface FireCalculation { - retirementDate: Date; +export interface FireCalculationCompleteEvent { projectedTotalAmount: number; - annualInterestRate: number; + retirementDate: Date; } diff --git a/libs/common/src/lib/interfaces/index.ts b/libs/common/src/lib/interfaces/index.ts index c6fc8ca3d..1b54c49ca 100644 --- a/libs/common/src/lib/interfaces/index.ts +++ b/libs/common/src/lib/interfaces/index.ts @@ -18,7 +18,7 @@ import type { DataProviderInfo } from './data-provider-info.interface'; import type { EnhancedSymbolProfile } from './enhanced-symbol-profile.interface'; import type { FilterGroup } from './filter-group.interface'; import type { Filter } from './filter.interface'; -import type { FireCalculation } from './fire-calculation.interface'; +import type { FireCalculationCompleteEvent } from './fire-calculation.interface'; import type { FireWealth } from './fire-wealth.interface'; import type { HistoricalDataItem } from './historical-data-item.interface'; import type { HoldingWithParents } from './holding-with-parents.interface'; @@ -141,8 +141,8 @@ export { ExportResponse, Filter, FilterGroup, + FireCalculationCompleteEvent, FireWealth, - FireCalculation, HistoricalDataItem, HistoricalResponse, Holding, diff --git a/libs/ui/src/lib/fire-calculator/fire-calculator.component.ts b/libs/ui/src/lib/fire-calculator/fire-calculator.component.ts index 4fd3e20af..655798b3d 100644 --- a/libs/ui/src/lib/fire-calculator/fire-calculator.component.ts +++ b/libs/ui/src/lib/fire-calculator/fire-calculator.component.ts @@ -4,7 +4,7 @@ import { } from '@ghostfolio/common/chart-helper'; import { primaryColorRgb } from '@ghostfolio/common/config'; import { getLocale } from '@ghostfolio/common/helper'; -import { FireCalculation } from '@ghostfolio/common/interfaces'; +import { FireCalculationCompleteEvent } from '@ghostfolio/common/interfaces'; import { ColorScheme } from '@ghostfolio/common/types'; import { CommonModule } from '@angular/common'; @@ -89,10 +89,11 @@ export class GfFireCalculatorComponent implements OnChanges, OnDestroy { @Input() savingsRate: number; @Output() annualInterestRateChanged = new EventEmitter(); + @Output() calculationCompleted = + new EventEmitter(); @Output() projectedTotalAmountChanged = new EventEmitter(); @Output() retirementDateChanged = new EventEmitter(); @Output() savingsRateChanged = new EventEmitter(); - @Output() calculationComplete = new EventEmitter(); @ViewChild('chartCanvas') chartCanvas: ElementRef; @@ -136,12 +137,12 @@ export class GfFireCalculatorComponent implements OnChanges, OnDestroy { this.calculatorForm.valueChanges .pipe(debounceTime(500), takeUntil(this.unsubscribeSubject)) .subscribe(() => { - const { retirementDate, projectedTotalAmount } = + const { projectedTotalAmount, retirementDate } = this.calculatorForm.getRawValue(); - this.calculationComplete.emit({ - retirementDate, + + this.calculationCompleted.emit({ projectedTotalAmount, - annualInterestRate: this.getR() + retirementDate }); }); @@ -175,10 +176,10 @@ export class GfFireCalculatorComponent implements OnChanges, OnDestroy { if (isNumber(this.fireWealth) && this.fireWealth >= 0) { this.calculatorForm.setValue( { - annualInterestRate: this.annualInterestRate ?? 5, - paymentPerPeriod: this.savingsRate ?? 0, + annualInterestRate: this.annualInterestRate, + paymentPerPeriod: this.savingsRate, principalInvestmentAmount: this.fireWealth, - projectedTotalAmount: this.projectedTotalAmount ?? 0, + projectedTotalAmount: this.projectedTotalAmount, retirementDate: this.retirementDate ?? this.DEFAULT_RETIREMENT_DATE }, {