50 lines
1.8 KiB
TypeScript
50 lines
1.8 KiB
TypeScript
import { getQuery } from 'h3'
|
|
import { startOfMonth, endOfMonth } from 'date-fns'
|
|
import { prisma } from '../../utils/db'
|
|
import { requireUser } from '../../utils/auth'
|
|
|
|
export default defineEventHandler(async (event) => {
|
|
const user = await requireUser(event)
|
|
const query = getQuery(event)
|
|
const month = typeof query.month === 'string' ? query.month : new Date().toISOString().slice(0, 7)
|
|
const type = query.type === 'income' || query.type === 'expense' ? query.type : undefined
|
|
const assetId = typeof query.assetId === 'string' && query.assetId ? query.assetId : undefined
|
|
const categoryId = typeof query.categoryId === 'string' && query.categoryId ? query.categoryId : undefined
|
|
const q = typeof query.q === 'string' ? query.q.trim() : ''
|
|
const monthStart = startOfMonth(new Date(`${month}-01T00:00:00`))
|
|
const monthEnd = endOfMonth(monthStart)
|
|
|
|
const transactions = await prisma.transaction.findMany({
|
|
where: {
|
|
userId: user.id,
|
|
occurredAt: { gte: monthStart, lte: monthEnd },
|
|
...(type ? { type } : {}),
|
|
...(assetId ? { assetId } : {}),
|
|
...(categoryId ? { categoryId } : {}),
|
|
...(q
|
|
? {
|
|
OR: [
|
|
{ title: { contains: q, mode: 'insensitive' } },
|
|
{ memo: { contains: q, mode: 'insensitive' } },
|
|
{ asset: { name: { contains: q, mode: 'insensitive' } } },
|
|
{ category: { name: { contains: q, mode: 'insensitive' } } }
|
|
]
|
|
}
|
|
: {})
|
|
},
|
|
include: {
|
|
asset: true,
|
|
category: { include: { parent: true } }
|
|
},
|
|
orderBy: { occurredAt: 'desc' }
|
|
})
|
|
|
|
const summary = transactions.reduce((acc, tx) => {
|
|
acc[tx.type] += tx.amount
|
|
acc.diff = acc.income - acc.expense
|
|
return acc
|
|
}, { income: 0, expense: 0, diff: 0 })
|
|
|
|
return { summary, transactions }
|
|
})
|