Invoice create: show discount row in totals, allow negative line items

- Add "Discount Applied" display row (red, hidden when zero) between subtotal
  and tax so users can see the discount being deducted at a glance
- Remove min="0" from UnitPrice and TotalPrice inputs (server-rendered and JS
  template) so negative adjustment lines can be entered without form rejection

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-16 11:41:47 -04:00
parent b2d6fae400
commit 27aa4e0ea6
@@ -283,13 +283,13 @@
<td class="text-end"> <td class="text-end">
<input type="number" name="InvoiceItems[@i].UnitPrice" <input type="number" name="InvoiceItems[@i].UnitPrice"
class="form-control form-control-sm text-end unit-price-input" class="form-control form-control-sm text-end unit-price-input"
value="@item.UnitPrice.ToString("F2")" min="0" step="0.01" value="@item.UnitPrice.ToString("F2")" step="0.01"
onchange="recalcRow(this)" oninput="recalcRow(this)" /> onchange="recalcRow(this)" oninput="recalcRow(this)" />
</td> </td>
<td class="text-end"> <td class="text-end">
<input type="number" name="InvoiceItems[@i].TotalPrice" <input type="number" name="InvoiceItems[@i].TotalPrice"
class="form-control form-control-sm text-end total-price-input" class="form-control form-control-sm text-end total-price-input"
value="@item.TotalPrice.ToString("F2")" min="0" step="0.01" value="@item.TotalPrice.ToString("F2")" step="0.01"
oninput="recalcTotals()" /> oninput="recalcTotals()" />
</td> </td>
<td class="text-center"> <td class="text-center">
@@ -371,6 +371,10 @@
<input asp-for="DiscountAmount" type="number" class="form-control form-control-sm text-end" <input asp-for="DiscountAmount" type="number" class="form-control form-control-sm text-end"
min="0" step="0.01" oninput="recalcTotals()" /> min="0" step="0.01" oninput="recalcTotals()" />
</div> </div>
<div id="discountRow" class="d-flex justify-content-between mb-1 d-none">
<span class="text-muted small">Discount Applied</span>
<span id="displayDiscount" class="small text-danger">&minus;$0.00</span>
</div>
<div class="mb-2"> <div class="mb-2">
<div class="d-flex justify-content-between align-items-center mb-1"> <div class="d-flex justify-content-between align-items-center mb-1">
<label class="form-label mb-0 text-muted">Tax (%)</label> <label class="form-label mb-0 text-muted">Tax (%)</label>
@@ -725,13 +729,13 @@
<td class="text-end"> <td class="text-end">
<input type="number" name="InvoiceItems[${idx}].UnitPrice" <input type="number" name="InvoiceItems[${idx}].UnitPrice"
class="form-control form-control-sm text-end unit-price-input" class="form-control form-control-sm text-end unit-price-input"
value="${unitPrice.toFixed(2)}" min="0" step="0.01" value="${unitPrice.toFixed(2)}" step="0.01"
onchange="recalcRow(this)" oninput="recalcRow(this)" /> onchange="recalcRow(this)" oninput="recalcRow(this)" />
</td> </td>
<td class="text-end"> <td class="text-end">
<input type="number" name="InvoiceItems[${idx}].TotalPrice" <input type="number" name="InvoiceItems[${idx}].TotalPrice"
class="form-control form-control-sm text-end total-price-input" class="form-control form-control-sm text-end total-price-input"
value="${total}" min="0" step="0.01" value="${total}" step="0.01"
oninput="recalcTotals()" /> oninput="recalcTotals()" />
</td> </td>
<td class="text-center"> <td class="text-center">
@@ -797,6 +801,15 @@
const total = taxableAmount + tax; const total = taxableAmount + tax;
document.getElementById('displaySubtotal').textContent = formatCurrency(subtotal); document.getElementById('displaySubtotal').textContent = formatCurrency(subtotal);
const discountRow = document.getElementById('discountRow');
if (discountRow) {
if (discount > 0) {
document.getElementById('displayDiscount').textContent = '' + formatCurrency(discount);
discountRow.classList.remove('d-none');
} else {
discountRow.classList.add('d-none');
}
}
document.getElementById('displayTax').textContent = formatCurrency(tax); document.getElementById('displayTax').textContent = formatCurrency(tax);
document.getElementById('displayTotal').textContent = formatCurrency(total); document.getElementById('displayTotal').textContent = formatCurrency(total);
} }