import { and, asc, eq } from "drizzle-orm"; import { cartoes, contas, lancamentos } from "@/db/schema"; import { buildDashboardAdminPeriodFilters, excludeAutoGeneratedEntryNotes, } from "@/lib/dashboard/lancamento-filters"; import { db } from "@/lib/db"; import { getAdminPagadorId } from "@/lib/pagadores/get-admin-id"; import { safeToNumber as toNumber } from "@/lib/utils/number"; export type TopExpense = { id: string; name: string; amount: number; purchaseDate: Date; paymentMethod: string; logo?: string | null; }; export type TopExpensesData = { expenses: TopExpense[]; }; export async function fetchTopExpenses( userId: string, period: string, cardOnly: boolean = false, ): Promise { const adminPagadorId = await getAdminPagadorId(userId); if (!adminPagadorId) { return { expenses: [] }; } const conditions = [ ...buildDashboardAdminPeriodFilters({ userId, period, adminPagadorId, }), eq(lancamentos.transactionType, "Despesa"), excludeAutoGeneratedEntryNotes(), ]; // Se cardOnly for true, filtra apenas pagamentos com cartão if (cardOnly) { conditions.push(eq(lancamentos.paymentMethod, "Cartão de Crédito")); } const results = await db .select({ id: lancamentos.id, name: lancamentos.name, amount: lancamentos.amount, purchaseDate: lancamentos.purchaseDate, paymentMethod: lancamentos.paymentMethod, cartaoId: lancamentos.cartaoId, contaId: lancamentos.contaId, cardLogo: cartoes.logo, accountLogo: contas.logo, }) .from(lancamentos) .leftJoin(cartoes, eq(lancamentos.cartaoId, cartoes.id)) .leftJoin(contas, eq(lancamentos.contaId, contas.id)) .where(and(...conditions)) .orderBy(asc(lancamentos.amount)) .limit(10); const expenses = results.map( (row: (typeof results)[number]): TopExpense => ({ id: row.id, name: row.name, amount: Math.abs(toNumber(row.amount)), purchaseDate: row.purchaseDate, paymentMethod: row.paymentMethod, logo: row.cardLogo ?? row.accountLogo ?? null, }), ); return { expenses, }; }