summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohn Wiegley <johnw@newartisans.com>2008-09-14 19:38:44 -0400
committerJohn Wiegley <johnw@newartisans.com>2008-09-14 19:38:44 -0400
commit7d1809cb15b1ebea4d96341ae0e5fc655487788a (patch)
treefa56bc87e3798b5529640075885271b8fa02f359 /src
parent0135c28049839c2db25351b8d8114f9f31649afc (diff)
downloadfork-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.cc39
-rw-r--r--src/textual.cc65
-rw-r--r--src/value.cc10
-rw-r--r--src/xact.h4
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
diff --git a/src/xact.h b/src/xact.h
index bb2f1e23..70d411ed 100644
--- a/src/xact.h
+++ b/src/xact.h
@@ -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)