SH EB
SH EB

Reputation: 61

create invoice line from custom module odoo 13

I have created a custom module and I have created a button to create an invoice the invoice was created successfully, but the problem is that the invoice line ids only create one line and ignore the other. here is my code

    def create_invoice(self):
    invoice = self.env['account.move'].create({
        'type': 'out_invoice',
        'state': 'draft',
        'journal_id': 1,
        'partner_id': self.partner_id.id,
        'amount_untaxed': self.package_price,
        'ref': self.name,
        'invoice_origin': self.name,
        'invoice_line_ids': [(0, 0, self._prepare_invoice_line())]
                           
    })

    return invoice
    
    
def _prepare_invoice_line(self):
    for order in self:
        for line in order.additional_services_ids:
            res = {
                'product_id': line.service_id.id,
                'quantity': line.quantity,
                'name': 'pro',
                'discount': 0,
                'price_unit': line.price_unit,
            }

        return res

Upvotes: 0

Views: 1100

Answers (2)

ex4
ex4

Reputation: 2428

Odoo many2many fields are pain.

You should have this kind of data structure in your invoice_line_ids

[
  (0,0,[invoice_line_1]),
  (0,0, [invoice_line_2]),
  ...
]

So modifying your code like this could work:

    def create_invoice(self):
    invoice = self.env['account.move'].create({
        'type': 'out_invoice',
        'state': 'draft',
        'journal_id': 1,
        'partner_id': self.partner_id.id,
        'amount_untaxed': self.package_price,
        'ref': self.name,
        'invoice_origin': self.name,
        'invoice_line_ids': [(0, 0, line) for line in self._prepare_invoice_line()]
                           
    })

    return invoice
    
    
def _prepare_invoice_line(self):
    res = []
    for order in self:
        for line in order.additional_services_ids:
            res.append({
                'product_id': line.service_id.id,
                'quantity': line.quantity,
                'name': 'pro',
                'discount': 0,
                'price_unit': line.price_unit,
            })
    return res

I don't know if this is a bug or by desing, but I've been banging my head to wall so many times with this.

--- EDIT --- There was a problem with _prepare_invoice_line -method as well. It was returning only one line instead of list of lines.

Upvotes: 1

Dipen Shah
Dipen Shah

Reputation: 2444

To create the multiple lines just do the loop over your data with the Odoo one2many syntax of creating data.

Example Code:

def create_invoice(self):
    invoice = self.env['account.move'].create({
        'type': 'out_invoice',
        'state': 'draft',
        'journal_id': 1,
        'partner_id': self.partner_id.id,
        'amount_untaxed': self.package_price,
        'ref': self.name,
        'invoice_origin': self.name,
        'invoice_line_ids': [(0, 0, {
                    'product_id': line.service_id.id,
                    'quantity': line.quantity,
                    'name': 'pro',
                    'discount': 0,
                    'price_unit': line.price_unit
                    }) for line in self.additional_services_ids] # Multiple Invoice Line Create code here
        })
    return invoice

(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, 0, 0) 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)

Upvotes: 1

Related Questions