diff options
author | John Wiegley <johnw@newartisans.com> | 2008-09-14 19:38:44 -0400 |
---|---|---|
committer | John Wiegley <johnw@newartisans.com> | 2008-09-14 19:38:44 -0400 |
commit | 7d1809cb15b1ebea4d96341ae0e5fc655487788a (patch) | |
tree | fa56bc87e3798b5529640075885271b8fa02f359 /src | |
parent | 0135c28049839c2db25351b8d8114f9f31649afc (diff) | |
download | fork-ledger-7d1809cb15b1ebea4d96341ae0e5fc655487788a.tar.gz fork-ledger-7d1809cb15b1ebea4d96341ae0e5fc655487788a.tar.bz2 fork-ledger-7d1809cb15b1ebea4d96341ae0e5fc655487788a.zip |
Transactional assignments (i.e., confirmed balances) are working now.
Diffstat (limited to 'src')
-rw-r--r-- | src/entry.cc | 39 | ||||
-rw-r--r-- | src/textual.cc | 65 | ||||
-rw-r--r-- | src/value.cc | 10 | ||||
-rw-r--r-- | src/xact.h | 4 |
4 files changed, 67 insertions, 51 deletions
diff --git a/src/entry.cc b/src/entry.cc index 7cb4b926..a1cfa702 100644 --- a/src/entry.cc +++ b/src/entry.cc @@ -130,7 +130,7 @@ bool entry_base_t::finalize() // :generatedp t)) // (add-xact entry null-xact))) - if (journal && journal->basket && xacts.size() == 1) { + if (journal && journal->basket && xacts.size() == 1 && ! balance.is_null()) { // jww (2008-07-24): Need to make the rest of the code aware of what to do // when it sees a generated xact. null_xact = new xact_t(journal->basket, XACT_GENERATED); @@ -173,10 +173,14 @@ bool entry_base_t::finalize() XACT_GENERATED)); } } - } else { + } + else if (balance.is_amount()) { null_xact->amount = balance.as_amount().negate(); null_xact->add_flags(XACT_CALCULATED); } + else if (! balance.is_null() && ! balance.is_realzero()) { + throw_(balance_error, "Entry does not balance"); + } balance = NULL_VALUE; } @@ -300,28 +304,37 @@ bool entry_base_t::finalize() // (format-value balance :width 20))) if (! balance.is_null()) { - balance.round(); + balance.in_place_round(); if (! balance.is_zero()) { #if 0 - error * err = - new balance_error("Entry does not balance", - new entry_context(*this, "While balancing entry:")); - err->context.push_front - (new value_context(balance, "Unbalanced remainder is:")); - throw err; + new entry_context(*this, "While balancing entry:"); #endif + add_error_context("Unbalanced remainder is: "); + add_error_context(value_context(balance)); + throw_(balance_error, "Entry does not balance"); } } // Add the final calculated totals each to their related account if (dynamic_cast<entry_t *>(this)) { + bool all_null = true; foreach (xact_t * xact, xacts) { - // jww (2008-08-09): For now, this feature only works for - // non-specific commodities. - add_or_set_value(xact->account->xdata().value, - xact->amount.strip_annotations()); + if (! xact->amount.is_null()) { + all_null = false; + + // jww (2008-08-09): For now, this feature only works for + // non-specific commodities. + add_or_set_value(xact->account->xdata().value, xact->amount); + + DEBUG("entry.finalize.totals", + "Total for " << xact->account->fullname() << " + " + << xact->amount.strip_annotations() << ": " + << xact->account->xdata().value.strip_annotations()); + } } + if (all_null) + return false; // ignore this entry completely } return true; diff --git a/src/textual.cc b/src/textual.cc index c3ca3895..cc941695 100644 --- a/src/textual.cc +++ b/src/textual.cc @@ -313,71 +313,78 @@ xact_t * parse_xact(char * line, account_t * account, entry_t * entry = NULL) DEBUG("ledger.textual.parse", "line " << linenum << ": " << "Found a balance assignment indicator"); if (in.good() && ! in.eof()) { - amount_t amt; + xact->assigned_amount = amount_t(); try { istream_pos_type beg = in.tellg(); - optional<expr_t> total_expr = - parse_amount_expr(in, amt, xact.get(), EXPR_PARSE_NO_MIGRATE); + xact->assigned_amount_expr = + parse_amount_expr(in, *xact->assigned_amount, xact.get(), + EXPR_PARSE_NO_MIGRATE); - if (amt.is_null()) + if (xact->assigned_amount->is_null()) throw parse_error ("An assigned balance must evaluate to a constant value"); DEBUG("ledger.textual.parse", "line " << linenum << ": " << - "XACT assign: parsed amt = " << amt); + "XACT assign: parsed amt = " << *xact->assigned_amount); - if (total_expr) { + if (xact->assigned_amount_expr) { istream_pos_type end = in.tellg(); - total_expr->set_text(string("=") + - string(line, long(beg), long(end - beg))); + xact->assigned_amount_expr->set_text + (string("=") + string(line, long(beg), long(end - beg))); } - // jww (2008-08-02): Save total_expr somewhere! - account_t::xdata_t& xdata(xact->account->xdata()); + amount_t& amt(*xact->assigned_amount); - DEBUG("ledger.xact.assign", "account balance = " << xdata.value); - DEBUG("ledger.xact.assign", "xact amount = " << amt); + DEBUG("xact.assign", + "account balance = " << xdata.value.strip_annotations()); + DEBUG("xact.assign", + "xact amount = " << amt.strip_annotations()); amount_t diff; if (xdata.value.is_amount()) { diff = amt - xdata.value.as_amount(); } else if (xdata.value.is_balance()) { - optional<amount_t> comm_bal = - xdata.value.as_balance().commodity_amount(amt.commodity()); - diff = amt - (comm_bal ? *comm_bal : amount_t(0L)); + if (optional<amount_t> comm_bal = + xdata.value.as_balance().commodity_amount(amt.commodity())) + diff = amt - *comm_bal; + else + diff = amt; } else if (xdata.value.is_balance_pair()) { - optional<amount_t> comm_bal = - xdata.value.as_balance_pair().commodity_amount(amt.commodity()); - diff = amt - (comm_bal ? *comm_bal : amount_t(0L)); + if (optional<amount_t> comm_bal = + xdata.value.as_balance_pair().commodity_amount(amt.commodity())) + diff = amt - *comm_bal; + else + diff = amt; } else { diff = amt; } - DEBUG("ledger.xact.assign", "diff = " << diff); + DEBUG("xact.assign", "diff = " << diff.strip_annotations()); DEBUG("ledger.textual.parse", "line " << linenum << ": " << - "XACT assign: diff = " << diff); + "XACT assign: diff = " << diff.strip_annotations()); - if (! diff.is_realzero()) { + if (! diff.is_zero()) { if (! xact->amount.is_null()) { - xact_t * temp = - new xact_t(xact->account, diff, - XACT_GENERATED | XACT_CALCULATED); - entry->add_xact(temp); - - DEBUG("ledger.textual.parse", "line " << linenum << ": " << - "Created balancing transaction"); + diff -= xact->amount; + if (! diff.is_zero()) { + xact_t * temp = new xact_t(xact->account, diff, + XACT_GENERATED | XACT_CALCULATED); + entry->add_xact(temp); + + DEBUG("ledger.textual.parse", "line " << linenum << ": " << + "Created balancing transaction"); + } } else { xact->amount = diff; DEBUG("ledger.textual.parse", "line " << linenum << ": " << "Overwrite null transaction"); } - xdata.value = amt; } } catch (const std::exception& err) { diff --git a/src/value.cc b/src/value.cc index be78327a..ea0bdf7b 100644 --- a/src/value.cc +++ b/src/value.cc @@ -1263,11 +1263,8 @@ bool value_t::is_realzero() const return as_any_pointer().empty(); default: - assert(false); - break; + throw_(value_error, "Cannot determine if " << label() << " is really zero"); } - assert(false); - return true; } bool value_t::is_zero() const @@ -1296,11 +1293,8 @@ bool value_t::is_zero() const return as_any_pointer().empty(); default: - assert(false); - break; + throw_(value_error, "Cannot determine if " << label() << " is zero"); } - assert(false); - return true; } value_t value_t::value(const optional<datetime_t>& moment) const @@ -69,6 +69,8 @@ public: optional<expr_t> amount_expr; optional<amount_t> cost; optional<expr_t> cost_expr; + optional<amount_t> assigned_amount; + optional<expr_t> assigned_amount_expr; istream_pos_type beg_pos; unsigned long beg_line; @@ -84,7 +86,7 @@ public: { TRACE_CTOR(xact_t, "account_t *, flags_t"); } - xact_t(account_t * _account, + xact_t(account_t * _account, const amount_t& _amount, flags_t _flags = XACT_NORMAL, const optional<string>& _note = none) |