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 -*- |
# -*- coding: utf-8 -*- |
||||
# Copyright 2017 LasLabs Inc. |
# Copyright 2017 LasLabs Inc. |
||||
|
# Copyright 2017 ACSONE SA/NV. |
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
# 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): |
class SaleOrderLine(models.Model): |
||||
_inherit = 'sale.order.line' |
_inherit = 'sale.order.line' |
||||
|
|
||||
|
is_contract = fields.Boolean( |
||||
|
string='Is a contract', related="product_id.is_contract" |
||||
|
) |
||||
contract_id = fields.Many2one( |
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 -*- |
# -*- coding: utf-8 -*- |
||||
# Copyright 2017 LasLabs Inc. |
# Copyright 2017 LasLabs Inc. |
||||
|
# Copyright 2018 ACSONE SA/NV. |
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
||||
|
|
||||
from . import test_product |
from . import test_product |
||||
from . import test_sale_order |
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