Browse Source

Switch to new calculation engine

pull/814/head
Thomas 3 years ago
parent
commit
59ba0728a4
  1. 11
      apps/api/src/app/account/account.controller.ts
  2. 26
      apps/api/src/app/portfolio/portfolio-service.strategy.ts
  3. 58
      apps/api/src/app/portfolio/portfolio.controller.ts
  4. 4
      apps/api/src/app/portfolio/portfolio.module.ts
  5. 1
      apps/api/src/app/user/interfaces/user-settings.interface.ts
  6. 4
      apps/api/src/app/user/update-user-setting.dto.ts
  7. 18
      apps/client/src/app/pages/account/account-page.component.ts
  8. 17
      apps/client/src/app/pages/account/account-page.html

11
apps/api/src/app/account/account.controller.ts

@ -1,4 +1,4 @@
import { PortfolioServiceStrategy } from '@ghostfolio/api/app/portfolio/portfolio-service.strategy'; import { PortfolioServiceNew } from '@ghostfolio/api/app/portfolio/portfolio.service-new';
import { UserService } from '@ghostfolio/api/app/user/user.service'; import { UserService } from '@ghostfolio/api/app/user/user.service';
import { import {
nullifyValuesInObject, nullifyValuesInObject,
@ -35,7 +35,7 @@ export class AccountController {
public constructor( public constructor(
private readonly accountService: AccountService, private readonly accountService: AccountService,
private readonly impersonationService: ImpersonationService, private readonly impersonationService: ImpersonationService,
private readonly portfolioServiceStrategy: PortfolioServiceStrategy, private readonly portfolioServiceNew: PortfolioServiceNew,
@Inject(REQUEST) private readonly request: RequestWithUser, @Inject(REQUEST) private readonly request: RequestWithUser,
private readonly userService: UserService private readonly userService: UserService
) {} ) {}
@ -91,9 +91,10 @@ export class AccountController {
this.request.user.id this.request.user.id
); );
let accountsWithAggregations = await this.portfolioServiceStrategy let accountsWithAggregations =
.get() await this.portfolioServiceNew.getAccountsWithAggregations(
.getAccountsWithAggregations(impersonationUserId || this.request.user.id); impersonationUserId || this.request.user.id
);
if ( if (
impersonationUserId || impersonationUserId ||

26
apps/api/src/app/portfolio/portfolio-service.strategy.ts

@ -1,26 +0,0 @@
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';
@Injectable()
export class PortfolioServiceStrategy {
public constructor(
private readonly portfolioService: PortfolioService,
private readonly portfolioServiceNew: PortfolioServiceNew,
@Inject(REQUEST) private readonly request: RequestWithUser
) {}
public get(newCalculationEngine?: boolean) {
if (
newCalculationEngine ||
this.request.user?.Settings?.settings?.['isNewCalculationEngine'] === true
) {
return this.portfolioServiceNew;
}
return this.portfolioService;
}
}

58
apps/api/src/app/portfolio/portfolio.controller.ts

@ -38,7 +38,7 @@ import { StatusCodes, getReasonPhrase } from 'http-status-codes';
import { PortfolioPositionDetail } from './interfaces/portfolio-position-detail.interface'; import { PortfolioPositionDetail } from './interfaces/portfolio-position-detail.interface';
import { PortfolioPositions } from './interfaces/portfolio-positions.interface'; import { PortfolioPositions } from './interfaces/portfolio-positions.interface';
import { PortfolioServiceStrategy } from './portfolio-service.strategy'; import { PortfolioServiceNew } from './portfolio.service-new';
@Controller('portfolio') @Controller('portfolio')
export class PortfolioController { export class PortfolioController {
@ -46,7 +46,7 @@ export class PortfolioController {
private readonly accessService: AccessService, private readonly accessService: AccessService,
private readonly configurationService: ConfigurationService, private readonly configurationService: ConfigurationService,
private readonly exchangeRateDataService: ExchangeRateDataService, private readonly exchangeRateDataService: ExchangeRateDataService,
private readonly portfolioServiceStrategy: PortfolioServiceStrategy, private readonly portfolioServiceNew: PortfolioServiceNew,
@Inject(REQUEST) private readonly request: RequestWithUser, @Inject(REQUEST) private readonly request: RequestWithUser,
private readonly userService: UserService private readonly userService: UserService
) {} ) {}
@ -57,9 +57,10 @@ export class PortfolioController {
@Headers('impersonation-id') impersonationId: string, @Headers('impersonation-id') impersonationId: string,
@Query('range') range @Query('range') range
): Promise<PortfolioChart> { ): Promise<PortfolioChart> {
const historicalDataContainer = await this.portfolioServiceStrategy const historicalDataContainer = await this.portfolioServiceNew.getChart(
.get() impersonationId,
.getChart(impersonationId, range); range
);
let chartData = historicalDataContainer.items; let chartData = historicalDataContainer.items;
@ -109,9 +110,11 @@ export class PortfolioController {
let hasError = false; let hasError = false;
const { accounts, holdings, hasErrors } = const { accounts, holdings, hasErrors } =
await this.portfolioServiceStrategy await this.portfolioServiceNew.getDetails(
.get(true) impersonationId,
.getDetails(impersonationId, this.request.user.id, range); this.request.user.id,
range
);
if (hasErrors || hasNotDefinedValuesInObject(holdings)) { if (hasErrors || hasNotDefinedValuesInObject(holdings)) {
hasError = true; hasError = true;
@ -174,9 +177,9 @@ export class PortfolioController {
); );
} }
let investments = await this.portfolioServiceStrategy let investments = await this.portfolioServiceNew.getInvestments(
.get() impersonationId
.getInvestments(impersonationId); );
if ( if (
impersonationId || impersonationId ||
@ -203,9 +206,8 @@ export class PortfolioController {
@Headers('impersonation-id') impersonationId: string, @Headers('impersonation-id') impersonationId: string,
@Query('range') range @Query('range') range
): Promise<PortfolioPerformanceResponse> { ): Promise<PortfolioPerformanceResponse> {
const performanceInformation = await this.portfolioServiceStrategy const performanceInformation =
.get() await this.portfolioServiceNew.getPerformance(impersonationId, range);
.getPerformance(impersonationId, range);
if ( if (
impersonationId || impersonationId ||
@ -228,9 +230,10 @@ export class PortfolioController {
@Headers('impersonation-id') impersonationId: string, @Headers('impersonation-id') impersonationId: string,
@Query('range') range @Query('range') range
): Promise<PortfolioPositions> { ): Promise<PortfolioPositions> {
const result = await this.portfolioServiceStrategy const result = await this.portfolioServiceNew.getPositions(
.get() impersonationId,
.getPositions(impersonationId, range); range
);
if ( if (
impersonationId || impersonationId ||
@ -270,9 +273,10 @@ export class PortfolioController {
hasDetails = user.subscription.type === 'Premium'; hasDetails = user.subscription.type === 'Premium';
} }
const { holdings } = await this.portfolioServiceStrategy const { holdings } = await this.portfolioServiceNew.getDetails(
.get(true) access.userId,
.getDetails(access.userId, access.userId); access.userId
);
const portfolioPublicDetails: PortfolioPublicDetails = { const portfolioPublicDetails: PortfolioPublicDetails = {
hasDetails, hasDetails,
@ -324,9 +328,7 @@ export class PortfolioController {
); );
} }
let summary = await this.portfolioServiceStrategy let summary = await this.portfolioServiceNew.getSummary(impersonationId);
.get()
.getSummary(impersonationId);
if ( if (
impersonationId || impersonationId ||
@ -360,9 +362,11 @@ export class PortfolioController {
@Param('dataSource') dataSource, @Param('dataSource') dataSource,
@Param('symbol') symbol @Param('symbol') symbol
): Promise<PortfolioPositionDetail> { ): Promise<PortfolioPositionDetail> {
let position = await this.portfolioServiceStrategy let position = await this.portfolioServiceNew.getPosition(
.get() dataSource,
.getPosition(dataSource, impersonationId, symbol); impersonationId,
symbol
);
if (position) { if (position) {
if ( if (
@ -403,6 +407,6 @@ export class PortfolioController {
); );
} }
return await this.portfolioServiceStrategy.get().getReport(impersonationId); return await this.portfolioServiceNew.getReport(impersonationId);
} }
} }

4
apps/api/src/app/portfolio/portfolio.module.ts

@ -13,7 +13,6 @@ import { SymbolProfileModule } from '@ghostfolio/api/services/symbol-profile.mod
import { Module } from '@nestjs/common'; import { Module } from '@nestjs/common';
import { CurrentRateService } from './current-rate.service'; import { CurrentRateService } from './current-rate.service';
import { PortfolioServiceStrategy } from './portfolio-service.strategy';
import { PortfolioController } from './portfolio.controller'; import { PortfolioController } from './portfolio.controller';
import { PortfolioService } from './portfolio.service'; import { PortfolioService } from './portfolio.service';
import { PortfolioServiceNew } from './portfolio.service-new'; import { PortfolioServiceNew } from './portfolio.service-new';
@ -21,7 +20,7 @@ import { RulesService } from './rules.service';
@Module({ @Module({
controllers: [PortfolioController], controllers: [PortfolioController],
exports: [PortfolioServiceStrategy], exports: [PortfolioServiceNew],
imports: [ imports: [
AccessModule, AccessModule,
ConfigurationModule, ConfigurationModule,
@ -40,7 +39,6 @@ import { RulesService } from './rules.service';
CurrentRateService, CurrentRateService,
PortfolioService, PortfolioService,
PortfolioServiceNew, PortfolioServiceNew,
PortfolioServiceStrategy,
RulesService RulesService
] ]
}) })

1
apps/api/src/app/user/interfaces/user-settings.interface.ts

@ -1,6 +1,5 @@
export interface UserSettings { export interface UserSettings {
emergencyFund?: number; emergencyFund?: number;
locale?: string; locale?: string;
isNewCalculationEngine?: boolean;
isRestrictedView?: boolean; isRestrictedView?: boolean;
} }

4
apps/api/src/app/user/update-user-setting.dto.ts

@ -5,10 +5,6 @@ export class UpdateUserSettingDto {
@IsOptional() @IsOptional()
emergencyFund?: number; emergencyFund?: number;
@IsBoolean()
@IsOptional()
isNewCalculationEngine?: boolean;
@IsBoolean() @IsBoolean()
@IsOptional() @IsOptional()
isRestrictedView?: boolean; isRestrictedView?: boolean;

18
apps/client/src/app/pages/account/account-page.component.ts

@ -222,24 +222,6 @@ 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() { public onRedeemCoupon() {
let couponCode = prompt('Please enter your coupon code:'); let couponCode = prompt('Please enter your coupon code:');
couponCode = couponCode?.trim(); couponCode = couponCode?.trim();

17
apps/client/src/app/pages/account/account-page.html

@ -169,23 +169,6 @@
></mat-slide-toggle> ></mat-slide-toggle>
</div> </div>
</div> </div>
<div
*ngIf="user?.subscription"
class="align-items-center d-flex mt-4 py-1"
>
<div class="pr-1 w-50">
<div i18n>New Calculation Engine</div>
<div class="hint-text text-muted" i18n>Experimental</div>
</div>
<div class="pl-1 w-50">
<mat-slide-toggle
color="primary"
[checked]="user.settings.isNewCalculationEngine"
[disabled]="!hasPermissionToUpdateUserSettings"
(change)="onNewCalculationChange($event)"
></mat-slide-toggle>
</div>
</div>
</mat-card-content> </mat-card-content>
</mat-card> </mat-card>
</div> </div>

Loading…
Cancel
Save