Restore all zeroed views + add bulk gift certificate creation

The HTML entity sweep script had a bug where it wrote empty files for any
view that contained no target Unicode characters, zeroing out 215 view files.
All views restored from the pre-sweep commit (cefdf3e).

Bulk gift certificate feature:
- BulkCreateGiftCertificateDto with Quantity (1-500), Amount, Reason, Expiry, Notes
- GenerateBulkGiftCertificatePdfAsync on IPdfService / PdfService: one Letter page
  per cert, reusing the same purple/gold branded ComposeGiftCertificateContent helper
- GiftCertificatesController: BulkCreate GET/POST, BulkResult GET, BulkDownloadPdf POST
- Views: BulkCreate.cshtml (form with live total preview), BulkResult.cshtml (table +
  Download All PDF button that POSTs cert IDs to avoid URL length limits)
- gift-certificate-bulk.js: live preview + spinner/disable on submit
- Index.cshtml: Bulk Create button added alongside New Certificate

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-14 20:09:22 -04:00
parent 3eda91f170
commit 4ec55e7290
240 changed files with 73116 additions and 0 deletions
@@ -0,0 +1,366 @@
@{
ViewData["Title"] = "Reports";
}
<div class="d-flex align-items-center gap-2 mb-3">
<a asp-controller="Help" asp-action="Index" class="btn btn-sm btn-outline-secondary"><i class="bi bi-arrow-left"></i></a>
<nav aria-label="breadcrumb">
<ol class="breadcrumb mb-0">
<li class="breadcrumb-item"><a asp-controller="Help" asp-action="Index">Help</a></li>
<li class="breadcrumb-item active">Reports</li>
</ol>
</nav>
</div>
<div class="row g-4">
<div class="col-lg-9">
<section id="overview" class="mb-5">
<h2 class="h4 fw-bold border-bottom pb-2 mb-3">
<i class="bi bi-info-circle text-primary me-2"></i>Overview
</h2>
<p>
The Reports section gives you financial summaries, operational insights, and AI-powered analysis
of your business. Reports are organized on the landing page by category — Financial, Operations,
and AI-Powered. Most reports are read-only views of live data and support PDF export.
</p>
<p>
You can find Reports under <strong>Reports</strong> in the left sidebar, which opens the
<strong>Reports Landing</strong> page at <strong>/Reports/Landing</strong>.
</p>
<div class="alert alert-permanent alert-info d-flex gap-2 mb-0" role="alert">
<i class="bi bi-lightbulb-fill flex-shrink-0 mt-1"></i>
<div>
Reports are read-only. To correct underlying data, navigate to the relevant module
(Jobs, Invoices, Inventory, etc.) and edit the record there.
</div>
</div>
</section>
<section id="financial-reports" class="mb-5">
<h2 class="h4 fw-bold border-bottom pb-2 mb-3">
<i class="bi bi-currency-dollar text-primary me-2"></i>Financial Reports
</h2>
<h3 class="h6 fw-semibold mt-3 mb-2">KPI Dashboard</h3>
<p>
A high-level scorecard showing your most important metrics at a glance — open jobs, pending
quotes, outstanding invoices, and recent revenue. Good for a quick daily check-in.
</p>
<h3 class="h6 fw-semibold mt-3 mb-2">Full Analytics</h3>
<p>
Detailed charts and KPI cards for the selected date range:
</p>
<ul class="mb-3">
<li class="mb-1"><strong>Total Invoiced</strong> — total value of all invoices created in the period.</li>
<li class="mb-1"><strong>Total Collected</strong> — total payments actually received.</li>
<li class="mb-1"><strong>Outstanding AR</strong> — current total of all unpaid invoices (always reflects today's balance, not filtered by date).</li>
<li class="mb-1"><strong>Overdue Balance</strong> — portion of AR where the due date has passed.</li>
<li class="mb-1"><strong>Monthly Invoiced vs. Collected chart</strong> — side-by-side bar chart by month; shows if collections are lagging behind invoicing.</li>
</ul>
<p>
The <strong>AI Financial Summary</strong> button in this view generates a plain-English narrative
of your financial performance using AI — useful for a quick briefing before a meeting. See the
<a href="#ai-reports">AI-Powered Reports</a> section below.
</p>
<h3 class="h6 fw-semibold mt-3 mb-2">Profit &amp; Loss</h3>
<p>
Revenue vs. expenses over a selected period. Shows gross revenue from invoices and a breakdown
of expenses by account category. Supports PDF export for your accountant.
</p>
<h3 class="h6 fw-semibold mt-3 mb-2">Balance Sheet</h3>
<p>
A snapshot of assets, liabilities, and equity as of a specific date. Assets include your
Accounts Receivable balance; liabilities include your Accounts Payable balance.
</p>
<h3 class="h6 fw-semibold mt-3 mb-2">AR Aging</h3>
<p>
Breaks down all outstanding invoices by how long they have been overdue:
<strong>Current</strong> (not yet due), <strong>130 days</strong>,
<strong>3160 days</strong>, <strong>6190 days</strong>, and <strong>90+ days</strong>.
Focus collection efforts on the 6190 and 90+ columns first.
</p>
<p>
The AR Aging page also has an <strong>AI AR Follow-Up</strong> button that drafts a
collection email for any overdue invoice — the tone automatically scales with how overdue
the invoice is (gentle reminder at 7 days, firmer at 30+).
</p>
<h3 class="h6 fw-semibold mt-3 mb-2">Sales &amp; Income</h3>
<p>
Revenue trends broken down by period (monthly or quarterly). Use this to spot seasonal
patterns in your job volume and revenue.
</p>
<h3 class="h6 fw-semibold mt-3 mb-2">Sales Tax Report</h3>
<p>
An invoice-basis Sales Tax Liability report — shows what you collected in tax during the
period and breaks it down so you can file accurately. Key figures:
</p>
<ul class="mb-3">
<li class="mb-1"><strong>Total Tax Billed</strong> — sum of all tax charged on invoices in the period.</li>
<li class="mb-1"><strong>Taxable Sales</strong> — subtotals of invoices where tax was charged.</li>
<li class="mb-1"><strong>Non-Taxable Sales</strong> — subtotals of tax-exempt invoices (e.g. tax-exempt customers).</li>
<li class="mb-1"><strong>Effective Tax Rate</strong> — overall average rate across all taxable invoices.</li>
<li class="mb-1"><strong>By Tax Account</strong> — breakdown by GL account (useful if you have multiple tax jurisdictions or rates).</li>
<li class="mb-1"><strong>By Month</strong> — month-by-month chart and table of taxable sales and tax billed.</li>
<li class="mb-1"><strong>Invoice Detail</strong> — every invoice in the period with its tax %, tax amount, and tax account. Non-taxable invoices appear shaded grey so they are easy to distinguish.</li>
</ul>
<p>
This report supports both <strong>PDF export</strong> and <strong>CSV export</strong>.
The CSV is formatted for handing to your accountant or importing into tax-filing software —
one row per invoice with all relevant columns. Use the quick preset buttons (This Month,
Last Month, YTD, Last Year) to jump to common filing periods without manually entering dates.
</p>
<div class="alert alert-permanent alert-info d-flex gap-2 mb-3" role="alert">
<i class="bi bi-lightbulb-fill flex-shrink-0 mt-1"></i>
<div>
<strong>Invoice basis vs. cash basis:</strong> The Sales Tax Report counts tax when an
invoice is created, not when it is paid. If your jurisdiction requires cash-basis reporting,
cross-reference payments using the <strong>Sales &amp; Income</strong> report.
</div>
</div>
<h3 class="h6 fw-semibold mt-3 mb-2">Revenue Trends</h3>
<p>
A charting view of monthly and quarterly revenue over time. Useful for year-over-year
comparisons and trend spotting.
</p>
<h3 class="h6 fw-semibold mt-3 mb-2">Top Outstanding Customers</h3>
<p>
Ranked list of customers with the highest current outstanding balances. Use this to quickly
identify who to call when you need to improve cash flow.
</p>
</section>
<section id="operations-reports" class="mb-5">
<h2 class="h4 fw-bold border-bottom pb-2 mb-3">
<i class="bi bi-briefcase text-primary me-2"></i>Operations Reports
</h2>
<h3 class="h6 fw-semibold mt-3 mb-2">Operations Report</h3>
<p>
A comprehensive view of job throughput, status distribution, and workload for the selected
period. Key metrics include:
</p>
<ul class="mb-3">
<li class="mb-1"><strong>Job counts by status</strong> — how many jobs are in each stage. A high count in one status can indicate a bottleneck.</li>
<li class="mb-1"><strong>Open, Completed, On Hold, and Overdue counts</strong> — KPI cards for the overall health of your job queue.</li>
<li class="mb-1"><strong>Job counts by priority</strong> — how many jobs are at each level (Low/Normal/High/Urgent/Rush).</li>
<li class="mb-1"><strong>Average completion time</strong> — average days from job creation to Completed status. Use as a baseline for quoting lead times.</li>
</ul>
<h3 class="h6 fw-semibold mt-3 mb-2">Customer Overview</h3>
<p>
Top customers by revenue, job count, and outstanding balance. Helps you understand which
customers drive the most business and which have the largest open accounts.
</p>
<h3 class="h6 fw-semibold mt-3 mb-2">Job Cycle Time Report</h3>
<p>
Shows how long jobs spend in each status on average. Use this to identify where jobs tend
to slow down — for example, if jobs spend an unusually long time in Sandblasting, that
stage may need more capacity.
</p>
<h3 class="h6 fw-semibold mt-3 mb-2">Powder Usage Report</h3>
<p>
Tracks powder consumption by inventory item and by job. Useful for verifying that actual
powder usage matches estimates, identifying waste, and planning purchasing.
</p>
<h3 class="h6 fw-semibold mt-3 mb-2">Inventory Snapshot</h3>
<p>Key inventory metrics including:</p>
<ul class="mb-3">
<li class="mb-1"><strong>Total inventory value</strong> — on-hand quantity × unit cost for all items.</li>
<li class="mb-1"><strong>Items below reorder point</strong> — items currently flagged as low stock.</li>
<li class="mb-1"><strong>Recent transaction summary</strong> — log of recent stock movements.</li>
</ul>
<h3 class="h6 fw-semibold mt-3 mb-2">Equipment &amp; Maintenance Report</h3>
<p>Equipment health overview for maintenance supervisors:</p>
<ul class="mb-3">
<li class="mb-1"><strong>Equipment status distribution</strong> — how many machines are Operational, Needs Maintenance, Under Maintenance, etc.</li>
<li class="mb-1"><strong>Upcoming maintenance tasks</strong> — scheduled tasks due soon.</li>
<li class="mb-1"><strong>Overdue maintenance tasks</strong> — tasks past their scheduled date that are not yet complete.</li>
</ul>
<div class="alert alert-permanent alert-info d-flex gap-2 mb-0" role="alert">
<i class="bi bi-lightbulb-fill flex-shrink-0 mt-1"></i>
<div>
Most reports support a date range filter. Set a <strong>From</strong> and <strong>To</strong>
date and click <strong>Apply</strong> to narrow the data to that period. Useful date ranges:
this month (1st to today), last month, year to date (Jan 1 to today), or full prior year.
</div>
</div>
</section>
<section id="ai-reports" class="mb-5">
<h2 class="h4 fw-bold border-bottom pb-2 mb-3">
<i class="bi bi-robot text-primary me-2"></i>AI-Powered Reports
</h2>
<p>
Several reports use AI to analyze your data and return insights in plain
English. These are found either on the Reports landing page or as buttons within other reports.
</p>
<h3 class="h6 fw-semibold mt-3 mb-2">AI Financial Summary</h3>
<p>
Generates a plain-English narrative of your financial performance — revenue trends, collection
rate, outstanding AR, and notable patterns. Accessible from the <strong>Full Analytics</strong>
view via the "Generate AI Summary" button. Useful for summarizing performance before a meeting
or for stakeholders who prefer prose over tables.
</p>
<h3 class="h6 fw-semibold mt-3 mb-2">Cash Flow Forecast</h3>
<p>
Projects your cash position over the next 30, 60, and 90 days based on:
</p>
<ul class="mb-3">
<li class="mb-1">Open accounts receivable (invoices expected to be paid)</li>
<li class="mb-1">Open accounts payable (bills coming due)</li>
<li class="mb-1">Active job pipeline (potential future revenue)</li>
</ul>
<p>
The forecast includes an <strong>outlook badge</strong> — Strong, Moderate, Tight, or
Concerning — based on the projected net cash position at each interval.
</p>
<h3 class="h6 fw-semibold mt-3 mb-2">Anomaly Detection</h3>
<p>
Scans the last 90 days of bills for unusual patterns and flags them for review:
</p>
<ul class="mb-3">
<li class="mb-1"><strong>Duplicate bills</strong> — same vendor, similar amount, close dates.</li>
<li class="mb-1"><strong>Amount spikes</strong> — a vendor bill significantly higher than their usual amounts.</li>
<li class="mb-1"><strong>Unusual vendors</strong> — vendors you have not used before or rarely use.</li>
<li class="mb-1"><strong>Account overruns</strong> — expense accounts with spending well above their typical level.</li>
</ul>
<p>Flags are sorted by severity. Review and dismiss any that are expected or already explained.</p>
<h3 class="h6 fw-semibold mt-3 mb-2">AI AR Follow-Up Emails</h3>
<p>
Drafts a collection email for overdue invoices directly from the <strong>AR Aging</strong> report.
Click the envelope icon next to any overdue invoice to generate a draft. The tone scales with
how many days overdue the invoice is — a gentle nudge at 7 days, a firmer reminder at 30+.
You can edit the draft before sending.
</p>
<h3 class="h6 fw-semibold mt-3 mb-2">AI Payment Risk Prediction</h3>
<p>
Available inside the <strong>AR Aging</strong> report (<a asp-controller="Reports" asp-action="ArAging">/Reports/ArAging</a>).
Click <strong>"Predict Payment Risk"</strong> at the bottom of the page to have Claude analyze
each open AR customer and assign a risk level:
</p>
<ul class="mb-3">
<li class="mb-1"><strong>High</strong> — customer has a history of late payment and is already overdue; prioritize a phone call today.</li>
<li class="mb-1"><strong>Medium</strong> — overdue but reasonable history, or current but spotty past performance.</li>
<li class="mb-1"><strong>Low</strong> — typically pays on time; no immediate follow-up needed.</li>
</ul>
<p>
Each prediction includes an estimated number of additional days to collection and a one-sentence
explanation of the scoring. Use this to triage your collection calls — start with High-risk
customers first.
</p>
<h3 class="h6 fw-semibold mt-3 mb-2">Ask Your Financials (Natural Language Queries)</h3>
<p>
A conversational AI tool at <a asp-controller="Reports" asp-action="FinancialQuery">/Reports/FinancialQuery</a>
that lets you ask plain-English questions about your business finances and get direct answers
grounded in your actual data. Example questions:
</p>
<ul class="mb-3">
<li class="mb-1">"What was our revenue this year?"</li>
<li class="mb-1">"What are our biggest expenses?"</li>
<li class="mb-1">"Which month had the highest revenue?"</li>
<li class="mb-1">"How much do customers owe us?"</li>
</ul>
<p>
Each answer includes <strong>supporting facts</strong> pulled directly from your data so you can
verify the figures, and a <strong>follow-up suggestion</strong> for what to ask next. Claude
will not invent numbers — if the data is not available in the snapshot, it says so. The page
also shows clickable example chips and remembers your last 5 questions during the session.
</p>
<h3 class="h6 fw-semibold mt-3 mb-2">Bank Rec AI Auto-Match</h3>
<p>
Inside <strong>Bank Reconciliation</strong> (<a asp-controller="BankReconciliations" asp-action="Index">/BankReconciliations</a>),
the <strong>Reconcile</strong> working view includes an <strong>AI Auto-Match</strong> panel.
Click <strong>"Suggest Matches"</strong> and Claude analyzes all uncleared transactions against
your statement ending balance, then suggests which items to mark as cleared — sorted by
confidence score with a one-sentence reason for each.
</p>
<p>
Click <strong>"Apply All Suggestions"</strong> to accept them in bulk; the checkboxes are marked
and persisted automatically. Review the highlighted rows (shown in blue) before applying if you
want to verify each one individually. Auto-match does not complete the reconciliation — you
still click "Complete Reconciliation" yourself once the difference reaches $0.00.
</p>
<h3 class="h6 fw-semibold mt-3 mb-2">Powder Insights</h3>
<p>
An AI-powered analysis of your powder usage patterns, efficiency, and cost optimization,
accessible at <strong>/PowderInsights</strong> from the Equipment section of the sidebar.
Requires at least 10 jobs with powder data; predictive cost-optimization features unlock
at 150 jobs.
</p>
<div class="alert alert-permanent alert-secondary d-flex gap-2 mb-0" role="alert">
<i class="bi bi-info-circle flex-shrink-0 mt-1"></i>
<div>
AI reports require the Anthropic API key to be configured. If you see a "not configured"
message, contact your system administrator to set up the key under
<strong>Settings &rsaquo; Company Settings</strong>.
</div>
</div>
</section>
<section id="pdf-export" class="mb-5">
<h2 class="h4 fw-bold border-bottom pb-2 mb-3">
<i class="bi bi-file-earmark-pdf text-primary me-2"></i>PDF &amp; CSV Export
</h2>
<p>
Most financial reports (P&amp;L, Balance Sheet, AR Aging, Sales &amp; Income, and others)
include a <strong>Download PDF</strong> button. Use this to generate a print-ready version
for your accountant, a business review, or your own records.
</p>
<p>
The <strong>Sales Tax Report</strong> also includes an <strong>Export CSV</strong> button.
The CSV file contains one row per invoice and is formatted so it can be opened directly in
Excel or imported into most tax-filing and accounting packages. Column headers match standard
tax report terminology: Invoice #, Customer, Date, Status, Subtotal, Tax %, Tax Amount,
Total, Amount Paid, Balance Due, Tax Account.
</p>
<p>
All PDF and CSV exports respect the same date range you have selected in the report — what
you see on screen is exactly what gets exported.
</p>
</section>
</div>
<div class="col-lg-3 d-none d-lg-block">
@{ await Html.RenderPartialAsync("_HelpNav"); }
<div class="card border-0 shadow-sm sticky-top" style="top:80px">
<div class="card-header bg-transparent fw-semibold small text-muted text-uppercase" style="letter-spacing:.05em; font-size:.7rem;">On this page</div>
<div class="card-body p-0">
<nav class="nav flex-column">
<a class="nav-link py-1 px-3 small text-body" href="#overview">Overview</a>
<a class="nav-link py-1 px-3 small text-body" href="#financial-reports">Financial Reports</a>
<a class="nav-link py-1 px-3 small text-body ps-4" href="#financial-reports" style="font-size:.75rem">Sales Tax Report</a>
<a class="nav-link py-1 px-3 small text-body" href="#operations-reports">Operations Reports</a>
<a class="nav-link py-1 px-3 small text-body" href="#ai-reports">AI-Powered Reports</a>
<a class="nav-link py-1 px-3 small text-body ps-4" href="#ai-reports" style="font-size:.75rem">Payment Risk Prediction</a>
<a class="nav-link py-1 px-3 small text-body ps-4" href="#ai-reports" style="font-size:.75rem">Ask Your Financials</a>
<a class="nav-link py-1 px-3 small text-body ps-4" href="#ai-reports" style="font-size:.75rem">Bank Rec Auto-Match</a>
<a class="nav-link py-1 px-3 small text-body" href="#pdf-export">PDF &amp; CSV Export</a>
</nav>
</div>
</div>
</div>
</div>