ODOO - 如何更新两个级别的 o2m 文件关系 [英] ODOO - How to update two levels o2m fileds relation

查看:59
本文介绍了ODOO - 如何更新两个级别的 o2m 文件关系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Odoo 社区版本 11.0-20190311

Odoo community version 11.0-20190311

我有一个父类 (dt_tst001),其 o2m 字段 (itens) 与类 (dt_tst002) 相关,另一个 o2m 字段 (tributos) 与第三类 (dt_tst003) 相关.

I have a parent class (dt_tst001) with a o2m field (itens) related to a class (dt_tst002), with another o2m field (tributos) related to a third class (dt_tst003).

在父类中有另一个字段 (seguro_total),当它的值更改时,我需要开始重新计算 (_upd_seguro) 第二个类中的字段 (seguro) 和第三个类中的字段 (base_calculo, valor_tributo).

In the parent class there is another field (seguro_total) and when its value is changed I need to start a recalculation (_upd_seguro) of field (seguro) in the second class and fields (base_calculo, valor_tributo) in the third class.

第二个类中的重新计算有效,但第三个中无效.

The recalculation in the second class is working, but not in the third one.

逐步调试更新值,但在检查表单时,它显示原始值,并将此值发送到数据库.

Debuging step by step the values are updated but when checking the form, it shows the original values, and this values are sent to the database.

示例代码:

class DT_TST001(models.Model):
    _name = "dt_tst001"
    _rec_name = "documento"

    documento = fields.Char(string = "Documento", size = 9, required = True)
    seguro_total = fields.Float(string = "Seguro total")
    itens = fields.One2many("dt_tst002", inverse_name = "documento_id", required = True)

    @api.onchange('seguro_total')
    def _upd_seguro(self):
        for item in self.itens:
            item.update({
                'seguro' : ((item.quantidade * item.valor_unitario) / item.valor_total) * self.seguro_total})

            for tributo in item.tributos:
                tributo.update({'base_calculo' : (item.valor_total + item.seguro)})
                tributo.update({'valor_tributo' : (item.valor_total + item.seguro) * tributo.aliquota / 100})


class DT_TST002(models.Model):
    _name = "dt_tst002"
    _rec_name = "documento_id"

    documento_id = fields.Many2one("dt_tst001", string = "Documento", required = True, ondelete='cascade')
    produto_id = fields.Char(string = "Produto", size = 15, required = True)
    quantidade = fields.Float(string="Quantidade", default = 0.00)
    valor_unitario = fields.Float(string="Valor unitário", required = True, default = 0.00)
    valor_total = fields.Float(string="Valor total", required = True, default = 0.00)
    seguro = fields.Float(string="Seguro", compute='_recalc_impostos', store=True)
    tributos = fields.One2many("dt_tst003", inverse_name = "item_id")

    @api.onchange('quantidade', 'valor_unitario', 'seguro')
    def _upd_valor_total(self):
        self.valor_total = (self.quantidade * self.valor_unitario) + self.seguro


class DT_TST003(models.Model):
    _name = "dt_tst003"

    item_id = fields.Many2one("dt_tst002", string = "Ítem", required = True, ondelete='cascade')
    tributo_id = fields.Char(string = "Tributo", size = 15, required = True)
    base_calculo = fields.Float(string = "Base de cálculo")
    aliquota = fields.Float(string = "Alíquota")
    valor_tributo = fields.Float(string = "Valor do tributo")

    @api.multi
    def name_get(self):
        result = []
        for m_tst003 in self:
            name = m_tst003.item_id.documento_id._name + " - " + m_tst003.item_id._name + " - " + m_tst003.tributo_id._name
            result.append((m_tst003.id, name))
        return result

示例视图定义:

<odoo>
    <data>
        <!-- VIEWS PARA NOTAS DE ENTRADA -->
        <record model="ir.ui.view" id="tst001_form">
            <field name="model">dt_tst001</field>
            <field name="name">tst001_form</field>
            <field name="arch" type="xml">
                <form string="Documento de entrada">
                    <group colspan="1" style="margin: 0px">
                        <field name="documento" style="text-transform: uppercase;"/>
                        <field name="seguro_total"/>
                    </group>
                    <notebook>
                        <page string="Ítens">
                            <group>
                                <h6>
                                    <field name="itens" context="{'form_view_ref' : 'dt_tst.tst002_form',
'tree_view_ref' : 'dt_tst.tst002_tree',
'default_itens' : itens}" force_save="1" class="oe_horizontal_separator oe_clear"/>
                                </h6>
                            </group>
                        </page>
                    </notebook>
                </form>
            </field>
        </record>

        <record model="ir.ui.view" id="tst001_tree">
            <field name="model">dt_tst001</field>
            <field name="name">tst001_tree</field>
            <field name="arch" type="xml">
                <tree string="Documentos de entrada">
                    <field name="documento"/>
                    <field name="seguro_total"/>
                </tree>
            </field>
        </record>

        <!-- ITENS -->
        <record model="ir.ui.view" id="tst002_form">
            <field name="model">dt_tst002</field>
            <field name="name">tst002_form</field>
            <field name="arch" type="xml">
                <form string="Ítem de documento de entrada">
                    <group style="margin: 0px">
                        <group colspan="4" style="margin: 0px">
                            <field name="produto_id"/>
                        </group>
                        <group colspan="4" style="margin: 0px">
                            <group style="margin: 0px">
                                <field name="quantidade"/>
                            </group>
                            <group style="margin: 0px">
                                <field name="valor_unitario"/>
                            </group>
                            <group colspan="4" style="margin: 0px">
                                <field name="valor_total" readonly="1" options='{"always_reload": True}' />
                            </group>
                        </group>
                        <group colspan="4" style="margin: 0px">
                            <field name="seguro"/>
                        </group>
                        <field name="valor_total" invisible="1"/>
                    </group>
                    <notebook>
                        <page string="Tributos">
                            <group>
                                <h6>
                                    <field name="tributos" context="{'form_view_ref' : 'dt_test.tst003_form',
