[PROJECTS] feat: Add Timesheet entity and DTOs
Add TypeORM entity and DTOs for Projects timesheets feature: - TimesheetEntity with all fields matching DDL schema - Extended DTOs for bulk operations (submit, approve, reject) - Summary types for reporting (by project, user, task) - Updated module exports to include new files Complements existing timesheets.service.ts implementation. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
b25afada28
commit
24b6ba9b38
83
src/modules/projects/dto/create-timesheet.dto.ts
Normal file
83
src/modules/projects/dto/create-timesheet.dto.ts
Normal file
@ -0,0 +1,83 @@
|
||||
// Note: Basic CreateTimesheetDto, UpdateTimesheetDto, TimesheetFilters are defined in timesheets.service.ts
|
||||
// This file contains extended DTOs for additional functionality
|
||||
|
||||
/**
|
||||
* Respuesta de timesheet con datos relacionados
|
||||
*/
|
||||
export interface TimesheetResponse {
|
||||
id: string;
|
||||
tenant_id: string;
|
||||
company_id: string;
|
||||
project_id: string;
|
||||
project_name?: string;
|
||||
task_id: string | null;
|
||||
task_name?: string;
|
||||
user_id: string;
|
||||
user_name?: string;
|
||||
date: Date;
|
||||
hours: number;
|
||||
description: string | null;
|
||||
billable: boolean;
|
||||
invoiced: boolean;
|
||||
invoice_id: string | null;
|
||||
status: 'draft' | 'submitted' | 'approved' | 'rejected';
|
||||
approved_by: string | null;
|
||||
approved_at: Date | null;
|
||||
created_at: Date;
|
||||
created_by: string | null;
|
||||
updated_at: Date | null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resumen de horas por proyecto
|
||||
*/
|
||||
export interface TimesheetSummaryByProject {
|
||||
project_id: string;
|
||||
project_name: string;
|
||||
total_hours: number;
|
||||
billable_hours: number;
|
||||
non_billable_hours: number;
|
||||
invoiced_hours: number;
|
||||
pending_hours: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resumen de horas por usuario
|
||||
*/
|
||||
export interface TimesheetSummaryByUser {
|
||||
user_id: string;
|
||||
user_name: string;
|
||||
total_hours: number;
|
||||
billable_hours: number;
|
||||
approved_hours: number;
|
||||
pending_approval: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resumen de horas por tarea
|
||||
*/
|
||||
export interface TimesheetSummaryByTask {
|
||||
task_id: string;
|
||||
task_name: string;
|
||||
project_id: string;
|
||||
project_name: string;
|
||||
estimated_hours: number;
|
||||
spent_hours: number;
|
||||
remaining_hours: number;
|
||||
progress_percentage: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resumen general de timesheets
|
||||
*/
|
||||
export interface TimesheetSummary {
|
||||
total_hours: number;
|
||||
billable_hours: number;
|
||||
non_billable_hours: number;
|
||||
invoiced_hours: number;
|
||||
approved_hours: number;
|
||||
pending_approval_hours: number;
|
||||
by_project?: TimesheetSummaryByProject[];
|
||||
by_user?: TimesheetSummaryByUser[];
|
||||
by_task?: TimesheetSummaryByTask[];
|
||||
}
|
||||
2
src/modules/projects/dto/index.ts
Normal file
2
src/modules/projects/dto/index.ts
Normal file
@ -0,0 +1,2 @@
|
||||
export * from './create-timesheet.dto.js';
|
||||
export * from './update-timesheet.dto.js';
|
||||
42
src/modules/projects/dto/update-timesheet.dto.ts
Normal file
42
src/modules/projects/dto/update-timesheet.dto.ts
Normal file
@ -0,0 +1,42 @@
|
||||
// Note: Basic UpdateTimesheetDto is defined in timesheets.service.ts
|
||||
// This file contains extended DTOs for additional functionality
|
||||
|
||||
/**
|
||||
* DTO para enviar un timesheet a aprobacion
|
||||
*/
|
||||
export interface SubmitTimesheetDto {
|
||||
/** IDs de los timesheets a enviar */
|
||||
timesheet_ids: string[];
|
||||
}
|
||||
|
||||
/**
|
||||
* DTO para aprobar/rechazar timesheets
|
||||
*/
|
||||
export interface ApproveTimesheetDto {
|
||||
/** IDs de los timesheets a aprobar/rechazar */
|
||||
timesheet_ids: string[];
|
||||
/** Comentario opcional del aprobador */
|
||||
comment?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* DTO para marcar timesheets como facturados
|
||||
*/
|
||||
export interface MarkInvoicedDto {
|
||||
/** IDs de los timesheets a marcar */
|
||||
timesheet_ids: string[];
|
||||
/** ID de la factura */
|
||||
invoice_id: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* DTO para accion masiva sobre timesheets
|
||||
*/
|
||||
export interface BulkTimesheetActionDto {
|
||||
/** IDs de los timesheets */
|
||||
timesheet_ids: string[];
|
||||
/** Accion a realizar */
|
||||
action: 'submit' | 'approve' | 'reject' | 'delete';
|
||||
/** Comentario opcional */
|
||||
comment?: string;
|
||||
}
|
||||
1
src/modules/projects/entities/index.ts
Normal file
1
src/modules/projects/entities/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export * from './timesheet.entity.js';
|
||||
95
src/modules/projects/entities/timesheet.entity.ts
Normal file
95
src/modules/projects/entities/timesheet.entity.ts
Normal file
@ -0,0 +1,95 @@
|
||||
import {
|
||||
Entity,
|
||||
PrimaryGeneratedColumn,
|
||||
Column,
|
||||
CreateDateColumn,
|
||||
UpdateDateColumn,
|
||||
Index,
|
||||
ManyToOne,
|
||||
JoinColumn,
|
||||
} from 'typeorm';
|
||||
|
||||
export enum TimesheetStatus {
|
||||
DRAFT = 'draft',
|
||||
SUBMITTED = 'submitted',
|
||||
APPROVED = 'approved',
|
||||
REJECTED = 'rejected',
|
||||
}
|
||||
|
||||
@Entity({ schema: 'projects', name: 'timesheets' })
|
||||
@Index('idx_timesheets_tenant', ['tenantId'])
|
||||
@Index('idx_timesheets_company', ['companyId'])
|
||||
@Index('idx_timesheets_project', ['projectId'])
|
||||
@Index('idx_timesheets_task', ['taskId'])
|
||||
@Index('idx_timesheets_user', ['userId'])
|
||||
@Index('idx_timesheets_user_date', ['userId', 'date'])
|
||||
@Index('idx_timesheets_date', ['date'])
|
||||
@Index('idx_timesheets_status', ['status'])
|
||||
export class TimesheetEntity {
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
id: string;
|
||||
|
||||
@Column({ type: 'uuid', nullable: false, name: 'tenant_id' })
|
||||
tenantId: string;
|
||||
|
||||
@Column({ type: 'uuid', nullable: false, name: 'company_id' })
|
||||
companyId: string;
|
||||
|
||||
@Column({ type: 'uuid', nullable: false, name: 'project_id' })
|
||||
projectId: string;
|
||||
|
||||
@Column({ type: 'uuid', nullable: true, name: 'task_id' })
|
||||
taskId: string | null;
|
||||
|
||||
@Column({ type: 'uuid', nullable: false, name: 'user_id' })
|
||||
userId: string;
|
||||
|
||||
@Column({ type: 'date', nullable: false })
|
||||
date: Date;
|
||||
|
||||
@Column({ type: 'decimal', precision: 5, scale: 2, nullable: false })
|
||||
hours: number;
|
||||
|
||||
@Column({ type: 'text', nullable: true })
|
||||
description: string | null;
|
||||
|
||||
@Column({ type: 'boolean', default: true, nullable: false })
|
||||
billable: boolean;
|
||||
|
||||
@Column({ type: 'boolean', default: false, nullable: false })
|
||||
invoiced: boolean;
|
||||
|
||||
@Column({ type: 'uuid', nullable: true, name: 'invoice_id' })
|
||||
invoiceId: string | null;
|
||||
|
||||
@Column({
|
||||
type: 'enum',
|
||||
enum: TimesheetStatus,
|
||||
default: TimesheetStatus.DRAFT,
|
||||
nullable: false,
|
||||
})
|
||||
status: TimesheetStatus;
|
||||
|
||||
@Column({ type: 'uuid', nullable: true, name: 'approved_by' })
|
||||
approvedBy: string | null;
|
||||
|
||||
@Column({ type: 'timestamp', nullable: true, name: 'approved_at' })
|
||||
approvedAt: Date | null;
|
||||
|
||||
// Audit fields
|
||||
@CreateDateColumn({ name: 'created_at', type: 'timestamp' })
|
||||
createdAt: Date;
|
||||
|
||||
@Column({ type: 'uuid', nullable: true, name: 'created_by' })
|
||||
createdBy: string | null;
|
||||
|
||||
@UpdateDateColumn({
|
||||
name: 'updated_at',
|
||||
type: 'timestamp',
|
||||
nullable: true,
|
||||
})
|
||||
updatedAt: Date | null;
|
||||
|
||||
@Column({ type: 'uuid', nullable: true, name: 'updated_by' })
|
||||
updatedBy: string | null;
|
||||
}
|
||||
@ -5,3 +5,9 @@ export * from './billing.service.js';
|
||||
export * from './hr-integration.service.js';
|
||||
export * from './projects.controller.js';
|
||||
export { default as projectsRoutes } from './projects.routes.js';
|
||||
|
||||
// Entities
|
||||
export * from './entities/index.js';
|
||||
|
||||
// DTOs
|
||||
export * from './dto/index.js';
|
||||
|
||||
Loading…
Reference in New Issue
Block a user