Siirry sisältöön
Odoo Menu
  • Kirjaudu sisään
  • Kokeile ilmaiseksi
  • Sovellukset
    Talous
    • Kirjanpito
    • Laskutus
    • Kulut
    • Datataulukot (BI)
    • Asiakirjat
    • Allekirjoita
    Myynti
    • CRM
    • Myynti
    • Kassajärjestelmä myymälään
    • Kassajärjestelmä ravintolaan
    • Tilaukset
    • Vuokraus
    Verkkosivut
    • Verkkosivun Rakennustyökalu
    • Verkkokauppa
    • Blogi
    • Foorumi
    • Livechat
    • Verkko-oppiminen
    Toimitusketju
    • Varastointi
    • Tuotanto
    • Tuotteen elinkaaren hallinta (PLM)
    • Ostot
    • Huolto
    • Laatu
    Henkilöstöhallinto
    • Työntekijät
    • Rekrytointi
    • Vapaat
    • Arvioinnit
    • Suositukset
    • Kuljetuskalusto
    Markkinointi
    • Somemarkkinointi
    • Sähköpostimarkkinointi
    • Tekstiviestimarkkinointi
    • Tapahtumat
    • Markkinoinnin automaatio
    • Kyselyt
    Palvelut
    • Projekti
    • Työaikakirjaukset
    • Kenttähuolto
    • Asiakaspalvelu
    • Suunnittelu
    • Ajanvaraukset
    Tuottavuus
    • Viestintä
    • Hyväksynnät
    • IoT
    • IP-puhe
    • Tietokirjasto
    • WhatsApp
    Kolmannen osapuolen sovellukset Odoo-Studio Odoo-Pilvialusta
  • Toimialat
    Vähittäiskauppa
    • Kirjakauppa
    • Vaatekauppa
    • Huonekaluliike
    • Ruokakauppa
    • Laitteistokauppa
    • Lelukauppa
    Ruoka & Majoitus
    • Baari ja Pubi
    • Ravintola
    • Pikaruoka
    • Majatalo
    • Juomien jakelija
    • Hotelli
    Kiinteistöt
    • Kiinteistönvälitystoimisto
    • Arkkitehtitoimisto
    • Rakentaminen
    • Kiinteistönhallinta
    • Puutarhanhoito
    • Kiinteistön omistajien yhdistys
    Konsultointi
    • Tilitoimisto
    • Odoo-kumppani
    • Markkinointitoimisto
    • Lakitoimisto
    • Osaajahankinta
    • Tilintarkastus & sertifiointi
    Tuotanto
    • Tekstiili
    • Metalli
    • Huonekalut
    • Ruoka
    • Panimo
    • Yrityslahjat
    Terveys & Liikunta
    • Urheiluseura
    • Silmälasiliike
    • Kuntokeskus
    • Hyvinvointialan ammattilaiset
    • Apteekki
    • Kampaamo
    Kaupat
    • Yleismies
    • IT-laitteisto & Tuki
    • Aurinkoenergiajärjestelmät
    • Suutari
    • Siivouspalvelut
    • LVI-palvelut
    Muut
    • Voittoa tavoittelematon järjestö
    • Ympäristötoimisto
    • Mainostaulujen vuokraus  
    • Valokuvaus
    • Leasing-pyörät
    • Ohjelmistojen jälleenmyyjä
    Selaa kaikkia toimialoja
  • Yhteisö
    Opi
    • Kurssit
    • Dokumentaatio
    • Todistukset
    • Koulutus
    • Blogi
    • Podcast
    Kannusta kouluttautumaan
    • Koulutusohjelmat
    • Scale Up! Liiketoimintapeli
    • Vieraile Odoolla
    Hanki ohjelmisto
    • Lataa
    • Vertaile versioita
    • Julkaisut
    Tee yhteistyötä
    • Github
    • Foorumi
    • Tapahtumat
    • Käännökset
    • Ryhdy kumppaniksi
    • Kumppanipalvelut
    • Rekisteröi tilitoimistosi
    Hanki palveluja
    • Löydä kumppani
    • Löydä kirjanpitäjä
    • Varaa asiantuntijatapaaminen
    • Implementaatiopalvelut
    • Asiakasreferenssit
    • Tuki
    • Versionkorotukset
    Github Youtube Twitter Linkedin Instagram Facebook Spotify
    +1 (650) 691-3277
    Varaa demo
  • Hinnoittelu
  • Asiakaspalvelu

Odoo is the world's easiest all-in-one management software.
It includes hundreds of business apps:

  • CRM
  • e-Commerce
  • Kirjanpito
  • Varastointi
  • PoS
  • Projekti
  • MRP
