Browse Source

Fix start date of date range filter

pull/8118/head
Thomas Kaul 5 days ago
parent
commit
615e68d894
  1. 32
      apps/api/src/app/activities/activities.service.spec.ts
  2. 8
      apps/api/src/app/activities/activities.service.ts
  3. 4
      apps/api/src/app/import/import.service.ts

32
apps/api/src/app/activities/activities.service.spec.ts

@ -9,6 +9,7 @@ import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-
import { PrismaService } from '@ghostfolio/api/services/prisma/prisma.service'; import { PrismaService } from '@ghostfolio/api/services/prisma/prisma.service';
import { SymbolProfileService } from '@ghostfolio/api/services/symbol-profile/symbol-profile.service'; import { SymbolProfileService } from '@ghostfolio/api/services/symbol-profile/symbol-profile.service';
import { TagService } from '@ghostfolio/api/services/tag/tag.service'; import { TagService } from '@ghostfolio/api/services/tag/tag.service';
import { getIntervalFromDateRange } from '@ghostfolio/common/calculation-helper';
import { import {
INVESTMENT_ACTIVITY_TYPES, INVESTMENT_ACTIVITY_TYPES,
NON_INVESTMENT_ACTIVITY_TYPES NON_INVESTMENT_ACTIVITY_TYPES
@ -27,6 +28,7 @@ import {
} from '@prisma/client'; } from '@prisma/client';
import { Big } from 'big.js'; import { Big } from 'big.js';
import { isUUID } from 'class-validator'; import { isUUID } from 'class-validator';
import { endOfDay } from 'date-fns';
import { ActivitiesService } from './activities.service'; import { ActivitiesService } from './activities.service';
@ -522,6 +524,36 @@ describe('ActivitiesService', () => {
}); });
}); });
describe('getWhereClause', () => {
afterEach(() => {
jest.useRealTimers();
});
it('excludes the activities of the start date of a date range', () => {
jest.useFakeTimers().setSystemTime(new Date(2024, 5, 15));
const { endDate, startDate } = getIntervalFromDateRange({
dateRange: 'ytd'
});
const { AND } = activitiesService['getWhereClause']({
endDate,
startDate,
includeDrafts: false,
userId: 'user-id',
withExcludedAccountsAndActivities: false
});
// The same limits as for the calendar year 2024
expect(AND).toEqual(
expect.arrayContaining([
{ date: { gt: endOfDay(new Date(2023, 11, 31)) } },
{ date: { lte: endOfDay(new Date(2024, 5, 15)) } }
])
);
});
});
describe('updateActivity', () => { describe('updateActivity', () => {
it('updates the custom asset profile of the user', async () => { it('updates the custom asset profile of the user', async () => {
const data = await getUpdatedActivityData({ userId: 'user-id' }); const data = await getUpdatedActivityData({ userId: 'user-id' });

8
apps/api/src/app/activities/activities.service.ts

@ -61,6 +61,7 @@ import {
Type as ActivityType Type as ActivityType
} from '@prisma/client'; } from '@prisma/client';
import { Big } from 'big.js'; import { Big } from 'big.js';
import { endOfDay } from 'date-fns';
import { groupBy, omit, uniqBy } from 'lodash-es'; import { groupBy, omit, uniqBy } from 'lodash-es';
import { randomUUID } from 'node:crypto'; import { randomUUID } from 'node:crypto';
@ -1037,12 +1038,15 @@ export class ActivitiesService {
const andConditions: Prisma.OrderWhereInput[] = []; const andConditions: Prisma.OrderWhereInput[] = [];
const where: Prisma.OrderWhereInput = { userId, AND: andConditions }; const where: Prisma.OrderWhereInput = { userId, AND: andConditions };
// The day of an activity is its calendar date in the time zone of the
// server, as in the portfolio calculator. The start date is excluded and
// the end date is included.
if (endDate) { if (endDate) {
andConditions.push({ date: { lte: endDate } }); andConditions.push({ date: { lte: endOfDay(endDate) } });
} }
if (startDate) { if (startDate) {
andConditions.push({ date: { gt: startDate } }); andConditions.push({ date: { gt: endOfDay(startDate) } });
} }
const { const {

4
apps/api/src/app/import/import.service.ts

@ -47,7 +47,7 @@ import { Injectable } from '@nestjs/common';
import { Account, DataSource, Prisma } from '@prisma/client'; import { Account, DataSource, Prisma } from '@prisma/client';
import { Big } from 'big.js'; import { Big } from 'big.js';
import { isISIN } from 'class-validator'; import { isISIN } from 'class-validator';
import { isSameSecond, parseISO } from 'date-fns'; import { isSameSecond, parseISO, subDays } from 'date-fns';
import { omit, uniqBy } from 'lodash-es'; import { omit, uniqBy } from 'lodash-es';
import { randomUUID } from 'node:crypto'; import { randomUUID } from 'node:crypto';
@ -111,7 +111,7 @@ export class ImportService {
userCurrency, userCurrency,
userId, userId,
includeDrafts: true, includeDrafts: true,
startDate: parseDate(dateOfFirstActivity), startDate: subDays(parseDate(dateOfFirstActivity), 1),
withExcludedAccountsAndActivities: true withExcludedAccountsAndActivities: true
}), }),
this.symbolProfileService.getSymbolProfiles([ this.symbolProfileService.getSymbolProfiles([

Loading…
Cancel
Save