mirror of
https://github.com/felipegcoutinho/openmonetis.git
synced 2026-05-11 03:31:47 +00:00
fix: exclui transações de contas fora do saldo nos totais por pessoa e orçamentos
Adicionado leftJoin(financialAccounts) + excludeTransactionsFromExcludedAccounts() em 6 queries de payers/details.ts (totais do mês, histórico, uso de cartões, etc.) e em fetchBudgetsForUser/fetchCategoryBudgetSummary de budgets/queries.ts. Contas marcadas como excludeFromBalance (ex: Ajuste de saldo) não entram mais nos cálculos de gasto, alinhando a tela de Pessoas, Orçamentos e o badge do modal. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,12 @@
|
||||
import { and, asc, eq, inArray, isNull, or, sql, sum } from "drizzle-orm";
|
||||
import { budgets, categories, transactions } from "@/db/schema";
|
||||
import {
|
||||
budgets,
|
||||
categories,
|
||||
financialAccounts,
|
||||
transactions,
|
||||
} from "@/db/schema";
|
||||
import { ACCOUNT_AUTO_INVOICE_NOTE_PREFIX } from "@/shared/lib/accounts/constants";
|
||||
import { excludeTransactionsFromExcludedAccounts } from "@/shared/lib/accounts/query-filters";
|
||||
import { db } from "@/shared/lib/db";
|
||||
import { getAdminPayerId } from "@/shared/lib/payers/get-admin-id";
|
||||
|
||||
@@ -75,6 +81,10 @@ export async function fetchBudgetsForUser(
|
||||
totalAmount: sum(transactions.amount).as("totalAmount"),
|
||||
})
|
||||
.from(transactions)
|
||||
.leftJoin(
|
||||
financialAccounts,
|
||||
eq(transactions.accountId, financialAccounts.id),
|
||||
)
|
||||
.where(
|
||||
and(
|
||||
eq(transactions.userId, userId),
|
||||
@@ -86,6 +96,7 @@ export async function fetchBudgetsForUser(
|
||||
isNull(transactions.note),
|
||||
sql`${transactions.note} NOT LIKE ${`${ACCOUNT_AUTO_INVOICE_NOTE_PREFIX}%`}`,
|
||||
),
|
||||
excludeTransactionsFromExcludedAccounts(),
|
||||
),
|
||||
)
|
||||
.groupBy(transactions.categoryId);
|
||||
@@ -127,3 +138,57 @@ export async function fetchBudgetsForUser(
|
||||
|
||||
return { budgets: budgetList, categoriesOptions };
|
||||
}
|
||||
|
||||
export type CategoryBudgetSummary = {
|
||||
amount: number;
|
||||
spent: number;
|
||||
};
|
||||
|
||||
export async function fetchCategoryBudgetSummary(
|
||||
userId: string,
|
||||
categoryId: string,
|
||||
period: string,
|
||||
): Promise<CategoryBudgetSummary | null> {
|
||||
const [adminPayerId, budget] = await Promise.all([
|
||||
getAdminPayerId(userId),
|
||||
db.query.budgets.findFirst({
|
||||
columns: { amount: true },
|
||||
where: and(
|
||||
eq(budgets.userId, userId),
|
||||
eq(budgets.categoryId, categoryId),
|
||||
eq(budgets.period, period),
|
||||
),
|
||||
}),
|
||||
]);
|
||||
|
||||
if (!adminPayerId || !budget) return null;
|
||||
|
||||
const totals = await db
|
||||
.select({
|
||||
totalAmount: sum(transactions.amount).as("totalAmount"),
|
||||
})
|
||||
.from(transactions)
|
||||
.leftJoin(
|
||||
financialAccounts,
|
||||
eq(transactions.accountId, financialAccounts.id),
|
||||
)
|
||||
.where(
|
||||
and(
|
||||
eq(transactions.userId, userId),
|
||||
eq(transactions.period, period),
|
||||
eq(transactions.transactionType, "Despesa"),
|
||||
eq(transactions.payerId, adminPayerId),
|
||||
eq(transactions.categoryId, categoryId),
|
||||
or(
|
||||
isNull(transactions.note),
|
||||
sql`${transactions.note} NOT LIKE ${`${ACCOUNT_AUTO_INVOICE_NOTE_PREFIX}%`}`,
|
||||
),
|
||||
excludeTransactionsFromExcludedAccounts(),
|
||||
),
|
||||
);
|
||||
|
||||
return {
|
||||
amount: toNumber(budget.amount),
|
||||
spent: Math.abs(toNumber(totals[0]?.totalAmount ?? 0)),
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user