import { and, eq, sql } from "drizzle-orm"; import { transactions } from "@/db/schema"; import { buildDashboardAdminPeriodFilters, excludeAutoGeneratedEntryNotes, } from "@/features/dashboard/transaction-filters"; import { db } from "@/shared/lib/db"; import { getAdminPayerId } from "@/shared/lib/payers/get-admin-id"; import { safeToNumber as toNumber } from "@/shared/utils/number"; export type PaymentConditionSummary = { condition: string; amount: number; percentage: number; transactions: number; }; export type PaymentConditionsData = { conditions: PaymentConditionSummary[]; }; export async function fetchPaymentConditions( userId: string, period: string, ): Promise { const adminPayerId = await getAdminPayerId(userId); if (!adminPayerId) { return { conditions: [] }; } const rows = await db .select({ condition: transactions.condition, totalAmount: sql`coalesce(sum(${transactions.amount}), 0)`, transactions: sql`count(${transactions.id})`, }) .from(transactions) .where( and( ...buildDashboardAdminPeriodFilters({ userId, period, adminPayerId, }), eq(transactions.transactionType, "Despesa"), excludeAutoGeneratedEntryNotes(), ), ) .groupBy(transactions.condition); const summaries = rows.map((row: (typeof rows)[number]) => { const totalAmount = Math.abs(toNumber(row.totalAmount)); const transactions = Number(row.transactions ?? 0); return { condition: row.condition, amount: totalAmount, transactions, }; }); const overallTotal = summaries.reduce( (acc: number, item: (typeof summaries)[number]) => acc + item.amount, 0, ); const conditions = summaries .map((item: (typeof summaries)[number]) => ({ condition: item.condition, amount: item.amount, transactions: item.transactions, percentage: overallTotal > 0 ? Number(((item.amount / overallTotal) * 100).toFixed(2)) : 0, })) .sort( (a: (typeof summaries)[number], b: (typeof summaries)[number]) => b.amount - a.amount, ); return { conditions, }; }