Feature/refactor various lodash functions with native JavaScript equivalents (#4170)
* Refactored various lodash functions with native JavaScript equivalents * Update changelog
This commit is contained in:
parent
80bb1b1f64
commit
ca45098de3
@ -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,18 +1133,15 @@ export class PortfolioService {
|
|||||||
netWorth,
|
netWorth,
|
||||||
totalInvestment,
|
totalInvestment,
|
||||||
valueWithCurrencyEffect
|
valueWithCurrencyEffect
|
||||||
} =
|
} = chart?.at(-1) ?? {
|
||||||
chart?.length > 0
|
netPerformance: 0,
|
||||||
? last(chart)
|
netPerformanceInPercentage: 0,
|
||||||
: {
|
netPerformanceInPercentageWithCurrencyEffect: 0,
|
||||||
netPerformance: 0,
|
netPerformanceWithCurrencyEffect: 0,
|
||||||
netPerformanceInPercentage: 0,
|
netWorth: 0,
|
||||||
netPerformanceInPercentageWithCurrencyEffect: 0,
|
totalInvestment: 0,
|
||||||
netPerformanceWithCurrencyEffect: 0,
|
valueWithCurrencyEffect: 0
|
||||||
netWorth: 0,
|
};
|
||||||
totalInvestment: 0,
|
|
||||||
valueWithCurrencyEffect: 0
|
|
||||||
};
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
chart,
|
chart,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user