mirror of
https://github.com/felipegcoutinho/openmonetis.git
synced 2026-05-09 11:01:45 +00:00
refactor: alinha features financeiras ao novo naming
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
|
||||
import { and, eq, inArray } from "drizzle-orm";
|
||||
import { z } from "zod";
|
||||
import { preLancamentos } from "@/db/schema";
|
||||
import { inboxItems } from "@/db/schema";
|
||||
import {
|
||||
handleActionError,
|
||||
revalidateForEntity,
|
||||
@@ -52,12 +52,12 @@ export async function markInboxAsProcessedAction(
|
||||
// Verificar se item existe e pertence ao usuário
|
||||
const [item] = await db
|
||||
.select()
|
||||
.from(preLancamentos)
|
||||
.from(inboxItems)
|
||||
.where(
|
||||
and(
|
||||
eq(preLancamentos.id, data.inboxItemId),
|
||||
eq(preLancamentos.userId, user.id),
|
||||
eq(preLancamentos.status, "pending"),
|
||||
eq(inboxItems.id, data.inboxItemId),
|
||||
eq(inboxItems.userId, user.id),
|
||||
eq(inboxItems.status, "pending"),
|
||||
),
|
||||
)
|
||||
.limit(1);
|
||||
@@ -68,7 +68,7 @@ export async function markInboxAsProcessedAction(
|
||||
|
||||
// Marcar item como processado
|
||||
await db
|
||||
.update(preLancamentos)
|
||||
.update(inboxItems)
|
||||
.set({
|
||||
status: "processed",
|
||||
processedAt: new Date(),
|
||||
@@ -76,8 +76,8 @@ export async function markInboxAsProcessedAction(
|
||||
})
|
||||
.where(
|
||||
and(
|
||||
eq(preLancamentos.id, data.inboxItemId),
|
||||
eq(preLancamentos.userId, user.id),
|
||||
eq(inboxItems.id, data.inboxItemId),
|
||||
eq(inboxItems.userId, user.id),
|
||||
),
|
||||
);
|
||||
|
||||
@@ -99,12 +99,12 @@ export async function discardInboxItemAction(
|
||||
// Verificar se item existe e pertence ao usuário
|
||||
const [item] = await db
|
||||
.select()
|
||||
.from(preLancamentos)
|
||||
.from(inboxItems)
|
||||
.where(
|
||||
and(
|
||||
eq(preLancamentos.id, data.inboxItemId),
|
||||
eq(preLancamentos.userId, user.id),
|
||||
eq(preLancamentos.status, "pending"),
|
||||
eq(inboxItems.id, data.inboxItemId),
|
||||
eq(inboxItems.userId, user.id),
|
||||
eq(inboxItems.status, "pending"),
|
||||
),
|
||||
)
|
||||
.limit(1);
|
||||
@@ -115,7 +115,7 @@ export async function discardInboxItemAction(
|
||||
|
||||
// Marcar item como descartado
|
||||
await db
|
||||
.update(preLancamentos)
|
||||
.update(inboxItems)
|
||||
.set({
|
||||
status: "discarded",
|
||||
discardedAt: new Date(),
|
||||
@@ -123,8 +123,8 @@ export async function discardInboxItemAction(
|
||||
})
|
||||
.where(
|
||||
and(
|
||||
eq(preLancamentos.id, data.inboxItemId),
|
||||
eq(preLancamentos.userId, user.id),
|
||||
eq(inboxItems.id, data.inboxItemId),
|
||||
eq(inboxItems.userId, user.id),
|
||||
),
|
||||
);
|
||||
|
||||
@@ -145,7 +145,7 @@ export async function bulkDiscardInboxItemsAction(
|
||||
|
||||
// Marcar todos os itens como descartados
|
||||
await db
|
||||
.update(preLancamentos)
|
||||
.update(inboxItems)
|
||||
.set({
|
||||
status: "discarded",
|
||||
discardedAt: new Date(),
|
||||
@@ -153,9 +153,9 @@ export async function bulkDiscardInboxItemsAction(
|
||||
})
|
||||
.where(
|
||||
and(
|
||||
inArray(preLancamentos.id, data.inboxItemIds),
|
||||
eq(preLancamentos.userId, user.id),
|
||||
eq(preLancamentos.status, "pending"),
|
||||
inArray(inboxItems.id, data.inboxItemIds),
|
||||
eq(inboxItems.userId, user.id),
|
||||
eq(inboxItems.status, "pending"),
|
||||
),
|
||||
);
|
||||
|
||||
@@ -178,13 +178,13 @@ export async function restoreDiscardedInboxItemAction(
|
||||
const data = restoreDiscardedInboxSchema.parse(input);
|
||||
|
||||
const [item] = await db
|
||||
.select({ id: preLancamentos.id })
|
||||
.from(preLancamentos)
|
||||
.select({ id: inboxItems.id })
|
||||
.from(inboxItems)
|
||||
.where(
|
||||
and(
|
||||
eq(preLancamentos.id, data.inboxItemId),
|
||||
eq(preLancamentos.userId, user.id),
|
||||
eq(preLancamentos.status, "discarded"),
|
||||
eq(inboxItems.id, data.inboxItemId),
|
||||
eq(inboxItems.userId, user.id),
|
||||
eq(inboxItems.status, "discarded"),
|
||||
),
|
||||
)
|
||||
.limit(1);
|
||||
@@ -197,7 +197,7 @@ export async function restoreDiscardedInboxItemAction(
|
||||
}
|
||||
|
||||
await db
|
||||
.update(preLancamentos)
|
||||
.update(inboxItems)
|
||||
.set({
|
||||
status: "pending",
|
||||
discardedAt: null,
|
||||
@@ -205,8 +205,8 @@ export async function restoreDiscardedInboxItemAction(
|
||||
})
|
||||
.where(
|
||||
and(
|
||||
eq(preLancamentos.id, data.inboxItemId),
|
||||
eq(preLancamentos.userId, user.id),
|
||||
eq(inboxItems.id, data.inboxItemId),
|
||||
eq(inboxItems.userId, user.id),
|
||||
),
|
||||
);
|
||||
|
||||
@@ -226,12 +226,12 @@ export async function deleteInboxItemAction(
|
||||
const data = deleteInboxSchema.parse(input);
|
||||
|
||||
const [item] = await db
|
||||
.select({ status: preLancamentos.status })
|
||||
.from(preLancamentos)
|
||||
.select({ status: inboxItems.status })
|
||||
.from(inboxItems)
|
||||
.where(
|
||||
and(
|
||||
eq(preLancamentos.id, data.inboxItemId),
|
||||
eq(preLancamentos.userId, user.id),
|
||||
eq(inboxItems.id, data.inboxItemId),
|
||||
eq(inboxItems.userId, user.id),
|
||||
),
|
||||
)
|
||||
.limit(1);
|
||||
@@ -248,11 +248,11 @@ export async function deleteInboxItemAction(
|
||||
}
|
||||
|
||||
await db
|
||||
.delete(preLancamentos)
|
||||
.delete(inboxItems)
|
||||
.where(
|
||||
and(
|
||||
eq(preLancamentos.id, data.inboxItemId),
|
||||
eq(preLancamentos.userId, user.id),
|
||||
eq(inboxItems.id, data.inboxItemId),
|
||||
eq(inboxItems.userId, user.id),
|
||||
),
|
||||
);
|
||||
|
||||
@@ -272,14 +272,11 @@ export async function bulkDeleteInboxItemsAction(
|
||||
const data = bulkDeleteInboxSchema.parse(input);
|
||||
|
||||
const result = await db
|
||||
.delete(preLancamentos)
|
||||
.delete(inboxItems)
|
||||
.where(
|
||||
and(
|
||||
eq(preLancamentos.userId, user.id),
|
||||
eq(preLancamentos.status, data.status),
|
||||
),
|
||||
and(eq(inboxItems.userId, user.id), eq(inboxItems.status, data.status)),
|
||||
)
|
||||
.returning({ id: preLancamentos.id });
|
||||
.returning({ id: inboxItems.id });
|
||||
|
||||
revalidateInbox();
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ import {
|
||||
markInboxAsProcessedAction,
|
||||
restoreDiscardedInboxItemAction,
|
||||
} from "@/features/inbox/actions";
|
||||
import { LancamentoDialog } from "@/features/transactions/components/dialogs/transaction-dialog/transaction-dialog";
|
||||
import { TransactionDialog } from "@/features/transactions/components/dialogs/transaction-dialog/transaction-dialog";
|
||||
import { ConfirmActionDialog } from "@/shared/components/confirm-action-dialog";
|
||||
import { EmptyState } from "@/shared/components/empty-state";
|
||||
import { Button } from "@/shared/components/ui/button";
|
||||
@@ -29,12 +29,12 @@ interface InboxPageProps {
|
||||
pendingItems: InboxItem[];
|
||||
processedItems: InboxItem[];
|
||||
discardedItems: InboxItem[];
|
||||
pagadorOptions: SelectOption[];
|
||||
splitPagadorOptions: SelectOption[];
|
||||
defaultPagadorId: string | null;
|
||||
contaOptions: SelectOption[];
|
||||
cartaoOptions: SelectOption[];
|
||||
categoriaOptions: SelectOption[];
|
||||
payerOptions: SelectOption[];
|
||||
splitPayerOptions: SelectOption[];
|
||||
defaultPayerId: string | null;
|
||||
accountOptions: SelectOption[];
|
||||
cardOptions: SelectOption[];
|
||||
categoryOptions: SelectOption[];
|
||||
estabelecimentos: string[];
|
||||
appLogoMap: Record<string, string>;
|
||||
}
|
||||
@@ -43,12 +43,12 @@ export function InboxPage({
|
||||
pendingItems,
|
||||
processedItems,
|
||||
discardedItems,
|
||||
pagadorOptions,
|
||||
splitPagadorOptions,
|
||||
defaultPagadorId,
|
||||
contaOptions,
|
||||
cartaoOptions,
|
||||
categoriaOptions,
|
||||
payerOptions,
|
||||
splitPayerOptions,
|
||||
defaultPayerId,
|
||||
accountOptions,
|
||||
cardOptions,
|
||||
categoryOptions,
|
||||
estabelecimentos,
|
||||
appLogoMap,
|
||||
}: InboxPageProps) {
|
||||
@@ -272,14 +272,14 @@ export function InboxPage({
|
||||
const appName = itemToProcess?.sourceAppName?.toLowerCase();
|
||||
if (!appName) return null;
|
||||
|
||||
for (const option of cartaoOptions) {
|
||||
for (const option of cardOptions) {
|
||||
const label = option.label.toLowerCase();
|
||||
if (label.includes(appName) || appName.includes(label)) {
|
||||
return option.value;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}, [itemToProcess?.sourceAppName, cartaoOptions]);
|
||||
}, [itemToProcess?.sourceAppName, cardOptions]);
|
||||
|
||||
const renderEmptyState = (message: string) => (
|
||||
<Card className="flex min-h-[50vh] w-full items-center justify-center py-12">
|
||||
@@ -378,21 +378,21 @@ export function InboxPage({
|
||||
</TabsContent>
|
||||
</Tabs>
|
||||
|
||||
<LancamentoDialog
|
||||
<TransactionDialog
|
||||
mode="create"
|
||||
open={processOpen}
|
||||
onOpenChange={handleProcessOpenChange}
|
||||
pagadorOptions={pagadorOptions}
|
||||
splitPagadorOptions={splitPagadorOptions}
|
||||
defaultPagadorId={defaultPagadorId}
|
||||
contaOptions={contaOptions}
|
||||
cartaoOptions={cartaoOptions}
|
||||
categoriaOptions={categoriaOptions}
|
||||
payerOptions={payerOptions}
|
||||
splitPayerOptions={splitPayerOptions}
|
||||
defaultPayerId={defaultPayerId}
|
||||
accountOptions={accountOptions}
|
||||
cardOptions={cardOptions}
|
||||
categoryOptions={categoryOptions}
|
||||
estabelecimentos={estabelecimentos}
|
||||
defaultPurchaseDate={defaultPurchaseDate}
|
||||
defaultName={defaultName}
|
||||
defaultAmount={defaultAmount}
|
||||
defaultCartaoId={matchedCartaoId}
|
||||
defaultCardId={matchedCartaoId}
|
||||
defaultPaymentMethod={matchedCartaoId ? "Cartão de crédito" : null}
|
||||
forceShowTransactionType
|
||||
onSuccess={handleLancamentoSuccess}
|
||||
|
||||
@@ -10,7 +10,7 @@ export interface InboxItem {
|
||||
parsedName: string | null;
|
||||
parsedAmount: string | null;
|
||||
status: string;
|
||||
lancamentoId: string | null;
|
||||
transactionId: string | null;
|
||||
processedAt: Date | null;
|
||||
discardedAt: Date | null;
|
||||
createdAt: Date;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { and, desc, eq } from "drizzle-orm";
|
||||
import { cartoes, categorias, contas, preLancamentos } from "@/db/schema";
|
||||
import { cards, categories, financialAccounts, inboxItems } from "@/db/schema";
|
||||
import type {
|
||||
InboxItem,
|
||||
SelectOption,
|
||||
@@ -9,8 +9,8 @@ import {
|
||||
buildSluggedFilters,
|
||||
} from "@/features/transactions/page-helpers";
|
||||
import {
|
||||
fetchLancamentoFilterSources,
|
||||
fetchRecentEstablishments,
|
||||
fetchTransactionFilterSources,
|
||||
} from "@/features/transactions/queries";
|
||||
import { db } from "@/shared/lib/db";
|
||||
|
||||
@@ -20,11 +20,9 @@ export async function fetchInboxItems(
|
||||
): Promise<InboxItem[]> {
|
||||
const items = await db
|
||||
.select()
|
||||
.from(preLancamentos)
|
||||
.where(
|
||||
and(eq(preLancamentos.userId, userId), eq(preLancamentos.status, status)),
|
||||
)
|
||||
.orderBy(desc(preLancamentos.createdAt));
|
||||
.from(inboxItems)
|
||||
.where(and(eq(inboxItems.userId, userId), eq(inboxItems.status, status)))
|
||||
.orderBy(desc(inboxItems.createdAt));
|
||||
|
||||
return items;
|
||||
}
|
||||
@@ -35,54 +33,57 @@ export async function fetchInboxItemById(
|
||||
): Promise<InboxItem | null> {
|
||||
const [item] = await db
|
||||
.select()
|
||||
.from(preLancamentos)
|
||||
.where(
|
||||
and(eq(preLancamentos.id, itemId), eq(preLancamentos.userId, userId)),
|
||||
)
|
||||
.from(inboxItems)
|
||||
.where(and(eq(inboxItems.id, itemId), eq(inboxItems.userId, userId)))
|
||||
.limit(1);
|
||||
|
||||
return item ?? null;
|
||||
}
|
||||
|
||||
export async function fetchCategoriasForSelect(
|
||||
export async function fetchCategoriesForSelect(
|
||||
userId: string,
|
||||
type?: string,
|
||||
): Promise<SelectOption[]> {
|
||||
const query = db
|
||||
.select({ id: categorias.id, name: categorias.name })
|
||||
.from(categorias)
|
||||
const rows = await db
|
||||
.select({ id: categories.id, name: categories.name })
|
||||
.from(categories)
|
||||
.where(
|
||||
type
|
||||
? and(eq(categorias.userId, userId), eq(categorias.type, type))
|
||||
: eq(categorias.userId, userId),
|
||||
? and(eq(categories.userId, userId), eq(categories.type, type))
|
||||
: eq(categories.userId, userId),
|
||||
)
|
||||
.orderBy(categorias.name);
|
||||
.orderBy(categories.name);
|
||||
|
||||
return query;
|
||||
return rows.map((row) => ({ value: row.id, label: row.name }));
|
||||
}
|
||||
|
||||
export async function fetchContasForSelect(
|
||||
export async function fetchAccountsForSelect(
|
||||
userId: string,
|
||||
): Promise<SelectOption[]> {
|
||||
const items = await db
|
||||
.select({ id: contas.id, name: contas.name })
|
||||
.from(contas)
|
||||
.where(and(eq(contas.userId, userId), eq(contas.status, "ativo")))
|
||||
.orderBy(contas.name);
|
||||
const rows = await db
|
||||
.select({ id: financialAccounts.id, name: financialAccounts.name })
|
||||
.from(financialAccounts)
|
||||
.where(
|
||||
and(
|
||||
eq(financialAccounts.userId, userId),
|
||||
eq(financialAccounts.status, "ativo"),
|
||||
),
|
||||
)
|
||||
.orderBy(financialAccounts.name);
|
||||
|
||||
return items;
|
||||
return rows.map((row) => ({ value: row.id, label: row.name }));
|
||||
}
|
||||
|
||||
export async function fetchCartoesForSelect(
|
||||
export async function fetchCardsForSelect(
|
||||
userId: string,
|
||||
): Promise<(SelectOption & { lastDigits?: string })[]> {
|
||||
const items = await db
|
||||
.select({ id: cartoes.id, name: cartoes.name })
|
||||
.from(cartoes)
|
||||
.where(and(eq(cartoes.userId, userId), eq(cartoes.status, "ativo")))
|
||||
.orderBy(cartoes.name);
|
||||
const rows = await db
|
||||
.select({ id: cards.id, name: cards.name })
|
||||
.from(cards)
|
||||
.where(and(eq(cards.userId, userId), eq(cards.status, "ativo")))
|
||||
.orderBy(cards.name);
|
||||
|
||||
return items;
|
||||
return rows.map((row) => ({ value: row.id, label: row.name }));
|
||||
}
|
||||
|
||||
export async function fetchAppLogoMap(
|
||||
@@ -90,13 +91,13 @@ export async function fetchAppLogoMap(
|
||||
): Promise<Record<string, string>> {
|
||||
const [userCartoes, userContas] = await Promise.all([
|
||||
db
|
||||
.select({ name: cartoes.name, logo: cartoes.logo })
|
||||
.from(cartoes)
|
||||
.where(eq(cartoes.userId, userId)),
|
||||
.select({ name: cards.name, logo: cards.logo })
|
||||
.from(cards)
|
||||
.where(eq(cards.userId, userId)),
|
||||
db
|
||||
.select({ name: contas.name, logo: contas.logo })
|
||||
.from(contas)
|
||||
.where(eq(contas.userId, userId)),
|
||||
.select({ name: financialAccounts.name, logo: financialAccounts.logo })
|
||||
.from(financialAccounts)
|
||||
.where(eq(financialAccounts.userId, userId)),
|
||||
]);
|
||||
|
||||
const logoMap: Record<string, string> = {};
|
||||
@@ -112,54 +113,51 @@ export async function fetchAppLogoMap(
|
||||
|
||||
export async function fetchPendingInboxCount(userId: string): Promise<number> {
|
||||
const items = await db
|
||||
.select({ id: preLancamentos.id })
|
||||
.from(preLancamentos)
|
||||
.select({ id: inboxItems.id })
|
||||
.from(inboxItems)
|
||||
.where(
|
||||
and(
|
||||
eq(preLancamentos.userId, userId),
|
||||
eq(preLancamentos.status, "pending"),
|
||||
),
|
||||
and(eq(inboxItems.userId, userId), eq(inboxItems.status, "pending")),
|
||||
);
|
||||
|
||||
return items.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch all data needed for the LancamentoDialog in inbox context
|
||||
* Fetch all data needed for the TransactionDialog in inbox context
|
||||
*/
|
||||
export async function fetchInboxDialogData(userId: string): Promise<{
|
||||
pagadorOptions: SelectOption[];
|
||||
splitPagadorOptions: SelectOption[];
|
||||
defaultPagadorId: string | null;
|
||||
contaOptions: SelectOption[];
|
||||
cartaoOptions: SelectOption[];
|
||||
categoriaOptions: SelectOption[];
|
||||
payerOptions: SelectOption[];
|
||||
splitPayerOptions: SelectOption[];
|
||||
defaultPayerId: string | null;
|
||||
accountOptions: SelectOption[];
|
||||
cardOptions: SelectOption[];
|
||||
categoryOptions: SelectOption[];
|
||||
estabelecimentos: string[];
|
||||
}> {
|
||||
const filterSources = await fetchLancamentoFilterSources(userId);
|
||||
const filterSources = await fetchTransactionFilterSources(userId);
|
||||
const sluggedFilters = buildSluggedFilters(filterSources);
|
||||
|
||||
const {
|
||||
pagadorOptions,
|
||||
splitPagadorOptions,
|
||||
defaultPagadorId,
|
||||
contaOptions,
|
||||
cartaoOptions,
|
||||
categoriaOptions,
|
||||
payerOptions,
|
||||
splitPayerOptions,
|
||||
defaultPayerId,
|
||||
accountOptions,
|
||||
cardOptions,
|
||||
categoryOptions,
|
||||
} = buildOptionSets({
|
||||
...sluggedFilters,
|
||||
pagadorRows: filterSources.pagadorRows,
|
||||
payerRows: filterSources.payerRows,
|
||||
});
|
||||
|
||||
const estabelecimentos = await fetchRecentEstablishments(userId);
|
||||
|
||||
return {
|
||||
pagadorOptions,
|
||||
splitPagadorOptions,
|
||||
defaultPagadorId,
|
||||
contaOptions,
|
||||
cartaoOptions,
|
||||
categoriaOptions,
|
||||
payerOptions,
|
||||
splitPayerOptions,
|
||||
defaultPayerId,
|
||||
accountOptions,
|
||||
cardOptions,
|
||||
categoryOptions,
|
||||
estabelecimentos,
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user