feat: set up modularized version of project with testing
This commit is contained in:
commit
7bea08ddac
19 changed files with 1138 additions and 0 deletions
54
src/timesheets/output.py
Normal file
54
src/timesheets/output.py
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
import csv
|
||||
import sys
|
||||
from collections import OrderedDict
|
||||
from typing import IO
|
||||
|
||||
from .projects import resolve_project_task
|
||||
from .utils import decimal_to_hhmm
|
||||
|
||||
|
||||
def write_csv(
|
||||
aggregated: list[dict],
|
||||
output: IO[str],
|
||||
date_str: str,
|
||||
project_map: dict,
|
||||
) -> None:
|
||||
"""Write the aggregated timesheet data as CSV."""
|
||||
writer = csv.writer(output)
|
||||
writer.writerow(["Date*", "Project*", "Task", "Description", "Quantity"])
|
||||
for entry in aggregated:
|
||||
project, task = resolve_project_task(entry["project"], project_map)
|
||||
writer.writerow(
|
||||
[
|
||||
date_str,
|
||||
project,
|
||||
task,
|
||||
entry["description"],
|
||||
f"{entry['quantity']:.2f}",
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
def print_summary(aggregated: list[dict], project_map: dict) -> None:
|
||||
"""Print a human-readable summary of time blocks to stdout."""
|
||||
grouped: dict[str, list[dict]] = OrderedDict()
|
||||
for entry in aggregated:
|
||||
project, task = resolve_project_task(entry["project"], project_map)
|
||||
label = f"{project} / {task}" if task else project
|
||||
grouped.setdefault(label, []).append(entry)
|
||||
|
||||
total_all = sum(e["quantity"] for e in aggregated)
|
||||
|
||||
all_descs = [e["description"] for e in aggregated]
|
||||
desc_width = max(max((len(d) for d in all_descs), default=40), 40)
|
||||
separator = "-" * (desc_width + 16)
|
||||
|
||||
for label, entries in grouped.items():
|
||||
project_total = sum(e["quantity"] for e in entries)
|
||||
print(f"\n {label} ({decimal_to_hhmm(project_total)})")
|
||||
print(" " + separator)
|
||||
for entry in entries:
|
||||
print(f" {entry['description']:<{desc_width}} {decimal_to_hhmm(entry['quantity'])}")
|
||||
print(" " + separator)
|
||||
|
||||
print(f"\n {'TOTAL':<{desc_width + 2}} {decimal_to_hhmm(total_all)}\n")
|
||||
Loading…
Add table
Add a link
Reference in a new issue