-
Notifications
You must be signed in to change notification settings - Fork 17
/
route.ts
153 lines (134 loc) · 3.95 KB
/
route.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
import config from '@/config/site'
import Mail from '@/emails/order_notification_owner'
import prisma from '@/lib/prisma'
import { sendMail } from '@persepolis/mail'
import { render } from '@react-email/render'
import { NextResponse } from 'next/server'
export async function GET(req: Request) {
try {
const userId = req.headers.get('X-USER-ID')
if (!userId) {
return new NextResponse('Unauthorized', { status: 401 })
}
const orders = await prisma.order.findMany({
where: {
userId,
},
include: {
address: true,
payments: true,
refund: true,
orderItems: true,
},
})
return NextResponse.json(orders)
} catch (error) {
console.error('[ORDERS_GET]', error)
return new NextResponse('Internal error', { status: 500 })
}
}
export async function POST(req: Request) {
try {
const userId = req.headers.get('X-USER-ID')
if (!userId) {
return new NextResponse('Unauthorized', { status: 401 })
}
const { addressId, discountCode } = await req.json()
if (discountCode) {
await prisma.discountCode.findUniqueOrThrow({
where: {
code: discountCode,
stock: {
gte: 1,
},
},
})
}
const cart = await prisma.cart.findUniqueOrThrow({
where: {
userId,
},
include: {
items: {
include: {
product: true,
},
},
},
})
const { tax, total, discount, payable } = calculateCosts({ cart })
const order = await prisma.order.create({
data: {
user: {
connect: {
id: userId,
},
},
status: 'Processing',
total,
tax,
payable,
discount,
shipping: 0,
address: {
connect: { id: addressId },
},
orderItems: {
create: cart?.items.map((orderItem) => ({
count: orderItem.count,
price: orderItem.product.price,
discount: orderItem.product.discount,
product: {
connect: {
id: orderItem.productId,
},
},
})),
},
},
})
const owners = await prisma.owner.findMany()
const notifications = await prisma.notification.createMany({
data: owners.map((owner) => ({
userId: owner.id,
content: `Order #${order.number} was created was created with a value of $${payable}.`,
})),
})
for (const owner of owners) {
await sendMail({
name: config.name,
to: owner.email,
subject: 'An order was created.',
html: render(
Mail({
id: order.id,
payable: payable.toFixed(2),
orderNum: order.number.toString(),
})
),
})
}
return NextResponse.json(order)
} catch (error) {
console.error('[ORDER_POST]', error)
return new NextResponse('Internal error', { status: 500 })
}
}
function calculateCosts({ cart }) {
let total = 0,
discount = 0
for (const item of cart?.items) {
total += item?.count * item?.product?.price
discount += item?.count * item?.product?.discount
}
const afterDiscount = total - discount
const tax = afterDiscount * 0.09
const payable = afterDiscount + tax
return {
total: parseFloat(total.toFixed(2)),
discount: parseFloat(discount.toFixed(2)),
afterDiscount: parseFloat(afterDiscount.toFixed(2)),
tax: parseFloat(tax.toFixed(2)),
payable: parseFloat(payable.toFixed(2)),
}
}