erp-construccion-backend-v2/src/modules/assets/entities/asset-cost.entity.ts
Adrian Flores Cortes 5f9c30d268 [MAE-015] feat: Implement assets module backend
Complete implementation of the Assets/Machinery/Maintenance module:

Entities (10):
- AssetCategory: Hierarchical asset categorization with depreciation config
- Asset: Main asset entity (machinery, vehicles, tools, equipment)
- AssetAssignment: Asset-to-project assignments tracking
- WorkOrder: Maintenance work orders with workflow
- WorkOrderPart: Parts/materials used in work orders
- MaintenancePlan: Preventive maintenance plans
- MaintenanceHistory: Historical maintenance records
- FuelLog: Fuel consumption tracking with efficiency calculation
- AssetCost: TCO (Total Cost of Ownership) tracking

Services (3):
- AssetService: CRUD, assignments, categories, statistics
- WorkOrderService: CRUD, workflow (start/hold/resume/complete/cancel), parts
- FuelLogService: CRUD, efficiency calculation, statistics

Controllers (3):
- AssetController: REST API for assets, assignments, categories
- WorkOrderController: REST API for work orders, workflow, plans
- FuelLogController: REST API for fuel logs, statistics

Features:
- Multi-tenant support with tenant_id
- Complete workflow for work orders (draft→scheduled→in_progress→completed)
- Automatic efficiency calculation for fuel consumption
- Asset assignment history tracking
- Maintenance plan generation
- TCO tracking by cost type

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25 05:41:54 -06:00

133 lines
3.2 KiB
TypeScript

/**
* AssetCost Entity - Costos de Activos (TCO)
*
* Registro de costos para calculo de TCO (Total Cost of Ownership).
*
* @module Assets (MAE-015)
*/
import {
Entity,
PrimaryGeneratedColumn,
Column,
CreateDateColumn,
UpdateDateColumn,
ManyToOne,
JoinColumn,
Index,
} from 'typeorm';
import { Asset } from './asset.entity';
export type CostType =
| 'maintenance'
| 'repair'
| 'fuel'
| 'insurance'
| 'tax'
| 'depreciation'
| 'operator'
| 'other';
@Entity('asset_costs', { schema: 'assets' })
@Index(['tenantId', 'assetId'])
@Index(['tenantId', 'periodStart', 'periodEnd'])
@Index(['tenantId', 'costType'])
@Index(['tenantId', 'projectId'])
export class AssetCost {
@PrimaryGeneratedColumn('uuid')
id!: string;
@Column({ name: 'tenant_id', type: 'uuid' })
@Index()
tenantId!: string;
// Activo
@Column({ name: 'asset_id', type: 'uuid' })
assetId!: string;
@ManyToOne(() => Asset)
@JoinColumn({ name: 'asset_id' })
asset!: Asset;
// Periodo
@Column({ name: 'period_start', type: 'date' })
periodStart!: Date;
@Column({ name: 'period_end', type: 'date' })
periodEnd!: Date;
@Column({ name: 'fiscal_year', type: 'int' })
fiscalYear!: number;
@Column({ name: 'fiscal_month', type: 'int' })
fiscalMonth!: number;
// Proyecto (si aplica)
@Column({ name: 'project_id', type: 'uuid', nullable: true })
projectId?: string;
@Column({ name: 'project_code', length: 50, nullable: true })
projectCode?: string;
// Tipo de costo
@Column({
name: 'cost_type',
type: 'enum',
enum: ['maintenance', 'repair', 'fuel', 'insurance', 'tax', 'depreciation', 'operator', 'other'],
enumName: 'cost_type',
})
costType!: CostType;
// Descripcion
@Column({ length: 255, nullable: true })
description?: string;
@Column({ name: 'reference_document', length: 100, nullable: true })
referenceDocument?: string;
// Monto
@Column({ type: 'decimal', precision: 18, scale: 2 })
amount!: number;
@Column({ length: 3, default: 'MXN' })
currency!: string;
// Uso asociado
@Column({ name: 'hours_in_period', type: 'decimal', precision: 12, scale: 2, nullable: true })
hoursInPeriod?: number;
@Column({ name: 'kilometers_in_period', type: 'decimal', precision: 12, scale: 2, nullable: true })
kilometersInPeriod?: number;
// Calculo de tarifa
@Column({ name: 'cost_per_hour', type: 'decimal', precision: 18, scale: 4, nullable: true })
costPerHour?: number;
@Column({ name: 'cost_per_kilometer', type: 'decimal', precision: 18, scale: 4, nullable: true })
costPerKilometer?: number;
// Origen
@Column({ name: 'source_module', length: 50, nullable: true })
sourceModule?: string;
@Column({ name: 'source_id', type: 'uuid', nullable: true })
sourceId?: string;
// Notas
@Column({ type: 'text', nullable: true })
notes?: string;
@Column({ type: 'jsonb', nullable: true })
metadata?: Record<string, any>;
// Auditoria
@Column({ name: 'created_by', type: 'uuid', nullable: true })
createdBy?: string;
@CreateDateColumn({ name: 'created_at', type: 'timestamptz' })
createdAt!: Date;
@UpdateDateColumn({ name: 'updated_at', type: 'timestamptz' })
updatedAt!: Date;
}