diff --git a/crates/ledger-core/src/error.rs b/crates/ledger-core/src/error.rs index d6eb3be..28212b3 100644 --- a/crates/ledger-core/src/error.rs +++ b/crates/ledger-core/src/error.rs @@ -655,6 +655,15 @@ pub enum LedgerError { )] TermsDiscountNeedsNetDays, + /// `invoicing.first_number` asked to move after a numbered invoice + /// exists: the series has begun, and a number is never reused or + /// renumbered (rules.md B-40, A-2). The store's check lands with the + /// invoice numbers it reads (P4b S4.3). + #[error( + "invoicing.first_number is locked: a numbered invoice already exists, so the series has begun and its numbers are never reused" + )] + FirstNumberLocked, + /// A date computed from another (payment terms' due or discount date) /// falls past the calendar the books keep. #[error( diff --git a/crates/ledger-core/src/ledger.rs b/crates/ledger-core/src/ledger.rs index 2b3b019..4fd384f 100644 --- a/crates/ledger-core/src/ledger.rs +++ b/crates/ledger-core/src/ledger.rs @@ -4702,12 +4702,11 @@ impl Ledger { } } Archived(true) => {} - Email(v) => match v { - Some(e) => { - crate::parties::check_email("email", e).map_err(LedgerError::InvalidParty)? + Email(v) => { + if let Some(e) = v { + crate::parties::check_email("email", e).map_err(LedgerError::InvalidParty)?; } - None => {} - }, + } // Terms are typed and already canonical (`crate::Terms`), so // there is nothing here a string could get wrong. DefaultTermsAsCustomer(_) | DefaultTermsAsVendor(_) => {} diff --git a/crates/ledger-core/src/settings.rs b/crates/ledger-core/src/settings.rs index 0c8e9c0..7387878 100644 --- a/crates/ledger-core/src/settings.rs +++ b/crates/ledger-core/src/settings.rs @@ -40,6 +40,8 @@ //! `lines`) are the one text the full-TIN check doesn't scan, because //! a routing number is nine digits (A-3); every other text in the //! list is scanned. +//! 8. An invoice number's prefix is 1 to 12 visible ASCII characters: +//! longer, blank or holding a space would not read as one number. //! ``` use crate::TaxForm; diff --git a/crates/ledger-store/src/store.rs b/crates/ledger-store/src/store.rs index 9c6753c..0e01fd8 100644 --- a/crates/ledger-store/src/store.rs +++ b/crates/ledger-store/src/store.rs @@ -1597,6 +1597,10 @@ impl Store { } /// Change one of a party's facts. Journaled as `party.updated`. + /// + /// An email or a default terms fact needs the `documents_v2` feature + /// (plan P4b S4.2): books that haven't declared it refuse the write + /// with the upgrade remedy, journaling nothing. pub fn update_party( &mut self, id: ledger_core::PartyId,