Commit Graph

191 Commits

Author SHA1 Message Date
admin a1926b0623 Fix: drop non-existent payee_name from transactions selects
The Financial Overview (dashboard Recent Transactions) and the reconciliation
list selected a payee_name column that doesn't exist on accounting.transactions,
so PostgREST errored and the views came back empty. Resolve payee/payor from
vendors/customers only.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-13 23:33:20 -04:00
admin 08c1d66aa1 Financial Overview: add Payee/Payor to Recent Transactions
The dashboard's Recent Transactions table (shown on the Financial Overview) now
has a Payee / Payor column — vendor for money out, customer for money in.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-13 23:27:58 -04:00
admin fa9671b4f5 Cash Disbursement: resolve vendor/bill for imported (Buildium GL) payments
The report only enriched app-posted (acmacc_txn) entries with vendor/bill, so
import-mode payments (buildium_gl) always showed 'No vendor on record'. It now
also pulls the vendor/bill from the register transaction linked to each GL bank
line (journal_entry_line_id), so matched imported disbursements show the vendor
(Robertson's, City of Titusville, Avria, FPL...) and bill instead of A/P.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-13 22:27:46 -04:00
admin ac454e8f5e Reports: drop Income Statement, add Monthly columns view to P&L
The Income Statement was a duplicate of the P&L, so removed it from the report
menu. The P&L now has a 'Monthly columns' toggle that renders the same
multi-period (by month/quarter/year) breakdown the income statement provided —
relabeled 'Profit & Loss'. Default P&L view is unchanged (single period).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-13 18:13:56 -04:00
admin 5714543533 Accounting: show Payee/Payor on transaction-style lists
Add a Payee / Payor column to the bank register (Banking), the reconciliation
list, and the Deposits 'awaiting deposit' list — showing the vendor (payee) for
money out or the customer/homeowner (payor) for money in. Expenses already shows
Vendor and Receive Payments shows Homeowner, so those were left as-is.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-13 17:49:26 -04:00
admin 1370b98be9 Bills: editing a paid bill saves and keeps its payment in sync
Editing a paid bill now updates the linked payment along with the bill: when the
amount changes and the bill has a single bill payment, the bank transaction, the
check, and the paid amount are all updated to the new total. The whole save is
wrapped in error handling and the bill_items insert is now error-checked, so any
failure surfaces a clear toast instead of silently appearing to 'not save'.
Also refreshes the transactions/accounts caches after a bill edit.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-13 16:59:06 -04:00
admin 9063e49389 Reconciliation PDF: include outstanding items in prior-period reports; Balance Sheet: stop folding distinctly-named equity accounts
- Prior-reconciliation 'View Report' PDF was hard-coding empty uncleared lists,
  so outstanding items never appeared. It now reconstructs the items outstanding
  as of that statement (dated on/before the statement date, not voided, and not
  cleared in that or an earlier reconciliation) and includes them, with the book
  balance reflecting them.
- Balance Sheet equity folding matched any name containing 'retained earnings'
  (or 'current year earnings'), so a distinct account like 'Retained Earnings
  Savings' was swallowed into the calculated line and never shown. Now only the
  exact standard accounts fold; other equity accounts render on their own line.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-13 12:47:46 -04:00
admin 3ab016fc57 Accounting: post locally-entered bank transactions to the GL (import mode)
Import-mode companies pull their GL from Buildium, so transactions entered
directly in Banking/Reconciliation never reached the GL — they reconciled but
were missing from GL-based reports (P&L etc.). This is why Bent Oak's May P&L
was missing Bank Interest and understated expenses.

- post_transaction_gl no longer gates on gl_managed; it posts any transaction
  that isn't voided, Buildium-sourced (journal_entry_line_id set), frozen
  (exclude_from_gl), a transfer/deposit leg, or missing an account/counter
- New accounting.transactions.exclude_from_gl flag freezes pre-existing manual /
  duplicate register rows on already-tied books so they can't double-post
- One-time data ops: linked all Buildium-sourced register rows to their GL bank
  line; froze remaining pre-existing manual rows for Bridgewater/Casuarina/
  Village Grove (ambiguous, would risk double-count); posted Bent Oak's 4
  verified-missing operating items. Bent Oak GL stays balanced.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-13 12:15:59 -04:00
admin b243256e80 Cash Disbursement report: group payments by vendor
Top-level grouping is now by vendor (name as the section header) with a
per-vendor subtotal, instead of by bank account. The bank account each payment
was drawn from moves to a column on the row. Vendor is resolved from the
reliable payment→vendor / payment→bill→vendor linkage; disbursements with no
vendor on record (e.g. Buildium GL-pull entries) collect under a 'No vendor on
record' group sorted last rather than being guessed. PDF + CSV updated to match.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-13 12:01:31 -04:00
admin ab6c2747fa Reconciliation: cap unreconciled list at the statement date
Show outstanding items dated on/before the statement_end_date (prior periods
included), but hide anything dated after it — e.g. a 2/28/2026 statement shows
2/28 and earlier, nothing later.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-13 11:17:13 -04:00
admin 6ad7688fbd Reconciliation: clear any uncleared item regardless of billed date
A transaction's billed date no longer gates which reconciliation it can clear
in — items billed in one period frequently clear the bank in another. The
reconcile list now shows every uncleared, non-voided item for the account
(reconciliation_id is null), dropping the date <= statement_end_date ceiling.
Finalized items still carry a reconciliation_id and drop off.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-13 11:02:06 -04:00
admin 6bf9da5482 Accounting: prior-period reconcile items, void txns, unified report filters, accrual-only
1. Reconciliation now shows ALL outstanding (unreconciled) items on/before the
   statement date, including ones from prior periods — removed the prior-recon
   date floor. Finalized items still drop off (they carry a reconciliation_id).

2. Void transactions in Banking and Reconciliation. New accounting.transactions
   .voided flag (+ voided_at/by); voided rows stay visible (strikethrough + VOID
   badge) but are excluded from the running balance, register totals, cached
   account balance, and reconciliation. post_transaction_gl reverses the GL for
   gl_managed companies; un-void supported from Banking.

3. Unified report filters: the single Period bar on the Reports page now drives
   every report. General Ledger, Trial Balance, AR Aging (Property), Pre-Paid
   Homeowners, Cash Disbursement, and Reserve Fund no longer have their own date
   pickers — they consume the shared from/to (range) or to (as-of).

4. Accrual only: removed the cash-basis toggle from Trial Balance and General
   Ledger (the data was always accrual GL anyway; the cash label was misleading).
   All income/expense reports recognize on billed/issue date.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-13 10:51:03 -04:00
admin 5aef967b74 Buildium GL sync: keep import-mode bank registers current
Root cause of 'syncs stop at 5/31': the nightly buildium-gl-sync writes journal
entries (so reports stay current) but never created the matching bank-register
transactions for import-mode companies (gl_auto_post=false). Those registers were
materialized once at import, so the reconciliation/register views froze ~5/31
while the GL kept advancing.

- Add accounting.transactions.journal_entry_line_id (FK + unique index) to link
  register rows to their source GL line, making materialization idempotent
- buildium-gl-sync now materializes a register transaction for each bank line it
  inserts, for import-mode companies only (bank debit -> deposit/credit,
  bank credit -> withdrawal/debit; category/coa from the single offset account),
  upserting on journal_entry_line_id so re-runs never double-insert
- One-time backfill (run against prod) filled the existing gap: 231 register
  rows across Bridgewater/Casuarina/Village Grove/Bent Oak, skipping 3 near-miss
  rows that share a day with an existing register row (incl. a Casuarina transfer)
  for manual review

gl_managed companies are unaffected — their register drives the GL via
post_transaction_gl, not the other way around.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-13 10:10:25 -04:00
admin 42475a0e93 Reconciliation: require a vendor on manual withdrawals
The Add Deposit/Withdrawal dialog on the reconciliation screen now shows a
required vendor dropdown for withdrawals (debits) and stores vendor_id on the
transaction, matching the vendor-required rule on Bills/Expenses/Banking.
Deposits (credits) are unaffected.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-13 09:53:07 -04:00
admin dedcbb8889 Bill Approvals: Buildium two-column form + require vendor on all backend payments
- Bill Approvals Create/Edit dialogs redesigned to the same professional
  two-column Buildium layout used on the accounting Bills page: left
  attachment panel (drag-drop + live image/PDF preview), right grouped form,
  prominent blue total bar, primary-action-first footer
- Accounting backend payments now require a vendor chosen from the dropdown:
  - Expenses: vendor is required; removed the free-text vendor fallback
  - Bills: must pick a 'Pay to' vendor before saving
  - Banking payments already enforced this
  (Reconciliation bank adjustments — interest/service charges — intentionally
   still allow no vendor, as they are not vendor payments)
- Board members remain locked to approving/denying their own assigned rows
  plus commenting and submitting invoices (per request); all bill edits, GL,
  line items, status, and deletes stay read-only for board users

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-13 00:14:13 -04:00
admin fbc5019730 Accounting: fix cross-page account-picker cache collisions + allow equity on bills
Root cause of filters conflicting between pages: many accounting pages shared
the same React Query keys (['accounts',cid], ['bank-accounts',cid],
['deposit-accounts',cid]) while running DIFFERENT queries, so whichever page
loaded first poisoned the others' cache (e.g. bill payment picker showing
banks-only with no equity; archived accounts leaking from the CoA list).

