Как исправить ValueError: Ожидается синглтон sale.order (41, ...) - PullRequest
0 голосов
/ 07 января 2019

Я написал собственный модуль odoo, и когда я его устанавливаю, он выдает одноэтапную ошибку. Когда я закомментирую все внутри _compute_margin (self) и просто верну 0.0, модуль установится нормально. Когда я затем изменяю функцию _compute_margin обратно на оригинальную и обновляю модуль, он обновляется нормально.

Какие изменения нужно внести, чтобы модуль мог нормально работать с содержимым функции _compute_margin?

class MyCompanyintercompanyMargin(models.Model):
    _name = 'my_companyintercompany.margin'
    name = fields.Char()
    x_marginsplitmodel = fields.Char()
    x_marginsplitdescription = fields.Char()

class ResPartner(models.Model):
    _name = 'res.partner'
    _inherit = 'res.partner'

    x_my_companyintercompany = fields.Boolean()
    x_my_companyintercompany_marginsplit = fields.Many2one(
        'my_companyintercompany.margin',
        string='Margin Split Model'
    )

    class SaleOrder(models.Model):
    _name = 'sale.order'
    _inherit = 'sale.order'

    x_endcustomer = fields.Many2one(
            comodel_name='res.partner',
            string='Customer'
    )

    x_my_companyintercompany_marginsplit = fields.Many2one(string='Margin Split', related="partner_id.x_my_companyintercompany_marginsplit")
    x_my_companyintercompany_marginsplitid = fields.Char(related="x_my_companyintercompany_marginsplit.name", string="Margin Split")

    x_prsmarginpercentage = fields.Float(string="Marge %")

    @api.depends('order_line.margin')
    def _compute_margin(self):
        amount_untaxed = self.amount_untaxed
        if self.x_my_companyintercompany_marginsplit:
            try:
                if self.x_my_companyintercompany_marginsplitid == "Total -2,5%":
                    totalordercost = 0.0
                    for line in self.order_line:
                        totalordercost += line.purchase_price * line.product_uom_qty
                    intercompanymargin = amount_untaxed * 0.025
                    self.x_prsmargin = amount_untaxed - totalordercost - intercompanymargin
                elif self.x_my_companyintercompany_marginsplitid == "Marge 50/50":
                    self.x_prsmargin = self.margin / 2
                else:
                    self.x_prsmargin = self.margin
            except:
                raise "Exception!"
        else:
            self.x_prsmargin = self.margin
        if amount_untaxed > 0.0:
              self.x_prsmarginpercentage = self.x_prsmargin / amount_untaxed * 100
        else:
               self.x_prsmarginpercentage = 0.0
    x_prsmargin = fields.Monetary(compute='_compute_margin', store='true')

Ответы [ 2 ]

0 голосов
/ 08 января 2019

Метод вычисления будет вызываться с несколькими записями, которые предоставлены в self. Но вы пытаетесь получить атрибуты непосредственно из self, который работает только на синглетах (наборы записей с одной записью).

Таким образом, у вас есть два варианта решения проблемы:

  1. Перепишите ваш метод как цикл for на self. Вы также должны украсить метод с @api.multi. Простой пример:
@api.multi
@api.depends('field1', 'field2', 'fieldn')
def _compute_my_field(self):
    for record in self:
        record.my_field = 4711
  1. Просто украсьте ваш метод вычисления с помощью @api.one, чтобы Odoo зациклился на каждой записи в self. Odoo будет зацикливаться на каждой записи в self и будет собирать возвращаемые значения метода в список, который будет возвращаемым значением в конце цикла. Вы можете использовать self так, как вы уже используете: как синглтон.
0 голосов
/ 08 января 2019

Вам нужно украсить свой метод вычисления с помощью @api.multi.

По сути, когда Odoo пытается инициализировать ваше новое поле в базе данных, оно рассчитывает сразу на несколько записей. То, как вы настроили свой метод в настоящее время, может поддерживать только одну запись за раз, поэтому вы получаете сообщение Ожидаемый синглтон .

Попробуйте следующее:

# First, include the @api.multi decorator
@api.multi
@api.depends('order_line.margin')
def _compute_margin(self):
    # Second, use a for loop to loop over self
    # because it's possible for self to be multiple records
    for order in self:
        # Finally, use your same method logic in the loop...

        # Except that you must assign the result **per record**
        # in the loop (with `order` in this example instead of `self`)
        order.x_prsmarginpercentage = ...

Подробнее см. В Документация Odoo ORM

...