1
votes

I'm trying to make a module to manage travel leaves for employees.

What I need to do is adding extra float field in hr.employee module of 'available_tickets' . To be allocated from other module named "travel_request". How to do this? Here's my code:

class travel_request(osv.osv):

    _name = 'travel.request'

    _columns = {

        'no_tickets': fields.float('Number of Tickets'),

     }

class hr_employee(osv.osv):
_inherit="hr.employee"


def _get_tickets(self, cr, uid, ids, field_name, args, context=None):
    res = {}
    tickets_obj = self.pool.get('travel.request')
    tickets_ids = self.pool.get('travel.request').search(cr, uid, [('user_id', '=', uid), ('state', '=', 'validate')])
    for t_id in tickets_ids :
        emp_ticket = tickets_obj.browse(cr, uid, t_id, context=context)

    res['available_tickets'] = emp_ticket.no_tickets
    return res    


_columns = {
    'available_tickets': fields.function(_get_tickets, string='Available Tickets', type="float", store=True),
}

I tried also this method:

def _get_tickets(self, cr, uid, ids, field_name, args, context=None):
    res = {}
    tickets_obj = self.pool.get('travel.request')
    for record in self.browse(cr, uid, ids, context=None):
        tickets_ids = tickets_obj.search(cr, uid, [('user_id', '=', uid), ('state', '=', 'validate')], ids, context=None)
        emp_ticket = tickets_obj.browse(cr, uid, tickets_ids[0], context=None )
        res['available_tickets'] = emp_ticket.no_tickets        
    return res 

But nothing happened, I don't know what is wrong.. can anyone help me to fix it

Here's the error message:

2016-02-16 13:29:14,549 27608 ERROR test2_travel openerp.http: Exception during JSON request handling.
Traceback (most recent call last):
  File "/opt/odoo8/odoo/openerp/http.py", line 537, in _handle_exception
    return super(JsonRequest, self)._handle_exception(exception)
  File "/opt/odoo8/odoo/openerp/http.py", line 574, in dispatch
    result = self._call_function(**self.params)
  File "/opt/odoo8/odoo/openerp/http.py", line 310, in _call_function
    return checked_call(self.db, *args, **kwargs)
  File "/opt/odoo8/odoo/openerp/service/model.py", line 118, in wrapper
    return f(dbname, *args, **kwargs)
  File "/opt/odoo8/odoo/openerp/http.py", line 307, in checked_call
    return self.endpoint(*a, **kw)
  File "/opt/odoo8/odoo/openerp/http.py", line 803, in __call__
    return self.method(*args, **kw)
  File "/opt/odoo8/odoo/openerp/http.py", line 403, in response_wrap
    response = f(*args, **kw)
  File "/opt/odoo8/odoo/addons/web/controllers/main.py", line 944, in call_kw
    return self._call_kw(model, method, args, kwargs)
  File "/opt/odoo8/odoo/addons/web/controllers/main.py", line 936, in _call_kw
    return getattr(request.registry.get(model), method)(request.cr, request.uid, *args, **kwargs)
  File "/opt/odoo8/odoo/openerp/api.py", line 268, in wrapper
    return old_api(self, *args, **kwargs)
  File "/opt/odoo8/odoo/addons/hr_holidays/hr_holidays.py", line 494, in create
    return super(hr_employee, self).create(cr, uid, vals, context=context)
  File "/opt/odoo8/odoo/openerp/api.py", line 268, in wrapper
    return old_api(self, *args, **kwargs)
  File "/opt/odoo8/odoo/addons/hr/hr.py", line 285, in create
    employee_id = super(hr_employee, self).create(cr, uid, data, context=context)
  File "/opt/odoo8/odoo/openerp/api.py", line 268, in wrapper
    return old_api(self, *args, **kwargs)
  File "/opt/odoo8/odoo/addons/mail/mail_thread.py", line 381, in create
    thread_id = super(mail_thread, self).create(cr, uid, values, context=context)
  File "/opt/odoo8/odoo/openerp/api.py", line 268, in wrapper
    return old_api(self, *args, **kwargs)
  File "/opt/odoo8/odoo/openerp/api.py", line 372, in old_api
    result = method(recs, *args, **kwargs)
  File "/opt/odoo8/odoo/openerp/models.py", line 4094, in create
    record = self.browse(self._create(old_vals))
  File "/opt/odoo8/odoo/openerp/api.py", line 266, in wrapper
    return new_api(self, *args, **kwargs)
  File "/opt/odoo8/odoo/openerp/api.py", line 508, in new_api
    result = method(self._model, cr, uid, *args, **old_kwargs)
  File "/opt/odoo8/odoo/openerp/models.py", line 4279, in _create
    result += self._columns[field].set(cr, self, id_new, field, vals[field], user, rel_context) or []
  File "/opt/odoo8/odoo/openerp/osv/fields.py", line 1486, in set
    self._fnct_inv(obj, cr, user, id, name, value, self._fnct_inv_arg, context)
  File "/opt/odoo8/odoo/addons/hr/hr.py", line 186, in _set_image
    return self.write(cr, uid, [id], {'image': tools.image_resize_image_big(value)}, context=context)
  File "/opt/odoo8/odoo/openerp/api.py", line 268, in wrapper
    return old_api(self, *args, **kwargs)
  File "/opt/odoo8/odoo/addons/mail/mail_thread.py", line 432, in write
    result = super(mail_thread, self).write(cr, uid, ids, values, context=context)
  File "/opt/odoo8/odoo/openerp/api.py", line 268, in wrapper
    return old_api(self, *args, **kwargs)
  File "/opt/odoo8/odoo/openerp/api.py", line 399, in old_api
    result = method(recs, *args, **kwargs)
  File "/opt/odoo8/odoo/openerp/models.py", line 3789, in write
    self._write(old_vals)
  File "/opt/odoo8/odoo/openerp/api.py", line 266, in wrapper
    return new_api(self, *args, **kwargs)
  File "/opt/odoo8/odoo/openerp/api.py", line 592, in new_api
    result = method(self._model, cr, uid, self.ids, *args, **old_kwargs)
  File "/opt/odoo8/odoo/openerp/models.py", line 4037, in _write
    cr, user, todo, fields_to_recompute, context)
  File "/opt/odoo8/odoo/openerp/api.py", line 268, in wrapper
    return old_api(self, *args, **kwargs)
  File "/opt/odoo8/odoo/openerp/models.py", line 4453, in _store_set_values
    cr.execute(query, (column._symbol_set[1](value), id))
  File "/opt/odoo8/odoo/openerp/sql_db.py", line 158, in wrapper
    return f(self, *args, **kwargs)
  File "/opt/odoo8/odoo/openerp/sql_db.py", line 234, in execute
    res = self._obj.execute(query, params)
