Commit Graph

181 Commits

Author SHA1 Message Date
admin acd99f04ce Avria Sign: fix PDF not rendering (field placement + signer page)
The pdf.js worker was set via new URL("pdfjs-dist/build/pdf.worker.min.mjs",
import.meta.url) — Vite only resolves relative paths there, so a bare
node_modules specifier 404s in production and react-pdf never renders the PDF
(both the field-placement step and the recipient signing page). Switch to a
Vite `?url` import so the worker is emitted as a hashed same-origin asset.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17 23:08:08 -04:00
admin 86e8513694 Inspections: apply violations new-vs-old cue to the map + list
Match the violations changes on the Inspections map: add a green "New" badge for
violations recorded in the last 7 days, both in the map pin popups and the unit
list, so new vs old is distinguishable. (Newest-first ordering and
auto-advance-to-next-stage on re-recording a property already existed here.)
Also fixed a misleading stage fallback that showed "New" as a notice level.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17 23:03:51 -04:00
admin b15ed4bff8 Avria Sign: add SHA-256 document hash to certificate of completion
The Certificate of Validation claimed "cryptographic proof ... and integrity"
but showed no hash. Add a real SHA-256 of the original document to the
certificate page so the integrity claim is backed by a verifiable digest.
(Deploy via MCP alongside the base-flow fix.)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17 22:58:27 -04:00
admin bebd5bd7cb Violation report: clean up Activity History formatting
The "Violation Updated" entries rendered raw change diffs: a "→" arrow the PDF
font can't draw (showed as "!'"), snake_case field names, "—" for empty, and a
dense single-paragraph wall.

- Render-time (fixes existing reports): normalizeTimelineText now maps "→"→"to"
  and smart quotes/dashes/ellipsis to ASCII, prettifies snake_case field labels
  (violation_type → "Violation Type", etc.), and puts each change on its own
  line for proper spacing.
- Logger (future entries): logViolationUpdated/logBulkUpdate now write
  professional notes — "Description / Notes changed from "X" to "Y".",
  "… set to …", "… cleared." — with Title-Case labels, long values truncated to
  80 chars, and one change per line. No arrows or raw field names.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17 22:48:18 -04:00
admin feb0d28c25 Violations: fix auto-escalation on re-record + surface new vs old by date
Auto-escalation was broken: calculateNextNoticeLevel queried unit_id but the
dialog passed the owner id, so it always returned "First Notice." Rewrote it to
advance one step past the property's highest CURRENTLY-OPEN stage (First →
Second → Third & Final, capped), identifying the property by unit, else owner,
else association+address; the dialog now passes all of those and re-runs when
the unit/address changes. So re-recording a violation on the same property
auto-selects the next stage.

New vs old by date: list now loads newest-first, and cards show a "New" badge
for violations recorded in the last 7 days (violation_date was already captured
and shown, plus the timeline group-by-date view).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17 22:32:28 -04:00
admin 71cc71f89f Inbound invoices: recipient-alias routing + parser hardening
parse-invoice: guard oversized PDFs (>18MB → clear "too large, saved for manual
entry" message) and surface the AI gateway's actual error instead of a bare
status code.

inbound-bill-email: route to an association by the recipient alias
(<alias>@bills.avriamail.com, via associations.inbound_alias) in addition to the
sender's vendor mapping; fix extractEmail (bare addresses were mis-split, e.g.
invoices@x → s@x); surface parse-invoice's real error in the inbox. Deployed via
MCP; migration associations_inbound_alias adds + populates the aliases.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17 22:13:49 -04:00
admin 386ee26a6a Bill summary PDF: itemized line items + total
Render an itemized table (Description / Qty / Unit Price / Amount) from the
linked invoice's line_items, with a Total row (the authoritative bill amount)
and a subtle note if the line items don't sum to it. Falls back to a single
row when no line items exist. Fetch invoices.line_items in the bills query and
pass it through to the generator.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17 21:13:50 -04:00
admin fa0f60a7f4 Bill Approvals: download a summarized bill PDF
Add a "Download PDF" action to each bill's row menu that generates a clean
one-page bill summary (vendor, amount, invoice #, bill/due dates, expense
account, description, status, and board approval statuses). New generator
src/pages/accounting/lib/billSummaryPdf.ts (jsPDF), styled like the other
report PDFs.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17 21:00:27 -04:00
admin fe78c25fd1 Messaging: add explicit Delete button to the conversation header
The list-row trash is always-visible now, but add an unmissable "Delete"
button in the open-conversation header (ChatView) too. Deletes the whole 1:1
conversation for everyone and clears the selection.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17 20:04:50 -04:00
admin 53765e1448 Reconciliation: add accrual bill (expense on bill date + paying withdrawal)
New "Add Bill" action on the bank reconciliation screen: enter a bill (bill
date, payment date, vendor, amount, expense account), and it creates the bill
(accrual expense on the bill date) plus a withdrawal that pays it (Dr A/P /
Cr Bank on the payment date) and clears into the current reconciliation. The
expense lands in the bill's period for reporting; the cash leaves on the
payment date.

