From 949b8d31cd6d91bca2183291f8f2ef216f555520 Mon Sep 17 00:00:00 2001 From: Andrea Date: Mon, 6 Mar 2017 09:48:49 +0100 Subject: [PATCH] [MIG+IMP] bi_view_editor: Migration to v10 + enhancements * Add menu items creation feature * Added selection of fields of a tree view * Improved usability and strings made translatable * Avoid display duplicated nodes * Robustness * Updated Dutch translation * Avoid possible sql injection in bi_view_editor * Removed deprecated RegistryManager --- bi_view_editor/README.rst | 8 +- bi_view_editor/__init__.py | 1 + bi_view_editor/__manifest__.py | 7 +- bi_view_editor/i18n/am.po | 2 +- bi_view_editor/i18n/ar.po | 2 +- bi_view_editor/i18n/bg.po | 2 +- bi_view_editor/i18n/bs.po | 2 +- bi_view_editor/i18n/ca.po | 2 +- bi_view_editor/i18n/cs.po | 2 +- bi_view_editor/i18n/da.po | 2 +- bi_view_editor/i18n/de.po | 2 +- bi_view_editor/i18n/el_GR.po | 2 +- bi_view_editor/i18n/en_GB.po | 2 +- bi_view_editor/i18n/es.po | 2 +- bi_view_editor/i18n/es_AR.po | 2 +- bi_view_editor/i18n/es_CL.po | 2 +- bi_view_editor/i18n/es_CO.po | 2 +- bi_view_editor/i18n/es_CR.po | 2 +- bi_view_editor/i18n/es_DO.po | 2 +- bi_view_editor/i18n/es_EC.po | 2 +- bi_view_editor/i18n/es_ES.po | 2 +- bi_view_editor/i18n/es_MX.po | 2 +- bi_view_editor/i18n/es_PE.po | 2 +- bi_view_editor/i18n/es_PY.po | 2 +- bi_view_editor/i18n/es_VE.po | 2 +- bi_view_editor/i18n/et.po | 2 +- bi_view_editor/i18n/eu.po | 2 +- bi_view_editor/i18n/fa.po | 2 +- bi_view_editor/i18n/fi.po | 2 +- bi_view_editor/i18n/fr.po | 2 +- bi_view_editor/i18n/fr_CA.po | 2 +- bi_view_editor/i18n/fr_CH.po | 2 +- bi_view_editor/i18n/gl.po | 2 +- bi_view_editor/i18n/gl_ES.po | 2 +- bi_view_editor/i18n/he.po | 2 +- bi_view_editor/i18n/hr.po | 2 +- bi_view_editor/i18n/hr_HR.po | 2 +- bi_view_editor/i18n/hu.po | 2 +- bi_view_editor/i18n/id.po | 2 +- bi_view_editor/i18n/it.po | 2 +- bi_view_editor/i18n/ja.po | 2 +- bi_view_editor/i18n/ko.po | 2 +- bi_view_editor/i18n/lt.po | 2 +- bi_view_editor/i18n/lt_LT.po | 2 +- bi_view_editor/i18n/lv.po | 2 +- bi_view_editor/i18n/mk.po | 2 +- bi_view_editor/i18n/mn.po | 2 +- bi_view_editor/i18n/nb.po | 2 +- bi_view_editor/i18n/nb_NO.po | 2 +- bi_view_editor/i18n/nl.po | 66 +-- bi_view_editor/i18n/nl_BE.po | 2 +- bi_view_editor/i18n/pl.po | 2 +- bi_view_editor/i18n/pt.po | 2 +- bi_view_editor/i18n/pt_BR.po | 2 +- bi_view_editor/i18n/pt_PT.po | 2 +- bi_view_editor/i18n/ro.po | 2 +- bi_view_editor/i18n/ru.po | 2 +- bi_view_editor/i18n/sk.po | 2 +- bi_view_editor/i18n/sl.po | 2 +- bi_view_editor/i18n/sr.po | 2 +- bi_view_editor/i18n/sr@latin.po | 2 +- bi_view_editor/i18n/sv.po | 2 +- bi_view_editor/i18n/th.po | 2 +- bi_view_editor/i18n/tr.po | 2 +- bi_view_editor/i18n/tr_TR.po | 2 +- bi_view_editor/i18n/uk.po | 2 +- bi_view_editor/i18n/vi.po | 2 +- bi_view_editor/i18n/vi_VN.po | 2 +- bi_view_editor/i18n/zh_CN.po | 2 +- bi_view_editor/i18n/zh_TW.po | 2 +- bi_view_editor/models/__init__.py | 1 + bi_view_editor/models/bve_view.py | 426 ++++++++++-------- bi_view_editor/models/ir_model.py | 195 ++++---- bi_view_editor/models/models.py | 61 +++ bi_view_editor/security/ir.model.access.csv | 1 - bi_view_editor/static/src/js/bve.js | 172 ++++--- bi_view_editor/templates/qweb_template.xml | 8 +- bi_view_editor/tests/test_bi_view.py | 7 +- bi_view_editor/views/bve_view.xml | 1 + bi_view_editor/wizard/__init__.py | 5 + .../wizard/wizard_ir_model_menu_create.py | 39 ++ 81 files changed, 662 insertions(+), 468 deletions(-) mode change 100644 => 100755 bi_view_editor/i18n/nl.po create mode 100644 bi_view_editor/models/models.py create mode 100644 bi_view_editor/wizard/__init__.py create mode 100644 bi_view_editor/wizard/wizard_ir_model_menu_create.py diff --git a/bi_view_editor/README.rst b/bi_view_editor/README.rst index f347a1b7..66c2afbc 100644 --- a/bi_view_editor/README.rst +++ b/bi_view_editor/README.rst @@ -28,17 +28,18 @@ Usage To graphically design your analysis data-set: -- From the Reporting menu, select "Custom BI Views" +- From the Dashboards menu, select "Custom BI Views" - Browse trough the business objects in the Query tab - Pick the interesting fields (Drag & Drop) -- For each selected field, right-click on the Options column and select whether it's a row, column or measure +- For each selected field, right-click on the Options column and select whether it's a row, column or measure; if you want to remove the field from the list view, unflag the checkbox ´List´ in the Options column - Save and click "Generate BI View" - Click "Open BI View" to view the result - If module Dashboard (board) is installed, the standard "Add to My Dashboard" functionality would be available +- Click "Create a menu" to create a new menu item directly linked to your new BI view (this feature is available in developer mode); when the BI view is reset back to draft this menu will be removed, and you will need to re-create the menu entry. .. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas :alt: Try me on Runbot - :target: https://runbot.odoo-community.org/runbot/143/9.0 + :target: https://runbot.odoo-community.org/runbot/143/10.0 Known issues / Roadmap ====================== @@ -47,6 +48,7 @@ Known issues / Roadmap * Provide graph view for table relations * Extend the capabilities of the tree views (e.g. add sums) * Provide a tutorial (eg. a working example of usage) +* Implement a more advanced UI, with possibilities to use LEFT JOIN as default instead of INNER JOIN Bug Tracker =========== diff --git a/bi_view_editor/__init__.py b/bi_view_editor/__init__.py index d4da6d0f..2bd76b60 100644 --- a/bi_view_editor/__init__.py +++ b/bi_view_editor/__init__.py @@ -3,4 +3,5 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). from . import models +from . import wizard from .hooks import uninstall_hook diff --git a/bi_view_editor/__manifest__.py b/bi_view_editor/__manifest__.py index a2fa6f0e..94177ed9 100644 --- a/bi_view_editor/__manifest__.py +++ b/bi_view_editor/__manifest__.py @@ -10,7 +10,7 @@ 'license': 'AGPL-3', 'website': 'http://www.onestein.eu', 'category': 'Reporting', - 'version': '9.0.1.0.0', + 'version': '10.0.1.0.1', 'depends': [ 'base', 'web' @@ -24,9 +24,6 @@ 'qweb': [ 'templates/qweb_template.xml', ], - 'js': [ - 'static/src/js/bve.js' - ], - 'installable': False, + 'installable': True, 'uninstall_hook': 'uninstall_hook' } diff --git a/bi_view_editor/i18n/am.po b/bi_view_editor/i18n/am.po index 305a7273..d3d1c11c 100644 --- a/bi_view_editor/i18n/am.po +++ b/bi_view_editor/i18n/am.po @@ -180,7 +180,7 @@ msgstr "" #: help:bve.view,data:0 msgid "" "Use the special query builder to define the query to generate your report " -"dataset. NOTE: Te be edited, the query should be in 'Draft' status." +"dataset. NOTE: To be edited, the query should be in 'Draft' status." msgstr "" #. module: bi_view_editor diff --git a/bi_view_editor/i18n/ar.po b/bi_view_editor/i18n/ar.po index 66466c16..d78da9a8 100644 --- a/bi_view_editor/i18n/ar.po +++ b/bi_view_editor/i18n/ar.po @@ -180,7 +180,7 @@ msgstr "" #: help:bve.view,data:0 msgid "" "Use the special query builder to define the query to generate your report " -"dataset. NOTE: Te be edited, the query should be in 'Draft' status." +"dataset. NOTE: To be edited, the query should be in 'Draft' status." msgstr "" #. module: bi_view_editor diff --git a/bi_view_editor/i18n/bg.po b/bi_view_editor/i18n/bg.po index 68a45629..0af37f7d 100644 --- a/bi_view_editor/i18n/bg.po +++ b/bi_view_editor/i18n/bg.po @@ -180,7 +180,7 @@ msgstr "" #: help:bve.view,data:0 msgid "" "Use the special query builder to define the query to generate your report " -"dataset. NOTE: Te be edited, the query should be in 'Draft' status." +"dataset. NOTE: To be edited, the query should be in 'Draft' status." msgstr "" #. module: bi_view_editor diff --git a/bi_view_editor/i18n/bs.po b/bi_view_editor/i18n/bs.po index 440528cd..b60ca0fc 100644 --- a/bi_view_editor/i18n/bs.po +++ b/bi_view_editor/i18n/bs.po @@ -180,7 +180,7 @@ msgstr "" #: help:bve.view,data:0 msgid "" "Use the special query builder to define the query to generate your report " -"dataset. NOTE: Te be edited, the query should be in 'Draft' status." +"dataset. NOTE: To be edited, the query should be in 'Draft' status." msgstr "" #. module: bi_view_editor diff --git a/bi_view_editor/i18n/ca.po b/bi_view_editor/i18n/ca.po index 4670b0fb..379d2e38 100644 --- a/bi_view_editor/i18n/ca.po +++ b/bi_view_editor/i18n/ca.po @@ -180,7 +180,7 @@ msgstr "Estat" #: help:bve.view,data:0 msgid "" "Use the special query builder to define the query to generate your report " -"dataset. NOTE: Te be edited, the query should be in 'Draft' status." +"dataset. NOTE: To be edited, the query should be in 'Draft' status." msgstr "" #. module: bi_view_editor diff --git a/bi_view_editor/i18n/cs.po b/bi_view_editor/i18n/cs.po index 4d5e07d9..4ca499d0 100644 --- a/bi_view_editor/i18n/cs.po +++ b/bi_view_editor/i18n/cs.po @@ -180,7 +180,7 @@ msgstr "" #: help:bve.view,data:0 msgid "" "Use the special query builder to define the query to generate your report " -"dataset. NOTE: Te be edited, the query should be in 'Draft' status." +"dataset. NOTE: To be edited, the query should be in 'Draft' status." msgstr "" #. module: bi_view_editor diff --git a/bi_view_editor/i18n/da.po b/bi_view_editor/i18n/da.po index 3d2b578e..845ebf1e 100644 --- a/bi_view_editor/i18n/da.po +++ b/bi_view_editor/i18n/da.po @@ -180,7 +180,7 @@ msgstr "" #: help:bve.view,data:0 msgid "" "Use the special query builder to define the query to generate your report " -"dataset. NOTE: Te be edited, the query should be in 'Draft' status." +"dataset. NOTE: To be edited, the query should be in 'Draft' status." msgstr "" #. module: bi_view_editor diff --git a/bi_view_editor/i18n/de.po b/bi_view_editor/i18n/de.po index 467a3f8b..e0901591 100644 --- a/bi_view_editor/i18n/de.po +++ b/bi_view_editor/i18n/de.po @@ -180,7 +180,7 @@ msgstr "Status" #: help:bve.view,data:0 msgid "" "Use the special query builder to define the query to generate your report " -"dataset. NOTE: Te be edited, the query should be in 'Draft' status." +"dataset. NOTE: To be edited, the query should be in 'Draft' status." msgstr "" #. module: bi_view_editor diff --git a/bi_view_editor/i18n/el_GR.po b/bi_view_editor/i18n/el_GR.po index 0d92f28e..e049c9b5 100644 --- a/bi_view_editor/i18n/el_GR.po +++ b/bi_view_editor/i18n/el_GR.po @@ -180,7 +180,7 @@ msgstr "" #: help:bve.view,data:0 msgid "" "Use the special query builder to define the query to generate your report " -"dataset. NOTE: Te be edited, the query should be in 'Draft' status." +"dataset. NOTE: To be edited, the query should be in 'Draft' status." msgstr "" #. module: bi_view_editor diff --git a/bi_view_editor/i18n/en_GB.po b/bi_view_editor/i18n/en_GB.po index 3a815d91..c246b238 100644 --- a/bi_view_editor/i18n/en_GB.po +++ b/bi_view_editor/i18n/en_GB.po @@ -180,7 +180,7 @@ msgstr "" #: help:bve.view,data:0 msgid "" "Use the special query builder to define the query to generate your report " -"dataset. NOTE: Te be edited, the query should be in 'Draft' status." +"dataset. NOTE: To be edited, the query should be in 'Draft' status." msgstr "" #. module: bi_view_editor diff --git a/bi_view_editor/i18n/es.po b/bi_view_editor/i18n/es.po index fc13c890..bfe74bf5 100644 --- a/bi_view_editor/i18n/es.po +++ b/bi_view_editor/i18n/es.po @@ -181,7 +181,7 @@ msgstr "Estado" #: help:bve.view,data:0 msgid "" "Use the special query builder to define the query to generate your report " -"dataset. NOTE: Te be edited, the query should be in 'Draft' status." +"dataset. NOTE: To be edited, the query should be in 'Draft' status." msgstr "Usa el constructor especial de consultas para definir la consulta del informe de datos. NOTA: para ser editada, la consulta debe estar en estado 'Borrador'" #. module: bi_view_editor diff --git a/bi_view_editor/i18n/es_AR.po b/bi_view_editor/i18n/es_AR.po index 09e10c71..32c9ac50 100644 --- a/bi_view_editor/i18n/es_AR.po +++ b/bi_view_editor/i18n/es_AR.po @@ -180,7 +180,7 @@ msgstr "" #: help:bve.view,data:0 msgid "" "Use the special query builder to define the query to generate your report " -"dataset. NOTE: Te be edited, the query should be in 'Draft' status." +"dataset. NOTE: To be edited, the query should be in 'Draft' status." msgstr "" #. module: bi_view_editor diff --git a/bi_view_editor/i18n/es_CL.po b/bi_view_editor/i18n/es_CL.po index 86f7d687..bc40b717 100644 --- a/bi_view_editor/i18n/es_CL.po +++ b/bi_view_editor/i18n/es_CL.po @@ -180,7 +180,7 @@ msgstr "" #: help:bve.view,data:0 msgid "" "Use the special query builder to define the query to generate your report " -"dataset. NOTE: Te be edited, the query should be in 'Draft' status." +"dataset. NOTE: To be edited, the query should be in 'Draft' status." msgstr "" #. module: bi_view_editor diff --git a/bi_view_editor/i18n/es_CO.po b/bi_view_editor/i18n/es_CO.po index 4e32d4d9..378f04fb 100644 --- a/bi_view_editor/i18n/es_CO.po +++ b/bi_view_editor/i18n/es_CO.po @@ -180,7 +180,7 @@ msgstr "" #: help:bve.view,data:0 msgid "" "Use the special query builder to define the query to generate your report " -"dataset. NOTE: Te be edited, the query should be in 'Draft' status." +"dataset. NOTE: To be edited, the query should be in 'Draft' status." msgstr "" #. module: bi_view_editor diff --git a/bi_view_editor/i18n/es_CR.po b/bi_view_editor/i18n/es_CR.po index 0a6aae1d..998c4140 100644 --- a/bi_view_editor/i18n/es_CR.po +++ b/bi_view_editor/i18n/es_CR.po @@ -180,7 +180,7 @@ msgstr "" #: help:bve.view,data:0 msgid "" "Use the special query builder to define the query to generate your report " -"dataset. NOTE: Te be edited, the query should be in 'Draft' status." +"dataset. NOTE: To be edited, the query should be in 'Draft' status." msgstr "" #. module: bi_view_editor diff --git a/bi_view_editor/i18n/es_DO.po b/bi_view_editor/i18n/es_DO.po index d7667082..63cee89f 100644 --- a/bi_view_editor/i18n/es_DO.po +++ b/bi_view_editor/i18n/es_DO.po @@ -180,7 +180,7 @@ msgstr "" #: help:bve.view,data:0 msgid "" "Use the special query builder to define the query to generate your report " -"dataset. NOTE: Te be edited, the query should be in 'Draft' status." +"dataset. NOTE: To be edited, the query should be in 'Draft' status." msgstr "" #. module: bi_view_editor diff --git a/bi_view_editor/i18n/es_EC.po b/bi_view_editor/i18n/es_EC.po index e912e08e..aac7c9b2 100644 --- a/bi_view_editor/i18n/es_EC.po +++ b/bi_view_editor/i18n/es_EC.po @@ -180,7 +180,7 @@ msgstr "" #: help:bve.view,data:0 msgid "" "Use the special query builder to define the query to generate your report " -"dataset. NOTE: Te be edited, the query should be in 'Draft' status." +"dataset. NOTE: To be edited, the query should be in 'Draft' status." msgstr "" #. module: bi_view_editor diff --git a/bi_view_editor/i18n/es_ES.po b/bi_view_editor/i18n/es_ES.po index 1e70ae1d..4be82873 100644 --- a/bi_view_editor/i18n/es_ES.po +++ b/bi_view_editor/i18n/es_ES.po @@ -180,7 +180,7 @@ msgstr "" #: help:bve.view,data:0 msgid "" "Use the special query builder to define the query to generate your report " -"dataset. NOTE: Te be edited, the query should be in 'Draft' status." +"dataset. NOTE: To be edited, the query should be in 'Draft' status." msgstr "" #. module: bi_view_editor diff --git a/bi_view_editor/i18n/es_MX.po b/bi_view_editor/i18n/es_MX.po index 42e5d6f5..f78e1714 100644 --- a/bi_view_editor/i18n/es_MX.po +++ b/bi_view_editor/i18n/es_MX.po @@ -180,7 +180,7 @@ msgstr "" #: help:bve.view,data:0 msgid "" "Use the special query builder to define the query to generate your report " -"dataset. NOTE: Te be edited, the query should be in 'Draft' status." +"dataset. NOTE: To be edited, the query should be in 'Draft' status." msgstr "" #. module: bi_view_editor diff --git a/bi_view_editor/i18n/es_PE.po b/bi_view_editor/i18n/es_PE.po index eb3368fe..094495bd 100644 --- a/bi_view_editor/i18n/es_PE.po +++ b/bi_view_editor/i18n/es_PE.po @@ -180,7 +180,7 @@ msgstr "" #: help:bve.view,data:0 msgid "" "Use the special query builder to define the query to generate your report " -"dataset. NOTE: Te be edited, the query should be in 'Draft' status." +"dataset. NOTE: To be edited, the query should be in 'Draft' status." msgstr "" #. module: bi_view_editor diff --git a/bi_view_editor/i18n/es_PY.po b/bi_view_editor/i18n/es_PY.po index 65bf63e9..9212daee 100644 --- a/bi_view_editor/i18n/es_PY.po +++ b/bi_view_editor/i18n/es_PY.po @@ -180,7 +180,7 @@ msgstr "" #: help:bve.view,data:0 msgid "" "Use the special query builder to define the query to generate your report " -"dataset. NOTE: Te be edited, the query should be in 'Draft' status." +"dataset. NOTE: To be edited, the query should be in 'Draft' status." msgstr "" #. module: bi_view_editor diff --git a/bi_view_editor/i18n/es_VE.po b/bi_view_editor/i18n/es_VE.po index 51b1a5e9..941f4b0e 100644 --- a/bi_view_editor/i18n/es_VE.po +++ b/bi_view_editor/i18n/es_VE.po @@ -180,7 +180,7 @@ msgstr "" #: help:bve.view,data:0 msgid "" "Use the special query builder to define the query to generate your report " -"dataset. NOTE: Te be edited, the query should be in 'Draft' status." +"dataset. NOTE: To be edited, the query should be in 'Draft' status." msgstr "" #. module: bi_view_editor diff --git a/bi_view_editor/i18n/et.po b/bi_view_editor/i18n/et.po index 15ea8a01..db1e0edc 100644 --- a/bi_view_editor/i18n/et.po +++ b/bi_view_editor/i18n/et.po @@ -180,7 +180,7 @@ msgstr "" #: help:bve.view,data:0 msgid "" "Use the special query builder to define the query to generate your report " -"dataset. NOTE: Te be edited, the query should be in 'Draft' status." +"dataset. NOTE: To be edited, the query should be in 'Draft' status." msgstr "" #. module: bi_view_editor diff --git a/bi_view_editor/i18n/eu.po b/bi_view_editor/i18n/eu.po index eac53734..8887a23c 100644 --- a/bi_view_editor/i18n/eu.po +++ b/bi_view_editor/i18n/eu.po @@ -180,7 +180,7 @@ msgstr "" #: help:bve.view,data:0 msgid "" "Use the special query builder to define the query to generate your report " -"dataset. NOTE: Te be edited, the query should be in 'Draft' status." +"dataset. NOTE: To be edited, the query should be in 'Draft' status." msgstr "" #. module: bi_view_editor diff --git a/bi_view_editor/i18n/fa.po b/bi_view_editor/i18n/fa.po index fee56cbe..198cd3d4 100644 --- a/bi_view_editor/i18n/fa.po +++ b/bi_view_editor/i18n/fa.po @@ -180,7 +180,7 @@ msgstr "" #: help:bve.view,data:0 msgid "" "Use the special query builder to define the query to generate your report " -"dataset. NOTE: Te be edited, the query should be in 'Draft' status." +"dataset. NOTE: To be edited, the query should be in 'Draft' status." msgstr "" #. module: bi_view_editor diff --git a/bi_view_editor/i18n/fi.po b/bi_view_editor/i18n/fi.po index fcb56681..bf1693d0 100644 --- a/bi_view_editor/i18n/fi.po +++ b/bi_view_editor/i18n/fi.po @@ -180,7 +180,7 @@ msgstr "Tila" #: help:bve.view,data:0 msgid "" "Use the special query builder to define the query to generate your report " -"dataset. NOTE: Te be edited, the query should be in 'Draft' status." +"dataset. NOTE: To be edited, the query should be in 'Draft' status." msgstr "" #. module: bi_view_editor diff --git a/bi_view_editor/i18n/fr.po b/bi_view_editor/i18n/fr.po index 3b301d72..20d9b833 100644 --- a/bi_view_editor/i18n/fr.po +++ b/bi_view_editor/i18n/fr.po @@ -180,7 +180,7 @@ msgstr "État" #: help:bve.view,data:0 msgid "" "Use the special query builder to define the query to generate your report " -"dataset. NOTE: Te be edited, the query should be in 'Draft' status." +"dataset. NOTE: To be edited, the query should be in 'Draft' status." msgstr "" #. module: bi_view_editor diff --git a/bi_view_editor/i18n/fr_CA.po b/bi_view_editor/i18n/fr_CA.po index 9d21e22d..6570510d 100644 --- a/bi_view_editor/i18n/fr_CA.po +++ b/bi_view_editor/i18n/fr_CA.po @@ -180,7 +180,7 @@ msgstr "" #: help:bve.view,data:0 msgid "" "Use the special query builder to define the query to generate your report " -"dataset. NOTE: Te be edited, the query should be in 'Draft' status." +"dataset. NOTE: To be edited, the query should be in 'Draft' status." msgstr "" #. module: bi_view_editor diff --git a/bi_view_editor/i18n/fr_CH.po b/bi_view_editor/i18n/fr_CH.po index 46ee3dd2..4c4c3b5c 100644 --- a/bi_view_editor/i18n/fr_CH.po +++ b/bi_view_editor/i18n/fr_CH.po @@ -180,7 +180,7 @@ msgstr "État" #: help:bve.view,data:0 msgid "" "Use the special query builder to define the query to generate your report " -"dataset. NOTE: Te be edited, the query should be in 'Draft' status." +"dataset. NOTE: To be edited, the query should be in 'Draft' status." msgstr "" #. module: bi_view_editor diff --git a/bi_view_editor/i18n/gl.po b/bi_view_editor/i18n/gl.po index 886ead88..81ce00a0 100644 --- a/bi_view_editor/i18n/gl.po +++ b/bi_view_editor/i18n/gl.po @@ -180,7 +180,7 @@ msgstr "" #: help:bve.view,data:0 msgid "" "Use the special query builder to define the query to generate your report " -"dataset. NOTE: Te be edited, the query should be in 'Draft' status." +"dataset. NOTE: To be edited, the query should be in 'Draft' status." msgstr "" #. module: bi_view_editor diff --git a/bi_view_editor/i18n/gl_ES.po b/bi_view_editor/i18n/gl_ES.po index f4771006..5ea4a4a2 100644 --- a/bi_view_editor/i18n/gl_ES.po +++ b/bi_view_editor/i18n/gl_ES.po @@ -180,7 +180,7 @@ msgstr "" #: help:bve.view,data:0 msgid "" "Use the special query builder to define the query to generate your report " -"dataset. NOTE: Te be edited, the query should be in 'Draft' status." +"dataset. NOTE: To be edited, the query should be in 'Draft' status." msgstr "" #. module: bi_view_editor diff --git a/bi_view_editor/i18n/he.po b/bi_view_editor/i18n/he.po index 31faf6f6..9fd527ec 100644 --- a/bi_view_editor/i18n/he.po +++ b/bi_view_editor/i18n/he.po @@ -180,7 +180,7 @@ msgstr "" #: help:bve.view,data:0 msgid "" "Use the special query builder to define the query to generate your report " -"dataset. NOTE: Te be edited, the query should be in 'Draft' status." +"dataset. NOTE: To be edited, the query should be in 'Draft' status." msgstr "" #. module: bi_view_editor diff --git a/bi_view_editor/i18n/hr.po b/bi_view_editor/i18n/hr.po index 0329f30e..56bea157 100644 --- a/bi_view_editor/i18n/hr.po +++ b/bi_view_editor/i18n/hr.po @@ -180,7 +180,7 @@ msgstr "Status" #: help:bve.view,data:0 msgid "" "Use the special query builder to define the query to generate your report " -"dataset. NOTE: Te be edited, the query should be in 'Draft' status." +"dataset. NOTE: To be edited, the query should be in 'Draft' status." msgstr "" #. module: bi_view_editor diff --git a/bi_view_editor/i18n/hr_HR.po b/bi_view_editor/i18n/hr_HR.po index 9963a373..34958ccf 100644 --- a/bi_view_editor/i18n/hr_HR.po +++ b/bi_view_editor/i18n/hr_HR.po @@ -180,7 +180,7 @@ msgstr "" #: help:bve.view,data:0 msgid "" "Use the special query builder to define the query to generate your report " -"dataset. NOTE: Te be edited, the query should be in 'Draft' status." +"dataset. NOTE: To be edited, the query should be in 'Draft' status." msgstr "" #. module: bi_view_editor diff --git a/bi_view_editor/i18n/hu.po b/bi_view_editor/i18n/hu.po index 38411b6c..da368444 100644 --- a/bi_view_editor/i18n/hu.po +++ b/bi_view_editor/i18n/hu.po @@ -180,7 +180,7 @@ msgstr "" #: help:bve.view,data:0 msgid "" "Use the special query builder to define the query to generate your report " -"dataset. NOTE: Te be edited, the query should be in 'Draft' status." +"dataset. NOTE: To be edited, the query should be in 'Draft' status." msgstr "" #. module: bi_view_editor diff --git a/bi_view_editor/i18n/id.po b/bi_view_editor/i18n/id.po index 41384bc3..1c03bbdc 100644 --- a/bi_view_editor/i18n/id.po +++ b/bi_view_editor/i18n/id.po @@ -180,7 +180,7 @@ msgstr "" #: help:bve.view,data:0 msgid "" "Use the special query builder to define the query to generate your report " -"dataset. NOTE: Te be edited, the query should be in 'Draft' status." +"dataset. NOTE: To be edited, the query should be in 'Draft' status." msgstr "" #. module: bi_view_editor diff --git a/bi_view_editor/i18n/it.po b/bi_view_editor/i18n/it.po index 5a33e030..455486e9 100644 --- a/bi_view_editor/i18n/it.po +++ b/bi_view_editor/i18n/it.po @@ -180,7 +180,7 @@ msgstr "Stato" #: help:bve.view,data:0 msgid "" "Use the special query builder to define the query to generate your report " -"dataset. NOTE: Te be edited, the query should be in 'Draft' status." +"dataset. NOTE: To be edited, the query should be in 'Draft' status." msgstr "" #. module: bi_view_editor diff --git a/bi_view_editor/i18n/ja.po b/bi_view_editor/i18n/ja.po index adfe2377..aa1f66f7 100644 --- a/bi_view_editor/i18n/ja.po +++ b/bi_view_editor/i18n/ja.po @@ -180,7 +180,7 @@ msgstr "" #: help:bve.view,data:0 msgid "" "Use the special query builder to define the query to generate your report " -"dataset. NOTE: Te be edited, the query should be in 'Draft' status." +"dataset. NOTE: To be edited, the query should be in 'Draft' status." msgstr "" #. module: bi_view_editor diff --git a/bi_view_editor/i18n/ko.po b/bi_view_editor/i18n/ko.po index 23ee1627..d6aadac6 100644 --- a/bi_view_editor/i18n/ko.po +++ b/bi_view_editor/i18n/ko.po @@ -180,7 +180,7 @@ msgstr "" #: help:bve.view,data:0 msgid "" "Use the special query builder to define the query to generate your report " -"dataset. NOTE: Te be edited, the query should be in 'Draft' status." +"dataset. NOTE: To be edited, the query should be in 'Draft' status." msgstr "" #. module: bi_view_editor diff --git a/bi_view_editor/i18n/lt.po b/bi_view_editor/i18n/lt.po index 8bef66e5..d0ada9a7 100644 --- a/bi_view_editor/i18n/lt.po +++ b/bi_view_editor/i18n/lt.po @@ -180,7 +180,7 @@ msgstr "" #: help:bve.view,data:0 msgid "" "Use the special query builder to define the query to generate your report " -"dataset. NOTE: Te be edited, the query should be in 'Draft' status." +"dataset. NOTE: To be edited, the query should be in 'Draft' status." msgstr "" #. module: bi_view_editor diff --git a/bi_view_editor/i18n/lt_LT.po b/bi_view_editor/i18n/lt_LT.po index be8670c2..95d218ec 100644 --- a/bi_view_editor/i18n/lt_LT.po +++ b/bi_view_editor/i18n/lt_LT.po @@ -180,7 +180,7 @@ msgstr "" #: help:bve.view,data:0 msgid "" "Use the special query builder to define the query to generate your report " -"dataset. NOTE: Te be edited, the query should be in 'Draft' status." +"dataset. NOTE: To be edited, the query should be in 'Draft' status." msgstr "" #. module: bi_view_editor diff --git a/bi_view_editor/i18n/lv.po b/bi_view_editor/i18n/lv.po index 910ddf9e..2c281b66 100644 --- a/bi_view_editor/i18n/lv.po +++ b/bi_view_editor/i18n/lv.po @@ -180,7 +180,7 @@ msgstr "" #: help:bve.view,data:0 msgid "" "Use the special query builder to define the query to generate your report " -"dataset. NOTE: Te be edited, the query should be in 'Draft' status." +"dataset. NOTE: To be edited, the query should be in 'Draft' status." msgstr "" #. module: bi_view_editor diff --git a/bi_view_editor/i18n/mk.po b/bi_view_editor/i18n/mk.po index e35012f3..5cf131da 100644 --- a/bi_view_editor/i18n/mk.po +++ b/bi_view_editor/i18n/mk.po @@ -180,7 +180,7 @@ msgstr "" #: help:bve.view,data:0 msgid "" "Use the special query builder to define the query to generate your report " -"dataset. NOTE: Te be edited, the query should be in 'Draft' status." +"dataset. NOTE: To be edited, the query should be in 'Draft' status." msgstr "" #. module: bi_view_editor diff --git a/bi_view_editor/i18n/mn.po b/bi_view_editor/i18n/mn.po index 01b169dd..acecd003 100644 --- a/bi_view_editor/i18n/mn.po +++ b/bi_view_editor/i18n/mn.po @@ -180,7 +180,7 @@ msgstr "" #: help:bve.view,data:0 msgid "" "Use the special query builder to define the query to generate your report " -"dataset. NOTE: Te be edited, the query should be in 'Draft' status." +"dataset. NOTE: To be edited, the query should be in 'Draft' status." msgstr "" #. module: bi_view_editor diff --git a/bi_view_editor/i18n/nb.po b/bi_view_editor/i18n/nb.po index d8c8510c..27c5738d 100644 --- a/bi_view_editor/i18n/nb.po +++ b/bi_view_editor/i18n/nb.po @@ -180,7 +180,7 @@ msgstr "" #: help:bve.view,data:0 msgid "" "Use the special query builder to define the query to generate your report " -"dataset. NOTE: Te be edited, the query should be in 'Draft' status." +"dataset. NOTE: To be edited, the query should be in 'Draft' status." msgstr "" #. module: bi_view_editor diff --git a/bi_view_editor/i18n/nb_NO.po b/bi_view_editor/i18n/nb_NO.po index 512e6ff6..09cff7e0 100644 --- a/bi_view_editor/i18n/nb_NO.po +++ b/bi_view_editor/i18n/nb_NO.po @@ -180,7 +180,7 @@ msgstr "" #: help:bve.view,data:0 msgid "" "Use the special query builder to define the query to generate your report " -"dataset. NOTE: Te be edited, the query should be in 'Draft' status." +"dataset. NOTE: To be edited, the query should be in 'Draft' status." msgstr "" #. module: bi_view_editor diff --git a/bi_view_editor/i18n/nl.po b/bi_view_editor/i18n/nl.po old mode 100644 new mode 100755 index a2bad31a..4007bba6 --- a/bi_view_editor/i18n/nl.po +++ b/bi_view_editor/i18n/nl.po @@ -1,16 +1,17 @@ # Translation of Odoo Server. # This file contains the translation of the following modules: # * bi_view_editor -# +# # Translators: msgid "" msgstr "" "Project-Id-Version: reporting-engine (8.0)\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2017-01-07 05:41+0000\n" -"PO-Revision-Date: 2016-03-21 15:33+0000\n" +"PO-Revision-Date: 2017-03-14 19:54+0100\n" "Last-Translator: <>\n" -"Language-Team: Dutch (http://www.transifex.com/oca/OCA-reporting-engine-8-0/language/nl/)\n" +"Language-Team: Dutch (http://www.transifex.com/oca/OCA-reporting-engine-10-0/" +"language/nl/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: \n" @@ -27,21 +28,27 @@ msgid "" "

