diff --git a/apps/api/src/app/portfolio/portfolio-service.factory.ts b/apps/api/src/app/portfolio/portfolio-service.factory.ts index e5a3eaae5..e1f21d7e0 100644 --- a/apps/api/src/app/portfolio/portfolio-service.factory.ts +++ b/apps/api/src/app/portfolio/portfolio-service.factory.ts @@ -1,4 +1,7 @@ -import { Injectable } from '@nestjs/common'; +import type { RequestWithUser } from '@ghostfolio/common/types'; +import { Inject, Injectable } from '@nestjs/common'; +import { REQUEST } from '@nestjs/core'; + import { PortfolioService } from './portfolio.service'; import { PortfolioServiceNew } from './portfolio.service-new'; @@ -6,11 +9,14 @@ import { PortfolioServiceNew } from './portfolio.service-new'; export class PortfolioServiceFactory { public constructor( private readonly portfolioService: PortfolioService, - private readonly portfolioServiceNew: PortfolioServiceNew + private readonly portfolioServiceNew: PortfolioServiceNew, + @Inject(REQUEST) private readonly request: RequestWithUser ) {} public get() { - if (false) { + if ( + this.request.user?.Settings?.settings?.['isNewCalculationEngine'] === true + ) { return this.portfolioServiceNew; } diff --git a/apps/api/src/app/portfolio/portfolio.service-new.ts b/apps/api/src/app/portfolio/portfolio.service-new.ts index 736385da0..da6bd44aa 100644 --- a/apps/api/src/app/portfolio/portfolio.service-new.ts +++ b/apps/api/src/app/portfolio/portfolio.service-new.ts @@ -399,11 +399,12 @@ export class PortfolioServiceNew { aImpersonationId: string, aSymbol: string ): Promise { + const userCurrency = this.request.user.Settings.currency; const userId = await this.getUserId(aImpersonationId, this.request.user.id); - const orders = (await this.orderService.getOrders({ userId })).filter( - (order) => order.symbol === aSymbol - ); + const orders = ( + await this.orderService.getOrders({ userCurrency, userId }) + ).filter((order) => order.symbol === aSymbol); if (orders.length <= 0) { return { @@ -871,24 +872,25 @@ export class PortfolioServiceNew { } public async getSummary(aImpersonationId: string): Promise { - const currency = this.request.user.Settings.currency; + const userCurrency = this.request.user.Settings.currency; const userId = await this.getUserId(aImpersonationId, this.request.user.id); const performanceInformation = await this.getPerformance(aImpersonationId); const { balance } = await this.accountService.getCashDetails( userId, - currency + userCurrency ); const orders = await this.orderService.getOrders({ + userCurrency, userId }); const dividend = this.getDividend(orders).toNumber(); const fees = this.getFees(orders).toNumber(); const firstOrderDate = orders[0]?.date; - const totalBuy = this.getTotalByType(orders, currency, 'BUY'); - const totalSell = this.getTotalByType(orders, currency, 'SELL'); + const totalBuy = this.getTotalByType(orders, userCurrency, 'BUY'); + const totalSell = this.getTotalByType(orders, userCurrency, 'SELL'); const committedFunds = new Big(totalBuy).sub(totalSell); @@ -1051,8 +1053,11 @@ export class PortfolioServiceNew { orders: OrderWithAccount[]; portfolioOrders: PortfolioOrder[]; }> { + const userCurrency = this.request.user?.Settings?.currency ?? baseCurrency; + const orders = await this.orderService.getOrders({ includeDrafts, + userCurrency, userId, types: ['BUY', 'SELL'] }); @@ -1061,7 +1066,6 @@ export class PortfolioServiceNew { return { transactionPoints: [], orders: [], portfolioOrders: [] }; } - const userCurrency = this.request.user?.Settings?.currency ?? baseCurrency; const portfolioOrders: PortfolioOrder[] = orders.map((order) => ({ currency: order.currency, dataSource: order.SymbolProfile?.dataSource ?? order.dataSource, diff --git a/apps/api/src/app/user/update-user-setting.dto.ts b/apps/api/src/app/user/update-user-setting.dto.ts index a6a583138..38dc9cafb 100644 --- a/apps/api/src/app/user/update-user-setting.dto.ts +++ b/apps/api/src/app/user/update-user-setting.dto.ts @@ -1,6 +1,11 @@ -import { IsBoolean } from 'class-validator'; +import { IsBoolean, IsOptional } from 'class-validator'; export class UpdateUserSettingDto { @IsBoolean() + @IsOptional() + isNewCalculationEngine?: boolean; + + @IsBoolean() + @IsOptional() isRestrictedView?: boolean; } diff --git a/apps/api/src/app/user/user.controller.ts b/apps/api/src/app/user/user.controller.ts index 0a7ed21cf..adb059412 100644 --- a/apps/api/src/app/user/user.controller.ts +++ b/apps/api/src/app/user/user.controller.ts @@ -23,7 +23,7 @@ import { import { REQUEST } from '@nestjs/core'; import { JwtService } from '@nestjs/jwt'; import { AuthGuard } from '@nestjs/passport'; -import { Provider, Role } from '@prisma/client'; +import { Provider } from '@prisma/client'; import { User as UserModel } from '@prisma/client'; import { StatusCodes, getReasonPhrase } from 'http-status-codes'; @@ -115,6 +115,12 @@ export class UserController { ...data }; + for (const key in userSettings) { + if (userSettings[key] === false) { + delete userSettings[key]; + } + } + return await this.userService.updateUserSetting({ userSettings, userId: this.request.user.id diff --git a/apps/client/src/app/pages/account/account-page.component.ts b/apps/client/src/app/pages/account/account-page.component.ts index 5d1d0d5e3..df7f81beb 100644 --- a/apps/client/src/app/pages/account/account-page.component.ts +++ b/apps/client/src/app/pages/account/account-page.component.ts @@ -192,6 +192,24 @@ export class AccountPageComponent implements OnDestroy, OnInit { }); } + public onNewCalculationChange(aEvent: MatSlideToggleChange) { + this.dataService + .putUserSetting({ isNewCalculationEngine: aEvent.checked }) + .pipe(takeUntil(this.unsubscribeSubject)) + .subscribe(() => { + this.userService.remove(); + + this.userService + .get() + .pipe(takeUntil(this.unsubscribeSubject)) + .subscribe((user) => { + this.user = user; + + this.changeDetectorRef.markForCheck(); + }); + }); + } + public onRedeemCoupon() { let couponCode = prompt('Please enter your coupon code:'); couponCode = couponCode?.trim(); diff --git a/apps/client/src/app/pages/account/account-page.html b/apps/client/src/app/pages/account/account-page.html index 1155741f9..081784bfb 100644 --- a/apps/client/src/app/pages/account/account-page.html +++ b/apps/client/src/app/pages/account/account-page.html @@ -135,6 +135,23 @@ > +
+
+
New Calculation Engine
+
Experimental
+
+
+ +
+