2015-06-26 2 views
3

Я работал над модулем в Odoo8 на Ubuntu 14.04. Я придумал странную проблему при сохранении записи формы на основе некоторых полей One2many. Ошибка говоритValueError Ожидаемый синглтон, Odoo8

ValueError 

Expected singleton: hr.employee.pay.change(84, 85) 

код Мой Python, как показано ниже

class hr_employee_pay_change(models.Model): 

    _name='hr.employee.pay.change' 
    hr_payroll_change_ids = fields.Many2one("employee.salary.change", "Employee", ondelete="cascade") 

    @api.onchange('emp_basic', 'emp_allowance') 
    @api.depends('emp_basic', 'emp_allowance') 
    def _current_total(self): 
     self.emp_current_total = self.emp_basic + self.emp_allowance 



    @api.onchange('emp_propose_allowance', 'emp_propose_basic') 
    @api.depends('emp_propose_allowance', 'emp_propose_basic') 
    def _proposed_total(self): 
     data_val={} 
     self.emp_propose_total = self.emp_propose_basic + self.emp_propose_allowance 
     cr=self._cr 
     uid=self._uid 
     ids=self._ids 
     val=int(self.employee_name) 
     if val: 
      cr.execute("select max_salary,min_salary from hr_job where id in (select job_id from hr_employee where id='"+str(val)+"')") 
      res=cr.fetchall() 
      for data_val in res: 
       max_sal=data_val[0] 
       min_sal=data_val[1] 
      if not min_sal < self.emp_propose_total < max_sal: 
       self.emp_propose_basic = 0.0 
       self.emp_propose_allowance = 0.0 
       return {'warning':{'title':'warning','message':'Out of Range, Proposed Total must be in between "'+str(max_sal)+'"to"'+str(min_sal)+'"'}} 
     else: 
      cr.execute("select wage from hr_contract where employee_id=0")  




    @api.onchange('employee_name') 
    @api.depends('employee_name') 
    def get_data(self): 
     data={} 
     cr=self._cr 
     uid=self._uid 
     ids=self._ids  
     value=int(self.employee_name)   
     if(self.employee_name): 
      cr.execute("select wage,allowance from hr_contract where employee_id ='"+str(value)+"'") 
      res=cr.fetchall() 
      for data in res: 
       self.emp_basic=data[0] 
       self.emp_allowance = data[1] 

     else:  
      cr.execute("select wage,allowance from hr_contract where employee_id=0") 



    employee_name = fields.Many2one('hr.employee', 'Employee Name', required=True) 
    zeo_number = fields.Char(related='employee_name.zeo_number', string='ZEO Number', readonly=True) 
    emp_basic = fields.Float('Basic Salary', compute='get_data',readonly=True, store=True) 
    emp_allowance = fields.Float('Allowance', compute='get_data',readonly=True, store=True) 
    emp_current_total = fields.Float('Totals', compute='_current_total', store=True, track_visibility='always') 
    emp_propose_basic = fields.Float('Proposed Basic') 
    emp_propose_allowance = fields.Float('Proposed Allowance') 
    emp_propose_total = fields.Float('Proposed Totals', compute='_proposed_total', store=True, track_visibility='always') 

Я не могу получить эту проблему. Я попытался удалить свойство «readonly = True» этого поля, и проблема исправлена, но мне нужно иметь их как только для чтения. Надежды на предложение

ответ

5

Ожидаемых Singleton:

Метода класса требуется один объекта вызывающего (Single Browsable Record) для вызова метода, и пусть он будет вызывать по несколько объектов, ссылающихся (Browsable набора записей) тогда метода не может определить, для какого объекта он должен обрабатываться, поэтому он вызовет ошибку. Ожидаемый синглтон.

Новый декоратор API используется для определения шаблона вызова метода, позволяют ли методы разрешать только один объект или несколько объектов использовать этот метод.

@ api.one

Этот декоратор автоматически петлями на отчетах RecordSet для вас. Self переопределяется как текущая запись

Примечание: Внимание: возвращенное значение помещается в список. Это не всегда поддерживается веб-клиентом, например. on button action методов. В этом случае вы должны использовать @ api.multi, чтобы украсить ваш метод и, вероятно, позвонить self.ensure_one() в определение метода.

@ api.multi

Самостоятельно быть текущим RecordSet без итерации. Это поведение по умолчанию (несколько объектов, доступных для просмотра). Методы, которые возвращают не данные premitive типа (список, словарь, функция) должны быть украшены @ api.multi

@ api.model

Этого декоратор преобразует старые вызовы API для украшенной функции к новому Подпись API. Это позволяет быть вежливым, когда мигрирующий код. Self не содержит записи/записи в методах, которые украшают этот декоратор.

Так просто называют как этот

self.env [ 'MODEL_NAME']. Method_name (аргументы)

Вы должны попробовать следующее,

class hr_employee_pay_change(models.Model): 
    _name='hr.employee.pay.change' 
    hr_payroll_change_ids = fields.Many2one("employee.salary.change", "Employee", ondelete="cascade") 

    @api.onchange('emp_basic', 'emp_allowance') 
    @api.depends('emp_basic', 'emp_allowance') 
    def _current_total(self): 
     for rec in self: 
      rec.emp_current_total = rec.emp_basic + rec.emp_allowance 

    @api.onchange('emp_propose_allowance', 'emp_propose_basic') 
    @api.depends('emp_propose_allowance', 'emp_propose_basic') 
    def _proposed_total(self): 
     for rec in self: 
      data_val={} 
      rec.emp_propose_total = rec.emp_propose_basic + rec.emp_propose_allowance 
      cr=self._cr 
      uid=self._uid 
      ids=self._ids 
      val=int(rec.employee_name) 
      if val: 
       cr.execute("select max_salary,min_salary from hr_job where id in (select job_id from hr_employee where id='"+str(val)+"')") 
       res=cr.fetchall() 
       for data_val in res: 
        max_sal=data_val[0] 
        min_sal=data_val[1] 
       if not min_sal < self.emp_propose_total < max_sal: 
        self.emp_propose_basic = 0.0 
        self.emp_propose_allowance = 0.0 
        return {'warning':{'title':'warning','message':'Out of Range, Proposed Total must be in between "'+str(max_sal)+'"to"'+str(min_sal)+'"'}} 
      else: 
       cr.execute("select wage from hr_contract where employee_id=0")  

    @api.onchange('employee_name') 
    @api.depends('employee_name') 
    def get_data(self): 
     for rec in self: 
      data={} 
      cr=self._cr 
      uid=rec._uid 
      ids=rec._ids  
      value=int(rec.employee_name)   
      if(rec.employee_name): 
       cr.execute("select wage,allowance from hr_contract where employee_id ='"+str(value)+"'") 
       res=cr.fetchall() 
       for data in res: 
        rec.emp_basic=data[0] 
        rec.emp_allowance = data[1] 

      else:  
       cr.execute("select wage,allowance from hr_contract where employee_id=0") 
Смежные вопросы