Fixes import-mode posting: app-created bills now carry gl_post_override=true
(new accounting.bills column) so post_bill_gl posts their expense even for
import-mode (gl_auto_post=false) companies. The previous external_source-based
gate didn't work because the bill back-sync trigger stamps every app bill with
external_source='acmacc_bill', making it indistinguishable from Buildium
imports; the explicit flag set only by the app's bill creators (Bills page +
reconciliation) is reliable, while Buildium-import/auto-reconcile bills stay
gated and never double-count the GL pull. Migration:
bills_gl_post_override_for_inapp_bills.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17 19:56:18 -04:00
admin 9c87777046 Messaging: whole-board from Direct New Message + always-visible delete
- Whole board where users actually look: the Direct "New Message" dialog now
  lists "Whole Board — <Association>" rows for staff (All/Board tabs). Clicking
  one opens the group-topic composer prefilled with that board's members (the
  composer is now reusable: hideTrigger + controlled open + initialSelected,
  wired through MessagesPage).
- Delete discoverability: the trash control on Direct conversations and Topic
  threads is now always visible (subtle, bottom-right) instead of hover-only,
  which read as "no delete option."

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17 19:38:15 -04:00
admin 6a6e2306ea Messaging: whole-board topics, delete conversations/threads, dialog overflow + board names
- Whole-board messaging: staff starting a Topic can add an entire association's
  board in one click ("Whole Board — <Association>") in NewTopicThreadDialog;
  create_topic_thread already permits staff to add board members.
- Delete for everyone: trash control on Direct conversations (deletes the 1:1
  both directions) and on Topic threads (deletes the thread for the creator or
  admin/manager — cascade). Backed by new RLS delete policies on direct_messages
  and message_threads (migration allow_delete_conversations_and_threads).
- Fix New Message dialog overflow for real: the grid child needed min-w-0 (+
  overflow-hidden on the card); applied the same guard to the Topic dialog.
- Fix board members showing as "Unknown User": fall back to board_members.member_name.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17 15:44:39 -04:00
admin bfc758f1f2 Messaging: fix New Message dialog overflow on long recipient names
The recipient row's inner name+badge flex lacked min-w-0, so a long name
(e.g. a full association name) couldn't truncate — it widened the row,
pushed the badge out, and stretched the dialog (and its full-width search
field) past max-w-md. Add min-w-0 so the name truncates and the dialog
stays within bounds.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17 15:01:23 -04:00
admin d5145e2515 Messaging: board topic threads with management + board
Add a "Topics" tab to the Messages page so board members can start a
topic-scoped group conversation with management and their own-association
board members. Topic = predefined category + free-text subject; recipients
are multi-selected; replies are visible to all participants.

- New public tables message_threads / message_thread_participants /
  thread_messages (migration board_topic_message_threads), added to the
  realtime publication; RLS scopes reads/writes to thread participants via
  is_thread_participant().
- create_topic_thread() RPC (SECURITY DEFINER) enforces recipient
  eligibility server-side: management (admin/manager) or a board member of
  the caller's own association; rejects anyone else.
