Browse Source

[ADD] split module sale_exception into base_exception

pull/775/head
Mourad Elhadj Mimoune 8 years ago
parent
commit
d5f18357b2
  1. 14
      base_exception/__manifest__.py
  2. 39
      base_exception/data/sale_exception_data.xml
  3. 2
      base_exception/models/__init__.py
  4. 215
      base_exception/models/base_exception.py
  5. 201
      base_exception/models/sale.py
  6. 9
      base_exception/security/base_exception_security.xml
  7. 6
      base_exception/security/ir.model.access.csv
  8. 5
      base_exception/tests/__init__.py
  9. 62
      base_exception/tests/test_sale_exception.py
  10. 51
      base_exception/views/base_exception_view.xml
  11. 116
      base_exception/views/sale_view.xml
  12. 2
      base_exception/wizard/__init__.py
  13. 35
      base_exception/wizard/base_exception_confirm.py
  14. 20
      base_exception/wizard/base_exception_confirm_view.xml
  15. 35
      base_exception/wizard/sale_exception_confirm.py

14
base_exception/__manifest__.py

@ -2,20 +2,18 @@
# © 2011 Raphaël Valyi, Renato Lima, Guewen Baconnier, Sodexis # © 2011 Raphaël Valyi, Renato Lima, Guewen Baconnier, Sodexis
# 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': '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', 'category': 'Generic Modules/Sale',
'author': "Akretion, Sodexis, Odoo Community Association (OCA)", 'author': "Akretion, Sodexis, Odoo Community Association (OCA)",
'website': 'http://www.akretion.com', 'website': 'http://www.akretion.com',
'depends': ['sale'], 'depends': ['sale'],
'license': 'AGPL-3', 'license': 'AGPL-3',
'data': [ 'data': [
'security/base_exception_security.xml',
'security/ir.model.access.csv', '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,
} }

39
base_exception/data/sale_exception_data.xml

@ -1,39 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data noupdate="1">
<record forcecreate="True" id="ir_cron_test_orders" model="ir.cron">
<field name="name">Test Draft Orders</field>
<field eval="False" name="active"/>
<field name="user_id" ref="base.user_root"/>
<field name="interval_number">20</field>
<field name="interval_type">minutes</field>
<field name="numbercall">-1</field>
<field eval="False" name="doall"/>
<field eval="'sale.order'" name="model"/>
<field eval="'test_all_draft_orders'" name="function"/>
<field eval="'()'" name="args"/>
</record>
<record id ="excep_no_zip" model="sale.exception">
<field name="name">No ZIP code on destination</field>
<field name="description">No ZIP code on destination</field>
<field name="sequence">50</field>
<field name="model">sale.order</field>
<field name="code">if not order.partner_shipping_id.zip:
failed=True</field>
<field name="active" eval="False"/>
</record>
<record id ="excep_no_stock" model="sale.exception">
<field name="name">Not Enough Virtual Stock</field>
<field name="description">Not Enough Virtual Stock</field>
<field name="sequence">50</field>
<field name="model">sale.order.line</field>
<field name="code">if line.product_id and line.product_id.type == 'product' and line.product_id.virtual_available &lt; line.product_uom_qty:
failed=True</field>
<field name="active" eval="False"/>
</record>
</data>
</openerp>

2
base_exception/models/__init__.py

@ -2,4 +2,4 @@
# © 2011 Raphaël Valyi, Renato Lima, Guewen Baconnier, Sodexis # © 2011 Raphaël Valyi, Renato Lima, Guewen Baconnier, Sodexis
# 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 sale
from . import base_exception

215
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 []

201
base_exception/models/sale.py

@ -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

9
base_exception/security/base_exception_security.xml

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="group_exception_rule_manager" model="res.groups">
<field name="name">Exception manager</field>
<field name="implied_ids" eval="[(4, ref('base.group_user'))]"/>
</record>
</odoo>

6
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" "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

5
base_exception/tests/__init__.py

@ -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

62
base_exception/tests/test_sale_exception.py

@ -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

51
base_exception/views/base_exception_view.xml

@ -0,0 +1,51 @@
<?xml version="1.0" ?>
<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_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>
<menuitem action="action_exception_rule_tree" id="menu_action_exception" parent="base_setup.menu_config" />
</odoo>

116
base_exception/views/sale_view.xml