\n" " " msgstr "" +"

\n" +" Klik om een nieuwe custom query object te maken.\n" +"

\n" +"\n" +"

\n" +" " #. module: bi_view_editor #: field:bve.view,action_id:0 msgid "Action" -msgstr "" +msgstr "Actie" #. module: bi_view_editor #: model:ir.model,name:bi_view_editor.model_bve_view msgid "BI View Editor" -msgstr "" +msgstr "BI Weergave bewerker" #. module: bi_view_editor #: selection:bve.view,state:0 msgid "Created" -msgstr "" +msgstr "Aangemaakt" #. module: bi_view_editor #: field:bve.view,create_uid:0 @@ -56,33 +63,33 @@ msgstr "Aangemaakt op" #. module: bi_view_editor #: view:bve.view:bi_view_editor.view_bi_view_editor_view_tree msgid "Custom BI View" -msgstr "" +msgstr "Aangepaste BI Weergave" #. module: bi_view_editor #: sql_constraint:bve.view:0 msgid "Custom BI View names must be unique!" -msgstr "" +msgstr "Aangepaste BI Weergave moet uniek zijn!" #. module: bi_view_editor #: model:ir.actions.act_window,name:bi_view_editor.action_bi_view_editor_view_form #: model:ir.ui.menu,name:bi_view_editor.menu_bi_view_editor_view msgid "Custom BI Views" -msgstr "" +msgstr "Aangepaste BI Weergaves" #. module: bi_view_editor #: view:bve.view:bi_view_editor.view_bi_view_editor_view_form msgid "Custom Object" -msgstr "" +msgstr "Aangepast object" #. module: bi_view_editor #: model:ir.ui.menu,name:bi_view_editor.menu_bi_view_editor_custom_reports msgid "Custom Reports" -msgstr "" +msgstr "Aangepaste rapporten" #. module: bi_view_editor #: field:bve.view,data:0 msgid "Data" -msgstr "" +msgstr "Data" #. module: bi_view_editor #: field:bve.view,display_name:0 @@ -92,23 +99,23 @@ msgstr "Te tonen naam" #. module: bi_view_editor #: selection:bve.view,state:0 msgid "Draft" -msgstr "" +msgstr "Concept" #. module: bi_view_editor #: code:addons/bi_view_editor/models/bve_view.py:72 #, python-format msgid "Error" -msgstr "" +msgstr "Fout" #. module: bi_view_editor #: view:bve.view:bi_view_editor.view_bi_view_editor_view_form msgid "Generate BI View" -msgstr "" +msgstr "Genereer BI Weergave" #. module: bi_view_editor #: field:bve.view,group_ids:0 msgid "Groups" -msgstr "" +msgstr "Groepen" #. module: bi_view_editor #: field:bve.view,id:0 @@ -133,12 +140,12 @@ msgstr "Laatst bijgewerkt op" #. module: bi_view_editor #: field:bve.view,model_name:0 msgid "Model Name" -msgstr "" +msgstr "Model naam" #. module: bi_view_editor #: model:ir.model,name:bi_view_editor.model_ir_model msgid "Models" -msgstr "" +msgstr "Modellen" #. module: bi_view_editor #: field:bve.view,name:0 @@ -149,39 +156,42 @@ msgstr "Naam" #: view:bve.view:bi_view_editor.view_bi_view_editor_view_form #: field:bve.view,note:0 msgid "Notes" -msgstr "" +msgstr "Notities" #. module: bi_view_editor #: view:bve.view:bi_view_editor.view_bi_view_editor_view_form msgid "Open BI View" -msgstr "" +msgstr "Open BI Weergave" #. module: bi_view_editor #: view:bve.view:bi_view_editor.view_bi_view_editor_view_form msgid "Query" -msgstr "" +msgstr "Query" #. module: bi_view_editor #: view:bve.view:bi_view_editor.view_bi_view_editor_view_form msgid "Reset to Draft" -msgstr "" +msgstr "Terug naar concept" #. module: bi_view_editor #: view:bve.view:bi_view_editor.view_bi_view_editor_view_form msgid "Security" -msgstr "" +msgstr "Beveiliging" #. module: bi_view_editor #: field:bve.view,state:0 msgid "State" -msgstr "" +msgstr "Status" #. module: bi_view_editor #: help:bve.view,data:0 msgid "" "Use the special query builder to define the query to generate your report " -"dataset. NOTE: Te be edited, the query should be in 'Draft' status." +"dataset. NOTE: To be edited, the query should be in 'Draft' status." msgstr "" +"Gebruik de speciale query bouwer om queries te definiëren voor uw " +"rapportage dataset. LET OP: Om te bewerken moet de query in de 'Concept\" " +"status zijn. " #. module: bi_view_editor #: help:bve.view,group_ids:0 @@ -189,6 +199,8 @@ msgid "" "User groups allowed to see the generated report; if NO groups are specified " "the report will be public for everyone." msgstr "" +"Gebruikers groepen die de gegenereerde rapporten kunnen zijn; wanneer geen " +"groepen ingesteld zijn is het rapport zichtbaar voor alle gebruikers." #. module: bi_view_editor #: field:bve.view,user_ids:0 @@ -198,10 +210,12 @@ msgstr "Gebruikers" #. module: bi_view_editor #: field:bve.view,view_id:0 msgid "View" -msgstr "" +msgstr "Weergave" #. module: bi_view_editor #: code:addons/bi_view_editor/models/bve_view.py:73 #, python-format msgid "You cannot delete a created view! Reset the view to draft first." msgstr "" +"U kunt een aangemaakte weergave niet verwijderen. Reset de weergave eerst " +"naar de concept fase." diff --git a/bi_view_editor/i18n/nl_BE.po b/bi_view_editor/i18n/nl_BE.po index b9a8059a..d5e5b75d 100644 --- a/bi_view_editor/i18n/nl_BE.po +++ b/bi_view_editor/i18n/nl_BE.po @@ -180,7 +180,7 @@ msgstr "" #: help:bve.view,data:0 msgid "" "Use the special query builder to define the query to generate your report " -"dataset. NOTE: Te be edited, the query should be in 'Draft' status." +"dataset. NOTE: To be edited, the query should be in 'Draft' status." msgstr "" #. module: bi_view_editor diff --git a/bi_view_editor/i18n/pl.po b/bi_view_editor/i18n/pl.po index afc9cee7..037a1276 100644 --- a/bi_view_editor/i18n/pl.po +++ b/bi_view_editor/i18n/pl.po @@ -180,7 +180,7 @@ msgstr "" #: help:bve.view,data:0 msgid "" "Use the special query builder to define the query to generate your report " -"dataset. NOTE: Te be edited, the query should be in 'Draft' status." +"dataset. NOTE: To be edited, the query should be in 'Draft' status." msgstr "" #. module: bi_view_editor diff --git a/bi_view_editor/i18n/pt.po b/bi_view_editor/i18n/pt.po index b5c9df90..dc147d5c 100644 --- a/bi_view_editor/i18n/pt.po +++ b/bi_view_editor/i18n/pt.po @@ -180,7 +180,7 @@ msgstr "" #: help:bve.view,data:0 msgid "" "Use the special query builder to define the query to generate your report " -"dataset. NOTE: Te be edited, the query should be in 'Draft' status." +"dataset. NOTE: To be edited, the query should be in 'Draft' status." msgstr "" #. module: bi_view_editor diff --git a/bi_view_editor/i18n/pt_BR.po b/bi_view_editor/i18n/pt_BR.po index 1b63df7f..7f722449 100644 --- a/bi_view_editor/i18n/pt_BR.po +++ b/bi_view_editor/i18n/pt_BR.po @@ -180,7 +180,7 @@ msgstr "Estado" #: help:bve.view,data:0 msgid "" "Use the special query builder to define the query to generate your report " -"dataset. NOTE: Te be edited, the query should be in 'Draft' status." +"dataset. NOTE: To be edited, the query should be in 'Draft' status." msgstr "" #. module: bi_view_editor diff --git a/bi_view_editor/i18n/pt_PT.po b/bi_view_editor/i18n/pt_PT.po index 979fa271..79580352 100644 --- a/bi_view_editor/i18n/pt_PT.po +++ b/bi_view_editor/i18n/pt_PT.po @@ -180,7 +180,7 @@ msgstr "" #: help:bve.view,data:0 msgid "" "Use the special query builder to define the query to generate your report " -"dataset. NOTE: Te be edited, the query should be in 'Draft' status." +"dataset. NOTE: To be edited, the query should be in 'Draft' status." msgstr "" #. module: bi_view_editor diff --git a/bi_view_editor/i18n/ro.po b/bi_view_editor/i18n/ro.po index 36d89903..50b9663c 100644 --- a/bi_view_editor/i18n/ro.po +++ b/bi_view_editor/i18n/ro.po @@ -180,7 +180,7 @@ msgstr "" #: help:bve.view,data:0 msgid "" "Use the special query builder to define the query to generate your report " -"dataset. NOTE: Te be edited, the query should be in 'Draft' status." +"dataset. NOTE: To be edited, the query should be in 'Draft' status." msgstr "" #. module: bi_view_editor diff --git a/bi_view_editor/i18n/ru.po b/bi_view_editor/i18n/ru.po index e7a49dc5..944b78fd 100644 --- a/bi_view_editor/i18n/ru.po +++ b/bi_view_editor/i18n/ru.po @@ -180,7 +180,7 @@ msgstr "" #: help:bve.view,data:0 msgid "" "Use the special query builder to define the query to generate your report " -"dataset. NOTE: Te be edited, the query should be in 'Draft' status." +"dataset. NOTE: To be edited, the query should be in 'Draft' status." msgstr "" #. module: bi_view_editor diff --git a/bi_view_editor/i18n/sk.po b/bi_view_editor/i18n/sk.po index 8c22a58b..2bc6810d 100644 --- a/bi_view_editor/i18n/sk.po +++ b/bi_view_editor/i18n/sk.po @@ -180,7 +180,7 @@ msgstr "" #: help:bve.view,data:0 msgid "" "Use the special query builder to define the query to generate your report " -"dataset. NOTE: Te be edited, the query should be in 'Draft' status." +"dataset. NOTE: To be edited, the query should be in 'Draft' status." msgstr "" #. module: bi_view_editor diff --git a/bi_view_editor/i18n/sl.po b/bi_view_editor/i18n/sl.po index 18b00f22..4186abe1 100644 --- a/bi_view_editor/i18n/sl.po +++ b/bi_view_editor/i18n/sl.po @@ -181,7 +181,7 @@ msgstr "Stanje" #: help:bve.view,data:0 msgid "" "Use the special query builder to define the query to generate your report " -"dataset. NOTE: Te be edited, the query should be in 'Draft' status." +"dataset. NOTE: To be edited, the query should be in 'Draft' status." msgstr "Uporabite posebni gradnik poizvedb za določanje poizvedbe, ki bo ustvarila poročilo z vašim naborom podatkov. OPOMBA: Urejate lahko le poizvedbe s statusom 'Osnutek'." #. module: bi_view_editor diff --git a/bi_view_editor/i18n/sr.po b/bi_view_editor/i18n/sr.po index 5cbf2b1f..1c2969a5 100644 --- a/bi_view_editor/i18n/sr.po +++ b/bi_view_editor/i18n/sr.po @@ -180,7 +180,7 @@ msgstr "" #: help:bve.view,data:0 msgid "" "Use the special query builder to define the query to generate your report " -"dataset. NOTE: Te be edited, the query should be in 'Draft' status." +"dataset. NOTE: To be edited, the query should be in 'Draft' status." msgstr "" #. module: bi_view_editor diff --git a/bi_view_editor/i18n/sr@latin.po b/bi_view_editor/i18n/sr@latin.po index 1f9fcecc..f0ec94ce 100644 --- a/bi_view_editor/i18n/sr@latin.po +++ b/bi_view_editor/i18n/sr@latin.po @@ -180,7 +180,7 @@ msgstr "" #: help:bve.view,data:0 msgid "" "Use the special query builder to define the query to generate your report " -"dataset. NOTE: Te be edited, the query should be in 'Draft' status." +"dataset. NOTE: To be edited, the query should be in 'Draft' status." msgstr "" #. module: bi_view_editor diff --git a/bi_view_editor/i18n/sv.po b/bi_view_editor/i18n/sv.po index 25062cde..10cd7f2f 100644 --- a/bi_view_editor/i18n/sv.po +++ b/bi_view_editor/i18n/sv.po @@ -180,7 +180,7 @@ msgstr "" #: help:bve.view,data:0 msgid "" "Use the special query builder to define the query to generate your report " -"dataset. NOTE: Te be edited, the query should be in 'Draft' status." +"dataset. NOTE: To be edited, the query should be in 'Draft' status." msgstr "" #. module: bi_view_editor diff --git a/bi_view_editor/i18n/th.po b/bi_view_editor/i18n/th.po index f1e17997..67768883 100644 --- a/bi_view_editor/i18n/th.po +++ b/bi_view_editor/i18n/th.po @@ -180,7 +180,7 @@ msgstr "" #: help:bve.view,data:0 msgid "" "Use the special query builder to define the query to generate your report " -"dataset. NOTE: Te be edited, the query should be in 'Draft' status." +"dataset. NOTE: To be edited, the query should be in 'Draft' status." msgstr "" #. module: bi_view_editor diff --git a/bi_view_editor/i18n/tr.po b/bi_view_editor/i18n/tr.po index af8f781e..736e18f3 100644 --- a/bi_view_editor/i18n/tr.po +++ b/bi_view_editor/i18n/tr.po @@ -180,7 +180,7 @@ msgstr "Durum" #: help:bve.view,data:0 msgid "" "Use the special query builder to define the query to generate your report " -"dataset. NOTE: Te be edited, the query should be in 'Draft' status." +"dataset. NOTE: To be edited, the query should be in 'Draft' status." msgstr "" #. module: bi_view_editor diff --git a/bi_view_editor/i18n/tr_TR.po b/bi_view_editor/i18n/tr_TR.po index 5d205bd5..e8d47018 100644 --- a/bi_view_editor/i18n/tr_TR.po +++ b/bi_view_editor/i18n/tr_TR.po @@ -181,7 +181,7 @@ msgstr "Hal" #: help:bve.view,data:0 msgid "" "Use the special query builder to define the query to generate your report " -"dataset. NOTE: Te be edited, the query should be in 'Draft' status." +"dataset. NOTE: To be edited, the query should be in 'Draft' status." msgstr "" #. module: bi_view_editor diff --git a/bi_view_editor/i18n/uk.po b/bi_view_editor/i18n/uk.po index 568fd2f7..32fb8468 100644 --- a/bi_view_editor/i18n/uk.po +++ b/bi_view_editor/i18n/uk.po @@ -180,7 +180,7 @@ msgstr "" #: help:bve.view,data:0 msgid "" "Use the special query builder to define the query to generate your report " -"dataset. NOTE: Te be edited, the query should be in 'Draft' status." +"dataset. NOTE: To be edited, the query should be in 'Draft' status." msgstr "" #. module: bi_view_editor diff --git a/bi_view_editor/i18n/vi.po b/bi_view_editor/i18n/vi.po index 46fad7a1..1f966276 100644 --- a/bi_view_editor/i18n/vi.po +++ b/bi_view_editor/i18n/vi.po @@ -180,7 +180,7 @@ msgstr "" #: help:bve.view,data:0 msgid "" "Use the special query builder to define the query to generate your report " -"dataset. NOTE: Te be edited, the query should be in 'Draft' status." +"dataset. NOTE: To be edited, the query should be in 'Draft' status." msgstr "" #. module: bi_view_editor diff --git a/bi_view_editor/i18n/vi_VN.po b/bi_view_editor/i18n/vi_VN.po index 474e0b5b..162905ef 100644 --- a/bi_view_editor/i18n/vi_VN.po +++ b/bi_view_editor/i18n/vi_VN.po @@ -180,7 +180,7 @@ msgstr "" #: help:bve.view,data:0 msgid "" "Use the special query builder to define the query to generate your report " -"dataset. NOTE: Te be edited, the query should be in 'Draft' status." +"dataset. NOTE: To be edited, the query should be in 'Draft' status." msgstr "" #. module: bi_view_editor diff --git a/bi_view_editor/i18n/zh_CN.po b/bi_view_editor/i18n/zh_CN.po index a005ee66..77eeaf6e 100644 --- a/bi_view_editor/i18n/zh_CN.po +++ b/bi_view_editor/i18n/zh_CN.po @@ -180,7 +180,7 @@ msgstr "" #: help:bve.view,data:0 msgid "" "Use the special query builder to define the query to generate your report " -"dataset. NOTE: Te be edited, the query should be in 'Draft' status." +"dataset. NOTE: To be edited, the query should be in 'Draft' status." msgstr "" #. module: bi_view_editor diff --git a/bi_view_editor/i18n/zh_TW.po b/bi_view_editor/i18n/zh_TW.po index c41e9f7f..4f54cca5 100644 --- a/bi_view_editor/i18n/zh_TW.po +++ b/bi_view_editor/i18n/zh_TW.po @@ -180,7 +180,7 @@ msgstr "" #: help:bve.view,data:0 msgid "" "Use the special query builder to define the query to generate your report " -"dataset. NOTE: Te be edited, the query should be in 'Draft' status." +"dataset. NOTE: To be edited, the query should be in 'Draft' status." msgstr "" #. module: bi_view_editor diff --git a/bi_view_editor/models/__init__.py b/bi_view_editor/models/__init__.py index 204ac77a..7e6dcc7e 100644 --- a/bi_view_editor/models/__init__.py +++ b/bi_view_editor/models/__init__.py @@ -2,5 +2,6 @@ # Copyright 2015-2017 Onestein () # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +from . import models from . import bve_view from . import ir_model diff --git a/bi_view_editor/models/bve_view.py b/bi_view_editor/models/bve_view.py index 91e053bb..d8419296 100644 --- a/bi_view_editor/models/bve_view.py +++ b/bi_view_editor/models/bve_view.py @@ -4,9 +4,9 @@ import json -from openerp import api, fields, models, tools -from openerp.exceptions import Warning as UserError -from openerp.tools.translate import _ +from odoo import api, fields, models, tools +from odoo.exceptions import UserError +from odoo.tools.translate import _ class BveView(models.Model): @@ -23,11 +23,17 @@ class BveView(models.Model): else: bve_view.user_ids = self.env['res.users'].sudo().search([]) - name = fields.Char(required=True, copy=False) - model_name = fields.Char() + @api.depends('name') + @api.multi + def _compute_model_name(self): + for bve_view in self: + name = [x for x in bve_view.name.lower() if x.isalnum()] + model_name = ''.join(name).replace('_', '.').replace(' ', '.') + bve_view.model_name = 'x_bve.' + model_name + name = fields.Char(required=True, copy=False) + model_name = fields.Char(compute='_compute_model_name', store=True) note = fields.Text(string='Notes') - state = fields.Selection( [('draft', 'Draft'), ('created', 'Created')], @@ -36,22 +42,19 @@ class BveView(models.Model): data = fields.Text( help="Use the special query builder to define the query " "to generate your report dataset. " - "NOTE: Te be edited, the query should be in 'Draft' status.") - + "NOTE: To be edited, the query should be in 'Draft' status.") action_id = fields.Many2one('ir.actions.act_window', string='Action') view_id = fields.Many2one('ir.ui.view', string='View') - group_ids = fields.Many2many( 'res.groups', string='Groups', help="User groups allowed to see the generated report; " "if NO groups are specified the report will be public " "for everyone.") - user_ids = fields.Many2many( 'res.users', string='Users', - compute=_compute_users, + compute='_compute_users', store=True) _sql_constraints = [ @@ -60,40 +63,21 @@ class BveView(models.Model): _('Custom BI View names must be unique!')), ] - @api.multi - def unlink(self): - for view in self: - if view.state == 'created': - raise UserError( - _('You cannot delete a created view! ' - 'Reset the view to draft first.')) - return super(BveView, self).unlink() - - @api.multi - def action_reset(self): - self.ensure_one() - if self.action_id: - if self.action_id.view_id: - self.action_id.view_id.sudo().unlink() - self.action_id.sudo().unlink() - - models = self.env['ir.model'].sudo().search( - [('model', '=', self.model_name)]) - for model in models: - model.sudo().unlink() - - table_name = self.model_name.replace('.', '_') - tools.drop_view_if_exists(self.env.cr, table_name) - - self.state = 'draft' + @classmethod + def _get_format_data(cls, data): + data = data.replace('\'', '"') + data = data.replace(': u"', ':"') + return data @api.multi def _create_view_arch(self): self.ensure_one() - def _get_field_def(field_name, def_type): + def _get_field_def(name, def_type=''): + if not def_type: + return '' return """""".format( - field_name, def_type + name, def_type ) def _get_field_type(field_info): @@ -102,28 +86,42 @@ class BveView(models.Model): measure = field_info['measure'] and 'measure' return row or column or measure + def _get_field_list(fields_info): + view_fields = [] + for field_info in fields_info: + field_name = field_info['name'] + def_type = _get_field_type(field_info) + if def_type: + field_def = _get_field_def(field_name, def_type) + view_fields.append(field_def) + return view_fields + fields_info = json.loads(self._get_format_data(self.data)) - view_fields = [] - for field_info in fields_info: - field_name = field_info['name'] - def_type = _get_field_type(field_info) - if def_type: - field_def = _get_field_def(field_name, def_type) - view_fields.append(field_def) + view_fields = _get_field_list(fields_info) return view_fields - @api.model - def _get_format_data(self, data): - data = data.replace('\'', '"') - data = data.replace(': u"', ':"') - return data - @api.multi - def action_create(self): + def _create_tree_view_arch(self): self.ensure_one() - self._create_bve_object() - self._create_bve_view() + def _get_field_def(name): + return """""".format( + name + ) + + def _get_field_list(fields_info): + view_fields = [] + for field_info in fields_info: + field_name = field_info['name'] + if field_info['list'] and 'join_node' not in field_info: + field_def = _get_field_def(field_name) + view_fields.append(field_def) + return view_fields + + fields_info = json.loads(self._get_format_data(self.data)) + + view_fields = _get_field_list(fields_info) + return view_fields @api.multi def _create_bve_view(self): @@ -140,33 +138,48 @@ class BveView(models.Model): 'model': self.model_name, 'priority': 16, 'arch': """ - {} - """.format("".join(self._create_view_arch())) + + {} + + """.format("".join(self._create_view_arch())) }, { 'name': 'Graph Analysis', 'type': 'graph', 'model': self.model_name, 'priority': 16, 'arch': """ - {} - """.format("".join(self._create_view_arch())) + + {} + + """.format("".join(self._create_view_arch())) + }, { + 'name': 'Search BI View', + 'type': 'search', + 'model': self.model_name, + 'priority': 16, + 'arch': """ + + {} + + """.format("".join(self._create_view_arch())) }] for vals in view_vals: View.sudo().create(vals) # create Tree view - tree_view = View.sudo().create( - {'name': 'Tree Analysis', - 'type': 'tree', - 'model': self.model_name, - 'priority': 16, - 'arch': """ - {} - """.format("".join(self._create_view_arch())) - }) + tree_view = View.sudo().create({ + 'name': 'Tree Analysis', + 'type': 'tree', + 'model': self.model_name, + 'priority': 16, + 'arch': """ + + {} + + """.format("".join(self._create_tree_view_arch())) + }) # set the Tree view as the default one action_vals = { @@ -188,10 +201,52 @@ class BveView(models.Model): }) @api.multi - def _create_bve_object(self): + def _build_access_rules(self, model): self.ensure_one() - def _get_fields_info(fields_data): + def group_ids_with_access(model_name, access_mode): + self.env.cr.execute('''SELECT + g.id + FROM + ir_model_access a + JOIN ir_model m ON (a.model_id=m.id) + JOIN res_groups g ON (a.group_id=g.id) + LEFT JOIN ir_module_category c ON (c.id=g.category_id) + WHERE + m.model=%s AND + a.active IS True AND + a.perm_''' + access_mode, (model_name,)) + return [x[0] for x in self.env.cr.fetchall()] + + info = json.loads(self._get_format_data(self.data)) + model_names = list(set([f['model'] for f in info])) + read_groups = set.intersection(*[set( + group_ids_with_access(model_name, 'read') + ) for model_name in model_names]) + + # read access + for group in read_groups: + self.env['ir.model.access'].sudo().create({ + 'name': 'read access to ' + self.model_name, + 'model_id': model.id, + 'group_id': group, + 'perm_read': True, + }) + + # read and write access + for group in self.group_ids: + self.env['ir.model.access'].sudo().create({ + 'name': 'read-write access to ' + self.model_name, + 'model_id': model.id, + 'group_id': group.id, + 'perm_read': True, + 'perm_write': True, + }) + + @api.model + def _create_sql_view(self): + + def get_fields_info(fields_data): fields_info = [] for field_data in fields_data: field = self.env['ir.model.fields'].browse(field_data['id']) @@ -208,46 +263,60 @@ class BveView(models.Model): fields_info.append(vals) return fields_info - def _build_query(): - data = self.data - if not data: - raise UserError(_('No data to process.')) - - formatted_data = json.loads(self._get_format_data(data)) - info = _get_fields_info(formatted_data) - fields = [("{}.{}".format(f['table_alias'], - f['select_field']), - f['as_field']) for f in info if 'join_node' not in f] - tables = set([(f['table'], f['table_alias']) for f in info]) + def get_join_nodes(info): join_nodes = [ (f['table_alias'], f['join'], f['select_field']) for f in info if f['join'] is not False] + return join_nodes + + def get_tables(info): + tables = set([(f['table'], f['table_alias']) for f in info]) + return tables + + def get_fields(info): + return [("{}.{}".format(f['table_alias'], + f['select_field']), + f['as_field']) for f in info if 'join_node' not in f] + + def check_empty_data(data): + if not data or data == '[]': + raise UserError(_('No data to process.')) + + check_empty_data(self.data) - table_name = self.model_name.replace('.', '_') - tools.drop_view_if_exists(self.env.cr, table_name) - - basic_fields = [ - ("t0.id", "id"), - ("t0.write_uid", "write_uid"), - ("t0.write_date", "write_date"), - ("t0.create_uid", "create_uid"), - ("t0.create_date", "create_date") - ] - - q = """CREATE or REPLACE VIEW %s as ( - SELECT %s - FROM %s - WHERE %s - )""" % (table_name, ','.join( - ["{} AS {}".format(f[0], f[1]) - for f in basic_fields + fields]), ','.join( - ["{} AS {}".format(t[0], t[1]) - for t in list(tables)]), " AND ".join( - ["{}.{} = {}.id".format(j[0], j[2], j[1]) - for j in join_nodes] + ["TRUE"])) - - self.env.cr.execute(q) + formatted_data = json.loads(self._get_format_data(self.data)) + info = get_fields_info(formatted_data) + select_fields = get_fields(info) + tables = get_tables(info) + join_nodes = get_join_nodes(info) + + table_name = self.model_name.replace('.', '_') + + # robustness in case something went wrong + self._cr.execute('DROP TABLE IF EXISTS "%s"' % table_name) + + basic_fields = [ + ("t0.id", "id") + ] + + q = """CREATE or REPLACE VIEW %s as ( + SELECT %s + FROM %s + WHERE %s + )""" % (table_name, ','.join( + ["{} AS {}".format(f[0], f[1]) + for f in basic_fields + select_fields]), ','.join( + ["{} AS {}".format(t[0], t[1]) + for t in list(tables)]), " AND ".join( + ["{}.{} = {}.id".format(j[0], j[2], j[1]) + for j in join_nodes] + ["TRUE"])) + + self.env.cr.execute(q) + + @api.multi + def action_create(self): + self.ensure_one() def _prepare_field(field_data): if not field_data['custom']: @@ -268,87 +337,90 @@ class BveView(models.Model): vals.update({'ttype': 'float'}) if field.ttype == 'selection' and not field.selection: model_obj = self.env[field.model_id.model] - selection = model_obj._columns[field.name].selection - selection_domain = str(selection) - vals.update({'selection': selection_domain}) + selection = model_obj._fields[field.name].selection + if callable(selection): + selection_domain = selection(model_obj) + else: + selection_domain = selection + vals.update({'selection': str(selection_domain)}) return vals - def _prepare_object(): - data = json.loads(self._get_format_data(self.data)) - return { - 'name': self.name, - 'model': self.model_name, - 'field_id': [ - (0, 0, _prepare_field(field)) - for field in data - if 'join_node' not in field] - } - - def _build_object(): - vals = _prepare_object() - Model = self.env['ir.model'] - res_id = Model.sudo().with_context(bve=True).create(vals) - return res_id + # clean dirty view (in case something went wrong) + self.action_reset() - def group_ids_with_access(model_name, access_mode): - self.env.cr.execute('''SELECT - g.id - FROM - ir_model_access a - JOIN ir_model m ON (a.model_id=m.id) - JOIN res_groups g ON (a.group_id=g.id) - LEFT JOIN ir_module_category c ON (c.id=g.category_id) - WHERE - m.model=%s AND - a.active IS True AND - a.perm_''' + access_mode, (model_name,)) - return [x[0] for x in self.env.cr.fetchall()] + # create sql view + self._create_sql_view() + + # create model and fields + data = json.loads(self._get_format_data(self.data)) + model_vals = { + 'name': self.name, + 'model': self.model_name, + 'state': 'manual', + 'field_id': [ + (0, 0, _prepare_field(field)) + for field in data + if 'join_node' not in field] + } + Model = self.env['ir.model'].sudo().with_context(bve=True) + model = Model.create(model_vals) - def _build_access_rules(obj): - info = json.loads(self._get_format_data(self.data)) - models = list(set([f['model'] for f in info])) - read_groups = set.intersection(*[set( - group_ids_with_access(model, 'read')) for model in models]) - - # read access - for group in read_groups: - self.env['ir.model.access'].sudo().create({ - 'name': 'read access to ' + self.model_name, - 'model_id': obj.id, - 'group_id': group, - 'perm_read': True, - }) - - # read and write access - for group in self.group_ids: - self.env['ir.model.access'].sudo().create({ - 'name': 'read-write access to ' + self.model_name, - 'model_id': obj.id, - 'group_id': group.id, - 'perm_read': True, - 'perm_write': True, - }) - - self.model_name = 'x_bve.' + ''.join( - [x for x in self.name.lower() - if x.isalnum()]).replace('_', '.').replace(' ', '.') - _build_query() - obj = _build_object() - _build_access_rules(obj) + # give access rights + self._build_access_rules(model) + + # create tree, graph and pivot views + self._create_bve_view() @api.multi def open_view(self): self.ensure_one() - return { - 'name': _('BI View'), - 'type': 'ir.actions.act_window', - 'res_model': self.model_name, - 'view_type': 'form', - 'view_mode': 'tree,graph,pivot', - } + [action] = self.action_id.read() + action['display_name'] = _('BI View') + return action @api.multi def copy(self, default=None): self.ensure_one() default = dict(default or {}, name=_("%s (copy)") % self.name) return super(BveView, self).copy(default=default) + + @api.multi + def action_reset(self): + self.ensure_one() + + has_menus = False + if self.action_id: + action = 'ir.actions.act_window,%d' % (self.action_id.id,) + menus = self.env['ir.ui.menu'].sudo().search( + [('action', '=', action)] + ) + has_menus = True if menus else False + menus.sudo().unlink() + + if self.action_id.view_id: + self.action_id.view_id.sudo().unlink() + self.action_id.sudo().unlink() + + self.env['ir.ui.view'].sudo().search( + [('model', '=', self.model_name)]).unlink() + ir_models = self.env['ir.model'].sudo().search( + [('model', '=', self.model_name)]) + for model in ir_models: + model.sudo().unlink() + + table_name = self.model_name.replace('.', '_') + tools.drop_view_if_exists(self.env.cr, table_name) + + self.state = 'draft' + + if has_menus: + return {'type': 'ir.actions.client', 'tag': 'reload'} + + @api.multi + def unlink(self): + for view in self: + if view.state == 'created': + raise UserError( + _('You cannot delete a created view! ' + 'Reset the view to draft first.')) + return super(BveView, self).unlink() diff --git a/bi_view_editor/models/ir_model.py b/bi_view_editor/models/ir_model.py index 44507974..bdac552f 100644 --- a/bi_view_editor/models/ir_model.py +++ b/bi_view_editor/models/ir_model.py @@ -2,8 +2,7 @@ # Copyright 2015-2017 Onestein () # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -from openerp import api, models -from openerp.modules.registry import RegistryManager +from odoo import api, models NO_BI_MODELS = [ 'temp.range', @@ -42,20 +41,17 @@ def dict_for_field(field): } +def dict_for_model(model): + return { + 'id': model.id, + 'name': model.name, + 'model': model.model + } + + class IrModel(models.Model): _inherit = 'ir.model' - @api.model - def _filter_bi_fields(self, ir_model_field_obj): - name = ir_model_field_obj.name - model = ir_model_field_obj.model_id - model_name = model.model - Model = self.env[model_name] - if name in Model._columns: - f = Model._columns[name] - return f._classic_write - return False - @api.model def _filter_bi_models(self, model): @@ -73,7 +69,6 @@ class IrModel(models.Model): def _check_contains(model_model): if 'mail' in model_model or \ - '_' in model_model or \ 'report' in model_model or \ 'edi.' in model_model: return 1 @@ -96,92 +91,73 @@ class IrModel(models.Model): model['model'], 'read', False) return False + @api.model + def sort_filter_models(self, models_list): + res = sorted( + filter(self._filter_bi_models, models_list), + key=lambda x: x['name']) + return res + + @api.model + def _search_fields(self, domain): + Fields = self.env['ir.model.fields'] + fields = Fields.sudo().search(domain) + return fields + @api.model def get_related_fields(self, model_ids): """ Return list of field dicts for all fields that can be joined with models in model_ids """ - Model = self.env['ir.model'] - domain = [('id', 'in', model_ids.values())] - models = Model.sudo().search(domain) - model_names = {} - for model in models: - model_names.update({model.id: model.model}) - - related_fields = self._get_related_fields_list(model_ids, model_names) - return related_fields - - @api.model - def _get_related_fields_list(self, model_ids, model_names): - def _get_right_fields(model_ids, model_names): - Fields = self.env['ir.model.fields'] - rfields = [] + def get_model_list(model_ids): + model_list = [] domain = [('model_id', 'in', model_ids.values()), + ('store', '=', True), ('ttype', 'in', ['many2one'])] - for field in filter( - self._filter_bi_fields, - Fields.sudo().search(domain)): - for model in model_ids.items(): + filtered_fields = self._search_fields(domain) + for model in model_ids.items(): + for field in filtered_fields: if model[1] == field.model_id.id: - rfields.append( + model_list.append( dict(dict_for_field(field), join_node=-1, table_alias=model[0]) ) - return rfields + return model_list - def _get_left_fields(model_ids, model_names): - Fields = self.env['ir.model.fields'] - lfields = [] + def get_relation_list(model_ids, model_names): + relation_list = [] domain = [('relation', 'in', model_names.values()), + ('store', '=', True), ('ttype', 'in', ['many2one'])] - for field in filter( - self._filter_bi_fields, - Fields.sudo().search(domain)): - for model in model_ids.items(): + filtered_fields = self._search_fields(domain) + for model in model_ids.items(): + for field in filtered_fields: if model_names[model[1]] == field['relation']: - lfields.append( + relation_list.append( dict(dict_for_field(field), join_node=model[0], table_alias=-1) ) - return lfields - - def _get_relation_list(model_ids, model_names, lfields): - relation_list = [] - for model in model_ids.items(): - for field in lfields: - if model_names[model[1]] == field['relation']: - relation_list.append( - dict(field, join_node=model[0]) - ) return relation_list - def _get_model_list(model_ids, rfields): - model_list = [] - for model in model_ids.items(): - for field in rfields: - if model[1] == field['model_id']: - model_list.append( - dict(field, table_alias=model[0]) - ) - return model_list - - lfields = _get_left_fields(model_ids, model_names) - rfields = _get_right_fields(model_ids, model_names) + models = self.sudo().browse(model_ids.values()) + model_names = {} + for model in models: + model_names.update({model.id: model.model}) - relation_list = _get_relation_list(model_ids, model_names, lfields) - model_list = _get_model_list(model_ids, rfields) + model_list = get_model_list(model_ids) + relation_list = get_relation_list(model_ids, model_names) - related_fields = relation_list + model_list - return related_fields + return relation_list + model_list @api.model def get_related_models(self, model_ids): """ Return list of model dicts for all models that can be - joined with models in model_ids + joined with the already selected models. """ + def _get_field(fields, orig, target): field_list = [] for f in fields: @@ -205,35 +181,19 @@ class IrModel(models.Model): domain = ['|', ('id', 'in', list_id), ('model', 'in', list_model)] - models = self.env['ir.model'].sudo().search(domain) - for model in models: - models_list.append({ - 'id': model.id, - 'name': model.name, - 'model': model.model - }) - return sorted( - filter(self._filter_bi_models, models_list), - key=lambda x: x['name'] - ) + for model in self.sudo().search(domain): + models_list.append(dict_for_model(model)) + return self.sort_filter_models(models_list) @api.model def get_models(self): """ Return list of model dicts for all available models. """ - def dict_for_model(model): - return { - 'id': model.id, - 'name': model.name, - 'model': model.model - } - - models_domain = [('transient', '=', False)] - return sorted(filter( - self._filter_bi_models, - [dict_for_model(model) - for model in self.search(models_domain)]), - key=lambda x: x['name']) + + models_list = [] + for model in self.search([('transient', '=', False)]): + models_list.append(dict_for_model(model)) + return self.sort_filter_models(models_list) @api.model def get_join_nodes(self, field_data, new_field): @@ -252,39 +212,45 @@ class IrModel(models.Model): for alias, model_id in model_ids.items(): if model_id == new_field['model_id']: join_nodes.append({'table_alias': alias}) - for dict_field in self.get_related_fields(model_ids): - condition = [ - dict_field['join_node'] == -1, - dict_field['table_alias'] == -1 - ] - relation = (new_field['model'] == dict_field['relation']) - model = (new_field['model_id'] == dict_field['model_id']) - if (relation and condition[0]) or (model and condition[1]): - join_nodes.append(dict_field) + for field in self.get_related_fields(model_ids): + c = [field['join_node'] == -1, field['table_alias'] == -1] + a = (new_field['model'] == field['relation']) + b = (new_field['model_id'] == field['model_id']) + if (a and c[0]) or (b and c[1]): + join_nodes.append(field) return join_nodes + def remove_duplicate_nodes(join_nodes): + seen = set() + nodes_list = [] + for node in join_nodes: + node_tuple = tuple(node.items()) + if node_tuple not in seen: + seen.add(node_tuple) + nodes_list.append(node) + return nodes_list + model_ids = _get_model_ids(field_data) keys = [(field['table_alias'], field['id']) for field in field_data if field.get('join_node', -1) != -1] join_nodes = _get_join_nodes_dict(model_ids, new_field) + join_nodes = remove_duplicate_nodes(join_nodes) + return filter( lambda x: 'id' not in x or (x['table_alias'], x['id']) not in keys, join_nodes) @api.model def get_fields(self, model_id): - bi_field_domain = [ + domain = [ ('model_id', '=', model_id), + ('store', '=', True), ('name', 'not in', NO_BI_FIELDS), ('ttype', 'not in', NO_BI_TTYPES) ] - Fields = self.env['ir.model.fields'] - fields = filter( - self._filter_bi_fields, - Fields.sudo().search(bi_field_domain) - ) fields_dict = [] - for field in fields: + filtered_fields = self._search_fields(domain) + for field in filtered_fields: fields_dict.append( {'id': field.id, 'model_id': model_id, @@ -312,16 +278,15 @@ class IrModel(models.Model): # this sql update is necessary since a write method here would # be not working (an orm constraint is restricting the modification # of the state field while updating ir.model) - q = ("""UPDATE ir_model SET state = 'manual' - WHERE id = """ + str(res.id)) - self.env.cr.execute(q) + q = "UPDATE ir_model SET state = 'manual' WHERE id = %s" + self.env.cr.execute(q, (res.id, )) - # update registry + # # update registry if self._context.get('bve'): # setup models; this reloads custom models in registry self.pool.setup_models(self._cr, partial=(not self.pool.ready)) # signal that registry has changed - RegistryManager.signal_registry_change(self.env.cr.dbname) + self.pool.signal_registry_change() return res diff --git a/bi_view_editor/models/models.py b/bi_view_editor/models/models.py new file mode 100644 index 00000000..4b62e6f9 --- /dev/null +++ b/bi_view_editor/models/models.py @@ -0,0 +1,61 @@ +# -*- coding: utf-8 -*- +# Copyright 2017 Onestein () +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo import api, models +from odoo.exceptions import UserError +from odoo.tools.translate import _ + + +class Base(models.AbstractModel): + _inherit = 'base' + + @api.model + def _bi_view(self): + return self._name[0:6] == 'x_bve.' + + @api.model + def _auto_end(self): + if not self._bi_view(): + super(Base, self)._auto_end() + + @api.model + def _auto_init(self): + if not self._bi_view(): + super(Base, self)._auto_init() + + @api.model + def _setup_complete(self): + if not self._bi_view(): + super(Base, self)._setup_complete() + else: + self.pool.models[self._name]._log_access = False + + @api.model + def _read_group_process_groupby(self, gb, query): + if not self._bi_view(): + return super(Base, self)._read_group_process_groupby(gb, query) + + split = gb.split(':') + if split[0] not in self._fields: + raise UserError( + _('No data to be displayed.')) + return super(Base, self)._read_group_process_groupby(gb, query) + + @api.model + def _add_magic_fields(self): + if self._bi_view(): + self._log_access = False + return super(Base, self)._add_magic_fields() + + @api.model_cr + def _table_exist(self): + if not self._bi_view(): + return super(Base, self)._table_exist() + return 1 + + # @api.model_cr + # def _create_table(self): + # if not self._bi_view(): + # return super(Base, self)._create_table() + # return 1 diff --git a/bi_view_editor/security/ir.model.access.csv b/bi_view_editor/security/ir.model.access.csv index 2547fb5a..81d91dc4 100644 --- a/bi_view_editor/security/ir.model.access.csv +++ b/bi_view_editor/security/ir.model.access.csv @@ -1,3 +1,2 @@ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink access_bve_view_everyone,bve.view,bi_view_editor.model_bve_view,,1,1,1,1 -access_bve_view_technical_settings,bve.view,bi_view_editor.model_bve_view,base.group_no_one,1,1,1,1 diff --git a/bi_view_editor/static/src/js/bve.js b/bi_view_editor/static/src/js/bve.js index 455adaf8..e6f6db9d 100644 --- a/bi_view_editor/static/src/js/bve.js +++ b/bi_view_editor/static/src/js/bve.js @@ -1,10 +1,65 @@ -openerp.bi_view_editor = function (instance, local) { +odoo.define('bi_view_editor', function (require) { +"use strict"; - instance.bi_view_editor.BVEEditor = instance.web.form.AbstractField.extend({ + var Core = require("web.core"); + var FormCommon = require('web.form_common'); + var Model = require('web.Model'); + var Data = require('web.data'); + var Widget = require('web.Widget'); + var Dialog = require("web.Dialog"); + var _t = Core._t; + + var JoinNodePopup = Widget.extend({ + template: "JoinNodePopup", + start: function() { + var self = this; + }, + + display_popup: function(choices, model_data, callback, callback_data) { + var self = this; + this.renderElement(); + var joinnodes = this.$el.find('#join-nodes'); + joinnodes.empty(); + for (var i=0; i" + model_data[choices[i].table_alias].model_name + ""; + } else { + var new_str = ""; + if (choices[i].join_node !== -1) { + new_str = "" + _t("new") + " "; + } + description = _t("Join using the field") + " " + choices[i].description + " " + _t("on ") + new_str + _t("model") +" " + choices[i].model_name + ""; + } + joinnodes.append($('' + description+ '') + .data('idx', i) + .wrap('

