Files
PowderCoatingLogix/src/PowderCoating.Web/Views/FixedAssets/Details.cshtml
T
spouliot 4ec55e7290 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>
2026-05-14 20:09:22 -04:00

223 lines
10 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
@using PowderCoating.Core.Entities
@model FixedAsset
@{
ViewData["Title"] = Model.Name;
ViewData["PageIcon"] = "bi-building-gear";
var fullyDeprec = Model.AccumulatedDepreciation >= (Model.PurchaseCost - Model.SalvageValue);
var depreciableBase = Model.PurchaseCost - Model.SalvageValue;
var progress = depreciableBase > 0
? (double)(Model.AccumulatedDepreciation / depreciableBase) * 100
: 100;
var entries = ViewBag.Entries as List<FixedAssetDepreciationEntry> ?? new();
var monthsRemaining = (int)(ViewBag.MonthsRemaining ?? 0);
}
<div class="d-flex justify-content-between align-items-center mb-4">
<a asp-action="Index" class="btn btn-outline-secondary">
<i class="bi bi-arrow-left me-1"></i>Asset Register
</a>
<div class="d-flex gap-2">
@if (!Model.IsDisposed)
{
<a asp-action="Edit" asp-route-id="@Model.Id" class="btn btn-outline-primary btn-sm">
<i class="bi bi-pencil me-1"></i>Edit
</a>
}
<form asp-action="Delete" asp-route-id="@Model.Id" method="post"
onsubmit="return confirm('Delete this asset? This cannot be undone. Assets with depreciation history cannot be deleted.')">
@Html.AntiForgeryToken()
<button type="submit" class="btn btn-outline-danger btn-sm">
<i class="bi bi-trash me-1"></i>Delete
</button>
</form>
</div>
</div>
@if (TempData["Success"] != null)
{
<div class="alert alert-success alert-permanent alert-dismissible fade show" role="alert">
<i class="bi bi-check-circle me-2"></i>@TempData["Success"]
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
</div>
}
@if (TempData["Error"] != null)
{
<div class="alert alert-danger alert-permanent alert-dismissible fade show" role="alert">
<i class="bi bi-exclamation-triangle me-2"></i>@TempData["Error"]
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
</div>
}
<div class="row g-4">
<!-- Left Column -->
<div class="col-lg-4">
<!-- Asset Details Card -->
<div class="card border-0 shadow-sm mb-4">
<div class="card-header bg-white border-0 py-3">
<h5 class="mb-0 fw-semibold">
<i class="bi bi-building-gear me-2 text-primary"></i>@Model.Name
</h5>
</div>
<div class="card-body">
@if (!string.IsNullOrWhiteSpace(Model.Description))
{
<p class="text-muted">@Model.Description</p>
}
<div class="mb-3">
@if (Model.IsDisposed)
{
<span class="badge bg-secondary fs-6">Disposed</span>
@if (Model.DisposalDate.HasValue)
{
<div class="text-muted small mt-1">Disposed @Model.DisposalDate.Value.ToLocalTime().ToString("MM/dd/yyyy")</div>
}
}
else if (fullyDeprec)
{
<span class="badge bg-light text-dark border fs-6">Fully Depreciated</span>
}
else
{
<span class="badge bg-success fs-6">Active</span>
<div class="text-muted small mt-1">@monthsRemaining month@(monthsRemaining == 1 ? "" : "s") remaining</div>
}
</div>
<table class="table table-sm table-borderless mb-0">
<tr>
<td class="text-muted ps-0">Purchase Date</td>
<td class="text-end fw-semibold">@Model.PurchaseDate.ToLocalTime().ToString("MM/dd/yyyy")</td>
</tr>
<tr>
<td class="text-muted ps-0">Purchase Cost</td>
<td class="text-end fw-semibold">@Model.PurchaseCost.ToString("C")</td>
</tr>
<tr>
<td class="text-muted ps-0">Salvage Value</td>
<td class="text-end">@Model.SalvageValue.ToString("C")</td>
</tr>
<tr>
<td class="text-muted ps-0">Useful Life</td>
<td class="text-end">@Model.UsefulLifeMonths months</td>
</tr>
<tr>
<td class="text-muted ps-0">Monthly Depreciation</td>
<td class="text-end">@Model.MonthlyDepreciation.ToString("C")</td>
</tr>
</table>
</div>
</div>
<!-- Book Value Card -->
<div class="card border-0 shadow-sm mb-4">
<div class="card-header bg-white border-0 py-3">
<h5 class="mb-0 fw-semibold"><i class="bi bi-bar-chart me-2 text-primary"></i>Book Value</h5>
</div>
<div class="card-body">
<div class="d-flex justify-content-between mb-1">
<span class="text-muted">Accumulated Depreciation</span>
<span class="text-danger fw-semibold">@Model.AccumulatedDepreciation.ToString("C")</span>
</div>
<div class="progress mb-3" style="height:8px;">
<div class="progress-bar bg-danger" style="width: @progress.ToString("F1")%"></div>
</div>
<div class="d-flex justify-content-between border-top pt-2">
<span class="fw-semibold">Book Value</span>
<span class="fw-bold fs-5 @(Model.BookValue <= 0 ? "text-muted" : "text-success")">@Model.BookValue.ToString("C")</span>
</div>
</div>
</div>
<!-- GL Accounts Card -->
@if (Model.AssetAccount != null || Model.DepreciationExpenseAccount != null || Model.AccumDepreciationAccount != null)
{
<div class="card border-0 shadow-sm">
<div class="card-header bg-white border-0 py-3">
<h5 class="mb-0 fw-semibold"><i class="bi bi-diagram-3 me-2 text-primary"></i>GL Accounts</h5>
</div>
<div class="card-body">
@if (Model.AssetAccount != null)
{
<div class="mb-2">
<div class="text-muted small">Asset Account</div>
<div class="fw-semibold">@Model.AssetAccount.AccountNumber @Model.AssetAccount.Name</div>
</div>
}
@if (Model.DepreciationExpenseAccount != null)
{
<div class="mb-2">
<div class="text-muted small">Depreciation Expense</div>
<div class="fw-semibold">@Model.DepreciationExpenseAccount.AccountNumber @Model.DepreciationExpenseAccount.Name</div>
</div>
}
@if (Model.AccumDepreciationAccount != null)
{
<div>
<div class="text-muted small">Accumulated Depreciation</div>
<div class="fw-semibold">@Model.AccumDepreciationAccount.AccountNumber @Model.AccumDepreciationAccount.Name</div>
</div>
}
</div>
</div>
}
</div>
<!-- Right Column: Depreciation History -->
<div class="col-lg-8">
<div class="card border-0 shadow-sm">
<div class="card-header bg-white border-0 py-3 d-flex justify-content-between align-items-center">
<h5 class="mb-0 fw-semibold"><i class="bi bi-clock-history me-2 text-primary"></i>Depreciation History</h5>
<span class="badge bg-light text-dark border">@entries.Count period@(entries.Count == 1 ? "" : "s") posted</span>
</div>
<div class="card-body p-0">
@if (!entries.Any())
{
<div class="text-center text-muted py-5">
<i class="bi bi-calendar-x display-4 d-block mb-3 opacity-25"></i>
<p>No depreciation posted yet. Use the <strong>Post Monthly Depreciation</strong> button on the <a asp-action="Index">Asset Register</a>.</p>
</div>
}
else
{
<div class="table-responsive">
<table class="table table-hover align-middle mb-0">
<thead class="table-light">
<tr>
<th>Period</th>
<th class="text-end">Amount</th>
<th>Journal Entry</th>
<th>Posted</th>
</tr>
</thead>
<tbody>
@foreach (var e in entries)
{
<tr>
<td>@(new DateTime(e.PeriodYear, e.PeriodMonth, 1).ToString("MMMM yyyy"))</td>
<td class="text-end text-danger">@e.Amount.ToString("C")</td>
<td>
@if (e.JournalEntry != null)
{
<a asp-controller="JournalEntries" asp-action="Details" asp-route-id="@e.JournalEntryId">
@e.JournalEntry.EntryNumber
</a>
}
else
{
<span class="text-muted">—</span>
}
</td>
<td class="text-muted small">@e.CreatedAt.ToLocalTime().ToString("MM/dd/yyyy")</td>
</tr>
}
</tbody>
</table>
</div>
}
</div>
</div>
</div>
</div>