- Frontend: messageTopics constant, useMessageThreads/useThreadMessages
  hooks (realtime), TopicThreadList/TopicThreadView/NewTopicThreadDialog,
  and a tabbed MessagesPage. Recipients notified via insert_notification
  with a /dashboard/messages?thread= deep link. Existing 1:1 DMs unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17 14:58:50 -04:00
admin 56e63edcd6 Violation reports: replace fining stamp with bold red header line
The diagonal semi-transparent "RECOMMENDED FOR FINING" stamp looked poor over
the report content. Remove it (drawRecommendedForFiningStamp + both call sites)
and instead print a bold red "RECOMMENDED FOR FINING" line just beneath the
navy header bar on both the Summary and Timeline reports, shifting the owner
block down to make room. Non-fining reports are unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17 12:16:16 -04:00
admin 0fadfcd2d2 Accounting reports: BvA column shading + reconciliation archived-account fix
Budget vs Actuals: shade the Budget / Actual / Variance / Variance % columns
in a light→dark grey gradient with left vertical borders so they're easy to
tell apart (shared BVA_COL styles applied to header, group-total and detail
rows; variance text bumped to emerald/red-700 for contrast on the darker fills).

Reconciliation R2: reconcile() classified GL lines via the active-only account
list and dropped lines on archived accounts, so the "Assets = Liabilities +
Equity (incl. net income)" check went out of balance by the archived balance
(e.g. VW's archived 4016 Renters Insurance Income, -$75). Feed reconcile any
account referenced by glCumulative but missing from the active list (joined
metadata), matching the Balance Sheet builder; once every line is typed, R2
reduces to R1 and passes whenever the ledger balances. Also tightens R3/R4.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17 11:53:07 -04:00
admin 61b9933bea AR Aging (Property): exclude archived owner-ledger entries
fetchOwnerLedger pulled all entries regardless of is_archived, so the
accounting AR Aging / Prepaid / batch reports still counted archived
(voided/duplicate) charges — e.g. 2455-VL showed $4K in violations
instead of $3K. Exclude archived entries at the source.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-16 22:49:52 -04:00
admin 46b0855840 Owner ledger: exclude archived entries from balance/breakdown views
Archived (voided/duplicate) owner_ledger_entries were still counted in
the per-unit account breakdown, Collections, and Outstanding Balances —
inflating totals (e.g. 2455-VL showed $4K in violations vs the real
$3K after a duplicate was archived). Filter out archived entries in all
three, matching the canonical Unit Ledger view.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-16 21:00:07 -04:00
admin c670ca7e0e Bids & Quotes: PDF attachment upload (board-accessible)
Adds a PDF upload to the bid/quote dialog (stored in the bid-attachments
bucket, saved to document_url/document_name) and shows the attachment in
the detail view. Board members with can_upload can attach PDFs — table
RLS and the storage bucket already permit it; only the UI was missing.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-16 20:53:19 -04:00
admin b18a9b9e78 Status updates: restore staff write RLS policy
The "Staff full access on status_updates" policy was missing from the
live DB (dropped outside migrations), so all inserts/updates failed with
"new row violates row-level security policy". Recreate it (admin/manager).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-16 20:53:19 -04:00
admin a866160482 Status updates: add "hidden from board" flag
Lets management post internal status updates that don't appear in the
board portal. Adds status_updates.hidden_from_board and re-creates the
association-scoped RLS SELECT policy so board members can't read hidden
rows (staff still see all). Dialog gains a "Hide from board" toggle, the
board view filters hidden updates, and management cards show a badge.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-16 20:28:09 -04:00
admin 03cd7127a2 Budget vs Actuals: show full per-period budget, no proration
The Budget column overlap-weighted partial months, so a YTD range
ending mid-month showed a fractional budget. Now include each budget
period's full amount whenever the selected window touches it, for both
the main and comparison windows — exactly as entered on the budget.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-16 14:26:32 -04:00
admin fe5d897139 Budget vs Actuals: source actuals from the GL
The accounting Budget vs. Actuals report computed actuals from
operational tables (bill_items + payment transactions + a
budget-weighted paid-invoice plug), which double-counted (a bill
counted as its line item AND its payment, plus redundant imported
bills) and diverged from the posted books — especially for Buildium
GL-import / import-mode associations whose activity lives only in
journal entries.

Now fetch GL lines via fetchAllGLLines and net per account
(income = credit - debit, expense = debit - credit), matching the
Income Statement. Budget side was already correct (reads active
accounting.budgets + budget_entries).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-16 14:07:10 -04:00
admin d7d53c5022 Merge pull request #14 from renee-png/bs-include-archived-accounts-with-balance
Reports: keep archived accounts with a balance on the financial statements
2026-06-16 13:16:10 -04:00
admin 8404f9b79d Reports: keep archived accounts with a balance on the financial statements
An archived COA account that still carried a GL balance was dropped from the
Balance Sheet (fetchAllGLLines filtered is_archived=false), so the report went
out of balance by exactly that amount. Now the financial-report GL fetches
include archived accounts (those without activity never appear, since this
queries journal lines), and buildBalanceSheet surfaces archived asset/liability
/equity accounts that carry a balance as line items; archived income/expense
flow into Net Income. Fixes the Village Woods $170.30 out-of-balance and the
same latent issue in Bent Oak and Casuarina.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-16 13:15:34 -04:00
admin a65c135122 Accounting: auto-create record-only bills for no-bill vendor payments (import mode)
Buildium often records vendor payments as direct checks (Dr Expense/Cr Bank)
with no bill. For import-mode companies post_bill_gl no-ops, so a bill is a
record only. New fn accounting.autocreate_nobill_vendor_bills() creates a paid
record-only bill for each such buildium_gl payment (vendor resolved by payee,
idempotent by external_id); buildium-gl-sync calls it per import-mode company
after each pull. No GL impact, no double-count.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-16 12:57:28 -04:00
admin 73f04017f5 Merge pull request #12 from renee-png/vendor-profile-email-billing-instructions
Vendor profile email: where-to-send-invoices block
2026-06-16 12:21:54 -04:00
admin 393268dd04 Vendor profile email: add where-to-send-invoices block
Below the Submit vendor profile button, instruct vendors to email bills to
ap@avriacam.com or mail them to the association's mailing address, c/o Avria
Community Management, LLC. The address is resolved from the vendor's
association (association_id, falling back to association_ids[0]).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-16 12:20:12 -04:00
admin fe6893b367 Merge pull request #11 from renee-png/accounting-email-sender-and-import-dup-guard
Email sender consolidation + import-mode register GL double-count guard
2026-06-16 12:08:39 -04:00
admin 7f5d21c398 Accounting: guard import-mode register rows against GL double-counting
post_transaction_gl now skips posting a register row whose exact bank
movement (company + bank account + date + amount + direction) is already
in buildium_gl, so categorizing an ad-hoc-materialized register row can no
longer duplicate the Buildium GL pull. Also freezes (exclude_from_gl) any
remaining unguarded buildium-overlapping register rows across all
import-mode companies. Genuinely-missing manual items (no GL match) still
post normally.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-16 12:03:40 -04:00
admin 2c50e96fbd Email: default automated sender to notifications@avriamail.com
The retired no-reply@avriamail.com had no email_senders row, so the
queue dispatcher 500'd on every run. Point DEFAULT_AUTOMATED_FROM at
notifications@avriamail.com (the sole remaining sender). The
AUTOMATED_EMAIL_FROM secret was set to match and the function deployed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-16 12:03:18 -04:00
admin 9aa1f94eb4 Accounting: categorize register transactions from Buildium GL lines
partymap mode now also resolves each Buildium transaction's dominant
income/expense account (from its Journal lines) to a local category, staged
alongside the party. Used to backfill accounting.transactions.category on the
materialized bank register. Applied to Village Woods.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 20:16:00 -04:00
admin 0faee9994d Accounting: partymap mode + register payee backfill
Adds "partymap" mode to buildium-payee-backfill: resolves each Buildium GL
transaction to a local vendor (by name) / customer (by unit_number) and stages
it in accounting.buildium_party_map. The materialized bank register
(accounting.transactions) is then backfilled in SQL by bridging each register
row to its journal-entry bank line (bijective row-number pairing within
date/amount/side groups, so same-amount/same-day payments each get a distinct
owner) and pulling the resolved vendor/customer + name from staging.

Applied to all five Buildium-imported associations (Village Woods, Bent Oak,
Village Grove, Bridgewater, Casuarina).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 19:44:42 -04:00
admin 12e551f578 Accounting: add account/txn detail modes to buildium-payee-backfill
account mode lists a single account's ledger entries; txn mode reconstructs
one transaction's full double-entry across accounts. Used to trace the VW
5098 discrepancy to a missing 2025-12-31 reserve-funded reclass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 17:27:00 -04:00
admin e999890ee5 Accounting: add report mode to buildium-payee-backfill
report mode pulls /v1/generalledger signed balances per account for the
window so imported books can be diffed against Buildium's authoritative GL
to verify completeness.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 17:18:34 -04:00
admin 3a7e08fb78 Accounting: buildium-payee-backfill edge function
Re-pulls Buildium GL transactions and backfills payor/payee names onto
imported journal_entries.description (matched by external_id). Vendor for
Bill/Check/EFT via PaymentDetail.Payee; owner for Charge/Payment/ApplyDeposit
resolved from UnitId via /v1/associations/owners. Idempotent; modes
sample/dry/apply. Used to backfill Village Woods.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 17:12:00 -04:00
admin 0eaf3efb4f Accounting: surface Recurring from Journal Entries & Bills pages
Add a 'Recurring' button to the Journal Entries and Bills page headers
that links to the Recurring (Bills & Journals) page, and rename the
sidebar item so it's clear it covers journals too. Improves discovery —
users looking for recurring journals on the Journal Entries page now have
a direct link.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 00:43:25 -04:00
admin 10cd24e738 Bank feeds: replace Plaid with Stripe Financial Connections
Swap the bank-linking + transaction-download integration from Plaid to
Stripe Financial Connections (you're already on Stripe for payments).

- accounting.stripe_bank_connections table (mirrors plaid_connections)
- stripe-financial-connections edge function: create_session / save_account
  / sync / disconnect, using per-association keys from stripe_account_mappings
  (handles connected accounts via Stripe-Account + stripeAccount on the client)
- lib/stripeBank.ts: client wrappers + the Stripe.js collectFinancialConnections
  Accounts flow
- AccountingBankingPage: Connect/Sync/Disconnect now drive Stripe FC; removed
  react-plaid-link usage and the PlaidLinkButton
- Integrations page wording updated
- Imported transactions land uncategorised in the bank feed (credit/debit by
  amount sign) for matching, same as before

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 00:27:05 -04:00
admin 266a99d4b2 Accounting: recurring bills & journal entries
Add accounting.recurring_templates (bill|journal) with a schedule
(frequency/interval/day-of-month/start/end). New generate_due_recurring()
materialises real bills (-> A/P) and journal entries on cadence — catching
up any missed periods — posting through existing triggers. Runs nightly via
pg_cron ('accounting-recurring-daily') and on demand from a new Recurring
page ('Generate due now'). Page lists templates with pause/resume/edit/
delete; create dialog handles both kinds (vendor + line items for bills,
signed balanced lines for journals). Wired into routes + accounting nav.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-14 23:28:43 -04:00
admin 91882a0422 Expense Summary: exclude unpaid bills (billed-but-paid view)
Expense Summary kept billed-date recognition but counted bills the
association hasn't paid yet. Back out the unpaid (prorated) portion of
period bills per expense account, so the report reflects amounts actually
paid. Direct payments are unaffected (cash already out). Bent Oak's open
5/27 City of Titusville water bill ($136) now drops out: Water/Sewer
757.25 -> 621.25.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-14 00:52:26 -04:00
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