I have a for loop the for loop has a if condition the code is given below
class hr_attendance(osv.osv):
_name = "hr.attendance"
_description = "Attendance"
def _worked_hours_compute(self, cr, uid, ids, fieldnames, args, context=None):
"""For each hr.attendance record of action sign-in: assign 0.
For each hr.attendance record of action sign-out: assign number of hours since last sign-in.
"""
res = {}
for obj in self.browse(cr, uid, ids, context=context):
if obj.action == 'sign_in':
res[obj.id] = 0
elif obj.action == 'sign_out':
# Get the associated sign-in
last_signin_id = self.search(cr, uid, [
('employee_id', '=', obj.employee_id.id),
('name', '<', obj.name), ('action', '=', 'sign_in')
], limit=1, order='name DESC')
if last_signin_id:
last_signin = self.browse(cr, uid, last_signin_id, context=context)[0]
# Compute time elapsed between sign-in and sign-out
last_signin_datetime = datetime.strptime(last_signin.name, '%Y-%m-%d %H:%M:%S')
signout_datetime = datetime.strptime(obj.name, '%Y-%m-%d %H:%M:%S')
workedhours_datetime = (signout_datetime - last_signin_datetime)
res[obj.id] = ((workedhours_datetime.seconds) / 60) / 60.0
else:
res[obj.id] = False
return res
_columns = {
'name': fields.datetime('Date', required=True, select=1),
'action': fields.selection([('sign_in', 'Sign In'), ('sign_out', 'Sign Out'), ('action','Action')], 'Action'),
'action_desc': fields.many2one("hr.action.reason", "Action Reason", domain="[('action_type', '=', action)]", help='Specifies the reason for Signing In/Signing Out in case of extra hours.'),
'employee_id': fields.many2one('hr.employee', "Employee", required=True, select=True),
'worked_hours': fields.function(_worked_hours_compute, type='float', string='Worked Hours', store=True),
's2':fields.integer('s2'),
'state':fields.boolean('state?', default=False),
}
_defaults = {
'name': lambda *a: time.strftime('%Y-%m-%d %H:%M:%S'), #please don't remove the lambda, if you remove it then the current time will not change
}
@api.constrains('s2')
def constrains_action(self):
if self.s2 == 0:
self.action = 'sign_in'
@api.constrains('s2')
def constraint_action(self):
if self.s2 == 1:
self.action = 'sign_out'
@api.constrains('name')
def constrains_date(self):
self.env.cr.execute(
'DELETE FROM hr_attendance USING hr_attendance ua2 WHERE hr_attendance.name = ua2.name AND hr_attendance.id < ua2.id')
def _altern_si_so(self, cr, uid, ids, context=None):
""" Alternance sign_in/sign_out check.
Previous (if exists) must be of opposite action.
Next (if exists) must be of opposite action.
"""
for att in self.browse(cr, uid, ids, context=context):
# search and browse for first previous and first next records
prev_att_ids = self.search(cr, uid, [('employee_id', '=', att.employee_id.id), ('name', '<', att.name),
('action', 'in', ('sign_in', 'sign_out'))], limit=1, order='name desc')
next_add_ids = self.search(cr, uid, [('employee_id', '=', att.employee_id.id), ('name', '>', att.name),
('action', 'in', ('sign_in', 'sign_out'))], limit=1, order='name ASC')
prev_atts = self.browse(cr, uid, prev_att_ids, context=context)
next_atts = self.browse(cr, uid, next_add_ids, context=context)
# check for alternance, return False if at least one condition is not satisfied
if prev_atts and prev_atts[0].action == att.action:
return self.write(cr, uid, ids, {'state': True})
elif prev_atts and prev_atts[0].action != att.action:
return prev_atts.write(cr, uid, ids, {'state': False})
if next_atts and next_atts[0].action == att.action: # next exists and is same action
return self.write(cr, uid, ids, {'state': True})
elif next_atts and next_atts[0].action != att.action:
return next_atts.write(cr, uid, ids, {'state': False})
if (not prev_atts) and (not next_atts) and att.action != 'sign_in': # first attendance must be sign_in
return self.write(cr, uid, ids, {'state': True})
else:
return self.write(cr, uid, ids, {'state' : False})
return True
_constraints = [
(_altern_si_so, 'Error ! Sign in (resp. Sign out) must follow Sign out (resp. Sign in)', ['action'])]
In the above code in elif I have given prev_atts or next_atts write() function shows type error write() takes exactly 2 arguments (5 given).
If I give self instead of prev_atts or next_atts it does not show any error.But I need the if condition based on prev_atts or next_atts.Since the state value must changed for previous record and next record not for the self or same record. In if condition it should change the same recorder in elif condition it should change previous or next record. How can I achieve this?
Thanks....
Aucun commentaire:
Enregistrer un commentaire