Added option --day-break

This commit is contained in:
John Wiegley 2012-03-17 05:27:43 -05:00
parent 018a2a8e7b
commit 22c1b867f0
9 changed files with 88 additions and 34 deletions

View file

@ -1,4 +1,4 @@
.Dd March 13, 2012
.Dd March 17, 2012
.Dt ledger 1
.Sh NAME
.Nm ledger
@ -300,6 +300,7 @@ See
.It Fl \-date-format Ar DATEFMT Pq Fl y
.It Fl \-datetime-format Ar FMT
.It Fl \-date-width Ar INT
.It Fl \-day-break
.It Fl \-dc
.It Fl \-debug Ar STR
.It Fl \-decimal-comma

View file

@ -94,6 +94,7 @@ void journal_t::initialize()
was_loaded = false;
force_checking = false;
check_payees = false;
day_break = false;
checking_style = CHECK_PERMISSIVE;
}

View file

@ -130,6 +130,7 @@ public:
bool was_loaded;
bool force_checking;
bool check_payees;
bool day_break;
payee_mappings_t payee_mappings;
account_mappings_t account_mappings;
accounts_map account_aliases;

View file

@ -105,6 +105,8 @@ std::size_t session_t::read_data(const string& master_account)
journal->force_checking = true;
if (HANDLED(check_payees))
journal->check_payees = true;
if (HANDLED(day_break))
journal->day_break = true;
if (HANDLED(permissive))
journal->checking_style = journal_t::CHECK_PERMISSIVE;
@ -320,6 +322,7 @@ option_t<session_t> * session_t::lookup_option(const char * p)
case 'd':
OPT(download); // -Q
else OPT(decimal_comma);
else OPT(day_break);
break;
case 'e':
OPT(explicit);

View file

@ -97,6 +97,7 @@ public:
{
HANDLER(cache_).report(out);
HANDLER(check_payees).report(out);
HANDLER(day_break).report(out);
HANDLER(download).report(out);
HANDLER(decimal_comma).report(out);
HANDLER(file_).report(out);
@ -122,6 +123,7 @@ public:
OPTION(session_t, cache_);
OPTION(session_t, check_payees);
OPTION(session_t, day_break);
OPTION(session_t, download); // -Q
OPTION_(session_t, decimal_comma, DO() {

View file

@ -486,8 +486,7 @@ void instance_t::clock_out_directive(char * line, bool /*capitalized*/)
n ? n : "",
end ? end : "");
timelog.clock_out(event);
context.count++;
context.count += timelog.clock_out(event);
}
#endif // TIMELOG_SUPPORT

View file

@ -41,9 +41,43 @@
namespace ledger {
namespace {
void clock_out_from_timelog(std::list<time_xact_t>& time_xacts,
time_xact_t out_event,
parse_context_t& context)
void create_timelog_xact(const time_xact_t& in_event,
const time_xact_t& out_event,
parse_context_t& context)
{
unique_ptr<xact_t> curr(new xact_t);
curr->_date = in_event.checkin.date();
curr->code = out_event.desc; // if it wasn't used above
curr->payee = in_event.desc;
curr->pos = in_event.position;
if (! in_event.note.empty())
curr->append_note(in_event.note.c_str(), *context.scope);
char buf[32];
std::sprintf(buf, "%lds", long((out_event.checkin - in_event.checkin)
.total_seconds()));
amount_t amt;
amt.parse(buf);
VERIFY(amt.valid());
post_t * post = new post_t(in_event.account, amt, POST_VIRTUAL);
post->set_state(item_t::CLEARED);
post->pos = in_event.position;
post->checkin = in_event.checkin;
post->checkout = out_event.checkin;
curr->add_post(post);
in_event.account->add_post(post);
if (! context.journal->add_xact(curr.get()))
throw parse_error(_("Failed to record 'out' timelog transaction"));
else
curr.release();
}
std::size_t clock_out_from_timelog(std::list<time_xact_t>& time_xacts,
time_xact_t out_event,
parse_context_t& context)
{
time_xact_t event;
@ -93,34 +127,35 @@ namespace {
if (! out_event.note.empty() && event.note.empty())
event.note = out_event.note;
unique_ptr<xact_t> curr(new xact_t);
curr->_date = event.checkin.date();
curr->code = out_event.desc; // if it wasn't used above
curr->payee = event.desc;
curr->pos = event.position;
if (! context.journal->day_break) {
create_timelog_xact(event, out_event, context);
return 1;
} else {
time_xact_t begin(event);
std::size_t xact_count = 0;
if (! event.note.empty())
curr->append_note(event.note.c_str(), *context.scope);
while (begin.checkin < out_event.checkin) {
DEBUG("timelog", "begin.checkin: " << begin.checkin);
datetime_t days_end(begin.checkin.date(), time_duration_t(23, 59, 59));
days_end += seconds(1);
DEBUG("timelog", "days_end: " << days_end);
char buf[32];
std::sprintf(buf, "%lds", long((out_event.checkin - event.checkin)
.total_seconds()));
amount_t amt;
amt.parse(buf);
VERIFY(amt.valid());
if (out_event.checkin <= days_end) {
create_timelog_xact(begin, out_event, context);
++xact_count;
break;
} else {
time_xact_t end(out_event);
end.checkin = days_end;
DEBUG("timelog", "end.checkin: " << end.checkin);
create_timelog_xact(begin, end, context);
++xact_count;
post_t * post = new post_t(event.account, amt, POST_VIRTUAL);
post->set_state(item_t::CLEARED);
post->pos = event.position;
post->checkin = event.checkin;
post->checkout = out_event.checkin;
curr->add_post(post);
event.account->add_post(post);
if (! context.journal->add_xact(curr.get()))
throw parse_error(_("Failed to record 'out' timelog transaction"));
else
curr.release();
begin.checkin = end.checkin;
}
}
return xact_count;
}
}
} // unnamed namespace
@ -155,12 +190,12 @@ void time_log_t::clock_in(time_xact_t event)
time_xacts.push_back(event);
}
void time_log_t::clock_out(time_xact_t event)
std::size_t time_log_t::clock_out(time_xact_t event)
{
if (time_xacts.empty())
throw std::logic_error(_("Timelog check-out event without a check-in"));
clock_out_from_timelog(time_xacts, event, context);
return clock_out_from_timelog(time_xacts, event, context);
}
} // namespace ledger

View file

@ -98,7 +98,7 @@ public:
}
void clock_in(time_xact_t event);
void clock_out(time_xact_t event);
std::size_t clock_out(time_xact_t event);
void close();
};

View file

@ -0,0 +1,12 @@
i 05/10/2011 08:58:37 682
o 05/12/2011 11:25:21
test reg --base
11-May-10 (682) 181604s 181604s
end test
test reg --base --day-break
11-May-10 (682) 54083s 54083s
11-May-11 (682) 86400s 140483s
11-May-12 (682) 41121s 181604s
end test