diff --git a/base_exception/__manifest__.py b/base_exception/__manifest__.py
index 2aa04f143..0ba5165b9 100644
--- a/base_exception/__manifest__.py
+++ b/base_exception/__manifest__.py
@@ -2,20 +2,18 @@
# © 2011 Raphaël Valyi, Renato Lima, Guewen Baconnier, Sodexis
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
-{'name': 'Sale Exception',
- 'summary': 'Custom exceptions on sale order',
- 'version': '9.0.1.0.0',
+{'name': 'Exception Rule',
+ 'version': '10.0.1.0.0',
'category': 'Generic Modules/Sale',
'author': "Akretion, Sodexis, Odoo Community Association (OCA)",
'website': 'http://www.akretion.com',
'depends': ['sale'],
'license': 'AGPL-3',
'data': [
+ 'security/base_exception_security.xml',
'security/ir.model.access.csv',
- 'wizard/sale_exception_confirm_view.xml',
- 'data/sale_exception_data.xml',
- 'views/sale_view.xml',
+ 'wizard/base_exception_confirm_view.xml',
+ 'views/base_exception_view.xml',
],
- 'images': [],
- 'installable': False,
+ 'installable': True,
}
diff --git a/base_exception/data/sale_exception_data.xml b/base_exception/data/sale_exception_data.xml
deleted file mode 100644
index 6db29dcf8..000000000
--- a/base_exception/data/sale_exception_data.xml
+++ /dev/null
@@ -1,39 +0,0 @@
-
-
-
-
-
- Test Draft Orders
-
-
- 20
- minutes
- -1
-
-
-
-
-
-
-
- No ZIP code on destination
- No ZIP code on destination
- 50
- sale.order
- if not order.partner_shipping_id.zip:
- failed=True
-
-
-
-
- Not Enough Virtual Stock
- Not Enough Virtual Stock
- 50
- sale.order.line
- if line.product_id and line.product_id.type == 'product' and line.product_id.virtual_available < line.product_uom_qty:
- failed=True
-
-
-
-
-
diff --git a/base_exception/models/__init__.py b/base_exception/models/__init__.py
index bc7f66f92..5f94bb885 100644
--- a/base_exception/models/__init__.py
+++ b/base_exception/models/__init__.py
@@ -2,4 +2,4 @@
# © 2011 Raphaël Valyi, Renato Lima, Guewen Baconnier, Sodexis
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
-from . import sale
+from . import base_exception
diff --git a/base_exception/models/base_exception.py b/base_exception/models/base_exception.py
new file mode 100644
index 000000000..1503e40d9
--- /dev/null
+++ b/base_exception/models/base_exception.py
@@ -0,0 +1,215 @@
+# -*- coding: utf-8 -*-
+# © 2011 Raphaël Valyi, Renato Lima, Guewen Baconnier, Sodexis
+# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
+
+import time
+from functools import wraps
+
+from odoo import api, models, fields, _
+from odoo.exceptions import UserError, ValidationError
+from odoo.tools.safe_eval import safe_eval
+
+
+def implemented_by_base_exception(func):
+ """Call a prefixed function based on 'namespace'."""
+ @wraps(func)
+ def wrapper(cls, *args, **kwargs):
+ fun_name = func.__name__
+ fun = '_%s%s' % (cls.rule_group, fun_name)
+ if not hasattr(cls, fun):
+ fun = '_default%s' % (fun_name)
+ return getattr(cls, fun)(*args, **kwargs)
+ return wrapper
+
+
+class ExceptionRule(models.Model):
+ _name = 'exception.rule'
+ _description = "Exception Rules"
+ _order = 'active desc, sequence asc'
+
+ name = fields.Char('Exception Name', required=True, translate=True)
+ description = fields.Text('Description', translate=True)
+ sequence = fields.Integer(
+ string='Sequence',
+ help="Gives the sequence order when applying the test")
+ rule_group = fields.Selection(
+ [],
+ help="Rule group is used the group the rules that must validated "
+ "at same time for a target object. Ex: "
+ "validate sale.order.line rules with sale order rules.",
+ required=True)
+ model = fields.Selection(
+ [],
+ string='Apply on', required=True)
+ active = fields.Boolean('Active')
+ code = fields.Text(
+ 'Python Code',
+ help="Python code executed to check if the exception apply or "
+ "not. The code must apply block = True to apply the "
+ "exception.",
+ default="""
+# Python code. Use failed = True to block the base.exception.
+# You can use the following variables :
+# - self: ORM model of the record which is checked
+# - "rule_group" or "rule_group_"line:
+# browse_record of the base.exception or
+# base.exception line (ex rule_group = sale for sale order)
+# - object: same as order or line, browse_record of the base.exception or
+# base.exception line
+# - pool: ORM model pool (i.e. self.pool)
+# - time: Python time module
+# - cr: database cursor
+# - uid: current user id
+# - context: current context
+""")
+
+
+class BaseException(models.AbstractModel):
+ _name = 'base.exception'
+
+ _order = 'main_exception_id asc'
+
+ main_exception_id = fields.Many2one(
+ 'exception.rule',
+ compute='_compute_main_error',
+ string='Main Exception',
+ store=True)
+ rule_group = fields.Selection(
+ [],
+ readonly=True,
+ )
+ exception_ids = fields.Many2many(
+ 'exception.rule',
+ string='Exceptions')
+ ignore_exception = fields.Boolean('Ignore Exceptions', copy=False)
+
+ @api.depends('exception_ids', 'ignore_exception')
+ def _compute_main_error(self):
+ for obj in self:
+ if not obj.ignore_exception and obj.exception_ids:
+ obj.main_exception_id = obj.exception_ids[0]
+ else:
+ obj.main_exception_id = False
+
+ @api.multi
+ def _popup_exceptions(self):
+ action = self._get_popup_action()
+ action = action.read()[0]
+ action.update({
+ 'context': {
+ 'active_id': self.ids[0],
+ 'active_ids': self.ids
+ }
+ })
+ return action
+
+ @api.model
+ def _get_popup_action(self):
+ action = self.env.ref('base_exception.action_exception_rule_confirm')
+ return action
+
+ @api.model
+ def _check_exception(self):
+ """
+ This method must be used in a constraint that must be created in the
+ object that inherits for base.exception.
+ for sale :
+ @api.constrains('ignore_exception',)
+ def sale_check_exception(self):
+ ...
+ ...
+ self._check_exception
+ """
+ exception_ids = self.detect_exceptions()
+ if exception_ids:
+ exceptions = self.env['exception.rule'].browse(exception_ids)
+ raise ValidationError('\n'.join(exceptions.mapped('name')))
+
+ @api.multi
+ def test_exceptions(self):
+ """
+ Condition method for the workflow from draft to confirm
+ """
+ if self.detect_exceptions():
+ return False
+ return True
+
+ @api.multi
+ def detect_exceptions(self):
+ """returns the list of exception_ids for all the considered base.exceptions
+ """
+ exception_obj = self.env['exception.rule']
+ model_exceptions = exception_obj.sudo().search(
+ [('model', '=', self._name)])
+ sub_exceptions = exception_obj.sudo().search(
+ [('rule_group', '=', self.rule_group),
+ ('id', 'not in', model_exceptions.ids),
+ ])
+
+ all_exception_ids = []
+ for obj in self:
+ if obj.ignore_exception:
+ continue
+ exception_ids = obj._detect_exceptions(
+ model_exceptions, sub_exceptions)
+ obj.exception_ids = [(6, 0, exception_ids)]
+ all_exception_ids += exception_ids
+ return all_exception_ids
+
+ @api.model
+ def _exception_rule_eval_context(self, obj_name, rec):
+ user = self.env['res.users'].browse(self._uid)
+ return {obj_name: rec,
+ 'self': self.pool.get(rec._name),
+ 'object': rec,
+ 'obj': rec,
+ 'pool': self.pool,
+ 'cr': self._cr,
+ 'uid': self._uid,
+ 'user': user,
+ 'time': time,
+ # copy context to prevent side-effects of eval
+ 'context': self._context.copy()}
+
+ @api.model
+ def _rule_eval(self, rule, obj_name, rec):
+ expr = rule.code
+ space = self._exception_rule_eval_context(obj_name, rec)
+ try:
+ safe_eval(expr,
+ space,
+ mode='exec',
+ nocopy=True) # nocopy allows to return 'result'
+ except Exception, e:
+ raise UserError(
+ _('Error when evaluating the exception.rule '
+ 'rule:\n %s \n(%s)') % (rule.name, e))
+ return space.get('failed', False)
+
+ @api.multi
+ def _detect_exceptions(self, model_exceptions,
+ sub_exceptions):
+ self.ensure_one()
+ exception_ids = []
+ for rule in model_exceptions:
+ if self._rule_eval(rule, self.rule_group, self):
+ exception_ids.append(rule.id)
+ if sub_exceptions:
+ for obj_line in self._get_lines():
+ for rule in sub_exceptions:
+ if rule.id in exception_ids:
+ # we do not matter if the exception as already been
+ # found for an line of this object
+ # (ex sale order line if obj is sale order)
+ continue
+ group_line = self.rule_group + '_line'
+ if self._rule_eval(rule, group_line, obj_line):
+ exception_ids.append(rule.id)
+ return exception_ids
+
+ @implemented_by_base_exception
+ def _get_lines(self):
+ pass
+
+ def _default_get_lines(self):
+ return []
diff --git a/base_exception/models/sale.py b/base_exception/models/sale.py
deleted file mode 100644
index 669b84c27..000000000
--- a/base_exception/models/sale.py
+++ /dev/null
@@ -1,201 +0,0 @@
-# -*- coding: utf-8 -*-
-# © 2011 Raphaël Valyi, Renato Lima, Guewen Baconnier, Sodexis
-# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
-
-import time
-
-from openerp import api, models, fields, _
-from openerp.exceptions import UserError, ValidationError
-from openerp.tools.safe_eval import safe_eval
-
-
-class SaleException(models.Model):
- _name = 'sale.exception'
- _description = "Sale Exceptions"
- _order = 'active desc, sequence asc'
-
- name = fields.Char('Exception Name', required=True, translate=True)
- description = fields.Text('Description', translate=True)
- sequence = fields.Integer(
- string='Sequence',
- help="Gives the sequence order when applying the test")
- model = fields.Selection(
- [('sale.order', 'Sale Order'),
- ('sale.order.line', 'Sale Order Line')],
- string='Apply on', required=True)
- active = fields.Boolean('Active')
- code = fields.Text(
- 'Python Code',
- help="Python code executed to check if the exception apply or "
- "not. The code must apply block = True to apply the "
- "exception.",
- default="""
-# Python code. Use failed = True to block the sale order.
-# You can use the following variables :
-# - self: ORM model of the record which is checked
-# - order or line: browse_record of the sale order or sale order line
-# - object: same as order or line, browse_record of the sale order or
-# sale order line
-# - pool: ORM model pool (i.e. self.pool)
-# - time: Python time module
-# - cr: database cursor
-# - uid: current user id
-# - context: current context
-""")
- sale_order_ids = fields.Many2many(
- 'sale.order',
- 'sale_order_exception_rel', 'exception_id', 'sale_order_id',
- string='Sale Orders',
- readonly=True)
-
-
-class SaleOrder(models.Model):
- _inherit = 'sale.order'
-
- _order = 'main_exception_id asc, date_order desc, name desc'
-
- main_exception_id = fields.Many2one(
- 'sale.exception',
- compute='_get_main_error',
- string='Main Exception',
- store=True)
- exception_ids = fields.Many2many(
- 'sale.exception',
- 'sale_order_exception_rel', 'sale_order_id', 'exception_id',
- string='Exceptions')
- ignore_exception = fields.Boolean('Ignore Exceptions', copy=False)
-
- @api.one
- @api.depends('exception_ids', 'ignore_exception')
- def _get_main_error(self):
- if not self.ignore_exception and self.exception_ids:
- self.main_exception_id = self.exception_ids[0]
- else:
- self.main_exception_id = False
-
- @api.model
- def test_all_draft_orders(self):
- order_set = self.search([('state', '=', 'draft')])
- order_set.test_exceptions()
- return True
-
- @api.multi
- def _popup_exceptions(self):
- action = self.env.ref('sale_exception.action_sale_exception_confirm')
- action = action.read()[0]
- action.update({
- 'context': {
- 'active_id': self.ids[0],
- 'active_ids': self.ids
- }
- })
- return action
-
- @api.one
- @api.constrains('ignore_exception', 'order_line', 'state')
- def check_sale_exception_constrains(self):
- if self.state == 'sale':
- exception_ids = self.detect_exceptions()
- if exception_ids:
- exceptions = self.env['sale.exception'].browse(exception_ids)
- raise ValidationError('\n'.join(exceptions.mapped('name')))
-
- @api.onchange('order_line')
- def onchange_ignore_exception(self):
- if self.state == 'sale':
- self.ignore_exception = False
-
- @api.multi
- def action_confirm(self):
- if self.detect_exceptions():
- return self._popup_exceptions()
- else:
- return super(SaleOrder, self).action_confirm()
-
- @api.multi
- def action_cancel(self):
- for order in self:
- if order.ignore_exception:
- order.ignore_exception = False
- return super(SaleOrder, self).action_cancel()
-
- @api.multi
- def test_exceptions(self):
- """
- Condition method for the workflow from draft to confirm
- """
- if self.detect_exceptions():
- return False
- return True
-
- @api.multi
- def detect_exceptions(self):
- """returns the list of exception_ids for all the considered sale orders
-
- as a side effect, the sale order's exception_ids column is updated with
- the list of exceptions related to the SO
- """
- exception_obj = self.env['sale.exception']
- order_exceptions = exception_obj.search(
- [('model', '=', 'sale.order')])
- line_exceptions = exception_obj.search(
- [('model', '=', 'sale.order.line')])
-
- all_exception_ids = []
- for order in self:
- if order.ignore_exception:
- continue
- exception_ids = order._detect_exceptions(order_exceptions,
- line_exceptions)
- order.exception_ids = [(6, 0, exception_ids)]
- all_exception_ids += exception_ids
- return all_exception_ids
-
- @api.model
- def _exception_rule_eval_context(self, obj_name, rec):
- user = self.env['res.users'].browse(self._uid)
- return {obj_name: rec,
- 'self': self.pool.get(rec._name),
- 'object': rec,
- 'obj': rec,
- 'pool': self.pool,
- 'cr': self._cr,
- 'uid': self._uid,
- 'user': user,
- 'time': time,
- # copy context to prevent side-effects of eval
- 'context': self._context.copy()}
-
- @api.model
- def _rule_eval(self, rule, obj_name, rec):
- expr = rule.code
- space = self._exception_rule_eval_context(obj_name, rec)
- try:
- safe_eval(expr,
- space,
- mode='exec',
- nocopy=True) # nocopy allows to return 'result'
- except Exception, e:
- raise UserError(
- _('Error when evaluating the sale exception '
- 'rule:\n %s \n(%s)') % (rule.name, e))
- return space.get('failed', False)
-
- @api.multi
- def _detect_exceptions(self, order_exceptions,
- line_exceptions):
- self.ensure_one()
- exception_ids = []
- for rule in order_exceptions:
- if self._rule_eval(rule, 'order', self):
- exception_ids.append(rule.id)
-
- for order_line in self.order_line:
- for rule in line_exceptions:
- if rule.id in exception_ids:
- # we do not matter if the exception as already been
- # found for an order line of this order
- continue
- if self._rule_eval(rule, 'line', order_line):
- exception_ids.append(rule.id)
- return exception_ids
diff --git a/base_exception/security/base_exception_security.xml b/base_exception/security/base_exception_security.xml
new file mode 100644
index 000000000..d69d3669b
--- /dev/null
+++ b/base_exception/security/base_exception_security.xml
@@ -0,0 +1,9 @@
+
+
+
+
+ Exception manager
+
+
+
+
diff --git a/base_exception/security/ir.model.access.csv b/base_exception/security/ir.model.access.csv
index 116e2c7b7..ee49a23e8 100644
--- a/base_exception/security/ir.model.access.csv
+++ b/base_exception/security/ir.model.access.csv
@@ -1,3 +1,5 @@
"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink"
-"access_sale_exception","sale.exception","model_sale_exception","base.group_user",1,0,0,0
-"access_sale_exception_manager","sale.exception","model_sale_exception","base.group_sale_manager",1,1,1,1
+"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
diff --git a/base_exception/tests/__init__.py b/base_exception/tests/__init__.py
deleted file mode 100644
index a343538ef..000000000
--- a/base_exception/tests/__init__.py
+++ /dev/null
@@ -1,5 +0,0 @@
-# -*- coding: utf-8 -*-
-# (c) 2015 Oihane Crucelaegui - AvanzOSC
-# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html
-
-from . import test_sale_exception
diff --git a/base_exception/tests/test_sale_exception.py b/base_exception/tests/test_sale_exception.py
deleted file mode 100644
index 5fbce18ce..000000000
--- a/base_exception/tests/test_sale_exception.py
+++ /dev/null
@@ -1,62 +0,0 @@
-from openerp.exceptions import ValidationError
-from openerp.addons.sale.tests.test_sale_order import TestSaleOrder
-
-
-class TestSaleException(TestSaleOrder):
-
- def test_sale_order_exception(self):
- exception = self.env.ref('sale_exception.excep_no_zip')
- exception.active = True
- partner = self.env.ref('base.res_partner_1')
- partner.zip = False
- p = self.env.ref('product.product_product_6')
- so = self.env['sale.order'].create({
- 'partner_id': partner.id,
- 'partner_invoice_id': partner.id,
- 'partner_shipping_id': partner.id,
- 'order_line': [(0, 0, {'name': p.name,
- 'product_id': p.id,
- 'product_uom_qty': 2,
- 'product_uom': p.uom_id.id,
- 'price_unit': p.list_price})],
- 'pricelist_id': self.env.ref('product.list0').id,
- })
-
- # confirm quotation
- so.action_confirm()
- self.assertTrue(so.state == 'draft')
-
- # Set ignore_exception flag (Done after ignore is selected at wizard)
- so.ignore_exception = True
- so.action_confirm()
- self.assertTrue(so.state == 'sale')
-
- # Add a order line to test after SO is confirmed
- p = self.env.ref('product.product_product_7')
-
- # set ignore_exception = False (Done by onchange of order_line)
- self.assertRaises(
- ValidationError,
- so.write,
- {
- 'ignore_exception': False,
- 'order_line': [(0, 0, {'name': p.name,
- 'product_id': p.id,
- 'product_uom_qty': 2,
- 'product_uom': p.uom_id.id,
- 'price_unit': p.list_price})]
- },
- )
-
- p = self.env.ref('product.product_product_7')
-
- # Set ignore exception True (Done manually by user)
- so.write({
- 'ignore_exception': True,
- 'order_line': [(0, 0, {'name': p.name,
- 'product_id': p.id,
- 'product_uom_qty': 2,
- 'product_uom': p.uom_id.id,
- 'price_unit': p.list_price})]
- })
- exception.active = False
diff --git a/base_exception/views/base_exception_view.xml b/base_exception/views/base_exception_view.xml
new file mode 100644
index 000000000..4f30a0f05
--- /dev/null
+++ b/base_exception/views/base_exception_view.xml
@@ -0,0 +1,51 @@
+
+
+
+
+ exception.rule.tree
+ exception.rule
+
+
+
+
+
+
+
+
+
+
+
+
+ exception.rule.form
+ exception.rule
+
+
+
+
+
+
+ Exception Rules
+ exception.rule
+ form
+ tree,form
+
+ {'active_test': False}
+
+
+
+
+
diff --git a/base_exception/views/sale_view.xml b/base_exception/views/sale_view.xml
deleted file mode 100644
index 59504d128..000000000
--- a/base_exception/views/sale_view.xml
+++ /dev/null
@@ -1,116 +0,0 @@
-
-
-
-
- sale.exception.tree
- sale.exception
-
-
-
-
-
-
-
-
-
-
-
-
- sale.exception.form
- sale.exception
-
-
-
-
-
-
- Exception Rules
- sale.exception
- form
- tree,form
-
- {'active_test': False}
-
-
-
-
-
-
- sale_exception.view_order_form
- sale.order
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- sale_exception.view_order_tree
- sale.order
-
-
-
-
-
-
-
-
-
- sale_exception.view_order_tree
- sale.order
-
-
-
-
-
-
-
-
-
- sale_exception.view_sales_order_filter
- sale.order
-
-
-
-
-
-
-
-
-
-
diff --git a/base_exception/wizard/__init__.py b/base_exception/wizard/__init__.py
index d2f4f0b07..613ae2e30 100644
--- a/base_exception/wizard/__init__.py
+++ b/base_exception/wizard/__init__.py
@@ -2,4 +2,4 @@
# © 2011 Raphaël Valyi, Renato Lima, Guewen Baconnier, Sodexis
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
-from . import sale_exception_confirm
+from . import base_exception_confirm
diff --git a/base_exception/wizard/base_exception_confirm.py b/base_exception/wizard/base_exception_confirm.py
new file mode 100644
index 000000000..d9a7b6844
--- /dev/null
+++ b/base_exception/wizard/base_exception_confirm.py
@@ -0,0 +1,35 @@
+# -*- coding: utf-8 -*-
+# © 2011 Raphaël Valyi, Renato Lima, Guewen Baconnier, Sodexis
+# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
+
+from odoo import api, fields, models
+
+
+class ExceptionRuleConfirm(models.AbstractModel):
+
+ _name = 'exception.rule.confirm'
+
+ related_model_id = fields.Many2one('base.exception',)
+ exception_ids = fields.Many2many('exception.rule',
+ string='Exceptions to resolve',
+ readonly=True)
+ ignore = fields.Boolean('Ignore Exceptions')
+
+ @api.model
+ def default_get(self, field_list):
+ res = super(ExceptionRuleConfirm, self).default_get(field_list)
+ current_model = self._context.get('active_model')
+ model_except_obj = self.env[current_model]
+ active_ids = self._context.get('active_ids')
+ assert len(active_ids) == 1, "Only 1 ID accepted, got %r" % active_ids
+ active_id = active_ids[0]
+ related_model_except = model_except_obj.browse(active_id)
+ exception_ids = [e.id for e in related_model_except.exception_ids]
+ res.update({'exception_ids': [(6, 0, exception_ids)]})
+ res.update({'related_model_id': active_id})
+ return res
+
+ @api.multi
+ def action_confirm(self):
+ self.ensure_one()
+ return {'type': 'ir.actions.act_window_close'}
diff --git a/base_exception/wizard/sale_exception_confirm_view.xml b/base_exception/wizard/base_exception_confirm_view.xml
similarity index 67%
rename from base_exception/wizard/sale_exception_confirm_view.xml
rename to base_exception/wizard/base_exception_confirm_view.xml
index b82bbbb2d..daffb29d5 100644
--- a/base_exception/wizard/sale_exception_confirm_view.xml
+++ b/base_exception/wizard/base_exception_confirm_view.xml
@@ -1,21 +1,21 @@
-
+
-
- Sale Exceptions
- sale.exception.confirm
+
+ Exceptions Rules
+ exception.rule.confirm
-
+
Blocked in draft due to exceptions
ir.actions.act_window
- sale.exception.confirm
+ exception.rule.confirm
form
form
-
+
new
-
+
diff --git a/base_exception/wizard/sale_exception_confirm.py b/base_exception/wizard/sale_exception_confirm.py
deleted file mode 100644
index facfdbd25..000000000
--- a/base_exception/wizard/sale_exception_confirm.py
+++ /dev/null
@@ -1,35 +0,0 @@
-# -*- coding: utf-8 -*-
-# © 2011 Raphaël Valyi, Renato Lima, Guewen Baconnier, Sodexis
-# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
-
-from openerp import models, fields, api
-
-
-class SaleExceptionConfirm(models.TransientModel):
-
- _name = 'sale.exception.confirm'
-
- sale_id = fields.Many2one('sale.order', 'Sale')
- exception_ids = fields.Many2many('sale.exception',
- string='Exceptions to resolve',
- readonly=True)
- ignore = fields.Boolean('Ignore Exceptions')
-
- @api.model
- def default_get(self, field_list):
- res = super(SaleExceptionConfirm, self).default_get(field_list)
- order_obj = self.env['sale.order']
- sale_id = self._context.get('active_ids')
- assert len(sale_id) == 1, "Only 1 ID accepted, got %r" % sale_id
- sale_id = sale_id[0]
- sale = order_obj.browse(sale_id)
- exception_ids = [e.id for e in sale.exception_ids]
- res.update({'exception_ids': [(6, 0, exception_ids)]})
- res.update({'sale_id': sale_id})
- return res
-
- @api.one
- def action_confirm(self):
- if self.ignore:
- self.sale_id.ignore_exception = True
- return {'type': 'ir.actions.act_window_close'}