Merge branch '14.0' into 14.0_MIG_web_widget_mermaid

This commit is contained in:
Maxime Chambreuil
2022-11-14 07:13:01 -07:00
committed by GitHub
33 changed files with 800 additions and 217 deletions

View File

@@ -1,9 +1,14 @@
# Do NOT update manually; changes here will be overwritten by Copier
_commit: v1.6.1
_commit: v1.11.0
_src_path: gh:oca/oca-addons-repo-template
ci: GitHub
dependency_installation_mode: PIP
generate_requirements_txt: true
github_check_license: true
github_enable_codecov: true
github_enable_makepot: true
github_enable_stale_action: true
github_enforce_dev_status_compatibility: true
include_wkhtmltopdf: false
odoo_version: 14.0
org_name: Odoo Community Association (OCA)
@@ -11,10 +16,11 @@ org_slug: OCA
rebel_module_groups:
- web_widget_model_viewer
repo_description: "This project aims to deal with modules related to the webclient\
\ of Odoo. You'll find modules that:\n\n - Add facilities to the UI\n - Add widgets\n\
\ - Ease the import/export features\n - Generally add clientside functionality"
\ of Odoo. You'll find modules that:\n\n - Add facilities to the UI\n - Add widgets\n\
\ - Ease the import/export features\n - Generally add clientside functionality"
repo_name: Web addons for Odoo
repo_slug: web
repo_website: https://github.com/OCA/web
travis_apt_packages: []
travis_apt_sources: []

1
.gitignore vendored
View File

@@ -15,7 +15,6 @@ build/
develop-eggs/
dist/
eggs/
lib/
lib64/
parts/
sdist/

View File

@@ -119,19 +119,15 @@ repos:
- id: flake8
name: flake8
additional_dependencies: ["flake8-bugbear==20.1.4"]
- repo: https://github.com/PyCQA/pylint
rev: v2.11.1
- repo: https://github.com/OCA/pylint-odoo
rev: 7.0.2
hooks:
- id: pylint
- id: pylint_odoo
name: pylint with optional checks
args:
- --rcfile=.pylintrc
- --exit-zero
verbose: true
additional_dependencies: &pylint_deps
- pylint-odoo==5.0.5
- id: pylint
name: pylint with mandatory checks
- id: pylint_odoo
args:
- --rcfile=.pylintrc-mandatory
additional_dependencies: *pylint_deps

View File

@@ -1,3 +1,5 @@
[MASTER]
load-plugins=pylint_odoo
score=n

View File

@@ -1,3 +1,4 @@
[MASTER]
load-plugins=pylint_odoo
score=n

View File

@@ -27,7 +27,7 @@ Available addons
addon | version | maintainers | summary
--- | --- | --- | ---
[support_branding](support_branding/) | 14.0.1.0.0 | | Adds your branding to an Odoo instance
[web_access_rule_buttons](web_access_rule_buttons/) | 14.0.1.0.0 | | Disable Edit button if access rules prevent this action
[web_access_rule_buttons](web_access_rule_buttons/) | 14.0.1.0.1 | | Disable Edit button if access rules prevent this action
[web_action_conditionable](web_action_conditionable/) | 14.0.1.0.1 | | web_action_conditionable
[web_advanced_search](web_advanced_search/) | 14.0.1.0.1 | | Easier and more powerful searching tools
[web_calendar_color_field](web_calendar_color_field/) | 14.0.1.0.0 | | Calendar Color Field
@@ -36,8 +36,8 @@ addon | version | maintainers | summary
[web_copy_confirm](web_copy_confirm/) | 14.0.1.0.0 | | Show confirmation dialogue before copying records
[web_decimal_numpad_dot](web_decimal_numpad_dot/) | 14.0.1.0.0 | | Allows using numpad dot to enter period decimal separator
[web_dialog_size](web_dialog_size/) | 14.0.1.0.0 | | A module that lets the user expand a dialog box to the full screen width.
[web_disable_export_group](web_disable_export_group/) | 14.0.1.0.0 | | Web Disable Export Group
[web_domain_field](web_domain_field/) | 14.0.1.0.1 | | Use computed field as domain
[web_disable_export_group](web_disable_export_group/) | 14.0.2.0.0 | | Web Disable Export Group
[web_domain_field](web_domain_field/) | 14.0.1.0.2 | | Use computed field as domain
[web_drop_target](web_drop_target/) | 14.0.1.1.1 | | Allows to drag files into Odoo
[web_environment_ribbon](web_environment_ribbon/) | 14.0.1.0.0 | | Web Environment Ribbon
[web_group_expand](web_group_expand/) | 14.0.1.0.0 | | Group Expand Buttons

View File