'tree_view_ref' : 'dt_test.tst003_tree',
'default_tributos' : tributos,
'default_valor_total' : valor_total}" force_save="1" class="oe_horizontal_separator oe_clear"/>
                                </h6>
                            </group>
                        </page>
                    </notebook>
                </form>
            </field>
        </record>

        <record model="ir.ui.view" id="dt_fis.tst002_tree">
            <field name="model">dt_tst002</field>
            <field name="name">tst002_tree</field>
            <field name="arch" type="xml">
                <tree string="Ítens de documentos de entrada">
                    <field name="produto_id"/>
                    <field name="quantidade"/>
                    <field name="valor_unitario"/>

                    <!-- Enviar campos invisíveis para que seu conteúdo seja resgatado no formulário -->
                    <field name="seguro" invisible="1"/>
                    <field name="tributos" invisible="1"/>
                </tree>
            </field>
        </record>

        <!-- VIEWS PARA DOCUMENTOS DE ENTRADA E SAÍDA -->
        <record model="ir.ui.view" id="tst003_form">
            <field name="model">dt_tst003</field>
            <field name="name">tst003_form</field>
            <field name="arch" type="xml">
                <form string="Tributos de ítem de documento fiscal">
                    <sheet>
                        <group>
                            <field name="tributo_id"/>
                            <field name="base_calculo"/>
                            <field name="aliquota"/>
                            <field name="valor_tributo"/>
                        </group>
                    </sheet>
                </form>
            </field>
        </record>

        <record model="ir.ui.view" id="tst003_tree">
            <field name="model">dt_tst003</field>
            <field name="name">tst003_tree</field>
            <field name="arch" type="xml">
                <tree string="Tributos de ítem de documento fiscal">
                    <field name="tributo_id"/>
                    <field name="base_calculo"/>
                    <field name="aliquota"/>
                    <field name="valor_tributo"/>
                </tree>
            </field>
        </record>

        <record model="ir.actions.act_window" id="dt_test.tst001_action">
            <field name="name">Documentos de entrada - teste</field>
            <field name="res_model">dt_tst001</field>
            <field name="view_mode">tree,form</field>
            <field name="view_type">form</field>
            <field name="view_ids" eval="[(5, 0, 0),
(0, 0, {'view_mode': 'tree', 'view_id': ref('tst001_tree')}),
(0, 0, {'view_mode': 'form', 'view_id': ref('tst001_form')})]"/>
            <field name="view_type">form</field>
        </record>

        <menuitem name="Documentos de entrada" id="dt_test.tst001_menu" parent="dt_test.tst_menu_registros" action="dt_test.tst001_action" sequence="10"/>
    </data>
</odoo>

谢谢!

推荐答案

好吧,它似乎在第二个类中工作,因为计算了 DT_TST002 类的 seguro 字段基于 _recalc_impostos 函数.它不使用 on_change.还有一点要注意,DT_TST001 类和 DT_TST001 类之间没有关系DT_TST003.

well, it seems in the second class it is working because seguro field of class DT_TST002 is computed based on _recalc_impostos function. it doesn't use on_change. one more thing to note, is there are no relation between class DT_TST001 & DT_TST003.

根据您的评论,on_change 方法如下所示:

according to your comment the on_change method would be like the following:

@api.onchange('seguro_total')
    def _upd_seguro(self):
        for item in self.itens:
            seguro = ((item.quantidade * item.valor_unitario) / item.valor_total) * self.seguro_total
            tributes = []
            for tributo in item.tributos:
                base_calculo = (item.valor_total + item.seguro)
                valor_tributo = (item.valor_total + item.seguro) * tributo.aliquota / 100
                tributes.append((1, tributo.id, {'base_calculo' : base_calculo, 'valor_tributo' : valor_tributo}))
            item.update({
                'seguro' : seguro
                'tributos' : tributes,
                })

另外,请注意您可以按如下方式处理关系字段

also, please note that you can deal with relational fields as following

(0, 0,  { values })    link to a new record that needs to be created with the given values dictionary
(1, ID, { values })    update the linked record with id = ID (write *values* on it)
(2, ID)                remove and delete the linked record with id = ID (calls unlink on ID, that will delete the object completely, and the link to it as well)
(3, ID)                cut the link to the linked record with id = ID (delete the relationship between the two objects but does not delete the target object itself)
(4, ID)                link to existing record with id = ID (adds a relationship)
(5)                    unlink all (like using (3,ID) for all linked records)
(6, 0, [IDs])          replace the list of linked IDs (like using (5) then (4,ID) for each ID in the list of IDs)

这篇关于ODOO - 如何更新两个级别的 o2m 文件关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