简体   繁体   English

在 account.move.line Odoo 15 中添加计算小计的新 Float 字段时出现 move_type 错误

[英]move_type error while adding new Float field that computed it subtotal in account.move.line Odoo 15

enter image description here I got this error while trying to get my new added margin field computed in price_subtotal into customer invoice line (account.move.line) model. I already made override for both functions create() and _get_price_total_and_subtotal_model() and my Code as Follow: enter image description here我在尝试将在 price_subtotal 中计算的新添加保证金字段放入客户发票行 (account.move.line) model 时遇到此错误。我已经覆盖了函数 create() 和 _get_price_total_and_subtotal_model() 以及我的代码如下:

any solutions for this issue?这个问题有什么解决办法吗?

` `

class AccountMoveLine(models.Model):
    _inherit = 'account.move.line'
    margin = fields.Float(string='Margin (%)', digits='Margin',default=0.0)

    @api.model
    def _get_price_total_and_subtotal_model(self, price_unit, quantity, discount, margin,          
    currency, product, partner, taxes, move_type):
    ''' This method is used to compute 'price_total' & 'price_subtotal'.

        :param price_unit:  The current price unit.
        :param quantity:    The current quantity.
        :param discount:    The current discount.
        :param currency:    The line's currency.
        :param product:     The line's product.
        :param partner:     The line's partner.
        :param taxes:       The applied taxes.
        :param move_type:   The type of the move.
        :return:            A dictionary containing 'price_subtotal' & 'price_total'.
        '''
        res = {}
        # Compute 'price_subtotal'.
        line_discount_price_unit = price_unit * (1 + (margin / 100.0) - (discount / 100.0))
        subtotal = quantity * line_discount_price_unit
        # Compute 'price_total'.
        if taxes:
            taxes_res = taxes._origin.with_context(force_sign=1).
                       compute_all(line_discount_price_unit, quantity=quantity,currency=currency,
                       product=product, partner=partner,
                       is_refund=move_type in ('out_refund','in_refund'))
            res['price_subtotal'] = taxes_res['total_excluded']
            res['price_total'] = taxes_res['total_included']
        else:
            res['price_total'] = res['price_subtotal'] = subtotal
        # In case of multi currency, round before it's use for computing debit credit
        if currency:
            res = {k: currency.round(v) for k, v in res.items()}
        return res

    @api.model_create_multi
    def create(self, vals_list):
        # OVERRIDE
        lines = super(AccountMoveLine, self).create(vals_list)
        ACCOUNTING_FIELDS = ('debit', 'credit', 'amount_currency')
        BUSINESS_FIELDS = ('price_unit', 'quantity', 'margin', 'discount', 'tax_ids')
        for vals in vals_list:
            move = self.env['account.move'].browse(vals['move_id'])
            vals.setdefault('company_currency_id',
                            move.company_id.currency_id.id)  # important to bypass the ORM limitation where monetary fields are not rounded; more info in the commit message

            # Ensure balance == amount_currency in case of missing currency or same currency as the one from the
            # company.
            currency_id = vals.get('currency_id') or move.company_id.currency_id.id
            if currency_id == move.company_id.currency_id.id:
                balance = vals.get('debit', 0.0) - vals.get('credit', 0.0)
                vals.update({
                    'currency_id': currency_id,
                    'amount_currency': balance,
                })
            else:
                vals['amount_currency'] = vals.get('amount_currency', 0.0)

            if move.is_invoice(include_receipts=True):
                currency = move.currency_id
                partner = self.env['res.partner'].browse(vals.get('partner_id'))
                taxes = self.new({'tax_ids': vals.get('tax_ids', [])}).tax_ids
                tax_ids = set(taxes.ids)
                taxes = self.env['account.tax'].browse(tax_ids)

                # Ensure consistency between accounting & business fields.
                # As we can't express such synchronization as computed fields without cycling, we need to do it both
                # in onchange and in create/write. So, if something changed in accounting [resp. business] fields,
                # business [resp. accounting] fields are recomputed.
                if any(vals.get(field) for field in ACCOUNTING_FIELDS):
                    price_subtotal = self._get_price_total_and_subtotal_model(
                        vals.get('price_unit', 0.0),
                        vals.get('quantity', 0.0),
                        vals.get('discount', 0.0),
                        vals.get('margin', 0.0),
                        currency,
                        self.env['product.product'].browse(vals.get('product_id')),
                        partner,
                        taxes,
                        move.move_type,
                    ).get('price_subtotal', 0.0)
                    vals.update(self._get_fields_onchange_balance_model(
                        vals.get('quantity', 0.0),
                        vals.get('discount', 0.0),
                        vals['amount_currency'],
                        move.move_type,
                        currency,
                        taxes,
                        price_subtotal
                    ))
                    vals.update(sel`your text`f._get_price_total_and_subtotal_model(
                        vals.get('price_unit', 0.0),
                        vals.get('quantity', 0.0),
                        vals.get('discount', 0.0),
                        vals.get('margin', 0.0),
                        currency,
                        self.env['product.product'].browse(vals.get('product_id')),
                        partner,
                        taxes,
                        move.move_type,
                    ))
                elif any(vals.get(field) for field in BUSINESS_FIELDS):
                    vals.update(self._get_price_total_and_subtotal_model(
                        vals.get('price_unit', 0.0),
                        vals.get('quantity', 0.0),
                        vals.get('discount', 0.0),
                        vals.get('margin', 0.0),
                        currency,
                        self.env['product.product'].browse(vals.get('product_id')),
                        partner,
                        taxes,
                        move.move_type,
                    ))
                    vals.update(self._get_fields_onchange_subtotal_model(
                        vals['price_subtotal'],
                        move.move_type,
                        currency,
                        move.company_id,
                        move.date,
                    ))



        moves = lines.mapped('move_id')
        if self._context.get('check_move_validity', True):
            moves._check_balanced()
        moves.filtered(lambda m: m.state == 'posted')._check_fiscalyear_lock_date()
        lines.filtered(lambda l: l.parent_state == 'posted')._check_tax_lock_date()
        moves._synchronize_business_models({'line_ids'})

        return lines
