@using PowderCoating.Application.DTOs.Common @using PowderCoating.Application.DTOs.Invoice @using PowderCoating.Core.Enums @using PowderCoating.Web.Controllers @model PagedResult @{ ViewData["Title"] = "Invoices"; ViewData["PageIcon"] = "bi-receipt"; ViewData["PageHelpTitle"] = "Invoices"; ViewData["PageHelpContent"] = "Invoices are created from completed jobs and sent to the customer for payment. Lifecycle: Draft (editable) → Sent (locked, awaiting payment) → Partially Paid / Paid. Overdue = past due date with a balance still owed. Outstanding shows the total A/R balance across all unpaid invoices currently on screen. Use Void to cancel without deleting history."; var searchTerm = ViewBag.SearchTerm as string; var statusFilter = ViewBag.StatusFilter as InvoiceStatus?; var outstandingOnly = (bool)(ViewBag.OutstandingOnly ?? false); var thisMonthOnly = (bool)(ViewBag.ThisMonthOnly ?? false); } @{ var _outstanding = Model.Items.Where(i => i.Status != InvoiceStatus.Paid && i.Status != InvoiceStatus.Voided && i.Status != InvoiceStatus.WrittenOff).Sum(i => i.BalanceDue); var _collected = Model.Items.Sum(i => i.AmountPaid); var _overdue = Model.Items.Count(i => i.IsOverdue); }
@await Html.PartialAsync("_Metric", (Label: "TOTAL", Value: Model.TotalCount.ToString(), Delta: (string?)null, DeltaDir: (string?)null))
@await Html.PartialAsync("_Metric", (Label: "OUTSTANDING", Value: _outstanding.ToString("C0"), Delta: (string?)null, DeltaDir: (string?)null))
@await Html.PartialAsync("_Metric", (Label: "OVERDUE", Value: _overdue.ToString(), Delta: (string?)null, DeltaDir: (string?)null))
@await Html.PartialAsync("_Metric", (Label: "COLLECTED", Value: _collected.ToString("C0"), Delta: (string?)null, DeltaDir: (string?)null))
@if (TempData["Success"] != null) { } @if (TempData["Error"] != null) { }
@if (outstandingOnly) { } @if (thisMonthOnly) { }
@if (!string.IsNullOrEmpty(searchTerm) || statusFilter.HasValue || outstandingOnly || thisMonthOnly) { Clear } @if (outstandingOnly) { Outstanding A/R } @if (thisMonthOnly && statusFilter == InvoiceStatus.Paid) { Paid — @DateTime.Now.ToString("MMMM yyyy") } else if (thisMonthOnly) { @DateTime.Now.ToString("MMMM yyyy") }
New Invoice
@if (Model != null && Model.Items.Any()) {
@foreach (var inv in Model.Items) { var rowClass = inv.IsOverdue ? "table-danger" : ""; }
Invoice # Customer Job # Status Date Due Total Balance Due Actions
@inv.InvoiceNumber @inv.CustomerName @if (inv.JobId.HasValue) { @inv.JobNumber } else { Merch } @await Html.PartialAsync("_StatusChip", (Kind: StatusChipHelper.InvoiceStatus(inv.Status), Text: InvoicesController.GetStatusDisplay(inv.Status))) @inv.InvoiceDate.ToString("MM/dd/yyyy") @(inv.DueDate.HasValue ? inv.DueDate.Value.ToString("MM/dd/yyyy") : "—") @inv.Total.ToString("C") @inv.BalanceDue.ToString("C")
@await Html.PartialAsync("_Pagination", Model)
} else {

No invoices found.

Create First Invoice
}
@section Scripts { }