Merge PR #414 into 12.0

Signed-off-by pedrobaeza
This commit is contained in:
OCA-git-bot
2020-01-29 17:54:00 +00:00
6 changed files with 196 additions and 5 deletions

View File

@@ -29,6 +29,7 @@
'data/contract_renew_cron.xml',
'data/mail_template.xml',
'wizards/contract_line_wizard.xml',
'wizards/contract_manually_create_invoice.xml',
'views/abstract_contract_line.xml',
'views/contract.xml',
'views/contract_line.xml',

View File

@@ -457,7 +457,17 @@ class ContractContract(models.Model):
This method triggers the creation of the next invoices of the contracts
even if their next invoicing date is in the future.
"""
return self._recurring_create_invoice()
invoice = self._recurring_create_invoice()
if invoice:
self.message_post(
body=_(
'Contract manually invoiced: '
'<a href="#" data-oe-model="%s" data-oe-id="%s">Invoice'
'</a>'
)
% (invoice._name, invoice.id)
)
return invoice
@api.multi
def _recurring_create_invoice(self, date_ref=False):
@@ -465,8 +475,9 @@ class ContractContract(models.Model):
return self._finalize_and_create_invoices(invoices_values)
@api.model
def cron_recurring_create_invoice(self):
domain = self._get_contracts_to_invoice_domain()
def cron_recurring_create_invoice(self, date_ref=None):
if not date_ref:
date_ref = fields.Date.context_today(self)
domain = self._get_contracts_to_invoice_domain(date_ref)
contracts_to_invoice = self.search(domain)
date_ref = fields.Date.context_today(contracts_to_invoice)
contracts_to_invoice._recurring_create_invoice(date_ref)
return contracts_to_invoice._recurring_create_invoice(date_ref)

View File

@@ -1737,6 +1737,39 @@ class TestContract(TestContractBase):
len(invoice_lines),
)
def test_contract_manually_create_invoice(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._onchange_date_start()
self.contract2.unlink()
contracts = self.contract
for i in range(10):
contracts |= self.contract.copy()
wizard = self.env['contract.manually.create.invoice'].create({
'invoice_date': self.today
})
wizard.action_show_contract_to_invoice()
contract_to_invoice_count = wizard.contract_to_invoice_count
self.assertEqual(
contracts,
self.env['contract.contract'].search(
wizard.action_show_contract_to_invoice()['domain']
),
)
action = wizard.create_invoice()
invoice_lines = self.env['account.invoice.line'].search(
[('contract_line_id', 'in',
contracts.mapped('contract_line_ids').ids)]
)
self.assertEqual(
len(contracts.mapped('contract_line_ids')),
len(invoice_lines),
)
invoices = self.env['account.invoice'].search(action['domain'])
self.assertEqual(invoice_lines.mapped('invoice_id'), invoices)
self.assertEqual(len(invoices), contract_to_invoice_count)
def test_get_period_to_invoice_monthlylastday_postpaid(self):
self.acct_line.date_start = '2018-01-05'
self.acct_line.recurring_invoicing_type = 'post-paid'

View File

@@ -1 +1,2 @@
from . import contract_line_wizard
from . import contract_manually_create_invoice

View File

@@ -0,0 +1,66 @@
# Copyright 2019 ACSONE SA/NV
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import api, fields, models, _
class ContractManuallyCreateInvoice(models.TransientModel):
_name = 'contract.manually.create.invoice'
_description = 'Contract Manually Create Invoice Wizard'
invoice_date = fields.Date(string="Invoice Date", required=True)
contract_to_invoice_count = fields.Integer(
compute="_compute_contract_to_invoice_ids"
)
contract_to_invoice_ids = fields.Many2many(
comodel_name="contract.contract",
compute="_compute_contract_to_invoice_ids",
)
contract_type = fields.Selection(
selection=[('sale', 'Customer'), ('purchase', 'Supplier')],
default='sale',
required=True,
)
@api.depends('invoice_date')
def _compute_contract_to_invoice_ids(self):
if not self.invoice_date:
# trick to show no invoice when no date has been entered yet
contract_to_invoice_domain = [('id', '=', False)]
else:
contract_to_invoice_domain = self.env[
'contract.contract'
]._get_contracts_to_invoice_domain(self.invoice_date)
self.contract_to_invoice_ids = self.env['contract.contract'].search(
contract_to_invoice_domain
+ [('contract_type', '=', self.contract_type)]
)
self.contract_to_invoice_count = len(self.contract_to_invoice_ids)
@api.multi
def action_show_contract_to_invoice(self):
self.ensure_one()
return {
"type": "ir.actions.act_window",
"name": _("Contracts to invoice"),
"res_model": "contract.contract",
"domain": [('id', 'in', self.contract_to_invoice_ids.ids)],
"view_mode": "tree,form",
"context": self.env.context,
}
@api.multi
def create_invoice(self):
self.ensure_one()
invoices = self.env['account.invoice']
for contract in self.contract_to_invoice_ids:
invoices |= contract.recurring_create_invoice()
return {
"type": "ir.actions.act_window",
"name": _("Invoices"),
"res_model": "account.invoice",
"domain": [('id', 'in', invoices.ids)],
"view_mode": "tree,form",
"context": self.env.context,
}

View File

@@ -0,0 +1,79 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2019 ACSONE SA/NV
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -->
<odoo>
<record model="ir.ui.view" id="contract_manually_create_invoice_form_view">
<field name="model">contract.manually.create.invoice</field>
<field name="arch" type="xml">
<form string="Contract Manually Create Invoice">
<group>
<group>
<field name="invoice_date"/>
<field name="contract_type" invisible="1"/>
</group>
<group>
<button name="action_show_contract_to_invoice" type="object"
class="btn-link"
attrs="{'invisible': [('contract_to_invoice_count', '=', 0)]}">
<field name="contract_to_invoice_count"/>
<span attrs="{'invisible': [('contract_to_invoice_count', '&gt;', 1)]}">
contract to invoice
</span>
<span attrs="{'invisible': [('contract_to_invoice_count', '&lt;', 1)]}">
contracts to invoice
</span>
</button>
</group>
</group>
<footer>
<button name="create_invoice"
attrs="{'invisible': [('contract_to_invoice_count', '=', 0)]}"
string="Create Invoices"
class="btn-primary"
type="object"/>
<button string="Cancel"
class="btn-default"
special="cancel"/>
</footer>
</form>
</field>
</record>
<record model="ir.actions.act_window"
id="sale_contract_manually_create_invoice_act_window">
<field name="name">Manually Invoice Sale Contracts</field>
<field name="res_model">contract.manually.create.invoice</field>
<field name="view_mode">form</field>
<field name="context">{'default_contract_type': 'sale'}</field>
<field name="target">new</field>
</record>
<record model="ir.ui.menu" id="sale_contract_manually_create_invoice_menu">
<field name="name">Manually Invoice Sale Contracts</field>
<field name="parent_id" ref="account.menu_finance_receivables"/>
<field name="groups_id" eval="[(6, 0, [ref('account.group_account_manager')])]"/>
<field name="action"
ref="sale_contract_manually_create_invoice_act_window"/>
<field name="sequence" eval="999"/>
</record>
<record model="ir.actions.act_window"
id="purchase_contract_manually_create_invoice_act_window">
<field name="name">Manually Invoice Purchase Contracts</field>
<field name="res_model">contract.manually.create.invoice</field>
<field name="view_mode">form</field>
<field name="context">{'default_contract_type': 'purchase'}</field>
<field name="target">new</field>
</record>
<record model="ir.ui.menu" id="purchase_contract_manually_create_invoice_menu">
<field name="name">Manually Invoice Purchase Contracts</field>
<field name="parent_id" ref="account.menu_finance_payables"/>
<field name="groups_id" eval="[(6, 0, [ref('account.group_account_manager')])]"/>
<field name="action"
ref="purchase_contract_manually_create_invoice_act_window"/>
<field name="sequence" eval="999"/>
</record>
</odoo>