[FIX+IMP] contract: lots of things

- Improve invoice generation through cron
  Avoid too much sql queries by iterating on first search
  Avoid performances problems through invoices ids isntead
  of recordset
- Improve tests
  Adds multi company tests
- Add a generation type on contract
  Add a generation type on contract that allows to generate other
  document than invoice (e.g. sale order)
- Allows to get several functions to create recurring documents
- Set visibility on button to show invoices
- Add generation_type field
- Update button visibility
- Simplify test flow
- Use Odoo conventions for methods
- Add explicit cron create type for invoices
- Improve function call for cron recurring creates
- Improve multi-company tests / don't break former tests structure
- Fix forwardport from 14.0 #741
This commit is contained in:
Denis Roussel
2021-11-03 18:20:54 +01:00
committed by Christopher Rogos
parent 1b1b2fd477
commit b36db56b6a
5 changed files with 169 additions and 16 deletions

View File

@@ -6,12 +6,16 @@
# Copyright 2018 ACSONE SA/NV
# Copyright 2021 Tecnativa - Víctor Martínez
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
import logging
from odoo import api, fields, models
from odoo.exceptions import UserError, ValidationError
from odoo.osv import expression
from odoo.tests import Form
from odoo.tools.translate import _
_logger = logging.getLogger(__name__)
class ContractContract(models.Model):
_name = "contract.contract"
@@ -607,23 +611,46 @@ class ContractContract(models.Model):
return moves
@api.model
def cron_recurring_create_invoice(self, date_ref=None):
def _get_recurring_create_func(self, create_type="invoice"):
"""
Allows to retrieve the recurring create function depending
on generate_type attribute
"""
if create_type == "invoice":
return self.__class__._recurring_create_invoice
@api.model
def _cron_recurring_create(self, date_ref=False, create_type="invoice"):
"""
The cron function in order to create recurrent documents
from contracts.
"""
_recurring_create_func = self._get_recurring_create_func(
create_type=create_type
)
if not date_ref:
date_ref = fields.Date.context_today(self)
domain = self._get_contracts_to_invoice_domain(date_ref)
invoices = self.env["account.move"]
domain = expression.AND(
[
domain,
[("generation_type", "=", create_type)],
]
)
contracts = self.search(domain)
companies = set(contracts.mapped("company_id"))
# Invoice by companies, so assignation emails get correct context
companies_to_invoice = self.read_group(domain, ["company_id"], ["company_id"])
for row in companies_to_invoice:
contracts_to_invoice = (
self.search(row["__domain"])
.with_context(allowed_company_ids=[row["company_id"][0]])
.filtered(
lambda a: not a.date_end or a.recurring_next_date <= a.date_end
)
)
invoices |= contracts_to_invoice._recurring_create_invoice(date_ref)
return invoices
for company in companies:
contracts_to_invoice = contracts.filtered(
lambda c: c.company_id == company
and (not c.date_end or c.recurring_next_date <= c.date_end)
).with_company(company)
_recurring_create_func(contracts_to_invoice, date_ref)
return True
@api.model
def cron_recurring_create_invoice(self, date_ref=None):
return self._cron_recurring_create(date_ref, create_type="invoice")
def action_terminate_contract(self):
self.ensure_one()