`

When you override a method and change the signature by adding a new argument, this can be work if you called _get_price_total_and_subtotal_model from the same class, but your overrided create method calls the super and the super will call _get_price_total_and_subtotal_model in the same class so you get this error because the super class uses a different signature for that same method name.当您重写一个方法并通过添加新参数更改签名时,如果您从同一个 class 调用_get_price_total_and_subtotal_model ,这可能会起作用,但是您重写的create方法调用super并且 super 将在同一个 class 中调用_get_price_total_and_subtotal_model所以你得到这个错误是因为 super class 对相同的方法名称使用了不同的签名。

Odoo tries to call the _get_price_total_and_subtotal_model function and pass 8 parameters but you redefined the function to use 9 parameters and move_type is the last and missing parameter: Odoo 尝试调用_get_price_total_and_subtotal_model function 并传递 8 个参数,但您重新定义了 function 以使用 9 个参数,而move_type是最后一个缺少的参数:

price_subtotal = self._get_price_total_and_subtotal_model(
                        vals.get('price_unit', 0.0),
                        vals.get('quantity', 0.0),
                        vals.get('discount', 0.0),
                        currency,
                        self.env['product.product'].browse(vals.get('product_id')),
                        partner,
                        taxes,
                        move.move_type,
                    ).get('price_subtotal', 0.0)

by adding the margin parameter just after discount , you created a new function that is inconsistent with the default function used by Odoo and will return an unexpected result.通过在discount之后添加margin参数,您创建了一个新的 function,它与 Odoo 使用的默认 function 不一致,将返回意外结果。

Also when Odoo triggers the _onchange_price_subtotal function, it uses the parameter names and will raise the following error此外,当 Odoo 触发_onchange_price_subtotal function 时,它使用参数名称并会引发以下错误

TypeError: _get_price_total_and_subtotal_model() missing 1 required positional argument: 'margin'

To overload the function you can use optional parameters要重载 function,您可以使用可选参数

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM