Skip to content
This repository was archived by the owner on Feb 24, 2026. It is now read-only.

Commit b36d7aa

Browse files
authored
feat: enhance employee filtering in statistics service (#122)
- Updated the getPeriodStatisticsDuration method to improve employee ID filtering based on user permissions. - Introduced a new filteredEmployeeIds array to ensure that only relevant employee IDs are considered based on the user's access rights. - Adjusted the timer-weekly-limit service to simplify the logic for determining if the current user is the employee in context. - These changes enhance data accuracy and maintain consistent access control across the application.
1 parent ccdd245 commit b36d7aa

2 files changed

Lines changed: 28 additions & 13 deletions

File tree

packages/core/src/lib/time-tracking/statistic/statistic.service.ts

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Injectable, Logger } from '@nestjs/common';
1+
import { Injectable, Logger, NotFoundException } from '@nestjs/common';
22
import { Brackets, SelectQueryBuilder, WhereExpressionBuilder } from 'typeorm';
33
import { reduce, pluck, pick, mapObject, groupBy, chain } from 'underscore';
44
import * as moment from 'moment';
@@ -22,7 +22,7 @@ import {
2222
IWeeklyStatisticsActivities,
2323
ITodayStatisticsActivities
2424
} from '@gauzy/contracts';
25-
import { ArraySum, isNotEmpty } from '@gauzy/utils';
25+
import { ArraySum, isEmpty, isNotEmpty } from '@gauzy/utils';
2626
import {
2727
ConfigService,
2828
DatabaseTypeEnum,
@@ -394,6 +394,8 @@ export class StatisticService {
394394
async getPeriodStatisticsDuration(request: IGetCountsStatistics): Promise<{ duration: number }> {
395395
const {
396396
organizationId,
397+
employeeId = [],
398+
employeeIds = [],
397399
startDate,
398400
endDate,
399401
projectIds = [],
@@ -403,19 +405,31 @@ export class StatisticService {
403405
onlyMe: isOnlyMeSelected
404406
} = request;
405407

406-
let employeeIds = request.employeeIds || [];
407-
408408
const user = RequestContext.currentUser();
409409
const tenantId = RequestContext.currentTenantId() ?? request.tenantId;
410410

411-
// Check if the user has permission to view/change other employees
412-
const hasChangeSelectedEmployeePermission: boolean = RequestContext.hasPermission(
411+
// Check if the user only can see himself
412+
const onlyCanSeeHimself: boolean = isOnlyMeSelected || !RequestContext.hasPermission(
413413
PermissionsEnum.CHANGE_SELECTED_EMPLOYEE
414414
);
415415

416-
// If the user does not have permission (or selected "only me"), restrict to their own employeeId
417-
if (user.employeeId && (isOnlyMeSelected || !hasChangeSelectedEmployeePermission)) {
418-
employeeIds = [user.employeeId];
416+
const filteredEmployeeIds = [];
417+
418+
if (onlyCanSeeHimself) {
419+
if (isEmpty(user.employeeId)) {
420+
// If not throw an error, the query will return all employees
421+
throw new NotFoundException(
422+
'No employee profile associated with your user account. Please contact your administrator.'
423+
);
424+
}
425+
426+
filteredEmployeeIds.push(user.employeeId);
427+
} else {
428+
if (isNotEmpty(employeeId)) {
429+
filteredEmployeeIds.push(employeeId);
430+
} else if (isNotEmpty(employeeIds)) {
431+
filteredEmployeeIds.push(...employeeIds);
432+
}
419433
}
420434

421435
// Format the date range (default: current ISO week)
@@ -444,8 +458,8 @@ export class StatisticService {
444458
);
445459

446460
// Apply filters conditionally
447-
if (isNotEmpty(employeeIds)) {
448-
query.andWhere('time_log.employeeId IN (:...employeeIds)', { employeeIds });
461+
if (isNotEmpty(filteredEmployeeIds)) {
462+
query.andWhere('time_log.employeeId IN (:...employeeIds)', { employeeIds: filteredEmployeeIds });
449463
}
450464

451465
if (isNotEmpty(projectIds)) {

packages/core/src/lib/time-tracking/timer/timer-weekly-limit.service.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@ export class TimerWeeklyLimitService {
2727
timeZone = 'UTC';
2828
throw new Error(`TimeZone is undefined`);
2929
}
30+
3031
const currentUser = RequestContext.currentUser();
31-
const isCurrentEmployee = employee.id === currentUser.employeeId;
32-
const isOnlyMe = isCurrentEmployee;
32+
const isOnlyMe = employee.id === currentUser.employeeId;
3333

3434
const refMomentLocal = moment.utc(refDate).tz(timeZone);
3535

@@ -53,6 +53,7 @@ export class TimerWeeklyLimitService {
5353
if (remainWeeklyTime <= 0 && !ignoreException) {
5454
throw new ConflictException(TimeErrorsEnum.WEEKLY_LIMIT_REACHED);
5555
}
56+
5657
return { remainWeeklyTime, workedThisWeek: statistics.duration };
5758
}
5859

0 commit comments

Comments
 (0)