Merge PR #741 into 14.0

Signed-off-by pedrobaeza
This commit is contained in:
OCA-git-bot
2022-01-26 08:10:09 +00:00
5 changed files with 170 additions and 16 deletions

View File

@@ -48,6 +48,20 @@ class ContractAbstractContract(models.AbstractModel):
help="Mark this check if you want to control recurrrence at line level instead" help="Mark this check if you want to control recurrrence at line level instead"
" of all together for the whole contract.", " of all together for the whole contract.",
) )
generation_type = fields.Selection(
string="Generation Type",
selection=lambda self: self._selection_generation_type(),
default=lambda self: self._default_generation_type(),
help="Choose the document that will be automatically generated by cron.",
)
@api.model
def _selection_generation_type(self):
return [("invoice", "Invoice")]
@api.model
def _default_generation_type(self):
return "invoice"
@api.onchange("contract_type") @api.onchange("contract_type")
def _onchange_contract_type(self): def _onchange_contract_type(self):

View File

@@ -6,12 +6,16 @@
# Copyright 2018 ACSONE SA/NV # Copyright 2018 ACSONE SA/NV
# Copyright 2021 Tecnativa - Víctor Martínez # Copyright 2021 Tecnativa - Víctor Martínez
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
import logging
from odoo import api, fields, models from odoo import api, fields, models
from odoo.exceptions import UserError, ValidationError from odoo.exceptions import UserError, ValidationError
from odoo.osv import expression
from odoo.tests import Form from odoo.tests import Form
from odoo.tools.translate import _ from odoo.tools.translate import _
_logger = logging.getLogger(__name__)
class ContractContract(models.Model): class ContractContract(models.Model):
_name = "contract.contract" _name = "contract.contract"
@@ -595,23 +599,46 @@ class ContractContract(models.Model):
return moves return moves
@api.model @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: if not date_ref:
date_ref = fields.Date.context_today(self) date_ref = fields.Date.context_today(self)
domain = self._get_contracts_to_invoice_domain(date_ref) 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 # Invoice by companies, so assignation emails get correct context
companies_to_invoice = self.read_group(domain, ["company_id"], ["company_id"]) for company in companies:
for row in companies_to_invoice: contracts_to_invoice = contracts.filtered(
contracts_to_invoice = ( lambda c: c.company_id == company
self.search(row["__domain"]) and (not c.date_end or c.recurring_next_date <= c.date_end)
.with_context(allowed_company_ids=[row["company_id"][0]]) ).with_company(company)
.filtered( _recurring_create_func(contracts_to_invoice, date_ref)
lambda a: not a.date_end or a.recurring_next_date <= a.date_end return True
)
) @api.model
invoices |= contracts_to_invoice._recurring_create_invoice(date_ref) def cron_recurring_create_invoice(self, date_ref=None):
return invoices return self._cron_recurring_create(date_ref, create_type="invoice")
def action_terminate_contract(self): def action_terminate_contract(self):
self.ensure_one() self.ensure_one()

View File

@@ -1,4 +1,3 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from . import test_contract from . import test_contract
from . import test_portal from . import test_portal
from . import test_multicompany

View File

@@ -0,0 +1,110 @@
# Copyright 2021 ACSONE SA/NV (<http://acsone.eu>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from .test_contract import TestContractBase
class ContractMulticompanyCase(TestContractBase):
@classmethod
def setUpClass(cls):
super().setUpClass()
chart_template = cls.env.ref("l10n_generic_coa.configurable_chart_template")
cls.company_obj = cls.env["res.company"]
cls.company_1 = cls.env.ref("base.main_company")
vals = {"name": "Company 2"}
cls.company_2 = cls.company_obj.create(vals)
chart_template.try_loading(company=cls.company_2)
cls.env.user.company_ids |= cls.company_2
cls.contract_mc = (
cls.env["contract.contract"]
.with_company(cls.company_2)
.create(
{
"name": "Test Contract MC",
"partner_id": cls.partner.id,
"pricelist_id": cls.partner.property_product_pricelist.id,
"line_recurrence": True,
"contract_type": "purchase",
"contract_line_ids": [
(
0,
0,
{
"product_id": cls.product_1.id,
"name": "Services from #START# to #END#",
"quantity": 1,
"uom_id": cls.product_1.uom_id.id,
"price_unit": 100,
"discount": 50,
"recurring_rule_type": "monthly",
"recurring_interval": 1,
"date_start": "2018-02-15",
"recurring_next_date": "2018-02-22",
},
)
],
}
)
)
cls.line_vals = {
"contract_id": cls.contract_mc.id,
"product_id": cls.product_1.id,
"name": "Services from #START# to #END#",
"quantity": 1,
"uom_id": cls.product_1.uom_id.id,
"price_unit": 100,
"discount": 50,
"recurring_rule_type": "monthly",
"recurring_interval": 1,
"date_start": "2018-01-01",
"recurring_next_date": "2018-01-15",
"is_auto_renew": False,
}
cls.acct_line_mc = (
cls.env["contract.line"].with_company(cls.company_2).create(cls.line_vals)
)
def test_cron_recurring_create_invoice_multi_company(self):
self.acct_line.date_start = "2018-01-01"
self.acct_line.recurring_invoicing_type = "post-paid"
self.acct_line.date_end = "2018-03-15"
self.acct_line_mc.date_start = "2018-01-01"
self.acct_line_mc.recurring_invoicing_type = "post-paid"
self.acct_line_mc.date_end = "2018-03-15"
contracts = self.contract2
contracts_company_2 = self.env["contract.contract"].browse()
for _i in range(10):
contracts |= self.contract.copy()
for _i in range(10):
vals = (
self.contract_mc.with_company(company=self.company_2)
.with_context(active_test=False)
.copy_data({"company_id": self.company_2.id})
)
contracts_company_2 |= self.contract_mc.with_company(
company=self.company_2
).create(vals)
self.env["contract.contract"].cron_recurring_create_invoice()
# Check company 1
invoice_lines_company_1 = self.env["account.move.line"].search(
[("contract_line_id", "in", contracts.mapped("contract_line_ids").ids)]
)
invoice_lines_company_2 = self.env["account.move.line"].search(
[
(
"contract_line_id",
"in",
contracts_company_2.mapped("contract_line_ids").ids,
)
]
)
self.assertEqual(
len(contracts.mapped("contract_line_ids")), len(invoice_lines_company_1)
)
self.assertEqual(
len(contracts_company_2.mapped("contract_line_ids")),
len(invoice_lines_company_2),
)

View File

@@ -40,7 +40,7 @@
<button <button
name="recurring_create_invoice" name="recurring_create_invoice"
type="object" type="object"
attrs="{'invisible': [('create_invoice_visibility', '=', False)]}" attrs="{'invisible': ['|', ('create_invoice_visibility', '=', False),('generation_type','!=','invoice')]}"
string="Create invoices" string="Create invoices"
groups="base.group_no_one" groups="base.group_no_one"
/> />
@@ -82,6 +82,7 @@
type="object" type="object"
icon="fa-list" icon="fa-list"
class="oe_stat_button" class="oe_stat_button"
attrs="{'invisible': [('generation_type','!=','invoice')]}"
> >
<field <field
string="Invoices" string="Invoices"
@@ -175,6 +176,9 @@
<field name="recurring_next_date" /> <field name="recurring_next_date" />
</group> </group>
</group> </group>
<group col="4" name="recurring_type" string="Recurring Type">
<field name="generation_type" />
</group>
<notebook> <notebook>
<page name="recurring_invoice_line" string="Recurring Invoices"> <page name="recurring_invoice_line" string="Recurring Invoices">
<field <field