Mourad Elhadj Mimoune
7 years ago
committed by
Mourad
11 changed files with 303 additions and 105 deletions
-
7.travis.yml
-
1base_exception/__init__.py
-
39base_exception/__manifest__.py
-
40base_exception/models/base_exception.py
-
12base_exception/security/ir.model.access.csv
-
4base_exception/tests/__init__.py
-
84base_exception/tests/test_base_exception.py
-
72base_exception/tests/test_tmp_model.py
-
83base_exception/views/base_exception_view.xml
-
2base_exception/wizard/base_exception_confirm.py
-
64base_exception/wizard/base_exception_confirm_view.xml
@ -1,21 +1,26 @@ |
|||||
# -*- coding: utf-8 -*- |
# -*- coding: utf-8 -*- |
||||
# © 2011 Raphaël Valyi, Renato Lima, Guewen Baconnier, Sodexis |
# © 2011 Raphaël Valyi, Renato Lima, Guewen Baconnier, Sodexis |
||||
|
# © 2017 Akretion (http://www.akretion.com) |
||||
|
# Mourad EL HADJ MIMOUNE <mourad.elhadj.mimoune@akretion.com> |
||||
# 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). |
||||
|
|
||||
{'name': 'Exception Rule', |
|
||||
'version': '10.0.1.0.0', |
|
||||
'category': 'Generic Modules', |
|
||||
'summary': """This module provide an abstract model to manage customizable |
|
||||
exceptions to be applied on different models (sale order, invoice, ...)""", |
|
||||
'author': "Akretion, Sodexis, Camptocamp, Odoo Community Association (OCA)", |
|
||||
'website': 'http://www.akretion.com', |
|
||||
'depends': ['base_setup'], |
|
||||
'license': 'AGPL-3', |
|
||||
'data': [ |
|
||||
'security/base_exception_security.xml', |
|
||||
'security/ir.model.access.csv', |
|
||||
'wizard/base_exception_confirm_view.xml', |
|
||||
'views/base_exception_view.xml', |
|
||||
], |
|
||||
'installable': True, |
|
||||
} |
|
||||
|
{ |
||||
|
'name': 'Exception Rule', |
||||
|
'version': '11.0.1.0.0', |
||||
|
'category': 'Generic Modules', |
||||
|
'summary': """ |
||||
|
This module provide an abstract model to manage customizable |
||||
|
exceptions to be applied on different models (sale order, invoice, ...)""", |
||||
|
'author': |
||||
|
"Akretion, Sodexis, Camptocamp, Odoo Community Association (OCA)", |
||||
|
'website': 'http://www.akretion.com', |
||||
|
'depends': ['base_setup'], |
||||
|
'license': 'AGPL-3', |
||||
|
'data': [ |
||||
|
'security/base_exception_security.xml', |
||||
|
'security/ir.model.access.csv', |
||||
|
'wizard/base_exception_confirm_view.xml', |
||||
|
'views/base_exception_view.xml', |
||||
|
], |
||||
|
'installable': True, |
||||
|
} |
@ -1,5 +1,7 @@ |
|||||
"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink" |
|
||||
"access_exception_rule","base.exception","model_exception_rule","base.group_user",1,0,0,0 |
|
||||
"access_exception_rule_manager","base.exception","model_exception_rule","base_exception.group_exception_rule_manager",1,1,1,1 |
|
||||
"access_base_exception","base.exception","model_base_exception","base.group_user",1,0,0,0 |
|
||||
"access_base_exception_manager","base.exception","model_base_exception","base_exception.group_exception_rule_manager",1,1,1,1 |
|
||||
|
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink |
||||
|
access_exception_rule,base.exception,model_exception_rule,base.group_user,1,0,0,0 |
||||
|
access_exception_rule_manager,base.exception,model_exception_rule,base_exception.group_exception_rule_manager,1,1,1,1 |
||||
|
access_base_exception,base.exception,model_base_exception,base.group_user,1,0,0,0 |
||||
|
access_base_exception_manager,base.exception,model_base_exception,base_exception.group_exception_rule_manager,1,1,1,1 |
||||
|
access_base_exception_test_purchase,access_base_exception_test_purchase,model_base_exception_test_purchase,base.group_system,1,1,1,1 |
||||
|
access_base_exception_test_model_line,access_base_exception_test_model_line,model_base_exception_test_model_line,base.group_system,1,1,1,1 |
@ -0,0 +1,4 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
|
||||
|
from . import test_tmp_model |
||||
|
from . import test_base_exception |
@ -0,0 +1,84 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# © 2016 Akretion Mourad EL HADJ MIMOUNE |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
||||
|
|
||||
|
from odoo.tests import common |
||||
|
|
||||
|
import logging |
||||
|
|
||||
|
_logger = logging.getLogger(__name__) |
||||
|
|
||||
|
|
||||
|
# @common.at_install(False) |
||||
|
# @common.post_install(True) |
||||
|
class TestBaseException(common.TransactionCase): |
||||
|
|
||||
|
def setUp(self): |
||||
|
super(TestBaseException, self).setUp() |
||||
|
|
||||
|
self.base_exception = self.env['base.exception'] |
||||
|
self.exception_rule = self.env['exception.rule'] |
||||
|
self.exception_confirm = self.env['exception.rule.confirm'] |
||||
|
|
||||
|
self.exception_rule._fields['rule_group'].selection.append( |
||||
|
('test_base', 'test base exception') |
||||
|
) |
||||
|
self.exception_rule._fields['model'].selection.append( |
||||
|
('base.exception.test.purchase', |
||||
|
'base.exception.test.purchase') |
||||
|
) |
||||
|
self.exception_rule._fields['model'].selection.append( |
||||
|
('base.exception.test.purchase.line', |
||||
|
'base.exception.test.purchase.line') |
||||
|
) |
||||
|
self.exceptionnozip = self.env['exception.rule'].create({ |
||||
|
'name': "No ZIP code on destination", |
||||
|
'sequence': 10, |
||||
|
'rule_group': "test_base", |
||||
|
'model': "base.exception.test.purchase", |
||||
|
'code': """if not test_base.partner_id.zip: |
||||
|
failed=True""", |
||||
|
}) |
||||
|
self.exceptionno_minorder = self.env['exception.rule'].create({ |
||||
|
'name': "Min order except", |
||||
|
'sequence': 10, |
||||
|
'rule_group': "test_base", |
||||
|
'model': "base.exception.test.purchase", |
||||
|
'code': """if test_base.amount_total <= 200.0: |
||||
|
failed=True""", |
||||
|
}) |
||||
|
|
||||
|
self.exceptionno_lineqty = self.env['exception.rule'].create({ |
||||
|
'name': "Qty > 0", |
||||
|
'sequence': 10, |
||||
|
'rule_group': "test_base", |
||||
|
'model': "base.exception.test.purchase.line", |
||||
|
'code': """if test_base_line.qty <= 0: |
||||
|
failed=True"""}) |
||||
|
|
||||
|
def test_sale_order_exception(self): |
||||
|
partner = self.env.ref('base.res_partner_1') |
||||
|
partner.zip = False |
||||
|
potest1 = self.env['base.exception.test.purchase'].create({ |
||||
|
'name': 'Test base exception to basic purchase', |
||||
|
'partner_id': partner.id, |
||||
|
'line_ids': [(0, 0, {'name': "line test", |
||||
|
'amount': 120.0, |
||||
|
'qty': 1.5})], |
||||
|
}) |
||||
|
|
||||
|
potest1.button_confirm() |
||||
|
# Set ignore_exception flag (Done after ignore is selected at wizard) |
||||
|
potest1.ignore_exception = True |
||||
|
potest1.button_confirm() |
||||
|
self.assertTrue(potest1.state == 'purchase') |
||||
|
# Simulation the opening of the wizard exception_confirm and |
||||
|
# set ignore_exception to True |
||||
|
except_confirm = self.exception_confirm.with_context( |
||||
|
{ |
||||
|
'active_id': potest1.id, |
||||
|
'active_ids': [potest1.id], |
||||
|
'active_model': potest1._name |
||||
|
}).new({'ignore': True}) |
||||
|
except_confirm.action_confirm() |
||||
|
self.assertTrue(potest1.ignore_exception) |
@ -0,0 +1,72 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# © 2017 Akretion (http://www.akretion.com) |
||||
|
# Mourad EL HADJ MIMOUNE <mourad.elhadj.mimoune@akretion.com> |
||||
|
|
||||
|
from odoo import fields, models, api |
||||
|
|
||||
|
|
||||
|
class PurchaseTest(models.Model): |
||||
|
_inherit = 'base.exception' |
||||
|
_name = "base.exception.test.purchase" |
||||
|
_description = "Base Ecxeption Test Model" |
||||
|
|
||||
|
rule_group = fields.Selection( |
||||
|
selection_add=[('test_base', 'test')], |
||||
|
default='test_base', |
||||
|
) |
||||
|
name = fields.Char(required=True) |
||||
|
user_id = fields.Many2one('res.users', string='Responsible') |
||||
|
state = fields.Selection( |
||||
|
[('draft', 'New'), ('cancel', 'Cancelled'), |
||||
|
('purchase', 'Purchase'), |
||||
|
('to approve', 'To approve'), ('done', 'Done')], |
||||
|
string="Status", readonly=True, default='draft') |
||||
|
active = fields.Boolean(default=True) |
||||
|
partner_id = fields.Many2one('res.partner', string='Partner') |
||||
|
line_ids = fields.One2many('base.exception.test.model.line', 'lead_id') |
||||
|
amount_total = fields.Float(compute='_compute_amount_total', store=True) |
||||
|
|
||||
|
@api.depends('line_ids') |
||||
|
def _compute_amount_total(self): |
||||
|
for record in self: |
||||
|
for line in record.line_ids: |
||||
|
record.amount_total += line.amount * line.qty |
||||
|
|
||||
|
@api.constrains('ignore_exception', 'line_ids', 'state') |
||||
|
def test_purchase_check_exception(self): |
||||
|
orders = self.filtered(lambda s: s.state == 'purchase') |
||||
|
if orders: |
||||
|
orders._check_exception() |
||||
|
|
||||
|
@api.multi |
||||
|
def button_approve(self, force=False): |
||||
|
self.write({'state': 'to approve'}) |
||||
|
return {} |
||||
|
|
||||
|
@api.multi |
||||
|
def button_draft(self): |
||||
|
self.write({'state': 'draft'}) |
||||
|
return {} |
||||
|
|
||||
|
@api.multi |
||||
|
def button_confirm(self): |
||||
|
self.write({'state': 'purchase'}) |
||||
|
return True |
||||
|
|
||||
|
@api.multi |
||||
|
def button_cancel(self): |
||||
|
self.write({'state': 'cancel'}) |
||||
|
|
||||
|
def test_base_get_lines(self): |
||||
|
self.ensure_one() |
||||
|
return self.line_ids |
||||
|
|
||||
|
|
||||
|
class LineTest(models.Model): |
||||
|
_name = "base.exception.test.model.line" |
||||
|
_description = "Base Ecxeption Test Model Line" |
||||
|
|
||||
|
name = fields.Char() |
||||
|
lead_id = fields.Many2one('base.exception.test.model', ondelete='cascade') |
||||
|
qty = fields.Float() |
||||
|
amount = fields.Float() |
@ -1,51 +1,50 @@ |
|||||
<?xml version="1.0" ?> |
<?xml version="1.0" ?> |
||||
<odoo> |
<odoo> |
||||
|
<record id="view_exception_rule_tree" model="ir.ui.view"> |
||||
|
<field name="name">exception.rule.tree</field> |
||||
|
<field name="model">exception.rule</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<tree string="Exception Rule"> |
||||
|
<field name="active"/> |
||||
|
<field name="name"/> |
||||
|
<field name="description"/> |
||||
|
<field name="model"/> |
||||
|
<field name="sequence"/> |
||||
|
</tree> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
<record id="view_exception_rule_tree" model="ir.ui.view"> |
|
||||
<field name="name">exception.rule.tree</field> |
|
||||
<field name="model">exception.rule</field> |
|
||||
<field name="arch" type="xml"> |
|
||||
<tree string="Exception Rule"> |
|
||||
<field name="active"/> |
|
||||
|
<record id="view_exception_rule_form" model="ir.ui.view"> |
||||
|
<field name="name">exception.rule.form</field> |
||||
|
<field name="model">exception.rule</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<form string="Exception Rule Setup" name="exception_rule"> |
||||
|
<group colspan="4" col="2"> |
||||
<field name="name"/> |
<field name="name"/> |
||||
<field name="description"/> |
<field name="description"/> |
||||
<field name="model"/> |
|
||||
|
</group> |
||||
|
<group colspan="4" groups="base_exception.group_exception_rule_manager"> |
||||
|
<field name="active"/> |
||||
<field name="sequence"/> |
<field name="sequence"/> |
||||
</tree> |
|
||||
</field> |
|
||||
</record> |
|
||||
|
|
||||
<record id="view_exception_rule_form" model="ir.ui.view"> |
|
||||
<field name="name">exception.rule.form</field> |
|
||||
<field name="model">exception.rule</field> |
|
||||
<field name="arch" type="xml"> |
|
||||
<form string="Exception Rule Setup" name="exception_rule"> |
|
||||
<group colspan="4" col="2"> |
|
||||
<field name="name"/> |
|
||||
<field name="description"/> |
|
||||
</group> |
|
||||
<group colspan="4" groups="base_exception.group_exception_rule_manager"> |
|
||||
<field name="active"/> |
|
||||
<field name="sequence"/> |
|
||||
</group> |
|
||||
<group colspan="4" col="2" groups="base.group_system"> |
|
||||
<field name="rule_group"/> |
|
||||
<field name="model"/> |
|
||||
<field name="code"/> |
|
||||
</group> |
|
||||
</form> |
|
||||
</field> |
|
||||
</record> |
|
||||
|
|
||||
<record id="action_exception_rule_tree" model="ir.actions.act_window"> |
|
||||
<field name="name">Exception Rules</field> |
|
||||
<field name="res_model">exception.rule</field> |
|
||||
<field name="view_type">form</field> |
|
||||
<field name="view_mode">tree,form</field> |
|
||||
<field name="view_id" ref="view_exception_rule_tree"/> |
|
||||
<field name="context">{'active_test': False}</field> |
|
||||
</record> |
|
||||
|
</group> |
||||
|
<group colspan="4" col="2" groups="base.group_system"> |
||||
|
<field name="rule_group"/> |
||||
|
<field name="model"/> |
||||
|
<field name="next_state"/> |
||||
|
<field name="code"/> |
||||
|
</group> |
||||
|
</form> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
<menuitem action="action_exception_rule_tree" id="menu_action_exception" parent="base.menu_custom" sequence="90" /> |
|
||||
|
<record id="action_exception_rule_tree" model="ir.actions.act_window"> |
||||
|
<field name="name">Exception Rules</field> |
||||
|
<field name="res_model">exception.rule</field> |
||||
|
<field name="view_type">form</field> |
||||
|
<field name="view_mode">tree,form</field> |
||||
|
<field name="view_id" ref="view_exception_rule_tree"/> |
||||
|
<field name="context">{'active_test': False}</field> |
||||
|
</record> |
||||
|
|
||||
|
<menuitem action="action_exception_rule_tree" id="menu_action_exception" parent="base.menu_custom" sequence="90" /> |
||||
</odoo> |
</odoo> |
@ -1,39 +1,35 @@ |
|||||
<?xml version="1.0" encoding="utf-8"?> |
<?xml version="1.0" encoding="utf-8"?> |
||||
<odoo> |
<odoo> |
||||
<data> |
|
||||
|
<record id="view_exception_rule_confirm" model="ir.ui.view"> |
||||
|
<field name="name">Exceptions Rules</field> |
||||
|
<field name="model">exception.rule.confirm</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<form string="Blocked in draft due to exceptions" version="7.0"> |
||||
|
<group> |
||||
|
<field name="exception_ids" nolabel="1" colspan="4"> |
||||
|
<tree string="Exceptions Rules"> |
||||
|
<field name="name"/> |
||||
|
<field name="description"/> |
||||
|
</tree> |
||||
|
</field> |
||||
|
<newline/> |
||||
|
<field name="ignore" groups='base_exception.group_exception_rule_manager'/> |
||||
|
</group> |
||||
|
<footer> |
||||
|
<button name="action_confirm" string="_Close" |
||||
|
colspan="1" type="object" icon="gtk-ok" /> |
||||
|
</footer> |
||||
|
</form> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
<record id="view_exception_rule_confirm" model="ir.ui.view"> |
|
||||
<field name="name">Exceptions Rules</field> |
|
||||
<field name="model">exception.rule.confirm</field> |
|
||||
<field name="arch" type="xml"> |
|
||||
<form string="Blocked in draft due to exceptions" version="7.0"> |
|
||||
<group> |
|
||||
<field name="exception_ids" nolabel="1" colspan="4"> |
|
||||
<tree string="Exceptions Rules"> |
|
||||
<field name="name"/> |
|
||||
<field name="description"/> |
|
||||
</tree> |
|
||||
</field> |
|
||||
<newline/> |
|
||||
<field name="ignore" groups='base_exception.group_exception_rule_manager'/> |
|
||||
</group> |
|
||||
<footer> |
|
||||
<button name="action_confirm" string="_Close" |
|
||||
colspan="1" type="object" icon="gtk-ok" /> |
|
||||
</footer> |
|
||||
</form> |
|
||||
</field> |
|
||||
|
<record id="action_exception_rule_confirm" model="ir.actions.act_window"> |
||||
|
<field name="name">Blocked in draft due to exceptions</field> |
||||
|
<field name="type">ir.actions.act_window</field> |
||||
|
<field name="res_model">exception.rule.confirm</field> |
||||
|
<field name="view_type">form</field> |
||||
|
<field name="view_mode">form</field> |
||||
|
<field name="view_id" ref="view_exception_rule_confirm"/> |
||||
|
<field name="target">new</field> |
||||
</record> |
</record> |
||||
|
|
||||
<record id="action_exception_rule_confirm" model="ir.actions.act_window"> |
|
||||
<field name="name">Blocked in draft due to exceptions</field> |
|
||||
<field name="type">ir.actions.act_window</field> |
|
||||
<field name="res_model">exception.rule.confirm</field> |
|
||||
<field name="view_type">form</field> |
|
||||
<field name="view_mode">form</field> |
|
||||
<field name="view_id" ref="view_exception_rule_confirm"/> |
|
||||
<field name="target">new</field> |
|
||||
</record> |
|
||||
|
|
||||
</data> |
|
||||
</odoo> |
</odoo> |
Write
Preview
Loading…
Cancel
Save
Reference in new issue