All apps
Sinun on rekisteröidyttävä, jotta voit olla vuorovaikutuksessa yhteisön kanssa.
Kaikki kirjoitukset Ihmiset Merkit
Tunnisteet (Näytä kaikki)
odoo accounting v14 pos v15
Tietoa tästä foorumista
Sinun on rekisteröidyttävä, jotta voit olla vuorovaikutuksessa yhteisön kanssa.
Kaikki kirjoitukset Ihmiset Merkit
Tunnisteet (Näytä kaikki)
odoo accounting v14 pos v15
Tietoa tästä foorumista
Apua

infinite loop with on_change?

Tilaa

Saat ilmoituksen, kun tähän viestiin ilmaantuu aktiviteettia

Tämä kysymys on merkitty
on_change
5 Vastaukset
12999 Näkymät
Avatar
vgze

Hello, I try add a on_change on two fields (fields A and fields B). I wand that:

  • if user change the fields A that aumaticaly change the fileds B.
  • if user change the fields B that aumaticaly change the fileds A.

I take the 2 events and they work. But when I launch theim together, infinite loop.

It is possible to take what I want to do?

edit:

sale_perso.py:

def price_unit_change(self, cr, uid, ids, price_unit, product):
    result = {}
    if product:
        product_obj = self.pool.get('product.product')
        product_obj = product_obj.browse(cr, uid, product)
        result['coeff'] = price_unit / product_obj.standard_price 
    return {'value': result}

def coeff_change(self, cr, uid, ids, coeff, standard_price):
    result = {}
    result['price_unit'] = coeff * standard_price
    return {'value': result}

sale_perso_view.xml: <openerp> <data>

    <record model="ir.ui.view" id="sale_order_line_type_price">
        <field name="name">sale.order.line.type.price</field>
        <field name="model">sale.order</field>
        <field name="inherit_id" ref="sale.view_order_form"/>
        <field name="arch" type="xml">
           <xpath expr="//field[@name='order_line']/tree//field[@name='price_unit']" position="replace">
                <field name="price_unit"  on_change="price_unit_change(price_unit, product_id)"/>
           </xpath>
           <xpath expr="//field[@name='order_line']/tree//field[@name='price_unit']" position="before">
                <field name="standard_price"/>
                <field name="coeff"  on_change="coeff_change(coeff, standard_price)"/>
            </xpath>
        </field>
    </record>
</data>
</openerp>
0
Avatar
Hylkää
ainur rofiq

fields A and B will always have the same value.
on_change event is triggered when focused loses, pressing TAB or ENTER.
Please post your on_change method and XML on_change field. thanks

ainur rofiq

When you change A then on_change(A) is triggered to change B = A. Now B is changed, then on_changed(B) is triggered to change A. At this point there is no change for A, so on_change(A) is not triggered. So there is no infinite loop.

Avatar
Adrian Merrall
Paras vastaus

Hi,

If you have an on_change on field A that returns

{'value': {'B': new_value,},}

This will then trigger an on_change on B and if this returns

{'value': {'A': new_value,},}

which will trigger the on_change on A and around we go.

A couple of thoughts here:

  1. 6.1 or older, add a hidden field to the form and pass/return that into the on_change events so your on_change event terminates if the hidden field is set.
  2. Version 7 - use the context. In on_change A, set a flag in the context to say it has just run. In the on_change for B, if the flag is in the context, remote it and terminate rather than re-setting A.

In Version 7, just pass the context in your XML like this:

<field name="A" on_change="a_change(A, context) />

HTH,

Adrian, Auckland, NZ

enter code here
1
Avatar
Hylkää
Avatar
vgze
Tekijä Paras vastaus

I never used the context dictionnary. I try but, the problem is still here.

sale_perso.py:

def price_unit_change(self, cr, uid, ids, price_unit, product, context):
    result = {}
    lang = context.get('lang',False)
    if context.get('cancel_event',False):
        context = {'lang': lang, 'cancel_event': False}
    else:
        context = {'lang': lang, 'cancel_event': True}
        if product:
            product_obj = self.pool.get('product.product')
            product_obj = product_obj.browse(cr, uid, product)
            result['coeff'] = price_unit / product_obj.standard_price 
    return {'value': result}

def coeff_change(self, cr, uid, ids, coeff, product, context):
    result = {}
    lang = context.get('lang',False)
    if context.get('cancel_event',False):
        context = {'lang': lang, 'cancel_event': False}
    else:
        context = {'lang': lang, 'cancel_event': True}
        if product:
            product_obj = self.pool.get('product.product')
            product_obj = product_obj.browse(cr, uid, product)
            result['price_unit'] = coeff * product_obj.standard_price 
    return {'value': result}