@@ -4,7 +4,7 @@
{
"name": "Web Access Rules Buttons",
"summary": "Disable Edit button if access rules prevent this action",
"version": "14.0.1.0.0",
"version": "14.0.1.0.1",
"author": "Camptocamp, Onestein, Odoo Community Association (OCA)",
"license": "AGPL-3",
"category": "Web",

View File

@@ -22,19 +22,16 @@ class Base(models.AbstractModel):
operations = ["read", "create", "write", "unlink"]
result = {}
for operation in operations:
try:
self.check_access_rule(operation)
except exceptions.AccessError:
result[operation] = False
if (
self.is_transient()
or self.ids
and self.env.user.has_group("base.user_admin")
):
if self.is_transient() or not self.ids:
# If we call check_access_rule() without id, it will try to
# run a SELECT without ID which will crash, so we just blindly
# allow the operations
result[operation] = True
else:
continue
try:
self.check_access_rule(operation)
except exceptions.AccessError:
result[operation] = False
else:
result[operation] = True
return result

View File

@@ -1,25 +1,38 @@
# Copyright 2019 Onestein BV
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo.tests.common import TransactionCase
from odoo.tests import common, new_test_user, users
class TestAccessRuleButtons(TransactionCase):
class TestAccessRuleButtons(common.TransactionCase):
def setUp(self):
super(TestAccessRuleButtons, self).setUp()
self.curr_obj = self.env["res.currency"]
super().setUp()
self.curr_record = self.env.ref("base.USD")
new_test_user(self.env, login="test-user", groups="base.group_system")
self.env.ref("base.user_admin").write(
{
"groups_id": [(4, self.env.ref("base.group_system").id)],
}
)
@users("admin", "test-user")
def test_check_access_rule_1(self):
res = self.curr_obj.check_access_rule_all(["write"])
self.assertFalse(res["write"])
res = self.env["res.currency"].check_access_rule_all(["write"])
self.assertTrue(res["write"])
@users("admin", "test-user")
def test_check_access_rule_2(self):
res = self.curr_record.check_access_rule_all(["write"])
res = (
self.env["res.currency"]
.browse(self.curr_record.id)
.check_access_rule_all(["write"])
)
self.assertFalse(res["write"])
@users("admin", "test-user")
def test_check_access_rule_3(self):
res = self.curr_record.check_access_rule_all()
res = (
self.env["res.currency"].browse(self.curr_record.id).check_access_rule_all()
)
self.assertFalse(res["read"])
self.assertFalse(res["create"])
self.assertFalse(res["write"])

View File

@@ -25,11 +25,9 @@ Web Disable Export Group
|badge1| |badge2| |badge3| |badge4| |badge5|
In the standard Odoo the UI option 'Export' that is present in the 'Action' menu
and the 'Export All' button of any list view is always enabled (for every user).
The standard export group prevents both options: 'Direct Export (xlsx)' and 'Export All'.
This module makes the option 'Export' and 'Export All' enabled only for the users
that belong to the Export Data group.
This module adds a new group for the 'Direct Export (xlsx)' feature, leaving the standard one for only the 'Export All' feature.
Admin user can always use the export option.
@@ -41,13 +39,13 @@ Admin user can always use the export option.
Configuration
=============
Enable the group "Export Data group" to the users who are allowed to
make use of the option 'Export'.
Enable the group "Direct Export" to the users who are allowed to
make use of the option 'Export xlsx'.
Usage
=====
Every user without *Export Data* permission won't have the option available.
Every user without *Direct Export (xlsx)* permission won't have the option available.
Bug Tracker
===========
@@ -81,6 +79,7 @@ Contributors
* David Vidal
* João Marques
* Alexandre Díaz
* Víctor Martínez
Maintainers
~~~~~~~~~~~

View File

@@ -4,7 +4,7 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
{
"name": "Web Disable Export Group",
"version": "14.0.1.0.0",
"version": "14.0.2.0.0",
"license": "AGPL-3",
"author": "Onestein, " "Tecnativa, " "Odoo Community Association (OCA)",
"website": "https://github.com/OCA/web",

View File

@@ -17,19 +17,33 @@ msgstr ""
"X-Generator: Weblate 3.10\n"
#. module: web_disable_export_group
#. openerp-web
#: code:addons/web_disable_export_group/static/src/js/disable_export_group.js:0
#: code:addons/web_disable_export_group/static/src/js/web_disable_export_group_tour.js:0
#, python-format
msgid "Export"
msgstr "Exportar"
#: model:res.groups,name:web_disable_export_group.group_export_xlsx_data
msgid "Direct Export (xlsx)"
msgstr ""
#. module: web_disable_export_group
#: model:res.groups,name:web_disable_export_group.group_export_data
msgid "Export Data"
msgstr "Exportar datos"
#: model:ir.model.fields,field_description:web_disable_export_group.field_ir_http__display_name
msgid "Display Name"
msgstr ""
#. module: web_disable_export_group
#: model:ir.model,name:web_disable_export_group.model_ir_http
msgid "HTTP Routing"
msgstr "Ruta HTTP"
#. module: web_disable_export_group
#: model:ir.model.fields,field_description:web_disable_export_group.field_ir_http__id
msgid "ID"
msgstr ""
#. module: web_disable_export_group
#: model:ir.model.fields,field_description:web_disable_export_group.field_ir_http____last_update
msgid "Last Modified on"
msgstr ""
#, python-format
#~ msgid "Export"
#~ msgstr "Exportar"
#~ msgid "Export Data"
#~ msgstr "Exportar datos"

View File

@@ -18,19 +18,33 @@ msgstr ""
"X-Generator: Weblate 3.9.1\n"
#. module: web_disable_export_group
#. openerp-web
#: code:addons/web_disable_export_group/static/src/js/disable_export_group.js:0
#: code:addons/web_disable_export_group/static/src/js/web_disable_export_group_tour.js:0
#, python-format
msgid "Export"
msgstr "Izvoz"
#: model:res.groups,name:web_disable_export_group.group_export_xlsx_data
msgid "Direct Export (xlsx)"
msgstr ""
#. module: web_disable_export_group
#: model:res.groups,name:web_disable_export_group.group_export_data
msgid "Export Data"
msgstr "Izvoz podataka"
#: model:ir.model.fields,field_description:web_disable_export_group.field_ir_http__display_name
msgid "Display Name"
msgstr ""
#. module: web_disable_export_group
#: model:ir.model,name:web_disable_export_group.model_ir_http
msgid "HTTP Routing"
msgstr "HTTP usmjeravanje"
#. module: web_disable_export_group
#: model:ir.model.fields,field_description:web_disable_export_group.field_ir_http__id
msgid "ID"
msgstr ""
#. module: web_disable_export_group
#: model:ir.model.fields,field_description:web_disable_export_group.field_ir_http____last_update
msgid "Last Modified on"
msgstr ""
#, python-format
#~ msgid "Export"
#~ msgstr "Izvoz"
#~ msgid "Export Data"
#~ msgstr "Izvoz podataka"

View File

@@ -17,19 +17,33 @@ msgstr ""
"X-Generator: Weblate 3.10\n"
#. module: web_disable_export_group
#. openerp-web
#: code:addons/web_disable_export_group/static/src/js/disable_export_group.js:0
#: code:addons/web_disable_export_group/static/src/js/web_disable_export_group_tour.js:0
#, python-format
msgid "Export"
msgstr "Exportar"
#: model:res.groups,name:web_disable_export_group.group_export_xlsx_data
msgid "Direct Export (xlsx)"
msgstr ""
#. module: web_disable_export_group
#: model:res.groups,name:web_disable_export_group.group_export_data
msgid "Export Data"
msgstr "Exportar Dados"
#: model:ir.model.fields,field_description:web_disable_export_group.field_ir_http__display_name
msgid "Display Name"
msgstr ""
#. module: web_disable_export_group
#: model:ir.model,name:web_disable_export_group.model_ir_http
msgid "HTTP Routing"
msgstr "Encaminhamento HTTP"
#. module: web_disable_export_group
#: model:ir.model.fields,field_description:web_disable_export_group.field_ir_http__id
msgid "ID"
msgstr ""
#. module: web_disable_export_group
#: model:ir.model.fields,field_description:web_disable_export_group.field_ir_http____last_update
msgid "Last Modified on"
msgstr ""
#, python-format
#~ msgid "Export"
#~ msgstr "Exportar"
#~ msgid "Export Data"
#~ msgstr "Exportar Dados"

View File

@@ -13,25 +13,16 @@ msgstr ""
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: web_disable_export_group
#: model:res.groups,name:web_disable_export_group.group_export_xlsx_data
msgid "Direct Export (xlsx)"
msgstr ""
#. module: web_disable_export_group
#: model:ir.model.fields,field_description:web_disable_export_group.field_ir_http__display_name
msgid "Display Name"
msgstr ""
#. module: web_disable_export_group
#. openerp-web
#: code:addons/web_disable_export_group/static/src/js/disable_export_group.js:0
#: code:addons/web_disable_export_group/static/src/js/web_disable_export_group_tour.js:0
#: code:addons/web_disable_export_group/static/src/js/web_disable_export_group_tour.js:0
#, python-format
msgid "Export"
msgstr ""
#. module: web_disable_export_group
#: model:res.groups,name:web_disable_export_group.group_export_data
msgid "Export Data"
msgstr ""
#. module: web_disable_export_group
#: model:ir.model,name:web_disable_export_group.model_ir_http
msgid "HTTP Routing"

View File

@@ -17,19 +17,33 @@ msgstr ""
"X-Generator: Weblate 3.8\n"
#. module: web_disable_export_group
#. openerp-web
#: code:addons/web_disable_export_group/static/src/js/disable_export_group.js:0
#: code:addons/web_disable_export_group/static/src/js/web_disable_export_group_tour.js:0
#, python-format
msgid "Export"
msgstr "导出"
#: model:res.groups,name:web_disable_export_group.group_export_xlsx_data
msgid "Direct Export (xlsx)"
msgstr ""
#. module: web_disable_export_group
#: model:res.groups,name:web_disable_export_group.group_export_data
msgid "Export Data"
msgstr "导出数据"
#: model:ir.model.fields,field_description:web_disable_export_group.field_ir_http__display_name
msgid "Display Name"
msgstr ""
#. module: web_disable_export_group
#: model:ir.model,name:web_disable_export_group.model_ir_http
msgid "HTTP Routing"
msgstr "HTTP路由"
#. module: web_disable_export_group
#: model:ir.model.fields,field_description:web_disable_export_group.field_ir_http__id
msgid "ID"
msgstr ""
#. module: web_disable_export_group
#: model:ir.model.fields,field_description:web_disable_export_group.field_ir_http____last_update
msgid "Last Modified on"
msgstr ""
#, python-format
#~ msgid "Export"
#~ msgstr "导出"
#~ msgid "Export Data"
#~ msgstr "导出数据"

View File

@@ -0,0 +1,16 @@
from openupgradelib import openupgrade
def add_new_group_from_group(self, env, group, new_group):
groups = env["res.groups"].search([("implied_ids", "=", group.id)])
groups.write({"implied_ids": [(4, new_group.id)]})
group.users.write({"groups_id": [(4, new_group.id)]})
@openupgrade.migrate()
def migrate(env, version):
group = env.ref("web_disable_export_group.group_export_data")
new_group = env.ref("web_disable_export_group.group_export_xlsx_data")
add_new_group_from_group(env, group, new_group)
group = env.ref("base.group_allow_export")
add_new_group_from_group(env, group, new_group)

View File

@@ -13,8 +13,8 @@ class Http(models.AbstractModel):
user = request.env.user
res.update(
{
"group_export_data": user
and user.has_group("web_disable_export_group.group_export_data"),
"group_xlsx_export_data": user
and user.has_group("web_disable_export_group.group_export_xlsx_data"),
}
)
return res

View File

@@ -1,2 +1,2 @@
Enable the group "Export Data group" to the users who are allowed to
make use of the option 'Export'.
Enable the group "Direct Export" to the users who are allowed to
make use of the option 'Export xlsx'.

View File

@@ -8,3 +8,4 @@
* David Vidal
* João Marques
* Alexandre Díaz
* Víctor Martínez

View File

@@ -1,7 +1,5 @@
In the standard Odoo the UI option 'Export' that is present in the 'Action' menu
and the 'Export All' button of any list view is always enabled (for every user).
The standard export group prevents both options: 'Direct Export (xlsx)' and 'Export All'.
This module makes the option 'Export' and 'Export All' enabled only for the users
that belong to the Export Data group.
This module adds a new group for the 'Direct Export (xlsx)' feature, leaving the standard one for only the 'Export All' feature.
Admin user can always use the export option.

View File

@@ -1 +1 @@
Every user without *Export Data* permission won't have the option available.
Every user without *Direct Export (xlsx)* permission won't have the option available.

View File

@@ -2,8 +2,10 @@
<!-- Copyright 2016 Onestein
License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl).-->
<odoo>
<record id="group_export_data" model="res.groups">
<field name="name">Export Data</field>
<record id="group_export_xlsx_data" model="res.groups">
<field name="name">Direct Export (xlsx)</field>
<field name="implied_ids" eval="[(4, ref('base.group_allow_export'))]" />
<field name="category_id" ref="base.module_category_hidden" />
<field
name="users"
eval="[(4, ref('base.user_root')), (4, ref('base.user_admin'))]"

View File

@@ -368,10 +368,8 @@ ul.auto-toc {
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<p><a class="reference external" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external" href="https://github.com/OCA/web/tree/14.0/web_disable_export_group"><img alt="OCA/web" src="https://img.shields.io/badge/github-OCA%2Fweb-lightgray.png?logo=github" /></a> <a class="reference external" href="https://translation.odoo-community.org/projects/web-14-0/web-14-0-web_disable_export_group"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external" href="https://runbot.odoo-community.org/runbot/162/14.0"><img alt="Try me on Runbot" src="https://img.shields.io/badge/runbot-Try%20me-875A7B.png" /></a></p>
<p>In the standard Odoo the UI option Export that is present in the Action menu
and the Export All button of any list view is always enabled (for every user).</p>
<p>This module makes the option Export and Export All enabled only for the users
that belong to the Export Data group.</p>
<p>The standard export group prevents both options: Direct Export (xlsx) and Export All.</p>
<p>This module adds a new group for the Direct Export (xlsx) feature, leaving the standard one for only the Export All feature.</p>
<p>Admin user can always use the export option.</p>
<p><strong>Table of contents</strong></p>
<div class="contents local topic" id="contents">
@@ -389,12 +387,12 @@ that belong to the Export Data group.</p>
</div>
<div class="section" id="configuration">
<h1><a class="toc-backref" href="#id1">Configuration</a></h1>
<p>Enable the group “Export Data group” to the users who are allowed to
make use of the option Export.</p>
<p>Enable the group “Direct Export” to the users who are allowed to
make use of the option Export xlsx.</p>
</div>
<div class="section" id="usage">
<h1><a class="toc-backref" href="#id2">Usage</a></h1>
<p>Every user without <em>Export Data</em> permission wont have the option available.</p>
<p>Every user without <em>Direct Export (xlsx)</em> permission wont have the option available.</p>
</div>
<div class="section" id="bug-tracker">
<h1><a class="toc-backref" href="#id3">Bug Tracker</a></h1>
@@ -425,6 +423,7 @@ If you spotted it first, help us smashing it by providing a detailed and welcome
<li>David Vidal</li>
<li>João Marques</li>
<li>Alexandre Díaz</li>
<li>Víctor Martínez</li>
</ul>
</li>
</ul>

View File

@@ -1,33 +1,15 @@
/* Copyright 2016 Onestein
Copyright 2018 Tecnativa - David Vidal
Copyright 2021 Tecnativa - Alexandre Díaz
Copyright 2022 Tecnativa - Víctor Martínez
License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl). */
odoo.define("web_disable_export_group", function (require) {
odoo.define("web_disable_export_group.WebDisableExportGroupController", function (
require
) {
"use strict";
const core = require("web.core");
const Sidebar = require("web.Sidebar");
const session = require("web.session");
const AbstractController = require("web.AbstractController");
const _t = core._t;
Sidebar.include({
/**
* @override
*/
_addItems: function (sectionCode, items) {
let _items = items;
if (
!session.is_superuser &&
sectionCode === "other" &&
items.length &&
!session.group_export_data
) {
_items = _.reject(_items, {label: _t("Export")});
}
this._super(sectionCode, _items);
},
});
AbstractController.include({
/**
@@ -37,8 +19,8 @@ odoo.define("web_disable_export_group", function (require) {
if (
!session.is_superuser &&
action &&
action.startsWith("export_") &&
!session.group_export_data
action.startsWith("export_xlsx") &&
!session.group_xlsx_export_data
) {
return false;
}

View File

@@ -1,16 +1,14 @@
/* Copyright 2020 Tecnativa - João Marques
Copyright 2022 Tecnativa - Víctor Martínez
License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl). */
odoo.define("web_disable_export_group.tour", function (require) {
"use strict";
var core = require("web.core");
var tour = require("web_tour.tour");
var _t = core._t;
tour.register(
"export_tour_admin",
"export_tour_xlsx_button_ok",
{
test: true,
url:
@@ -21,25 +19,10 @@ odoo.define("web_disable_export_group.tour", function (require) {
content: "Check if 'Export all' button exists",
trigger: ".o_list_buttons:has(.o_list_export_xlsx)",
},
{
content: "Select all records",
trigger: ".custom-control-input:first",
},
{
content: "Open actions",
trigger: ".o_dropdown_toggler_btn",
},
{
content: "Check if Export button exists",
trigger:
'.o_cp_action_menus ul.o_dropdown_menu a:contains("' +
_t("Export") +
'")',
},
]
);
tour.register(
"export_tour_demo",
"export_tour_xlsx_button_ko",
{
test: true,
url:
@@ -50,21 +33,6 @@ odoo.define("web_disable_export_group.tour", function (require) {
content: "Check if 'Export all' button exists",
trigger: ".o_list_buttons:not(:has(.o_list_export_xlsx))",
},
{
content: "Select all records",
trigger: ".custom-control-input:first",
},
{
content: "Open actions",
trigger: ".o_dropdown_toggler_btn",
},
{
content: "Check if Export button does not exist",
trigger:
'.o_cp_action_menus ul.o_dropdown_menu a:first:not(:contains("' +
_t("Export") +
'"))',
},
]
);
return {};

View File

@@ -1,32 +1,33 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
# Copyright 2020 Tecnativa - João Marques
# Copyright 2022 Tecnativa - Víctor Martínez
import odoo.tests
from odoo.tests import new_test_user
@odoo.tests.tagged("post_install", "-at_install")
class TestTour(odoo.tests.HttpCase):
def setUp(self):
super().setUp()
self.env["res.users"].create(
{
"name": "user_not_export",
"login": "user_not_export",
"password": "user_not_export",
"groups_id": [
(
6,
0,
[
self.env.ref("base.group_user").id,
self.env.ref("base.group_system").id,
],
)
],
}
new_test_user(
self.env,
login="user_not_export",
password="user_not_export",
groups="base.group_user,base.group_system",
)
new_test_user(
self.env,
login="user_export_xlsx",
password="user_export_xlsx",
groups="base.group_user,base.group_system,%s"
% ("web_disable_export_group.group_export_xlsx_data"),
)
def test_admin(self):
self.start_tour("/web", "export_tour_admin", login="admin")
self.start_tour("/web", "export_tour_xlsx_button_ok", login="admin")
def test_user_not_export(self):
self.start_tour("/web", "export_tour_demo", login="user_not_export")
self.start_tour("/web", "export_tour_xlsx_button_ko", login="user_not_export")
def test_user_export_xlsx(self):
self.start_tour("/web", "export_tour_xlsx_button_ok", login="user_export_xlsx")

View File

@@ -1,11 +1,42 @@
.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
================
Web Domain Field
================
.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
.. |badge1| image:: https://img.shields.io/badge/maturity-Production%2FStable-green.png
:target: https://odoo-community.org/page/development-status
:alt: Production/Stable
.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fweb-lightgray.png?logo=github
:target: https://github.com/OCA/web/tree/14.0/web_domain_field
:alt: OCA/web
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/web-14-0/web-14-0-web_domain_field
:alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png
:target: https://runbot.odoo-community.org/runbot/162/14.0
:alt: Try me on Runbot
|badge1| |badge2| |badge3| |badge4| |badge5|
When you define a view you can specify on the relational fields a domain
attribute. This attribute is evaluated as filter to apply when displaying
existing records for selection.
**Table of contents**
.. contents::
:local:
Usage
=====
When you define a view you can specify on the relational fields a domain
attribute. This attribute is evaluated as filter to apply when displaying
existing records for selection.
@@ -51,7 +82,6 @@ The field used as domain must provide the domain as a JSON encoded string.
store=False,
)
@api.multi
@api.depends('name')
def _compute_product_id_domain(self):
for rec in self:
@@ -59,49 +89,44 @@ The field used as domain must provide the domain as a JSON encoded string.
[('type', '=', 'product'), ('name', 'like', rec.name)]
)
Usage
=====
.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas
:alt: Try me on Runbot
:target: https://runbot.odoo-community.org/runbot/162/10.0
Bug Tracker
===========
Bugs are tracked on `GitHub Issues
<https://github.com/OCA/web/issues>`_. In case of trouble, please
check there if your issue has already been reported. If you spotted it first,
help us smashing it by providing a detailed and welcomed feedback.
Bugs are tracked on `GitHub Issues <https://github.com/OCA/web/issues>`_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us smashing it by providing a detailed and welcomed
`feedback <https://github.com/OCA/web/issues/new?body=module:%20web_domain_field%0Aversion:%2014.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
Do not contact contributors directly about support or help with technical issues.
Credits
=======
Images
------
Authors
~~~~~~~
* Odoo Community Association: `Icon <https://github.com/OCA/maintainer-tools/blob/master/template/module/static/description/icon.svg>`_.
* ACSONE SA/NV
Contributors
------------
~~~~~~~~~~~~
* Laurent Mignon <laurent.mignon@acsone.eu>
* Denis Roussel <denis.roussel@acsone.eu>
* Raf Ven <raf.ven@dynapps.be>
Maintainer
----------
Maintainers
~~~~~~~~~~~
This module is maintained by the OCA.
.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: https://odoo-community.org
This module is maintained by the OCA.
OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.
To contribute to this module, please visit https://odoo-community.org.
This module is part of the `OCA/web <https://github.com/OCA/web/tree/14.0/web_domain_field>`_ project on GitHub.
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

View File

@@ -5,7 +5,7 @@
"name": "Web Domain Field",
"summary": """
Use computed field as domain""",
"version": "14.0.1.0.1",
"version": "14.0.1.0.2",
"development_status": "Production/Stable",
"license": "AGPL-3",
"author": "ACSONE SA/NV,Odoo Community Association (OCA)",

View File

@@ -0,0 +1,3 @@
* Laurent Mignon <laurent.mignon@acsone.eu>
* Denis Roussel <denis.roussel@acsone.eu>
* Raf Ven <raf.ven@dynapps.be>

View File

@@ -0,0 +1,3 @@
When you define a view you can specify on the relational fields a domain
attribute. This attribute is evaluated as filter to apply when displaying
existing records for selection.

View File

@@ -0,0 +1,51 @@
When you define a view you can specify on the relational fields a domain
attribute. This attribute is evaluated as filter to apply when displaying
existing records for selection.
.. code-block:: xml
<field name="product_id" domain="[('type','=','product')]"/>
The value provided for the domain attribute must be a string representing a
valid Odoo domain. This string is evaluated on the client side in a
restricted context where we can reference as right operand the values of
fields present into the form and a limited set of functions.
In this context it's hard to build complex domain and we are facing to some
limitations as:
* The syntax to include in your domain a criteria involving values from a
x2many field is complex.
* The right side of domain in case of x2many can involve huge amount of ids
(performance problem).
* Domains computed by an onchange on an other field are not recomputed when
you modify the form and don't modify the field triggering the onchange.
* It's not possible to extend an existing domain. You must completely redefine
the domain in your specialized addon
* etc...
In order to mitigate these limitations this new addon allows you to use the
value of a field as domain of an other field in the xml definition of your
view.
.. code-block:: xml
<field name="product_id_domain" invisible="1"/>
<field name="product_id" domain="product_id_domain"/>
The field used as domain must provide the domain as a JSON encoded string.
.. code-block:: python
product_id_domain = fields.Char(
compute="_compute_product_id_domain",
readonly=True,
store=False,
)
@api.depends('name')
def _compute_product_id_domain(self):
for rec in self:
rec.product_id_domain = json.dumps(
[('type', '=', 'product'), ('name', 'like', rec.name)]
)

View File

@@ -0,0 +1,474 @@
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.15.1: http://docutils.sourceforge.net/" />
<title>Web Domain Field</title>
<style type="text/css">
/*
:Author: David Goodger (goodger@python.org)
:Id: $Id: html4css1.css 7952 2016-07-26 18:15:59Z milde $
:Copyright: This stylesheet has been placed in the public domain.
Default cascading style sheet for the HTML output of Docutils.
See http://docutils.sf.net/docs/howto/html-stylesheets.html for how to
customize this style sheet.
*/
/* used to remove borders from tables and images */
.borderless, table.borderless td, table.borderless th {
border: 0 }
table.borderless td, table.borderless th {
/* Override padding for "table.docutils td" with "! important".
The right padding separates the table cells. */
padding: 0 0.5em 0 0 ! important }
.first {
/* Override more specific margin styles with "! important". */
margin-top: 0 ! important }
.last, .with-subtitle {
margin-bottom: 0 ! important }
.hidden {
display: none }
.subscript {
vertical-align: sub;
font-size: smaller }
.superscript {
vertical-align: super;
font-size: smaller }
a.toc-backref {
text-decoration: none ;
color: black }
blockquote.epigraph {
margin: 2em 5em ; }
dl.docutils dd {
margin-bottom: 0.5em }
object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] {
overflow: hidden;
}
/* Uncomment (and remove this text!) to get bold-faced definition list terms
dl.docutils dt {
font-weight: bold }
*/
div.abstract {
margin: 2em 5em }
div.abstract p.topic-title {
font-weight: bold ;
text-align: center }
div.admonition, div.attention, div.caution, div.danger, div.error,
div.hint, div.important, div.note, div.tip, div.warning {
margin: 2em ;
border: medium outset ;
padding: 1em }
div.admonition p.admonition-title, div.hint p.admonition-title,
div.important p.admonition-title, div.note p.admonition-title,
div.tip p.admonition-title {
font-weight: bold ;
font-family: sans-serif }
div.attention p.admonition-title, div.caution p.admonition-title,
div.danger p.admonition-title, div.error p.admonition-title,
div.warning p.admonition-title, .code .error {
color: red ;
font-weight: bold ;
font-family: sans-serif }
/* Uncomment (and remove this text!) to get reduced vertical space in
compound paragraphs.
div.compound .compound-first, div.compound .compound-middle {
margin-bottom: 0.5em }
div.compound .compound-last, div.compound .compound-middle {
margin-top: 0.5em }
*/
div.dedication {
margin: 2em 5em ;
text-align: center ;
font-style: italic }
div.dedication p.topic-title {
font-weight: bold ;
font-style: normal }
div.figure {
margin-left: 2em ;
margin-right: 2em }
div.footer, div.header {
clear: both;
font-size: smaller }
div.line-block {
display: block ;
margin-top: 1em ;
margin-bottom: 1em }
div.line-block div.line-block {
margin-top: 0 ;
margin-bottom: 0 ;
margin-left: 1.5em }
div.sidebar {
margin: 0 0 0.5em 1em ;
border: medium outset ;
padding: 1em ;
background-color: #ffffee ;
width: 40% ;
float: right ;
clear: right }
div.sidebar p.rubric {
font-family: sans-serif ;
font-size: medium }
div.system-messages {
margin: 5em }
div.system-messages h1 {
color: red }
div.system-message {
border: medium outset ;
padding: 1em }
div.system-message p.system-message-title {
color: red ;
font-weight: bold }
div.topic {
margin: 2em }
h1.section-subtitle, h2.section-subtitle, h3.section-subtitle,
h4.section-subtitle, h5.section-subtitle, h6.section-subtitle {
margin-top: 0.4em }
h1.title {
text-align: center }
h2.subtitle {
text-align: center }
hr.docutils {
width: 75% }
img.align-left, .figure.align-left, object.align-left, table.align-left {
clear: left ;
float: left ;
margin-right: 1em }
img.align-right, .figure.align-right, object.align-right, table.align-right {
clear: right ;
float: right ;
margin-left: 1em }
img.align-center, .figure.align-center, object.align-center {
display: block;
margin-left: auto;
margin-right: auto;
}
table.align-center {
margin-left: auto;
margin-right: auto;
}
.align-left {
text-align: left }
.align-center {
clear: both ;
text-align: center }
.align-right {
text-align: right }
/* reset inner alignment in figures */
div.align-right {
text-align: inherit }
/* div.align-center * { */
/* text-align: left } */
.align-top {
vertical-align: top }
.align-middle {
vertical-align: middle }
.align-bottom {
vertical-align: bottom }
ol.simple, ul.simple {
margin-bottom: 1em }
ol.arabic {
list-style: decimal }
ol.loweralpha {
list-style: lower-alpha }
ol.upperalpha {
list-style: upper-alpha }
ol.lowerroman {
list-style: lower-roman }
ol.upperroman {
list-style: upper-roman }
p.attribution {
text-align: right ;
margin-left: 50% }
p.caption {
font-style: italic }
p.credits {
font-style: italic ;
font-size: smaller }
p.label {
white-space: nowrap }
p.rubric {
font-weight: bold ;
font-size: larger ;
color: maroon ;
text-align: center }
p.sidebar-title {
font-family: sans-serif ;
font-weight: bold ;
font-size: larger }
p.sidebar-subtitle {
font-family: sans-serif ;
font-weight: bold }
p.topic-title {
font-weight: bold }
pre.address {
margin-bottom: 0 ;
margin-top: 0 ;
font: inherit }
pre.literal-block, pre.doctest-block, pre.math, pre.code {
margin-left: 2em ;
margin-right: 2em }
pre.code .ln { color: grey; } /* line numbers */
pre.code, code { background-color: #eeeeee }
pre.code .comment, code .comment { color: #5C6576 }
pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold }
pre.code .literal.string, code .literal.string { color: #0C5404 }
pre.code .name.builtin, code .name.builtin { color: #352B84 }
pre.code .deleted, code .deleted { background-color: #DEB0A1}
pre.code .inserted, code .inserted { background-color: #A3D289}
span.classifier {
font-family: sans-serif ;
font-style: oblique }
span.classifier-delimiter {
font-family: sans-serif ;
font-weight: bold }
span.interpreted {
font-family: sans-serif }
span.option {
white-space: nowrap }
span.pre {
white-space: pre }
span.problematic {
color: red }
span.section-subtitle {
/* font-size relative to parent (h1..h6 element) */
font-size: 80% }
table.citation {
border-left: solid 1px gray;
margin-left: 1px }
table.docinfo {
margin: 2em 4em }
table.docutils {
margin-top: 0.5em ;
margin-bottom: 0.5em }
table.footnote {
border-left: solid 1px black;
margin-left: 1px }
table.docutils td, table.docutils th,
table.docinfo td, table.docinfo th {
padding-left: 0.5em ;
padding-right: 0.5em ;
vertical-align: top }
table.docutils th.field-name, table.docinfo th.docinfo-name {
font-weight: bold ;
text-align: left ;
white-space: nowrap ;
padding-left: 0 }
/* "booktabs" style (no vertical lines) */
table.docutils.booktabs {
border: 0px;
border-top: 2px solid;
border-bottom: 2px solid;
border-collapse: collapse;
}
table.docutils.booktabs * {
border: 0px;
}
table.docutils.booktabs th {
border-bottom: thin solid;
text-align: left;
}
h1 tt.docutils, h2 tt.docutils, h3 tt.docutils,
h4 tt.docutils, h5 tt.docutils, h6 tt.docutils {
font-size: 100% }
ul.auto-toc {
list-style-type: none }
</style>
</head>
<body>
<div class="document" id="web-domain-field">
<h1 class="title">Web Domain Field</h1>
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<p><a class="reference external" href="https://odoo-community.org/page/development-status"><img alt="Production/Stable" src="https://img.shields.io/badge/maturity-Production%2FStable-green.png" /></a> <a class="reference external" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external" href="https://github.com/OCA/web/tree/14.0/web_domain_field"><img alt="OCA/web" src="https://img.shields.io/badge/github-OCA%2Fweb-lightgray.png?logo=github" /></a> <a class="reference external" href="https://translation.odoo-community.org/projects/web-14-0/web-14-0-web_domain_field"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external" href="https://runbot.odoo-community.org/runbot/162/14.0"><img alt="Try me on Runbot" src="https://img.shields.io/badge/runbot-Try%20me-875A7B.png" /></a></p>
<p>When you define a view you can specify on the relational fields a domain
attribute. This attribute is evaluated as filter to apply when displaying
existing records for selection.</p>
<p><strong>Table of contents</strong></p>
<div class="contents local topic" id="contents">
<ul class="simple">
<li><a class="reference internal" href="#usage" id="id1">Usage</a></li>
<li><a class="reference internal" href="#bug-tracker" id="id2">Bug Tracker</a></li>
<li><a class="reference internal" href="#credits" id="id3">Credits</a><ul>
<li><a class="reference internal" href="#authors" id="id4">Authors</a></li>
<li><a class="reference internal" href="#contributors" id="id5">Contributors</a></li>
<li><a class="reference internal" href="#maintainers" id="id6">Maintainers</a></li>
</ul>
</li>
</ul>
</div>
<div class="section" id="usage">
<h1><a class="toc-backref" href="#id1">Usage</a></h1>
<p>When you define a view you can specify on the relational fields a domain
attribute. This attribute is evaluated as filter to apply when displaying
existing records for selection.</p>
<pre class="code xml literal-block">
<span class="nt">&lt;field</span> <span class="na">name=</span><span class="s">&quot;product_id&quot;</span> <span class="na">domain=</span><span class="s">&quot;[('type','=','product')]&quot;</span><span class="nt">/&gt;</span>
</pre>
<p>The value provided for the domain attribute must be a string representing a
valid Odoo domain. This string is evaluated on the client side in a
restricted context where we can reference as right operand the values of
fields present into the form and a limited set of functions.</p>
<p>In this context its hard to build complex domain and we are facing to some
limitations as:</p>
<blockquote>
<ul class="simple">
<li>The syntax to include in your domain a criteria involving values from a
x2many field is complex.</li>
<li>The right side of domain in case of x2many can involve huge amount of ids
(performance problem).</li>
<li>Domains computed by an onchange on an other field are not recomputed when
you modify the form and dont modify the field triggering the onchange.</li>
<li>Its not possible to extend an existing domain. You must completely redefine
the domain in your specialized addon</li>
<li>etc…</li>
</ul>
</blockquote>
<p>In order to mitigate these limitations this new addon allows you to use the
value of a field as domain of an other field in the xml definition of your
view.</p>
<pre class="code xml literal-block">
<span class="nt">&lt;field</span> <span class="na">name=</span><span class="s">&quot;product_id_domain&quot;</span> <span class="na">invisible=</span><span class="s">&quot;1&quot;</span><span class="nt">/&gt;</span>
<span class="nt">&lt;field</span> <span class="na">name=</span><span class="s">&quot;product_id&quot;</span> <span class="na">domain=</span><span class="s">&quot;product_id_domain&quot;</span><span class="nt">/&gt;</span>
</pre>
<p>The field used as domain must provide the domain as a JSON encoded string.</p>
<pre class="code python literal-block">
<span class="n">product_id_domain</span> <span class="o">=</span> <span class="n">fields</span><span class="o">.</span><span class="n">Char</span><span class="p">(</span>
<span class="n">compute</span><span class="o">=</span><span class="s2">&quot;_compute_product_id_domain&quot;</span><span class="p">,</span>
<span class="n">readonly</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span>
<span class="n">store</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
<span class="p">)</span>
<span class="nd">&#64;api</span><span class="o">.</span><span class="n">depends</span><span class="p">(</span><span class="s1">'name'</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">_compute_product_id_domain</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">for</span> <span class="n">rec</span> <span class="ow">in</span> <span class="bp">self</span><span class="p">:</span>
<span class="n">rec</span><span class="o">.</span><span class="n">product_id_domain</span> <span class="o">=</span> <span class="n">json</span><span class="o">.</span><span class="n">dumps</span><span class="p">(</span>
<span class="p">[(</span><span class="s1">'type'</span><span class="p">,</span> <span class="s1">'='</span><span class="p">,</span> <span class="s1">'product'</span><span class="p">),</span> <span class="p">(</span><span class="s1">'name'</span><span class="p">,</span> <span class="s1">'like'</span><span class="p">,</span> <span class="n">rec</span><span class="o">.</span><span class="n">name</span><span class="p">)]</span>
<span class="p">)</span>
</pre>
</div>
<div class="section" id="bug-tracker">
<h1><a class="toc-backref" href="#id2">Bug Tracker</a></h1>
<p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/web/issues">GitHub Issues</a>.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us smashing it by providing a detailed and welcomed
<a class="reference external" href="https://github.com/OCA/web/issues/new?body=module:%20web_domain_field%0Aversion:%2014.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p>
<p>Do not contact contributors directly about support or help with technical issues.</p>
</div>
<div class="section" id="credits">
<h1><a class="toc-backref" href="#id3">Credits</a></h1>
<div class="section" id="authors">
<h2><a class="toc-backref" href="#id4">Authors</a></h2>
<ul class="simple">
<li>ACSONE SA/NV</li>
</ul>
</div>
<div class="section" id="contributors">
<h2><a class="toc-backref" href="#id5">Contributors</a></h2>
<ul class="simple">
<li>Laurent Mignon &lt;<a class="reference external" href="mailto:laurent.mignon&#64;acsone.eu">laurent.mignon&#64;acsone.eu</a>&gt;</li>
<li>Denis Roussel &lt;<a class="reference external" href="mailto:denis.roussel&#64;acsone.eu">denis.roussel&#64;acsone.eu</a>&gt;</li>
<li>Raf Ven &lt;<a class="reference external" href="mailto:raf.ven&#64;dynapps.be">raf.ven&#64;dynapps.be</a>&gt;</li>
</ul>
</div>
<div class="section" id="maintainers">
<h2><a class="toc-backref" href="#id6">Maintainers</a></h2>
<p>This module is maintained by the OCA.</p>
<a class="reference external image-reference" href="https://odoo-community.org"><img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" /></a>
<p>OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.</p>
<p>This module is part of the <a class="reference external" href="https://github.com/OCA/web/tree/14.0/web_domain_field">OCA/web</a> project on GitHub.</p>
<p>You are welcome to contribute. To learn how please visit <a class="reference external" href="https://odoo-community.org/page/Contribute">https://odoo-community.org/page/Contribute</a>.</p>
</div>
</div>
</div>
</body>
</html>