Odoo Help


What is wrong with my inherit of hr_employee?

Michael Watchorn
on 3/10/14, 2:04 PM 2,435 views

I am trying to call the sign-in/sign-out change state function: 'attendance_action_change' that's part of hr_employee (a class within the hr_attendance module).

Here's the error I get:

AttributeError: 'super' object has no attribute 'attendance_action_change'

Here is my code:

import os
import openerp

import openerp.addons.web.http as http
import openerp.addons.hr_attendance.hr_attendance


class PunchcardController(http.Controller):
    _cp_path = '/my_punchcard'
    _inherit = 'hr_attendance.hr_employee'
    _name = 'punchcard.employee'

    def index(self, req, s_action=None, **kw):
        Returns a Login screen (input box for user id, and submit button) 
        The form submits the user id to the PunchIn function/webpage.
        template = PUNCHCARD_TEMPLATE
        return template

#Creating my own copy of the function to overide the parent, which in turn just calls the parent. The return line is where the code breaks.
    def attendance_action_change(self, cr, uid, ids):
        Calls the sign-in/sign-out change function 'attendance_action_change' from the inherited hr_employee object 
        return super(PunchcardController, self).attendance_action_change(cr, uid, ids)

    def PunchIn(self, req, user_id, **kw):
        Authenticates with the server and runs a sign-in/sign-out change
        Returns a webpage showing the user id. 
        print user_id
        print str(user_id)

        template = "<html><head></head><body>AND NOW USER # " + str(user_id) + " IS IN</body></html>"

        req.session.authenticate('dbname', 'user-name', 'password')

        ids=[] #creating my empty list of people to change attendance state
        ids.append(user_id) #building my id list of people who will get their attendance state changed (only ever 1 person)
        print req.session._uid #verifying I have something to submit as a uid
        cr = openerp.pooler.get_db('dbname').cursor()  #get a connection to the DB
        attendance_change_result = self.attendance_action_change(cr, req.session._uid, ids)
        if attendance_change_result:
            print "sign in/out changed!"
        return template


and for completeness, here's the hr_employee class:

(The function I want is the last one in the class: 'attendance_action_change')

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

    def _state(self, cr, uid, ids, name, args, context=None):
        result = {}
        if not ids:
            return result
        for id in ids:
            result[id] = 'absent'
        cr.execute('SELECT hr_attendance.action, hr_attendance.employee_id \
                FROM ( \
                    SELECT MAX(name) AS name, employee_id \
                    FROM hr_attendance \
                    WHERE action in (\'sign_in\', \'sign_out\') \
                    GROUP BY employee_id \
                ) AS foo \
                LEFT JOIN hr_attendance \
                    ON (hr_attendance.employee_id = foo.employee_id \
                        AND hr_attendance.name = foo.name) \
                WHERE hr_attendance.employee_id IN %s',(tuple(ids),))
        for res in cr.fetchall():
            result[res[1]] = res[0] == 'sign_in' and 'present' or 'absent'
        return result

    def _last_sign(self, cr, uid, ids, name, args, context=None):
        result = {}
        if not ids:
            return result
        for id in ids:
            result[id] = False
            cr.execute("""select max(name) as name
                        from hr_attendance
                        where action in ('sign_in', 'sign_out') and employee_id = %s""",(id,))
            for res in cr.fetchall():
                result[id] = res[0]
        return result

    def _attendance_access(self, cr, uid, ids, name, args, context=None):
        # this function field use to hide attendance button to singin/singout from menu
        group = self.pool.get('ir.model.data').get_object(cr, uid, 'base', 'group_hr_attendance')
        visible = False
        if uid in [user.id for user in group.users]:
            visible = True
        return dict([(x, visible) for x in ids])

    _columns = {
       'state': fields.function(_state, type='selection', selection=[('absent', 'Absent'), ('present', 'Present')], string='Attendance'),
       'last_sign': fields.function(_last_sign, type='datetime', string='Last Sign'),
       'attendance_access': fields.function(_attendance_access, string='Attendance Access', type='boolean'),

    def _action_check(self, cr, uid, emp_id, dt=False, context=None):
        cr.execute('SELECT MAX(name) FROM hr_attendance WHERE employee_id=%s', (emp_id,))
        res = cr.fetchone()
        return not (res and (res[0]>=(dt or time.strftime('%Y-%m-%d %H:%M:%S'))))

    def attendance_action_change(self, cr, uid, ids, context=None):
        if context is None:
            context = {}
        action_date = context.get('action_date', False)
        action = context.get('action', False)
        hr_attendance = self.pool.get('hr.attendance')
        warning_sign = {'sign_in': _('Sign In'), 'sign_out': _('Sign Out')}
        for employee in self.browse(cr, uid, ids, context=context):
            if not action:
                if employee.state == 'present': action = 'sign_out'
                if employee.state == 'absent': action = 'sign_in'

            if not self._action_check(cr, uid, employee.id, action_date, context):
                raise osv.except_osv(_('Warning'), _('You tried to %s with a date anterior to another event !\nTry to contact the HR Manager to correct attendances.')%(warning_sign[action],))

            vals = {'action': action, 'employee_id': employee.id}
            if action_date:
                vals['name'] = action_date
            hr_attendance.create(cr, uid, vals, context=context)
        return True



Med Said BARA

--Med Said BARA--

| 5 5 7
--Med Said BARA--
Med Said BARA
On 3/12/14, 1:22 PM


I think that your problem is related to Method Resolution Order and Multiple Inheritance:


It seems that super() tries to find attendance_action_change at http.Controller

what will happen if we use, class PunchcardController(hr_attendance.hr_employee, http.Controller): ???

I've found a valuable informations HERE about the usage of super

good idea, I had only tried with the hr_attenance.hr_employee before the http.Controller. However, I get the "No handler found" error, which I get if I mess at all with the contents of the brackets that hold http.Controller. From my (limited) understanding of MRO, it should look for "attendance_action_change" in http.Controller first, and when it doesn't find it there, it should look in hr_employee. I had also found the cafepy articles, haven't finished with them yet. I will examine the PDF you linked to as well, I just took a brief look at the Forward, and it looks promising - thanks.

Michael Watchorn
on 3/13/14, 3:06 PM

Keep me informed and Good Luck

Med Said BARA
on 3/13/14, 3:20 PM

About This Community

This platform is for beginners and experts willing to share their Odoo knowledge. It's not a forum to discuss ideas, but a knowledge base of questions and their answers.


Odoo Training Center

Access to our E-learning platform and experience all Odoo Apps through learning videos, exercises and Quizz.

Test it now

Question tools

0 follower(s)


Asked: 3/10/14, 2:04 PM
Seen: 2435 times
Last updated: 3/16/15, 8:10 AM