Skip to content

Commit efff1aa

Browse files
committed
feat: Create end point last entries #215
1 parent f386c1e commit efff1aa

File tree

3 files changed

+95
-7
lines changed

3 files changed

+95
-7
lines changed

tests/time_tracker_api/time_entries/time_entries_namespace_test.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,26 @@ def test_list_all_time_entries(
158158
dao_get_all_mock.assert_called_once()
159159

160160

161+
def test_list_last_time_entries(
162+
client: FlaskClient, mocker: MockFixture, valid_header: dict
163+
):
164+
from time_tracker_api.time_entries.time_entries_namespace import (
165+
time_entries_dao,
166+
)
167+
168+
dao_get_all_mock = mocker.patch.object(
169+
time_entries_dao, 'get_last_projects_worked', return_value=[]
170+
)
171+
172+
response = client.get(
173+
"/time-entries/latest", headers=valid_header, follow_redirects=True
174+
)
175+
176+
assert HTTPStatus.OK == response.status_code
177+
assert [] == json.loads(response.data)
178+
dao_get_all_mock.assert_called_once()
179+
180+
161181
def test_get_time_entry_should_succeed_with_valid_id(
162182
client: FlaskClient, mocker: MockFixture, valid_header: dict
163183
):

time_tracker_api/time_entries/time_entries_model.py

Lines changed: 63 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,7 @@ def find_all_entries(
164164
conditions: dict = None,
165165
custom_sql_conditions: List[str] = None,
166166
date_range: dict = None,
167+
**kwargs,
167168
):
168169
conditions = conditions if conditions else {}
169170
custom_sql_conditions = (
@@ -182,6 +183,8 @@ def find_all_entries(
182183
conditions=conditions,
183184
custom_sql_conditions=custom_sql_conditions,
184185
custom_params=custom_params,
186+
max_count=kwargs.get("max_count", None),
187+
offset=kwargs.get("offset", 0),
185188
)
186189
return time_entries
187190

@@ -457,7 +460,8 @@ def get_all(self, conditions: dict = None, **kwargs) -> list:
457460
conditions.update({"owner_id": event_ctx.user_id})
458461

459462
custom_query = self.build_custom_query(
460-
is_admin=event_ctx.is_admin, conditions=conditions,
463+
is_admin=event_ctx.is_admin,
464+
conditions=conditions,
461465
)
462466
date_range = self.handle_date_filter_args(args=conditions)
463467
limit = conditions.get("limit", None)
@@ -470,14 +474,56 @@ def get_all(self, conditions: dict = None, **kwargs) -> list:
470474
max_count=limit,
471475
)
472476

477+
def get_last_projects_worked(
478+
self, conditions: dict = None, **kwargs
479+
) -> list:
480+
event_ctx = self.create_event_context("read-many")
481+
conditions.update({"owner_id": event_ctx.user_id})
482+
custom_query = self.build_custom_query(
483+
is_admin=event_ctx.is_admin,
484+
conditions=conditions,
485+
)
486+
date_range = self.handle_date_filter_args(args=conditions)
487+
488+
project_dao = projects_model.create_dao()
489+
projects = project_dao.get_all()
490+
projects_ids = [project.id for project in projects]
491+
492+
activity_dao = activities_model.create_dao()
493+
activities = activity_dao.get_all(
494+
visible_only=False,
495+
)
496+
497+
result = []
498+
for id_project in projects_ids:
499+
conditions.update({"project_id": id_project})
500+
501+
limit = 2
502+
latest = self.repository.find_all_entries(
503+
event_ctx,
504+
conditions=conditions,
505+
custom_sql_conditions=custom_query,
506+
date_range=date_range,
507+
max_count=limit,
508+
)
509+
510+
if len(latest) >= 1:
511+
result.append(latest[0])
512+
513+
add_activity_name_to_time_entries(result, activities)
514+
add_project_info_to_time_entries(result, projects)
515+
516+
return result
517+
473518
def get_all_paginated(self, conditions: dict = None, **kwargs) -> list:
474519
get_all_conditions = dict(conditions)
475520
get_all_conditions.pop("length")
476521
get_all_conditions.pop("start")
477522
event_ctx = self.create_event_context("read-many")
478523
get_all_conditions.update({"owner_id": event_ctx.user_id})
479524
custom_query = self.build_custom_query(
480-
is_admin=event_ctx.is_admin, conditions=get_all_conditions,
525+
is_admin=event_ctx.is_admin,
526+
conditions=get_all_conditions,
481527
)
482528
date_range = self.handle_date_filter_args(args=get_all_conditions)
483529
records_total = self.repository.count(
@@ -488,7 +534,8 @@ def get_all_paginated(self, conditions: dict = None, **kwargs) -> list:
488534
)
489535
conditions.update({"owner_id": event_ctx.user_id})
490536
custom_query = self.build_custom_query(
491-
is_admin=event_ctx.is_admin, conditions=conditions,
537+
is_admin=event_ctx.is_admin,
538+
conditions=conditions,
492539
)
493540
date_range = self.handle_date_filter_args(args=conditions)
494541
length = conditions.get("length", None)
@@ -532,7 +579,11 @@ def update(self, id, data: dict, description=None):
532579
time_entry = self.repository.find(id, event_ctx)
533580
self.check_whether_current_user_owns_item(time_entry)
534581

535-
return self.repository.partial_update(id, data, event_ctx,)
582+
return self.repository.partial_update(
583+
id,
584+
data,
585+
event_ctx,
586+
)
536587

537588
def stop(self, id):
538589
event_ctx = self.create_event_context("update", "Stop time entry")
@@ -542,7 +593,9 @@ def stop(self, id):
542593
self.check_time_entry_is_not_stopped(time_entry)
543594

544595
return self.repository.partial_update(
545-
id, {'end_date': current_datetime_str()}, event_ctx,
596+
id,
597+
{'end_date': current_datetime_str()},
598+
event_ctx,
546599
)
547600

548601
def restart(self, id):
@@ -553,15 +606,18 @@ def restart(self, id):
553606
self.check_time_entry_is_not_started(time_entry)
554607

555608
return self.repository.partial_update(
556-
id, {'end_date': None}, event_ctx,
609+
id,
610+
{'end_date': None},
611+
event_ctx,
557612
)
558613

559614
def delete(self, id):
560615
event_ctx = self.create_event_context("delete")
561616
time_entry = self.repository.find(id, event_ctx)
562617
self.check_whether_current_user_owns_item(time_entry)
563618
self.repository.delete(
564-
id, event_ctx,
619+
id,
620+
event_ctx,
565621
)
566622

567623
def find_running(self):

time_tracker_api/time_entries/time_entries_namespace.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,18 @@ def post(self):
256256
return time_entries_dao.create(ns.payload), HTTPStatus.CREATED
257257

258258

259+
@ns.route('/latest')
260+
class TimeEntries(Resource):
261+
@ns.doc('list_latest_time_entries')
262+
@ns.expect(attributes_filter)
263+
@ns.marshal_list_with(time_entry)
264+
@ns.response(HTTPStatus.NOT_FOUND, 'Time entry not found')
265+
def get(self):
266+
"""List the latest time entries"""
267+
conditions = attributes_filter.parse_args()
268+
return time_entries_dao.get_last_projects_worked(conditions=conditions)
269+
270+
259271
@ns.route('/<string:id>')
260272
@ns.response(HTTPStatus.NOT_FOUND, 'This time entry does not exist')
261273
@ns.response(HTTPStatus.UNPROCESSABLE_ENTITY, 'The id has an invalid format')

0 commit comments

Comments
 (0)