Add user application API
issue5783 review31421002
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
* Add user application API
|
||||
* Remove tree structure on Work
|
||||
* Add optional origin on Work
|
||||
|
||||
|
||||
+6
-1
@@ -1,9 +1,13 @@
|
||||
# This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
# this repository contains the full copyright notices and license terms.
|
||||
|
||||
from trytond.pool import Pool
|
||||
|
||||
from .work import *
|
||||
from .line import *
|
||||
from .user import *
|
||||
from . import routes
|
||||
|
||||
__all__ = ['register', 'routes']
|
||||
|
||||
|
||||
def register():
|
||||
@@ -16,6 +20,7 @@ def register():
|
||||
HoursEmployeeContext,
|
||||
HoursEmployeeWeekly,
|
||||
HoursEmployeeMonthly,
|
||||
UserApplication,
|
||||
module='timesheet', type_='model')
|
||||
Pool.register(
|
||||
EnterLines,
|
||||
|
||||
@@ -25,3 +25,8 @@ A timesheet line express the fact that one employee spend a part of
|
||||
his/her time on a specific work at a given date. An optional
|
||||
Description field allow to give some extra informations about what
|
||||
have been done.
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
user_application
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
Timesheet User Application
|
||||
##########################
|
||||
|
||||
The timesheet module defines some routes for user applications:
|
||||
|
||||
- `GET` `/<database_name>/timesheet/employees`:
|
||||
return the list of the user employees as dictionary with the keys: `id`
|
||||
and `name`.
|
||||
|
||||
- `GET` `/<database_name>/timesheet/employee/<int:employee>/works`:
|
||||
return the list of works available for the employee. The works are
|
||||
dictionary with keys: `id`, `name`, `start` and `end`. The dates are in
|
||||
the format `%Y-%m-%d`.
|
||||
|
||||
- `GET` `/<database_name>/timesheet/employee/<int:employee>/lines/<date>`:
|
||||
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.
|
||||
|
||||
- `POST` `/<database_name>/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.
|
||||
|
||||
- `PUT` `/<database_name>/timesheet/line/<int:line>`:
|
||||
Update the line using the data like for the `POST`.
|
||||
|
||||
- `DELETE` `/<database_name>/timesheet/line/<int:line>`:
|
||||
Delete the line
|
||||
@@ -0,0 +1,119 @@
|
||||
# This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
# this repository contains the full copyright notices and license terms.
|
||||
import datetime
|
||||
|
||||
from werkzeug.exceptions import abort, Response
|
||||
|
||||
from trytond.transaction import Transaction
|
||||
from trytond.wsgi import app
|
||||
from trytond.protocols.wrappers import with_pool, with_transaction, \
|
||||
user_application
|
||||
|
||||
timesheet_application = user_application('timesheet')
|
||||
|
||||
|
||||
@app.route('/<database_name>/timesheet/employees', methods=['GET'])
|
||||
@with_pool
|
||||
@with_transaction()
|
||||
@timesheet_application
|
||||
def timesheet_employees(request, pool):
|
||||
User = pool.get('res.user')
|
||||
user = User(Transaction().user)
|
||||
return [{'id': e.id, 'name': e.rec_name} for e in user.employees]
|
||||
|
||||
|
||||
@app.route('/<database_name>/timesheet/employee/<int:employee>/works',
|
||||
methods=['GET'])
|
||||
@with_pool
|
||||
@with_transaction()
|
||||
@timesheet_application
|
||||
def timesheet_works(request, pool, employee):
|
||||
Work = pool.get('timesheet.work')
|
||||
Employee = pool.get('company.employee')
|
||||
employee = Employee(employee)
|
||||
with Transaction().set_context(
|
||||
company=employee.company.id, employee=employee.id):
|
||||
works = Work.search([])
|
||||
return [{
|
||||
'id': w.id,
|
||||
'name': w.rec_name,
|
||||
'start': (w.timesheet_start_date.strftime('%Y-%m-%d')
|
||||
if w.timesheet_start_date else None),
|
||||
'end': (w.timesheet_end_date.strftime('%Y-%m-%d')
|
||||
if w.timesheet_end_date else None),
|
||||
} for w in works]
|
||||
|
||||
|
||||
@app.route('/<database_name>/timesheet/employee/<int:employee>/lines/<date>',
|
||||
methods=['GET'])
|
||||
@with_pool
|
||||
@with_transaction()
|
||||
@timesheet_application
|
||||
def timesheet_lines(request, pool, employee, date):
|
||||
User = pool.get('res.user')
|
||||
Employee = pool.get('company.employee')
|
||||
Line = pool.get('timesheet.line')
|
||||
|
||||
employee = Employee(employee)
|
||||
date = datetime.datetime.strptime(date, '%Y-%m-%d').date()
|
||||
user = User(Transaction().user)
|
||||
if employee not in user.employees:
|
||||
abort(403)
|
||||
|
||||
with Transaction().set_context(
|
||||
company=employee.company.id, employee=employee.id):
|
||||
lines = Line.search([
|
||||
('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]
|
||||
|
||||
|
||||
@app.route('/<database_name>/timesheet/line/<int:line>',
|
||||
methods=['PUT', 'DELETE'])
|
||||
@app.route('/<database_name>/timesheet/line', methods=['POST'])
|
||||
@with_pool
|
||||
@with_transaction()
|
||||
@timesheet_application
|
||||
def timesheet(request, pool, line=None):
|
||||
Line = pool.get('timesheet.line')
|
||||
User = pool.get('res.user')
|
||||
Employee = pool.get('company.employee')
|
||||
if request.method in {'POST', 'PUT'}:
|
||||
data = request.parsed_data
|
||||
if 'employee' in data:
|
||||
employee = Employee(data['employee'])
|
||||
data['company'] = employee.company.id
|
||||
else:
|
||||
employee = User(Transaction().user).employee
|
||||
if 'date' in data:
|
||||
data['date'] = datetime.datetime.strptime(
|
||||
data['date'], '%Y-%m-%d').date()
|
||||
if 'duration' in data:
|
||||
data['duration'] = datetime.timedelta(
|
||||
seconds=data['duration'])
|
||||
with Transaction().set_context(
|
||||
company=employee.company.id, employee=employee.id):
|
||||
if not line:
|
||||
line, = Line.create([request.parsed_data])
|
||||
else:
|
||||
line = Line(line)
|
||||
Line.write([line], request.parsed_data)
|
||||
return {
|
||||
'id': line.id,
|
||||
'work': line.work.id,
|
||||
'work.name': line.work.rec_name,
|
||||
'duration': line.duration.total_seconds(),
|
||||
'description': line.description,
|
||||
}
|
||||
else:
|
||||
with Transaction().set_context(
|
||||
company=line.company.id, employee=line.employee.id):
|
||||
Line.delete([line])
|
||||
return Response(None, 204)
|
||||
@@ -0,0 +1,15 @@
|
||||
# This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
# this repository contains the full copyright notices and license terms.
|
||||
from trytond.pool import PoolMeta
|
||||
|
||||
__all__ = ['UserApplication']
|
||||
|
||||
|
||||
class UserApplication:
|
||||
__metaclass__ = PoolMeta
|
||||
__name__ = 'res.user.application'
|
||||
|
||||
@classmethod
|
||||
def __setup__(cls):
|
||||
super(UserApplication, cls).__setup__()
|
||||
cls.application.selection.append(('timesheet', 'Timesheet'))
|
||||
Reference in New Issue
Block a user