merge: P4b S7, bad debts (branch S7, 4b4fecb9)
The fourth of the paused branches: Ledger::write_off and the bad_debts control role, invoice.written_off with its evidence filed in the same store call, books.write_off_invoice, the write-off on the timeline and in Needs attention, Lean writeOff_within_bounds, rules.md B-41 and the bookspec examples. Twenty-eight files conflicted with the S4.4, S5 and S6 merges; resolved as plan 8.0.2 says, keeping both sides' appends with their seams restored, and: the scope table at 125; S7's law numbered 37; B-41 placed before B-42; the handbook's step 4 and recovery procedures folded into the one invoices-and-bills section; S7's wire tests in their own module with the confirm S4.4's contract needs; S7's copy of the payment steps dropped (S6 replaced them with Ledger::settle) and its write-off journaled through S6's journal_auto_lines; in the old-books fixture S7's hand-written write-off moved to a second invoice, since S6's hand-written payment settles invoice 1 in full. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HS8WZziDnyxunC23MUxrLp
This commit is contained in:
commit
335a3eaa7e
47 files changed
+2883
-74
No files matched your search
@@ -418,6 +418,54 @@ pub fn invoice_sent_of(line: &JournalLine) -> Result<(u64, Sent), StoreError> {
|
||||
))
|
||||
}
|
||||
|
||||
/// A bad-debt write-off as journaled (plan P4b S7; rules.md B-41):
|
||||
/// `invoice.written_off {invoice_id, entry_id, date, amount, reason}`.
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct WrittenOff {
|
||||
/// The invoice written off.
|
||||
pub invoice_id: u64,
|
||||
/// The entry that posted it (already rebuilt from its own events).
|
||||
pub entry_id: u64,
|
||||
/// The write-off's day.
|
||||
pub date: NaiveDate,
|
||||
/// What was written off.
|
||||
pub amount: rust_decimal::Decimal,
|
||||
/// Why (it has no resolution: the evidence is the receipt).
|
||||
pub reason: String,
|
||||
}
|
||||
|
||||
/// `invoice.written_off {invoice_id, entry_id, date, amount, reason}`.
|
||||
pub fn invoice_written_off(
|
||||
invoice_id: u64,
|
||||
entry_id: u64,
|
||||
date: NaiveDate,
|
||||
amount: rust_decimal::Decimal,
|
||||
reason: &str,
|
||||
) -> Value {
|
||||
json!({
|
||||
"invoice_id": invoice_id,
|
||||
"entry_id": entry_id,
|
||||
"date": date.to_string(),
|
||||
"amount": amount.to_string(),
|
||||
"reason": reason,
|
||||
})
|
||||
}
|
||||
|
||||
/// Read an `invoice.written_off` payload.
|
||||
pub fn invoice_written_off_of(p: &Value) -> Result<WrittenOff, StoreError> {
|
||||
const E: &str = "invoice.written_off";
|
||||
let amount = str_of(p, E, "amount")?
|
||||
.parse()
|
||||
.map_err(|_| corrupt(E, "amount"))?;
|
||||
Ok(WrittenOff {
|
||||
invoice_id: u64_of(p, E, "invoice_id")?,
|
||||
entry_id: u64_of(p, E, "entry_id")?,
|
||||
date: date_of(&str_of(p, E, "date")?, E, "date")?,
|
||||
amount,
|
||||
reason: str_of(p, E, "reason")?,
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
Reference in new issue
Block a user