feat: Implement complete APU (Análisis de Precios Unitarios) module
High priority features: - APU CRUD with materials, labor, and equipment breakdown - Labor catalog with FSR (Factor de Salario Real) calculation - Equipment catalog with hourly cost calculation - Link APU to budget line items (partidas) - Explosion de insumos (consolidated materials list) Additional features: - Duplicate APU functionality - Excel export for explosion de insumos - Search and filters in APU list - Price validation alerts for outdated prices - PDF report export for APU New components: - APUForm, APUList, APUDetail - ManoObraForm, EquipoForm - ConfiguracionAPUForm - VincularAPUDialog - PartidasManager - ExplosionInsumos - APUPDF New UI components: - Alert component - Tooltip component Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -82,6 +82,38 @@ enum UnidadMedida {
|
||||
PIEZA
|
||||
ROLLO
|
||||
CAJA
|
||||
HORA
|
||||
JORNADA
|
||||
VIAJE
|
||||
LOTE
|
||||
GLOBAL
|
||||
}
|
||||
|
||||
enum CategoriaManoObra {
|
||||
PEON
|
||||
AYUDANTE
|
||||
OFICIAL_ALBANIL
|
||||
OFICIAL_FIERRERO
|
||||
OFICIAL_CARPINTERO
|
||||
OFICIAL_PLOMERO
|
||||
OFICIAL_ELECTRICISTA
|
||||
CABO
|
||||
MAESTRO_OBRA
|
||||
OPERADOR_EQUIPO
|
||||
}
|
||||
|
||||
enum TipoEquipo {
|
||||
MAQUINARIA_PESADA
|
||||
MAQUINARIA_LIGERA
|
||||
HERRAMIENTA_ELECTRICA
|
||||
TRANSPORTE
|
||||
}
|
||||
|
||||
enum TipoInsumoAPU {
|
||||
MATERIAL
|
||||
MANO_OBRA
|
||||
EQUIPO
|
||||
HERRAMIENTA_MENOR
|
||||
}
|
||||
|
||||
// ============== MODELS ==============
|
||||
@@ -137,6 +169,11 @@ model Empresa {
|
||||
empleados Empleado[]
|
||||
subcontratistas Subcontratista[]
|
||||
clientes Cliente[]
|
||||
// APU Relations
|
||||
categoriasTrabajo CategoriaTrabajoAPU[]
|
||||
equiposMaquinaria EquipoMaquinaria[]
|
||||
apus AnalisisPrecioUnitario[]
|
||||
configuracionAPU ConfiguracionAPU?
|
||||
}
|
||||
|
||||
model Cliente {
|
||||
@@ -267,6 +304,8 @@ model TareaObra {
|
||||
|
||||
@@index([faseId])
|
||||
@@index([estado])
|
||||
@@index([asignadoId])
|
||||
@@index([faseId, estado])
|
||||
}
|
||||
|
||||
model RegistroAvance {
|
||||
@@ -281,6 +320,8 @@ model RegistroAvance {
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
@@index([obraId])
|
||||
@@index([registradoPorId])
|
||||
@@index([obraId, createdAt])
|
||||
}
|
||||
|
||||
model Presupuesto {
|
||||
@@ -312,6 +353,8 @@ model PartidaPresupuesto {
|
||||
categoria CategoriaGasto
|
||||
presupuestoId String
|
||||
presupuesto Presupuesto @relation(fields: [presupuestoId], references: [id], onDelete: Cascade)
|
||||
apuId String?
|
||||
apu AnalisisPrecioUnitario? @relation(fields: [apuId], references: [id])
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@ -319,6 +362,7 @@ model PartidaPresupuesto {
|
||||
gastos Gasto[]
|
||||
|
||||
@@index([presupuestoId])
|
||||
@@index([apuId])
|
||||
}
|
||||
|
||||
model Gasto {
|
||||
@@ -395,10 +439,12 @@ model Material {
|
||||
// Relations
|
||||
movimientos MovimientoInventario[]
|
||||
itemsOrden ItemOrdenCompra[]
|
||||
insumosAPU InsumoAPU[]
|
||||
|
||||
@@unique([codigo, empresaId])
|
||||
@@index([empresaId])
|
||||
@@index([nombre])
|
||||
@@index([activo, empresaId])
|
||||
}
|
||||
|
||||
model MovimientoInventario {
|
||||
@@ -470,6 +516,7 @@ model JornadaTrabajo {
|
||||
|
||||
@@index([empleadoId])
|
||||
@@index([fecha])
|
||||
@@index([empleadoId, fecha])
|
||||
}
|
||||
|
||||
model Subcontratista {
|
||||
@@ -773,6 +820,8 @@ model FotoAvance {
|
||||
@@index([obraId])
|
||||
@@index([faseId])
|
||||
@@index([fechaCaptura])
|
||||
@@index([subidoPorId])
|
||||
@@index([obraId, fechaCaptura])
|
||||
}
|
||||
|
||||
// ============== NOTIFICACIONES PUSH ==============
|
||||
@@ -894,4 +943,134 @@ model ActividadLog {
|
||||
@@index([empresaId])
|
||||
@@index([tipo])
|
||||
@@index([createdAt])
|
||||
@@index([obraId, createdAt])
|
||||
@@index([empresaId, createdAt])
|
||||
}
|
||||
|
||||
// ============== ANÁLISIS DE PRECIOS UNITARIOS (APU) ==============
|
||||
|
||||
model CategoriaTrabajoAPU {
|
||||
id String @id @default(cuid())
|
||||
codigo String
|
||||
nombre String
|
||||
categoria CategoriaManoObra
|
||||
salarioDiario Float
|
||||
factorIMSS Float @default(0.2675)
|
||||
factorINFONAVIT Float @default(0.05)
|
||||
factorRetiro Float @default(0.02)
|
||||
factorVacaciones Float @default(0.0411)
|
||||
factorPrimaVac Float @default(0.0103)
|
||||
factorAguinaldo Float @default(0.0411)
|
||||
factorSalarioReal Float // Calculado: 1 + suma de factores
|
||||
salarioReal Float // salarioDiario * FSR
|
||||
activo Boolean @default(true)
|
||||
empresaId String
|
||||
empresa Empresa @relation(fields: [empresaId], references: [id])
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
// Relations
|
||||
insumosAPU InsumoAPU[]
|
||||
|
||||
@@unique([codigo, empresaId])
|
||||
@@index([empresaId])
|
||||
@@index([categoria])
|
||||
}
|
||||
|
||||
model EquipoMaquinaria {
|
||||
id String @id @default(cuid())
|
||||
codigo String
|
||||
nombre String
|
||||
tipo TipoEquipo
|
||||
valorAdquisicion Float
|
||||
vidaUtilHoras Float
|
||||
valorRescate Float @default(0)
|
||||
consumoCombustible Float? // Litros por hora
|
||||
precioCombustible Float? // Precio por litro
|
||||
factorMantenimiento Float @default(0.60)
|
||||
costoOperador Float? // Costo por hora del operador
|
||||
costoHorario Float // Calculado
|
||||
activo Boolean @default(true)
|
||||
empresaId String
|
||||
empresa Empresa @relation(fields: [empresaId], references: [id])
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
// Relations
|
||||
insumosAPU InsumoAPU[]
|
||||
|
||||
@@unique([codigo, empresaId])
|
||||
@@index([empresaId])
|
||||
@@index([tipo])
|
||||
}
|
||||
|
||||
model AnalisisPrecioUnitario {
|
||||
id String @id @default(cuid())
|
||||
codigo String
|
||||
descripcion String
|
||||
unidad UnidadMedida
|
||||
rendimientoDiario Float? // Cantidad de unidades por jornada
|
||||
costoMateriales Float @default(0)
|
||||
costoManoObra Float @default(0)
|
||||
costoEquipo Float @default(0)
|
||||
costoHerramienta Float @default(0)
|
||||
costoDirecto Float @default(0)
|
||||
porcentajeIndirectos Float @default(0)
|
||||
costoIndirectos Float @default(0)
|
||||
porcentajeUtilidad Float @default(0)
|
||||
costoUtilidad Float @default(0)
|
||||
precioUnitario Float @default(0)
|
||||
activo Boolean @default(true)
|
||||
empresaId String
|
||||
empresa Empresa @relation(fields: [empresaId], references: [id])
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
// Relations
|
||||
insumos InsumoAPU[]
|
||||
partidas PartidaPresupuesto[]
|
||||
|
||||
@@unique([codigo, empresaId])
|
||||
@@index([empresaId])
|
||||
@@index([unidad])
|
||||
}
|
||||
|
||||
model InsumoAPU {
|
||||
id String @id @default(cuid())
|
||||
tipo TipoInsumoAPU
|
||||
descripcion String
|
||||
unidad UnidadMedida
|
||||
cantidad Float
|
||||
desperdicio Float @default(0) // Porcentaje
|
||||
cantidadConDesperdicio Float
|
||||
rendimiento Float? // Para mano de obra: unidades por jornada
|
||||
precioUnitario Float
|
||||
importe Float
|
||||
apuId String
|
||||
apu AnalisisPrecioUnitario @relation(fields: [apuId], references: [id], onDelete: Cascade)
|
||||
materialId String?
|
||||
material Material? @relation(fields: [materialId], references: [id])
|
||||
categoriaManoObraId String?
|
||||
categoriaManoObra CategoriaTrabajoAPU? @relation(fields: [categoriaManoObraId], references: [id])
|
||||
equipoId String?
|
||||
equipo EquipoMaquinaria? @relation(fields: [equipoId], references: [id])
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@index([apuId])
|
||||
@@index([tipo])
|
||||
@@index([materialId])
|
||||
@@index([categoriaManoObraId])
|
||||
@@index([equipoId])
|
||||
}
|
||||
|
||||
model ConfiguracionAPU {
|
||||
id String @id @default(cuid())
|
||||
porcentajeHerramientaMenor Float @default(3)
|
||||
porcentajeIndirectos Float @default(8)
|
||||
porcentajeUtilidad Float @default(10)
|
||||
empresaId String @unique
|
||||
empresa Empresa @relation(fields: [empresaId], references: [id])
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user