Skip to content

Commit 0181ca9

Browse files
committed
feat: Implement filters on time-entries by uuid (close #154)
2 parents 5780b98 + 7659c9f commit 0181ca9

File tree

6 files changed

+72
-4
lines changed

6 files changed

+72
-4
lines changed

commons/data_access_layer/cosmos_db.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -408,6 +408,10 @@ def get_current_month() -> int:
408408
return datetime.now().month
409409

410410

411+
def get_current_day() -> int:
412+
return datetime.now().day
413+
414+
411415
def get_date_range_of_month(year: int, month: int) -> Dict[str, str]:
412416
first_day_of_month = 1
413417
start_date = datetime(

tests/time_tracker_api/time_entries/time_entries_namespace_test.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -482,6 +482,7 @@ def test_get_running_should_call_find_running(
482482
'find_running',
483483
return_value=fake_time_entry,
484484
)
485+
time_entries_dao.stop_time_entry_if_was_left_running = Mock()
485486

486487
response = client.get(
487488
"/time-entries/running", headers=valid_header, follow_redirects=True

time_tracker_api/time_entries/time_entries_model.py

Lines changed: 52 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
from dataclasses import dataclass, field
33
from typing import List, Callable
44
from azure.cosmos import PartitionKey
5+
from azure.cosmos.exceptions import CosmosResourceNotFoundError
56
from flask_restplus import abort
67
from flask_restplus._http import HTTPStatus
78

@@ -11,19 +12,25 @@
1112
CustomError,
1213
CosmosDBModel,
1314
current_datetime_str,
15+
datetime_str,
1416
get_date_range_of_month,
1517
get_current_year,
1618
get_current_month,
19+
get_current_day,
1720
)
1821
from commons.data_access_layer.database import EventContext
22+
from time_tracker_api.activities import activities_model
1923

20-
from utils.extend_model import add_project_name_to_time_entries
24+
from utils.extend_model import (
25+
add_project_name_to_time_entries,
26+
add_activity_name_to_time_entries,
27+
)
2128
from utils import worked_time
29+
from utils.worked_time import str_to_datetime
2230
from utils.extend_model import (
2331
create_in_condition,
2432
create_custom_query_from_str,
2533
)
26-
2734
from time_tracker_api.projects.projects_model import ProjectCosmosDBModel
2835
from time_tracker_api.projects import projects_model
2936
from time_tracker_api.database import CRUDDao, APICosmosDBDao
@@ -78,6 +85,22 @@ def __init__(self, data): # pragma: no cover
7885
def running(self):
7986
return self.end_date is None
8087

88+
@property
89+
def was_left_running(self) -> bool:
90+
start_date = str_to_datetime(self.start_date)
91+
return (
92+
get_current_day() > start_date.day
93+
or get_current_month() > start_date.month
94+
or get_current_year() > start_date.year
95+
)
96+
97+
@property
98+
def start_date_at_midnight(self) -> str:
99+
start_date = str_to_datetime(self.start_date)
100+
return datetime_str(
101+
start_date.replace(hour=23, minute=59, second=59, microsecond=0)
102+
)
103+
81104
def __add__(self, other):
82105
if type(other) is ProjectCosmosDBModel:
83106
time_entry = self.__class__
@@ -150,6 +173,10 @@ def find_all(
150173
custom_sql_conditions=[custom_conditions]
151174
)
152175
add_project_name_to_time_entries(time_entries, projects)
176+
177+
activity_dao = activities_model.create_dao()
178+
activities = activity_dao.get_all()
179+
add_activity_name_to_time_entries(time_entries, activities)
153180
return time_entries
154181

155182
def on_create(self, new_item_data: dict, event_context: EventContext):
@@ -296,6 +323,21 @@ def check_time_entry_is_not_started(self, data):
296323
"The specified time entry is already running",
297324
)
298325

326+
def stop_time_entry_if_was_left_running(
327+
self, time_entry: TimeEntryCosmosDBModel
328+
):
329+
330+
if time_entry.was_left_running:
331+
end_date = time_entry.start_date_at_midnight
332+
event_ctx = self.create_event_context(
333+
"update", "Stop time-entry that was left running"
334+
)
335+
336+
self.repository.partial_update(
337+
time_entry.id, {'end_date': end_date}, event_ctx
338+
)
339+
raise CosmosResourceNotFoundError()
340+
299341
def get_all(self, conditions: dict = None, **kwargs) -> list:
300342
event_ctx = self.create_event_context("read-many")
301343
conditions.update({"owner_id": event_ctx.user_id})
@@ -381,9 +423,16 @@ def delete(self, id):
381423

382424
def find_running(self):
383425
event_ctx = self.create_event_context("find_running")
384-
return self.repository.find_running(
426+
time_entry = self.repository.find_running(
385427
event_ctx.tenant_id, event_ctx.user_id
386428
)
429+
# TODO: we need to make this work using the users time zone
430+
# This is disabled as part of https://github.com/ioet/time-tracker-backend/issues/160
431+
# Remove all these comments after implementing
432+
# https://github.com/ioet/time-tracker-backend/issues/159
433+
# https://github.com/ioet/time-tracker-backend/issues/162
434+
# self.stop_time_entry_if_was_left_running(time_entry)
435+
return time_entry
387436

388437
def get_worked_time(self, conditions: dict = {}):
389438
event_ctx = self.create_event_context(

time_tracker_api/time_entries/time_entries_namespace.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,13 @@
122122
description='Name of the project where time-entry was registered',
123123
example=faker.word(['mobile app', 'web app']),
124124
),
125+
'activity_name': fields.String(
126+
required=False,
127+
title='Activity Name',
128+
max_length=50,
129+
description='Name of the activity associated with the time-entry',
130+
example=faker.word(['development', 'QA']),
131+
),
125132
}
126133
time_entry_response_fields.update(common_fields)
127134

time_tracker_api/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = '0.14.1'
1+
__version__ = '0.14.3'

utils/extend_model.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,13 @@ def add_project_name_to_time_entries(time_entries, projects):
3131
setattr(time_entry, 'project_name', project.name)
3232

3333

34+
def add_activity_name_to_time_entries(time_entries, activities):
35+
for time_entry in time_entries:
36+
for activity in activities:
37+
if time_entry.activity_id == activity.id:
38+
setattr(time_entry, 'activity_name', activity.name)
39+
40+
3441
def create_in_condition(
3542
data_object: list, attr_to_filter: str = "", first_attr: str = "c.id"
3643
):

0 commit comments

Comments
 (0)