Skip to content

Commit 91cd576

Browse files
committed
feat: Create end point last entries #215
1 parent 59a6122 commit 91cd576

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,8 @@ def find_all_entries(
164164
conditions=conditions,
165165
custom_sql_conditions=custom_sql_conditions,
166166
custom_params=custom_params,
167+
max_count=kwargs.get("max_count", None),
168+
offset=kwargs.get("offset", 0),
167169
)
168170
return time_entries
169171

@@ -173,6 +175,7 @@ def count(
173175
conditions: dict = None,
174176
custom_sql_conditions: List[str] = None,
175177
date_range: dict = None,
178+
**kwargs,
176179
):
177180
conditions = conditions if conditions else {}
178181
custom_sql_conditions = (
@@ -424,7 +427,8 @@ def get_all(self, conditions: dict = None, **kwargs) -> list:
424427
conditions.update({"owner_id": event_ctx.user_id})
425428

426429
custom_query = self.build_custom_query(
427-
is_admin=event_ctx.is_admin, conditions=conditions,
430+
is_admin=event_ctx.is_admin,
431+
conditions=conditions,
428432
)
429433
date_range = self.handle_date_filter_args(args=conditions)
430434
limit = conditions.get("limit", None)
@@ -437,14 +441,56 @@ def get_all(self, conditions: dict = None, **kwargs) -> list:
437441
max_count=limit,
438442
)
439443

444+
def get_last_projects_worked(
445+
self, conditions: dict = None, **kwargs
446+
) -> list:
447+
event_ctx = self.create_event_context("read-many")
448+
conditions.update({"owner_id": event_ctx.user_id})
449+
custom_query = self.build_custom_query(
450+
is_admin=event_ctx.is_admin,
451+
conditions=conditions,
452+
)
453+
date_range = self.handle_date_filter_args(args=conditions)
454+
455+
project_dao = projects_model.create_dao()
456+
projects = project_dao.get_all()
457+
projects_ids = [project.id for project in projects]
458+
459+
activity_dao = activities_model.create_dao()
460+
activities = activity_dao.get_all(
461+
visible_only=False,
462+
)
463+
464+
result = []
465+
for id_project in projects_ids:
466+
conditions.update({"project_id": id_project})
467+
468+
limit = 2
469+
latest = self.repository.find_all_entries(
470+
event_ctx,
471+
conditions=conditions,
472+
custom_sql_conditions=custom_query,
473+
date_range=date_range,
474+
max_count=limit,
475+
)
476+
477+
if len(latest) >= 1:
478+
result.append(latest[0])
479+
480+
add_activity_name_to_time_entries(result, activities)
481+
add_project_info_to_time_entries(result, projects)
482+
483+
return result
484+
440485
def get_all_paginated(self, conditions: dict = None, **kwargs) -> list:
441486
get_all_conditions = dict(conditions)
442487
get_all_conditions.pop("length")
443488
get_all_conditions.pop("start")
444489
event_ctx = self.create_event_context("read-many")
445490
get_all_conditions.update({"owner_id": event_ctx.user_id})
446491
custom_query = self.build_custom_query(
447-
is_admin=event_ctx.is_admin, conditions=get_all_conditions,
492+
is_admin=event_ctx.is_admin,
493+
conditions=get_all_conditions,
448494
)
449495
date_range = self.handle_date_filter_args(args=get_all_conditions)
450496
records_total = self.repository.count(
@@ -455,7 +501,8 @@ def get_all_paginated(self, conditions: dict = None, **kwargs) -> list:
455501
)
456502
conditions.update({"owner_id": event_ctx.user_id})
457503
custom_query = self.build_custom_query(
458-
is_admin=event_ctx.is_admin, conditions=conditions,
504+
is_admin=event_ctx.is_admin,
505+
conditions=conditions,
459506
)
460507
date_range = self.handle_date_filter_args(args=conditions)
461508
length = conditions.get("length", None)
@@ -499,7 +546,11 @@ def update(self, id, data: dict, description=None):
499546
time_entry = self.repository.find(id, event_ctx)
500547
self.check_whether_current_user_owns_item(time_entry)
501548

502-
return self.repository.partial_update(id, data, event_ctx,)
549+
return self.repository.partial_update(
550+
id,
551+
data,
552+
event_ctx,
553+
)
503554

504555
def stop(self, id):
505556
event_ctx = self.create_event_context("update", "Stop time entry")
@@ -509,7 +560,9 @@ def stop(self, id):
509560
self.check_time_entry_is_not_stopped(time_entry)
510561

511562
return self.repository.partial_update(
512-
id, {'end_date': current_datetime_str()}, event_ctx,
563+
id,
564+
{'end_date': current_datetime_str()},
565+
event_ctx,
513566
)
514567

515568
def restart(self, id):
@@ -520,15 +573,18 @@ def restart(self, id):
520573
self.check_time_entry_is_not_started(time_entry)
521574

522575
return self.repository.partial_update(
523-
id, {'end_date': None}, event_ctx,
576+
id,
577+
{'end_date': None},
578+
event_ctx,
524579
)
525580

526581
def delete(self, id):
527582
event_ctx = self.create_event_context("delete")
528583
time_entry = self.repository.find(id, event_ctx)
529584
self.check_whether_current_user_owns_item(time_entry)
530585
self.repository.delete(
531-
id, event_ctx,
586+
id,
587+
event_ctx,
532588
)
533589

534590
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)