diff --git a/src/commands/CmdStop.cpp b/src/commands/CmdStop.cpp index 8348c0db..1fb05ad7 100644 --- a/src/commands/CmdStop.cpp +++ b/src/commands/CmdStop.cpp @@ -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); } }