Replace literal Unicode special chars with HTML entities across all 233 views
Sweeps em dashes, en dashes, multiplication signs, ellipses, and curly quotes to their HTML entity equivalents (— – × … ‘ ’) in all .cshtml files, skipping <script> blocks. Prevents encoding corruption from AI tools and Windows encoding mismatches that caused recurring symbol bugs. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,235 +0,0 @@
|
||||
@model List<IGrouping<PowderCoating.Core.Enums.AccountType, PowderCoating.Application.DTOs.Accounting.AccountListDto>>
|
||||
@using PowderCoating.Core.Enums
|
||||
|
||||
@{
|
||||
ViewData["Title"] = "Chart of Accounts";
|
||||
ViewData["PageIcon"] = "bi-journal-bookmark";
|
||||
ViewData["PageHelpTitle"] = "Chart of Accounts";
|
||||
ViewData["PageHelpContent"] = "The master list of financial accounts grouped by type: Asset (what you own), Liability (what you owe), Equity (owner's stake), Revenue (income), Cost of Goods Sold (direct costs), Expense (overhead). Click any row to view its ledger. System accounts (sys badge) cannot be deleted. Recalculate Balances recomputes every account's balance from transaction history.";
|
||||
|
||||
string TypeIcon(AccountType t) => t switch
|
||||
{
|
||||
AccountType.Asset => "bi-safe",
|
||||
AccountType.Liability => "bi-credit-card",
|
||||
AccountType.Equity => "bi-bar-chart-line",
|
||||
AccountType.Revenue => "bi-graph-up-arrow",
|
||||
AccountType.CostOfGoods => "bi-box-seam",
|
||||
AccountType.Expense => "bi-receipt-cutoff",
|
||||
_ => "bi-journal"
|
||||
};
|
||||
|
||||
string TypeColor(AccountType t) => t switch
|
||||
{
|
||||
AccountType.Asset => "success",
|
||||
AccountType.Liability => "danger",
|
||||
AccountType.Equity => "primary",
|
||||
AccountType.Revenue => "info",
|
||||
AccountType.CostOfGoods => "warning",
|
||||
AccountType.Expense => "secondary",
|
||||
_ => "secondary"
|
||||
};
|
||||
|
||||
string TypeLabel(AccountType t) => t switch
|
||||
{
|
||||
AccountType.CostOfGoods => "Cost of Goods Sold",
|
||||
_ => t.ToString()
|
||||
};
|
||||
}
|
||||
|
||||
<div class="d-flex justify-content-end mb-4">
|
||||
<div class="d-flex gap-2">
|
||||
<form asp-action="FixOpeningBalanceSigns" method="post"
|
||||
onsubmit="return confirm('Fix opening balance signs for Revenue, Liability, and Equity accounts imported from QuickBooks? This corrects negative balances caused by QB\'s sign convention.')">
|
||||
@Html.AntiForgeryToken()
|
||||
<button type="submit" class="btn btn-outline-warning"
|
||||
title="Fixes negative opening balances on Revenue/Liability/Equity accounts imported from QuickBooks IIF">
|
||||
<i class="bi bi-sign-stop me-1"></i>Fix QB Import Signs
|
||||
</button>
|
||||
</form>
|
||||
<form id="recalcBalancesForm" asp-action="RecalculateBalances" method="post">
|
||||
@Html.AntiForgeryToken()
|
||||
<button type="button" id="btnRecalcBalances" class="btn btn-outline-secondary"
|
||||
title="Recompute CurrentBalance for all accounts from ledger transactions">
|
||||
<i class="bi bi-arrow-repeat me-1"></i>Recalculate Balances
|
||||
</button>
|
||||
</form>
|
||||
<a asp-action="Create" class="btn btn-primary">
|
||||
<i class="bi bi-plus-lg me-1"></i>New Account
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@* Bootstrap toast — confirmation before recalculating balances *@
|
||||
<div class="toast-container position-fixed top-50 start-50 translate-middle p-3" style="z-index:1100">
|
||||
<div id="recalcConfirmToast" class="toast align-items-center border-0 bg-dark text-white" role="alert" aria-atomic="true" data-bs-autohide="false">
|
||||
<div class="toast-body d-flex flex-column gap-2 py-3 px-3">
|
||||
<div class="d-flex align-items-center gap-2">
|
||||
<i class="bi bi-arrow-repeat fs-5 text-warning"></i>
|
||||
<span class="fw-semibold">Recalculate all account balances?</span>
|
||||
</div>
|
||||
<p class="mb-1 small text-white-50">This will recompute every account's balance from transaction history. The page will reload when done.</p>
|
||||
<div class="d-flex gap-2">
|
||||
<button id="btnRecalcConfirm" type="button" class="btn btn-warning btn-sm fw-semibold">
|
||||
<i class="bi bi-check-lg me-1"></i>Yes, recalculate
|
||||
</button>
|
||||
<button type="button" class="btn btn-outline-light btn-sm" data-bs-dismiss="toast">Cancel</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@if (TempData["Success"] != null)
|
||||
{
|
||||
<div class="alert alert-success 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-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>
|
||||
}
|
||||
|
||||
@if (!Model.Any())
|
||||
{
|
||||
<div class="card shadow-sm border-0">
|
||||
<div class="card-body text-center py-5">
|
||||
<i class="bi bi-journal-bookmark display-4 text-muted mb-3 d-block"></i>
|
||||
<h5 class="mb-2">No accounts set up yet</h5>
|
||||
<p class="text-muted mb-4">Get started quickly by loading a standard chart of accounts<br>tailored for a powder coating business.</p>
|
||||
<form asp-action="SeedDefaultAccounts" method="post">
|
||||
@Html.AntiForgeryToken()
|
||||
<button type="submit" class="btn btn-primary">
|
||||
<i class="bi bi-magic me-1"></i>Create Default Accounts
|
||||
</button>
|
||||
<a asp-action="Create" class="btn btn-outline-secondary ms-2">
|
||||
<i class="bi bi-plus-lg me-1"></i>Add Manually
|
||||
</a>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
@foreach (var group in Model)
|
||||
{
|
||||
var color = TypeColor(group.Key);
|
||||
var icon = TypeIcon(group.Key);
|
||||
var label = TypeLabel(group.Key);
|
||||
|
||||
<div class="card shadow-sm mb-4">
|
||||
<div class="card-header bg-@color bg-opacity-10 border-@color border-opacity-25">
|
||||
<div class="d-flex align-items-center gap-2">
|
||||
<i class="bi @icon text-@color fs-5"></i>
|
||||
<h6 class="mb-0 fw-semibold text-@color">@label</h6>
|
||||
<span class="badge bg-@color ms-auto">@group.Count() accounts</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body p-0">
|
||||
<table class="table table-hover table-sm mb-0">
|
||||
<thead class="table-light">
|
||||
<tr>
|
||||
<th style="width:110px">Number</th>
|
||||
<th>Name</th>
|
||||
<th>Sub-Type</th>
|
||||
<th>Parent</th>
|
||||
<th style="width:80px">Status</th>
|
||||
<th style="width:120px" class="text-end">Balance</th>
|
||||
<th style="width:150px" class="text-end">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (var acct in group.OrderBy(a => a.AccountNumber))
|
||||
{
|
||||
<tr class="@(acct.IsActive ? "" : "text-muted opacity-75") table-row-link"
|
||||
data-href="@Url.Action("Ledger", new { id = acct.Id })"
|
||||
style="cursor:pointer">
|
||||
<td>
|
||||
<code class="text-@color">@acct.AccountNumber</code>
|
||||
</td>
|
||||
<td>
|
||||
<span class="fw-medium">@acct.Name</span>
|
||||
@if (acct.IsSystem)
|
||||
{
|
||||
<span class="badge bg-secondary ms-1" title="System account — cannot be deleted">sys</span>
|
||||
}
|
||||
</td>
|
||||
<td><span class="text-muted small">@acct.AccountSubType.ToDisplayName()</span></td>
|
||||
<td>
|
||||
@if (!string.IsNullOrEmpty(acct.ParentAccountName))
|
||||
{
|
||||
<span class="text-muted small">@acct.ParentAccountName</span>
|
||||
}
|
||||
</td>
|
||||
<td>
|
||||
@if (acct.IsActive)
|
||||
{
|
||||
<span class="badge bg-success-subtle text-success">Active</span>
|
||||
}
|
||||
else
|
||||
{
|
||||
<span class="badge bg-secondary-subtle text-secondary">Inactive</span>
|
||||
}
|
||||
</td>
|
||||
<td class="text-end text-nowrap fw-medium @(acct.CurrentBalance >= 0 ? "text-success" : "text-danger")">
|
||||
@acct.CurrentBalance.ToString("C")
|
||||
</td>
|
||||
<td class="text-end text-nowrap">
|
||||
<a asp-action="Ledger" asp-route-id="@acct.Id" class="btn btn-sm btn-outline-secondary me-1" title="View Ledger">
|
||||
<i class="bi bi-journal-text"></i>
|
||||
</a>
|
||||
<a asp-action="Edit" asp-route-id="@acct.Id" class="btn btn-sm btn-outline-primary me-1" title="Edit">
|
||||
<i class="bi bi-pencil"></i>
|
||||
</a>
|
||||
@if (!acct.IsSystem)
|
||||
{
|
||||
<form asp-action="Delete" asp-route-id="@acct.Id" method="post" class="d-inline"
|
||||
onsubmit="return confirm('Delete account @acct.AccountNumber – @acct.Name?')">
|
||||
@Html.AntiForgeryToken()
|
||||
<button type="submit" class="btn btn-sm btn-outline-danger" title="Delete">
|
||||
<i class="bi bi-trash"></i>
|
||||
</button>
|
||||
</form>
|
||||
}
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
@if (!Model.Any())
|
||||
{
|
||||
<div class="text-center py-5">
|
||||
<i class="bi bi-journal-x display-3 text-muted"></i>
|
||||
<p class="mt-3 text-muted">No accounts found. Use the Seed Data page to generate default accounts.</p>
|
||||
</div>
|
||||
}
|
||||
|
||||
@section Scripts {
|
||||
<script>
|
||||
document.querySelectorAll('tr.table-row-link').forEach(row => {
|
||||
row.addEventListener('click', e => {
|
||||
if (e.target.closest('a, button, form')) return;
|
||||
window.location.href = row.dataset.href;
|
||||
});
|
||||
});
|
||||
|
||||
// Recalculate Balances — show confirmation toast instead of native confirm()
|
||||
const recalcToast = new bootstrap.Toast(document.getElementById('recalcConfirmToast'));
|
||||
|
||||
document.getElementById('btnRecalcBalances').addEventListener('click', () => {
|
||||
recalcToast.show();
|
||||
});
|
||||
|
||||
document.getElementById('btnRecalcConfirm').addEventListener('click', () => {
|
||||
recalcToast.hide();
|
||||
document.getElementById('recalcBalancesForm').submit();
|
||||
});
|
||||
</script>
|
||||
}
|
||||
|
||||
|
||||
@@ -1,284 +0,0 @@
|
||||
@model PowderCoating.Application.DTOs.Accounting.AccountLedgerDto
|
||||
@using PowderCoating.Core.Enums
|
||||
|
||||
@{
|
||||
ViewData["Title"] = $"Ledger — {Model.AccountNumber} {Model.Name}";
|
||||
ViewData["PageIcon"] = "bi-journal-text";
|
||||
ViewData["PageHelpTitle"] = "Account Ledger";
|
||||
ViewData["PageHelpContent"] = "A chronological list of every transaction posted to this account. Click any Reference to open the source record. Debit increases asset and expense accounts; credit increases liability, equity, and revenue accounts. Use the date range or quick buttons (This Month, YTD, etc.) to narrow the view.";
|
||||
|
||||
string typeColor = Model.AccountType switch
|
||||
{
|
||||
AccountType.Asset => "success",
|
||||
AccountType.Liability => "danger",
|
||||
AccountType.Equity => "primary",
|
||||
AccountType.Revenue => "info",
|
||||
AccountType.CostOfGoods => "warning",
|
||||
AccountType.Expense => "secondary",
|
||||
_ => "secondary"
|
||||
};
|
||||
|
||||
string typeIcon = Model.AccountType switch
|
||||
{
|
||||
AccountType.Asset => "bi-safe",
|
||||
AccountType.Liability => "bi-credit-card",
|
||||
AccountType.Equity => "bi-bar-chart-line",
|
||||
AccountType.Revenue => "bi-graph-up-arrow",
|
||||
AccountType.CostOfGoods => "bi-box-seam",
|
||||
AccountType.Expense => "bi-receipt-cutoff",
|
||||
_ => "bi-journal"
|
||||
};
|
||||
|
||||
string typeLabel = Model.AccountType.ToDisplayName();
|
||||
|
||||
// Derive from AccountSubType (more reliable than AccountType which users can misconfigure)
|
||||
bool normalDebitBalance =
|
||||
Model.AccountSubType == AccountSubType.Cash ||
|
||||
Model.AccountSubType == AccountSubType.Checking ||
|
||||
Model.AccountSubType == AccountSubType.Savings ||
|
||||
Model.AccountSubType == AccountSubType.AccountsReceivable ||
|
||||
Model.AccountSubType == AccountSubType.Inventory ||
|
||||
Model.AccountSubType == AccountSubType.FixedAsset ||
|
||||
Model.AccountSubType == AccountSubType.OtherCurrentAsset ||
|
||||
Model.AccountSubType == AccountSubType.OtherAsset ||
|
||||
Model.AccountSubType == AccountSubType.CostOfGoodsSold ||
|
||||
(int)Model.AccountSubType >= 50; // all Expense subtypes
|
||||
|
||||
string balanceLabel = normalDebitBalance ? "Debit Balance" : "Credit Balance";
|
||||
|
||||
// Quick-range helpers for the filter bar
|
||||
var today = DateTime.Today;
|
||||
var thisMonthFrom = new DateTime(today.Year, today.Month, 1).ToString("yyyy-MM-dd");
|
||||
var thisMonthTo = today.ToString("yyyy-MM-dd");
|
||||
var lastMonthFrom = new DateTime(today.Year, today.Month, 1).AddMonths(-1).ToString("yyyy-MM-dd");
|
||||
var lastMonthTo = new DateTime(today.Year, today.Month, 1).AddDays(-1).ToString("yyyy-MM-dd");
|
||||
var qtdFrom = new DateTime(today.Year, ((today.Month - 1) / 3) * 3 + 1, 1).ToString("yyyy-MM-dd");
|
||||
var ytdFrom = new DateTime(today.Year, 1, 1).ToString("yyyy-MM-dd");
|
||||
}
|
||||
|
||||
<!-- Breadcrumb -->
|
||||
<nav aria-label="breadcrumb" class="mb-3">
|
||||
<ol class="breadcrumb">
|
||||
<li class="breadcrumb-item"><a asp-action="Index">Chart of Accounts</a></li>
|
||||
<li class="breadcrumb-item active">@Model.AccountNumber – @Model.Name</li>
|
||||
</ol>
|
||||
</nav>
|
||||
|
||||
<!-- Account header -->
|
||||
<div class="d-flex align-items-center gap-3 mb-4">
|
||||
<div class="rounded-3 p-3 bg-@typeColor bg-opacity-10 text-@typeColor">
|
||||
<i class="bi @typeIcon fs-3"></i>
|
||||
</div>
|
||||
<div>
|
||||
<p class="text-muted mb-0">
|
||||
<span class="badge bg-@typeColor bg-opacity-75 me-1">@typeLabel</span>
|
||||
<span class="text-muted small">@Model.AccountSubType.ToDisplayName() · @balanceLabel</span>
|
||||
</p>
|
||||
</div>
|
||||
<div class="ms-auto">
|
||||
<a asp-action="Edit" asp-route-id="@Model.Id" class="btn btn-sm btn-outline-secondary">
|
||||
<i class="bi bi-pencil me-1"></i>Edit Account
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Date range filter -->
|
||||
<div class="card shadow-sm mb-4">
|
||||
<div class="card-body py-3">
|
||||
<form method="get" class="row g-2 align-items-end">
|
||||
<input type="hidden" name="id" value="@Model.Id" />
|
||||
<div class="col-auto">
|
||||
<label class="form-label form-label-sm mb-1">From</label>
|
||||
<input type="date" name="from" class="form-control form-control-sm" value="@Model.From.ToString("yyyy-MM-dd")" />
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<label class="form-label form-label-sm mb-1">To</label>
|
||||
<input type="date" name="to" class="form-control form-control-sm" value="@Model.To.ToString("yyyy-MM-dd")" />
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<button type="submit" class="btn btn-primary btn-sm">
|
||||
<i class="bi bi-funnel me-1"></i>Filter
|
||||
</button>
|
||||
</div>
|
||||
<div class="col-auto ms-2">
|
||||
<div class="btn-group btn-group-sm" role="group">
|
||||
<a href="@Url.Action("Ledger", new { id = Model.Id, from = thisMonthFrom, to = thisMonthTo })"
|
||||
class="btn btn-outline-secondary">This Month</a>
|
||||
<a href="@Url.Action("Ledger", new { id = Model.Id, from = lastMonthFrom, to = lastMonthTo })"
|
||||
class="btn btn-outline-secondary">Last Month</a>
|
||||
<a href="@Url.Action("Ledger", new { id = Model.Id, from = qtdFrom, to = thisMonthTo })"
|
||||
class="btn btn-outline-secondary">QTD</a>
|
||||
<a href="@Url.Action("Ledger", new { id = Model.Id, from = ytdFrom, to = thisMonthTo })"
|
||||
class="btn btn-outline-secondary">YTD</a>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Summary cards -->
|
||||
<div class="row g-3 mb-4">
|
||||
<div class="col-6 col-md-3">
|
||||
<div class="card shadow-sm h-100 text-center">
|
||||
<div class="card-body py-3">
|
||||
<div class="h5 text-muted mb-1">@Model.OpeningBalance.ToString("C")</div>
|
||||
<div class="text-muted small">Opening Balance</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6 col-md-3">
|
||||
<div class="card shadow-sm h-100 text-center">
|
||||
<div class="card-body py-3">
|
||||
@{
|
||||
var netChange = normalDebitBalance
|
||||
? Model.PeriodDebits - Model.PeriodCredits
|
||||
: Model.PeriodCredits - Model.PeriodDebits;
|
||||
var netColor = netChange >= 0 ? "success" : "danger";
|
||||
}
|
||||
<div class="h5 text-@netColor mb-1">@netChange.ToString("C")</div>
|
||||
<div class="text-muted small">Period Net Change</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6 col-md-3">
|
||||
<div class="card shadow-sm h-100 text-center">
|
||||
<div class="card-body py-3">
|
||||
<div class="h5 text-success mb-1">@Model.PeriodDebits.ToString("C")</div>
|
||||
<div class="text-muted small">Total Debits</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6 col-md-3">
|
||||
<div class="card shadow-sm h-100 text-center border-@typeColor border-opacity-50">
|
||||
<div class="card-body py-3">
|
||||
<div class="h5 fw-bold text-@typeColor mb-1">@Model.ClosingBalance.ToString("C")</div>
|
||||
<div class="text-muted small">Closing @balanceLabel</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Ledger table -->
|
||||
<div class="card shadow-sm">
|
||||
<div class="card-header d-flex align-items-center justify-content-between">
|
||||
<div class="d-flex align-items-center gap-2">
|
||||
<span class="fw-semibold">
|
||||
<i class="bi bi-journal-text me-1"></i>
|
||||
Transactions
|
||||
<span class="text-muted fw-normal small ms-1">
|
||||
@Model.From.ToString("MMM d") – @Model.To.ToString("MMM d, yyyy")
|
||||
</span>
|
||||
</span>
|
||||
<a tabindex="0" class="help-icon" role="button"
|
||||
data-bs-toggle="popover" data-bs-placement="right" data-bs-trigger="focus"
|
||||
data-bs-title="Transaction Ledger"
|
||||
data-bs-content="Each row is one side of a double-entry posting. Reference links back to the source record (invoice, bill, expense, or payment). Debit and Credit show which side of the entry hit this account. Running Balance updates after each line. The Opening Balance row shows the balance brought forward from before the selected date range.">
|
||||
<i class="bi bi-question-circle"></i>
|
||||
</a>
|
||||
</div>
|
||||
<span class="badge bg-secondary">@Model.Entries.Count entries</span>
|
||||
</div>
|
||||
|
||||
@if (!Model.Entries.Any())
|
||||
{
|
||||
<div class="card-body text-center py-5 text-muted">
|
||||
<i class="bi bi-journal-x fs-1 d-block mb-2"></i>
|
||||
<p class="mb-0">No transactions found for this account in the selected period.</p>
|
||||
</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover table-sm align-middle mb-0">
|
||||
<thead class="table-light">
|
||||
<tr>
|
||||
<th style="width:105px">Date</th>
|
||||
<th style="width:160px">Reference</th>
|
||||
<th style="width:140px">Source</th>
|
||||
<th>Description</th>
|
||||
<th class="text-end" style="width:110px">Debit</th>
|
||||
<th class="text-end" style="width:110px">Credit</th>
|
||||
<th class="text-end" style="width:120px">Balance</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<!-- Opening balance row -->
|
||||
<tr class="table-light">
|
||||
<td class="text-muted small">@Model.From.ToString("MM/dd/yyyy")</td>
|
||||
<td><span class="fw-medium text-muted">—</span></td>
|
||||
<td><span class="badge bg-dark-subtle text-dark">Opening Balance</span></td>
|
||||
<td class="text-muted small">Balance brought forward as of @Model.From.ToString("MMM d, yyyy")</td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td class="text-end">
|
||||
<span class="fw-semibold @(Model.OpeningBalance < 0 ? "text-danger" : "")">
|
||||
@Model.OpeningBalance.ToString("C")
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
@foreach (var entry in Model.Entries)
|
||||
{
|
||||
<tr>
|
||||
<td class="text-muted small">@entry.Date.ToString("MM/dd/yyyy")</td>
|
||||
<td>
|
||||
@if (entry.LinkController != null && entry.LinkId.HasValue)
|
||||
{
|
||||
<a asp-controller="@entry.LinkController" asp-action="Details"
|
||||
asp-route-id="@entry.LinkId" class="text-decoration-none fw-medium">
|
||||
@entry.Reference
|
||||
</a>
|
||||
}
|
||||
else
|
||||
{
|
||||
<span class="fw-medium">@entry.Reference</span>
|
||||
}
|
||||
</td>
|
||||
<td>
|
||||
@{
|
||||
string sourceBadge = entry.Source switch
|
||||
{
|
||||
"Invoice" => "bg-info-subtle text-info",
|
||||
"Invoice Payment" => "bg-success-subtle text-success",
|
||||
"Customer Payment" => "bg-success-subtle text-success",
|
||||
"Bill" => "bg-warning-subtle text-warning",
|
||||
"Bill Payment" => "bg-danger-subtle text-danger",
|
||||
"Expense" => "bg-secondary-subtle text-secondary",
|
||||
"Sales Tax" => "bg-primary-subtle text-primary",
|
||||
_ => "bg-secondary-subtle text-secondary"
|
||||
};
|
||||
}
|
||||
<span class="badge @sourceBadge">@entry.Source</span>
|
||||
</td>
|
||||
<td class="text-muted small">@entry.Description</td>
|
||||
<td class="text-end">
|
||||
@if (entry.Debit > 0)
|
||||
{
|
||||
<span class="text-success fw-medium">@entry.Debit.ToString("C")</span>
|
||||
}
|
||||
</td>
|
||||
<td class="text-end">
|
||||
@if (entry.Credit > 0)
|
||||
{
|
||||
<span class="text-danger fw-medium">@entry.Credit.ToString("C")</span>
|
||||
}
|
||||
</td>
|
||||
<td class="text-end">
|
||||
<span class="fw-semibold @(entry.RunningBalance < 0 ? "text-danger" : "")">
|
||||
@entry.RunningBalance.ToString("C")
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
<tfoot class="table-light fw-semibold">
|
||||
<tr>
|
||||
<td colspan="4" class="text-muted small">Period Totals</td>
|
||||
<td class="text-end text-success">@Model.PeriodDebits.ToString("C")</td>
|
||||
<td class="text-end text-danger">@Model.PeriodCredits.ToString("C")</td>
|
||||
<td class="text-end">@Model.ClosingBalance.ToString("C")</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user