Initial commit: wanderbooks accounting semantics engine
This commit is contained in:
1 parent
d3a0b097b2
commit
a614600a87
1 file changed
+78
@@ -0,0 +1,78 @@
|
|||||||
|
//! Error type for the ledger engine.
|
||||||
|
|
||||||
|
use rust_decimal::Decimal;
|
||||||
|
use thiserror::Error;
|
||||||
|
|
||||||
|
/// Every way a ledger command can fail.
|
||||||
|
///
|
||||||
|
/// Variants are part of the engine's contract: agents adding features add
|
||||||
|
/// variants here rather than inventing ad-hoc error reporting.
|
||||||
|
#[derive(Debug, Error, PartialEq, Eq)]
|
||||||
|
pub enum LedgerError {
|
||||||
|
/// A journal entry must have at least two lines (one debit, one credit).
|
||||||
|
#[error("journal entry has fewer than two lines")]
|
||||||
|
TooFewLines,
|
||||||
|
|
||||||
|
/// Debits and credits must be exactly equal. No epsilon, ever.
|
||||||
|
#[error("journal entry does not balance: debits {debits} != credits {credits}")]
|
||||||
|
UnbalancedEntry {
|
||||||
|
/// Sum of debit lines.
|
||||||
|
debits: Decimal,
|
||||||
|
/// Sum of credit lines.
|
||||||
|
credits: Decimal,
|
||||||
|
},
|
||||||
|
|
||||||
|
/// Zero-amount lines are noise; they are rejected, not ignored.
|
||||||
|
#[error("journal line has a zero amount")]
|
||||||
|
ZeroAmountLine,
|
||||||
|
|
||||||
|
/// The referenced account does not exist in the chart of accounts.
|
||||||
|
#[error("unknown account id {0}")]
|
||||||
|
UnknownAccount(u64),
|
||||||
|
|
||||||
|
/// Placeholder (header) accounts organize the chart; they take no postings.
|
||||||
|
#[error("account '{0}' is a placeholder and cannot take postings")]
|
||||||
|
PlaceholderAccount(String),
|
||||||
|
|
||||||
|
/// All lines of an entry (and their accounts) must share one currency.
|
||||||
|
#[error("currency mismatch: expected {expected}, found {found}")]
|
||||||
|
CurrencyMismatch {
|
||||||
|
/// The currency that was expected.
|
||||||
|
expected: String,
|
||||||
|
/// The currency that was found.
|
||||||
|
found: String,
|
||||||
|
},
|
||||||
|
|
||||||
|
/// Currency codes are three ASCII letters (ISO 4217 alpha-3).
|
||||||
|
#[error("invalid currency code '{0}': must be three ASCII letters")]
|
||||||
|
InvalidCurrencyCode(String),
|
||||||
|
|
||||||
|
/// Posted entries are immutable. This is load-bearing: it is what makes
|
||||||
|
/// the ledger an audit trail instead of a spreadsheet.
|
||||||
|
#[error("entry {0} is already posted and immutable")]
|
||||||
|
EntryAlreadyPosted(u64),
|
||||||
|
|
||||||
|
/// Only posted entries can be reversed.
|
||||||
|
#[error("entry {0} is not posted yet")]
|
||||||
|
EntryNotPosted(u64),
|
||||||
|
|
||||||
|
/// The referenced journal entry does not exist.
|
||||||
|
#[error("entry {0} does not exist")]
|
||||||
|
UnknownEntry(u64),
|
||||||
|
|
||||||
|
/// Account codes must be unique within a chart of accounts.
|
||||||
|
#[error("account code '{0}' is already in use")]
|
||||||
|
DuplicateAccountCode(String),
|
||||||
|
|
||||||
|
/// Account codes must not be empty.
|
||||||
|
#[error("account code must not be empty")]
|
||||||
|
EmptyAccountCode,
|
||||||
|
|
||||||
|
/// The referenced parent account does not exist.
|
||||||
|
#[error("unknown parent account id {0}")]
|
||||||
|
UnknownParentAccount(u64),
|
||||||
|
|
||||||
|
/// Any attempt to mutate a posted entry: add lines, delete it, edit it.
|
||||||
|
#[error("cannot modify a posted entry; post a reversing entry instead")]
|
||||||
|
PostedEntryImmutable,
|
||||||
|
}
|
||||||
Reference in new issue
Block a user