-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[MIG] base_exception: Migration to 11.0
- Loading branch information
1 parent
dfc5652
commit 37472b9
Showing
11 changed files
with
303 additions
and
105 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,14 +12,10 @@ addons: | |
packages: | ||
- expect-dev # provides unbuffer utility | ||
- python-lxml # because pip installation is slow | ||
- unixodbc-dev | ||
- python-mysqldb | ||
|
||
env: | ||
global: | ||
- VERSION="11.0" TESTS="0" LINT_CHECK="0" TRANSIFEX="0" | ||
- TRANSIFEX_USER='[email protected]' | ||
- secure: Z06mZCN+Hm3myqHSOZpOOk1pd4oq1epAWZv6m9OX2bTNHbhyOVOGK6JWWsnDm/3DUCN1ZeLtSGOl9bvQfMa8ahQHA80MkLL16YlTvQV59Lh+L2gAYmxX+ogJCJgeQSVAXlGLscgkADCu/HzDlmatrDeROMtULn5i23j2qcyUNyM= | ||
|
||
matrix: | ||
- LINT_CHECK="1" | ||
|
@@ -30,7 +26,6 @@ env: | |
# - TESTS="1" ODOO_REPO="OCA/OCB" INCLUDE="database_cleanup" | ||
# - TESTS="1" ODOO_REPO="odoo/odoo" INCLUDE="database_cleanup" | ||
|
||
|
||
before_install: | ||
- "export PATH=$PWD/travis_phantomjs/phantomjs-2.1.1-linux-x86_64/bin:$PATH" | ||
- "if [ $(phantomjs --version) != '2.1.1' ]; then rm -rf $PWD/travis_phantomjs; mkdir -p $PWD/travis_phantomjs; fi" | ||
|
@@ -47,4 +42,4 @@ script: | |
- travis_run_tests | ||
|
||
after_success: | ||
- travis_after_tests_success | ||
- travis_after_tests_success |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,21 +1,26 @@ | ||
# -*- coding: utf-8 -*- | ||
# © 2011 Raphaël Valyi, Renato Lima, Guewen Baconnier, Sodexis | ||
# © 2017 Akretion (http://www.akretion.com) | ||
# Mourad EL HADJ MIMOUNE <[email protected]> | ||
# 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, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,7 @@ | ||
# -*- coding: utf-8 -*- | ||
# © 2011 Raphaël Valyi, Renato Lima, Guewen Baconnier, Sodexis | ||
# © 2017 Akretion (http://www.akretion.com) | ||
# Mourad EL HADJ MIMOUNE <[email protected]> | ||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). | ||
|
||
import time | ||
|
@@ -42,6 +44,12 @@ class ExceptionRule(models.Model): | |
selection=[], | ||
string='Apply on', required=True) | ||
active = fields.Boolean('Active') | ||
next_state = fields.Char( | ||
'Next state', | ||
help="If we detect exception we set de state of object (ex purchase) " | ||
"to the next_state (ex 'to approve'). If there are more than one " | ||
"exception detected and all have a value for next_state, we use" | ||
"the exception having the smallest sequence value") | ||
code = fields.Text( | ||
'Python Code', | ||
help="Python code executed to check if the exception apply or " | ||
|
@@ -63,6 +71,26 @@ class ExceptionRule(models.Model): | |
# - context: current context | ||
""") | ||
|
||
@api.constrains('next_state') | ||
def _check_next_state_value(self): | ||
""" Ensure that the next_state value is in the state values of | ||
destination model """ | ||
for rule in self: | ||
if rule.next_state: | ||
select_vals = self.env[ | ||
rule.model].fields_get()[ | ||
'state']['selection'] | ||
if rule.next_state\ | ||
not in [s[0] for s in select_vals]: | ||
raise ValidationError( | ||
_('The value "%s" you chose for the "next state" ' | ||
'field state of "%s" is wrong.' | ||
' Value must be in this list %s') | ||
% (rule.next_state, | ||
rule.model, | ||
select_vals) | ||
) | ||
|
||
|
||
class BaseException(models.AbstractModel): | ||
_name = 'base.exception' | ||
|
@@ -182,7 +210,7 @@ def _rule_eval(self, rule, obj_name, rec): | |
space, | ||
mode='exec', | ||
nocopy=True) # nocopy allows to return 'result' | ||
except Exception, e: | ||
except Exception as e: | ||
raise UserError( | ||
_('Error when evaluating the exception.rule ' | ||
'rule:\n %s \n(%s)') % (rule.name, e)) | ||
|
@@ -193,9 +221,16 @@ def _detect_exceptions(self, model_exceptions, | |
sub_exceptions): | ||
self.ensure_one() | ||
exception_ids = [] | ||
next_state_rule = False | ||
for rule in model_exceptions: | ||
if self._rule_eval(rule, self.rule_group, self): | ||
exception_ids.append(rule.id) | ||
if rule.next_state: | ||
if not next_state_rule: | ||
next_state_rule = rule | ||
elif next_state_rule and\ | ||
rule.sequence < next_state_rule.sequence: | ||
next_state_rule = rule | ||
if sub_exceptions: | ||
for obj_line in self._get_lines(): | ||
for rule in sub_exceptions: | ||
|
@@ -207,6 +242,9 @@ def _detect_exceptions(self, model_exceptions, | |
group_line = self.rule_group + '_line' | ||
if self._rule_eval(rule, group_line, obj_line): | ||
exception_ids.append(rule.id) | ||
# set object to next state | ||
if next_state_rule: | ||
self.state = next_state_rule.next_state | ||
return exception_ids | ||
|
||
@implemented_by_base_exception | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
# -*- coding: utf-8 -*- | ||
|
||
from . import test_tmp_model | ||
from . import test_base_exception |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
# -*- coding: utf-8 -*- | ||
# © 2017 Akretion (http://www.akretion.com) | ||
# Mourad EL HADJ MIMOUNE <[email protected]> | ||
|
||
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() |
Oops, something went wrong.