viewer: drop parties' bill arms (the ledger tags bill entries with their vendor, which wins); burn tests for one covered month and breaking even
check / check (push) Waiting to run

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GWVo7x3UHw5kwCUaWxiejX
This commit is contained in:
swaitsandClaude Opus 5.5 committed 2026-10-14 19:00:47 -06:00
1 parent 7a6cc154ae
commit ca3a279219
2 files changed
+50 -13

No files matched your search

+3 -12
View File
@@ -489,18 +489,15 @@ impl Books {
}
}
/// Customer or vendor names for entries created by invoices and bills and
/// their payments, from the journal.
/// Customer names for entries created by invoices and their payments,
/// from the journal. (Bills and bill payments need nothing here: the
/// ledger tags their entries with the vendor, which takes precedence.)
fn parties(ledger: &Ledger, journal: &[JournalLine]) -> HashMap<EntryId, String> {
let mut out = HashMap::new();
let customer = |id: Option<u64>| {
id.and_then(|c| ledger.get_customer(c))
.map(|c| c.name.clone())
};
let vendor = |id: Option<u64>| {
id.and_then(|v| ledger.get_vendor(v))
.map(|v| v.name.clone())
};
let u = |p: &Value, k: &str| p.get(k).and_then(|v| v.as_u64());
for line in journal {
let p = &line.payload;
@@ -514,12 +511,6 @@ fn parties(ledger: &Ledger, journal: &[JournalLine]) -> HashMap<EntryId, String>
.and_then(|i| ledger.get_invoice(i))
.map(|i| i.customer_id),
),
"bill.created" => vendor(u(p, "vendor_id")),
"bill.paid" => vendor(
u(p, "bill_id")
.and_then(|b| ledger.get_bill(b))
.map(|b| b.vendor_id),
),
_ => None,
};
if let Some(n) = name {
+47 -1
View File
@@ -430,7 +430,53 @@ fn comparisons_and_burn_on_fixed_dates() {
let b3 = data::load_once(&source(&d3, "", today)).unwrap();
// 10.00 / 3 = 3.333... -> 3.33
assert_eq!(b3.kpis.monthly_burn, Some(Decimal::new(333, 2)));
for x in [d, d2, d3] {
// Books covering only last month: one month, not two.
let (d4, mut s4) = store_at("burn-one");
let c4 = s4
.add_account("1000", "Checking", AccountType::Asset, None, false)
.unwrap();
let e4 = s4
.add_account("6000", "Rent", AccountType::Expense, None, false)
.unwrap();
post(
&mut s4,
NaiveDate::from_ymd_opt(2026, 4, 20).unwrap(),
e4,
c4,
9_000,
);
drop(s4);
let b4 = data::load_once(&source(&d4, "", today)).unwrap();
assert_eq!(b4.kpis.monthly_burn, Some(Decimal::new(9_000, 2)));
// Breaking even burns nothing.
let (d5, mut s5) = store_at("burn-even");
let c5 = s5
.add_account("1000", "Checking", AccountType::Asset, None, false)
.unwrap();
let r5 = s5
.add_account("4000", "Sales", AccountType::Revenue, None, false)
.unwrap();
let e5 = s5
.add_account("6000", "Rent", AccountType::Expense, None, false)
.unwrap();
post(
&mut s5,
NaiveDate::from_ymd_opt(2026, 3, 5).unwrap(),
e5,
c5,
4_000,
);
post(
&mut s5,
NaiveDate::from_ymd_opt(2026, 3, 6).unwrap(),
c5,
r5,
4_000,
);
drop(s5);
let b5 = data::load_once(&source(&d5, "", today)).unwrap();
assert_eq!(b5.kpis.monthly_burn, None);
for x in [d, d2, d3, d4, d5] {
let _ = std::fs::remove_dir_all(x);
}
}