feat: Add estimaciones, dashboard comparativo, bulk pricing, and enhanced Gantt

- Implement complete Estimaciones module with CRUD operations
  - Create/edit/view estimaciones with partidas selection
  - Automatic calculation of accumulated amounts
  - State workflow (BORRADOR → ENVIADA → APROBADA → PAGADA)
  - Integration with presupuestos and partidas

- Add dashboard comparativo presupuesto vs ejecutado
  - Summary cards with totals and variance
  - Category breakdown table with progress
  - Per-obra comparison table with filters
  - Integrated as tab in Reportes page

- Implement bulk price update functionality
  - Support for MATERIAL, MANO_OBRA, EQUIPO types
  - Percentage or fixed value methods
  - Optional cascade recalculation of APUs
  - UI dialog in APU list

- Enhance Gantt chart with API integration
  - New /api/obras/[id]/programacion endpoint
  - Drag & drop to change task dates (persisted)
  - Progress bar drag to update completion
  - Auto-fetch complete scheduling data
  - View mode options and refresh button

- Add order creation from materials explosion
  - Material selection with checkboxes
  - Create purchase order dialog
  - Integration with existing ordenes system

- Create missing UI components (Tabs, Checkbox, Form)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Mexus
2026-02-05 23:10:29 +00:00
parent e964e8f0b5
commit 09a29bb5c1
29 changed files with 5771 additions and 50 deletions

View File

@@ -341,7 +341,8 @@ model Presupuesto {
updatedAt DateTime @updatedAt
// Relations
partidas PartidaPresupuesto[]
partidas PartidaPresupuesto[]
estimaciones Estimacion[]
@@index([obraId])
}
@@ -363,8 +364,9 @@ model PartidaPresupuesto {
updatedAt DateTime @updatedAt
// Relations
gastos Gasto[]
avances AvancePartida[]
gastos Gasto[]
avances AvancePartida[]
estimacionPartidas EstimacionPartida[]
@@index([presupuestoId])
@@index([apuId])
@@ -1108,6 +1110,100 @@ model ConfiguracionAPU {
updatedAt DateTime @updatedAt
}
// ============== ESTIMACIONES ==============
enum EstadoEstimacion {
BORRADOR
ENVIADA
EN_REVISION
APROBADA
RECHAZADA
PAGADA
}
model Estimacion {
id String @id @default(cuid())
numero Int // Número de estimación (1, 2, 3...)
periodo String // Descripción del periodo (ej: "15-31 Enero 2024")
fechaInicio DateTime // Fecha inicio del periodo
fechaFin DateTime // Fecha fin del periodo
fechaEmision DateTime @default(now())
fechaEnvio DateTime?
fechaAprobacion DateTime?
estado EstadoEstimacion @default(BORRADOR)
// Totales
importeEjecutado Float @default(0) // Monto ejecutado este periodo
importeAcumulado Float @default(0) // Monto acumulado hasta esta estimación
importeAnterior Float @default(0) // Monto de estimaciones anteriores
amortizacion Float @default(0) // Amortización de anticipo
retencion Float @default(0) // Retención (% del contrato)
porcentajeRetencion Float @default(5) // % de retención
deduccionesVarias Float @default(0) // Otras deducciones
importeNeto Float @default(0) // Importe a pagar
// IVA
subtotal Float @default(0)
iva Float @default(0)
porcentajeIVA Float @default(16)
total Float @default(0)
// Notas y observaciones
observaciones String? @db.Text
motivoRechazo String?
// Relaciones
presupuestoId String
presupuesto Presupuesto @relation(fields: [presupuestoId], references: [id], onDelete: Cascade)
partidas EstimacionPartida[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@unique([presupuestoId, numero])
@@index([presupuestoId])
@@index([estado])
@@index([fechaEmision])
}
model EstimacionPartida {
id String @id @default(cuid())
// Cantidades
cantidadContrato Float // Cantidad original del presupuesto
cantidadAnterior Float @default(0) // Ejecutado en estimaciones previas
cantidadEstimacion Float // Ejecutado en esta estimación
cantidadAcumulada Float // Anterior + Esta estimación
cantidadPendiente Float // Contrato - Acumulada
// Importes
precioUnitario Float
importeAnterior Float @default(0)
importeEstimacion Float // cantidadEstimacion * precioUnitario
importeAcumulado Float
// Porcentajes
porcentajeAnterior Float @default(0)
porcentajeEstimacion Float
porcentajeAcumulado Float
// Notas para esta partida
notas String?
// Relaciones
estimacionId String
estimacion Estimacion @relation(fields: [estimacionId], references: [id], onDelete: Cascade)
partidaId String
partida PartidaPresupuesto @relation(fields: [partidaId], references: [id])
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@unique([estimacionId, partidaId])
@@index([estimacionId])
@@index([partidaId])
}
// ============== IMPORTACIÓN DE CATÁLOGOS ==============
enum TipoImportacion {