Rework stop command

- Compute the set difference between the latest interval's tag set and the given tag set
- If no tags given, the difference is set to `{}`
- In case of an empty difference, close the current open interval, apply exclusions and update the database
- In case of a non-empty difference, just add a new open interval and let the overlap resolution do the job...

Signed-off-by: Thomas Lauf <thomas.lauf@tngtech.com>
This commit is contained in:
Thomas Lauf 2020-08-19 14:51:07 +02:00
parent 96aaa71eb4
commit 3feba61459

View file

@ -87,70 +87,47 @@ int CmdStop (
throw format ("The current interval does not have the '{1}' tag.", *diff.begin ());
}
else if (!filter.tags ().empty ())
{
std::set_difference(latest.tags ().begin (), latest.tags ().end (),
filter.tags ().begin (), filter.tags ().end (),
std::inserter(diff, diff.begin()));
}
journal.startTransaction ();
Interval modified {latest};
// If a stop date is specified (and occupies filter.start) then use
// that instead of the current time.
if (filter.is_started ())
if (diff.empty ())
{
if (modified.start >= filter.start)
{
throw std::string ("The end of a date range must be after the start.");
}
Interval modified { latest };
modified.end = filter.start;
database.deleteInterval (latest);
validate (cli, rules, database, modified);
for (auto& interval : flatten (modified, getAllExclusions (rules, modified)))
{
database.addInterval (interval, verbose);
if (verbose)
{
std::cout << intervalSummarize (database, rules, interval);
}
}
}
else
{
modified.end = Datetime ();
}
Interval next { filter.start, 0 };
for (auto& tag : diff)
{
next.tag (tag);
}
// Close the interval.
database.deleteInterval (latest);
validate (cli, rules, database, modified);
for (auto& interval : flatten (modified, getAllExclusions (rules, modified)))
{
database.addInterval (interval, verbose);
validate (cli, rules, database, next);
database.addInterval (next, verbose);
if (verbose)
{
std::cout << intervalSummarize (database, rules, interval);
}
}
// If tags are specified, but are not a full set of tags, remove them
// before closing the interval.
if (! filter.tags ().empty () &&
setIntersect (filter.tags (), latest.tags ()).size () != latest.tags ().size ())
{
for (auto& tag : filter.tags ())
{
if (modified.hasTag (tag))
{
modified.untag (tag);
}
else
{
throw format ("The current interval does not have the '{1}' tag.", tag);
}
}
}
// Open a new interval with remaining tags, if any.
if (! filter.tags ().empty () &&
modified.tags ().size () != latest.tags ().size ())
{
modified.start = modified.end;
modified.end = {0};
validate (cli, rules, database, modified);
database.addInterval (modified, verbose);
if (verbose)
{
std::cout << '\n' << intervalSummarize (database, rules, modified);
std::cout << '\n' << intervalSummarize (database, rules, next);
}
}