- Give every account read query a unique key discriminator per page/purpose;
  ['accounts',cid] / ['bank-accounts',cid] / ['deposit-accounts',cid] stay as
  invalidation prefixes (React Query partial match) so cross-page refresh still works
- Bill line-item category picker now includes expense + asset + equity + liability
  (was expense-only) — fixes 11 bills/13 lines categorized to equity (reserve-funded)
  that showed blank/—; and lets you assign an equity account to a bill
- Payment account picker (bills + expenses) reliably shows banks + equity now that
  it no longer collides with the banks-only deposit/receive-payment pickers

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-12 23:54:38 -04:00
admin f518f0b8f4 Bills: Buildium-style record/edit form + new read-only bill detail view
- Record/Edit dialog redesigned to a two-column layout: large attachment panel
  (drop/preview/replace) on the left; Bill Details + Item Details table on the
  right; prominent total bar; Save / Save & add another / Cancel footer.
  Keeps AI parse, field highlighting, vendor mapping
- New read-only bill detail view (click a bill #/vendor): header with vendor +
  status + Pay/Duplicate/Delete/Edit, Bill details card, item-details table,
  and a Bill amount sidebar (Total / Paid / Remaining)
- duplicateBill clones a bill into a fresh create form

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-12 23:41:36 -04:00
admin 512abcc1a2 Reconciliation: add deposits/withdrawals directly from the reconcile screen
- Deposit / Withdrawal buttons in the statement-transactions header open a
  dialog (date, amount, description, income/expense category, reference)
- New transaction posts to the bank account, is marked cleared, and is
  auto-checked into the current reconciliation; category picker excludes bank
  and archived accounts. gl-managed companies post the offset via the existing
  transaction GL trigger; import-mode books add register-only (consistent with
  Banking), so imported GL isn't double-counted

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-12 23:26:10 -04:00
admin 2d6f7ea17b Reconciliation: only show the open period + sortable column headers
- Transactions on/before the last completed reconciliation's statement date no
  longer reappear in a new reconciliation (date floor). Imported GL registers
  were inserted cleared-but-unreconciled, flooding the list with prior-period
  rows; reconciling now works period-by-period
- Sortable headers (Date / Description / Ref # / Deposit / Withdrawal) with
  asc/desc toggle indicators

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-12 23:08:12 -04:00
admin 8a57f53317 Accounting report batches: saved per-association packets → one combined PDF
- accounting.report_batches (name + ordered report_ids per company, member RLS)
- batchReports.ts engine: cover page + each report on a fresh page + one global
  Page X/Y footer. Financial four reuse the page's fetchReportData/buildFinancial
  (injected to avoid an import cycle); Trial Balance, General Ledger, Cash
  Disbursement, AR Aging, Pre-Paid, Reserve Fund built from the same source data
- Reports page: Report Batches dialog (name, ordered report checklist, saved
  batches load/delete, Save, Generate PDF); page now defaults to This Month
- reportPdf.appendStructuredReportPdf used for the financial sections

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-12 22:57:12 -04:00
admin b9235f644f Accounting: period presets (Month/YTD/Prev-Year/Custom) + logo-free reports
- Shared PeriodPicker (default This Month); wired into General Ledger report,
  Journal Entries page, and bank registers (Banking shows a Balance forward
  row carrying the running balance at period start)
- Financial reports are now logo-free: drawBrandedHeader/reportPdf skip the
  logo block; ReportSheet drops the on-screen logo
- reportPdf: appendStructuredReportPdf + skipFooter scaffolding for upcoming
  report batches (not yet wired)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-12 22:40:58 -04:00
admin b4014f378c Payment accounts can be equity; archived accounts excluded from all dropdowns
- Bill payment + expense paid-through pickers now offer bank OR equity
  accounts (reserve-component style payments); label updated to
  'Payment account'
- is_archived=false filter added to every accounting account dropdown:
  journal entries, bills (expense + payment), expenses, invoices/sales
  receipts/receive payments deposit-to, deposits (bank + line source),
  assessments, opening balances, budget detail, reconciliation

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-12 20:38:00 -04:00
admin 920def8826 Reports: archived accounts hidden everywhere except the General Ledger
- fetchAllGLLines filters accounts.is_archived=false, covering P&L, Balance
  Sheet, Cash Flow, Movement of Equity and Income Statement in one place
- Trial Balance, Reserve Fund Schedule and Budget vs Actuals account lists
  exclude archived; Banking page hides archived accounts from cards/pickers
- General Ledger report intentionally keeps archived accounts (history)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-12 20:27:18 -04:00
admin 03d3c5ee8d Chart of Accounts: archive accounts + safe deletes
- accounting.accounts.is_archived; COA mirror sets public is_active accordingly
  so association-side pickers hide archived accounts
- COA page: archive/restore per row + bulk, show-archived toggle, delete
  confirm dialog with 'Archive instead'; FK-blocked deletes (posted activity)
  get a friendly message + one-click archive; bulk delete skips blocked
  accounts per-id instead of failing the batch
- fetchChartOfAccounts excludes archived platform accounts from pickers;
  parent dropdowns and Opening Balances only offer active accounts

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-12 20:11:11 -04:00
admin df8623ff9f buildium-gl-sync: include inactive bank-account GL ids from /v1/bankaccounts
/v1/glaccounts omits some inactive accounts (e.g. prior-management bank
accounts) whose ledgers still hold one side of historical transactions,
making checks/deposits come back unbalanced on backfills (found during the
Casuarina Club GL import).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-12 19:52:21 -04:00
admin 28c3c7bd0a Bills import: degrade gracefully when Buildium API key lacks Vendors permission
GET /v1/vendors 403s on keys without the Vendors scope; import bills without
vendor links instead of failing the pull, and surface it in results.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-12 18:58:13 -04:00
admin cc5f70bc5b Bills import: A/P cutover guard — only post JEs dated after the GL watermark
Anything on/before buildium_gl.last_synced_date is already in the books as
buildium_gl entries; ap_cutover_date freezes that boundary so direct
buildium_bill/billpay postings never double-count history.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-12 18:46:24 -04:00
admin 25064d8418 Direct Buildium A/P import: bills, payments, one-off checks via GL Account Map
- public.bills.line_items + line-aware accounting mirror (one bill_item per
  Buildium line with its mapped platform account)
- buildium-sync bills: strict per-line resolution through
  buildium_gl_account_links (unmapped -> bill held + flagged); pulls
  /bills/{id}/payments (check#, bank, date) and /bankaccounts/{id}/checks
  (one-off checks become paid bill+payment pairs)
- import-mode companies get direct JEs (buildium_bill Dr expense/Cr AP,
  buildium_billpay Dr AP/Cr mapped bank) + cleared register rows; sets
  buildium_gl.exclude_ap so the nightly GL pull skips Bill/Bill Payment/Check
- buildium-gl-sync: exclude_ap transaction-type filter; preserve buildium_gl
  config keys when advancing the watermark
- Settings: Pull Bills & Expenses card with held/unmapped reporting

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-12 18:43:58 -04:00
admin 4e77098f88 Buildium GL account map: active accounts only, add-one-at-a-time UI
- gl_accounts fetched without includeAll (active Buildium accounts only)
- replaced per-account row grid (370+ selects) with a single add row:
  Buildium dropdown -> system account dropdown -> Add
- mappings list is plain rows with remove + push-target radio; changes save
  immediately (no bulk Save); flagged sync-blockers are click-to-select chips
- Auto-map exact matches button inserts code/name-identical pairs

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-12 17:31:40 -04:00
admin e510a76dfc Accounting reports: AR Aging (Property), Pre-Paid Homeowners, Cash Disbursement
Buildium-style reports built on the owner ledger and GL:
- AR Aging (Property): FIFO-aged buckets (0-30/over 30/60/90) per unit with
  charge-type breakdown, collection status, summary + distribution bar
- Pre-Paid Homeowners: units with net credit balances as of a date
- Cash Disbursement: bank-credit GL entries grouped by bank account with
  check#/vendor/invoice enrichment from the banking register and GL line detail
All with branded PDF/CSV exports; shared owner-ledger helpers in lib/ownerLedger.ts

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-12 17:26:30 -04:00
admin 4c7fe7840b ARC decision letters: launch letter editor prefilled with ARC merge fields
- ARC detail header: Decision Letter button -> Forms & Letters (Letters tab) with
  association/owner/subject + projectTitle/decisionStatus/arcDate/decisionDate/
  propertyAddress/decisionNotes context
- LetterGenerator: resolves ARC tokens (before generic ones), new {{mailingAddress}}
  token, click-to-insert merge-field palette; templates via existing Save Template flow

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-12 15:56:27 -04:00
admin c1fad194f7 ARC imports: record Buildium decision votes + richer decision notes; PDF spacing
- Buildium API exposes no ARC comment threads or member votes (verified live);
  surface the final decision instead: vote row dated to the actual decision,
  decision_notes 'Approved by X on date (via Buildium)'
- record_buildium_arc_vote RPC bypasses the finalized-ARC write lock that was
  silently swallowing import votes; 69 existing imports backfilled
- Application Record PDF: paragraph break between comments and decision notes

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-12 14:26:48 -04:00
admin ff65c8a656 Buildium GL account map: strict account links, separate pull/push charges
- buildium_gl_account_links + buildium_unmapped_gl_accounts tables (strict, hold-and-flag)
- buildium-sync: pull charges syncType, account-first push resolution, no fuzzy matching, push dryRun
- buildium-gl-sync: links-only resolution, watermark held while unmapped accounts exist
- GL Account Map settings tab + Pull Charges card + unmapped results panel

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-12 14:07:18 -04:00
admin abd46bcb2b Hostinger Reach integration UI + ARC Buildium matching, drop Mailchimp
- HostingerReachPage (replaces MailchimpPage): connect Reach via
  reach-connection, per-association segment sync via reach-sync
- ARC Applications: Buildium import review/matching updates
- buildium-import-stage/apply: latest staging + apply changes (already
  deployed to Supabase)
- migrations: hostinger_reach_integration + arc_finalized_lock service
  role (already applied to live DB)
- CI: note that deployment is VPS-side polling (auto-deploy.sh cron)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-11 23:07:30 -04:00
admin 220892203c CI: auto-deploy to VPS on push to main
After the build check passes, SSH to the VPS with a forced-command key
(can only run deploy.sh) which pulls main, builds, and rsyncs dist/ to
public_html. Replaces the manual `ssh myvps ... deploy.sh` step.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-11 22:55:39 -04:00
admin f5f6285bbd Accounting: fix empty JE/GL pages + nightly Buildium GL pull sync
- Add missing indexes on journal_entry_lines (journal_entry_id, account_id)
  and journal_entries (company_id, date): Bridgewater's ledger query took
  7.5s, blew the 8s statement timeout, and rendered the JE/GL pages empty
- Paginate JE/GL page fetches past the 1000-row PostgREST cap (shared
  fetchJournalEntries helper) and surface query errors instead of
  swallowing them into an empty list
- New buildium-gl-sync edge function (scheduled nightly via pg_cron):
  incrementally pulls new Buildium GL activity into accounting journal
  entries via GET /v1/generalledger, reconstructing double-entry JEs by
  grouping per-account entries by transaction id; watermark + 14-day
  overlap window, dedupe on (company_id, external_source, external_id),
  account mapping by external_id/code/name with auto-create for new
  Buildium accounts

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-11 22:12:38 -04:00
admin 4f0ac97e83 Income Statement: Buildium-style category subgroups
Group the multi-period Income Statement by account category (Operating Income,
Administration, Utilities, Reserves Budget, …) with "Total for <category>"
subtotals, matching the Buildium layout, in the on-screen table, PDF, and CSV.

- New accounting.accounts.category column (nullable; null = ungrouped), seeded
  from the local chart_of_accounts parent hierarchy.
- Editable in Chart of Accounts: single-edit (with datalist autocomplete) and
  bulk-edit (blank = no change, __clear__ to unset).
- buildium-account-categories edge function pulls each account's parent-GL
  category from Buildium (matched by code, fallback name) and backfills
  accounting.accounts.category; idempotent and re-runnable.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-10 22:34:58 -04:00
admin cb8a29696f Accounting reports: add multi-period Income Statement
New "Income Statement" report with a By Month/Quarter/Year selector that lays
out income/expense accounts in period columns plus a Total column, with Total
Income / Total Expense / Net Income rows. Built from the GL over the selected
range; includes branded PDF and CSV export. Accounts are listed flat under
Income/Expense for now (category subgroups to follow once accounts are
categorized).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-10 21:04:49 -04:00
admin ca092f7b8b Budget Workbook: step through all clients with prev/next
Add prev/next buttons and a "Client N of M" indicator around the association
picker so a budget can be built for every client in turn. Cycles in name order
and wraps; direct dropdown selection still works.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-10 11:35:36 -04:00
admin 217e511792 Budget Workbook: export a Proposed Budget PDF
Add a PDF button that generates a board-ready proposed budget: income and
expense tables (monthly/annual per account with totals), a summary, and a
headline banner for the per-unit monthly assessment. Uses the workbook's
projected figures (overrides/inflation/unit override) via jsPDF + autotable.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-10 10:58:59 -04:00
admin 6fe1e3943c Budget Workbook: editable unit count for per-unit assessment rate
The per-unit assessment (annual expenses / 12 / units) used the live association
unit count only. Add an override so the rate can use weighted/excluded units,
persisted on accounting.budget_workbooks.unit_override (null = live count). New
"# Units" control with a reset link; summary card and CSV use the effective count.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 22:43:45 -04:00
admin d18296c3a6 Accounting Banking: allow cash deposits with no homeowner
The Banking-page deposit form required a homeowner, blocking general/cash
deposits. Drop that requirement: a deposit still needs an income account, and
post_transaction_gl already books Dr Bank / Cr income when no customer is set
(vs. Dr Bank / Cr A/R with one). The Homeowner field is now optional with an
explicit "No homeowner (general deposit)" choice.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 22:35:33 -04:00
admin 215ecb3153 Budget Workbook: replace Budget Management with a YTD-actuals workbook
/dashboard/budget-management now renders a Budget Workbook that pulls YTD
actuals (from the accounting GL, through a chosen month), derives a monthly
average (YTD/N), takes a per-line inflation %, and projects an annual budget
(avg x 12 x (1+infl)). Footer rolls up annual budget / 12 / # units = per-unit
monthly assessment. Income + expense sections; all imported fields editable.

- Standalone saved worksheet (accounting.budget_workbooks/_lines, RLS like accounts)
- "Push to Budget" writes projected/12 into accounting.budgets + budget_entries
- Uses accounting.accounts (synced with the Accounting dashboard COA) and paginates
  the GL fetch (1000-row cap). Nav relabeled Budget Management -> Budget Workbook.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 16:29:25 -04:00
admin ea2f2a089a Accounting Banking: page through all register transactions
The bank register fetched transactions in a single request, which
PostgREST caps at 1000 rows. An imported bank account with a longer
register (e.g. Bridgewater Checking, ~1,500 rows) truncated, throwing
off the displayed running balance. Page through all rows ordered by a
stable key (date, created_at, id).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 13:30:19 -04:00
admin bd4c385478 Accounting reports: page through all GL lines (fix 1000-row truncation)
PostgREST caps each response at 1000 rows. The P&L and Balance Sheet
fetch every journal_entry_line for the company and aggregate client-side,
so any association with >1000 GL lines (e.g. an imported Buildium GL) only
saw the first 1000 — accounts whose activity fell past that point read as
$0 and were hidden, making reports look empty/out-of-balance. Fetch the GL
in 1000-row pages ordered by a stable key so every line is included.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 01:23:57 -04:00
admin d2d2c83e7b Accounting: refresh reports + General Ledger after posting a journal entry
Manual journal entries post straight to the GL, but saving/deleting one
only invalidated the journal-entries list — so the Reports data (P&L /
Balance Sheet) and the General Ledger tab kept showing stale figures
until a manual refresh. Invalidate reports-data and gl-journal-entries
on save and delete too.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 00:53:18 -04:00
admin 4b5c2ea2ea Accounting: add General Ledger tab
Buildium-style GL grouped by account type with date-range filter,
account filter, beginning/ending balances, per-line running balance,
and grand totals. Reads posted journal entries.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 22:17:23 -04:00
admin f315d86e03 Accounting: editable deposits (Recent Deposits list + edit/delete)
Add a "Recent Deposits" list to the Deposits page with Edit (date, bank
account, memo — GL re-posts via the deposit trigger) and Delete (releases the
deposited transactions/payments back to "awaiting deposit" and reverses the GL).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 19:57:10 -04:00
admin 8a2ea60824 Accounting: editable journal entries + Reports refresh button
- Journal Entries: add Edit (row + detail drawer) that loads an entry into the
  form and saves changes (updates the entry and replaces its lines). Warns when
  editing an auto-generated entry (may be overwritten by its source sync).
- Reports: add a Refresh button that re-fetches the underlying data so the
  report reflects the latest GL.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 19:33:39 -04:00
admin aa94622a78 Opening Balances: fix duplicate earnings accounts; recognize name variants
The auto-provision effect could fire twice and create duplicate "Current Year
Earnings" accounts (seen on Village Grove). Use the idempotent
coa_get_or_create RPC with a once-per-company ref guard, and match existing
name variants (Current Year Income / Net Income / Retained Earnings) so it
won't create redundant accounts. Balance sheet now also folds
"Current Year Income"/"Net Income" equity accounts into the Net Income line.
Removed the existing Village Grove duplicate (zero activity).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 19:04:51 -04:00