UNPKG

expense-log-mcp

Version:

A MCP server that provides tools for logging expenses.

72 lines (71 loc) 2.82 kB
import { z } from "zod"; import prisma from "../db.js"; import { successResponse, errorResponse, getErrorMessage } from "./utils.js"; const getGroupedExpensesParameters = z.object({ ledgerId: z.string(), categoryIds: z.array(z.string()).optional(), payer: z.string().optional(), startDate: z.string().optional(), endDate: z.string().optional(), }); export const getGroupedExpenses = { name: "getGroupedExpenses", description: `Retrieves and groups expenses by payer and category, showing total amounts, with optional filters for category IDs, payer, and date range (ISO 8601 format).`, parameters: getGroupedExpensesParameters, execute: async ({ ledgerId, categoryIds, payer, startDate, endDate }) => { try { const where = buildWhereFilter(ledgerId, categoryIds, payer, startDate, endDate); const expenses = await prisma.expense.findMany({ where }); const categories = await prisma.expenseCategory.findMany(); const categoryMap = new Map(); categories.forEach(category => { categoryMap.set(category.id, category.name); }); const groupedExpenses = groupExpenses(expenses, categoryMap); return successResponse("Grouped expenses retrieved successfully.", groupedExpenses); } catch (e) { return errorResponse("DATABSAE_ERROR", getErrorMessage(e)); } } }; function buildWhereFilter(ledgerId, categoryIds, payer, startDate, endDate) { const where = {}; where.ledgerId = ledgerId; if (categoryIds && categoryIds.length > 0) { where.categoryId = { in: categoryIds }; } if (payer) { where.payer = payer; } if (!startDate && !endDate) { const now = new Date(); startDate = new Date(now.getFullYear(), now.getMonth(), 1).toISOString(); endDate = new Date(now.getFullYear(), now.getMonth() + 1, 0).toISOString(); } where.createdAt = {}; if (startDate) { where.createdAt.gte = new Date(startDate); } if (endDate) { where.createdAt.lte = new Date(endDate); } return where; } function groupExpenses(expenses, categoryMap) { return expenses.reduce((acc, expense) => { const payer = expense.payer; const categoryId = expense.categoryId; const categoryName = categoryMap.get(categoryId) || 'Unknown Category'; if (!acc[payer]) { acc[payer] = { expenseCategories: {}, totalAmount: 0 }; } if (!acc[payer].expenseCategories[categoryName]) { acc[payer].expenseCategories[categoryName] = 0; } acc[payer].expenseCategories[categoryName] += expense.amount; acc[payer].totalAmount += expense.amount; return acc; }, {}); }