') + .parent()); + } + var dialog = new Dialog(this, { + dialogClass: 'oe_act_window', + title: _t("Choose join node"), + $content: this.$el, + buttons: [{text: _t("Cancel"), + classes: "btn-default o_form_button_cancel", + close: true + }] + }).open(); + + joinnodes.find('a').click(function() { + callback(callback_data, choices[$(this).data('idx')]); + dialog.close(); + }); + + this.start(); + } + }); + + var BiViewEditor = FormCommon.AbstractField.extend({ template: "BVEEditor", activeModelMenus: [], currentFilter: "", - init: function(parent, action) { + init: function() { this._super.apply(this, arguments); }, start: function() { @@ -23,7 +78,6 @@ openerp.bi_view_editor = function (instance, local) { drop: function (event, ui) { self.add_field(ui.draggable); ui.draggable.draggable('option', 'revert', false ); - ui.draggable.remove(); } }); if (!this.get("effective_readonly")) { @@ -68,6 +122,8 @@ openerp.bi_view_editor = function (instance, local) { icons += " "; if(field.measure) icons += " "; + if(field.list) + icons += " "; return icons; }, @@ -80,20 +136,20 @@ openerp.bi_view_editor = function (instance, local) { load_classes: function(scrollTo) { scrollTo = (typeof scrollTo === 'undefined') ? false : scrollTo; var self = this; - var model = new instance.web.Model("ir.model"); + var model = new Model("ir.model"); if (this.$el.find(".field-list tbody tr").length > 0) { - model.call("get_related_models", [this.get_model_ids()], { context: new instance.web.CompoundContext() }).then(function(result) { + model.call("get_related_models", [this.get_model_ids()], { context: new Data.CompoundContext() }).then(function(result) { self.show_classes(result); }); } else { - model.call("get_models", { context: new instance.web.CompoundContext() }).then(function(result) { + model.call("get_models", { context: new Data.CompoundContext() }).then(function(result) { self.show_classes(result); }); } }, show_classes: function (result) { var self = this; - var model = new instance.web.Model("ir.model"); + var model = new Model("ir.model"); self.$el.find(".class-list .class").remove(); self.$el.find(".class-list .field").remove(); var css = this.get('effective_readonly') ? 'cursor: default' : 'cursor: pointer'; @@ -112,7 +168,7 @@ openerp.bi_view_editor = function (instance, local) { if(index !== -1) self.activeModelMenus.splice(index, 1); } else { self.activeModelMenus.push(classel.data('model-data').id); - model.call("get_fields", [classel.data('model-data').id], { context: new instance.web.CompoundContext() }).then(function(result) { + model.call("get_fields", [classel.data('model-data').id], { context: new Data.CompoundContext() }).then(function(result) { for (var i = 0; i < result.length; i++) { classel.find("#bve-field-" + result[i].name).remove(); self._render_field(self, i, result, classel, addField) @@ -122,12 +178,13 @@ openerp.bi_view_editor = function (instance, local) { } } function renderFields(result) { - console.log(result); - var item = self.$el.find(".class-list #bve-class-" + result[0].model_id); - for (var o = 0; o < result.length; o++) { - self._render_field(self, o, result, item, addField) + if (typeof(result[0]) !== 'undefined') { + var item = self.$el.find(".class-list #bve-class-" + result[0].model_id); + for (var o = 0; o < result.length; o++) { + self._render_field(self, o, result, item, addField) + } + item.data('bve-processed', true); } - item.data('bve-processed', true); } for (var i = 0; i < result.length; i++) { var item = $("
" + result[i].name + "
") @@ -138,7 +195,7 @@ openerp.bi_view_editor = function (instance, local) { var index = self.activeModelMenus.indexOf(item.find(".class").data('model-data').id); if(index !== -1 && !self.get("effective_readonly")) { - model.call("get_fields", [self.activeModelMenus[index]], { context: new instance.web.CompoundContext() }).then(renderFields); + model.call("get_fields", [self.activeModelMenus[index]], { context: new Data.CompoundContext() }).then(renderFields); } self.filter(); } @@ -165,15 +222,19 @@ openerp.bi_view_editor = function (instance, local) { _contextMenu.find(identifier).attr('checked', false); }, _false_if_undefined: function(to_check) { - if (typeof check === 'undefined') return false; - return check; + if (typeof to_check === 'undefined') return false; + return to_check; + }, + _true_if_undefined: function(to_check) { + if (typeof to_check === 'undefined') return true; + return to_check; }, add_field_to_table: function(data, options) { var self = this; - data.row = self._false_if_undefined(data.row); data.column = self._false_if_undefined(data.column); data.measure = self._false_if_undefined(data.measure); + data.list = self._true_if_undefined(data.list); var n = 1; var name = data.name; @@ -220,10 +281,11 @@ openerp.bi_view_editor = function (instance, local) { self.set_checkbox(currentFieldData.column, '#column-checkbox', contextMenu); self.set_checkbox(currentFieldData.row, '#row-checkbox', contextMenu); self.set_checkbox(currentFieldData.measure, '#measure-checkbox', contextMenu); + self.set_checkbox(currentFieldData.list, '#list-checkbox', contextMenu); var to_disable = false; if(currentFieldData.type === "float" || currentFieldData.type === "integer" || currentFieldData.type === "monetary") to_disable = true; - var identifiers = [['#column-checkbox', 'column', to_disable], ['#row-checkbox', 'row', to_disable], ['#measure-checkbox', 'measure', !to_disable]]; + var identifiers = [['#column-checkbox', 'column', to_disable], ['#row-checkbox', 'row', to_disable], ['#measure-checkbox', 'measure', !to_disable], ['#list-checkbox', 'list', false]]; identifiers.forEach(function (element) { contextMenu.find(element[0]).attr('disabled', element[2]); }); @@ -260,8 +322,13 @@ openerp.bi_view_editor = function (instance, local) { self.clean_join_nodes(); self.internal_set_value(JSON.stringify(self.get_fields())); self.load_classes(); + self.$el.find(".field-list .delete-button").hide(); + self.$el.find(".field-list .delete-button:last").show(); return false; }); + + self.$el.find(".field-list .delete-button").hide(); + self.$el.find(".field-list .delete-button:last").show(); }, clean_join_nodes: function () { var aliases = $.makeArray(this.$el.find(".field-list tbody tr").map(function (idx, el) { @@ -320,19 +387,29 @@ openerp.bi_view_editor = function (instance, local) { self.load_classes(field); }, add_field: function(field) { + var self = this; + + // Quick fix for double click + if(self._adding) { + return; + } + self._adding = true; + setTimeout(function() { + self._adding = false; + }, 1000); + // End quick fix + var data = field.data('field-data'); - var model = new instance.web.Model("ir.model"); + var model = new Model("ir.model"); var model_ids = this.get_model_ids(); var field_data = this.get_fields(); - var self = this; - model.call('get_join_nodes', [field_data, data], {context: new instance.web.CompoundContext()}).then(function(result) { + model.call('get_join_nodes', [field_data, data], {context: new Data.CompoundContext()}).then(function(result) { if (result.length === 1) { self.add_field_and_join_node(data, result[0]); self.internal_set_value(JSON.stringify(self.get_fields())); - //self.load_classes(data); } else if (result.length > 1) { - var pop = new local.JoinNodePopup(self); + var pop = new JoinNodePopup(self); pop.display_popup(result, self.get_model_data(), self.add_field_and_join_node.bind(self), data); } else { // first field and table only. @@ -363,49 +440,6 @@ openerp.bi_view_editor = function (instance, local) { this.load_classes(); } }); - instance.web.form.widgets.add('BVEEditor', 'instance.bi_view_editor.BVEEditor'); - - local.JoinNodePopup = instance.web.Widget.extend({ - template: "JoinNodePopup", - start: function() { - var self = this; - }, - - display_popup: function(choices, model_data, callback, callback_data) { - var self = this; - this.renderElement(); - var joinnodes = this.$el.find('#join-nodes'); - joinnodes.empty(); - for (var i=0; i" + description+ "") - .data('idx', i) - .wrap("

") - .parent()); - - } - var dialog = new instance.web.Dialog(this, { - dialogClass: 'oe_act_window', - title: "Choose Join Node", - $content: this.$el - }).open(); - - joinnodes.find('a').click(function() { - callback(callback_data, choices[$(this).data('idx')]); - dialog.close(); - }); - - this.start(); - } - }); + Core.form_widget_registry.add('BVEEditor', BiViewEditor); -}; +}); diff --git a/bi_view_editor/templates/qweb_template.xml b/bi_view_editor/templates/qweb_template.xml index fae5371b..cc8243f6 100644 --- a/bi_view_editor/templates/qweb_template.xml +++ b/bi_view_editor/templates/qweb_template.xml @@ -2,7 +2,6 @@
-

Please choose the join node

@@ -44,9 +43,10 @@
    -
  • Column
  • -
  • Row
  • -
  • Measure
  • +
  • Column
  • +
  • Row
  • +
  • Measure
  • +
  • List
diff --git a/bi_view_editor/tests/test_bi_view.py b/bi_view_editor/tests/test_bi_view.py index b4f4f24b..375227aa 100644 --- a/bi_view_editor/tests/test_bi_view.py +++ b/bi_view_editor/tests/test_bi_view.py @@ -2,8 +2,8 @@ # Copyright 2017 Onestein () # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -from openerp.tests.common import TransactionCase, at_install, post_install -from openerp.exceptions import Warning as UserError +from odoo.tests.common import TransactionCase, at_install, post_install +from odoo.exceptions import UserError class TestBiViewEditor(TransactionCase): @@ -66,6 +66,7 @@ class TestBiViewEditor(TransactionCase): 'table_alias': 't0', 'row': 0, 'column': 1, + 'list': 1, 'measure': 0 }, {'model_id': self.partner_model.id, @@ -81,6 +82,7 @@ class TestBiViewEditor(TransactionCase): 'description': self.partner_company_field.field_description, 'row': 0, 'column': 0, + 'list': 1, 'measure': 0 }, {'model_id': self.company_model.id, @@ -94,6 +96,7 @@ class TestBiViewEditor(TransactionCase): 'table_alias': 't1', 'row': 1, 'column': 0, + 'list': 0, 'measure': 0 } ] diff --git a/bi_view_editor/views/bve_view.xml b/bi_view_editor/views/bve_view.xml index 7152ad02..d6d50254 100644 --- a/bi_view_editor/views/bve_view.xml +++ b/bi_view_editor/views/bve_view.xml @@ -18,6 +18,7 @@