source: src/app/api/invoices/route.ts@ 5d6f37a

main
Last change on this file since 5d6f37a was 5d6f37a, checked in by Naum Shapkarovski <naumshapkarovski@…>, 7 weeks ago

add customer

  • Property mode set to 100644
File size: 2.9 KB
Line 
1import { NextRequest, NextResponse } from 'next/server';
2import { invoiceSchema, invoiceTableFiltersSchema } from 'mvpmasters-shared';
3import prisma from 'src/lib/prisma';
4import { auth } from 'src/lib/firebase-admin';
5
6// Helper function to get userId from Authorization header
7async function getUserId(request: NextRequest) {
8 const authHeader = request.headers.get('Authorization');
9 if (!authHeader?.startsWith('Bearer ')) {
10 return null;
11 }
12
13 try {
14 const token = authHeader.split('Bearer ')[1];
15 const decodedToken = await auth.verifyIdToken(token);
16 return decodedToken.uid;
17 } catch (error) {
18 return null;
19 }
20}
21
22export async function GET(request: NextRequest) {
23 try {
24 const userId = await getUserId(request);
25 if (!userId) {
26 return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
27 }
28
29 const searchParams = request.nextUrl.searchParams;
30 const filters = {
31 name: searchParams.get('name') || '',
32 service: searchParams.getAll('service'),
33 status: searchParams.get('status') || '',
34 startDate: searchParams.get('startDate') ? new Date(searchParams.get('startDate')!) : null,
35 endDate: searchParams.get('endDate') ? new Date(searchParams.get('endDate')!) : null,
36 };
37
38 // Validate filters
39 const validatedFilters = invoiceTableFiltersSchema.parse(filters);
40
41 const invoices = await prisma.invoice.findMany({
42 where: {
43 userId,
44 status: validatedFilters.status ? { equals: validatedFilters.status } : undefined,
45 createDate: {
46 gte: validatedFilters.startDate,
47 lte: validatedFilters.endDate,
48 },
49 items:
50 validatedFilters.service.length > 0
51 ? { some: { service: { id: { in: validatedFilters.service } } } }
52 : undefined,
53 },
54 include: {
55 items: {
56 include: {
57 service: true,
58 },
59 },
60 invoiceFrom: true,
61 invoiceTo: true,
62 },
63 });
64
65 return NextResponse.json(invoices);
66 } catch (error) {
67 return NextResponse.json({ error: 'Internal Server Error' }, { status: 500 });
68 }
69}
70
71export async function POST(request: NextRequest) {
72 try {
73 const userId = await getUserId(request);
74 if (!userId) {
75 return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
76 }
77
78 const body = await request.json();
79 const validatedData = invoiceSchema.parse(body);
80
81 const invoice = await prisma.invoice.create({
82 data: {
83 ...validatedData,
84 userId,
85 items: {
86 create: validatedData.items,
87 },
88 },
89 include: {
90 items: {
91 include: {
92 service: true,
93 },
94 },
95 invoiceFrom: true,
96 invoiceTo: true,
97 },
98 });
99
100 return NextResponse.json(invoice, { status: 201 });
101 } catch (error) {
102 return NextResponse.json({ error: 'Internal Server Error' }, { status: 500 });
103 }
104}
Note: See TracBrowser for help on using the repository browser.