import { NextRequest, NextResponse } from 'next/server'; import { createInvoiceSchema, invoiceSchema, invoiceTableFiltersSchema } from 'src/schemas'; import prisma from 'src/lib/prisma'; import { auth } from 'src/lib/firebase-admin'; import { InvoiceStatus } from '@prisma/client'; // Helper function to get userId from Authorization header async function getUserId(request: NextRequest) { const authHeader = request.headers.get('Authorization'); if (!authHeader?.startsWith('Bearer ')) { return null; } try { const token = authHeader.split('Bearer ')[1]; const decodedToken = await auth.verifyIdToken(token); return decodedToken.uid; } catch (error) { return null; } } export async function GET(request: NextRequest) { try { const userId = await getUserId(request); // if (!userId) { // return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }); // } const searchParams = request.nextUrl.searchParams; const filters = { name: searchParams.get('name') || '', service: searchParams.getAll('service'), status: searchParams.get('status') || '', startDate: searchParams.get('startDate') ? new Date(searchParams.get('startDate')!) : null, endDate: searchParams.get('endDate') ? new Date(searchParams.get('endDate')!) : null, }; // Validate filters const validatedFilters = invoiceTableFiltersSchema.parse(filters); const invoices = await prisma.invoice.findMany({ where: { status: validatedFilters.status ? { equals: validatedFilters.status as InvoiceStatus } : undefined, issueDate: { ...(validatedFilters.startDate && { gte: validatedFilters.startDate }), ...(validatedFilters.endDate && { lte: validatedFilters.endDate }), }, items: validatedFilters.service.length > 0 ? { some: { service: { id: { in: validatedFilters.service } } } } : undefined, }, include: { items: { include: { service: true, }, }, invoiceFrom: true, invoiceTo: true, }, }); return NextResponse.json(invoices); } catch (error) { return NextResponse.json({ error: 'Internal Server Error' }, { status: 500 }); } } export async function POST(request: NextRequest) { try { const userId = await getUserId(request); // if (!userId) { // return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }); // } const body = await request.json(); const validatedData = createInvoiceSchema.parse(body); const tenant = await prisma.tenant.findUnique({ where: { id: validatedData.invoiceFrom.id }, }); const toCustomer = await prisma.client.findUnique({ where: { id: validatedData.invoiceTo.id }, }); if (!tenant || !toCustomer) { return NextResponse.json({ error: 'Invoice sender or recipient not found' }, { status: 404 }); } // Update lastInvoiceNumber in tenant const updatedTenant = await prisma.tenant.update({ where: { id: tenant.id }, data: { lastInvoiceNumber: validatedData.invoiceNumber, }, }); const invoice = await prisma.invoice.create({ data: { dueDate: validatedData.dueDate, status: validatedData.status, currency: validatedData.currency, quantityType: validatedData.quantityType, subTotal: validatedData.subTotal, issueDate: validatedData.issueDate, month: validatedData.month, discount: validatedData.discount, taxes: validatedData.taxes, totalAmount: validatedData.totalAmount, invoiceNumber: validatedData.invoiceNumber, invoiceFromId: tenant.id, invoiceToId: toCustomer.id, items: { create: validatedData.items.map((item) => ({ title: item.title, price: item.price, total: item.total, quantity: item.quantity, description: item.description, service: { connect: { id: item.service.id }, }, })), }, }, include: { items: { include: { service: true, }, }, invoiceFrom: true, invoiceTo: true, }, }); return NextResponse.json(invoice, { status: 201 }); } catch (error) { console.error(error); return NextResponse.json({ error: 'Internal Server Error' }, { status: 500 }); } }