import { NextResponse } from "next/server"; import { auth } from "@/lib/auth"; import { prisma } from "@/lib/prisma"; import { partidaPresupuestoSchema } from "@/lib/validations"; import { z } from "zod"; const partidaUpdateSchema = partidaPresupuestoSchema.partial().extend({ apuId: z.string().optional().nullable(), }); export async function GET( request: Request, { params }: { params: Promise<{ id: string; partidaId: string }> } ) { try { const session = await auth(); if (!session?.user?.empresaId) { return NextResponse.json({ error: "No autorizado" }, { status: 401 }); } const { id, partidaId } = await params; const partida = await prisma.partidaPresupuesto.findFirst({ where: { id: partidaId, presupuestoId: id, presupuesto: { obra: { empresaId: session.user.empresaId }, }, }, include: { apu: { include: { insumos: { include: { material: true, categoriaManoObra: true, equipo: true, }, }, }, }, }, }); if (!partida) { return NextResponse.json( { error: "Partida no encontrada" }, { status: 404 } ); } return NextResponse.json(partida); } catch (error) { console.error("Error fetching partida:", error); return NextResponse.json( { error: "Error al obtener la partida" }, { status: 500 } ); } } export async function PUT( request: Request, { params }: { params: Promise<{ id: string; partidaId: string }> } ) { try { const session = await auth(); if (!session?.user?.empresaId) { return NextResponse.json({ error: "No autorizado" }, { status: 401 }); } const { id, partidaId } = await params; const body = await request.json(); const validatedData = partidaUpdateSchema.parse(body); // Verify partida exists and belongs to empresa const existingPartida = await prisma.partidaPresupuesto.findFirst({ where: { id: partidaId, presupuestoId: id, presupuesto: { obra: { empresaId: session.user.empresaId }, }, }, }); if (!existingPartida) { return NextResponse.json( { error: "Partida no encontrada" }, { status: 404 } ); } // If APU is provided, get price from it let precioUnitario = validatedData.precioUnitario ?? existingPartida.precioUnitario; if (validatedData.apuId) { const apu = await prisma.analisisPrecioUnitario.findFirst({ where: { id: validatedData.apuId, empresaId: session.user.empresaId, }, }); if (apu) { precioUnitario = apu.precioUnitario; } } const cantidad = validatedData.cantidad ?? existingPartida.cantidad; const total = cantidad * precioUnitario; const partida = await prisma.partidaPresupuesto.update({ where: { id: partidaId }, data: { codigo: validatedData.codigo, descripcion: validatedData.descripcion, unidad: validatedData.unidad, cantidad: validatedData.cantidad, precioUnitario, total, categoria: validatedData.categoria, apuId: validatedData.apuId, }, include: { apu: { select: { id: true, codigo: true, descripcion: true, precioUnitario: true, }, }, }, }); // Update presupuesto total await updatePresupuestoTotal(id); return NextResponse.json(partida); } catch (error) { console.error("Error updating partida:", error); return NextResponse.json( { error: "Error al actualizar la partida" }, { status: 500 } ); } } export async function DELETE( request: Request, { params }: { params: Promise<{ id: string; partidaId: string }> } ) { try { const session = await auth(); if (!session?.user?.empresaId) { return NextResponse.json({ error: "No autorizado" }, { status: 401 }); } const { id, partidaId } = await params; // Verify partida exists and belongs to empresa const existingPartida = await prisma.partidaPresupuesto.findFirst({ where: { id: partidaId, presupuestoId: id, presupuesto: { obra: { empresaId: session.user.empresaId }, }, }, }); if (!existingPartida) { return NextResponse.json( { error: "Partida no encontrada" }, { status: 404 } ); } await prisma.partidaPresupuesto.delete({ where: { id: partidaId }, }); // Update presupuesto total await updatePresupuestoTotal(id); return NextResponse.json({ message: "Partida eliminada correctamente" }); } catch (error) { console.error("Error deleting partida:", error); return NextResponse.json( { error: "Error al eliminar la partida" }, { status: 500 } ); } } async function updatePresupuestoTotal(presupuestoId: string) { const result = await prisma.partidaPresupuesto.aggregate({ where: { presupuestoId }, _sum: { total: true }, }); const total = result._sum.total || 0; await prisma.presupuesto.update({ where: { id: presupuestoId }, data: { total }, }); // Also update obra's presupuestoTotal if this presupuesto is approved const presupuesto = await prisma.presupuesto.findUnique({ where: { id: presupuestoId }, select: { obraId: true, aprobado: true }, }); if (presupuesto?.aprobado) { const obraTotal = await prisma.presupuesto.aggregate({ where: { obraId: presupuesto.obraId, aprobado: true }, _sum: { total: true }, }); await prisma.obra.update({ where: { id: presupuesto.obraId }, data: { presupuestoTotal: obraTotal._sum.total || 0 }, }); } }