DataError: invalid input syntax for integer: "available_tickets"
LINE 1: ...ployee" SET "available_tickets"='5.00' WHERE id = 'available...
1
you need change value on fly? I mean in GUI?Danila Ganchar
yes, and sorry I didn't define the field as function.. I've updated it in the questionyouta

1 Answers

4
votes

You have multiple issues.

1. Your error message

The error message DataError: invalid input syntax for integer: "available_tickets" points at your error. Your computed field implementation returns a dict with "available_tickets" as the key instead of the employee IDs. So when the system tries to update the database it fails to find an employee record with ID "available_tickets".

The problem lies is in get_tickets():

res['available_tickets'] = emp_ticket.no_tickets

You need to iterate over the employee ids that are passed to get_tickets() and return a result res that looks like this:

{
  1: 3.0,  # 3 `available_tickets` for employee ID 1
  2: 4.0,  # 4 `available_tickets` for employee ID 2
  ...
}

So in get_tickets() you should have something like this:

res[emp.id] = <computed number of tickets> # emp = hr.employee record!

Please a look at the documentation for writing computed fields (old API, new API), or examples in the official Odoo modules for inspiration.

2. Your computed field logic

Your current (draft?) implementation for the get_tickets() makes little sense:

  • it should have a main loop over the requested hr.employee IDs. This is important because Odoo computed fields are computed in batch by the system.
  • it should presumably not depend on the current user to compute the result. Currently you're searching for the travel.requests of the current user via this domain ('user_id', '=', uid). This means you're looking at the travel.requests of the user who is viewing or modifying the employee, not the user of that employee. This is where the ids variable should be used ; to browse the employees for whom you are computing values, and then search the appropriate travel.request.
  • if you are storing the computed value (store=True), you need proper recomputing triggers, otherwise the stored value will not change when you modify/add travel.request. In the new API this is done with the @api.depends, and in the old API by passing a store dictionary, as explained in the documentation.

Reading the documentation and the source code of official addons is really the best way to learn about Odoo computed fields.