sbejaoui
6 years ago
committed by
Thomas Binsfeld
10 changed files with 231 additions and 34 deletions
-
3product_contract/__manifest__.py
-
24product_contract/models/product_template.py
-
12product_contract/models/sale_order.py
-
49product_contract/models/sale_order_line.py
-
2product_contract/tests/__init__.py
-
2product_contract/tests/test_sale_order.py
-
37product_contract/tests/test_sale_order_line.py
-
44product_contract/views/product_template.xml
-
29product_contract/views/product_template_view.xml
-
63product_contract/views/sale_order.xml
@ -1,14 +1,57 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# Copyright 2017 LasLabs Inc. |
|||
# Copyright 2017 ACSONE SA/NV. |
|||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
|||
|
|||
from odoo import fields, models |
|||
from odoo import api, fields, models |
|||
|
|||
|
|||
class SaleOrderLine(models.Model): |
|||
_inherit = 'sale.order.line' |
|||
|
|||
is_contract = fields.Boolean( |
|||
string='Is a contract', related="product_id.is_contract" |
|||
) |
|||
contract_id = fields.Many2one( |
|||
comodel_name='account.analytic.account', |
|||
string='Contract' |
|||
comodel_name='account.analytic.account', string='Contract' |
|||
) |
|||
recurring_rule_type = fields.Selection( |
|||
[ |
|||
('daily', 'Day(s)'), |
|||
('weekly', 'Week(s)'), |
|||
('monthly', 'Month(s)'), |
|||
('monthlylastday', 'Month(s) last day'), |
|||
('yearly', 'Year(s)'), |
|||
], |
|||
default='monthly', |
|||
string='Recurrence', |
|||
help="Specify Interval for automatic invoice generation.", |
|||
copy=False, |
|||
) |
|||
recurring_invoicing_type = fields.Selection( |
|||
[('pre-paid', 'Pre-paid'), ('post-paid', 'Post-paid')], |
|||
default='pre-paid', |
|||
string='Invoicing type', |
|||
help="Specify if process date is 'from' or 'to' invoicing date", |
|||
copy=False, |
|||
) |
|||
recurring_interval = fields.Integer( |
|||
default=1, |
|||
string='Repeat Every', |
|||
help="Repeat every (Days/Week/Month/Year)", |
|||
copy=False, |
|||
) |
|||
date_start = fields.Date(string='Date Start', default=fields.Date.today()) |
|||
date_end = fields.Date(string='Date End', index=True) |
|||
recurring_next_date = fields.Date( |
|||
default=fields.Date.today(), copy=False, string='Date of Next Invoice' |
|||
) |
|||
|
|||
@api.onchange('product_id') |
|||
def onchange_product(self): |
|||
if self.product_id.is_contract: |
|||
self.recurring_rule_type = self.product_id.recurring_rule_type |
|||
self.recurring_invoicing_type = ( |
|||
self.product_id.recurring_invoicing_type |
|||
) |
|||
self.recurring_interval = self.product_id.recurring_interval |
@ -1,6 +1,8 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# Copyright 2017 LasLabs Inc. |
|||
# Copyright 2018 ACSONE SA/NV. |
|||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
|||
|
|||
from . import test_product |
|||
from . import test_sale_order |
|||
from . import test_sale_order_line |
@ -0,0 +1,37 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# Copyright 2018 ACSONE SA/NV. |
|||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
|||
|
|||
from mock import MagicMock |
|||
from odoo.tests.common import TransactionCase |
|||
|
|||
|
|||
class TestSaleOrder(TransactionCase): |
|||
|
|||
def setUp(self): |
|||
super(TestSaleOrder, self).setUp() |
|||
self.product = self.env.ref('product.product_product_1') |
|||
self.sale = self.env.ref('sale.sale_order_2') |
|||
self.contract = self.env['account.analytic.contract'].create({ |
|||
'name': 'Test', |
|||
}) |
|||
self.product.product_tmpl_id.is_contract = True |
|||
self.sale_order_line = self.sale.order_line.filtered( |
|||
lambda l: l.product_id == self.product |
|||
) |
|||
|
|||
def test_onchange_product(self): |
|||
""" It should get recurrence invoicing info to the sale line from |
|||
its product """ |
|||
self.assertEqual( |
|||
self.sale_order_line.recurring_rule_type, |
|||
self.product.recurring_rule_type |
|||
) |
|||
self.assertEqual( |
|||
self.sale_order_line.recurring_interval, |
|||
self.product.recurring_interval |
|||
) |
|||
self.assertEqual( |
|||
self.sale_order_line.recurring_invoicing_type, |
|||
self.product.recurring_invoicing_type |
|||
) |
@ -0,0 +1,44 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
|
|||
<!-- |
|||
Copyright 2017 LasLabs Inc. |
|||
Copyright 2018 ACSONE SA/NV. |
|||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
|||
--> |
|||
|
|||
<odoo> |
|||
|
|||
<record id="product_template_form_contract_view" model="ir.ui.view"> |
|||
<field name="name">account.invoice.select.contract</field> |
|||
<field name="model">product.template</field> |
|||
<field name="inherit_id" ref="product.product_template_form_view"/> |
|||
<field name="arch" type="xml"> |
|||
<xpath expr="//div[@name='options']" position="inside"> |
|||
<div> |
|||
<field name="is_contract"/> |
|||
<label for="is_contract"/> |
|||
</div> |
|||
</xpath> |
|||
<xpath expr="//group[@name='group_standard_price']" |
|||
position="inside"> |
|||
<field name="contract_template_id" |
|||
attrs="{'invisible': [('is_contract', '=', False)], |
|||
'required':[('is_contract', '=', True)]}"/> |
|||
<field name="recurring_invoicing_type" |
|||
attrs="{'invisible': [('is_contract', '=', False)], |
|||
'required':[('is_contract', '=', True)]}"/> |
|||
|
|||
<label for="recurring_interval" attrs="{'invisible': [('is_contract', '=', False)], |
|||
'required':[('is_contract', '=', True)]}"/> |
|||
<div attrs="{'invisible': [('is_contract', '=', False)], |
|||
'required':[('is_contract', '=', True)]}"> |
|||
<field name="recurring_interval" |
|||
class="oe_inline" nolabel="1"/> |
|||
<field name="recurring_rule_type" |
|||
class="oe_inline" nolabel="1"/> |
|||
</div> |
|||
</xpath> |
|||
</field> |
|||
</record> |
|||
|
|||
</odoo> |
@ -1,29 +0,0 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
|
|||
<!-- |
|||
Copyright 2017 LasLabs Inc. |
|||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
|||
--> |
|||
|
|||
<odoo> |
|||
|
|||
<record id="product_template_form_contract_view" model="ir.ui.view"> |
|||
<field name="name">account.invoice.select.contract</field> |
|||
<field name="model">product.template</field> |
|||
<field name="inherit_id" ref="product.product_template_form_view"/> |
|||
<field name="arch" type="xml"> |
|||
<xpath expr="//div[@name='options']" position="inside"> |
|||
<div> |
|||
<field name="is_contract" /> |
|||
<label for="is_contract" /> |
|||
</div> |
|||
</xpath> |
|||
<xpath expr="//group[@name='group_standard_price']" position="inside"> |
|||
<field name="contract_template_id" |
|||
attrs="{'invisible': [('is_contract', '=', False)], |
|||
'required':[('is_contract', '=', True)]}" /> |
|||
</xpath> |
|||
</field> |
|||
</record> |
|||
|
|||
</odoo> |
@ -0,0 +1,63 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
|
|||
<!-- |
|||
Copyright 2018 ACSONE SA/NV. |
|||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
|||
--> |
|||
|
|||
<odoo> |
|||
|
|||
<record id="view_order_form" model="ir.ui.view"> |
|||
<field name="name">sale.order.form (in product_contract)</field> |
|||
<field name="model">sale.order</field> |
|||
<field name="inherit_id" ref="sale.view_order_form"/> |
|||
<field name="arch" type="xml"> |
|||
<xpath expr="//field[@name='order_line']" position="before"> |
|||
<field name="is_contract" invisible="1"/> |
|||
</xpath> |
|||
<xpath expr="//field[@name='order_line']/form//field[@name='tax_id']/parent::group" |
|||
position="after"> |
|||
<separator colspan="4" string="Recurrence Invoicing" |
|||
attrs="{'invisible': [('is_contract', '=', False)]}"/> |
|||
<group attrs="{'invisible': [('is_contract', '=', False)]}"> |
|||
<field name="is_contract" invisible="1"/> |
|||
<field name="recurring_invoicing_type" |
|||
attrs="{'invisible': [('is_contract', '=', False)], |
|||
'required':[('is_contract', '=', True)]}"/> |
|||
</group> |
|||
<group attrs="{'invisible': [('is_contract', '=', False)]}"> |
|||
<label for="recurring_interval"/> |
|||
<div> |
|||
<field name="recurring_interval" |
|||
class="oe_inline" nolabel="1" |
|||
attrs="{'required':[('is_contract', '=', True)]}"/> |
|||
<field name="recurring_rule_type" |
|||
class="oe_inline" nolabel="1" |
|||
attrs="{'required':[('is_contract', '=', True)]}"/> |
|||
</div> |
|||
</group> |
|||
<group attrs="{'invisible': [('is_contract', '=', False)]}"> |
|||
<field name="date_start"/> |
|||
<field name="recurring_next_date"/> |
|||
</group> |
|||
<group attrs="{'invisible': [('is_contract', '=', False)]}"> |
|||
<field name="date_end"/> |
|||
</group> |
|||
</xpath> |
|||
<xpath expr="//field[@name='order_line']/tree//field[@name='price_total']" |
|||
position="after"> |
|||
<field name="date_start" |
|||
attrs="{'column_invisible': [('parent.is_contract', '=', False)]}"/> |
|||
<field name="date_end" |
|||
attrs="{'column_invisible': [('parent.is_contract', '=', False)]}"/> |
|||
<field name="recurring_next_date" |
|||
attrs="{'column_invisible': [('parent.is_contract', '=', False)]}"/> |
|||
</xpath> |
|||
<xpath expr="//field[@name='order_line']/tree" |
|||
position="attributes"> |
|||
<attribute name="editable"/> |
|||
</xpath> |
|||
</field> |
|||
</record> |
|||
|
|||
</odoo> |
Write
Preview
Loading…
Cancel
Save
Reference in new issue