Files
PowderCoatingLogix/src/PowderCoating.Web/Views/Reports/FinancialQuery.cshtml
T
spouliot 959e323f3a Add 4 AI bookkeeping features
Feature 7: Bank Rec Auto-Match — AiSuggestMatches endpoint scores uncleared
transactions vs statement ending balance; AI Auto-Match panel in Reconcile.cshtml
with confidence highlights and Apply All button.

Feature 8: Late Payment Prediction — PredictLatePayments endpoint scores open AR
customers by risk (high/medium/low) using historical avg-days-to-pay + late rate;
rendered as badge table in AR Aging view via ar-aging-ai.js.

Feature 9: Natural Language Financial Queries — FinancialQuery GET page + RunFinancialQuery
POST; 12-month context snapshot pre-loaded; answers grounded in real data with
supporting facts, follow-up suggestions, session history, and example chips.

Feature 10: Recurring Bill Detection — RunRecurringDetection scans 12 months of bills
for vendor payment patterns (monthly/quarterly/annual); card grid view in Bills/RecurringDetection.cshtml
with confidence badges, next-expected-date, and suggested actions.

Supporting: 4 new DTO groups in AccountingAiDtos.cs, 4 method signatures in
IAccountingAiService.cs, 4 implementations in AccountingAiService.cs, 4 new
AiFeatures constants, 2 new Landing page AI report cards.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-10 19:22:49 -04:00

123 lines
6.0 KiB
Plaintext

@using System.Text.Json
@{
ViewData["Title"] = "Ask Your Financials";
ViewData["PageIcon"] = "bi-chat-dots";
var context = ViewBag.Context as PowderCoating.Application.DTOs.AI.FinancialQueryContext;
var contextJson = JsonSerializer.Serialize(context);
}
<div class="d-flex justify-content-between align-items-center mb-4">
<div>
<h4 class="fw-semibold mb-1"><i class="bi bi-chat-dots text-primary me-2"></i>Ask Your Financials</h4>
<p class="text-muted small mb-0">Ask Claude a plain-English question about your business finances. Data as of @DateTime.Today.ToString("MMMM d, yyyy").</p>
</div>
<a asp-action="Landing" class="btn btn-outline-secondary">
<i class="bi bi-arrow-left me-1"></i>Reports
</a>
</div>
<div class="row g-4">
<div class="col-lg-8">
<!-- Query input -->
<div class="card shadow-sm mb-4">
<div class="card-body">
<label class="form-label fw-semibold">Your question</label>
<div class="input-group">
<input type="text" id="queryInput" class="form-control form-control-lg"
placeholder="e.g. What did we spend on powder last quarter?"
autocomplete="off" />
<button id="queryBtn" class="btn btn-primary px-4" type="button">
<i class="bi bi-send me-1"></i>Ask
</button>
</div>
<div class="mt-2 d-flex flex-wrap gap-2" id="suggestionChips">
<span class="text-muted small me-1">Try:</span>
</div>
</div>
</div>
<!-- Answer area -->
<div id="answerArea" class="d-none">
<div class="card shadow-sm border-primary border-opacity-25">
<div class="card-header bg-primary-subtle text-primary-emphasis fw-semibold">
<i class="bi bi-robot me-1"></i>Claude's Answer
</div>
<div class="card-body">
<div id="answerSpinner" class="text-center py-3 d-none">
<div class="spinner-border text-primary" role="status"></div>
<p class="text-muted mt-2 small">Analyzing your financials…</p>
</div>
<div id="answerError" class="alert alert-danger alert-permanent d-none"></div>
<p id="answerText" class="mb-3 fs-6 d-none"></p>
<div id="factsArea" class="d-none">
<p class="small fw-semibold text-muted mb-1">Supporting data:</p>
<ul id="factsList" class="list-unstyled small text-muted mb-0"></ul>
</div>
<div id="followUpArea" class="mt-3 pt-3 border-top d-none">
<span class="text-muted small me-2">Follow-up suggestion:</span>
<button id="followUpBtn" class="btn btn-sm btn-outline-primary"></button>
</div>
</div>
</div>
<!-- History -->
<div id="historyArea" class="mt-3 d-none">
<p class="text-muted small fw-semibold mb-2"><i class="bi bi-clock-history me-1"></i>Earlier questions this session</p>
<div id="historyList" class="d-flex flex-column gap-2"></div>
</div>
</div>
</div>
<div class="col-lg-4">
<!-- Snapshot -->
<div class="card shadow-sm mb-3">
<div class="card-header fw-semibold text-muted small">
<i class="bi bi-graph-up me-1"></i>YTD Snapshot
</div>
<div class="card-body pb-2">
<div class="d-flex justify-content-between small mb-2">
<span class="text-muted">Revenue</span>
<span class="fw-medium">@context?.TotalRevenueYtd.ToString("C0")</span>
</div>
<div class="d-flex justify-content-between small mb-2">
<span class="text-muted">Expenses</span>
<span class="fw-medium">@context?.TotalExpensesYtd.ToString("C0")</span>
</div>
<div class="d-flex justify-content-between small mb-2 border-top pt-2">
<span class="fw-semibold">Net Income</span>
<span class="fw-bold @(context?.NetIncomeYtd >= 0 ? "text-success" : "text-danger")">
@context?.NetIncomeYtd.ToString("C0")
</span>
</div>
<div class="d-flex justify-content-between small mb-2 border-top pt-2">
<span class="text-muted">AR Outstanding</span>
<span class="fw-medium text-warning">@context?.ArOutstanding.ToString("C0")</span>
</div>
<div class="d-flex justify-content-between small mb-2">
<span class="text-muted">AP Outstanding</span>
<span class="fw-medium text-danger">@context?.ApOutstanding.ToString("C0")</span>
</div>
</div>
</div>
<!-- Tips -->
<div class="card shadow-sm border-0 bg-light">
<div class="card-body small">
<p class="fw-semibold text-muted mb-2"><i class="bi bi-lightbulb me-1 text-warning"></i>Tips</p>
<ul class="list-unstyled text-muted mb-0 small">
<li class="mb-1">Ask about specific time periods: "last month", "Q1", "this year"</li>
<li class="mb-1">Compare periods: "compared to last quarter"</li>
<li class="mb-1">Ask about vendors, categories, or customers</li>
<li>Claude only uses data it was given — it won't invent figures</li>
</ul>
</div>
</div>
</div>
</div>
<input type="hidden" id="contextJson" value="@Html.Raw(System.Text.Encodings.Web.HtmlEncoder.Default.Encode(contextJson))" />
@section Scripts {
<script src="/js/financial-query.js"></script>
}