From 666d967888ebe285fdd0b55ef858e7f5cf885339 Mon Sep 17 00:00:00 2001 From: yksolanki9 Date: Mon, 2 Jan 2023 19:29:13 +0530 Subject: [PATCH] Add option to group investments by year --- .../src/app/portfolio/portfolio-calculator.ts | 33 ++++++++++++------- .../src/app/portfolio/portfolio.service.ts | 33 +++++++++++-------- .../analysis/analysis-page.component.ts | 3 +- libs/common/src/lib/types/group-by.type.ts | 2 +- 4 files changed, 43 insertions(+), 28 deletions(-) diff --git a/apps/api/src/app/portfolio/portfolio-calculator.ts b/apps/api/src/app/portfolio/portfolio-calculator.ts index 2d14b9011..6225ae787 100644 --- a/apps/api/src/app/portfolio/portfolio-calculator.ts +++ b/apps/api/src/app/portfolio/portfolio-calculator.ts @@ -2,6 +2,7 @@ import { TimelineInfoInterface } from '@ghostfolio/api/app/portfolio/interfaces/ import { IDataGatheringItem } from '@ghostfolio/api/services/interfaces/interfaces'; import { DATE_FORMAT, parseDate, resetHours } from '@ghostfolio/common/helper'; import { ResponseError, TimelinePosition } from '@ghostfolio/common/interfaces'; +import { GroupBy } from '@ghostfolio/common/types'; import { Logger } from '@nestjs/common'; import { Type as TypeOfOrder } from '@prisma/client'; import Big from 'big.js'; @@ -478,46 +479,54 @@ export class PortfolioCalculator { }); } - public getInvestmentsByMonth(): { date: string; investment: Big }[] { + public getInvestmentsByGroup( + groupBy: GroupBy + ): { date: string; investment: Big }[] { if (this.orders.length === 0) { return []; } const investments = []; let currentDate: Date; - let investmentByMonth = new Big(0); + let investmentByGroup = new Big(0); for (const [index, order] of this.orders.entries()) { if ( - isSameMonth(parseDate(order.date), currentDate) && - isSameYear(parseDate(order.date), currentDate) + isSameYear(parseDate(order.date), currentDate) && + (groupBy === 'year' || isSameMonth(parseDate(order.date), currentDate)) ) { - // Same month: Add up investments + // Same group: Add up investments - investmentByMonth = investmentByMonth.plus( + investmentByGroup = investmentByGroup.plus( order.quantity.mul(order.unitPrice).mul(this.getFactor(order.type)) ); } else { - // New month: Store previous month and reset + // New group: Store previous group and reset if (currentDate) { investments.push({ date: format(set(currentDate, { date: 1 }), DATE_FORMAT), - investment: investmentByMonth + investment: investmentByGroup }); } currentDate = parseDate(order.date); - investmentByMonth = order.quantity + investmentByGroup = order.quantity .mul(order.unitPrice) .mul(this.getFactor(order.type)); } if (index === this.orders.length - 1) { - // Store current month (latest order) + // Store current group (latest order) investments.push({ - date: format(set(currentDate, { date: 1 }), DATE_FORMAT), - investment: investmentByMonth + date: format( + set( + currentDate, + groupBy === 'month' ? { date: 1 } : { date: 1, month: 1 } + ), + DATE_FORMAT + ), + investment: investmentByGroup }); } } diff --git a/apps/api/src/app/portfolio/portfolio.service.ts b/apps/api/src/app/portfolio/portfolio.service.ts index 21654f531..74a366702 100644 --- a/apps/api/src/app/portfolio/portfolio.service.ts +++ b/apps/api/src/app/portfolio/portfolio.service.ts @@ -282,26 +282,31 @@ export class PortfolioService { let investments: InvestmentItem[]; - if (groupBy === 'month') { - investments = portfolioCalculator.getInvestmentsByMonth().map((item) => { - return { - date: item.date, - investment: item.investment.toNumber() - }; - }); + if (groupBy) { + investments = portfolioCalculator + .getInvestmentsByGroup(groupBy) + .map((item) => { + return { + date: item.date, + investment: item.investment.toNumber() + }; + }); - // Add investment of current month - const dateOfCurrentMonth = format( - set(new Date(), { date: 1 }), + // Add investment of current group + const dateOfCurrentGroup = format( + set( + new Date(), + groupBy === 'month' ? { date: 1 } : { date: 1, month: 1 } + ), DATE_FORMAT ); - const investmentOfCurrentMonth = investments.filter(({ date }) => { - return date === dateOfCurrentMonth; + const investmentOfCurrentGroup = investments.filter(({ date }) => { + return date === dateOfCurrentGroup; }); - if (investmentOfCurrentMonth.length <= 0) { + if (investmentOfCurrentGroup.length <= 0) { investments.push({ - date: dateOfCurrentMonth, + date: dateOfCurrentGroup, investment: 0 }); } diff --git a/apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts b/apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts index 3fd80923c..130a6244f 100644 --- a/apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts +++ b/apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts @@ -202,6 +202,7 @@ export class AnalysisPageComponent implements OnDestroy, OnInit { public onChangeGroupBy(aMode: GroupBy) { this.mode = aMode; + this.update(); } public ngOnDestroy() { @@ -308,7 +309,7 @@ export class AnalysisPageComponent implements OnDestroy, OnInit { this.dataService .fetchInvestments({ filters: this.activeFilters, - groupBy: 'month', + groupBy: this.mode, range: this.user?.settings?.dateRange }) .pipe(takeUntil(this.unsubscribeSubject)) diff --git a/libs/common/src/lib/types/group-by.type.ts b/libs/common/src/lib/types/group-by.type.ts index d4009a721..01fd67a20 100644 --- a/libs/common/src/lib/types/group-by.type.ts +++ b/libs/common/src/lib/types/group-by.type.ts @@ -1 +1 @@ -export type GroupBy = 'month'; +export type GroupBy = 'month' | 'year';