143 lines
8.0 KiB
Plaintext
143 lines
8.0 KiB
Plaintext
@model PowderCoating.Application.DTOs.Common.PagedResult<PowderCoating.Application.DTOs.Invoice.InvoiceListDto>
|
|
@using PowderCoating.Core.Enums
|
|
@using PowderCoating.Web.Controllers
|
|
|
|
@{
|
|
ViewData["Title"] = $"Invoices - {ViewBag.CustomerName}";
|
|
ViewData["PageIcon"] = "bi-receipt";
|
|
}
|
|
|
|
<div class="d-flex justify-content-end gap-2 mb-4">
|
|
<a asp-controller="Invoices" asp-action="Create" asp-route-customerId="@ViewBag.CustomerId" class="btn btn-primary">
|
|
<i class="bi bi-plus-circle me-2"></i>New Invoice
|
|
</a>
|
|
<a asp-action="Details" asp-route-id="@ViewBag.CustomerId" class="btn btn-outline-secondary">
|
|
<i class="bi bi-arrow-left me-2"></i>Back to Customer
|
|
</a>
|
|
</div>
|
|
|
|
<div class="card border-0 shadow-sm">
|
|
<div class="card-header bg-white border-0 py-3">
|
|
<div class="d-flex justify-content-between align-items-center">
|
|
<h5 class="mb-0 fw-semibold">
|
|
@Model.TotalCount invoice(s) total
|
|
</h5>
|
|
</div>
|
|
</div>
|
|
<div class="card-body p-0">
|
|
@if (!Model.Items.Any())
|
|
{
|
|
<div class="text-center py-5">
|
|
<i class="bi bi-receipt" style="font-size: 4rem; color: #d1d5db;"></i>
|
|
<h5 class="mt-3 text-muted">No invoices found</h5>
|
|
<p class="text-muted mb-4">This customer has no invoices yet</p>
|
|
<a asp-controller="Invoices" asp-action="Create" asp-route-customerId="@ViewBag.CustomerId" class="btn btn-primary">
|
|
<i class="bi bi-plus-circle me-2"></i>Create Invoice
|
|
</a>
|
|
</div>
|
|
}
|
|
else
|
|
{
|
|
<div class="table-responsive">
|
|
<table class="table table-hover mb-0">
|
|
<thead>
|
|
<tr>
|
|
<th sortable="InvoiceNumber" current-sort="@ViewBag.SortColumn" current-direction="@ViewBag.SortDirection" class="ps-4">Invoice #</th>
|
|
<th>Job #</th>
|
|
<th sortable="Status" current-sort="@ViewBag.SortColumn" current-direction="@ViewBag.SortDirection">Status</th>
|
|
<th sortable="DueDate" current-sort="@ViewBag.SortColumn" current-direction="@ViewBag.SortDirection">Due Date</th>
|
|
<th sortable="Total" current-sort="@ViewBag.SortColumn" current-direction="@ViewBag.SortDirection" class="text-end">Total</th>
|
|
<th sortable="BalanceDue" current-sort="@ViewBag.SortColumn" current-direction="@ViewBag.SortDirection" class="text-end">Balance Due</th>
|
|
<th class="text-end pe-4">Actions</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
@foreach (var inv in Model.Items)
|
|
{
|
|
<tr style="cursor: pointer;" onclick="window.location.href='@Url.Action("Details", "Invoices", new { id = inv.Id })'">
|
|
<td class="ps-4">
|
|
<div class="d-flex align-items-center gap-2">
|
|
<div class="rounded-circle d-flex align-items-center justify-content-center"
|
|
style="width: 40px; height: 40px; background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%); color: white; font-weight: 600;">
|
|
<i class="bi bi-receipt"></i>
|
|
</div>
|
|
<div>
|
|
<div class="fw-semibold">@inv.InvoiceNumber</div>
|
|
<small class="text-muted">@inv.InvoiceDate.Tz(ViewBag.CompanyTimeZone as string).ToString("MMM dd, yyyy")</small>
|
|
</div>
|
|
</div>
|
|
</td>
|
|
<td class="align-middle">
|
|
@if (inv.JobId.HasValue && !string.IsNullOrEmpty(inv.JobNumber))
|
|
{
|
|
<a asp-controller="Jobs" asp-action="Details" asp-route-id="@inv.JobId"
|
|
class="text-decoration-none" onclick="event.stopPropagation()">
|
|
@inv.JobNumber
|
|
</a>
|
|
}
|
|
else
|
|
{
|
|
<span class="text-muted fst-italic">No job</span>
|
|
}
|
|
</td>
|
|
<td class="align-middle">
|
|
<span class="badge bg-@InvoicesController.GetStatusColorClass(inv.Status)">
|
|
@InvoicesController.GetStatusDisplay(inv.Status)
|
|
</span>
|
|
@if (inv.IsOverdue)
|
|
{
|
|
<span class="badge bg-danger ms-1">Overdue</span>
|
|
}
|
|
</td>
|
|
<td class="align-middle">
|
|
@if (inv.DueDate.HasValue)
|
|
{
|
|
<span class="@(inv.IsOverdue ? "text-danger fw-semibold" : "")">
|
|
@inv.DueDate.Value.Tz(ViewBag.CompanyTimeZone as string).ToString("MMM dd, yyyy")
|
|
@if (inv.IsOverdue)
|
|
{
|
|
<i class="bi bi-exclamation-triangle ms-1"></i>
|
|
}
|
|
</span>
|
|
}
|
|
else
|
|
{
|
|
<span class="text-muted">—</span>
|
|
}
|
|
</td>
|
|
<td class="align-middle text-end fw-semibold">@inv.Total.ToString("C")</td>
|
|
<td class="align-middle text-end">
|
|
@if (inv.BalanceDue > 0)
|
|
{
|
|
<span class="fw-semibold text-danger">@inv.BalanceDue.ToString("C")</span>
|
|
}
|
|
else
|
|
{
|
|
<span class="text-success fw-semibold">Paid</span>
|
|
}
|
|
</td>
|
|
<td class="text-end pe-4 align-middle" onclick="event.stopPropagation()">
|
|
<div class="btn-group btn-group-sm">
|
|
<a asp-controller="Invoices" asp-action="Details" asp-route-id="@inv.Id"
|
|
class="btn btn-outline-primary" title="View Invoice">
|
|
<i class="bi bi-eye"></i>
|
|
</a>
|
|
<a asp-controller="Invoices" asp-action="DownloadPdf" asp-route-id="@inv.Id"
|
|
class="btn btn-outline-secondary" title="Download PDF">
|
|
<i class="bi bi-file-earmark-pdf"></i>
|
|
</a>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
}
|
|
</div>
|
|
@if (Model.TotalCount > 0)
|
|
{
|
|
@await Html.PartialAsync("_Pagination", Model)
|
|
}
|
|
</div>
|