diff --git a/web_dashboard_tile/__init__.py b/web_dashboard_tile/__init__.py index 386e21ce..9ad11b3e 100644 --- a/web_dashboard_tile/__init__.py +++ b/web_dashboard_tile/__init__.py @@ -1 +1,26 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2010-2013 OpenERP s.a. (). +# Copyright (C) 2014 initOS GmbH & Co. KG (). +# Copyright (C) 2015-Today GRAP +# Author Markus Schneider +# @author Sylvain LE GAL (https://twitter.com/legalsylvain) +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + from . import tile diff --git a/web_dashboard_tile/__openerp__.py b/web_dashboard_tile/__openerp__.py index a1203b6c..d0f8cf41 100644 --- a/web_dashboard_tile/__openerp__.py +++ b/web_dashboard_tile/__openerp__.py @@ -22,41 +22,71 @@ ############################################################################## { "name": "Dashboard Tile", - "version": "0.4", - "depends": ['web', 'board', 'mail'], - 'author': "initOS GmbH & Co. KG,Odoo Community Association (OCA)", + "summary": "Add Tiles to Dashboard", + "version": "1.0", + "depends": [ + 'web', + 'board', + 'mail', + 'web_widget_color', + ], + 'author': "initOS GmbH & Co. KG,GRAP,Odoo Community Association (OCA)", "category": "", 'license': 'AGPL-3', "description": """ - module to give you a dashboard where you can configure tile from any view - and add them as short cut. +Add Tiles to Dashboard +====================== +Features: +--------- +module to give you a dashboard where you can configure tile from any view +and add them as short cut. - Kown issues/limits: - * change color picks wrong color - * can not edit tile from dashboard - * context are ignored - * date filter can not be relative - * combine domain of menue and filter so can not restore origin filter +* Tile can be: + * displayed only for a user; + * global for all users (In that case, some tiles will be hidden if + the current user doesn't have access to the given model); +* The tile displays items count of a given model restricted to a given domain; +* Optionnaly, the tile can display the result of a function of a field; + * Function is one of sum/avg/min/max/median; + * Field must be integer or float; - possible future improvments: - * support context_today - * add icons - * support client side action (like inbox) - * support select int/float column with min/max/avg/sum to display - * change position (maybe drag&drop) - """, - "summary": "Add tile to dashboard", - 'data': ['tile.xml', - 'security/ir.model.access.csv', - 'security/rules.xml'], - 'css': ['static/src/css/tile.css'], +Screenshot: +----------- +* Dashboad sample, displaying Sale Orders to invoice: +.. image:: web_dashboard_tile/static/src/img/screenshot_dashboard.png +* Tree view displayed when user click on the tile: +.. image:: web_dashboard_tile/static/src/img/screenshot_action_click.png + + +Kown issues/limits: +------------------- +* can not edit tile from dashboard (color, sequence, function, ...); +* context are ignored; +* date filter can not be relative; +* combine domain of menue and filter so can not restore origin filter; +possible future improvments: +---------------------------- +* support context_today; +* add icons; +* support client side action (like inbox); + """, + 'data': [ + 'view/tile.xml', + 'security/ir.model.access.csv', + 'security/rules.xml', + ], + 'css': [ + 'static/src/css/tile.css', + ], 'demo': [ + 'demo/res_groups.yml', + 'demo/tile_tile.yml', + ], + 'js': [ + 'static/src/js/custom_js.js', ], - 'test': [ + 'qweb': [ + 'static/src/xml/custom_xml.xml', ], - 'installable': True, - 'auto_install': False, - 'js': ['static/src/js/custom_js.js'], - 'qweb': ['static/src/xml/custom_xml.xml'], } diff --git a/web_dashboard_tile/demo/res_groups.yml b/web_dashboard_tile/demo/res_groups.yml new file mode 100644 index 00000000..735437c5 --- /dev/null +++ b/web_dashboard_tile/demo/res_groups.yml @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2015-Today GRAP +# @author Sylvain LE GAL (https://twitter.com/legalsylvain) +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + +- !record {model: res.groups, id: base.group_no_one}: + users: + - base.user_root diff --git a/web_dashboard_tile/demo/tile_tile.yml b/web_dashboard_tile/demo/tile_tile.yml new file mode 100644 index 00000000..c40b5903 --- /dev/null +++ b/web_dashboard_tile/demo/tile_tile.yml @@ -0,0 +1,33 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2015-Today GRAP +# @author Sylvain LE GAL (https://twitter.com/legalsylvain) +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + +- !record {model: tile.tile, id: installed_modules}: + name: Installed Modules + model_id: base.model_ir_module_module + domain: [['state', 'in', ['installed', 'to upgrade', 'to remove']]] + action_id: base.open_module_tree + +- !record {model: tile.tile, id: installed_OCA_modules}: + name: Installed OCA Modules + model_id: base.model_ir_module_module + domain: [['state', 'in', ['installed', 'to upgrade', 'to remove']], ['author', 'ilike', 'Odoo Community Association (OCA)']] + action_id: base.open_module_tree diff --git a/web_dashboard_tile/i18n/fr.po b/web_dashboard_tile/i18n/fr.po index b2517ed3..6bb700fa 100644 --- a/web_dashboard_tile/i18n/fr.po +++ b/web_dashboard_tile/i18n/fr.po @@ -6,8 +6,8 @@ msgid "" msgstr "" "Project-Id-Version: OpenERP Server 7.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-04-05 19:36+0000\n" -"PO-Revision-Date: 2015-04-05 19:36+0000\n" +"POT-Creation-Date: 2015-04-10 01:04+0000\n" +"PO-Revision-Date: 2015-04-10 01:04+0000\n" "Last-Translator: <>\n" "Language-Team: \n" "MIME-Version: 1.0\n" @@ -20,6 +20,37 @@ msgstr "" msgid "Action" msgstr "Action" +#. module: web_dashboard_tile +#: field:tile.tile,active:0 +msgid "Active" +msgstr "Actif" + +#. module: web_dashboard_tile +#: selection:tile.tile,field_function:0 +msgid "Average" +msgstr "Moyenne" + +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/tile.py:82 +#, python-format +msgid "Average value of '%s'" +msgstr "Valeur moyenne du champ '%s'" + +#. module: web_dashboard_tile +#: field:tile.tile,color:0 +msgid "Background color" +msgstr "Couleur de fond" + +#. module: web_dashboard_tile +#: field:tile.tile,computed_value:0 +msgid "Computed Value" +msgstr "Valeur calculée" + +#. module: web_dashboard_tile +#: field:tile.tile,count:0 +msgid "Count" +msgstr "Quantité" + #. module: web_dashboard_tile #. openerp-web #: code:addons/web_dashboard_tile/static/src/xml/custom_xml.xml:8 @@ -66,6 +97,21 @@ msgstr "Editer..." msgid "Error" msgstr "Erreur" +#. module: web_dashboard_tile +#: constraint:tile.tile:0 +msgid "Error ! Please select a field of the selected model." +msgstr "Erreur ! Veuillez sélectioner un champ qui correspond au modèle." + +#. module: web_dashboard_tile +#: constraint:tile.tile:0 +msgid "Error ! Please set both fields: 'Field' and 'Function'." +msgstr "Erreur ! Veuillez renseigner les deux champs : 'Champ' et 'Fonction'." + +#. module: web_dashboard_tile +#: field:tile.tile,field_id:0 +msgid "Field" +msgstr "Champ" + #. module: web_dashboard_tile #. openerp-web #: code:addons/web_dashboard_tile/static/src/js/custom_js.js:61 @@ -74,15 +120,63 @@ msgid "Filter name is required." msgstr "Le nom du filtre est requis." #. module: web_dashboard_tile -#: field:tile.tile,color:0 -msgid "Kanban Color" -msgstr "Couleur dans la vue Kanban" +#: field:tile.tile,font_color:0 +msgid "Font Color" +msgstr "Couleur du texte" + +#. module: web_dashboard_tile +#: field:tile.tile,field_function:0 +msgid "Function" +msgstr "Fonction" + +#. module: web_dashboard_tile +#: field:tile.tile,helper:0 +msgid "Helper Text" +msgstr "Texte Descriptif" + +#. module: web_dashboard_tile +#: selection:tile.tile,field_function:0 +msgid "Maximum" +msgstr "Maximum" + +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/tile.py:76 +#, python-format +msgid "Maximum value of '%s'" +msgstr "Valeur maximale du champ '%s'" + +#. module: web_dashboard_tile +#: selection:tile.tile,field_function:0 +msgid "Median" +msgstr "Médiane" + +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/tile.py:85 +#, python-format +msgid "Median value of '%s'" +msgstr "Valeur médian du champ '%s'" + +#. module: web_dashboard_tile +#: selection:tile.tile,field_function:0 +msgid "Minimum" +msgstr "Minimum" + +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/tile.py:73 +#, python-format +msgid "Minimum value of '%s'" +msgstr "Valeur minimale du champ '%s'" #. module: web_dashboard_tile #: field:tile.tile,model_id:0 msgid "Model" msgstr "Modèle" +#. module: web_dashboard_tile +#: field:tile.tile,sequence:0 +msgid "Sequence" +msgstr "Séquence" + #. module: web_dashboard_tile #. openerp-web #: code:addons/web_dashboard_tile/static/src/js/custom_js.js:100 @@ -90,6 +184,11 @@ msgstr "Modèle" msgid "Success" msgstr "Succès" +#. module: web_dashboard_tile +#: selection:tile.tile,field_function:0 +msgid "Sum" +msgstr "Somme" + #. module: web_dashboard_tile #: field:tile.tile,name:0 msgid "Tile Name" @@ -100,7 +199,7 @@ msgstr "Nom de l'indicateur" #: code:addons/web_dashboard_tile/static/src/js/custom_js.js:100 #, python-format msgid "Tile is created" -msgstr "L'indicateur a été crée" +msgstr "L'indicateur a été créé" #. module: web_dashboard_tile #. openerp-web @@ -109,18 +208,13 @@ msgstr "L'indicateur a été crée" msgid "Tile:" msgstr "Indicateur :" +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/tile.py:79 +#, python-format +msgid "Total value of '%s'" +msgstr "Somme du champ '%s'" + #. module: web_dashboard_tile #: field:tile.tile,user_id:0 msgid "User" msgstr "Utilisateur" - -#. module: web_dashboard_tile -#: field:tile.tile,count:0 -msgid "unknown" -msgstr "inconnu" - -#. module: web_dashboard_tile -#: view:tile.tile:0 -msgid "í" -msgstr "í" - diff --git a/web_dashboard_tile/i18n/web_dashboard_tile.pot b/web_dashboard_tile/i18n/web_dashboard_tile.pot index bcaef112..0e89f8ca 100644 --- a/web_dashboard_tile/i18n/web_dashboard_tile.pot +++ b/web_dashboard_tile/i18n/web_dashboard_tile.pot @@ -6,8 +6,8 @@ msgid "" msgstr "" "Project-Id-Version: OpenERP Server 7.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-04-05 19:42+0000\n" -"PO-Revision-Date: 2015-04-05 19:42+0000\n" +"POT-Creation-Date: 2015-04-10 01:03+0000\n" +"PO-Revision-Date: 2015-04-10 01:03+0000\n" "Last-Translator: <>\n" "Language-Team: \n" "MIME-Version: 1.0\n" @@ -20,6 +20,37 @@ msgstr "" msgid "Action" msgstr "" +#. module: web_dashboard_tile +#: field:tile.tile,active:0 +msgid "Active" +msgstr "" + +#. module: web_dashboard_tile +#: selection:tile.tile,field_function:0 +msgid "Average" +msgstr "" + +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/tile.py:82 +#, python-format +msgid "Average value of '%s'" +msgstr "" + +#. module: web_dashboard_tile +#: field:tile.tile,color:0 +msgid "Background color" +msgstr "" + +#. module: web_dashboard_tile +#: field:tile.tile,computed_value:0 +msgid "Computed Value" +msgstr "" + +#. module: web_dashboard_tile +#: field:tile.tile,count:0 +msgid "Count" +msgstr "" + #. module: web_dashboard_tile #. openerp-web #: code:addons/web_dashboard_tile/static/src/xml/custom_xml.xml:8 @@ -66,6 +97,21 @@ msgstr "" msgid "Error" msgstr "" +#. module: web_dashboard_tile +#: constraint:tile.tile:0 +msgid "Error ! Please select a field of the selected model." +msgstr "" + +#. module: web_dashboard_tile +#: constraint:tile.tile:0 +msgid "Error ! Please set both fields: 'Field' and 'Function'." +msgstr "" + +#. module: web_dashboard_tile +#: field:tile.tile,field_id:0 +msgid "Field" +msgstr "" + #. module: web_dashboard_tile #. openerp-web #: code:addons/web_dashboard_tile/static/src/js/custom_js.js:61 @@ -74,8 +120,51 @@ msgid "Filter name is required." msgstr "" #. module: web_dashboard_tile -#: field:tile.tile,color:0 -msgid "Kanban Color" +#: field:tile.tile,font_color:0 +msgid "Font Color" +msgstr "" + +#. module: web_dashboard_tile +#: field:tile.tile,field_function:0 +msgid "Function" +msgstr "" + +#. module: web_dashboard_tile +#: field:tile.tile,helper:0 +msgid "Helper Text" +msgstr "" + +#. module: web_dashboard_tile +#: selection:tile.tile,field_function:0 +msgid "Maximum" +msgstr "" + +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/tile.py:76 +#, python-format +msgid "Maximum value of '%s'" +msgstr "" + +#. module: web_dashboard_tile +#: selection:tile.tile,field_function:0 +msgid "Median" +msgstr "" + +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/tile.py:85 +#, python-format +msgid "Median value of '%s'" +msgstr "" + +#. module: web_dashboard_tile +#: selection:tile.tile,field_function:0 +msgid "Minimum" +msgstr "" + +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/tile.py:73 +#, python-format +msgid "Minimum value of '%s'" msgstr "" #. module: web_dashboard_tile @@ -83,6 +172,11 @@ msgstr "" msgid "Model" msgstr "" +#. module: web_dashboard_tile +#: field:tile.tile,sequence:0 +msgid "Sequence" +msgstr "" + #. module: web_dashboard_tile #. openerp-web #: code:addons/web_dashboard_tile/static/src/js/custom_js.js:100 @@ -90,6 +184,11 @@ msgstr "" msgid "Success" msgstr "" +#. module: web_dashboard_tile +#: selection:tile.tile,field_function:0 +msgid "Sum" +msgstr "" + #. module: web_dashboard_tile #: field:tile.tile,name:0 msgid "Tile Name" @@ -109,6 +208,12 @@ msgstr "" msgid "Tile:" msgstr "" +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/tile.py:79 +#, python-format +msgid "Total value of '%s'" +msgstr "" + #. module: web_dashboard_tile #: field:tile.tile,user_id:0 msgid "User" @@ -121,13 +226,7 @@ msgstr "" msgid "tile.tile" msgstr "" -#. module: web_dashboard_tile -#: field:tile.tile,count:0 -msgid "unknown" -msgstr "" - #. module: web_dashboard_tile #: view:tile.tile:0 msgid "í" msgstr "" - diff --git a/web_dashboard_tile/migrations/7.0.1.0/post-migration-color.py b/web_dashboard_tile/migrations/7.0.1.0/post-migration-color.py new file mode 100644 index 00000000..f8c33840 --- /dev/null +++ b/web_dashboard_tile/migrations/7.0.1.0/post-migration-color.py @@ -0,0 +1,48 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2015-Today GRAP +# @author Sylvain LE GAL (https://twitter.com/legalsylvain) +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + + +COLOR_NUMERIC_TO_RVB = { + 0: '#006015', + 1: '#CD2513', + 2: '#CDC713', + 3: '#57158A', + 4: '#0E9B2D', + 5: '#7F0C00', + 6: '#7F7B00', + 7: '#320455', + 8: '#CD6E13', + 9: '#0E6C7E', +} + + +def migrate_color(cr): + for old, new in COLOR_NUMERIC_TO_RVB.iteritems(): + cr.execute(""" + UPDATE tile_tile + SET color='%s', font_color='#FFFFFF' + WHERE color='%s' + """ % (new, old)) + + +def migrate(cr, installed_version): + migrate_color(cr) diff --git a/web_dashboard_tile/static/src/css/tile.css b/web_dashboard_tile/static/src/css/tile.css index 06c23705..1d057cee 100644 --- a/web_dashboard_tile/static/src/css/tile.css +++ b/web_dashboard_tile/static/src/css/tile.css @@ -4,72 +4,41 @@ border: 0; border-radius: 0; } -.openerp .oe_kanban_view .oe_dashbaord_tile .tile_count{ - font-size: 48px; - font-weight: bold; - position: absolute; - left: 9px; - bottom: 9px; -} + +.openerp .oe_kanban_view .oe_dashbaord_tile .tile_label, +.openerp .oe_kanban_view .oe_dashbaord_tile .tile_count_without_computed_value, +.openerp .oe_kanban_view .oe_dashbaord_tile .tile_count_with_computed_value, +.openerp .oe_kanban_view .oe_dashbaord_tile .tile_computed_value { + width: 140px; + text-align: center; +} + .openerp .oe_kanban_view .oe_dashbaord_tile .tile_label{ - padding: 9px; + padding: 5px; font-size: 15px; } -.openerp .oe_kanban_view .oe_dashbaord_tile a{ - color: #fff; -} -.openerp .oe_kanban_view .oe_dashbaord_tile.oe_tile_color_, -.openerp .oe_kanban_view .oe_dashbaord_tile.oe_tile_color_ a, -.openerp .oe_kanban_view .oe_dashbaord_tile .oe_dropdown_menu a{ - color: #000; -} -.openerp .oe_kanban_view .oe_tile_color_1, -.openerp .oe_dashbaord_tile a.oe_kanban_color_1{ - background: #CD2513; - color: #fff; -} -.openerp .oe_kanban_view .oe_tile_color_2, -.openerp .oe_dashbaord_tile a.oe_kanban_color_2{ - background: #CDC713; - color: #fff; -} -.openerp .oe_kanban_view .oe_tile_color_3, -.openerp .oe_dashbaord_tile a.oe_kanban_color_3{ - background: #57158A; - color: #fff; -} -.openerp .oe_kanban_view .oe_tile_color_4, -.openerp .oe_dashbaord_tile a.oe_kanban_color_4{ - background: #0E9B2D; - color: #fff; -} -.openerp .oe_kanban_view .oe_tile_color_5, -.openerp .oe_dashbaord_tile a.oe_kanban_color_5{ - background: #7F0C00; - color: #fff; -} -.openerp .oe_kanban_view .oe_tile_color_6, -.openerp .oe_dashbaord_tile a.oe_kanban_color_6{ - background: #7F7B00; - color: #fff; -} -.openerp .oe_kanban_view .oe_tile_color_7, -.openerp .oe_dashbaord_tile a.oe_kanban_color_7{ - background: #320455; - color: #fff; + +.openerp .oe_kanban_view .oe_dashbaord_tile .tile_count_without_computed_value{ + font-size: 52px; + font-weight: bold; + position: absolute; + left: 5px; + bottom: 5px; } -.openerp .oe_kanban_view .oe_tile_color_8, -.openerp .oe_dashbaord_tile a.oe_kanban_color_8{ - background: #CD6E13; - color: #fff; + +.openerp .oe_kanban_view .oe_dashbaord_tile .tile_count_with_computed_value{ + font-size: 38px; + font-weight: bold; + position: absolute; + left: 5px; + bottom: 30px; } -.openerp .oe_kanban_view .oe_tile_color_9, -.openerp .oe_dashbaord_tile a.oe_kanban_color_9{ - background: #0E6C7E; - color: #fff; + +.openerp .oe_kanban_view .oe_dashbaord_tile .tile_computed_value{ + font-size: 18px; + font-weight: bold; + position: absolute; + right: 10px; + bottom: 5px; + font-style: italic; } -.openerp .oe_kanban_view .oe_tile_color_0, -.openerp .oe_dashbaord_tile a.oe_kanban_color_0{ - background: #006015; - color: #fff; -} \ No newline at end of file diff --git a/web_dashboard_tile/static/src/img/avg.png b/web_dashboard_tile/static/src/img/avg.png new file mode 100644 index 00000000..2f534e93 Binary files /dev/null and b/web_dashboard_tile/static/src/img/avg.png differ diff --git a/web_dashboard_tile/static/src/img/max.png b/web_dashboard_tile/static/src/img/max.png new file mode 100644 index 00000000..ff33ee43 Binary files /dev/null and b/web_dashboard_tile/static/src/img/max.png differ diff --git a/web_dashboard_tile/static/src/img/median.png b/web_dashboard_tile/static/src/img/median.png new file mode 100644 index 00000000..61d5dd7c Binary files /dev/null and b/web_dashboard_tile/static/src/img/median.png differ diff --git a/web_dashboard_tile/static/src/img/min.png b/web_dashboard_tile/static/src/img/min.png new file mode 100644 index 00000000..de7c3fd0 Binary files /dev/null and b/web_dashboard_tile/static/src/img/min.png differ diff --git a/web_dashboard_tile/static/src/img/screenshot_action_click.png b/web_dashboard_tile/static/src/img/screenshot_action_click.png new file mode 100644 index 00000000..3fd41f99 Binary files /dev/null and b/web_dashboard_tile/static/src/img/screenshot_action_click.png differ diff --git a/web_dashboard_tile/static/src/img/screenshot_dashboard.png b/web_dashboard_tile/static/src/img/screenshot_dashboard.png new file mode 100644 index 00000000..9cbdeecd Binary files /dev/null and b/web_dashboard_tile/static/src/img/screenshot_dashboard.png differ diff --git a/web_dashboard_tile/static/src/img/sum.png b/web_dashboard_tile/static/src/img/sum.png new file mode 100644 index 00000000..90908e8b Binary files /dev/null and b/web_dashboard_tile/static/src/img/sum.png differ diff --git a/web_dashboard_tile/tile.py b/web_dashboard_tile/tile.py index b88523c6..92243875 100644 --- a/web_dashboard_tile/tile.py +++ b/web_dashboard_tile/tile.py @@ -4,7 +4,9 @@ # OpenERP, Open Source Management Solution # Copyright (C) 2010-2013 OpenERP s.a. (). # Copyright (C) 2014 initOS GmbH & Co. KG (). +# Copyright (C) 2015-Today GRAP # Author Markus Schneider +# @author Sylvain LE GAL (https://twitter.com/legalsylvain) # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as @@ -22,35 +24,150 @@ ############################################################################## from openerp.osv import orm, fields -import random +from openerp.tools.translate import _ class tile(orm.Model): _name = 'tile.tile' + _order = 'sequence, name' - def _get_tile_count(self, cr, uid, ids, field_name, field_value, - arg, context=None): - result = {} - records = self.browse(cr, uid, ids) + def median(self, aList): + # https://docs.python.org/3/library/statistics.html#statistics.median + # TODO : refactor, using statistics.median when Odoo will be available + # in Python 3.4 + even = (0 if len(aList) % 2 else 1) + 1 + half = (len(aList) - 1) / 2 + return sum(sorted(aList)[half:half + even]) / float(even) + + def _get_tile_info(self, cr, uid, ids, fields, args, context=None): + ima_obj = self.pool['ir.model.access'] + res = {} + records = self.browse(cr, uid, ids, context=context) for r in records: - model = self.pool.get(r.model_id.model) - result[r.id] = model.search_count(cr, uid, eval(r.domain), context) - return result + res[r.id] = { + 'active': False, + 'count': 0, + 'computed_value': 0, + 'helper': '', + } + if ima_obj.check( + cr, uid, r.model_id.model, 'read', False, context): + # Compute count item + model = self.pool.get(r.model_id.model) + count = model.search_count( + cr, uid, eval(r.domain), context=context) + res[r.id].update({ + 'active': True, + 'count': count, + }) + + # Compute datas for field_id depending of field_function + if r.field_function and r.field_id and count != 0: + ids = model.search( + cr, uid, eval(r.domain), context=context) + vals = [x[r.field_id.name] for x in model.read( + cr, uid, ids, [r.field_id.name], context=context)] + desc = r.field_id.field_description + if r.field_function == 'min': + value = min(vals) + helper = _("Minimum value of '%s'") % desc + elif r.field_function == 'max': + value = max(vals) + helper = _("Maximum value of '%s'") % desc + elif r.field_function == 'sum': + value = sum(vals) + helper = _("Total value of '%s'") % desc + elif r.field_function == 'avg': + value = sum(vals) / len(vals) + helper = _("Average value of '%s'") % desc + elif r.field_function == 'median': + value = self.median(vals) + helper = _("Median value of '%s'") % desc + res[r.id].update({ + 'computed_value': value, + 'helper': helper, + }) + return res + + def _search_active(self, cr, uid, obj, name, arg, context=None): + ima_obj = self.pool['ir.model.access'] + ids = [] + cr.execute(""" + SELECT tt.id, im.model + FROM tile_tile tt + INNER JOIN ir_model im + ON tt.model_id = im.id""") + for result in cr.fetchall(): + if (ima_obj.check(cr, uid, result[1], 'read', False) == + arg[0][2]): + ids.append(result[0]) + return [('id', 'in', ids)] _columns = { 'name': fields.char('Tile Name'), - 'model_id': fields.many2one('ir.model', 'Model'), + 'model_id': fields.many2one('ir.model', 'Model', required=True), 'user_id': fields.many2one('res.users', 'User'), 'domain': fields.text('Domain'), 'action_id': fields.many2one('ir.actions.act_window', 'Action'), - 'count': fields.function(_get_tile_count, type='int', String='Count', - readonly=True), - 'color': fields.char('Kanban Color') + 'count': fields.function( + _get_tile_info, type='int', string='Count', + multi='tile_info', readonly=True), + 'computed_value': fields.function( + _get_tile_info, type='float', string='Computed Value', + multi='tile_info', readonly=True), + 'helper': fields.function( + _get_tile_info, type='char', string='Helper Text', + multi='tile_info', readonly=True), + 'field_function': fields.selection([ + ('min', 'Minimum'), + ('max', 'Maximum'), + ('sum', 'Sum'), + ('avg', 'Average'), + ('median', 'Median'), + ], 'Function'), + 'field_id': fields.many2one( + 'ir.model.fields', 'Field', + domain="[('model_id', '=', model_id)," + " ('ttype', 'in', ['float', 'int'])]"), + 'active': fields.function( + _get_tile_info, type='boolean', string='Active', + multi='tile_info', readonly=True, fnct_search=_search_active), + 'color': fields.char('Background color'), + 'font_color': fields.char('Font Color'), + 'sequence': fields.integer( + 'Sequence', required=True), } + # Constraint Section + def _check_model_id_field_id(self, cr, uid, ids, context=None): + for t in self.browse(cr, uid, ids, context=context): + if t.field_id and t.field_id.model_id.id != t.model_id.id: + return False + return True + + def _check_field_id_field_function(self, cr, uid, ids, context=None): + for t in self.browse(cr, uid, ids, context=context): + if t.field_id and not t.field_function or\ + t.field_function and not t.field_id: + return False + return True + + _constraints = [ + ( + _check_model_id_field_id, + "Error ! Please select a field of the selected model.", + ['model_id', 'field_id']), + ( + _check_field_id_field_function, + "Error ! Please set both fields: 'Field' and 'Function'.", + ['field_id', 'field_function']), + ] + _defaults = { 'domain': '[]', - 'color': 0, + 'color': '#0E6C7E', + 'font_color': '#FFFFFF', + 'sequence': 0, } def open_link(self, cr, uid, ids, context=None): @@ -89,6 +206,4 @@ class tile(orm.Model): [('model', '=', vals['model_id'])]) vals['model_id'] = model_ids[0] - if 'color' not in vals: - vals['color'] = random.randint(1, 10) return self.create(cr, uid, vals, context) diff --git a/web_dashboard_tile/tile.xml b/web_dashboard_tile/view/tile.xml similarity index 65% rename from web_dashboard_tile/tile.xml rename to web_dashboard_tile/view/tile.xml index 3d9a4ec4..154efd90 100644 --- a/web_dashboard_tile/tile.xml +++ b/web_dashboard_tile/view/tile.xml @@ -6,11 +6,13 @@ tile.tile + - - + + + @@ -26,6 +28,10 @@ + + + + @@ -43,30 +49,35 @@ + + + + -