store journals payroll.taxes_remitted; viewer tests for the numbers mutation found unchecked
check / check (push) Canceled after 0s
check / check (push) Canceled after 0s
A payroll tax remittance was journaled as a plain entry, so the viewer labeled it "Journal entry" and, at a 0.00 threshold, flagged it as missing a receipt (the server posts it without one, like a payroll run). The store now names it with payroll.taxes_remitted, as it names runs with payroll.run; replay and the projection pass over it, and the viewer's journal page describes it. tests/view_model.rs: the cash history is never empty when cash moved and ends on the last day it did; the prior month runs to the same day; burn averages over only the months the books cover, half away from zero; cash accounts found by name when the settings name none; card accounts; each entry's accounts debits first, once each; only what arrived since the last refresh is fresh; integrity counts files again without rereading them; the invoice's customer, the bill payment's vendor, payroll and remittance origins. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GWVo7x3UHw5kwCUaWxiejX
This commit is contained in:
1 parent
f0fc725ca2
commit
c1f92ed3e8
5 files changed
+341
-1
No files matched your search
@@ -1755,6 +1755,17 @@ impl Store {
|
||||
"lines": plan.iter().map(|(a, s, m)| plain_line_json(*a, *s, *m)).collect::<Vec<_>>(),
|
||||
}),
|
||||
)?);
|
||||
// Name the entry as a remittance, as payroll.run names a run's
|
||||
// (readers like the viewer tell it from a hand-made entry by this).
|
||||
let total: Decimal = plan
|
||||
.iter()
|
||||
.filter(|(_, s, _)| *s == Side::Debit)
|
||||
.map(|(_, _, m)| m.amount)
|
||||
.sum();
|
||||
journaled.push(self.append_journal(
|
||||
"payroll.taxes_remitted",
|
||||
json!({"entry_id": entry_id, "date": date.to_string(), "total": total.to_string()}),
|
||||
)?);
|
||||
let live = self.ledger.remit_payroll_taxes(date, cash_account)?;
|
||||
debug_assert_eq!(live, entry_id, "id allocator diverged from journal");
|
||||
for line in &journaled {
|
||||
@@ -3294,6 +3305,10 @@ pub(crate) fn replay_line_into_ledger(
|
||||
| "attachment.withdrawn" => {
|
||||
// Not accounting state; the projection records them.
|
||||
}
|
||||
"payroll.taxes_remitted" => {
|
||||
// Names the remittance entry (rebuilt by the entry events just
|
||||
// before it) for readers; no ledger state of its own.
|
||||
}
|
||||
"asset.registered" => {
|
||||
let want = get_u64(p, "id")?;
|
||||
let got = ledger.register_asset(NewAsset {
|
||||
@@ -3758,6 +3773,9 @@ fn apply_line_rows(conn: &Connection, line: &JournalLine) -> Result<(), StoreErr
|
||||
)?;
|
||||
}
|
||||
}
|
||||
"payroll.taxes_remitted" => {
|
||||
// The entry was projected by its own events; this only names it.
|
||||
}
|
||||
"receipt.attached" | "document.filed" => {
|
||||
conn.execute(
|
||||
"INSERT OR IGNORE INTO blobs(sha256, size_bytes, mime_type, original_name, created_at) VALUES (?,?,?,?,?)",
|
||||
|
||||
Reference in new issue
Block a user