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:
Mexus
2026-02-05 07:14:14 +00:00
parent e1847597d6
commit 56e39af3ff
47 changed files with 7779 additions and 18 deletions

View File

@@ -0,0 +1,44 @@
import { auth } from "@/lib/auth";
import { prisma } from "@/lib/prisma";
import { notFound } from "next/navigation";
import { ManoObraForm } from "@/components/apu";
async function getCategoria(empresaId: string, id: string) {
const categoria = await prisma.categoriaTrabajoAPU.findFirst({
where: { id, empresaId },
});
return categoria;
}
export default async function EditarManoObraPage({
params,
}: {
params: Promise<{ id: string }>;
}) {
const session = await auth();
const { id } = await params;
if (!session?.user?.empresaId) {
return <div>Error: No se encontro la empresa</div>;
}
const categoria = await getCategoria(session.user.empresaId, id);
if (!categoria) {
notFound();
}
return (
<div className="space-y-6">
<div>
<h1 className="text-2xl font-bold">Editar Categoria de Mano de Obra</h1>
<p className="text-slate-600">
Modificando {categoria.codigo} - {categoria.nombre}
</p>
</div>
<ManoObraForm categoria={categoria} />
</div>
);
}