Browse Source

Merge remote-tracking branch 'origin/main' into feature/upgrade-bootstrap-to-version-5

pull/8131/head
KenTandrian 3 days ago
parent
commit
d0553f792d
  1. 3
      CHANGELOG.md
  2. 46
      apps/api/src/app/portfolio/portfolio.service.spec.ts
  3. 3
      apps/api/src/app/portfolio/portfolio.service.ts
  4. 4
      package-lock.json
  5. 2
      package.json

3
CHANGELOG.md

@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## Unreleased ## 3.85.0 - 2026-10-12
### Added ### Added
@ -21,6 +21,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Fixed ### Fixed
- Fixed the border color of the drop area in the import activities dialog (dark mode) - Fixed the border color of the drop area in the import activities dialog (dark mode)
- Fixed the start date of the investment timeline chart on the analysis page
- Fixed the matching of assets and accounts in the import of activities with _Ghostfolio AI_ (experimental) - Fixed the matching of assets and accounts in the import of activities with _Ghostfolio AI_ (experimental)
- Fixed an issue where the update of an activity could change the asset class and asset sub class of an asset profile which does not belong to the user - Fixed an issue where the update of an activity could change the asset class and asset sub class of an asset profile which does not belong to the user

46
apps/api/src/app/portfolio/portfolio.service.spec.ts

@ -23,7 +23,7 @@ import {
Filter, Filter,
PortfolioSummary PortfolioSummary
} from '@ghostfolio/common/interfaces'; } from '@ghostfolio/common/interfaces';
import { AccountWithBalance } from '@ghostfolio/common/types'; import { AccountWithBalance, DateRange } from '@ghostfolio/common/types';
import { AssetClass, DataSource, Prisma } from '@prisma/client'; import { AssetClass, DataSource, Prisma } from '@prisma/client';
import { Big } from 'big.js'; import { Big } from 'big.js';
@ -842,6 +842,50 @@ describe('PortfolioService', () => {
}); });
}); });
describe('getInvestments', () => {
afterEach(() => {
jest.useRealTimers();
});
it.each(['2025', 'ytd'] as DateRange[])(
'should exclude the investment of the start date of the date range %s',
async (dateRange) => {
jest.useFakeTimers().setSystemTime(parseDate('2025-06-15').getTime());
jest
.spyOn(activitiesService, 'getActivitiesForPortfolioCalculator')
.mockResolvedValue({ activities: [{} as Activity], count: 1 });
jest
.spyOn(portfolioCalculatorFactory, 'createCalculator')
.mockReturnValue({
getSnapshot: jest.fn().mockResolvedValue({
historicalData: [
{ date: '2024-12-31', investmentValueWithCurrencyEffect: 100 },
{ date: '2025-01-01', investmentValueWithCurrencyEffect: 200 }
]
})
} as unknown as PortfolioCalculator);
jest.spyOn(userService, 'user').mockResolvedValue({
id: userDummyData.id,
settings: {
settings: {
baseCurrency: 'CHF'
}
}
} as unknown as Awaited<ReturnType<typeof userService.user>>);
const { investments } = await portfolioService.getInvestments({
dateRange,
userId: userDummyData.id
});
expect(investments).toEqual([{ date: '2025-01-01', investment: 200 }]);
}
);
});
describe('getPerformance', () => { describe('getPerformance', () => {
let getPerformanceOfCalculator: jest.Mock; let getPerformanceOfCalculator: jest.Mock;

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

@ -98,7 +98,6 @@ import {
endOfDay, endOfDay,
format, format,
isAfter, isAfter,
isBefore,
isSameMonth, isSameMonth,
isSameYear, isSameYear,
min, min,
@ -564,7 +563,7 @@ export class PortfolioService {
const date = resetHours(parseDate(historicalDataItem.date)); const date = resetHours(parseDate(historicalDataItem.date));
return ( return (
!isBefore(date, resetHours(startDate)) && isAfter(date, resetHours(startDate)) &&
!isAfter(date, resetHours(endDate)) !isAfter(date, resetHours(endDate))
); );
}); });

4
package-lock.json

@ -1,12 +1,12 @@
{ {
"name": "ghostfolio", "name": "ghostfolio",
"version": "3.84.2", "version": "3.85.0",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "ghostfolio", "name": "ghostfolio",
"version": "3.84.2", "version": "3.85.0",
"hasInstallScript": true, "hasInstallScript": true,
"license": "AGPL-3.0", "license": "AGPL-3.0",
"dependencies": { "dependencies": {

2
package.json

@ -1,6 +1,6 @@
{ {
"name": "ghostfolio", "name": "ghostfolio",
"version": "3.84.2", "version": "3.85.0",
"homepage": "https://ghostfol.io", "homepage": "https://ghostfol.io",
"license": "AGPL-3.0", "license": "AGPL-3.0",
"repository": "https://github.com/ghostfolio/ghostfolio", "repository": "https://github.com/ghostfolio/ghostfolio",

Loading…
Cancel
Save