Browse Source

Refactoring

pull/692/head
Thomas 3 years ago
parent
commit
57eb5bf0ac
  1. 6
      apps/api/src/app/portfolio/interfaces/portfolio-position-detail.interface.ts
  2. 1
      apps/api/src/app/portfolio/portfolio.controller.ts
  3. 16
      apps/api/src/app/portfolio/portfolio.service-new.ts
  4. 16
      apps/api/src/app/portfolio/portfolio.service.ts
  5. 13
      apps/api/src/interceptors/transform-data-source-in-response.interceptor.ts
  6. 18
      apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.component.ts
  7. 10
      apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html

6
apps/api/src/app/portfolio/interfaces/portfolio-position-detail.interface.ts

@ -1,12 +1,8 @@
import { EnhancedSymbolProfile } from '@ghostfolio/api/services/interfaces/symbol-profile.interface'; import { EnhancedSymbolProfile } from '@ghostfolio/api/services/interfaces/symbol-profile.interface';
import { OrderWithAccount } from '@ghostfolio/common/types'; import { OrderWithAccount } from '@ghostfolio/common/types';
import { AssetClass, AssetSubClass } from '@prisma/client';
export interface PortfolioPositionDetail { export interface PortfolioPositionDetail {
assetClass?: AssetClass;
assetSubClass?: AssetSubClass;
averagePrice: number; averagePrice: number;
currency: string;
firstBuyDate: string; firstBuyDate: string;
grossPerformance: number; grossPerformance: number;
grossPerformancePercent: number; grossPerformancePercent: number;
@ -15,13 +11,11 @@ export interface PortfolioPositionDetail {
marketPrice: number; marketPrice: number;
maxPrice: number; maxPrice: number;
minPrice: number; minPrice: number;
name: string;
netPerformance: number; netPerformance: number;
netPerformancePercent: number; netPerformancePercent: number;
orders: OrderWithAccount[]; orders: OrderWithAccount[];
quantity: number; quantity: number;
SymbolProfile: EnhancedSymbolProfile; SymbolProfile: EnhancedSymbolProfile;
symbol: string;
transactionCount: number; transactionCount: number;
value: number; value: number;
} }

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

@ -344,6 +344,7 @@ export class PortfolioController {
@Get('position/:dataSource/:symbol') @Get('position/:dataSource/:symbol')
@UseInterceptors(TransformDataSourceInRequestInterceptor) @UseInterceptors(TransformDataSourceInRequestInterceptor)
@UseInterceptors(TransformDataSourceInResponseInterceptor)
@UseGuards(AuthGuard('jwt')) @UseGuards(AuthGuard('jwt'))
public async getPosition( public async getPosition(
@Headers('impersonation-id') impersonationId: string, @Headers('impersonation-id') impersonationId: string,

16
apps/api/src/app/portfolio/portfolio.service-new.ts

@ -417,7 +417,6 @@ export class PortfolioServiceNew {
if (orders.length <= 0) { if (orders.length <= 0) {
return { return {
averagePrice: undefined, averagePrice: undefined,
currency: undefined,
firstBuyDate: undefined, firstBuyDate: undefined,
grossPerformance: undefined, grossPerformance: undefined,
grossPerformancePercent: undefined, grossPerformancePercent: undefined,
@ -426,21 +425,16 @@ export class PortfolioServiceNew {
marketPrice: undefined, marketPrice: undefined,
maxPrice: undefined, maxPrice: undefined,
minPrice: undefined, minPrice: undefined,
name: undefined,
netPerformance: undefined, netPerformance: undefined,
netPerformancePercent: undefined, netPerformancePercent: undefined,
orders: [], orders: [],
quantity: undefined, quantity: undefined,
symbol: aSymbol,
SymbolProfile: undefined, SymbolProfile: undefined,
transactionCount: undefined, transactionCount: undefined,
value: undefined value: undefined
}; };
} }
const assetClass = orders[0].SymbolProfile?.assetClass;
const assetSubClass = orders[0].SymbolProfile?.assetSubClass;
const name = orders[0].SymbolProfile?.name ?? '';
const positionCurrency = orders[0].currency; const positionCurrency = orders[0].currency;
const [SymbolProfile] = await this.symbolProfileService.getSymbolProfiles([ const [SymbolProfile] = await this.symbolProfileService.getSymbolProfiles([
aSymbol aSymbol
@ -561,16 +555,12 @@ export class PortfolioServiceNew {
} }
return { return {
assetClass,
assetSubClass,
currency,
firstBuyDate, firstBuyDate,
grossPerformance, grossPerformance,
investment, investment,
marketPrice, marketPrice,
maxPrice, maxPrice,
minPrice, minPrice,
name,
netPerformance, netPerformance,
orders, orders,
SymbolProfile, SymbolProfile,
@ -581,7 +571,6 @@ export class PortfolioServiceNew {
historicalData: historicalDataArray, historicalData: historicalDataArray,
netPerformancePercent: position.netPerformancePercentage?.toNumber(), netPerformancePercent: position.netPerformancePercentage?.toNumber(),
quantity: quantity.toNumber(), quantity: quantity.toNumber(),
symbol: aSymbol,
value: this.exchangeRateDataService.toCurrency( value: this.exchangeRateDataService.toCurrency(
quantity.mul(marketPrice).toNumber(), quantity.mul(marketPrice).toNumber(),
currency, currency,
@ -626,16 +615,12 @@ export class PortfolioServiceNew {
} }
return { return {
assetClass,
assetSubClass,
marketPrice, marketPrice,
maxPrice, maxPrice,
minPrice, minPrice,
name,
orders, orders,
SymbolProfile, SymbolProfile,
averagePrice: 0, averagePrice: 0,
currency: currentData[aSymbol]?.currency,
firstBuyDate: undefined, firstBuyDate: undefined,
grossPerformance: undefined, grossPerformance: undefined,
grossPerformancePercent: undefined, grossPerformancePercent: undefined,
@ -644,7 +629,6 @@ export class PortfolioServiceNew {
netPerformance: undefined, netPerformance: undefined,
netPerformancePercent: undefined, netPerformancePercent: undefined,
quantity: 0, quantity: 0,
symbol: aSymbol,
transactionCount: undefined, transactionCount: undefined,
value: 0 value: 0
}; };

16
apps/api/src/app/portfolio/portfolio.service.ts

@ -405,7 +405,6 @@ export class PortfolioService {
if (orders.length <= 0) { if (orders.length <= 0) {
return { return {
averagePrice: undefined, averagePrice: undefined,
currency: undefined,
firstBuyDate: undefined, firstBuyDate: undefined,
grossPerformance: undefined, grossPerformance: undefined,
grossPerformancePercent: undefined, grossPerformancePercent: undefined,
@ -414,21 +413,16 @@ export class PortfolioService {
marketPrice: undefined, marketPrice: undefined,
maxPrice: undefined, maxPrice: undefined,
minPrice: undefined, minPrice: undefined,
name: undefined,
netPerformance: undefined, netPerformance: undefined,
netPerformancePercent: undefined, netPerformancePercent: undefined,
orders: [], orders: [],
quantity: undefined, quantity: undefined,
symbol: aSymbol,
SymbolProfile: undefined, SymbolProfile: undefined,
transactionCount: undefined, transactionCount: undefined,
value: undefined value: undefined
}; };
} }
const assetClass = orders[0].SymbolProfile?.assetClass;
const assetSubClass = orders[0].SymbolProfile?.assetSubClass;
const name = orders[0].SymbolProfile?.name ?? '';
const positionCurrency = orders[0].currency; const positionCurrency = orders[0].currency;
const [SymbolProfile] = await this.symbolProfileService.getSymbolProfiles([ const [SymbolProfile] = await this.symbolProfileService.getSymbolProfiles([
aSymbol aSymbol
@ -547,16 +541,12 @@ export class PortfolioService {
} }
return { return {
assetClass,
assetSubClass,
currency,
firstBuyDate, firstBuyDate,
grossPerformance, grossPerformance,
investment, investment,
marketPrice, marketPrice,
maxPrice, maxPrice,
minPrice, minPrice,
name,
netPerformance, netPerformance,
orders, orders,
SymbolProfile, SymbolProfile,
@ -566,7 +556,6 @@ export class PortfolioService {
historicalData: historicalDataArray, historicalData: historicalDataArray,
netPerformancePercent: position.netPerformancePercentage.toNumber(), netPerformancePercent: position.netPerformancePercentage.toNumber(),
quantity: quantity.toNumber(), quantity: quantity.toNumber(),
symbol: aSymbol,
value: this.exchangeRateDataService.toCurrency( value: this.exchangeRateDataService.toCurrency(
quantity.mul(marketPrice).toNumber(), quantity.mul(marketPrice).toNumber(),
currency, currency,
@ -611,16 +600,12 @@ export class PortfolioService {
} }
return { return {
assetClass,
assetSubClass,
marketPrice, marketPrice,
maxPrice, maxPrice,
minPrice, minPrice,
name,
orders, orders,
SymbolProfile, SymbolProfile,
averagePrice: 0, averagePrice: 0,
currency: currentData[aSymbol]?.currency,
firstBuyDate: undefined, firstBuyDate: undefined,
grossPerformance: undefined, grossPerformance: undefined,
grossPerformancePercent: undefined, grossPerformancePercent: undefined,
@ -629,7 +614,6 @@ export class PortfolioService {
netPerformance: undefined, netPerformance: undefined,
netPerformancePercent: undefined, netPerformancePercent: undefined,
quantity: 0, quantity: 0,
symbol: aSymbol,
transactionCount: undefined, transactionCount: undefined,
value: 0 value: 0
}; };

13
apps/api/src/interceptors/transform-data-source-in-response.interceptor.ts

@ -58,12 +58,25 @@ export class TransformDataSourceInResponseInterceptor<T>
}); });
} }
if (data.orders) {
data.orders.map((order) => {
order.dataSource = encodeDataSource(order.dataSource);
return order;
});
}
if (data.positions) { if (data.positions) {
data.positions.map((position) => { data.positions.map((position) => {
position.dataSource = encodeDataSource(position.dataSource); position.dataSource = encodeDataSource(position.dataSource);
return position; return position;
}); });
} }
if (data.SymbolProfile) {
data.SymbolProfile.dataSource = encodeDataSource(
data.SymbolProfile.dataSource
);
}
} }
return data; return data;

18
apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.component.ts

@ -11,7 +11,7 @@ import { DataService } from '@ghostfolio/client/services/data.service';
import { DATE_FORMAT, downloadAsFile } from '@ghostfolio/common/helper'; import { DATE_FORMAT, downloadAsFile } from '@ghostfolio/common/helper';
import { OrderWithAccount } from '@ghostfolio/common/types'; import { OrderWithAccount } from '@ghostfolio/common/types';
import { LineChartItem } from '@ghostfolio/ui/line-chart/interfaces/line-chart.interface'; import { LineChartItem } from '@ghostfolio/ui/line-chart/interfaces/line-chart.interface';
import { AssetSubClass, SymbolProfile } from '@prisma/client'; import { SymbolProfile } from '@prisma/client';
import { format, isSameMonth, isToday, parseISO } from 'date-fns'; import { format, isSameMonth, isToday, parseISO } from 'date-fns';
import { Subject } from 'rxjs'; import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators'; import { takeUntil } from 'rxjs/operators';
@ -26,13 +26,11 @@ import { PositionDetailDialogParams } from './interfaces/interfaces';
styleUrls: ['./position-detail-dialog.component.scss'] styleUrls: ['./position-detail-dialog.component.scss']
}) })
export class PositionDetailDialog implements OnDestroy, OnInit { export class PositionDetailDialog implements OnDestroy, OnInit {
public assetSubClass: AssetSubClass;
public averagePrice: number; public averagePrice: number;
public benchmarkDataItems: LineChartItem[]; public benchmarkDataItems: LineChartItem[];
public countries: { public countries: {
[code: string]: { name: string; value: number }; [code: string]: { name: string; value: number };
}; };
public currency: string;
public firstBuyDate: string; public firstBuyDate: string;
public grossPerformance: number; public grossPerformance: number;
public grossPerformancePercent: number; public grossPerformancePercent: number;
@ -41,7 +39,6 @@ export class PositionDetailDialog implements OnDestroy, OnInit {
public marketPrice: number; public marketPrice: number;
public maxPrice: number; public maxPrice: number;
public minPrice: number; public minPrice: number;
public name: string;
public netPerformance: number; public netPerformance: number;
public netPerformancePercent: number; public netPerformancePercent: number;
public orders: OrderWithAccount[]; public orders: OrderWithAccount[];
@ -50,7 +47,6 @@ export class PositionDetailDialog implements OnDestroy, OnInit {
public sectors: { public sectors: {
[name: string]: { name: string; value: number }; [name: string]: { name: string; value: number };
}; };
public symbol: string;
public SymbolProfile: SymbolProfile; public SymbolProfile: SymbolProfile;
public transactionCount: number; public transactionCount: number;
public value: number; public value: number;
@ -73,9 +69,7 @@ export class PositionDetailDialog implements OnDestroy, OnInit {
.pipe(takeUntil(this.unsubscribeSubject)) .pipe(takeUntil(this.unsubscribeSubject))
.subscribe( .subscribe(
({ ({
assetSubClass,
averagePrice, averagePrice,
currency,
firstBuyDate, firstBuyDate,
grossPerformance, grossPerformance,
grossPerformancePercent, grossPerformancePercent,
@ -84,21 +78,17 @@ export class PositionDetailDialog implements OnDestroy, OnInit {
marketPrice, marketPrice,
maxPrice, maxPrice,
minPrice, minPrice,
name,
netPerformance, netPerformance,
netPerformancePercent, netPerformancePercent,
orders, orders,
quantity, quantity,
symbol,
SymbolProfile, SymbolProfile,
transactionCount, transactionCount,
value value
}) => { }) => {
this.assetSubClass = assetSubClass;
this.averagePrice = averagePrice; this.averagePrice = averagePrice;
this.benchmarkDataItems = []; this.benchmarkDataItems = [];
this.countries = {}; this.countries = {};
this.currency = currency;
this.firstBuyDate = firstBuyDate; this.firstBuyDate = firstBuyDate;
this.grossPerformance = grossPerformance; this.grossPerformance = grossPerformance;
this.grossPerformancePercent = grossPerformancePercent; this.grossPerformancePercent = grossPerformancePercent;
@ -119,13 +109,11 @@ export class PositionDetailDialog implements OnDestroy, OnInit {
this.marketPrice = marketPrice; this.marketPrice = marketPrice;
this.maxPrice = maxPrice; this.maxPrice = maxPrice;
this.minPrice = minPrice; this.minPrice = minPrice;
this.name = name;
this.netPerformance = netPerformance; this.netPerformance = netPerformance;
this.netPerformancePercent = netPerformancePercent; this.netPerformancePercent = netPerformancePercent;
this.orders = orders; this.orders = orders;
this.quantity = quantity; this.quantity = quantity;
this.sectors = {}; this.sectors = {};
this.symbol = symbol;
this.SymbolProfile = SymbolProfile; this.SymbolProfile = SymbolProfile;
this.transactionCount = transactionCount; this.transactionCount = transactionCount;
this.value = value; this.value = value;
@ -195,7 +183,7 @@ export class PositionDetailDialog implements OnDestroy, OnInit {
if (Number.isInteger(this.quantity)) { if (Number.isInteger(this.quantity)) {
this.quantityPrecision = 0; this.quantityPrecision = 0;
} else if (assetSubClass === 'CRYPTOCURRENCY') { } else if (this.SymbolProfile?.assetSubClass === 'CRYPTOCURRENCY') {
if (this.quantity < 1) { if (this.quantity < 1) {
this.quantityPrecision = 7; this.quantityPrecision = 7;
} else if (this.quantity < 1000) { } else if (this.quantity < 1000) {
@ -225,7 +213,7 @@ export class PositionDetailDialog implements OnDestroy, OnInit {
.subscribe((data) => { .subscribe((data) => {
downloadAsFile( downloadAsFile(
data, data,
`ghostfolio-export-${this.symbol}-${format( `ghostfolio-export-${this.SymbolProfile?.symbol}-${format(
parseISO(data.meta.date), parseISO(data.meta.date),
'yyyyMMddHHmm' 'yyyyMMddHHmm'
)}.json`, )}.json`,

10
apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html

@ -2,7 +2,7 @@
mat-dialog-title mat-dialog-title
position="center" position="center"
[deviceType]="data.deviceType" [deviceType]="data.deviceType"
[title]="name ?? symbol" [title]="SymbolProfile?.name ?? SymbolProfile?.symbol"
(closeButtonClicked)="onClose()" (closeButtonClicked)="onClose()"
></gf-dialog-header> ></gf-dialog-header>
@ -55,7 +55,7 @@
<gf-value <gf-value
label="Ø Buy Price" label="Ø Buy Price"
size="medium" size="medium"
[currency]="currency" [currency]="SymbolProfile?.currency"
[locale]="data.locale" [locale]="data.locale"
[value]="averagePrice" [value]="averagePrice"
></gf-value> ></gf-value>
@ -64,7 +64,7 @@
<gf-value <gf-value
label="Market Price" label="Market Price"
size="medium" size="medium"
[currency]="currency" [currency]="SymbolProfile?.currency"
[locale]="data.locale" [locale]="data.locale"
[value]="marketPrice" [value]="marketPrice"
></gf-value> ></gf-value>
@ -73,7 +73,7 @@
<gf-value <gf-value
label="Minimum Price" label="Minimum Price"
size="medium" size="medium"
[currency]="currency" [currency]="SymbolProfile?.currency"
[locale]="data.locale" [locale]="data.locale"
[ngClass]="{ 'text-danger': minPrice?.toFixed(2) === marketPrice?.toFixed(2) && maxPrice?.toFixed(2) !== minPrice?.toFixed(2) }" [ngClass]="{ 'text-danger': minPrice?.toFixed(2) === marketPrice?.toFixed(2) && maxPrice?.toFixed(2) !== minPrice?.toFixed(2) }"
[value]="minPrice" [value]="minPrice"
@ -83,7 +83,7 @@
<gf-value <gf-value
label="Maximum Price" label="Maximum Price"
size="medium" size="medium"
[currency]="currency" [currency]="SymbolProfile?.currency"
[locale]="data.locale" [locale]="data.locale"
[ngClass]="{ 'text-success': maxPrice?.toFixed(2) === marketPrice?.toFixed(2) && maxPrice?.toFixed(2) !== minPrice?.toFixed(2) }" [ngClass]="{ 'text-success': maxPrice?.toFixed(2) === marketPrice?.toFixed(2) && maxPrice?.toFixed(2) !== minPrice?.toFixed(2) }"
[value]="maxPrice" [value]="maxPrice"

Loading…
Cancel
Save