From c73dc08b9210acf80d4bd55368a72a8f801ff5f6 Mon Sep 17 00:00:00 2001 From: Scott Pouliot Date: Sat, 20 Jun 2026 18:15:36 -0400 Subject: [PATCH] Add trial-balance (GL health) indicator to Chart of Accounts Surfaces the audit #2 check in the UI: a badge at the top of the Chart of Accounts page shows "Trial balance: Balanced" or "off by $X (excess debits/credits)". Computed in AccountsController.Index from already-loaded accounts: debit-normal (Asset/COGS/Expense) minus credit-normal (Liability/Equity/Revenue) CurrentBalance, which nets to ~0 for balanced books. Helps companies spot one-sided postings / opening-balance gaps. Help KB + Settings article updated. Co-Authored-By: Claude Opus 4.8 --- .../Controllers/AccountsController.cs | 8 ++++++ .../Helpers/HelpKnowledgeBase.cs | 3 ++ .../Views/Accounts/Index.cshtml | 28 ++++++++++++++++++- .../Views/Help/Settings.cshtml | 9 ++++++ 4 files changed, 47 insertions(+), 1 deletion(-) diff --git a/src/PowderCoating.Web/Controllers/AccountsController.cs b/src/PowderCoating.Web/Controllers/AccountsController.cs index a1d94f8..e242113 100644 --- a/src/PowderCoating.Web/Controllers/AccountsController.cs +++ b/src/PowderCoating.Web/Controllers/AccountsController.cs @@ -69,6 +69,14 @@ public class AccountsController : Controller // Default-account pickers (Revenue / COGS / Inventory) — see SaveDefaultAccounts. await PopulateDefaultAccountViewDataAsync(companyId, accounts); + // GL health: trial-balance net. Debit-normal (Asset/COGS/Expense) minus credit-normal + // (Liability/Equity/Revenue) should net to ~0 for balanced books. A non-zero value flags + // drift or one-sided postings (often opening balances entered without an offsetting entry). + ViewBag.TrialBalanceNet = accounts.Sum(a => + (a.AccountType == AccountType.Asset || a.AccountType == AccountType.CostOfGoods + || a.AccountType == AccountType.Expense) + ? a.CurrentBalance : -a.CurrentBalance); + return View(grouped); } diff --git a/src/PowderCoating.Web/Helpers/HelpKnowledgeBase.cs b/src/PowderCoating.Web/Helpers/HelpKnowledgeBase.cs index e183894..199a7b3 100644 --- a/src/PowderCoating.Web/Helpers/HelpKnowledgeBase.cs +++ b/src/PowderCoating.Web/Helpers/HelpKnowledgeBase.cs @@ -678,6 +678,9 @@ public static class HelpKnowledgeBase **Step 5 — Set up your Chart of Accounts (for billing/AP)** If you use the Bills and accounting features, go to [Chart of Accounts](/Accounts) and confirm the seeded accounts fit your setup. The wizard seeds a standard set automatically. + **Trial balance indicator (Chart of Accounts)** + The Chart of Accounts page shows a Trial Balance badge: "Balanced" when total debits equal total credits, otherwise how far off the books are (excess debits/credits). A non-zero value usually means opening balances were entered without an offsetting entry, or a one-sided posting. Run Recalculate Balances first; if it persists, review opening balances. + **Default accounts (Chart of Accounts → Set Defaults)** On the Chart of Accounts page, the "Default Accounts" card lets you choose a default Revenue, COGS, and Inventory account for your company. These are used automatically when an item or invoice line doesn't specify one: invoice lines fall back to your default Revenue account (then to account 4000 if none is set), and new inventory and catalog items are pre-filled with your default COGS/Inventory accounts. Leave any blank to keep the current behavior. Note: setting BOTH a COGS and an Inventory Asset default makes new items post inventory-consumption COGS (perpetual inventory) — leave them blank if you expense materials when you purchase them. diff --git a/src/PowderCoating.Web/Views/Accounts/Index.cshtml b/src/PowderCoating.Web/Views/Accounts/Index.cshtml index 589f35f..653df0f 100644 --- a/src/PowderCoating.Web/Views/Accounts/Index.cshtml +++ b/src/PowderCoating.Web/Views/Accounts/Index.cshtml @@ -36,7 +36,33 @@ }; } -
+@{ + var tbNet = (decimal)(ViewBag.TrialBalanceNet ?? 0m); + var tbBalanced = Math.Abs(tbNet) < 0.01m; +} +
+ @if (Model.Any()) + { +
+ @if (tbBalanced) + { + + Trial balance: Balanced + + } + else + { + + Trial balance off by @tbNet.ToString("C") (@(tbNet > 0 ? "excess debits" : "excess credits")) + + } +
+ } + else + { +
+ }
@Html.AntiForgeryToken() diff --git a/src/PowderCoating.Web/Views/Help/Settings.cshtml b/src/PowderCoating.Web/Views/Help/Settings.cshtml index fdd16d0..55fbfc3 100644 --- a/src/PowderCoating.Web/Views/Help/Settings.cshtml +++ b/src/PowderCoating.Web/Views/Help/Settings.cshtml @@ -262,6 +262,15 @@
+

Trial Balance Indicator

+

+ The top of the Chart of Accounts page shows a Trial balance badge. When total + debits equal total credits it reads Balanced; otherwise it shows how far off the books + are (excess debits or credits). A non-zero value usually means opening balances were entered + without an offsetting entry, or a one-sided posting occurred. Run Recalculate Balances + first; if it persists, review your opening balances or ask your accountant. +

+