/** * Estimacion Entity * Estimaciones de obra periodicas para subcontratistas * * @module Estimates * @table estimates.estimaciones * @ddl schemas/04-estimates-schema-ddl.sql */ import { Entity, PrimaryGeneratedColumn, Column, CreateDateColumn, UpdateDateColumn, ManyToOne, OneToMany, JoinColumn, Index, Check, } from 'typeorm'; import { Tenant } from '../../core/entities/tenant.entity'; import { User } from '../../core/entities/user.entity'; import { Fraccionamiento } from '../../construction/entities/fraccionamiento.entity'; import { EstimacionConcepto } from './estimacion-concepto.entity'; import { Amortizacion } from './amortizacion.entity'; import { Retencion } from './retencion.entity'; import { EstimacionWorkflow } from './estimacion-workflow.entity'; export type EstimateStatus = 'draft' | 'submitted' | 'reviewed' | 'approved' | 'invoiced' | 'paid' | 'rejected' | 'cancelled'; @Entity({ schema: 'estimates', name: 'estimaciones' }) @Index(['tenantId', 'estimateNumber'], { unique: true }) @Index(['contratoId', 'sequenceNumber'], { unique: true }) @Index(['tenantId']) @Index(['contratoId']) @Index(['fraccionamientoId']) @Index(['status']) @Index(['periodStart', 'periodEnd']) @Check(`"period_end" >= "period_start"`) export class Estimacion { @PrimaryGeneratedColumn('uuid') id: string; @Column({ name: 'tenant_id', type: 'uuid' }) tenantId: string; @Column({ name: 'contrato_id', type: 'uuid' }) contratoId: string; @Column({ name: 'fraccionamiento_id', type: 'uuid' }) fraccionamientoId: string; @Column({ name: 'estimate_number', type: 'varchar', length: 30 }) estimateNumber: string; @Column({ name: 'period_start', type: 'date' }) periodStart: Date; @Column({ name: 'period_end', type: 'date' }) periodEnd: Date; @Column({ name: 'sequence_number', type: 'integer' }) sequenceNumber: number; @Column({ type: 'enum', enum: ['draft', 'submitted', 'reviewed', 'approved', 'invoiced', 'paid', 'rejected', 'cancelled'], enumName: 'estimates.estimate_status', default: 'draft', }) status: EstimateStatus; @Column({ type: 'decimal', precision: 16, scale: 2, default: 0 }) subtotal: number; @Column({ name: 'advance_amount', type: 'decimal', precision: 16, scale: 2, default: 0 }) advanceAmount: number; @Column({ name: 'retention_amount', type: 'decimal', precision: 16, scale: 2, default: 0 }) retentionAmount: number; @Column({ name: 'tax_amount', type: 'decimal', precision: 16, scale: 2, default: 0 }) taxAmount: number; @Column({ name: 'total_amount', type: 'decimal', precision: 16, scale: 2, default: 0 }) totalAmount: number; @Column({ name: 'submitted_at', type: 'timestamptz', nullable: true }) submittedAt: Date | null; @Column({ name: 'submitted_by', type: 'uuid', nullable: true }) submittedById: string | null; @Column({ name: 'reviewed_at', type: 'timestamptz', nullable: true }) reviewedAt: Date | null; @Column({ name: 'reviewed_by', type: 'uuid', nullable: true }) reviewedById: string | null; @Column({ name: 'approved_at', type: 'timestamptz', nullable: true }) approvedAt: Date | null; @Column({ name: 'approved_by', type: 'uuid', nullable: true }) approvedById: string | null; @Column({ name: 'invoice_id', type: 'uuid', nullable: true }) invoiceId: string | null; @Column({ name: 'invoiced_at', type: 'timestamptz', nullable: true }) invoicedAt: Date | null; @Column({ name: 'paid_at', type: 'timestamptz', nullable: true }) paidAt: Date | null; @Column({ type: 'text', nullable: true }) notes: string | null; @CreateDateColumn({ name: 'created_at', type: 'timestamptz' }) createdAt: Date; @Column({ name: 'created_by', type: 'uuid', nullable: true }) createdById: string | null; @UpdateDateColumn({ name: 'updated_at', type: 'timestamptz', nullable: true }) updatedAt: Date | null; @Column({ name: 'updated_by', type: 'uuid', nullable: true }) updatedById: string | null; @Column({ name: 'deleted_at', type: 'timestamptz', nullable: true }) deletedAt: Date | null; @Column({ name: 'deleted_by', type: 'uuid', nullable: true }) deletedById: string | null; // Relations @ManyToOne(() => Tenant) @JoinColumn({ name: 'tenant_id' }) tenant: Tenant; @ManyToOne(() => Fraccionamiento) @JoinColumn({ name: 'fraccionamiento_id' }) fraccionamiento: Fraccionamiento; @ManyToOne(() => User) @JoinColumn({ name: 'submitted_by' }) submittedBy: User | null; @ManyToOne(() => User) @JoinColumn({ name: 'reviewed_by' }) reviewedBy: User | null; @ManyToOne(() => User) @JoinColumn({ name: 'approved_by' }) approvedBy: User | null; @ManyToOne(() => User) @JoinColumn({ name: 'created_by' }) createdBy: User | null; @OneToMany(() => EstimacionConcepto, (c) => c.estimacion) conceptos: EstimacionConcepto[]; @OneToMany(() => Amortizacion, (a) => a.estimacion) amortizaciones: Amortizacion[]; @OneToMany(() => Retencion, (r) => r.estimacion) retenciones: Retencion[]; @OneToMany(() => EstimacionWorkflow, (w) => w.estimacion) workflow: EstimacionWorkflow[]; }