Feature/refactor various lodash functions with native JavaScript equivalents (#4170)

* Refactored various lodash functions with native JavaScript equivalents

* Update changelog
pull/4184/head^2
Szymon Łągiewka 5 days ago committed by GitHub
parent 80bb1b1f64
commit ca45098de3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## Unreleased ## Unreleased
### Changed
- Refactored various `lodash` functions with native JavaScript equivalents
### Fixed ### Fixed
- Fixed an issue with the renaming of activities with type `FEE`, `INTEREST`, `ITEM` or `LIABILITY` - Fixed an issue with the renaming of activities with type `FEE`, `INTEREST`, `ITEM` or `LIABILITY`

@ -38,7 +38,7 @@ import {
isSameDay, isSameDay,
subDays subDays
} from 'date-fns'; } from 'date-fns';
import { isNumber, last, uniqBy } from 'lodash'; import { isNumber, uniqBy } from 'lodash';
import ms from 'ms'; import ms from 'ms';
import { BenchmarkValue } from './interfaces/benchmark-value.interface'; import { BenchmarkValue } from './interfaces/benchmark-value.interface';
@ -258,7 +258,7 @@ export class BenchmarkService {
} }
const includesEndDate = isSameDay( const includesEndDate = isSameDay(
parseDate(last(marketData).date), parseDate(marketData.at(-1).date),
endDate endDate
); );

