diff --git a/time_tracker_api/activities/activities_api.py b/time_tracker_api/activities/activities_api.py index b9578842..9a5ab4ee 100644 --- a/time_tracker_api/activities/activities_api.py +++ b/time_tracker_api/activities/activities_api.py @@ -4,28 +4,56 @@ # Activity Model activity = ns.model('Activity', { - 'id': fields.String(readOnly=True, required=True, title='Identifier', - description='The unique id of the activity'), - 'name': fields.String(required=True, title='Name', max_length=50, - description='Canonical name of the activity'), - 'description': fields.String(title='Description', - description='Comments about the activity'), - 'tenant_id': fields.String(required=True, title='Tenant', max_length=64, - description='The tenant this belongs to') + 'name': fields.String( + required=True, + title='Name', + max_length=50, + description='Canonical name of the activity', + ), + 'description': fields.String( + title='Description', + description='Comments about the activity', + ), +}) + +activity_response = ns.inherit('ActivityResponse', activity, { + 'id': fields.String( + readOnly=True, + required=True, + title='Identifier', + description='The unique identifier', + ), + 'created_at': fields.Date( + readOnly=True, + title='Created', + description='Date of creation' + ), + 'created_by': fields.String( + readOnly=True, + title='Creator', + max_length=64, + description='User that created it', + ), + 'tenant_id': fields.String( + readOnly=True, + title='Tenant', + max_length=64, + description='The tenant this belongs to', + ), }) -@ns.route('/') +@ns.route('') class Activities(Resource): @ns.doc('list_activities') - @ns.marshal_list_with(activity, code=200) + @ns.marshal_list_with(activity_response, code=200) def get(self): """List all available activities""" return [] @ns.doc('create_activity') @ns.expect(activity) - @ns.marshal_with(activity, code=201) + @ns.marshal_with(activity_response, code=201) @ns.response(400, 'Invalid format of the attributes of the activity.') def post(self): """Create a single activity""" @@ -37,7 +65,7 @@ def post(self): @ns.param('id', 'The unique identifier of the activity') class Activity(Resource): @ns.doc('get_activity') - @ns.marshal_with(activity) + @ns.marshal_with(activity_response) def get(self, id): """Retrieve all the data of a single activity""" return {} @@ -51,7 +79,7 @@ def delete(self, id): @ns.doc('put_activity') @ns.response(400, 'Invalid format of the attributes of the activity.') @ns.expect(activity) - @ns.marshal_with(activity) + @ns.marshal_with(activity_response) def put(self, id): """Updates an activity""" return ns.payload diff --git a/time_tracker_api/api.py b/time_tracker_api/api.py index 4f2742fa..8fbd74d7 100644 --- a/time_tracker_api/api.py +++ b/time_tracker_api/api.py @@ -10,3 +10,6 @@ from time_tracker_api.activities import activities_api api.add_namespace(activities_api.ns) + +from time_tracker_api.time_entries import time_entry_api +api.add_namespace(time_entry_api.ns) diff --git a/time_tracker_api/time_entries/time_entry_api.py b/time_tracker_api/time_entries/time_entry_api.py new file mode 100644 index 00000000..95434da4 --- /dev/null +++ b/time_tracker_api/time_entries/time_entry_api.py @@ -0,0 +1,134 @@ +from flask_restplus import fields, Resource, Namespace + +ns = Namespace('time-entries', description='API for time entries') + +# TimeEntry Model +time_entry = ns.model('TimeEntry', { + 'project_id': fields.String( + required=True, + title='Project', + max_length=64, + description='The id of the selected project', + ), + 'activity_id': fields.String( + required=False, + title='Activity', + max_length=64, + description='The id of the selected activity', + ), + 'technologies': fields.String( + required=True, + title='Technologies', + max_length=64, + description='Canonical names of the used technologies during this period', + ), + 'description': fields.String( + title='Comments', + description='Comments about the time entry' + ), + 'start_date': fields.DateTime( + required=True, + title='Start date', + description='When the user started doing this activity', + ), + 'end_date': fields.DateTime( + required=True, + title='End date', + description='When the user ended doing this activity', + ), +}) + +time_entry_response = ns.inherit('TimeEntryResponse', time_entry, { + 'id': fields.String( + readOnly=True, + required=True, + title='Identifier', + description='The unique identifier', + ), + 'running': fields.Boolean( + readOnly=True, + title='Is it running?', + description='Whether this time entry is currently running or not' + ), + 'created_at': fields.Date( + readOnly=True, + title='Created', + description='Date of creation' + ), + 'created_by': fields.String( + readOnly=True, + title='Creator', + max_length=64, + description='User that created it', + ), + 'tenant_id': fields.String( + readOnly=True, + title='Tenant', + max_length=64, + description='The tenant this belongs to', + ), +}) + + +@ns.route('') +class TimeEntries(Resource): + @ns.doc('list_time_entries') + @ns.marshal_list_with(time_entry_response, code=200) + def get(self): + """List all available time entries""" + return [] + + @ns.doc('create_time_entry') + @ns.expect(time_entry) + @ns.marshal_with(time_entry_response, code=201) + @ns.response(400, 'Invalid format of the attributes of the time entry') + def post(self): + """Starts a time entry by creating it""" + return ns.payload, 201 + + +@ns.route('/') +@ns.response(404, 'Time entry not found') +@ns.param('id', 'The unique identifier of the time entry') +class TimeEntry(Resource): + @ns.doc('get_time_entry') + @ns.marshal_with(time_entry_response) + def get(self, id): + """Retrieve all the data of a single time entry""" + return {} + + @ns.doc('delete_time_entry') + @ns.response(204, 'The time entry was deleted successfully (No content is returned)') + def delete(self, id): + """Deletes a time entry""" + return None, 204 + + @ns.doc('put_time_entry') + @ns.response(400, 'Invalid format of the attributes of the time entry.') + @ns.expect(time_entry) + @ns.marshal_with(time_entry_response) + def put(self, id): + """Updates a time entry""" + return ns.payload + + +@ns.route('/stop') +@ns.response(404, 'Running time entry not found') +@ns.param('id', 'The unique identifier of a running time entry') +class StopTimeEntry(Resource): + @ns.doc('stop_time_entry') + @ns.response(204, 'The time entry was stopped successfully (No content is returned)') + def post(self, id): + """Stops a running time entry""" + return None, 204 + + +@ns.route('/continue') +@ns.response(404, 'Stopped time entry not found') +@ns.param('id', 'The unique identifier of a stopped time entry') +class ContinueTimeEntry(Resource): + @ns.doc('continue_time_entry') + @ns.response(204, 'The time entry was continued successfully (No content is returned)') + def post(self, id): + """Restart an stopped time entry""" + return None, 204