sale_perso_view.xml:

  <?xml version="1.0"?>
    <openerp>
    <data>
       <record model="ir.ui.view" id="sale_order_line_type_price">
        <field name="name">sale.order.line.type.price</field>
        <field name="model">sale.order</field>
        <field name="inherit_id" ref="sale.view_order_form"/>
        <field name="arch" type="xml">
           <xpath expr="//field[@name='order_line']/tree//field[@name='price_unit']" position="replace">
                <field name="price_unit"  on_change="price_unit_change(price_unit, product_id, context)"/>
            </xpath>
           <xpath expr="//field[@name='order_line']/tree//field[@name='price_unit']" position="after">
                <field name="type_price"/>
            </xpath>
           <xpath expr="//field[@name='order_line']/tree//field[@name='price_unit']" position="before">
                <field name="list_price"/>
                <field name="prixmat"/>
                <field name="standard_price"/>
                <field name="coeff"  on_change="coeff_change(coeff, product_id, context)"/>
            </xpath>
           <xpath expr="//field[@name='order_line']/tree//field[@name='name']" position="after">
                <field name="marque"/>
            </xpath>
        </field>
    </record>
    </data>
    </openerp>
0
Avatar
Hylkää
Avatar
Christophe Combelles
Paras vastaus

Hi, I was able to reproduce the issue an found no obvious way to do so. So I entered a new bug report #1203343 (sorry, no "karma" to post the full link :-/)

0
Avatar
Hylkää
Avatar
Edison Ibáñez
Paras vastaus

I had the same problem, solved it updating the context before checking if the previous value was modified

def onchange_comision_value(self, cr, uid, ids, comision, context):
    res = {}
    ctx = dict(context)
    ctx.update
    if context.get('cancel_event', False):
        ctx.update({'cancel_event': False,})
    else:
        ctx.update({'cancel_event': True,})
        for i in self.browse(cr,uid,ids):
            aux_percent = ( comision * 100 ) / i.amount_untaxed
            res['comision_percent'] = aux_percent
    return {'value': res}

def onchange_comision_percent(self, cr, uid, ids, comision_percent, context):
    res = {}
    ctx = dict(context)
    ctx.update
    if context.get('cancel_event', False):
        ctx.update({'cancel_event': False,})
    else:
        ctx.update({'cancel_event': True,})
        for i in self.browse(cr,uid,ids):
            aux_comision = ( i.amount_untaxed * comision_percent ) / 100
            res['comision'] = aux_comision
    return {'value': res}

<field name='comision_percent' class="oe_custom_input  oe_inline" nolabel="1" on_change="onchange_comision_percent(comision_percent, context)" /> %% 
 <field name='comision' string='Comision' class="oe_inline" widget='monetary' options="{'currency_field': 'currency_id'}" on_change="onchange_comision_value(comision, context)" />

I hope that even you need

Greetings.

0
Avatar
Hylkää
Avatar
Edison Ibáñez
Paras vastaus

the solution for your problem, here in the module fleet epecificamente in part:

    def on_change_liter(self, cr, uid, ids, liter, price_per_liter, amount, context=None):
    #need to cast in float because the value receveid from web client maybe an integer (Javascript and JSON do not
    #make any difference between 3.0 and 3). This cause a problem if you encode, for example, 2 liters at 1.5 per
    #liter => total is computed as 3.0, then trigger an onchange that recomputes price_per_liter as 3/2=1 (instead
    #of 3.0/2=1.5)
    #If there is no change in the result, we return an empty dict to prevent an infinite loop due to the 3 intertwine
    #onchange. And in order to verify that there is no change in the result, we have to limit the precision of the 
    #computation to 2 decimal
    liter = float(liter)
    price_per_liter = float(price_per_liter)
    amount = float(amount)
    if liter > 0 and price_per_liter > 0 and round(liter*price_per_liter,2) != amount:
        return {'value' : {'amount' : round(liter * price_per_liter,2),}}
    elif amount > 0 and liter > 0 and round(amount/liter,2) != price_per_liter:
        return {'value' : {'price_per_liter' : round(amount / liter,2),}}
    elif amount > 0 and price_per_liter > 0 and round(amount/price_per_liter,2) != liter:
        return {'value' : {'liter' : round(amount / price_per_liter,2),}}
    else :
        return {}

