Skip to content

Commit

Permalink
Bugfix: first billable date (#4)
Browse files Browse the repository at this point in the history
- add first_billable_date property to correctly resolve edge case
- add rich traceback handling

fixes #3
  • Loading branch information
twolffpiggott authored Jun 25, 2023
1 parent ff065a6 commit 1534031
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 5 deletions.
7 changes: 3 additions & 4 deletions toggl_tally/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,11 @@ def __init__(
self.session = requests.Session()

def auth(self):
try:
api_token = os.environ["TOGGL_API_TOKEN"]
except KeyError as exception:
api_token = os.getenv("TOGGL_API_TOKEN")
if api_token is None:
raise KeyError(
"Please ensure that the 'TOGGL_API_TOKEN' environment variable is set"
) from exception
)
self.session.auth = (api_token, "api_token")

def get_time_entries_between(self, start_date: datetime, end_date: datetime):
Expand Down
5 changes: 4 additions & 1 deletion toggl_tally/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import click
import yaml
from rich.console import Console
from rich.traceback import install

from toggl_tally import RichReport, TogglAPI, TogglFilter, TogglTally

Expand Down Expand Up @@ -59,6 +60,8 @@ def _comma_separated_arg_split(ctx, param, value):
)
@click.pass_context
def toggl_tally(ctx: click.Context, config: Optional[Path]):
# rich traceback handling
install(max_frames=1)
if config is not None:
with config.open("r") as f:
config_dict = yaml.safe_load(f)
Expand Down Expand Up @@ -171,7 +174,7 @@ def hours(
)
with console.status("[bold dark_cyan]Getting time entries"):
unfiltered_time_entries = api.get_time_entries_between(
start_date=tally.last_invoice_date,
start_date=tally.first_billable_date,
end_date=tally.now,
)
filtered_time_entries = filter.filter_time_entries(response=unfiltered_time_entries)
Expand Down
10 changes: 10 additions & 0 deletions toggl_tally/tally.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,16 @@ def last_invoice_date(self) -> datetime:
else:
return self.current_month_invoice_date

@property
def first_billable_date(self) -> datetime:
last_invoice_date = self.last_invoice_date
if last_invoice_date.day < self.invoice_day_of_month:
# Return the next day
return last_invoice_date + timedelta(days=1)
else:
# Return the last invoice date
return last_invoice_date

@property
def next_invoice_date(self) -> datetime:
if self.now < self.current_month_invoice_date:
Expand Down
33 changes: 33 additions & 0 deletions toggl_tally/tests/test_tally.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,12 @@ def test_toggl_tally_next_working_day(toggl_tally_object, expected_next_working_
datetime(2023, 3, 20),
id="invoice_date_current_month_public_holiday",
),
pytest.param(
dict(now=datetime(2023, 6, 17), invoice_day_of_month=20),
datetime(2023, 5, 19),
datetime(2023, 6, 20),
id="invoice_date_weekend",
),
],
indirect=["toggl_tally_object"],
)
Expand All @@ -101,6 +107,11 @@ def test_toggl_tally_invoice_dates(
datetime(2023, 3, 24),
id="last_billable_date_inclusive",
),
pytest.param(
dict(now=datetime(2023, 5, 17), invoice_day_of_month=20),
datetime(2023, 5, 19),
id="last_billable_date_inclusive_2",
),
pytest.param(
dict(now=datetime(2023, 3, 1), invoice_day_of_month=21),
datetime(2023, 3, 20),
Expand Down Expand Up @@ -222,3 +233,25 @@ def test_toggle_tally_rrule_day_strs_fails_for_empty():
exception_match_str = re.escape("Working days should be non-empty")
with pytest.raises(ValueError, match=exception_match_str):
sut._get_rrule_days([])


@pytest.mark.parametrize(
"toggl_tally_object,expected_first_billable_date",
[
pytest.param(
dict(now=datetime(2023, 6, 18), invoice_day_of_month=19),
datetime(2023, 5, 19),
id="first_billable_date_inclusive",
),
pytest.param(
dict(now=datetime(2023, 6, 19), invoice_day_of_month=20),
datetime(2023, 5, 20),
id="first_billable_date_exclusive",
),
],
indirect=["toggl_tally_object"],
)
def test_toggl_tally_first_billable_date(
toggl_tally_object, expected_first_billable_date
):
assert toggl_tally_object.first_billable_date == expected_first_billable_date

0 comments on commit 1534031

Please sign in to comment.