@model PagedResult @{ ViewData["Title"] = "Quotes"; ViewData["PageIcon"] = "bi-file-text"; var searchTerm = ViewBag.SearchTerm as string; var statusFilter = ViewBag.StatusFilter as int?; var statusCode = ViewBag.StatusCode as string; } @{ var _statOpen = (int)(ViewBag.StatOpenCount ?? 0); var _statApproved = (int)(ViewBag.StatApprovedCount ?? 0); var _statValue = (decimal)(ViewBag.StatTotalValue ?? 0m); var _notCalibrated = (bool)(ViewBag.QuotingNotCalibrated ?? false); } @if (_notCalibrated) {
Your quoting isn't calibrated yet. AI photo quotes and calculated item time estimates are using generic industry averages — they may not match your shop's actual throughput. Set up your equipment profile →
}
@await Html.PartialAsync("_Metric", (Label: "TOTAL", Value: Model.TotalCount.ToString(), Delta: (string?)null, DeltaDir: (string?)null))
@await Html.PartialAsync("_Metric", (Label: "OPEN", Value: _statOpen.ToString(), Delta: (string?)null, DeltaDir: (string?)null))
@await Html.PartialAsync("_Metric", (Label: "APPROVED", Value: _statApproved.ToString(), Delta: (string?)null, DeltaDir: (string?)null))
@await Html.PartialAsync("_Metric", (Label: "TOTAL VALUE", Value: _statValue.ToString("C0"), Delta: (string?)null, DeltaDir: (string?)null))
@if (!string.IsNullOrEmpty(searchTerm) || statusFilter.HasValue || !string.IsNullOrEmpty(statusCode) || !string.IsNullOrEmpty(ViewBag.TagFilter as string)) { Clear } @if (!string.IsNullOrEmpty(statusCode) && statusCode.ToUpper() == "SENT") { Pending (Sent) Quotes }
New Quote New
@if (Model != null && Model.Items.Any()) {
@foreach (var quote in Model.Items) { }
Quote Number Customer/Prospect Type Description Status Quote Date Expiration Date Total Actions
@quote.QuoteNumber @if (!string.IsNullOrWhiteSpace(quote.Tags)) {
@foreach (var tag in quote.Tags.Split(',', StringSplitOptions.RemoveEmptyEntries).Select(t => t.Trim()).Where(t => !string.IsNullOrWhiteSpace(t))) { @tag }
}
@quote.CustomerOrProspectName @await Html.PartialAsync("_StatusChip", (Kind: quote.IsProspect ? "cool" : "ok", Text: quote.IsProspect ? "Prospect" : "Customer")) @if (!string.IsNullOrWhiteSpace(quote.Description)) { @(quote.Description.Length > 50 ? quote.Description.Substring(0, 50) + "..." : quote.Description) } else { - } @quote.StatusDisplayName @if (quote.IsExpired) { } @quote.QuoteDate.ToString("MM/dd/yyyy") @if (quote.ExpirationDate.HasValue) { @quote.ExpirationDate.Value.ToString("MM/dd/yyyy") } else { - } @quote.Total.ToString("C")
@if (quote.IsProspect && quote.StatusCode == "APPROVED") { }
@foreach (var quote in Model.Items) {
@quote.QuoteNumber
@quote.CustomerOrProspectName
Type @if (quote.IsProspect) { Prospect } else { Customer }
Status @await Html.PartialAsync("_StatusChip", (Kind: StatusChipHelper.QuoteStatus(quote.StatusCode), Text: quote.StatusDisplayName)) @if (quote.IsExpired) { }
Quote Date @quote.QuoteDate.ToString("MM/dd/yyyy")
@if (quote.ExpirationDate.HasValue) {
Expires @quote.ExpirationDate.Value.ToString("MM/dd/yyyy")
}
Total @quote.Total.ToString("C")
}
} else {

No quotes found.

@if (!string.IsNullOrEmpty(searchTerm) || statusFilter.HasValue || !string.IsNullOrEmpty(statusCode) || !string.IsNullOrEmpty(ViewBag.TagFilter as string)) {

No quotes match your current filter. View all quotes.

} else { Create Your First Quote }
}
@if (Model.TotalCount > 0) { @await Html.PartialAsync("_Pagination", Model) }
@Html.AntiForgeryToken() @section Scripts { }