fix: useEffect anti-patterns, attendance permissions, and received-invoices schema mismatch
- Remove ref-mirror useEffect in AuthContext (cachedUserRef already written at mutation sites) - Replace useEffect slide direction in ReceivedInvoices with render-time computation - Fix Login.tsx useEffect dependency array (mount-only alert should have [] deps) - Move "project created" alert to navigation source in ProjectCreate, remove useEffect in ProjectDetail - Move companySettings defaults into fetch callbacks in InvoiceDetail and OfferDetail - Replace due_date useEffect with useMemo in InvoiceDetail - Capture initial snapshots from API data instead of useEffect in InvoiceDetail, OfferDetail, OrderDetail - Replace localStorage draft useEffect with lazy useState initializer in OfferDetail - Fix attendance dropdown to filter by attendance.record permission only - Fix clock-out 404 on update-address (remove departure_time filter for departure action) - Fix received-invoices stats endpoint referencing non-existent is_deleted and amount_czk columns Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -99,7 +99,7 @@ export default async function receivedInvoicesRoutes(
|
||||
|
||||
// Aggregate by currency → CurrencyAmount[] format
|
||||
const aggregateByCurrency = (
|
||||
invs: typeof monthInvoices,
|
||||
invs: { currency: string; [key: string]: unknown }[],
|
||||
field: "amount" | "vat_amount",
|
||||
) => {
|
||||
const map: Record<string, number> = {};
|
||||
@@ -116,7 +116,7 @@ export default async function receivedInvoicesRoutes(
|
||||
};
|
||||
|
||||
const sumCzk = async (
|
||||
invs: typeof monthInvoices,
|
||||
invs: { currency: string; [key: string]: unknown }[],
|
||||
field: "amount" | "vat_amount",
|
||||
) => {
|
||||
let total = 0;
|
||||
@@ -127,16 +127,12 @@ export default async function receivedInvoicesRoutes(
|
||||
return Math.round(total * 100) / 100;
|
||||
};
|
||||
|
||||
// Also get all-time unpaid — use DB-level aggregation for count/sums
|
||||
const stats = await prisma.received_invoices.aggregate({
|
||||
where: { status: { not: "paid" }, is_deleted: false },
|
||||
_sum: { amount: true, amount_czk: true },
|
||||
_count: true,
|
||||
// All-time unpaid invoices (no soft-delete column, so just filter by status)
|
||||
const unpaidCount = await prisma.received_invoices.count({
|
||||
where: { status: { not: "paid" } },
|
||||
});
|
||||
|
||||
// We still need per-currency breakdown for unpaid, so fetch only those
|
||||
const allUnpaid = await prisma.received_invoices.findMany({
|
||||
where: { status: { not: "paid" }, is_deleted: false },
|
||||
where: { status: { not: "paid" } },
|
||||
select: { amount: true, currency: true },
|
||||
});
|
||||
|
||||
@@ -146,10 +142,8 @@ export default async function receivedInvoicesRoutes(
|
||||
vat_month: aggregateByCurrency(monthInvoices, "vat_amount"),
|
||||
vat_month_czk: await sumCzk(monthInvoices, "vat_amount"),
|
||||
unpaid: aggregateByCurrency(allUnpaid, "amount"),
|
||||
unpaid_czk: stats._sum.amount_czk
|
||||
? Math.round(Number(stats._sum.amount_czk) * 100) / 100
|
||||
: await sumCzk(allUnpaid, "amount"),
|
||||
unpaid_count: stats._count,
|
||||
unpaid_czk: await sumCzk(allUnpaid, "amount"),
|
||||
unpaid_count: unpaidCount,
|
||||
month_count: monthInvoices.length,
|
||||
});
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user