summaryrefslogtreecommitdiff
path: root/src/timelog.cc
diff options
context:
space:
mode:
authorJohn Wiegley <johnw@newartisans.com>2012-04-26 16:39:25 -0500
committerJohn Wiegley <johnw@newartisans.com>2012-04-26 16:39:25 -0500
commit64a9b42381c26baf24e58b40f50f0b253e551811 (patch)
tree5447a29dff64c3a8b7be8100a01bcb4a2d73b0bb /src/timelog.cc
parent7cc550fc22357e2ded194d3e65287c6b3317f5ae (diff)
parentb4407c10c0071365322b2963747bf42a57fd7304 (diff)
downloadfork-ledger-64a9b42381c26baf24e58b40f50f0b253e551811.tar.gz
fork-ledger-64a9b42381c26baf24e58b40f50f0b253e551811.tar.bz2
fork-ledger-64a9b42381c26baf24e58b40f50f0b253e551811.zip
Merge branch 'release/v3.0.0-20120426'
Diffstat (limited to 'src/timelog.cc')
-rw-r--r--src/timelog.cc113
1 files changed, 77 insertions, 36 deletions
diff --git a/src/timelog.cc b/src/timelog.cc
index ee9a0b6c..e84e4188 100644
--- a/src/timelog.cc
+++ b/src/timelog.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2010, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2012, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -36,14 +36,48 @@
#include "post.h"
#include "account.h"
#include "journal.h"
+#include "context.h"
namespace ledger {
namespace {
- void clock_out_from_timelog(std::list<time_xact_t>& time_xacts,
- time_xact_t out_event,
- journal_t& journal,
- scope_t& scope)
+ 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;
@@ -76,6 +110,11 @@ namespace {
(_("Timelog check-out event does not match any current check-ins"));
}
+ if (event.checkin.is_not_a_date_time())
+ throw parse_error(_("Timelog check-in has no corresponding check-out"));
+ if (out_event.checkin.is_not_a_date_time())
+ throw parse_error(_("Timelog check-out has no corresponding check-in"));
+
if (out_event.checkin < event.checkin)
throw parse_error
(_("Timelog check-out date less than corresponding check-in"));
@@ -88,32 +127,35 @@ namespace {
if (! out_event.note.empty() && event.note.empty())
event.note = out_event.note;
- std::auto_ptr<xact_t> curr(new xact_t);
- curr->_date = out_event.checkin.date();
- curr->code = out_event.desc; // if it wasn't used above
- curr->payee = event.desc;
- curr->pos = event.position;
-
- if (! event.note.empty())
- curr->append_note(event.note.c_str(), scope);
-
- char buf[32];
- std::sprintf(buf, "%lds", long((out_event.checkin - event.checkin)
- .total_seconds()));
- amount_t amt;
- amt.parse(buf);
- VERIFY(amt.valid());
-
- post_t * post = new post_t(event.account, amt, POST_VIRTUAL);
- post->set_state(item_t::CLEARED);
- post->pos = event.position;
- curr->add_post(post);
- event.account->add_post(post);
-
- if (! journal.add_xact(curr.get()))
- throw parse_error(_("Failed to record 'out' timelog transaction"));
- else
- curr.release();
+ 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;
+
+ 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);
+
+ 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;
+
+ begin.checkin = end.checkin;
+ }
+ }
+ return xact_count;
+ }
}
} // unnamed namespace
@@ -129,9 +171,8 @@ void time_log_t::close()
DEBUG("timelog", "Clocking out from account " << account->fullname());
clock_out_from_timelog(time_xacts,
time_xact_t(none, CURRENT_TIME(), account),
- journal, scope);
- if (context_count)
- (*context_count)++;
+ context);
+ context.count++;
}
assert(time_xacts.empty());
}
@@ -149,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, journal, scope);
+ return clock_out_from_timelog(time_xacts, event, context);
}
} // namespace ledger