Add Credit Memos standalone management module
CreditMemosController with Index, Details, Create, Apply, and Void actions. All business logic (atomic apply transaction, RemainingBalance cap, customer.CreditBalance adjustment, auto-Paid invoice when BalanceDue hits zero) mirrors the invoice-centric IssueCreditMemo/ApplyCredit/VoidCreditMemo actions in InvoicesController but redirects back to the credit memo rather than an invoice. Views: Index (stats bar, status+search filter, table), Details (two-col layout with application history table and Bootstrap Apply/Void confirm modals), Create (customer dropdown, amount, reason, notes, optional expiry). Apply modal populates amount automatically from min(remaining credit, invoice balance due) via credit-memo.js data-attribute wiring (no inline scripts). Nav: Credit Memos added to Billing & Payments section in _Layout. Build: 0 errors. Unit tests: 200/200. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,30 @@
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
var modal = document.getElementById('applyModal');
|
||||
if (!modal) return;
|
||||
|
||||
var remainingBalance = parseFloat(modal.dataset.remainingBalance || '0');
|
||||
var invoiceSelect = document.getElementById('applyInvoiceId');
|
||||
var amountInput = document.getElementById('applyAmount');
|
||||
var maxHint = document.getElementById('applyMaxHint');
|
||||
|
||||
if (!invoiceSelect) return;
|
||||
|
||||
invoiceSelect.addEventListener('change', function () {
|
||||
var selected = this.options[this.selectedIndex];
|
||||
if (!selected || !selected.value) {
|
||||
amountInput.value = '';
|
||||
if (maxHint) maxHint.textContent = '';
|
||||
return;
|
||||
}
|
||||
|
||||
var invoiceBalance = parseFloat(selected.dataset.balance || '0');
|
||||
var max = Math.min(remainingBalance, invoiceBalance);
|
||||
amountInput.value = max.toFixed(2);
|
||||
amountInput.max = max.toFixed(2);
|
||||
if (maxHint) maxHint.textContent = 'Max applicable: $' + max.toFixed(2);
|
||||
});
|
||||
});
|
||||
})();
|
||||
Reference in New Issue
Block a user