The new code is working now.
This commit is contained in:
parent
f2c60057ef
commit
f1523b5464
6 changed files with 64 additions and 59 deletions
|
|
@ -483,41 +483,41 @@ void changed_value_posts::operator()(post_t& post)
|
|||
last_post = &post;
|
||||
}
|
||||
|
||||
void subtotal_posts::report_subtotal(const char * spec_fmt,
|
||||
const date_t& start,
|
||||
const date_t& finish)
|
||||
void subtotal_posts::report_subtotal(const char * spec_fmt,
|
||||
const optional<date_interval_t>& interval)
|
||||
{
|
||||
if (component_posts.empty())
|
||||
return;
|
||||
|
||||
date_t range_start = start;
|
||||
date_t range_finish = finish;
|
||||
optional<date_t> range_start = interval ? interval->start : none;
|
||||
optional<date_t> range_finish = interval ? interval->inclusive_end() : none;
|
||||
|
||||
foreach (post_t * post, component_posts) {
|
||||
date_t date = post->date();
|
||||
if (! is_valid(range_start) || date < range_start)
|
||||
if (! range_start || date < *range_start)
|
||||
range_start = date;
|
||||
if (! is_valid(range_finish) || date > range_finish)
|
||||
if (! range_finish || date > *range_finish)
|
||||
range_finish = date;
|
||||
}
|
||||
component_posts.clear();
|
||||
|
||||
std::ostringstream out_date;
|
||||
if (spec_fmt) {
|
||||
out_date << format_date(range_finish, string(spec_fmt));
|
||||
out_date << format_date(*range_finish, string(spec_fmt));
|
||||
}
|
||||
else if (date_format) {
|
||||
string fmt = "- ";
|
||||
fmt += *date_format;
|
||||
out_date << format_date(range_finish, string(fmt));
|
||||
out_date << format_date(*range_finish, string(fmt));
|
||||
}
|
||||
else {
|
||||
out_date << format_date(range_finish, std::string("- ") + output_date_format);
|
||||
out_date << format_date(*range_finish, std::string("- ") + output_date_format);
|
||||
}
|
||||
|
||||
xact_temps.push_back(xact_t());
|
||||
xact_t& xact = xact_temps.back();
|
||||
xact.payee = out_date.str();
|
||||
xact._date = range_start;
|
||||
xact._date = *range_start;
|
||||
|
||||
foreach (values_map::value_type& pair, values)
|
||||
handle_value(pair.second.value, pair.second.account, &xact, post_temps,
|
||||
|
|
@ -556,13 +556,13 @@ void subtotal_posts::operator()(post_t& post)
|
|||
post.reported_account()->xdata().add_flags(ACCOUNT_EXT_HAS_UNB_VIRTUALS);
|
||||
}
|
||||
|
||||
void interval_posts::report_subtotal(const date_t& finish)
|
||||
void interval_posts::report_subtotal(const date_interval_t& interval)
|
||||
{
|
||||
if (last_post && interval) {
|
||||
if (exact_periods)
|
||||
subtotal_posts::report_subtotal();
|
||||
else
|
||||
subtotal_posts::report_subtotal(NULL, *interval.start, finish);
|
||||
subtotal_posts::report_subtotal(NULL, interval);
|
||||
}
|
||||
|
||||
last_post = NULL;
|
||||
|
|
@ -572,37 +572,40 @@ void interval_posts::operator()(post_t& post)
|
|||
{
|
||||
date_t date = post.date();
|
||||
|
||||
if (! interval.find_period(post.date(), &last_interval))
|
||||
if (! interval.find_period(post.date()))
|
||||
return;
|
||||
|
||||
if (interval.duration) {
|
||||
if (last_interval) {
|
||||
if (interval != last_interval) {
|
||||
report_subtotal(last_interval.inclusive_end());
|
||||
if (last_interval && interval != last_interval) {
|
||||
report_subtotal(last_interval);
|
||||
|
||||
if (generate_empty_posts) {
|
||||
for (++last_interval; interval != last_interval; ++last_interval) {
|
||||
// Generate a null posting, so the intervening periods can be
|
||||
// seen when -E is used, or if the calculated amount ends up being
|
||||
// non-zero
|
||||
xact_temps.push_back(xact_t());
|
||||
xact_t& null_xact = xact_temps.back();
|
||||
null_xact.add_flags(ITEM_TEMP);
|
||||
null_xact._date = last_interval.inclusive_end();
|
||||
if (generate_empty_posts) {
|
||||
for (++last_interval; interval != last_interval; ++last_interval) {
|
||||
// Generate a null posting, so the intervening periods can be
|
||||
// seen when -E is used, or if the calculated amount ends up being
|
||||
// non-zero
|
||||
xact_temps.push_back(xact_t());
|
||||
xact_t& null_xact = xact_temps.back();
|
||||
null_xact.add_flags(ITEM_TEMP);
|
||||
null_xact._date = last_interval.inclusive_end();
|
||||
|
||||
post_temps.push_back(post_t(&empty_account));
|
||||
post_t& null_post = post_temps.back();
|
||||
null_post.add_flags(ITEM_TEMP | POST_CALCULATED);
|
||||
null_post.amount = 0L;
|
||||
null_xact.add_post(&null_post);
|
||||
post_temps.push_back(post_t(&empty_account));
|
||||
post_t& null_post = post_temps.back();
|
||||
null_post.add_flags(ITEM_TEMP | POST_CALCULATED);
|
||||
null_post.amount = 0L;
|
||||
null_xact.add_post(&null_post);
|
||||
|
||||
last_post = &null_post;
|
||||
subtotal_posts::operator()(null_post);
|
||||
last_post = &null_post;
|
||||
subtotal_posts::operator()(null_post);
|
||||
|
||||
report_subtotal(last_interval.inclusive_end());
|
||||
}
|
||||
report_subtotal(last_interval);
|
||||
}
|
||||
assert(interval == last_interval);
|
||||
} else {
|
||||
last_interval = interval;
|
||||
}
|
||||
} else {
|
||||
last_interval = interval;
|
||||
}
|
||||
subtotal_posts::operator()(post);
|
||||
} else {
|
||||
|
|
@ -750,7 +753,7 @@ void budget_posts::report_budget_items(const date_t& date)
|
|||
optional<date_t> begin = pair.first.start;
|
||||
if (! begin) {
|
||||
if (! pair.first.find_period(date))
|
||||
throw_(std::runtime_error, "Something odd has happened");
|
||||
throw_(std::runtime_error, _()"Something odd has happened");
|
||||
begin = pair.first.start;
|
||||
}
|
||||
assert(begin);
|
||||
|
|
@ -821,7 +824,7 @@ void forecast_posts::add_post(const date_interval_t& period, post_t& post)
|
|||
date_interval_t& i = pending_posts.back().first;
|
||||
if (! i.start) {
|
||||
if (! i.find_period(CURRENT_DATE()))
|
||||
throw_(std::runtime_error, "Something odd has happened");
|
||||
throw_(std::runtime_error, _("Something odd has happened"));
|
||||
++i;
|
||||
} else {
|
||||
while (*i.start < CURRENT_DATE())
|
||||
|
|
|
|||
|
|
@ -539,9 +539,8 @@ public:
|
|||
clear_xacts_posts(xact_temps);
|
||||
}
|
||||
|
||||
void report_subtotal(const char * spec_fmt = NULL,
|
||||
const date_t& start = date_t(),
|
||||
const date_t& finish = date_t());
|
||||
void report_subtotal(const char * spec_fmt = NULL,
|
||||
const optional<date_interval_t>& interval = none);
|
||||
|
||||
virtual void flush() {
|
||||
if (values.size() > 0)
|
||||
|
|
@ -585,12 +584,12 @@ public:
|
|||
TRACE_DTOR(interval_posts);
|
||||
}
|
||||
|
||||
void report_subtotal(const date_t& finish);
|
||||
void report_subtotal(const date_interval_t& interval);
|
||||
|
||||
virtual void flush() {
|
||||
if (last_post && interval.duration) {
|
||||
if (interval.is_valid())
|
||||
report_subtotal(interval.inclusive_end());
|
||||
report_subtotal(interval);
|
||||
subtotal_posts::flush();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -204,7 +204,7 @@ value_t period_command(call_scope_t& args)
|
|||
|
||||
out << i << "): " << format_date(*interval.start);
|
||||
if (interval.end_of_duration)
|
||||
out << " -- " << format_date(interval.inclusive_end());
|
||||
out << " -- " << format_date(*interval.inclusive_end());
|
||||
out << std::endl;
|
||||
|
||||
if (! interval.skip_duration)
|
||||
|
|
|
|||
|
|
@ -592,8 +592,6 @@ void instance_t::period_xact_directive(char * line)
|
|||
try {
|
||||
|
||||
std::auto_ptr<period_xact_t> pe(new period_xact_t(skip_ws(line + 1)));
|
||||
if (! pe->period)
|
||||
throw_(parse_error, _("Parsing time period '%1'") << line);
|
||||
|
||||
reveal_context = false;
|
||||
|
||||
|
|
|
|||
23
src/times.cc
23
src/times.cc
|
|
@ -195,7 +195,7 @@ std::ostream& operator<<(std::ostream& out,
|
|||
|
||||
void date_interval_t::resolve_end()
|
||||
{
|
||||
if (! end_of_duration) {
|
||||
if (start && ! end_of_duration) {
|
||||
end_of_duration = add_duration(*start, *duration);
|
||||
DEBUG("times.interval",
|
||||
"stabilize: end_of_duration = " << *end_of_duration);
|
||||
|
|
@ -222,6 +222,11 @@ void date_interval_t::resolve_end()
|
|||
|
||||
void date_interval_t::stabilize(const optional<date_t>& date)
|
||||
{
|
||||
#if defined(DEBUG_ON)
|
||||
if (date)
|
||||
DEBUG("times.interval", "stabilize: with date = " << *date);
|
||||
#endif
|
||||
|
||||
if (date && ! aligned) {
|
||||
DEBUG("times.interval", "stabilize: date passed, but not aligned");
|
||||
if (duration) {
|
||||
|
|
@ -311,8 +316,7 @@ void date_interval_t::stabilize(const optional<date_t>& date)
|
|||
}
|
||||
}
|
||||
|
||||
bool date_interval_t::find_period(const date_t& date,
|
||||
date_interval_t * last_interval)
|
||||
bool date_interval_t::find_period(const date_t& date)
|
||||
{
|
||||
stabilize(date);
|
||||
|
||||
|
|
@ -322,13 +326,16 @@ bool date_interval_t::find_period(const date_t& date,
|
|||
return false;
|
||||
}
|
||||
|
||||
if (date < *start) {
|
||||
if (! start) {
|
||||
throw_(std::runtime_error, _("Date interval is improperly initialized"));
|
||||
}
|
||||
else if (date < *start) {
|
||||
DEBUG("times.interval",
|
||||
"false: date [" << date << "] < start [" << *start << "]");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (date < *end_of_duration) {
|
||||
if (end_of_duration && date < *end_of_duration) {
|
||||
DEBUG("times.interval",
|
||||
"true: date [" << date << "] < end_of_duration ["
|
||||
<< *end_of_duration << "]");
|
||||
|
|
@ -349,12 +356,6 @@ bool date_interval_t::find_period(const date_t& date,
|
|||
|
||||
while (date >= scan && (! end || scan < *end)) {
|
||||
if (date < end_of_scan) {
|
||||
if (last_interval) {
|
||||
last_interval->start = start;
|
||||
last_interval->next = next;
|
||||
last_interval->end_of_duration = end_of_duration;
|
||||
}
|
||||
|
||||
start = scan;
|
||||
end_of_duration = end_of_scan;
|
||||
next = none;
|
||||
|
|
|
|||
10
src/times.h
10
src/times.h
|
|
@ -155,6 +155,7 @@ public:
|
|||
}
|
||||
date_interval_t(const date_interval_t& other)
|
||||
: start(other.start),
|
||||
aligned(other.aligned),
|
||||
skip_duration(other.skip_duration),
|
||||
factor(other.factor),
|
||||
next(other.next),
|
||||
|
|
@ -193,10 +194,13 @@ public:
|
|||
/** Find the current or next period containing date. Returns true if the
|
||||
date_interval_t object has been altered to reflect the interval
|
||||
containing date, or false if no such period can be found. */
|
||||
bool find_period(const date_t& date, date_interval_t * last_interval = NULL);
|
||||
bool find_period(const date_t& date);
|
||||
|
||||
date_t inclusive_end() const {
|
||||
return *end_of_duration - gregorian::days(1);
|
||||
optional<date_t> inclusive_end() const {
|
||||
if (end_of_duration)
|
||||
return *end_of_duration - gregorian::days(1);
|
||||
else
|
||||
return none;
|
||||
}
|
||||
|
||||
date_interval_t& operator++();
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue