Browse Source
Merge branch 'main' into bugfix/handle-exception-in-holding-detail-endpoint-for-cash-positions
pull/7391/head
Thomas Kaul
1 month ago
committed by
GitHub
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with
11 additions and
8 deletions
-
CHANGELOG.md
-
apps/api/src/app/access/access.controller.ts
-
apps/api/src/app/portfolio/calculator/portfolio-calculator.ts
-
apps/api/src/services/benchmark/benchmark.service.ts
-
apps/client/src/app/components/investment-chart/investment-chart.component.ts
|
|
@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 |
|
|
### Fixed |
|
|
### Fixed |
|
|
|
|
|
|
|
|
- Resolved an exception in the `GET api/v1/portfolio/holding/:dataSource/:symbol` endpoint for cash positions |
|
|
- Resolved an exception in the `GET api/v1/portfolio/holding/:dataSource/:symbol` endpoint for cash positions |
|
|
|
|
|
- Improved the error handling in the access endpoints (`POST` and `PUT`) to return `400 Bad Request` when granting access to a non-existent user |
|
|
|
|
|
|
|
|
## 3.31.0 - 2026-07-20 |
|
|
## 3.31.0 - 2026-07-20 |
|
|
|
|
|
|
|
|
|
|
|
@ -87,7 +87,7 @@ export class AccessController { |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
try { |
|
|
try { |
|
|
return this.accessService.createAccess({ |
|
|
return await this.accessService.createAccess({ |
|
|
alias: data.alias || undefined, |
|
|
alias: data.alias || undefined, |
|
|
granteeUser: data.granteeUserId |
|
|
granteeUser: data.granteeUserId |
|
|
? { connect: { id: data.granteeUserId } } |
|
|
? { connect: { id: data.granteeUserId } } |
|
|
@ -155,7 +155,7 @@ export class AccessController { |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
try { |
|
|
try { |
|
|
return this.accessService.updateAccess({ |
|
|
return await this.accessService.updateAccess({ |
|
|
data: { |
|
|
data: { |
|
|
alias: data.alias, |
|
|
alias: data.alias, |
|
|
granteeUser: data.granteeUserId |
|
|
granteeUser: data.granteeUserId |
|
|
|
|
|
@ -51,6 +51,8 @@ import { |
|
|
format, |
|
|
format, |
|
|
isAfter, |
|
|
isAfter, |
|
|
isBefore, |
|
|
isBefore, |
|
|
|
|
|
isFuture, |
|
|
|
|
|
isPast, |
|
|
isWithinInterval, |
|
|
isWithinInterval, |
|
|
min, |
|
|
min, |
|
|
startOfDay, |
|
|
startOfDay, |
|
|
@ -134,7 +136,7 @@ export abstract class PortfolioCalculator { |
|
|
dateOfFirstActivity = date; |
|
|
dateOfFirstActivity = date; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if (isAfter(date, new Date())) { |
|
|
if (isFuture(date)) { |
|
|
// Adapt date to today if activity is in future (e.g. liability)
|
|
|
// Adapt date to today if activity is in future (e.g. liability)
|
|
|
// to include it in the interval
|
|
|
// to include it in the interval
|
|
|
date = endOfDay(new Date()); |
|
|
date = endOfDay(new Date()); |
|
|
@ -1113,7 +1115,7 @@ export abstract class PortfolioCalculator { |
|
|
portfolioSnapshot |
|
|
portfolioSnapshot |
|
|
); |
|
|
); |
|
|
|
|
|
|
|
|
if (isAfter(new Date(), new Date(expiration))) { |
|
|
if (isPast(new Date(expiration))) { |
|
|
isCachedPortfolioSnapshotExpired = true; |
|
|
isCachedPortfolioSnapshotExpired = true; |
|
|
} |
|
|
} |
|
|
} catch {} |
|
|
} catch {} |
|
|
|
|
|
@ -23,7 +23,7 @@ import { BenchmarkTrend } from '@ghostfolio/common/types'; |
|
|
import { Injectable, Logger } from '@nestjs/common'; |
|
|
import { Injectable, Logger } from '@nestjs/common'; |
|
|
import { SymbolProfile } from '@prisma/client'; |
|
|
import { SymbolProfile } from '@prisma/client'; |
|
|
import { Big } from 'big.js'; |
|
|
import { Big } from 'big.js'; |
|
|
import { addHours, isAfter, subDays } from 'date-fns'; |
|
|
import { addHours, isPast, subDays } from 'date-fns'; |
|
|
import { round, uniqBy } from 'lodash'; |
|
|
import { round, uniqBy } from 'lodash'; |
|
|
import ms from 'ms'; |
|
|
import ms from 'ms'; |
|
|
|
|
|
|
|
|
@ -94,7 +94,7 @@ export class BenchmarkService { |
|
|
|
|
|
|
|
|
this.logger.debug('Fetched benchmarks from cache'); |
|
|
this.logger.debug('Fetched benchmarks from cache'); |
|
|
|
|
|
|
|
|
if (isAfter(new Date(), new Date(expiration))) { |
|
|
if (isPast(new Date(expiration))) { |
|
|
this.calculateAndCacheBenchmarks({ |
|
|
this.calculateAndCacheBenchmarks({ |
|
|
enableSharing |
|
|
enableSharing |
|
|
}); |
|
|
}); |
|
|
|
|
|
@ -41,7 +41,7 @@ import { |
|
|
} from 'chart.js'; |
|
|
} from 'chart.js'; |
|
|
import 'chartjs-adapter-date-fns'; |
|
|
import 'chartjs-adapter-date-fns'; |
|
|
import { type AnnotationOptions } from 'chartjs-plugin-annotation'; |
|
|
import { type AnnotationOptions } from 'chartjs-plugin-annotation'; |
|
|
import { isAfter } from 'date-fns'; |
|
|
import { isFuture } from 'date-fns'; |
|
|
import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader'; |
|
|
import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader'; |
|
|
|
|
|
|
|
|
@Component({ |
|
|
@Component({ |
|
|
@ -311,6 +311,6 @@ export class GfInvestmentChartComponent implements OnChanges, OnDestroy { |
|
|
return undefined; |
|
|
return undefined; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
return isAfter(new Date(xValue), new Date()) ? aValue : undefined; |
|
|
return isFuture(new Date(xValue)) ? aValue : undefined; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|