feat(expenses): add edit amount and due date for pending expenses
This commit is contained in:
@@ -12,6 +12,7 @@ import { listExpensesHandler } from "./handlers/listExpenses";
|
||||
import { listPeriodicExpensesHandler } from "./handlers/listPeriodicExpenses";
|
||||
import { payExpenseHandler } from "./handlers/payExpense";
|
||||
import { softDeletePeriodicExpenseHandler } from "./handlers/softDeletePeriodicExpense";
|
||||
import { updateExpenseHandler } from "./handlers/updateExpense";
|
||||
import { updatePeriodicExpenseHandler } from "./handlers/updatePeriodicExpense";
|
||||
|
||||
const app = new Hono();
|
||||
@@ -34,5 +35,6 @@ app.get("/expenses", listExpensesHandler);
|
||||
app.post("/expenses", createNonPeriodicExpenseHandler);
|
||||
app.post("/expenses/import", importExpensesHandler);
|
||||
app.put("/expenses/:id/pay", payExpenseHandler);
|
||||
app.put("/expenses/:id", updateExpenseHandler);
|
||||
|
||||
export default app;
|
||||
|
||||
@@ -23,6 +23,11 @@ export const payExpenseSchema = z.object({
|
||||
paymentDate: z.string().datetime().optional(),
|
||||
});
|
||||
|
||||
export const updateExpenseSchema = z.object({
|
||||
amount: z.number().positive("El monto debe ser mayor a 0"),
|
||||
dueDate: z.string().datetime({ message: "La fecha debe ser una fecha ISO válida" }),
|
||||
});
|
||||
|
||||
function lastDayOfMonth(year: number, month: number): number {
|
||||
return new Date(year, month, 0).getDate();
|
||||
}
|
||||
@@ -187,6 +192,32 @@ export async function payExpense(
|
||||
return result;
|
||||
}
|
||||
|
||||
export async function updateExpense(
|
||||
id: number,
|
||||
data: z.infer<typeof updateExpenseSchema>,
|
||||
) {
|
||||
const existing = await prisma.expense.findUniqueOrThrow({ where: { id } });
|
||||
if (existing.status !== PaymentStatus.PENDING) {
|
||||
throw new Error("Solo se pueden editar gastos pendientes");
|
||||
}
|
||||
|
||||
const dueDate = new Date(data.dueDate);
|
||||
const year = dueDate.getUTCFullYear();
|
||||
const month = dueDate.getUTCMonth() + 1;
|
||||
|
||||
const result = await prisma.expense.update({
|
||||
where: { id },
|
||||
data: {
|
||||
amount: data.amount,
|
||||
dueDate,
|
||||
year,
|
||||
month,
|
||||
},
|
||||
});
|
||||
cache.invalidateByPrefix("expenses:");
|
||||
return result;
|
||||
}
|
||||
|
||||
export async function getMonthlyPayedTotal(year: number, month: number) {
|
||||
const cacheKey = `expenses:monthly-total:${year}:${month}`;
|
||||
const cached = cache.get(cacheKey);
|
||||
|
||||
10
apps/backend/src/modules/expenses/handlers/updateExpense.ts
Normal file
10
apps/backend/src/modules/expenses/handlers/updateExpense.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import type { Context } from "hono";
|
||||
import { updateExpense, updateExpenseSchema } from "../expenses.service";
|
||||
|
||||
export async function updateExpenseHandler(c: Context) {
|
||||
const id = Number(c.req.param("id"));
|
||||
const body = await c.req.json();
|
||||
const parsed = updateExpenseSchema.parse(body);
|
||||
const result = await updateExpense(id, parsed);
|
||||
return c.json(result);
|
||||
}
|
||||
Reference in New Issue
Block a user