import { and, eq, sql } from "drizzle-orm"; import { lancamentos, pagadores } from "@/db/schema"; import { ACCOUNT_AUTO_INVOICE_NOTE_PREFIX } from "@/lib/accounts/constants"; import { toNumber } from "@/lib/dashboard/common"; import { db } from "@/lib/db"; export type PaymentStatusCategory = { total: number; confirmed: number; pending: number; }; export type PaymentStatusData = { income: PaymentStatusCategory; expenses: PaymentStatusCategory; }; export async function fetchPaymentStatus( userId: string, period: string, ): Promise { // Busca receitas confirmadas e pendentes para o período do pagador admin // Exclui lançamentos de pagamento de fatura (para evitar contagem duplicada) const incomeResult = await db .select({ confirmed: sql` coalesce( sum( case when ${lancamentos.isSettled} = true then ${lancamentos.amount} else 0 end ), 0 ) `, pending: sql` coalesce( sum( case when ${lancamentos.isSettled} = false or ${lancamentos.isSettled} is null then ${lancamentos.amount} else 0 end ), 0 ) `, }) .from(lancamentos) .innerJoin(pagadores, eq(lancamentos.pagadorId, pagadores.id)) .where( and( eq(lancamentos.userId, userId), eq(lancamentos.period, period), eq(lancamentos.transactionType, "Receita"), eq(pagadores.role, "admin"), sql`(${lancamentos.note} IS NULL OR ${lancamentos.note} NOT LIKE ${`${ACCOUNT_AUTO_INVOICE_NOTE_PREFIX}%`})`, ), ); // Busca despesas confirmadas e pendentes para o período do pagador admin // Exclui lançamentos de pagamento de fatura (para evitar contagem duplicada) const expensesResult = await db .select({ confirmed: sql` coalesce( sum( case when ${lancamentos.isSettled} = true then ${lancamentos.amount} else 0 end ), 0 ) `, pending: sql` coalesce( sum( case when ${lancamentos.isSettled} = false or ${lancamentos.isSettled} is null then ${lancamentos.amount} else 0 end ), 0 ) `, }) .from(lancamentos) .innerJoin(pagadores, eq(lancamentos.pagadorId, pagadores.id)) .where( and( eq(lancamentos.userId, userId), eq(lancamentos.period, period), eq(lancamentos.transactionType, "Despesa"), eq(pagadores.role, "admin"), sql`(${lancamentos.note} IS NULL OR ${lancamentos.note} NOT LIKE ${`${ACCOUNT_AUTO_INVOICE_NOTE_PREFIX}%`})`, ), ); const incomeData = incomeResult[0] ?? { confirmed: 0, pending: 0 }; const confirmedIncome = toNumber(incomeData.confirmed); const pendingIncome = toNumber(incomeData.pending); const expensesData = expensesResult[0] ?? { confirmed: 0, pending: 0 }; const confirmedExpenses = toNumber(expensesData.confirmed); const pendingExpenses = toNumber(expensesData.pending); return { income: { total: confirmedIncome + pendingIncome, confirmed: confirmedIncome, pending: pendingIncome, }, expenses: { total: confirmedExpenses + pendingExpenses, confirmed: confirmedExpenses, pending: pendingExpenses, }, }; }