File Cabinet MVP: case detail with inline Ledger CRUD

- Extend Transaction with ledger fields (item_no, employee_number, t_code, t_type_l, quantity, rate, billed)
- Startup SQLite migration to add missing columns on transactions
- Ledger create/update/delete endpoints with validations and auto-compute Amount = Quantity × Rate
- Uniqueness: ensure (transaction_date, item_no) per case by auto-incrementing
- Compute case totals (billed/unbilled/overall) and display in case view
- Update case.html for master-detail ledger UI; add client-side auto-compute JS
- Enhance import_ledger_data to populate extended fields
- Close/Reopen actions retained; case detail sorting by date/item
- Auth: switch to pbkdf2_sha256 default (bcrypt fallback) and seed admin robustness

Tested in Docker: health OK, login OK, import ROLODEX/FILES OK, ledger create persisted and totals displayed.
This commit is contained in:
HotSwapp
2025-10-07 09:26:58 -05:00
parent f9c3b3cc9c
commit 950d261eb4
13 changed files with 496 additions and 19 deletions

View File

@@ -50,6 +50,24 @@ document.addEventListener('DOMContentLoaded', function() {
}
});
});
// Auto-compute Amount = Quantity × Rate in ledger add form
var qtyInput = document.querySelector('form[action*="/ledger"] .js-qty');
var rateInput = document.querySelector('form[action*="/ledger"] .js-rate');
var amountInput = document.querySelector('form[action*="/ledger"] .js-amount');
function recomputeAmount() {
if (!qtyInput || !rateInput || !amountInput) return;
var q = parseFloat(qtyInput.value);
var r = parseFloat(rateInput.value);
if (!isNaN(q) && !isNaN(r)) {
var amt = (q * r);
amountInput.value = amt.toFixed(2);
}
}
if (qtyInput) qtyInput.addEventListener('input', recomputeAmount);
if (rateInput) rateInput.addEventListener('input', recomputeAmount);
});
// Utility functions