feat(parser): resolve overlapping timesheet entries

Parallel work is logged as overlapping entries. resolve_overlaps()
splits the shared time equally using the midpoint of the overlap region:

- Partial overlap: the midpoint becomes the boundary between the two
  entries (earlier entry trimmed, later entry delayed).
- Full containment: the containing entry is split into two pieces
  surrounding the contained one, with the midpoint rule applied to
  the overlap region.

Open entries (no end time) are passed through unchanged.

resolve_overlaps() is called automatically in filter_rows_by_date,
filter_week_sections, and the --input single-day path in cli.py, so
all subcommands benefit without further changes.
This commit is contained in:
Jef Roosens 2026-05-28 12:53:56 +02:00
parent f99e114770
commit 9f0a6e2027
Signed by: Jef Roosens
GPG key ID: 119385BCAA005C21
3 changed files with 302 additions and 3 deletions

View file

@ -26,6 +26,7 @@ from .parser import (
filter_rows_by_date,
filter_week_sections,
parse_document,
resolve_overlaps,
)
from .projects import load_project_map
from .utils import AmbiguousDateError, format_date, parse_date_arg
@ -211,7 +212,7 @@ def _resolve_rows(
except FileNotFoundError:
print(f"Error: file not found: {args.input}", file=sys.stderr)
sys.exit(1)
return parse_document(content.splitlines())
return resolve_overlaps(parse_document(content.splitlines()))
def _resolve_week_sections(