Control roles in the journal (books.assign_role, books.roles); the MCP reloads wanderbooks.toml on change and reports settings problems (books.settings, digest); new writes a full commented wanderbooks.toml
check / check (push) Canceled after 0s
check / check (push) Canceled after 0s
- core: ControlAccount keys, Ledger::assign_role/check_assign_role/role_account (rules.md B-23): one account per role, of the role's type, balance sheet roles move only when empty; invoices, bills, payroll, remittance, and closes post to the assigned account; an assigned role frees its default code for renumbering - store: role.assigned journaled and replayed (strict account_id) - mcp: settings.rs reloads by content at the start of each request, keeps the last good settings on a broken edit; books.settings with chart problems; digest settings_problems; instructions say when to edit the toml - viewer: journal text for role.assigned - cli: full example wanderbooks.toml, tested to load with every example uncommented - tests: spec_roles.rs (25, spec-blind), store roles.rs (6), MCP reload/problems/roles, settings unit tests 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
efa370dfa3
commit
1771d87e0e
19 files changed
+3044
-132
No files matched your search
@@ -97,8 +97,8 @@ pub enum LedgerError {
|
||||
/// decides with the human how to handle it.
|
||||
#[error(
|
||||
"account {code} \"{name}\" is {}, but {role} needs account {code} to be a postable {expected:?} account; \
|
||||
wanderbooks won't post {role} there. Decide with the books' owner how to handle it \
|
||||
(for instance, renumber that account so {code} is free, if they agree)",
|
||||
wanderbooks won't post {role} there. Decide with the books' owner how to handle it: \
|
||||
assign {role} to an account of theirs, or renumber that account so {code} is free",
|
||||
if *placeholder { format!("a placeholder {found:?} account") } else { format!("a {found:?} account") }
|
||||
)]
|
||||
ControlAccountMismatch {
|
||||
@@ -116,6 +116,44 @@ pub enum LedgerError {
|
||||
placeholder: bool,
|
||||
},
|
||||
|
||||
/// No control role has that name (see `ledger_core::control_accounts`).
|
||||
#[error(
|
||||
"no role {0:?}; the roles are receivables, revenue, payables, general_expense, \
|
||||
retained_earnings, salary_expense, payroll_tax_expense, federal_withholding, \
|
||||
state_withholding, social_security_payable, medicare_payable, other_deductions_payable"
|
||||
)]
|
||||
UnknownRole(String),
|
||||
|
||||
/// One account per role: an account already filling a role can't take
|
||||
/// a second (its balance would mix what the two control).
|
||||
#[error("account {code} \"{name}\" already holds {role}; give each role its own account")]
|
||||
RoleTaken {
|
||||
/// The account's code.
|
||||
code: String,
|
||||
/// The account's name.
|
||||
name: String,
|
||||
/// The role it fills, e.g. "accounts receivable".
|
||||
role: String,
|
||||
},
|
||||
|
||||
/// A balance sheet role (receivables, payables, withholdings, retained
|
||||
/// earnings) can't move while its account holds a balance: the control
|
||||
/// account must keep agreeing with what it controls.
|
||||
#[error(
|
||||
"{role} is in account {code} \"{name}\", which holds {balance}; move that balance to the \
|
||||
new account with a journal entry first, then assign the role"
|
||||
)]
|
||||
RoleHoldsBalance {
|
||||
/// The role, e.g. "accounts receivable".
|
||||
role: String,
|
||||
/// The code of the account filling it now.
|
||||
code: String,
|
||||
/// That account's name.
|
||||
name: String,
|
||||
/// Its balance.
|
||||
balance: rust_decimal::Decimal,
|
||||
},
|
||||
|
||||
/// A rule set by law (a dollar threshold, a rate) isn't known to
|
||||
/// wanderbooks for the year asked; the engine never guesses (see
|
||||
/// [`crate::rules`]).
|
||||
|
||||
Reference in new issue
Block a user