Overslaan naar inhoud
Menu
Je moet geregistreerd zijn om te kunnen communiceren met de community.
Deze vraag is gerapporteerd
22 Antwoorden
54566 Weergaven

Hi everybody,

I'm new to odoo, and I created my custom module for contract.

I change the view to update my new field base on the selected resource. My code:


View:
<field name="working_hours" position="replace">
                    <field name="working_hours"
                           on_change="on_change_working_hours(working_hours)"/>
                </field>
Python code:
@api.onchange('working_hours')
    def on_change_working_hours(self, working_hours):
        if working_hours:
            res_calendar = self.env['resource.calendar'].search([('id', '=', working_hours)])
            if res_calendar:
                self.expected_working_hours = res_calendar.expected_working_hours

But when changing the field 'working_hours', I got errror:

    raise ValueError("Expected singleton: %s" % self)
ValueError: Expected singleton: hr.contract()

How can I update my code?

Thank you.



Avatar
Annuleer

Hai Vu,

What is the type of the field expected_working_hours ?

Beste antwoord

View definition with @api.onchange you shouldn't need to call the function and therefore shouldn't need to replace anything.

You could change your python code to accept multiple records.

In python use an iterator "for record in self"

@api.onchange('working_hours') 
def on_change_working_hours(self):
    for record in self:
        if record.working_hours:
            res_calendar = self.env['resource.calendar'].search([('id', '=', record.working_hours)])
            if res_calendar:
                record.expected_working_hours = res_calendar.expected_working_hours
Avatar
Annuleer
Auteur

Hi Ecarde,

I tried but the code in the loop 'for record in self:' is never reached.

Auteur

Hi,

I changed the code and it works

thank you

Glad it solved your problem. Could you mark my post as the answer?

Beste antwoord

ValueErrorExpected singleton: financial.grant(1, 3, 4)




Avatar
Annuleer
Auteur Beste antwoord

expected_working_hours is type of Float

Avatar
Annuleer

Ok, then this code solve your problem, please check the use of decorators, only it's necesary @api.onchange

Warning: Some code was fixed, I'm assuming working_hours it's m2o field to resource.calendar entity.

@api.onchange('working_hours')

def on_change_working_hours(self):

self.expected_working_hours = self.working_hours.expected_working_hours if self.working_hours else 0.

Please, confirm me if this answer solve your question.

Auteur

Hi Rafael,

This code doesn't fix my issue.

But, I updated my code like this, and it works:

@api.onchange('working_hours')

def onchange_working_hours(self, working_hours):

result = {}

if working_hours:

res_calendar = self.env['resource.calendar'].search([('id', '=', working_hours)])

if res_calendar:

result['expected_working_hours'] = res_calendar.expected_working_hours

return {'value': result}

Beste antwoord

Hi Huynh,
I think your model is hr.contract,
 and  Expected singleton: hr.contract  is error because of self contain multiple records,

Am not guaranteed, if you change in the code in python it will solve the singleton error,

@api.onchange('working_hours')
def on_change_working_hours(self, working_hours):
if working_hours:
res_calendar = self.env['resource.calendar'].search([('id', '=', working_hours.id)])
if res_calendar:
for s in self:
s.expected_working_hours = res_calendar.expected_working_hours
     Also one think that always make code more clear and give the complete one with Model and all.

Avatar
Annuleer
Auteur

Hi Krishnan,

This change does not solve my problem, the code:

s.expected_working_hours =...

is never reached.

This is fully my code:

class Contract(models.Model):

_inherit = 'hr.contract'

expected_working_hours = fields.Float('Expected Working Hours',

required=True)

@api.onchange('working_hours')

def onchange_working_hours(self, working_hours):

if working_hours:

res_calendar = self.env['resource.calendar'].search([('id', '=', working_hours)])

if res_calendar:

self.expected_working_hours = res_calendar.expected_working_hours

Hi Vu,

can you print and check what you are getting in the res_calendar & res_calendar.expected_working_hours ?

res_calendar = self.env['resource.calendar'].search([('id', '=', working_hours)])

if res_calendar:

print res_calender

print res_calendar.expected_working_hours

self.expected_working_hours = res_calendar.expected_working_hours

Auteur

I think the problem is from the line

self.expected_working_hours = res_calendar.expected_working_hours

I debug and got correct value

but the problem still happened with a constant number

res_calendar = self.env['resource.calendar'].search([('id', '=', working_hours.id)])

working_hours is a record, use the id of that record.

Auteur

Hi Krishnan,

I think it isn't the issue I got, I can find the correct resource.calendar with working_hours

But, the problem is when assign the value to self.expected_working_hours.

It also happened when I just try:

self.expected_working_hours = 40

Beste antwoord

At first, if you use the new api as it seems do not need to declare the onchange in the view, with the decorator in python is enough. Next, i assume that working_hours is a Many2one id because otherwise there may be the problem.

Then:

There isn't need to declare view inheritance

Python code:
@api.onchange('working_hours') def on_change_working_hours(self):
    if working_hours:
         self.expected_working_hours = self.env['resource.calendar'].search([('id', '=', working_hours)]).id or False
Avatar
Annuleer
Auteur

The problem is when assign the value to self.expected_working_hours.

It also happened when I just try:

self.expected_working_hours = 40

Maybe yo need try tos ways:

1. Declare expected_workings_hours as a computed field if it'll always be a formula.

2. Try with a write: self.write{'expected_workings_hours':40} but I don't recommend this.

Auteur

Hi Rafael,

The field 'expected_working_hours' is not always a formula field. It's computed, but user can change it.

Try force search code line to limit 1 like this:

self.env['resource.calendar'].search([('id', '=', working_hours)], limit=1)

Otherwise i will need to see expected_working_hours field declaration because i can't find it in odoo source code

Auteur

No, the 'expected_working_hours' is my new field.

I declare it both in 'resource_calendar' and 'hr_contract', type of float.

By default, the hr_contract.expected_working_hours will be get from resource_calendar. But, user can change it.

Ok, then this code solve your problem, please check the use of decorators, only it's necesary @api.onchange

Warning: Some code was fixed, I'm assuming working_hours it's m2o field to resource.calendar entity.

@api.onchange('working_hours')

def on_change_working_hours(self):

self.expected_working_hours = self.working_hours.expected_working_hours if self.working_hours else 0.

Please, confirm me if this answer solve your question.