mirror of
https://github.com/OCA/contract.git
synced 2025-02-13 17:57:24 +02:00
Merge pull request #266 from Tecnativa/10-contract-optimize
[10.0][IMP] contract: Performance boost 🚀
This commit is contained in:
@@ -16,6 +16,25 @@ Configuration
|
|||||||
|
|
||||||
To view discount field set *Discount on lines* in user access rights.
|
To view discount field set *Discount on lines* in user access rights.
|
||||||
|
|
||||||
|
You might find that generating all pending invoices at once takes too much
|
||||||
|
time and produces some performance problems, mostly in cases where you
|
||||||
|
generate a lot of invoices in little time (i.e. when invoicing thousands
|
||||||
|
of contracts yearly, and you get to January 1st of the next year). To avoid
|
||||||
|
this bottleneck, the trick is to **increase the cron frequence and decrease
|
||||||
|
the contracts batch size**. The counterpart is that some invoices could not
|
||||||
|
be generated in the exact day you expected. To configure that:
|
||||||
|
|
||||||
|
#. Go to *Settings > Activate the developer mode*.
|
||||||
|
#. Go to *Settings > Technical > Automation > Scheduled Actions >
|
||||||
|
Generate Recurring Invoices from Contracts > Edit > Information*.
|
||||||
|
#. Set a lower interval. For example, change *Interval Unit* to *Hours*.
|
||||||
|
#. Go to the *Technical Data* tab, and add a batch size in *Arguments*.
|
||||||
|
For example, it should look like ``(20,)``.
|
||||||
|
#. Save.
|
||||||
|
|
||||||
|
That's it! From now on, only 20 invoices per hour will be generated.
|
||||||
|
That should take only a few seconds each hour, and shouln't block other users.
|
||||||
|
|
||||||
Usage
|
Usage
|
||||||
=====
|
=====
|
||||||
|
|
||||||
|
|||||||
@@ -255,12 +255,16 @@ class AccountAnalyticAccount(models.Model):
|
|||||||
@api.multi
|
@api.multi
|
||||||
def _create_invoice(self):
|
def _create_invoice(self):
|
||||||
self.ensure_one()
|
self.ensure_one()
|
||||||
invoice_vals = self._prepare_invoice()
|
# Re-read contract with correct company
|
||||||
invoice = self.env['account.invoice'].create(invoice_vals)
|
_self = self.with_context(self.get_invoice_context())
|
||||||
|
invoice_vals = _self._prepare_invoice()
|
||||||
|
invoice = _self.env['account.invoice'].create(invoice_vals)
|
||||||
|
# Lines are read from an env where expensive values are precomputed
|
||||||
for line in self.recurring_invoice_line_ids:
|
for line in self.recurring_invoice_line_ids:
|
||||||
invoice_line_vals = self._prepare_invoice_line(line, invoice.id)
|
invoice_line_vals = _self._prepare_invoice_line(line, invoice.id)
|
||||||
self.env['account.invoice.line'].create(invoice_line_vals)
|
_self.env['account.invoice.line'].create(invoice_line_vals)
|
||||||
invoice.compute_taxes()
|
# Update next invoice date for current contract
|
||||||
|
_self.recurring_next_date = _self.env.context['next_date']
|
||||||
return invoice
|
return invoice
|
||||||
|
|
||||||
@api.multi
|
@api.multi
|
||||||
@@ -287,6 +291,7 @@ class AccountAnalyticAccount(models.Model):
|
|||||||
relativedelta(days=1))
|
relativedelta(days=1))
|
||||||
date_to = date_start
|
date_to = date_start
|
||||||
ctx.update({
|
ctx.update({
|
||||||
|
'mail_notrack': True,
|
||||||
'next_date': next_date,
|
'next_date': next_date,
|
||||||
'date_format': date_format,
|
'date_format': date_format,
|
||||||
'date_from': date_from,
|
'date_from': date_from,
|
||||||
@@ -317,18 +322,21 @@ class AccountAnalyticAccount(models.Model):
|
|||||||
|
|
||||||
:return: invoices created
|
:return: invoices created
|
||||||
"""
|
"""
|
||||||
invoices = self.env['account.invoice']
|
_self = self.with_context(prefetch_fields=False)
|
||||||
for contract in self:
|
invoices = _self.env['account.invoice']
|
||||||
if limit and len(invoices) >= limit:
|
# Precompute expensive computed fields in batch
|
||||||
break
|
recurring_lines = _self.mapped("recurring_invoice_line_ids")
|
||||||
if not contract.check_dates_valid():
|
recurring_lines._fields["price_unit"].determine_value(recurring_lines)
|
||||||
continue
|
# Create invoices
|
||||||
# Re-read contract with correct company
|
with _self.env.norecompute():
|
||||||
ctx = contract.get_invoice_context()
|
for contract in _self:
|
||||||
invoices |= contract.with_context(ctx)._create_invoice()
|
if limit and len(invoices) >= limit:
|
||||||
contract.write({
|
break
|
||||||
'recurring_next_date': fields.Date.to_string(ctx['next_date'])
|
if not contract.check_dates_valid():
|
||||||
})
|
continue
|
||||||
|
invoices |= contract._create_invoice()
|
||||||
|
invoices.compute_taxes()
|
||||||
|
_self.recompute()
|
||||||
return invoices
|
return invoices
|
||||||
|
|
||||||
@api.model
|
@api.model
|
||||||
|
|||||||
Reference in New Issue
Block a user