Skip to content

Commit

Permalink
[Fix] Adjust Pending Time Logs Entries (#8240)
Browse files Browse the repository at this point in the history
* wip: working on start/stop adjust entries

* fix: start/stop timer methods improvement
  • Loading branch information
rahul-rocket authored Sep 23, 2024
1 parent 88de863 commit 3990b94
Show file tree
Hide file tree
Showing 10 changed files with 447 additions and 372 deletions.
10 changes: 4 additions & 6 deletions packages/contracts/src/timesheet.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
} from './organization-projects.model';
import { IEmployee, IEmployeeFindInput, IEmployeeEntityInput } from './employee.model';
import { ITask } from './task.model';
import { ITag } from './tag.model';
import { ITag, ITaggable } from './tag.model';
import { IPaginationInput } from './core.model';
import { ReportGroupByFilter } from './report.model';
import { IUser } from './user.model';
Expand Down Expand Up @@ -98,7 +98,7 @@ export interface IDateRange {
export interface ITimeLog
extends IBasePerTenantAndOrganizationEntityModel,
IRelationalOrganizationProject,
IRelationalOrganizationTeam {
IRelationalOrganizationTeam, ITaggable {
employee: IEmployee;
employeeId: ID;
timesheet?: ITimesheet;
Expand All @@ -113,14 +113,12 @@ export interface ITimeLog
source?: TimeLogSourceEnum;
startedAt?: Date;
stoppedAt?: Date;
/** Edited At* */
editedAt?: Date;
logType: TimeLogType;
logType?: TimeLogType;
description?: string;
reason?: string;
duration: number;
isBillable: boolean;
tags?: string[];
isBillable?: boolean;
isRunning?: boolean;
isEdited?: boolean;
}
Expand Down
35 changes: 15 additions & 20 deletions packages/core/src/core/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -306,33 +306,28 @@ export function freshTimestamp(): Date {
}

/**
* Function that performs the date range validation
* Validates the date range between startedAt and stoppedAt.
*
* @param startedAt
* @param stoppedAt
* @returns
* @param startedAt The start date of the range.
* @param stoppedAt The end date of the range.
* @throws BadRequestException if the dates are invalid or if the stoppedAt date is before the startedAt date.
*/
export function validateDateRange(startedAt: Date, stoppedAt: Date): void {
try {
const start = moment(startedAt);
const end = moment(stoppedAt);
const start = moment(startedAt);
const end = moment(stoppedAt);

console.log('------ Stopped Timer ------', start.toDate(), end.toDate());
console.log('------ Stopped Timer ------', start.toDate(), end.toDate());

if (!start.isValid() || !end.isValid()) {
throw 'Started and Stopped date must be valid date.';
// If either start or end date is invalid, return without throwing an exception
}
if (!start.isValid() || !end.isValid()) {
throw new BadRequestException('Started and Stopped date must be valid dates.');
}

if (end.isBefore(start)) {
throw 'Stopped date must be greater than started date.';
}
} catch (error) {
// If any error occurs during date validation, throw a BadRequestException
throw new BadRequestException(error);
if (end.isBefore(start)) {
throw new BadRequestException('Stopped date must be greater than the started date.');
}
}


/**
* Function that returns intersection of 2 arrays
* @param arr1 Array 1
Expand Down Expand Up @@ -474,8 +469,8 @@ export const flatten = (input: any): any => {
const newKey = Array.isArray(value)
? key
: nestedKeys.length > 0
? `${key}.${nestedKeys.join('.')}`
: key;
? `${key}.${nestedKeys.join('.')}`
: key;
return acc.concat(newKey);
}
}, []) || []
Expand Down
60 changes: 35 additions & 25 deletions packages/core/src/employee/employee.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ import { Brackets, FindManyOptions, FindOneOptions, In, SelectQueryBuilder, Wher
import * as moment from 'moment';
import {
IBasePerTenantAndOrganizationEntityModel,
ID,
IDateRangePicker,
IEmployee,
IFindMembersInput,
IOrganization,
IPagination,
PermissionsEnum
} from '@gauzy/contracts';
Expand Down Expand Up @@ -97,7 +97,7 @@ export class EmployeeService extends TenantAwareCrudService<Employee> {
* @param userIds An array of user IDs.
* @returns A promise resolving to an array of employees.
*/
async findEmployeesByUserIds(userIds: string[]): Promise<Employee[]> {
async findEmployeesByUserIds(userIds: ID[]): Promise<Employee[]> {
try {
// Get the tenant ID from the current request context
const tenantId = RequestContext.currentTenantId();
Expand Down Expand Up @@ -137,7 +137,7 @@ export class EmployeeService extends TenantAwareCrudService<Employee> {
* @param userId The ID of the user.
* @returns The employeeId or null if not found or in case of an error.
*/
async findEmployeeIdByUserId(userId: string): Promise<string | null> {
async findEmployeeIdByUserId(userId: ID): Promise<string | null> {
try {
const tenantId = RequestContext.currentTenantId();
// Construct the where clause based on whether tenantId is available
Expand Down Expand Up @@ -172,29 +172,35 @@ export class EmployeeService extends TenantAwareCrudService<Employee> {
* @param userId The ID of the user to find.
* @returns A Promise resolving to the employee if found, otherwise null.
*/
async findOneByUserId(userId: string, options?: FindOneOptions<Employee>): Promise<IEmployee | null> {
async findOneByUserId(userId: ID, options?: FindOneOptions<Employee>): Promise<IEmployee | null> {
try {
// Retrieve the tenant ID from the current context
const tenantId = RequestContext.currentTenantId();

// Construct the where clause based on whether tenantId is available
// Define the base where clause
const whereClause = {
userId,
...(tenantId && { tenantId }), // Include tenantId if available
isActive: true,
isArchived: false,
...(tenantId && { tenantId }) // Include tenantId if available
};
const queryOptions = options ? { ...options } : {};

// Merge the existing where conditions in options, if any
const queryOptions: FindOneOptions<Employee> = {
...options,
where: {
...whereClause,
...(options?.where || {}) // Merge with existing where options if present
}
};

switch (this.ormType) {
case MultiORMEnum.MikroORM:
const { mikroOptions } = parseTypeORMFindToMikroOrm<Employee>(options as FindManyOptions);
const item = await this.mikroOrmRepository.findOne(whereClause, mikroOptions);
const { where, mikroOptions } = parseTypeORMFindToMikroOrm<Employee>(queryOptions as FindManyOptions);
const item = await this.mikroOrmRepository.findOne(where, mikroOptions);
return this.serialize(item as Employee);
case MultiORMEnum.TypeORM:
return this.typeOrmRepository.findOne({
where: whereClause,
...queryOptions
});
return this.typeOrmRepository.findOne(queryOptions);
default:
throw new Error(`Not implemented for ${this.ormType}`);
}
Expand All @@ -208,7 +214,7 @@ export class EmployeeService extends TenantAwareCrudService<Employee> {
* Retrieves all active employees with their associated user and organization details.
* @returns A Promise that resolves to an array of active employees.
*/
public async findAllActive(): Promise<Employee[]> {
public async findAllActive(): Promise<IEmployee[]> {
try {
return await super.find({
where: { isActive: true, isArchived: false },
Expand All @@ -232,7 +238,7 @@ export class EmployeeService extends TenantAwareCrudService<Employee> {
* @returns
*/
async findWorkingEmployees(
organizationId: IOrganization['id'],
organizationId: ID,
forRange: IDateRangePicker | any,
withUser: boolean = false
): Promise<IPagination<IEmployee>> {
Expand Down Expand Up @@ -497,17 +503,19 @@ export class EmployeeService extends TenantAwareCrudService<Employee> {
* Softly delete an employee by ID, with organization and tenant constraints.
*
* @param employeeId - ID of the employee to delete.
* @param options - Contains organizationId and possibly other per-tenant information.
* @param params - Contains organizationId and possibly other per-tenant information.
* @returns - UpdateResult or DeleteResult depending on the ORM type.
*/
async softRemovedById(
employeeId: IEmployee['id'],
options: IBasePerTenantAndOrganizationEntityModel
employeeId: ID,
params: IBasePerTenantAndOrganizationEntityModel
): Promise<Employee> {
try {
const { organizationId } = options;
// Obtain the organization ID from the provided parameters
const organizationId = params.organizationId;

// Obtain tenant ID from the current request context
const tenantId = RequestContext.currentTenantId() || options.tenantId;
const tenantId = RequestContext.currentTenantId() || params.tenantId;

// Perform the soft delete operation
return await super.softRemove(employeeId, {
Expand All @@ -527,18 +535,20 @@ export class EmployeeService extends TenantAwareCrudService<Employee> {
* and tenant ID to ensure that the correct employee is restored.
*
* @param employeeId The ID of the employee to restore.
* @param options Additional context parameters, including organization ID and tenant ID.
* @param params Additional context parameters, including organization ID and tenant ID.
* @returns The restored Employee entity.
* @throws BadRequestException if the employee cannot be restored or if an error occurs.
*/
async softRecoverById(
employeeId: IEmployee['id'],
options: IBasePerTenantAndOrganizationEntityModel
employeeId: ID,
params: IBasePerTenantAndOrganizationEntityModel
): Promise<Employee> {
try {
const { organizationId } = options;
// Obtain the organization ID from the provided parameters
const organizationId = params.organizationId;

// Obtain the tenant ID from the current request context or the provided options
const tenantId = RequestContext.currentTenantId() || options.tenantId;
const tenantId = RequestContext.currentTenantId() || params.tenantId;

// Perform the soft recovery operation using the ID, organization ID, and tenant ID
return await super.softRecover(employeeId, {
Expand Down
Loading

0 comments on commit 3990b94

Please sign in to comment.