diff --git a/CHANGELOG b/CHANGELOG index d625158472..3119c030e2 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,4 @@ +* Add UUID on line for synchronisation * Remove support for Python 2.7 Version 4.8.0 - 2018-04-23 diff --git a/doc/user_application.rst b/doc/user_application.rst index d70f3ea62b..9a3dc9f938 100644 --- a/doc/user_application.rst +++ b/doc/user_application.rst @@ -15,11 +15,13 @@ The timesheet module defines some routes for user applications: - `GET` `//timesheet/employee//lines/`: return the list of timesheet lines for the employee at the date (`%Y-%m-%d'). The lines are dictionary with keys: `id`, `work`, - `work.name`, `duration` and `description`. The duration is in seconds. + `work.name`, `duration`, `description` and `uuid`. The duration is in + seconds. - `POST` `//timesheet/line`: Create a line using the data as dictionary of value. The date must be in - the format `%Y-%m-%d` and the `duration` in seconds. + the format `%Y-%m-%d` and the `duration` in seconds. If a `uuid` value is + provided, it will update the record if found instead of create a new one. - `PUT` `//timesheet/line/`: Update the line using the data like for the `POST`. diff --git a/line.py b/line.py index a45106e142..0cf5744740 100644 --- a/line.py +++ b/line.py @@ -7,7 +7,7 @@ from sql import Literal from sql.aggregate import Max, Sum from sql.functions import Extract, CharLength -from trytond.model import ModelView, ModelSQL, fields +from trytond.model import ModelView, ModelSQL, fields, Unique from trytond.wizard import Wizard, StateView, StateAction, Button from trytond.pyson import Eval, PYSONEncoder, Date from trytond.transaction import Transaction @@ -56,10 +56,16 @@ class Line(ModelSQL, ModelView): help="The work on which the time is spent.") description = fields.Char('Description', help="Additional description of the work done.") + uuid = fields.Char("UUID", readonly=True) @classmethod def __setup__(cls): super(Line, cls).__setup__() + t = cls.__table__() + cls._sql_constraints = [ + ('uuid_unique', Unique(t, t.uuid), + "The UUID of timesheet line must be unique."), + ] cls._order.insert(0, ('date', 'DESC')) cls._error_messages.update({ 'duration_positive': ( @@ -136,6 +142,16 @@ class Line(ModelSQL, ModelView): def hours(self): return self.duration.total_seconds() / 60 / 60 + def to_json(self): + return { + 'id': self.id, + 'work': self.work.id, + 'work.name': self.work.rec_name, + 'duration': self.duration.total_seconds(), + 'description': self.description, + 'uuid': self.uuid, + } + class EnterLinesStart(ModelView): 'Enter Lines' diff --git a/routes.py b/routes.py index b4ec45bc18..7276eaf187 100644 --- a/routes.py +++ b/routes.py @@ -69,13 +69,7 @@ def timesheet_lines(request, pool, employee, date): ('employee', '=', employee.id), ('date', '=', date), ]) - return [{ - 'id': l.id, - 'work': l.work.id, - 'work.name': l.work.rec_name, - 'duration': l.duration.total_seconds(), - 'description': l.description, - } for l in lines] + return [l.to_json() for l in lines] @app.route('//timesheet/line/', @@ -90,6 +84,14 @@ def timesheet(request, pool, line=None): Employee = pool.get('company.employee') if request.method in {'POST', 'PUT'}: data = request.parsed_data.copy() + + if not line and data.get('uuid'): + lines = Line.search([ + ('uuid', '=', data['uuid']), + ]) + if lines: + line, = lines + if 'employee' in data: employee = Employee(data['employee']) data['company'] = employee.company.id @@ -115,13 +117,7 @@ def timesheet(request, pool, line=None): return Response(None, 204) line, = lines Line.write(lines, data) - return { - 'id': line.id, - 'work': line.work.id, - 'work.name': line.work.rec_name, - 'duration': line.duration.total_seconds(), - 'description': line.description, - } + return line.to_json() else: with Transaction().set_user(0): lines = Line.search([('id', '=', line)])