@ -1,116 +0,0 @@
<?xml version="1.0" ?>
<odoo>
<record id="view_sale_exception_tree" model="ir.ui.view">
<field name="name">sale.exception.tree</field>
<field name="model">sale.exception</field>
<field name="arch" type="xml">
<tree string="Sale Exception">
<field name="active"/>
<field name="name"/>
<field name="description"/>
<field name="model"/>
<field name="sequence"/>
</tree>
</field>
</record>
<record id="view_sale_exception_form" model="ir.ui.view">
<field name="name">sale.exception.form</field>
<field name="model">sale.exception</field>
<field name="arch" type="xml">
<form string="Sale Exception Setup" name="sale_exception">
<group colspan="4" col="2">
<field name="name"/>
<field name="description"/>
</group>
<group colspan="4" groups="base.group_sale_manager">
<field name="active"/>
<field name="sequence"/>
</group>
<group colspan="4" col="2" groups="base.group_system">
<field name="model"/>
<field name="code"/>
</group>
<group colspan="4" col="2">
<separator string="Affected Sales Orders"/>
<newline/>
<field name="sale_order_ids" nolabel="1" domain="[('state', '=', 'draft')]"/>
</group>
</form>
</field>
</record>
<record id="action_sale_test_tree" model="ir.actions.act_window">
<field name="name">Exception Rules</field>
<field name="res_model">sale.exception</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="view_id" ref="view_sale_exception_tree"/>
<field name="context">{'active_test': False}</field>
</record>
<menuitem action="action_sale_test_tree" id="menu_sale_test" parent="base.menu_sale_general_settings" />
<record id="view_order_form" model="ir.ui.view">
<field name="name">sale_exception.view_order_form</field>
<field name="model">sale.order</field>
<field name="inherit_id" ref="sale.view_order_form"/>
<field name="arch" type="xml">
<field name="name" position="after">
<group>
<field name="main_exception_id" options='{"no_open": True}'
class="oe_inline" string="Error:"
attrs="{'invisible':[('main_exception_id','=', False)]}"/>
</group>
</field>
<xpath expr="//field[@name='date_order']/.." position="inside">
<field name="ignore_exception" states="sale" />
</xpath>
<xpath expr="//group[@name='sales_person']/.."
position="inside">
<newline />
<group name="exception" colspan="2" col="2">
<separator string="Exception" colspan="2"/>
<field name="exception_ids" colspan="2" nolabel="1"/>
</group>
</xpath>
</field>
</record>
<record id="view_order_tree" model="ir.ui.view">
<field name="name">sale_exception.view_order_tree</field>
<field name="model">sale.order</field>
<field name="inherit_id" ref="sale.view_order_tree"/>
<field name="arch" type="xml">
<field name="state" position="after">
<field name="main_exception_id"/>
</field>
</field>
</record>
<record id="view_quotation_tree" model="ir.ui.view">
<field name="name">sale_exception.view_order_tree</field>
<field name="model">sale.order</field>
<field name="inherit_id" ref="sale.view_quotation_tree"/>
<field name="arch" type="xml">
<field name="state" position="after">
<field name="main_exception_id"/>
</field>
</field>
</record>
<record id="view_sales_order_filter" model="ir.ui.view">
<field name="name">sale_exception.view_sales_order_filter</field>
<field name="model">sale.order</field>
<field name="inherit_id" ref="sale.view_sales_order_filter" />
<field name="arch" type="xml">
<filter name="sales" position="after">
<separator orientation="vertical"/>
<filter icon="terp-emblem-important" name="tofix" string="Blocked in draft" domain="[('main_exception_id','!=',False)]"/>
</filter>
</field>
</record>
</odoo>

2
base_exception/wizard/__init__.py

@ -2,4 +2,4 @@
# © 2011 Raphaël Valyi, Renato Lima, Guewen Baconnier, Sodexis # © 2011 Raphaël Valyi, Renato Lima, Guewen Baconnier, Sodexis
# 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 sale_exception_confirm
from . import base_exception_confirm

35
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'}

20
base_exception/wizard/sale_exception_confirm_view.xml → base_exception/wizard/base_exception_confirm_view.xml

@ -1,21 +1,21 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<openerp>
<odoo>
<data> <data>
<record id="view_sale_exception_confirm" model="ir.ui.view">
<field name="name">Sale Exceptions</field>
<field name="model">sale.exception.confirm</field>
<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"> <field name="arch" type="xml">
<form string="Blocked in draft due to exceptions" version="7.0"> <form string="Blocked in draft due to exceptions" version="7.0">
<group> <group>
<field name="exception_ids" nolabel="1" colspan="4"> <field name="exception_ids" nolabel="1" colspan="4">
<tree string="Sale Exceptions">
<tree string="Exceptions Rules">
<field name="name"/> <field name="name"/>
<field name="description"/> <field name="description"/>
</tree> </tree>
</field> </field>
<newline/> <newline/>
<field name="ignore" groups='base.group_sale_manager'/>
<field name="ignore" groups='base_exception.group_exception_rule_manager'/>
</group> </group>
<footer> <footer>
<button name="action_confirm" string="_Close" <button name="action_confirm" string="_Close"
@ -25,15 +25,15 @@
</field> </field>
</record> </record>
<record id="action_sale_exception_confirm" model="ir.actions.act_window">
<record id="action_exception_rule_confirm" model="ir.actions.act_window">
<field name="name">Blocked in draft due to exceptions</field> <field name="name">Blocked in draft due to exceptions</field>
<field name="type">ir.actions.act_window</field> <field name="type">ir.actions.act_window</field>
<field name="res_model">sale.exception.confirm</field>
<field name="res_model">exception.rule.confirm</field>
<field name="view_type">form</field> <field name="view_type">form</field>
<field name="view_mode">form</field> <field name="view_mode">form</field>
<field name="view_id" ref="view_sale_exception_confirm"/>
<field name="view_id" ref="view_exception_rule_confirm"/>
<field name="target">new</field> <field name="target">new</field>
</record> </record>
</data> </data>
</openerp>
</odoo>

35
base_exception/wizard/sale_exception_confirm.py

@ -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'}
Loading…
Cancel
Save