Accounting platform: remove Zoho, unify reports, board access, vendor sharing

- Remove the Zoho Books integration (edge functions, sync libs, settings,
  reports/overview, banking links, fees tab, import dialog); preserve fee
  rules as a standalone FeesTab and the COA accounting_system classification.
- Financial Overview/Reports (staff + board) render the Accounting dashboard
  and reports; board reports mirror the rich Accounting Reports.
- New Reserve Fund Schedule report + an is_reserve flag on accounts.
- Unify all report exports to a branded format (logo + centered header +
  footer): shared ReportSheet (on-screen) and reportHeader (PDF). Budget vs
  Actuals and Bank Reconciliation PDFs now match the reference layout.
- Render financial reports inline (no preview pop-up).
- Budget Management mirrors Accounting Budgeting (staff-accessible) with SPA
  navigation; editable bills in the Accounting Bills page.
- Negative opening balances flow through to the GL and reports (allow negative
  input; keep non-zero on save; signed CSV import).
- Upload a per-account trial balance via CSV on Opening Balances.
- Board members: read-only RLS access to their association's accounting ledger;
  editable board-members panel on the association page; share vendor contacts
  with the board (toggle + directory section).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-02 18:29:31 -04:00
parent db20226d62
commit e302fb91f0
63 changed files with 2406 additions and 9514 deletions
+1 -15
View File
@@ -1,6 +1,5 @@
import { useState, useEffect } from "react";
import { supabase } from "@/integrations/supabase/client";
import { pushBillToZohoAfterCreate, pushBillPaymentToZohoAfterPay, deleteBillPaymentFromZohoAfterUnpay } from "@/lib/zohoBillSync";
import { useToast } from "@/hooks/use-toast";
import { FileText, Plus, Search, MoreHorizontal, Edit, Trash2, CheckCircle, XCircle, DollarSign, Download, Loader2 } from "lucide-react";
import RecordImportButton from "@/components/RecordImportButton";
@@ -178,9 +177,8 @@ export default function BillsPage() {
await supabase.from("bills").update(payload).eq("id", editing.id);
toast({ title: "Bill updated" });
} else {
const { data: newBill } = await supabase.from("bills").insert(payload).select("id").single();
await supabase.from("bills").insert(payload).select("id").single();
toast({ title: "Bill created" });
if (newBill?.id) pushBillToZohoAfterCreate(newBill.id);
}
setDialogOpen(false);
fetchData();
@@ -219,18 +217,6 @@ export default function BillsPage() {
await supabase.from("bills").update(updates).eq("id", id);
toast({ title: `Bill ${status.replace("_", " ")}` });
if (status === "paid") {
const result = await pushBillPaymentToZohoAfterPay(id);
if (!result.success) {
toast({ variant: "destructive", title: "Zoho payment sync failed", description: result.error });
}
} else if (revertingToUnpaid) {
const result = await deleteBillPaymentFromZohoAfterUnpay(id);
if (!result.success) {
toast({ variant: "destructive", title: "Zoho payment delete failed", description: result.error });
}
}
fetchData();
};