The new code is working now.
This commit is contained in:
parent
f2c60057ef
commit
f1523b5464
6 changed files with 64 additions and 59 deletions
|
|
@ -484,40 +484,40 @@ void changed_value_posts::operator()(post_t& post)
|
||||||
}
|
}
|
||||||
|
|
||||||
void subtotal_posts::report_subtotal(const char * spec_fmt,
|
void subtotal_posts::report_subtotal(const char * spec_fmt,
|
||||||
const date_t& start,
|
const optional<date_interval_t>& interval)
|
||||||
const date_t& finish)
|
|
||||||
{
|
{
|
||||||
if (component_posts.empty())
|
if (component_posts.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
date_t range_start = start;
|
optional<date_t> range_start = interval ? interval->start : none;
|
||||||
date_t range_finish = finish;
|
optional<date_t> range_finish = interval ? interval->inclusive_end() : none;
|
||||||
|
|
||||||
foreach (post_t * post, component_posts) {
|
foreach (post_t * post, component_posts) {
|
||||||
date_t date = post->date();
|
date_t date = post->date();
|
||||||
if (! is_valid(range_start) || date < range_start)
|
if (! range_start || date < *range_start)
|
||||||
range_start = date;
|
range_start = date;
|
||||||
if (! is_valid(range_finish) || date > range_finish)
|
if (! range_finish || date > *range_finish)
|
||||||
range_finish = date;
|
range_finish = date;
|
||||||
}
|
}
|
||||||
component_posts.clear();
|
component_posts.clear();
|
||||||
|
|
||||||
std::ostringstream out_date;
|
std::ostringstream out_date;
|
||||||
if (spec_fmt) {
|
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) {
|
else if (date_format) {
|
||||||
string fmt = "- ";
|
string fmt = "- ";
|
||||||
fmt += *date_format;
|
fmt += *date_format;
|
||||||
out_date << format_date(range_finish, string(fmt));
|
out_date << format_date(*range_finish, string(fmt));
|
||||||
}
|
}
|
||||||
else {
|
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_temps.push_back(xact_t());
|
||||||
xact_t& xact = xact_temps.back();
|
xact_t& xact = xact_temps.back();
|
||||||
xact.payee = out_date.str();
|
xact.payee = out_date.str();
|
||||||
xact._date = range_start;
|
xact._date = *range_start;
|
||||||
|
|
||||||
foreach (values_map::value_type& pair, values)
|
foreach (values_map::value_type& pair, values)
|
||||||
handle_value(pair.second.value, pair.second.account, &xact, post_temps,
|
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);
|
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 (last_post && interval) {
|
||||||
if (exact_periods)
|
if (exact_periods)
|
||||||
subtotal_posts::report_subtotal();
|
subtotal_posts::report_subtotal();
|
||||||
else
|
else
|
||||||
subtotal_posts::report_subtotal(NULL, *interval.start, finish);
|
subtotal_posts::report_subtotal(NULL, interval);
|
||||||
}
|
}
|
||||||
|
|
||||||
last_post = NULL;
|
last_post = NULL;
|
||||||
|
|
@ -572,13 +572,12 @@ void interval_posts::operator()(post_t& post)
|
||||||
{
|
{
|
||||||
date_t date = post.date();
|
date_t date = post.date();
|
||||||
|
|
||||||
if (! interval.find_period(post.date(), &last_interval))
|
if (! interval.find_period(post.date()))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (interval.duration) {
|
if (interval.duration) {
|
||||||
if (last_interval) {
|
if (last_interval && interval != last_interval) {
|
||||||
if (interval != last_interval) {
|
report_subtotal(last_interval);
|
||||||
report_subtotal(last_interval.inclusive_end());
|
|
||||||
|
|
||||||
if (generate_empty_posts) {
|
if (generate_empty_posts) {
|
||||||
for (++last_interval; interval != last_interval; ++last_interval) {
|
for (++last_interval; interval != last_interval; ++last_interval) {
|
||||||
|
|
@ -599,10 +598,14 @@ void interval_posts::operator()(post_t& post)
|
||||||
last_post = &null_post;
|
last_post = &null_post;
|
||||||
subtotal_posts::operator()(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);
|
subtotal_posts::operator()(post);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -750,7 +753,7 @@ void budget_posts::report_budget_items(const date_t& date)
|
||||||
optional<date_t> begin = pair.first.start;
|
optional<date_t> begin = pair.first.start;
|
||||||
if (! begin) {
|
if (! begin) {
|
||||||
if (! pair.first.find_period(date))
|
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;
|
begin = pair.first.start;
|
||||||
}
|
}
|
||||||
assert(begin);
|
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;
|
date_interval_t& i = pending_posts.back().first;
|
||||||
if (! i.start) {
|
if (! i.start) {
|
||||||
if (! i.find_period(CURRENT_DATE()))
|
if (! i.find_period(CURRENT_DATE()))
|
||||||
throw_(std::runtime_error, "Something odd has happened");
|
throw_(std::runtime_error, _("Something odd has happened"));
|
||||||
++i;
|
++i;
|
||||||
} else {
|
} else {
|
||||||
while (*i.start < CURRENT_DATE())
|
while (*i.start < CURRENT_DATE())
|
||||||
|
|
|
||||||
|
|
@ -540,8 +540,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
void report_subtotal(const char * spec_fmt = NULL,
|
void report_subtotal(const char * spec_fmt = NULL,
|
||||||
const date_t& start = date_t(),
|
const optional<date_interval_t>& interval = none);
|
||||||
const date_t& finish = date_t());
|
|
||||||
|
|
||||||
virtual void flush() {
|
virtual void flush() {
|
||||||
if (values.size() > 0)
|
if (values.size() > 0)
|
||||||
|
|
@ -585,12 +584,12 @@ public:
|
||||||
TRACE_DTOR(interval_posts);
|
TRACE_DTOR(interval_posts);
|
||||||
}
|
}
|
||||||
|
|
||||||
void report_subtotal(const date_t& finish);
|
void report_subtotal(const date_interval_t& interval);
|
||||||
|
|
||||||
virtual void flush() {
|
virtual void flush() {
|
||||||
if (last_post && interval.duration) {
|
if (last_post && interval.duration) {
|
||||||
if (interval.is_valid())
|
if (interval.is_valid())
|
||||||
report_subtotal(interval.inclusive_end());
|
report_subtotal(interval);
|
||||||
subtotal_posts::flush();
|
subtotal_posts::flush();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -204,7 +204,7 @@ value_t period_command(call_scope_t& args)
|
||||||
|
|
||||||
out << i << "): " << format_date(*interval.start);
|
out << i << "): " << format_date(*interval.start);
|
||||||
if (interval.end_of_duration)
|
if (interval.end_of_duration)
|
||||||
out << " -- " << format_date(interval.inclusive_end());
|
out << " -- " << format_date(*interval.inclusive_end());
|
||||||
out << std::endl;
|
out << std::endl;
|
||||||
|
|
||||||
if (! interval.skip_duration)
|
if (! interval.skip_duration)
|
||||||
|
|
|
||||||
|
|
@ -592,8 +592,6 @@ void instance_t::period_xact_directive(char * line)
|
||||||
try {
|
try {
|
||||||
|
|
||||||
std::auto_ptr<period_xact_t> pe(new period_xact_t(skip_ws(line + 1)));
|
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;
|
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()
|
void date_interval_t::resolve_end()
|
||||||
{
|
{
|
||||||
if (! end_of_duration) {
|
if (start && ! end_of_duration) {
|
||||||
end_of_duration = add_duration(*start, *duration);
|
end_of_duration = add_duration(*start, *duration);
|
||||||
DEBUG("times.interval",
|
DEBUG("times.interval",
|
||||||
"stabilize: end_of_duration = " << *end_of_duration);
|
"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)
|
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) {
|
if (date && ! aligned) {
|
||||||
DEBUG("times.interval", "stabilize: date passed, but not aligned");
|
DEBUG("times.interval", "stabilize: date passed, but not aligned");
|
||||||
if (duration) {
|
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,
|
bool date_interval_t::find_period(const date_t& date)
|
||||||
date_interval_t * last_interval)
|
|
||||||
{
|
{
|
||||||
stabilize(date);
|
stabilize(date);
|
||||||
|
|
||||||
|
|
@ -322,13 +326,16 @@ bool date_interval_t::find_period(const date_t& date,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (date < *start) {
|
if (! start) {
|
||||||
|
throw_(std::runtime_error, _("Date interval is improperly initialized"));
|
||||||
|
}
|
||||||
|
else if (date < *start) {
|
||||||
DEBUG("times.interval",
|
DEBUG("times.interval",
|
||||||
"false: date [" << date << "] < start [" << *start << "]");
|
"false: date [" << date << "] < start [" << *start << "]");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (date < *end_of_duration) {
|
if (end_of_duration && date < *end_of_duration) {
|
||||||
DEBUG("times.interval",
|
DEBUG("times.interval",
|
||||||
"true: date [" << date << "] < end_of_duration ["
|
"true: date [" << date << "] < end_of_duration ["
|
||||||
<< *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)) {
|
while (date >= scan && (! end || scan < *end)) {
|
||||||
if (date < end_of_scan) {
|
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;
|
start = scan;
|
||||||
end_of_duration = end_of_scan;
|
end_of_duration = end_of_scan;
|
||||||
next = none;
|
next = none;
|
||||||
|
|
|
||||||
|
|
@ -155,6 +155,7 @@ public:
|
||||||
}
|
}
|
||||||
date_interval_t(const date_interval_t& other)
|
date_interval_t(const date_interval_t& other)
|
||||||
: start(other.start),
|
: start(other.start),
|
||||||
|
aligned(other.aligned),
|
||||||
skip_duration(other.skip_duration),
|
skip_duration(other.skip_duration),
|
||||||
factor(other.factor),
|
factor(other.factor),
|
||||||
next(other.next),
|
next(other.next),
|
||||||
|
|
@ -193,10 +194,13 @@ public:
|
||||||
/** Find the current or next period containing date. Returns true if the
|
/** Find the current or next period containing date. Returns true if the
|
||||||
date_interval_t object has been altered to reflect the interval
|
date_interval_t object has been altered to reflect the interval
|
||||||
containing date, or false if no such period can be found. */
|
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 {
|
optional<date_t> inclusive_end() const {
|
||||||
|
if (end_of_duration)
|
||||||
return *end_of_duration - gregorian::days(1);
|
return *end_of_duration - gregorian::days(1);
|
||||||
|
else
|
||||||
|
return none;
|
||||||
}
|
}
|
||||||
|
|
||||||
date_interval_t& operator++();
|
date_interval_t& operator++();
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue