With this patch we save about 83% of the execution time when generating invoices in batch.
# Optimizations made
## Recompute once at the end of the batch
This part avoids recomputing many fields per record. Instead, global recomputations are triggered at the end of the block:
```python
with _self.env.norecompute():
...
invoices.compute_taxes()
_self.recompute()
```
Notice the explicit call to `compute_taxes()`, which was explicit before also, but it was done once per invoice, losing batch-computing boost.
## Disabling prefetch for extra fields
It's done in this part:
```python
_self = self.with_context(prefetch_fields=False)
```
Prefetching makes sense when we are going to use a lot of fields for a model that has only a few.
In our case, we are using not much fields, but the models involved have lots of them.
This produces more queries to get those fields, but the queries are noticeably smaller. At the end of the day, it saves a lot of time, which is what matters.
## Disabling track mail creation
This part does it:
```diff
ctx.update({
+ 'mail_notrack': True,
'next_date': next_date,
```
It makes that when creating invoices, we don't create the "Invoice created" message.
## Precomputing price
Obtaining `price_unit` from `contract.recurring_invoice_line_ids` was quite expenisve in terms of CPU, and it was being made once per line, each one in a different context, which means also a different cache.
Instead of that, lines now share a single context, and are computed before starting the batch.
This code precomputes stuff:
```python
# Precompute expensive computed fields in batch
recurring_lines = _self.mapped("recurring_invoice_line_ids")
recurring_lines._fields["price_unit"].determine_value(recurring_lines)
```
And the usage of 2 different environments done inside `_create_invoice()` (`self` and `_self`) guarantee that the invoices are filled with the correct data, but also that the lines use the cached precomputed value instead of having to compute it each time.
# Performance gain
According to my tests, generating 10 invoices took 62 seconds before, and it takes about 18 seconds now.
To avoid blocking the queue when there are more than the specified limit
of contracts, we process the limit while creating invoices instead
of while searching for contracts, and break the process when the
max of invoices has been created.
See https://github.com/OCA/contract/pull/260#pullrequestreview-192187022
for more details.
In case you need to use this new feature in the cron, it is
also modified as `noupdate=1`.
The test as it was, leaves to the demo pricelist the control on the price of
the product, so other modules that modifies this pricelist will make the
test to fail.
This is the minimum change needed for avoiding the problem.
In previous commit changed inheritance order of
'account.analytic.*.line' models, thus classes and models were renamed.
This commit only renames files to temporary names.
This commit does not change file contents.
Bug description
---------------
`account.analytic.contract.line` inherits
`account.analytic.invoice.line`
`account.analytic.invoice.line` defines field `analytic_account_id`:
- comodel='account.analytic.account'
`account.analytic.contract.line` redefines field `analytic_account_id`:
- comodel='account.analytic.contract'
On attempt to extend `account.analytic.invoice.line` model adding
field that depends on `analytic_account_id.date_start`
Odoo fails to update, because it adds this field to
`account.analytic.contract.line` through inheritance,
and `account.analytic.contract` model have no this field.
What is done
------------
Change inheritance order:
- `account.analytic.invoice.line` inherits
`account.analytic.contract.line`
- no file renames at this stage (this wil be done in next commit)
When a contrat had no payment token but the corresponding partner had
one, the transaction was created without an acquirer, leading to an
integrity error in postgres.
This change makes sure the token used to test the ability to pay an
invoice is passed along to the transaction creation call.
Tests were also added to check the ability to use the contract token if
present, but the partner's in the opposite case.
This change fixes#165.