def on_change_price_per_liter(self, cr, uid, ids, liter, price_per_liter, amount, context=None):
    #need to cast in float because the value receveid from web client maybe an integer (Javascript and JSON do not
    #make any difference between 3.0 and 3). This cause a problem if you encode, for example, 2 liters at 1.5 per
    #liter => total is computed as 3.0, then trigger an onchange that recomputes price_per_liter as 3/2=1 (instead
    #of 3.0/2=1.5)
    #If there is no change in the result, we return an empty dict to prevent an infinite loop due to the 3 intertwine
    #onchange. And in order to verify that there is no change in the result, we have to limit the precision of the 
    #computation to 2 decimal
    liter = float(liter)
    price_per_liter = float(price_per_liter)
    amount = float(amount)
    if liter > 0 and price_per_liter > 0 and round(liter*price_per_liter,2) != amount:
        return {'value' : {'amount' : round(liter * price_per_liter,2),}}
    elif amount > 0 and price_per_liter > 0 and round(amount/price_per_liter,2) != liter:
        return {'value' : {'liter' : round(amount / price_per_liter,2),}}
    elif amount > 0 and liter > 0 and round(amount/liter,2) != price_per_liter:
        return {'value' : {'price_per_liter' : round(amount / liter,2),}}
    else :
        return {}

def on_change_amount(self, cr, uid, ids, liter, price_per_liter, amount, context=None):
    #need to cast in float because the value receveid from web client maybe an integer (Javascript and JSON do not
    #make any difference between 3.0 and 3). This cause a problem if you encode, for example, 2 liters at 1.5 per
    #liter => total is computed as 3.0, then trigger an onchange that recomputes price_per_liter as 3/2=1 (instead
    #of 3.0/2=1.5)
    #If there is no change in the result, we return an empty dict to prevent an infinite loop due to the 3 intertwine
    #onchange. And in order to verify that there is no change in the result, we have to limit the precision of the 
    #computation to 2 decimal
    liter = float(liter)
    price_per_liter = float(price_per_liter)
    amount = float(amount)
    if amount > 0 and liter > 0 and round(amount/liter,2) != price_per_liter:
        return {'value': {'price_per_liter': round(amount / liter,2),}}
    elif amount > 0 and price_per_liter > 0 and round(amount/price_per_liter,2) != liter:
        return {'value': {'liter': round(amount / price_per_liter,2),}}
    elif liter > 0 and price_per_liter > 0 and round(liter*price_per_liter,2) != amount:
        return {'value': {'amount': round(liter * price_per_liter,2),}}
    else :
        return {}

there is this doing the same thing you wantthe solution for your problem, here in the fleet module

0
Avatar
Hylkää
Nautitko keskustelusta? Älä vain lue, vaan osallistu!

Luo tili jo tänään nauttiaksesi yksinoikeusominaisuuksista ja osallistuaksesi mahtavaan yhteisöömme!

Rekisteröidy
Aiheeseen liittyviä artikkeleita Vastaukset Näkymät Toimenpide
How to use On change function? Ratkaistu
on_change
Avatar
Avatar
Avatar
Avatar
10
kesäk. 16
33971
Lines Functional values how to shows before saving the record
on_change
Avatar
Avatar
1
lokak. 15
10095
Two on_change methods for the same field
on_change
Avatar
Avatar
4
elok. 15
4329
How to make an on_change event for a one2many related field
on_change
Avatar
Avatar
1
maalisk. 15
5422
how to use on_change attribute ?
on_change
Avatar
1
maalisk. 15
4559
Yhteisö
  • Kurssit
  • Dokumentaatio
  • Foorumi
Avoin lähdekoodi
  • Lataa
  • Github
  • Runbot
  • Käännökset
Palvelut
  • Odoo.sh hosting
  • Tuki
  • Versionkorotus
  • Räätälöidyt kehitykset
  • Koulutus
  • Löydä kirjanpitäjä
  • Löydä kumppani
  • Ryhdy kumppaniksi
Meistä
  • Yrityksemme
  • Tavaramerkki
  • Ota yhteyttä
  • Työpaikat
  • Tapahtumat
  • Podcast
  • Blogi
  • Asiakkaat
  • Oikeudellinen ilmoitus • Yksityisyys
  • Tietoturva
الْعَرَبيّة Català 简体中文 繁體中文 (台灣) Čeština Dansk Nederlands English Suomi Français Deutsch हिंदी Bahasa Indonesia Italiano 日本語 한국어 (KR) Lietuvių kalba Język polski Português (BR) română русский язык Slovenský jazyk slovenščina Español (América Latina) Español ภาษาไทย Türkçe українська Tiếng Việt

Odoo on kokoelma avoimen lähdekoodin yrityssovelluksia, jotka kattavat kaikki yrityksesi tarpeet: asiakkuudenhallinta eli CRM, verkkokauppa, kirjanpito, varastointi, kassajärjestelmä, projektinhallinta, jne.

Odoon uniikki arvolupaus on olla samanaikaisesti erittäin helppokäyttöinen ja täysin integroitu.

Website made with

Odoo Experience on YouTube

1. Use the live chat to ask your questions.
2. The operator answers within a few minutes.

Live support on Youtube
Watch now