Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
feat: Check whether time entry is running or not when start and stop
  • Loading branch information
EliuX committed Apr 30, 2020
commit e2d7eb1929fe77c0065c77a9d3b5905fafc19ee1
2 changes: 1 addition & 1 deletion time_tracker_api/database.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ def create(self, project):
raise NotImplementedError # pragma: no cover

@abc.abstractmethod
def update(self, id, data):
def update(self, id, data, description=None):
raise NotImplementedError # pragma: no cover

@abc.abstractmethod
Expand Down
38 changes: 36 additions & 2 deletions time_tracker_api/time_entries/time_entries_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,14 @@ def current_user_id():
def find_running(self):
pass

@abc.abstractmethod
def stop(self, id: str):
pass

@abc.abstractmethod
def restart(self, id: str):
pass


container_definition = {
'id': 'time_entry',
Expand Down Expand Up @@ -169,6 +177,20 @@ def check_whether_current_user_owns_item(cls, data: dict):
raise CustomError(HTTPStatus.FORBIDDEN,
"The current user is not the owner of this time entry")

@classmethod
def checks_owner_and_is_not_stopped(cls, data: dict):
cls.check_whether_current_user_owns_item(data)

if data.get('end_date') is not None:
raise CustomError(HTTPStatus.UNPROCESSABLE_ENTITY, "The specified time entry is already stopped")

@classmethod
def checks_owner_and_is_not_started(cls, data: dict):
cls.check_whether_current_user_owns_item(data)

if data.get('end_date') is None:
raise CustomError(HTTPStatus.UNPROCESSABLE_ENTITY, "The specified time entry is already running")

def get_all(self, conditions: dict = {}) -> list:
event_ctx = self.create_event_context("read-many")
conditions.update({"owner_id": event_ctx.user_id})
Expand All @@ -182,11 +204,23 @@ def create(self, data: dict):
event_ctx = self.create_event_context("create")
return self.repository.create(data, event_ctx)

def update(self, id, data: dict):
event_ctx = self.create_event_context("update")
def update(self, id, data: dict, description=None):
event_ctx = self.create_event_context("update", description)
return self.repository.partial_update(id, data, event_ctx,
peeker=self.check_whether_current_user_owns_item)

def stop(self, id):
event_ctx = self.create_event_context("update", "Stop time entry")
return self.repository.partial_update(id, {
'end_date': current_datetime_str()
}, event_ctx, peeker=self.checks_owner_and_is_not_stopped)

def restart(self, id):
event_ctx = self.create_event_context("update", "Restart time entry")
return self.repository.partial_update(id, {
'end_date': None
}, event_ctx, peeker=self.checks_owner_and_is_not_started)

def delete(self, id):
event_ctx = self.create_event_context("delete")
self.repository.delete(id, event_ctx, peeker=self.check_whether_current_user_owns_item)
Expand Down
12 changes: 4 additions & 8 deletions time_tracker_api/time_entries/time_entries_namespace.py
Original file line number Diff line number Diff line change
Expand Up @@ -163,30 +163,26 @@ def delete(self, id):

@ns.route('/<string:id>/stop')
@ns.response(HTTPStatus.NOT_FOUND, 'Running time entry not found')
@ns.response(HTTPStatus.UNPROCESSABLE_ENTITY, 'The id has an invalid format')
@ns.response(HTTPStatus.UNPROCESSABLE_ENTITY, '"The specified time entry is already stopped')
@ns.param('id', 'The unique identifier of a running time entry')
class StopTimeEntry(Resource):
@ns.doc('stop_time_entry')
@ns.marshal_with(time_entry)
def post(self, id):
"""Stop a running time entry"""
return time_entries_dao.update(id, {
'end_date': current_datetime_str()
})
return time_entries_dao.stop(id)


@ns.route('/<string:id>/restart')
@ns.response(HTTPStatus.NOT_FOUND, 'Stopped time entry not found')
@ns.response(HTTPStatus.UNPROCESSABLE_ENTITY, 'The id has an invalid format')
@ns.response(HTTPStatus.UNPROCESSABLE_ENTITY, 'The specified time entry is already running')
@ns.param('id', 'The unique identifier of a stopped time entry')
class RestartTimeEntry(Resource):
@ns.doc('restart_time_entry')
@ns.marshal_with(time_entry)
def post(self, id):
"""Restart a time entry"""
return time_entries_dao.update(id, {
'end_date': None
})
return time_entries_dao.restart(id)


@ns.route('/running')
Expand Down