[REM] base: remove model ir.values

This commit is contained in:
Raphael Collet
2017-08-28 09:53:23 +02:00
parent 55549f1e61
commit 10cb1beead
13 changed files with 0 additions and 744 deletions
-22
View File
@@ -1,22 +0,0 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import api, models, tools
from odoo.addons.calendar.models.calendar import calendar_id2real_id
class IrValues(models.Model):
_inherit = 'ir.values'
@api.model
@api.returns('self', lambda value: value.id)
def set_action(self, name, action_slot, model, action, res_id=False):
if res_id:
res_id = calendar_id2real_id(res_id)
return super(IrValues, self).set_action(name, action_slot, model, action, res_id=res_id)
@api.model
@tools.ormcache_context('self._uid', 'action_slot', 'model', 'res_id', keys=('lang',))
def get_actions(self, action_slot, model, res_id=False):
if res_id:
res_id = calendar_id2real_id(res_id)
return super(IrValues, self).get_actions(action_slot, model, res_id=res_id)
-4
View File
@@ -299,10 +299,6 @@ def set_cookie_and_redirect(redirect_url):
redirect.autocorrect_location_header = False
return redirect
def load_actions_from_ir_values(action_slot, model, res_id):
actions = request.env['ir.values'].get_actions(action_slot, model, res_id)
return [(id, name, clean_action(action)) for id, name, action in actions]
def clean_action(action):
action.setdefault('flags', {})
action_type = action.setdefault('type', 'ir.actions.act_window_close')
-1
View File
@@ -32,7 +32,6 @@ The kernel of Odoo, needed for all installation.
'ir/ir_translation_view.xml',
'ir/ir_ui_menu_view.xml',
'ir/ir_ui_view_view.xml',
'ir/ir_values_view.xml',
'ir/ir_default_view.xml',
'ir/ir_autovacuum.xml',
'ir/ir_model_report.xml',
-1
View File
@@ -10,7 +10,6 @@ from . import ir_actions_report
from . import ir_attachment
from . import ir_cron
from . import ir_filters
from . import ir_values
from . import ir_default
from . import ir_translation
from . import ir_exports
-6
View File
@@ -46,8 +46,6 @@ class IrActions(models.Model):
res = super(IrActions, self).create(vals)
# self.get_bindings() depends on action records
self.clear_caches()
# ir_values.get_actions() depends on action records
self.env['ir.values'].clear_caches()
return res
@api.multi
@@ -55,8 +53,6 @@ class IrActions(models.Model):
res = super(IrActions, self).write(vals)
# self.get_bindings() depends on action records
self.clear_caches()
# ir_values.get_actions() depends on action records
self.env['ir.values'].clear_caches()
return res
@api.multi
@@ -68,8 +64,6 @@ class IrActions(models.Model):
res = super(IrActions, self).unlink()
# self.get_bindings() depends on action records
self.clear_caches()
# ir_values.get_actions() depends on action records
self.env['ir.values'].clear_caches()
return res
@api.model
-431
View File
@@ -1,431 +0,0 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from ast import literal_eval
from odoo import api, fields, models, tools, _
from odoo.exceptions import AccessError, MissingError, ValidationError
from odoo.tools import pickle, pycompat
import logging
_logger = logging.getLogger(__name__)
#: Possible slots to bind an action to with :meth:`~.set_action`
ACTION_SLOTS = [
"client_action_multi", # sidebar wizard action
"client_print_multi", # sidebar report printing button
"client_action_relate", # sidebar related link
"tree_but_open", # double-click on item in tree view
"tree_but_action", # deprecated: same as tree_but_open
]
class IrValues(models.Model):
"""Holds internal model-specific action bindings and user-defined default
field values. definitions. This is a legacy internal model, mixing
two different concepts, and will likely be updated or replaced in a
future version by cleaner, separate models. You should not depend
explicitly on it.
The purpose of each ``ir.values`` entry depends on its type, defined
by the ``key`` column:
* 'default': user-defined default values, used when creating new
records of this model:
* 'action': binding of an action to a particular *action slot* of
this model, making the action easily available in the user
interface for this model.
The ``key2`` column acts as a qualifier, further refining the type
of the entry. The possible values are:
* for 'default' entries: an optional condition restricting the
cases where this particular default value will be applicable,
or ``False`` for no condition
* for 'action' entries: the ``key2`` qualifier is one of the available
action slots, defining how this action can be invoked:
* ``'client_print_multi'`` for report printing actions that will
be available on views displaying items from this model
* ``'client_action_multi'`` for assistants (wizards) actions
that will be available in views displaying objects of this model
* ``'client_action_relate'`` for links towards related documents
that should be available in views displaying objects of this model
* ``'tree_but_open'`` for actions that will be triggered when
double-clicking an item from this model in a hierarchical tree view
Each entry is specific to a model (``model`` column), and for ``'actions'``
type, may even be made specific to a given record of that model when the
``res_id`` column contains a record ID (``False`` means it's global for
all records).
The content of the entry is defined by the ``value`` column, which may either
contain an arbitrary value, or a reference string defining the action that
should be executed.
.. rubric:: Usage: default values
The ``'default'`` entries are usually defined manually by the
users, and set by their UI clients calling :meth:`~.set_default`.
These default values are then automatically used by the
ORM every time a new record is about to be created, i.e. when
:meth:`~odoo.models.Model.default_get`
or :meth:`~odoo.models.Model.create` are called.
.. rubric:: Usage: action bindings
Business applications will usually bind their actions during
installation, and Odoo UI clients will apply them as defined,
based on the list of actions included in the result of
:meth:`~odoo.models.Model.fields_view_get`,
or directly returned by explicit calls to :meth:`~.get_actions`.
"""
_name = 'ir.values'
name = fields.Char(required=True)
model = fields.Char(string='Model Name', index=True, required=True,
help="Model to which this entry applies")
# TODO: model_id and action_id should be read-write function fields
model_id = fields.Many2one('ir.model', string='Model (change only)',
help="Model to which this entry applies - "
"helper field for setting a model, will "
"automatically set the correct model name")
action_id = fields.Many2one('ir.actions.actions', string='Action (change only)',
help="Action bound to this entry - "
"helper field for binding an action, will "
"automatically set the correct reference")
value = fields.Binary(help="Default value (pickled) or reference to an action")
value_unpickle = fields.Binary(string='Default value or action reference',
compute='_value_unpickle', inverse='_value_pickle')
key = fields.Selection([('action', 'Action'), ('default', 'Default')],
string='Type', index=True, required=True, default='action',
help="- Action: an action attached to one slot of the given model\n"
"- Default: a default value for a model field")
key2 = fields.Char(string='Qualifier', index=True, default='tree_but_open',
help="For actions, one of the possible action slots: \n"
" - client_action_multi\n"
" - client_print_multi\n"
" - client_action_relate\n"
" - tree_but_open\n"
"For defaults, an optional condition")
res_id = fields.Integer(string='Record ID', index=True,
help="Database identifier of the record to which this applies. "
"0 = for all records")
user_id = fields.Many2one('res.users', string='User', ondelete='cascade', index=True,
help="If set, action binding only applies for this user.")
company_id = fields.Many2one('res.company', string='Company', ondelete='cascade', index=True,
help="If set, action binding only applies for this company")
@api.depends('key', 'value')
def _value_unpickle(self):
for record in self:
value = record.value
if record.key == 'default' and value:
# default values are pickled on the fly
with tools.ignore(Exception):
value = str(pickle.loads(value))
record.value_unpickle = value
def _value_pickle(self):
context = dict(self._context)
context.pop(self.CONCURRENCY_CHECK_FIELD, None)
for record in self.with_context(context):
value = record.value_unpickle
# Only char-like fields should be written directly. Other types should be converted to
# their appropriate type first.
if record.model in self.env and record.name in self.env[record.model]._fields:
field = self.env[record.model]._fields[record.name]
if field.type not in ['char', 'text', 'html', 'selection']:
value = literal_eval(value)
if record.key == 'default':
value = pickle.dumps(value)
record.value = value
@api.onchange('model_id')
def onchange_object_id(self):
if self.model_id:
self.model = self.model_id.model
@api.onchange('action_id')
def onchange_action_id(self):
if self.action_id:
self.value_unpickle = self.action_id
@api.model_cr_context
def _auto_init(self):
res = super(IrValues, self)._auto_init()
tools.create_index(self._cr, 'ir_values_key_model_key2_res_id_user_id_idx',
self._table, ['key', 'model', 'key2', 'res_id', 'user_id'])
return res
@api.model
def create(self, vals):
self.clear_caches()
return super(IrValues, self).create(vals)
@api.multi
def write(self, vals):
self.clear_caches()
return super(IrValues, self).write(vals)
@api.multi
def unlink(self):
self.clear_caches()
return super(IrValues, self).unlink()
@api.model
@api.returns('self', lambda value: value.id)
def set_default(self, model, field_name, value, for_all_users=True, company_id=False, condition=False):
"""Defines a default value for the given model and field_name. Any previous
default for the same scope (model, field_name, value, for_all_users, company_id, condition)
will be replaced and lost in the process.
Defaults can be later retrieved via :meth:`~.get_defaults`, which will return
the highest priority default for any given field. Defaults that are more specific
have a higher priority, in the following order (highest to lowest):
* specific to user and company
* specific to user only
* specific to company only
* global to everyone
:param string model: model name
:param string field_name: field name to which the default applies
:param value: the default field value to set
:type value: any serializable Python value
:param bool for_all_users: whether the default should apply to everybody or only
the user calling the method
:param int company_id: optional ID of the company to which the default should
apply. If omitted, the default will be global. If True
is passed, the current user's company will be used.
:param string condition: optional condition specification that can be used to
restrict the applicability of the default values
(e.g. based on another field's value). This is an
opaque string as far as the API is concerned, but client
stacks typically use single-field conditions in the
form ``'key=stringified_value'``.
(Currently, the condition is trimmed to 200 characters,
so values that share the same first 200 characters always
match)
:return: the newly created ir.values entry
"""
if isinstance(value, pycompat.string_types):
value = pycompat.to_native(value)
if company_id is True:
# should be company-specific, need to get company id
company_id = self.env.user.company_id.id
# check consistency of model, field_name and value
try:
field = self.env[model]._fields[field_name]
field.convert_to_cache(value, self.browse())
except KeyError:
_logger.warning("Invalid field %s.%s", model, field_name)
except Exception:
raise ValidationError(_("Invalid value for %s.%s: %s") % (model, field_name, value))
# remove existing defaults for the same scope
search_criteria = [
('key', '=', 'default'),
('key2', '=', condition and condition[:200]),
('model', '=', model),
('name', '=', field_name),
('user_id', '=', False if for_all_users else self._uid),
('company_id', '=', company_id)
]
self.search(search_criteria).unlink()
return self.create({
'name': field_name,
'value': pickle.dumps(value),
'model': model,
'key': 'default',
'key2': condition and condition[:200],
'user_id': False if for_all_users else self._uid,
'company_id': company_id,
})
@api.model
def get_default(self, model, field_name, for_all_users=True, company_id=False, condition=False):
""" Return the default value defined for model, field_name, users, company and condition.
Return ``None`` if no such default exists.
"""
search_criteria = [
('key', '=', 'default'),
('key2', '=', condition and condition[:200]),
('model', '=', model),
('name', '=', field_name),
('user_id', '=', False if for_all_users else self._uid),
('company_id', '=', company_id)
]
defaults = self.search(search_criteria)
return pickle.loads(defaults.value) if defaults else None
@api.model
def get_defaults(self, model, condition=False):
"""Returns any default values that are defined for the current model and user,
(and match ``condition``, if specified), previously registered via
:meth:`~.set_default`.
Defaults are global to a model, not field-specific, but an optional
``condition`` can be provided to restrict matching default values
to those that were defined for the same condition (usually based
on another field's value).
Default values also have priorities depending on whom they apply
to: only the highest priority value will be returned for any
field. See :meth:`~.set_default` for more details.
:param string model: model name
:param string condition: optional condition specification that can be used to
restrict the applicability of the default values
(e.g. based on another field's value). This is an
opaque string as far as the API is concerned, but client
stacks typically use single-field conditions in the
form ``'key=stringified_value'``.
(Currently, the condition is trimmed to 200 characters,
so values that share the same first 200 characters always
match)
:return: list of default values tuples of the form ``(id, field_name, value)``
(``id`` is the ID of the default entry, usually irrelevant)
"""
# use a direct SQL query for performance reasons,
# this is called very often
query = """ SELECT v.id, v.name, v.value FROM ir_values v
LEFT JOIN res_users u ON (v.user_id = u.id)
WHERE v.key = %%s AND v.model = %%s
AND (v.user_id = %%s OR v.user_id IS NULL)
AND (v.company_id IS NULL OR
v.company_id = (SELECT company_id FROM res_users WHERE id = %%s)
)
%s
ORDER BY v.user_id, v.company_id, v.id"""
params = ('default', model, self._uid, self._uid)
if condition:
query = query % 'AND v.key2 = %s'
params += (condition[:200],)
else:
query = query % 'AND v.key2 IS NULL'
self._cr.execute(query, params)
# keep only the highest priority default for each field
defaults = {}
for row in self._cr.dictfetchall():
value = pickle.loads(row['value'])
defaults.setdefault(row['name'], (row['id'], row['name'], value))
return list(defaults.values())
# use ormcache: this is called a lot by BaseModel.default_get()!
@api.model
@tools.ormcache('self._uid', 'model', 'condition')
def get_defaults_dict(self, model, condition=False):
""" Returns a dictionary mapping field names with their corresponding
default value. This method simply improves the returned value of
:meth:`~.get_defaults`.
"""
return dict((f, v) for i, f, v in self.get_defaults(model, condition))
@api.model
@api.returns('self', lambda value: value.id)
def set_action(self, name, action_slot, model, action, res_id=False):
"""Binds an the given action to the given model's action slot - for later
retrieval via :meth:`~.get_actions`. Any existing binding of the same action
to the same slot is first removed, allowing an update of the action's name.
See the class description for more details about the various action
slots: :class:`~ir_values`.
:param string name: action label, usually displayed by UI client
:param string action_slot: the action slot to which the action should be
bound to - one of ``client_action_multi``,
``client_print_multi``, ``client_action_relate``,
``tree_but_open``.
:param string model: model name
:param string action: action reference, in the form ``'model,id'``
:param int res_id: optional record id - will bind the action only to a
specific record of the model, not all records.
:return: the newly created ir.values entry
"""
assert isinstance(action, pycompat.string_types) and ',' in action, \
'Action definition must be an action reference, e.g. "ir.actions.act_window,42"'
assert action_slot in ACTION_SLOTS, \
'Action slot (%s) must be one of: %r' % (action_slot, ACTION_SLOTS)
action = action.encode('utf-8')
# remove existing action definition of same slot and value
search_criteria = [
('key', '=', 'action'),
('key2', '=', action_slot),
('model', '=', model),
('res_id', '=', res_id or 0), # int field -> NULL == 0
('value', '=', action),
]
self.search(search_criteria).unlink()
return self.create({
'key': 'action',
'key2': action_slot,
'model': model,
'res_id': res_id,
'name': name,
'value': action,
})
@api.model
@tools.ormcache_context('self._uid', 'action_slot', 'model', 'res_id', keys=('lang',))
def get_actions(self, action_slot, model, res_id=False):
"""Retrieves the list of actions bound to the given model's action slot.
See the class description for more details about the various action
slots: :class:`~.ir_values`.
:param string action_slot: the action slot to which the actions should be
bound to - one of ``client_action_multi``,
``client_print_multi``, ``client_action_relate``,
``tree_but_open``.
:param string model: model name
:param int res_id: optional record id - will bind the action only to a
specific record of the model, not all records.
:return: list of action tuples of the form ``(id, name, action_def)``,
where ``id`` is the ID of the default entry, ``name`` is the
action label, and ``action_def`` is a dict containing the
action definition as obtained by calling
:meth:`~odoo.models.Model.read` on the action record.
"""
assert action_slot in ACTION_SLOTS, 'Illegal action slot value: %s' % action_slot
# use a direct SQL query for performance reasons,
# this is called very often
query = """ SELECT v.id, v.name, v.value FROM ir_values v
WHERE v.key = %s AND v.key2 = %s AND v.model = %s
AND (v.res_id = %s OR v.res_id IS NULL OR v.res_id = 0)
ORDER BY v.id """
self._cr.execute(query, ('action', action_slot, model, res_id or None))
# map values to their corresponding action record
actions = []
for id, name, value in self._cr.fetchall():
if not value:
continue # skip if undefined
action_model, action_id = bytes(value).decode('utf-8').split(',')
if action_model not in self.env:
continue # unknown model? skip it!
action = self.env[action_model].browse(int(action_id))
actions.append((id, name, action))
# process values and their action
results = {}
for id, name, action in actions:
# FIXME: needs cleanup
try:
action_def = dict([(k, v.convert_to_read(action[k], action)) for k, v in action._fields.items()])
if action._name in ('ir.actions.report', 'ir.actions.act_window'):
if action.groups_id and not action.groups_id & self.env.user.groups_id:
if name == 'Menuitem':
raise AccessError(_('You do not have the permission to perform this operation!!!'))
continue
# keep only the last action registered for each action name
results[name] = (id, name, action_def)
except (AccessError, MissingError):
continue
return sorted(results.values())
-126
View File
@@ -1,126 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!-- Values -->
<record id="values_view_form_action" model="ir.ui.view">
<field name="name">ir.values.form.action</field>
<field name="model">ir.values</field>
<field name="arch" type="xml">
<form string="Action Bindings">
<group>
<group>
<field name="name"/>
<field name="model_id"/>
<field name="model"/>
<field name="res_id"/>
<field name="key2"/>
</group>
<group>
<field name="action_id"/>
<field name="value_unpickle" colspan="4" string="Action Reference"/>
</group>
</group>
</form>
</field>
</record>
<record id="values_view_form_defaults" model="ir.ui.view">
<field name="name">ir.values.form.defaults</field>
<field name="model">ir.values</field>
<field name="arch" type="xml">
<form string="User-defined Defaults">
<group>
<group>
<field name="name"/>
<field name="model"/>
<field name="model_id"/>
</group>
<group>
<field name="key2" string="Condition"/>
<field name="user_id"/>
<field name="company_id" groups="base.group_multi_company"/>
</group>
<separator string="Default value or action reference"/>
<field name="value_unpickle" nolabel="1" colspan="2"/>
</group>
</form>
</field>
</record>
<record id="values_view_tree_action" model="ir.ui.view">
<field name="name">ir.values.tree.action</field>
<field name="model">ir.values</field>
<field name="arch" type="xml">
<tree string="Action Bindings/Defaults">
<field name="name"/>
<field name="model"/>
<field name="value_unpickle"/>
<field name="key2"/>
</tree>
</field>
</record>
<record id="values_view_search_action" model="ir.ui.view">
<field name="name">ir.values.search.action</field>
<field name="model">ir.values</field>
<field name="arch" type="xml">
<search string="Client Actions">
<field name="name"
filter_domain="['|', '|', ('name','ilike',self), ('model','ilike',self), ('key2','ilike',self)]"
string="Client Action"/>
<group expand="0" string="Group By">
<filter string="Model" domain="[]" context="{'group_by':'model'}"/>
<filter string="Type" domain="[]" context="{'group_by':'key2'}"/>
</group>
</search>
</field>
</record>
<record id="act_values_form_action" model="ir.actions.act_window">
<field name="name">Action Bindings</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">ir.values</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="search_view_id" ref="values_view_search_action"/>
<field name="domain">[('key','=','action')]</field>
<field name="context">{'default_key':'action'}</field>
</record>
<record model="ir.actions.act_window.view" id="action_values_tree_view">
<field name="sequence" eval="1"/>
<field name="view_mode">tree</field>
<field name="view_id" ref="values_view_tree_action"/>
<field name="act_window_id" ref="act_values_form_action"/>
</record>
<record model="ir.actions.act_window.view" id="action_values_form_view">
<field name="sequence" eval="2"/>
<field name="view_mode">form</field>
<field name="view_id" ref="values_view_form_action"/>
<field name="act_window_id" ref="act_values_form_action"/>
</record>
<menuitem action="act_values_form_action" id="menu_values_form_action" parent="next_id_6"/>
<record id="act_values_form_defaults" model="ir.actions.act_window">
<field name="name">User-defined Defaults</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">ir.values</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="search_view_id" ref="values_view_search_action"/>
<field name="domain">[('key','=','default')]</field>
<field name="context">{'default_key':'default','default_key2':''}</field>
</record>
<record model="ir.actions.act_window.view" id="action_values_defaults_tree_view">
<field name="sequence" eval="1"/>
<field name="view_mode">tree</field>
<field name="view_id" ref="values_view_tree_action"/>
<field name="act_window_id" ref="act_values_form_defaults"/>
</record>
<record model="ir.actions.act_window.view" id="action_values_defaults_form_view">
<field name="sequence" eval="2"/>
<field name="view_mode">form</field>
<field name="view_id" ref="values_view_form_defaults"/>
<field name="act_window_id" ref="act_values_form_defaults"/>
</record>
<menuitem action="act_values_form_defaults" id="menu_values_form_defaults" parent="next_id_6"/>
</odoo>
-6
View File
@@ -683,8 +683,6 @@ class GroupsView(models.Model):
self._update_user_groups_view()
# actions.get_bindings() depends on action records
self.env['ir.actions.actions'].clear_caches()
# ir_values.get_actions() depends on action records
self.env['ir.values'].clear_caches()
return user
@api.multi
@@ -693,8 +691,6 @@ class GroupsView(models.Model):
self._update_user_groups_view()
# actions.get_bindings() depends on action records
self.env['ir.actions.actions'].clear_caches()
# ir_values.get_actions() depends on action records
self.env['ir.values'].clear_caches()
return res
@api.multi
@@ -703,8 +699,6 @@ class GroupsView(models.Model):
self._update_user_groups_view()
# actions.get_bindings() depends on action records
self.env['ir.actions.actions'].clear_caches()
# ir_values.get_actions() depends on action records
self.env['ir.values'].clear_caches()
return res
@api.model
@@ -104,13 +104,6 @@
<field name="perm_write" eval="False"/>
</record>
<record model="ir.rule" id="ir_values_default_rule">
<field name="name">Defaults: alter personal values only</field>
<field name="model_id" ref="model_ir_values"/>
<field name="domain_force">[('key','=','default'),('user_id','=',user.id)]</field>
<field name="perm_read" eval="False"/>
</record>
<record model="ir.rule" id="ir_default_user_rule">
<field name="name">Defaults: alter personal defaults</field>
<field name="model_id" ref="model_ir_default"/>
@@ -32,7 +32,6 @@
"access_ir_ui_view_group_user","ir_ui_view group_user","model_ir_ui_view",,1,0,0,0
"access_ir_ui_view_group_system","ir_ui_view group_system","model_ir_ui_view","group_system",1,1,1,1
"access_ir_ui_view_custom_group_user","ir_ui_view_custom_group_user","model_ir_ui_view_custom",,1,1,1,1
"access_ir_values_group_all","ir_values group_all","model_ir_values",,1,1,1,1
"access_ir_default_all","ir_default all","model_ir_default",,1,0,0,0
"access_ir_default_group_user","ir_default group_user","model_ir_default","group_user",1,1,1,1
"access_ir_default_group_system","ir_default group_system","model_ir_default","group_system",1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
32 access_ir_ui_view_group_user ir_ui_view group_user model_ir_ui_view 1 0 0 0
33 access_ir_ui_view_group_system ir_ui_view group_system model_ir_ui_view group_system 1 1 1 1
34 access_ir_ui_view_custom_group_user ir_ui_view_custom_group_user model_ir_ui_view_custom 1 1 1 1
access_ir_values_group_all ir_values group_all model_ir_values 1 1 1 1
35 access_ir_default_all ir_default all model_ir_default 1 0 0 0
36 access_ir_default_group_user ir_default group_user model_ir_default group_user 1 1 1 1
37 access_ir_default_group_system ir_default group_system model_ir_default group_system 1 1 1 1
-1
View File
@@ -12,7 +12,6 @@ from . import test_ir_http
from . import test_ir_filters
from . import test_ir_sequence
from . import test_ir_sequence_date_range
from . import test_ir_values
from . import test_ir_default
from . import test_mail
from . import test_menu
-129
View File
@@ -1,129 +0,0 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import tools
from odoo.exceptions import ValidationError
from odoo.tests.common import TransactionCase
class TestIrValues(TransactionCase):
def test_defaults(self):
# Create some default value for some model, for all users.
ir_values = self.env['ir.values']
ir_values.set_default('res.partner', 'ref', 'X11')
ir_values.set_default('res.partner.title', 'shortcut', 'Mr', condition='name=Mister')
# Retrieve them: ds is a list of triplets (id, name, value)
ds = ir_values.get_defaults('res.partner')
d = next((d for d in ds if d[1] == 'ref'), None)
self.assertTrue(d, "At least one value should be retrieved for this model.")
self.assertEqual(d[2], 'X11', "Can't retrieve the created default value.")
ds = ir_values.get_defaults('res.partner.title')
d = next((d for d in ds if d[1] == 'shortcut'), None)
self.assertFalse(d, "No value should be retrieved, the condition is not met.")
ds = ir_values.get_defaults('res.partner.title', condition="name=Miss")
d = next((d for d in ds if d[1] == 'shortcut'), None)
self.assertFalse(d, "No value should be retrieved, the condition is not met.")
ds = ir_values.get_defaults('res.partner.title', condition="name=Mister")
d = next((d for d in ds if d[1] == 'shortcut'), None)
self.assertTrue(d, "At least one value should be retrieved.")
self.assertEqual(d[2], 'Mr', "Can't retrieve the created default value.")
# Do it again but for a specific user.
ir_values.set_default('res.partner', 'ref', '007', for_all_users=False)
# Retrieve it and check it is the one for the current user.
ds = ir_values.get_defaults('res.partner')
d = next((d for d in ds if d[1] == 'ref'), None)
self.assertTrue(d, "At least one value should be retrieved for this model.")
self.assertEqual(d[2], '007', "Can't retrieve the created default value.")
# create valid but unusable defaults, a ValidationError should not be thrown
with tools.mute_logger('odoo.addons.base.ir.ir_values'):
ir_values.set_default('unknown_model', 'unknown_field', 42)
ir_values.set_default('res.partner', 'unknown_field', 42)
# create invalid defaults
with self.assertRaises(ValidationError):
ir_values.set_default('res.partner', 'lang', 'some_LANG')
with self.assertRaises(ValidationError):
ir_values.set_default('res.partner', 'credit_limit', 'foo')
def test_actions(self):
# Create some action bindings for a model.
act_id_1 = self.ref('base.act_values_form_action')
act_id_2 = self.ref('base.act_values_form_defaults')
act_id_3 = self.ref('base.action_res_company_form')
ir_values = self.env['ir.values']
ir_values.set_action('OnDblClick Action', action_slot='tree_but_open', model='res.partner', action='ir.actions.act_window,%d' % act_id_1, res_id=False)
ir_values.set_action('OnDblClick Action 2', action_slot='tree_but_open', model='res.partner', action='ir.actions.act_window,%d' % act_id_2, res_id=False)
ir_values.set_action('Side Wizard', action_slot='client_action_multi', model='res.partner', action='ir.actions.act_window,%d' % act_id_3, res_id=False)
reports = self.env['ir.actions.report'].search([])
report_id = next(report.id for report in reports if not report.groups_id)
ir_values.set_action('Nice Report', action_slot='client_print_multi', model='res.partner', action='ir.actions.report,%d' % report_id, res_id=False)
# Replace one action binding to set a new name.
ir_values.set_action('OnDblClick Action New', action_slot='tree_but_open', model='res.partner', action='ir.actions.act_window,%d' % act_id_1, res_id=False)
# Retrieve the action bindings and check they're correct
actions = ir_values.get_actions(action_slot='tree_but_open', model='res.partner', res_id=False)
self.assertEqual(len(actions), 2, "Mismatching number of bound actions")
# first action
self.assertEqual(len(actions[0]), 3, "Malformed action definition")
self.assertEqual(actions[0][1], 'OnDblClick Action 2', 'Bound action does not match definition')
self.assertTrue(isinstance(actions[0][2], dict) and actions[0][2]['id'] == act_id_2,
'Bound action does not match definition')
# second action - this ones comes last because it was re-created with a different name
self.assertEqual(len(actions[1]), 3, "Malformed action definition")
self.assertEqual(actions[1][1], 'OnDblClick Action New', 'Re-Registering an action should replace it')
self.assertTrue(isinstance(actions[1][2], dict) and actions[1][2]['id'] == act_id_1,
'Bound action does not match definition')
actions = ir_values.get_actions(action_slot='client_action_multi', model='res.partner', res_id=False)
self.assertEqual(len(actions), 1, "Mismatching number of bound actions")
self.assertEqual(len(actions[0]), 3, "Malformed action definition")
self.assertEqual(actions[0][1], 'Side Wizard', 'Bound action does not match definition')
self.assertTrue(isinstance(actions[0][2], dict) and actions[0][2]['id'] == act_id_3,
'Bound action does not match definition')
actions = ir_values.get_actions(action_slot='client_print_multi', model='res.partner', res_id=False)
self.assertEqual(len(actions), 1, "Mismatching number of bound actions")
self.assertEqual(len(actions[0]), 3, "Malformed action definition")
self.assertEqual(actions[0][1], 'Nice Report', 'Bound action does not match definition')
self.assertTrue(isinstance(actions[0][2], dict) and actions[0][2]['id'] == report_id,
'Bound action does not match definition')
def test_orders(self):
ir_values = self.env['ir.values']
# create a global rule for all
ir_values.set_default(
'res.partner', 'ref', 'value_global',
for_all_users=True, company_id=False, condition=False)
self.assertEqual(
ir_values.get_defaults_dict('res.partner')['ref'],
'value_global',
"Can't retrieve the created default value for all.")
# set a default value for current company (behavior of 'set default' from debug mode)
ir_values.set_default(
'res.partner', 'ref', 'value_company',
for_all_users=True, company_id=True, condition=False)
self.assertEqual(
ir_values.get_defaults_dict('res.partner')['ref'],
'value_company',
"Can't retrieve the created default value for company.")
# set a default value for current user (behavior of 'set default' from debug mode)
ir_values.set_default(
'res.partner', 'ref', 'value_user',
for_all_users=False, company_id=True, condition=False)
self.assertEqual(
ir_values.get_defaults_dict('res.partner')['ref'],
'value_user',
"Can't retrieve the created default value for user.")
-9
View File
@@ -2832,7 +2832,6 @@ class BaseModel(MetaModel('DummyModel', (object,), {'_register': False})):
cr = self._cr
Data = self.env['ir.model.data'].sudo().with_context({})
Values = self.env['ir.values']
Defaults = self.env['ir.default'].sudo()
Attachment = self.env['ir.attachment']
@@ -2851,14 +2850,6 @@ class BaseModel(MetaModel('DummyModel', (object,), {'_register': False})):
if data:
data.unlink()
# For the same reason, remove the relevant records in ir_values
refs = ['%s,%s' % (self._name, i) for i in sub_ids]
values = Values.search(['|', ('value', 'in', refs),
'&', ('model', '=', self._name),
('res_id', 'in', sub_ids)])
if values:
values.unlink()
# For the same reason, remove the defaults having some of the
# records as value
Defaults.discard_records(self.browse(sub_ids))