pythonormodooodoo-10

Expected singleton error occurs when return more than one record in odoo?


This method to get the product price from the PO, and it works well if the PO have only one record otherwise I am getting this error.

raise ValueError("Expected singleton: %s" % self)

This is the method

@api.multi
def create_refund_invoice(self):
    inv_obj = self.env['account.invoice']
    for pick in self.filtered(lambda x:x.return_type):
        type = 'in_refund' if pick.return_type == 'purchase' else 'out_refund'
        inv_lines = {'type':type, 'partner_id':pick.partner_id.id, 'invoice_line_ids':[]}
        account = pick.return_type == 'sale' and pick.partner_id.property_account_receivable_id.id or pick.partner_id.property_account_payable_id.id
        inv_lines['account_id'] = account
        inv_lines['origin'] = pick.name
        inv_lines['name'] = pick.origin
        for line in pick.move_lines:
            name = line.product_id.partner_ref
            for rec in self:

                rec.order_id = line.env['purchase.order'].search([('name', '=', line.origin)]).order_line
                rec.price = rec.order_id.price_unit
            inv_lines['invoice_line_ids'] += [(0, None, {
                'product_id':line.product_id.id,
                'name':name,
                'quantity':line.quantity_done,
                'price_unit': rec.price,
                'account_id':line.product_id.product_tmpl_id.get_product_accounts()['income'].id})]
        if inv_lines['invoice_line_ids']:
            inv_id = inv_obj.create(inv_lines)
            pick.invoice_id = inv_id.id

Solution

  • It is necessary for odoo that when you are getting more than one record then you can not access it's field values directly.

    In your code you are trying to get purchase_order_line of purchase_order It may possible that many lines are available in a single order.

    def create_refund_invoice(self):
        purchase_order_obj = self.env['purchase.order']
        inv_obj = self.env['account.invoice']
        for pick in self.filtered(lambda x:x.return_type):
            type = 'in_refund' if pick.return_type == 'purchase' else 'out_refund'
            inv_lines = {'type':type, 'partner_id':pick.partner_id.id, 'invoice_line_ids':[]}
            account = pick.return_type == 'sale' and pick.partner_id.property_account_receivable_id.id or pick.partner_id.property_account_payable_id.id
            inv_lines['account_id'] = account
            inv_lines['origin'] = pick.name
            inv_lines['name'] = pick.origin
            for line in pick.move_lines:
                name = line.product_id.partner_ref
                for rec in self:
                    order_lines = purchase_order_obj.search([('name', '=', line.origin)]).order_line
                    for pol in order_lines:
                        price = pol.order_id.price_unit
                        inv_lines['invoice_line_ids'] += [(0, None, {
                                                'product_id':line.product_id.id,
                                                'name':name,
                                                'quantity':line.quantity_done,
                                                'price_unit': price,
                                                'account_id':line.product_id.product_tmpl_id.get_product_accounts()['income'].id})
                                                ]
            if inv_lines['invoice_line_ids']:
                inv_id = inv_obj.create(inv_lines)
                pick.invoice_id = inv_id.id
    

    I have updated code test above code and update it as per your requirement.