Files
openmonetis/app/(dashboard)/cartoes/[cartaoId]/fatura/data.ts
Felipe Coutinho a7f63fb77a refactor: migrate from ESLint to Biome and extract SQL queries to data.ts
- Replace ESLint with Biome for linting and formatting
- Configure Biome with tabs, double quotes, and organized imports
- Move all SQL/Drizzle queries from page.tsx files to data.ts files
- Create new data.ts files for: ajustes, dashboard, relatorios/categorias
- Update existing data.ts files: extrato, fatura (add lancamentos queries)
- Remove all drizzle-orm imports from page.tsx files
- Update README.md with new tooling info

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-27 13:15:37 +00:00

118 lines
2.8 KiB
TypeScript

import { and, desc, eq, type SQL, sum } from "drizzle-orm";
import { cartoes, faturas, lancamentos } from "@/db/schema";
import { buildInvoicePaymentNote } from "@/lib/accounts/constants";
import { db } from "@/lib/db";
import {
INVOICE_PAYMENT_STATUS,
type InvoicePaymentStatus,
} from "@/lib/faturas";
const toNumber = (value: string | number | null | undefined) => {
if (typeof value === "number") {
return value;
}
if (value === null || value === undefined) {
return 0;
}
const parsed = Number(value);
return Number.isNaN(parsed) ? 0 : parsed;
};
export async function fetchCardData(userId: string, cartaoId: string) {
const card = await db.query.cartoes.findFirst({
columns: {
id: true,
name: true,
brand: true,
closingDay: true,
dueDay: true,
logo: true,
limit: true,
status: true,
note: true,
contaId: true,
},
where: and(eq(cartoes.id, cartaoId), eq(cartoes.userId, userId)),
});
return card;
}
export async function fetchInvoiceData(
userId: string,
cartaoId: string,
selectedPeriod: string,
): Promise<{
totalAmount: number;
invoiceStatus: InvoicePaymentStatus;
paymentDate: Date | null;
}> {
const [invoiceRow, totalRow] = await Promise.all([
db.query.faturas.findFirst({
columns: {
id: true,
period: true,
paymentStatus: true,
},
where: and(
eq(faturas.cartaoId, cartaoId),
eq(faturas.userId, userId),
eq(faturas.period, selectedPeriod),
),
}),
db
.select({ totalAmount: sum(lancamentos.amount) })
.from(lancamentos)
.where(
and(
eq(lancamentos.userId, userId),
eq(lancamentos.cartaoId, cartaoId),
eq(lancamentos.period, selectedPeriod),
),
),
]);
const totalAmount = toNumber(totalRow[0]?.totalAmount);
const isInvoiceStatus = (
value: string | null | undefined,
): value is InvoicePaymentStatus =>
!!value && ["pendente", "pago"].includes(value);
const invoiceStatus = isInvoiceStatus(invoiceRow?.paymentStatus)
? invoiceRow?.paymentStatus
: INVOICE_PAYMENT_STATUS.PENDING;
// Buscar data do pagamento se a fatura estiver paga
let paymentDate: Date | null = null;
if (invoiceStatus === INVOICE_PAYMENT_STATUS.PAID) {
const invoiceNote = buildInvoicePaymentNote(cartaoId, selectedPeriod);
const paymentLancamento = await db.query.lancamentos.findFirst({
columns: {
purchaseDate: true,
},
where: and(
eq(lancamentos.userId, userId),
eq(lancamentos.note, invoiceNote),
),
});
paymentDate = paymentLancamento?.purchaseDate
? new Date(paymentLancamento.purchaseDate)
: null;
}
return { totalAmount, invoiceStatus, paymentDate };
}
export async function fetchCardLancamentos(filters: SQL[]) {
return db.query.lancamentos.findMany({
where: and(...filters),
with: {
pagador: true,
conta: true,
cartao: true,
categoria: true,
},
orderBy: desc(lancamentos.purchaseDate),
});
}