@ -49,7 +49,7 @@ import {
min, min,
subDays subDays
} from 'date-fns'; } from 'date-fns';
import { first, isNumber, last, sortBy, sum, uniq, uniqBy } from 'lodash'; import { isNumber, sortBy, sum, uniq, uniqBy } from 'lodash';
export abstract class PortfolioCalculator { export abstract class PortfolioCalculator {
protected static readonly ENABLE_LOGGING = false; protected static readonly ENABLE_LOGGING = false;
@ -167,7 +167,7 @@ export abstract class PortfolioCalculator {
@LogPerformance @LogPerformance
public async computeSnapshot(): Promise<PortfolioSnapshot> { public async computeSnapshot(): Promise<PortfolioSnapshot> {
const lastTransactionPoint = last(this.transactionPoints); const lastTransactionPoint = this.transactionPoints.at(-1);
const transactionPoints = this.transactionPoints?.filter(({ date }) => { const transactionPoints = this.transactionPoints?.filter(({ date }) => {
return isBefore(parseDate(date), this.endDate); return isBefore(parseDate(date), this.endDate);
@ -772,9 +772,7 @@ export abstract class PortfolioCalculator {
let firstActivityDate: Date; let firstActivityDate: Date;
try { try {
const firstAccountBalanceDateString = first( const firstAccountBalanceDateString = this.accountBalanceItems[0]?.date;
this.accountBalanceItems
)?.date;
firstAccountBalanceDate = firstAccountBalanceDateString firstAccountBalanceDate = firstAccountBalanceDateString
? parseDate(firstAccountBalanceDateString) ? parseDate(firstAccountBalanceDateString)
: new Date(); : new Date();

@ -19,7 +19,6 @@ import { PortfolioSnapshotServiceMock } from '@ghostfolio/api/services/queues/po
import { parseDate } from '@ghostfolio/common/helper'; import { parseDate } from '@ghostfolio/common/helper';
import { Big } from 'big.js'; import { Big } from 'big.js';
import { last } from 'lodash';
jest.mock('@ghostfolio/api/app/portfolio/current-rate.service', () => { jest.mock('@ghostfolio/api/app/portfolio/current-rate.service', () => {
return { return {
@ -201,7 +200,7 @@ describe('PortfolioCalculator', () => {
totalValuablesWithCurrencyEffect: new Big('0') totalValuablesWithCurrencyEffect: new Big('0')
}); });
expect(last(portfolioSnapshot.historicalData)).toMatchObject( expect(portfolioSnapshot.historicalData.at(-1)).toMatchObject(
expect.objectContaining({ expect.objectContaining({
netPerformance: -15.8, netPerformance: -15.8,
netPerformanceInPercentage: -0.05528341497550734703, netPerformanceInPercentage: -0.05528341497550734703,

@ -19,7 +19,6 @@ import { PortfolioSnapshotServiceMock } from '@ghostfolio/api/services/queues/po
import { parseDate } from '@ghostfolio/common/helper'; import { parseDate } from '@ghostfolio/common/helper';
import { Big } from 'big.js'; import { Big } from 'big.js';
import { last } from 'lodash';
jest.mock('@ghostfolio/api/app/portfolio/current-rate.service', () => { jest.mock('@ghostfolio/api/app/portfolio/current-rate.service', () => {
return { return {
@ -186,7 +185,7 @@ describe('PortfolioCalculator', () => {
totalValuablesWithCurrencyEffect: new Big('0') totalValuablesWithCurrencyEffect: new Big('0')
}); });
expect(last(portfolioSnapshot.historicalData)).toMatchObject( expect(portfolioSnapshot.historicalData.at(-1)).toMatchObject(
expect.objectContaining({ expect.objectContaining({
netPerformance: -15.8, netPerformance: -15.8,
netPerformanceInPercentage: -0.05528341497550734703, netPerformanceInPercentage: -0.05528341497550734703,

@ -19,7 +19,6 @@ import { PortfolioSnapshotServiceMock } from '@ghostfolio/api/services/queues/po
import { parseDate } from '@ghostfolio/common/helper'; import { parseDate } from '@ghostfolio/common/helper';
import { Big } from 'big.js'; import { Big } from 'big.js';
import { last } from 'lodash';
jest.mock('@ghostfolio/api/app/portfolio/current-rate.service', () => { jest.mock('@ghostfolio/api/app/portfolio/current-rate.service', () => {
return { return {
@ -177,7 +176,7 @@ describe('PortfolioCalculator', () => {
totalValuablesWithCurrencyEffect: new Big('0') totalValuablesWithCurrencyEffect: new Big('0')
}); });
expect(last(portfolioSnapshot.historicalData)).toMatchObject( expect(portfolioSnapshot.historicalData.at(-1)).toMatchObject(
expect.objectContaining({ expect.objectContaining({
netPerformance: 23.05, netPerformance: 23.05,
netPerformanceInPercentage: 0.08437042459736457, netPerformanceInPercentage: 0.08437042459736457,

@ -20,7 +20,6 @@ import { PortfolioSnapshotServiceMock } from '@ghostfolio/api/services/queues/po
import { parseDate } from '@ghostfolio/common/helper'; import { parseDate } from '@ghostfolio/common/helper';
import { Big } from 'big.js'; import { Big } from 'big.js';
import { last } from 'lodash';
jest.mock('@ghostfolio/api/app/portfolio/current-rate.service', () => { jest.mock('@ghostfolio/api/app/portfolio/current-rate.service', () => {
return { return {
@ -205,7 +204,7 @@ describe('PortfolioCalculator', () => {
totalValuablesWithCurrencyEffect: new Big('0') totalValuablesWithCurrencyEffect: new Big('0')
}); });
expect(last(portfolioSnapshot.historicalData)).toMatchObject( expect(portfolioSnapshot.historicalData.at(-1)).toMatchObject(
expect.objectContaining({ expect.objectContaining({
netPerformance: new Big('27172.74').mul(0.97373).toNumber(), netPerformance: new Big('27172.74').mul(0.97373).toNumber(),
netPerformanceInPercentage: 42.41983590271396609433, netPerformanceInPercentage: 42.41983590271396609433,

@ -19,7 +19,6 @@ import { PortfolioSnapshotServiceMock } from '@ghostfolio/api/services/queues/po
import { parseDate } from '@ghostfolio/common/helper'; import { parseDate } from '@ghostfolio/common/helper';
import { Big } from 'big.js'; import { Big } from 'big.js';
import { last } from 'lodash';
jest.mock('@ghostfolio/api/app/portfolio/current-rate.service', () => { jest.mock('@ghostfolio/api/app/portfolio/current-rate.service', () => {
return { return {
@ -158,7 +157,7 @@ describe('PortfolioCalculator', () => {
totalValuablesWithCurrencyEffect: new Big('0') totalValuablesWithCurrencyEffect: new Big('0')
}); });
expect(last(portfolioSnapshot.historicalData)).toMatchObject( expect(portfolioSnapshot.historicalData.at(-1)).toMatchObject(
expect.objectContaining({ expect.objectContaining({
netPerformance: 0, netPerformance: 0,
netPerformanceInPercentage: 0, netPerformanceInPercentage: 0,

@ -20,7 +20,6 @@ import { PortfolioSnapshotServiceMock } from '@ghostfolio/api/services/queues/po
import { parseDate } from '@ghostfolio/common/helper'; import { parseDate } from '@ghostfolio/common/helper';
import { Big } from 'big.js'; import { Big } from 'big.js';
import { last } from 'lodash';
jest.mock('@ghostfolio/api/app/portfolio/current-rate.service', () => { jest.mock('@ghostfolio/api/app/portfolio/current-rate.service', () => {
return { return {
@ -184,7 +183,7 @@ describe('PortfolioCalculator', () => {
totalValuablesWithCurrencyEffect: new Big('0') totalValuablesWithCurrencyEffect: new Big('0')
}); });
expect(last(portfolioSnapshot.historicalData)).toMatchObject( expect(portfolioSnapshot.historicalData.at(-1)).toMatchObject(
expect.objectContaining({ expect.objectContaining({
netPerformance: new Big('26.33').mul(0.8854).toNumber(), netPerformance: new Big('26.33').mul(0.8854).toNumber(),
netPerformanceInPercentage: 0.29544434470377019749, netPerformanceInPercentage: 0.29544434470377019749,

@ -19,7 +19,6 @@ import { PortfolioSnapshotServiceMock } from '@ghostfolio/api/services/queues/po
import { parseDate } from '@ghostfolio/common/helper'; import { parseDate } from '@ghostfolio/common/helper';
import { Big } from 'big.js'; import { Big } from 'big.js';
import { last } from 'lodash';
jest.mock('@ghostfolio/api/app/portfolio/current-rate.service', () => { jest.mock('@ghostfolio/api/app/portfolio/current-rate.service', () => {
return { return {
@ -158,7 +157,7 @@ describe('PortfolioCalculator', () => {
totalValuablesWithCurrencyEffect: new Big('0') totalValuablesWithCurrencyEffect: new Big('0')
}); });
expect(last(portfolioSnapshot.historicalData)).toMatchObject( expect(portfolioSnapshot.historicalData.at(-1)).toMatchObject(
expect.objectContaining({ expect.objectContaining({
netPerformance: 0, netPerformance: 0,
netPerformanceInPercentage: 0, netPerformanceInPercentage: 0,

@ -20,7 +20,6 @@ import { PortfolioSnapshotServiceMock } from '@ghostfolio/api/services/queues/po
import { parseDate } from '@ghostfolio/common/helper'; import { parseDate } from '@ghostfolio/common/helper';
import { Big } from 'big.js'; import { Big } from 'big.js';
import { last } from 'lodash';
jest.mock('@ghostfolio/api/app/portfolio/current-rate.service', () => { jest.mock('@ghostfolio/api/app/portfolio/current-rate.service', () => {
return { return {
@ -190,7 +189,7 @@ describe('PortfolioCalculator', () => {
totalValuablesWithCurrencyEffect: new Big('0') totalValuablesWithCurrencyEffect: new Big('0')
}); });
expect(last(portfolioSnapshot.historicalData)).toMatchObject( expect(portfolioSnapshot.historicalData.at(-1)).toMatchObject(
expect.objectContaining({ expect.objectContaining({
totalInvestmentValueWithCurrencyEffect: 298.58 totalInvestmentValueWithCurrencyEffect: 298.58
}) })

@ -21,7 +21,6 @@ import { PortfolioSnapshotServiceMock } from '@ghostfolio/api/services/queues/po
import { parseDate } from '@ghostfolio/common/helper'; import { parseDate } from '@ghostfolio/common/helper';
import { Big } from 'big.js'; import { Big } from 'big.js';
import { last } from 'lodash';
import { join } from 'path'; import { join } from 'path';
jest.mock('@ghostfolio/api/app/portfolio/current-rate.service', () => { jest.mock('@ghostfolio/api/app/portfolio/current-rate.service', () => {
@ -182,7 +181,7 @@ describe('PortfolioCalculator', () => {
totalValuablesWithCurrencyEffect: new Big('0') totalValuablesWithCurrencyEffect: new Big('0')
}); });
expect(last(portfolioSnapshot.historicalData)).toMatchObject( expect(portfolioSnapshot.historicalData.at(-1)).toMatchObject(
expect.objectContaining({ expect.objectContaining({
netPerformance: 17.68, netPerformance: 17.68,
netPerformanceInPercentage: 0.12184460284330327256, netPerformanceInPercentage: 0.12184460284330327256,

@ -21,7 +21,6 @@ import { PortfolioSnapshotServiceMock } from '@ghostfolio/api/services/queues/po
import { parseDate } from '@ghostfolio/common/helper'; import { parseDate } from '@ghostfolio/common/helper';
import { Big } from 'big.js'; import { Big } from 'big.js';
import { last } from 'lodash';
import { join } from 'path'; import { join } from 'path';
jest.mock('@ghostfolio/api/app/portfolio/current-rate.service', () => { jest.mock('@ghostfolio/api/app/portfolio/current-rate.service', () => {
@ -229,7 +228,7 @@ describe('PortfolioCalculator', () => {
totalValuablesWithCurrencyEffect: new Big('0') totalValuablesWithCurrencyEffect: new Big('0')
}); });
expect(last(portfolioSnapshot.historicalData)).toMatchObject( expect(portfolioSnapshot.historicalData.at(-1)).toMatchObject(
expect.objectContaining({ expect.objectContaining({
netPerformance: 19.86, netPerformance: 19.86,
netPerformanceInPercentage: 0.13100263852242744063, netPerformanceInPercentage: 0.13100263852242744063,

@ -13,7 +13,7 @@ import { DateRange } from '@ghostfolio/common/types';
import { Logger } from '@nestjs/common'; import { Logger } from '@nestjs/common';
import { Big } from 'big.js'; import { Big } from 'big.js';
import { addMilliseconds, differenceInDays, format, isBefore } from 'date-fns'; import { addMilliseconds, differenceInDays, format, isBefore } from 'date-fns';
import { cloneDeep, first, last, sortBy } from 'lodash'; import { cloneDeep, sortBy } from 'lodash';
export class TWRPortfolioCalculator extends PortfolioCalculator { export class TWRPortfolioCalculator extends PortfolioCalculator {
private chartDates: string[]; private chartDates: string[];
@ -221,7 +221,7 @@ export class TWRPortfolioCalculator extends PortfolioCalculator {
}; };
} }
const dateOfFirstTransaction = new Date(first(orders).date); const dateOfFirstTransaction = new Date(orders[0].date);
const endDateString = format(end, DATE_FORMAT); const endDateString = format(end, DATE_FORMAT);
const startDateString = format(start, DATE_FORMAT); const startDateString = format(start, DATE_FORMAT);
@ -342,7 +342,7 @@ export class TWRPortfolioCalculator extends PortfolioCalculator {
}); });
} }
const lastOrder = last(orders); const lastOrder = orders.at(-1);
lastUnitPrice = lastOrder.unitPriceFromMarketData ?? lastOrder.unitPrice; lastUnitPrice = lastOrder.unitPriceFromMarketData ?? lastOrder.unitPrice;
} }

@ -13,7 +13,7 @@ import type { RequestWithUser } from '@ghostfolio/common/types';
import { Inject, Injectable } from '@nestjs/common'; import { Inject, Injectable } from '@nestjs/common';
import { REQUEST } from '@nestjs/core'; import { REQUEST } from '@nestjs/core';
import { isBefore, isToday } from 'date-fns'; import { isBefore, isToday } from 'date-fns';
import { flatten, isEmpty, uniqBy } from 'lodash'; import { isEmpty, uniqBy } from 'lodash';
import { GetValueObject } from './interfaces/get-value-object.interface'; import { GetValueObject } from './interfaces/get-value-object.interface';
import { GetValuesObject } from './interfaces/get-values-object.interface'; import { GetValuesObject } from './interfaces/get-values-object.interface';
@ -102,7 +102,9 @@ export class CurrentRateService {
}) })
); );
const values = flatten(await Promise.all(promises)); const values = await Promise.all(promises).then((array) => {
return array.flat();
});
const response: GetValuesObject = { const response: GetValuesObject = {
dataProviderInfos, dataProviderInfos,

@ -77,7 +77,7 @@ import {
parseISO, parseISO,
set set
} from 'date-fns'; } from 'date-fns';
import { isEmpty, last, uniq } from 'lodash'; import { isEmpty, uniq } from 'lodash';
import { PortfolioCalculator } from './calculator/portfolio-calculator'; import { PortfolioCalculator } from './calculator/portfolio-calculator';
import { import {
@ -1133,10 +1133,7 @@ export class PortfolioService {
netWorth, netWorth,
totalInvestment, totalInvestment,
valueWithCurrencyEffect valueWithCurrencyEffect
} = } = chart?.at(-1) ?? {
chart?.length > 0
? last(chart)
: {
netPerformance: 0, netPerformance: 0,
netPerformanceInPercentage: 0, netPerformanceInPercentage: 0,
netPerformanceInPercentageWithCurrencyEffect: 0, netPerformanceInPercentageWithCurrencyEffect: 0,

Loading…
Cancel
Save