diff --git a/addons/account/models/account_invoice.py b/addons/account/models/account_invoice.py index 6c48ce84e9d..90b1727531d 100644 --- a/addons/account/models/account_invoice.py +++ b/addons/account/models/account_invoice.py @@ -1865,12 +1865,12 @@ class AccountInvoiceLine(models.Model): } return data - @api.model - def create(self, vals): - if vals.get('display_type', self.default_get(['display_type'])['display_type']): - vals.update(price_unit=0, account_id=False, quantity=0) - - return super(AccountInvoiceLine, self).create(vals) + @api.model_create_multi + def create(self, vals_list): + for vals in vals_list: + if vals.get('display_type', self.default_get(['display_type'])['display_type']): + vals.update(price_unit=0, account_id=False, quantity=0) + return super(AccountInvoiceLine, self).create(vals_list) @api.multi def write(self, values): diff --git a/addons/sale/models/sale.py b/addons/sale/models/sale.py index 5fec16b88a2..c73944cd777 100644 --- a/addons/sale/models/sale.py +++ b/addons/sale/models/sale.py @@ -522,6 +522,8 @@ class SaleOrder(models.Model): # We only want to create sections that have at least one invoiceable line pending_section = None + # Create lines in batch to avoid performance problems + line_vals_list = [] for line in order.order_line: if line.display_type == 'line_section': pending_section = line @@ -543,14 +545,21 @@ class SaleOrder(models.Model): if line.qty_to_invoice > 0 or (line.qty_to_invoice < 0 and final): if pending_section: - pending_section.invoice_line_create(invoices[group_key].id, pending_section.qty_to_invoice) + line_vals_list.extend(pending_section.invoice_line_create_vals( + invoices[group_key].id, + pending_section.qty_to_invoice + )) pending_section = None - line.invoice_line_create(invoices[group_key].id, line.qty_to_invoice) + line_vals_list.extend(line.invoice_line_create_vals( + invoices[group_key].id, line.qty_to_invoice + )) if references.get(invoices.get(group_key)): if order not in references[invoices[group_key]]: references[invoices[group_key]] |= order + self.env['account.invoice.line'].create(line_vals_list) + for group_key in invoices: invoices[group_key].write({'name': ', '.join(invoices_name[group_key]), 'origin': ', '.join(invoices_origin[group_key])}) @@ -1363,18 +1372,34 @@ class SaleOrderLine(models.Model): @api.multi def invoice_line_create(self, invoice_id, qty): """ Create an invoice line. The quantity to invoice can be positive (invoice) or negative (refund). + + .. deprecated:: 12.0 + Replaced by :func:`invoice_line_create_vals` which can be used for creating + `account.invoice.line` records in batch + :param invoice_id: integer :param qty: float quantity to invoice :returns recordset of account.invoice.line created """ - invoice_lines = self.env['account.invoice.line'] + return self.env['account.invoice.line'].create( + self.invoice_line_create_vals(invoice_id, qty)) + + def invoice_line_create_vals(self, invoice_id, qty): + """ Create an invoice line. The quantity to invoice can be positive (invoice) or negative + (refund). + + :param invoice_id: integer + :param qty: float quantity to invoice + :returns list of dict containing creation values for account.invoice.line records + """ + vals_list = [] precision = self.env['decimal.precision'].precision_get('Product Unit of Measure') for line in self: if not float_is_zero(qty, precision_digits=precision) or not line.product_id: vals = line._prepare_invoice_line(qty=qty) vals.update({'invoice_id': invoice_id, 'sale_line_ids': [(6, 0, [line.id])]}) - invoice_lines |= self.env['account.invoice.line'].create(vals) - return invoice_lines + vals_list.append(vals) + return vals_list @api.multi def _prepare_procurement_values(self, group_id=False):