import { NextRequest, NextResponse } from 'next/server'; import { prisma } from '@/lib/prisma'; import { getCurrentUser } from '@/lib/auth'; // GET - Liste tous les prescripteurs avec budgets, consommé et restant // PATCH - Met à jour le budget d'un prescripteur (body: { prescripteurValue, montant }) export async function GET() { try { const user = await getCurrentUser(); if (!user) { return NextResponse.json({ error: 'Non autorisé' }, { status: 401 }); } const [prescripteurs, budgets, participations] = await Promise.all([ prisma.adherentOption.findMany({ where: { type: 'prescripteur' }, orderBy: [{ order: 'asc' }, { value: 'asc' }], }), prisma.prescripteurBudget.findMany(), prisma.participationFinanciere.findMany({ include: { adherent: { select: { prescripteur: true, prenom: true, nom: true } }, trajet: { select: { date: true } }, }, orderBy: { createdAt: 'desc' }, }), ]); const consomméMap = new Map(); const historiqueMap = new Map>(); for (const p of participations) { const prescripteur = p.adherent.prescripteur; if (!prescripteur) continue; const montant = p.montant ?? 0; if (['envoye', 'paye'].includes(p.statut)) { consomméMap.set(prescripteur, (consomméMap.get(prescripteur) ?? 0) + montant); } const hist = historiqueMap.get(prescripteur) ?? []; hist.push({ id: p.id, date: p.trajet.date.toISOString(), adherentNom: `${p.adherent.prenom} ${p.adherent.nom}`, montant, }); historiqueMap.set(prescripteur, hist); } const budgetMap = new Map(budgets.map((b) => [b.prescripteurValue, { montant: b.montant, ajustementConsomme: b.ajustementConsomme ?? 0 }])); const items = prescripteurs.map((p) => { const budgetData = budgetMap.get(p.value); const montant = budgetData?.montant ?? 0; const ajustementConsomme = budgetData?.ajustementConsomme ?? 0; const consomméCalculé = consomméMap.get(p.value) ?? 0; const consommé = consomméCalculé + ajustementConsomme; const restant = Math.max(0, montant - consommé); const historique = (historiqueMap.get(p.value) ?? []).sort( (a, b) => new Date(b.date).getTime() - new Date(a.date).getTime() ); return { id: p.id, value: p.value, montant, consommé, restant, ajustementConsomme, historique, }; }); const totalAlloue = items.reduce((s, i) => s + i.montant, 0); const totalConsomme = items.reduce((s, i) => s + i.consommé, 0); const totalRestant = Math.max(0, totalAlloue - totalConsomme); return NextResponse.json({ global: { totalAlloue, totalConsomme, totalRestant }, prescripteurs: items, }); } catch (error) { console.error('Erreur lors de la récupération des budgets:', error); return NextResponse.json({ error: 'Erreur serveur' }, { status: 500 }); } } export async function PATCH(request: NextRequest) { try { const user = await getCurrentUser(); if (!user) { return NextResponse.json({ error: 'Non autorisé' }, { status: 401 }); } const body = await request.json(); const { prescripteurValue, montant: montantRaw, montantToAdd, rectifier, ajustementConsomme: ajRaw } = body; if (!prescripteurValue || typeof prescripteurValue !== 'string') { return NextResponse.json({ error: 'Prescripteur requis' }, { status: 400 }); } const exists = await prisma.adherentOption.findFirst({ where: { type: 'prescripteur', value: prescripteurValue }, }); if (!exists) { return NextResponse.json({ error: 'Prescripteur non trouvé' }, { status: 404 }); } const existing = await prisma.prescripteurBudget.findUnique({ where: { prescripteurValue }, }); let montantFinal: number; let ajustementFinal: number | undefined; if (rectifier) { const montant = typeof montantRaw === 'number' ? montantRaw : parseFloat(String(montantRaw ?? 0).replace(',', '.')); if (isNaN(montant) || montant < 0) { return NextResponse.json({ error: 'Budget invalide' }, { status: 400 }); } montantFinal = montant; const aj = typeof ajRaw === 'number' ? ajRaw : parseFloat(String(ajRaw ?? 0).replace(',', '.')); ajustementFinal = isNaN(aj) ? 0 : aj; } else if (montantToAdd !== undefined && montantToAdd !== null) { const toAdd = typeof montantToAdd === 'number' ? montantToAdd : parseFloat(String(montantToAdd).replace(',', '.')); if (isNaN(toAdd) || toAdd <= 0) { return NextResponse.json({ error: 'Montant à ajouter invalide' }, { status: 400 }); } montantFinal = (existing?.montant ?? 0) + toAdd; } else { const montant = typeof montantRaw === 'number' ? montantRaw : parseFloat(String(montantRaw ?? 0).replace(',', '.')); if (isNaN(montant) || montant < 0) { return NextResponse.json({ error: 'Montant invalide' }, { status: 400 }); } montantFinal = montant; } const updateData: { montant: number; ajustementConsomme?: number } = { montant: montantFinal }; if (ajustementFinal !== undefined) { updateData.ajustementConsomme = ajustementFinal; } const createData: { prescripteurValue: string; montant: number; ajustementConsomme?: number } = { prescripteurValue, montant: montantFinal, }; if (ajustementFinal !== undefined) { createData.ajustementConsomme = ajustementFinal; } const budget = await prisma.prescripteurBudget.upsert({ where: { prescripteurValue }, update: updateData, create: createData, }); return NextResponse.json(budget); } catch (error) { console.error('Erreur lors de la mise à jour du budget:', error); return NextResponse.json({ error: 'Erreur serveur' }, { status: 500 }); } }