From f9f9d80a8d66bab81609479c74cfb4796ee304d7 Mon Sep 17 00:00:00 2001 From: Markus Schneider Date: Mon, 15 Sep 2014 16:13:51 +0200 Subject: [PATCH 01/50] add web_advanced_search_wildcard module --- web_advanced_search_wildcard/__init__.py | 0 web_advanced_search_wildcard/__openerp__.py | 47 +++++++++++++++++++ web_advanced_search_wildcard/i18n/de.po | 6 +++ .../i18n/search_enhanced_operators.po | 23 +++++++++ .../static/src/js/search.js | 6 +++ 5 files changed, 82 insertions(+) create mode 100644 web_advanced_search_wildcard/__init__.py create mode 100644 web_advanced_search_wildcard/__openerp__.py create mode 100644 web_advanced_search_wildcard/i18n/de.po create mode 100644 web_advanced_search_wildcard/i18n/search_enhanced_operators.po create mode 100644 web_advanced_search_wildcard/static/src/js/search.js diff --git a/web_advanced_search_wildcard/__init__.py b/web_advanced_search_wildcard/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/web_advanced_search_wildcard/__openerp__.py b/web_advanced_search_wildcard/__openerp__.py new file mode 100644 index 00000000..3308ec6f --- /dev/null +++ b/web_advanced_search_wildcard/__openerp__.py @@ -0,0 +1,47 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2010-2013 OpenERP s.a. (). +# Copyright (C) 2014 initOS GmbH & Co. KG (). +# Author Thomas Rehn +# +# 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 . +# +############################################################################## +{ + "name": "Webmodule add wildcard operators for advanced search", + "version": "0.1", + "depends": ["web"], + 'author': 'initOS GmbH & Co. KG', + "category": "", + "summary": "Simular search in searchbar", + 'license': 'AGPL-3', + "description": """ + Allows =ilike operator to advanced search option. + Use % as a placeholder. + Example: "Zip matches 1%" gives all zip starting with 1 + Also allows insensitive exact search. + Example "Name matches john" will find "John" and "john" but not "Johnson". + """, + 'data': [ + ], + 'demo': [ + ], + 'test': [ + ], + 'js': ['static/src/js/search.js'], + 'installable': True, + 'auto_install': False, +} diff --git a/web_advanced_search_wildcard/i18n/de.po b/web_advanced_search_wildcard/i18n/de.po new file mode 100644 index 00000000..314c4df2 --- /dev/null +++ b/web_advanced_search_wildcard/i18n/de.po @@ -0,0 +1,6 @@ +#. module: web +#. openerp-web +#: code:addons/search_enhanced_operators/static/src/js/search.js:3 +#, python-format +msgid "matches" +msgstr "entspricht" diff --git a/web_advanced_search_wildcard/i18n/search_enhanced_operators.po b/web_advanced_search_wildcard/i18n/search_enhanced_operators.po new file mode 100644 index 00000000..d6a1a5ac --- /dev/null +++ b/web_advanced_search_wildcard/i18n/search_enhanced_operators.po @@ -0,0 +1,23 @@ +# Translation of OpenERP Server. +# This file contains the translation of the following modules: +# +msgid "" +msgstr "" +"Project-Id-Version: OpenERP Server 7.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2014-09-15 09:11+0000\n" +"PO-Revision-Date: 2014-09-15 11:12+0100\n" +"Last-Translator: M\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: \n" + +#. module: search_enhanced_operators +#. openerp-web +#: code:addons/search_enhanced_operators/static/src/js/search.js:4 +#, python-format +msgid "matches" +msgstr "" + diff --git a/web_advanced_search_wildcard/static/src/js/search.js b/web_advanced_search_wildcard/static/src/js/search.js new file mode 100644 index 00000000..4a5318a8 --- /dev/null +++ b/web_advanced_search_wildcard/static/src/js/search.js @@ -0,0 +1,6 @@ +openerp.search_enhanced_operators = function(instance){ + var _lt = instance.web._lt; + instance.web.search.ExtendedSearchProposition.Char.prototype.operators.push( + {value: '=ilike', text: _lt("matches")} + ); +}; From c5ca63466fe6e83d7e92010567cbe39353d6b7c1 Mon Sep 17 00:00:00 2001 From: Markus Schneider Date: Thu, 18 Sep 2014 13:07:44 +0200 Subject: [PATCH 02/50] rename empty translation file --- ...rch_enhanced_operators.po => web_advanced_search_wildcard.pot} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename web_advanced_search_wildcard/i18n/{search_enhanced_operators.po => web_advanced_search_wildcard.pot} (100%) diff --git a/web_advanced_search_wildcard/i18n/search_enhanced_operators.po b/web_advanced_search_wildcard/i18n/web_advanced_search_wildcard.pot similarity index 100% rename from web_advanced_search_wildcard/i18n/search_enhanced_operators.po rename to web_advanced_search_wildcard/i18n/web_advanced_search_wildcard.pot From 841f91542dfd5f959baac2d96a3403c8a24ed2d3 Mon Sep 17 00:00:00 2001 From: Markus Schneider Date: Mon, 22 Sep 2014 11:13:21 +0200 Subject: [PATCH 03/50] rename module inside translation file --- web_advanced_search_wildcard/i18n/de.po | 2 +- .../i18n/web_advanced_search_wildcard.pot | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/web_advanced_search_wildcard/i18n/de.po b/web_advanced_search_wildcard/i18n/de.po index 314c4df2..bfc97d1a 100644 --- a/web_advanced_search_wildcard/i18n/de.po +++ b/web_advanced_search_wildcard/i18n/de.po @@ -1,6 +1,6 @@ #. module: web #. openerp-web -#: code:addons/search_enhanced_operators/static/src/js/search.js:3 +#: code:addons/web_advanced_search_wildcard/static/src/js/search.js:3 #, python-format msgid "matches" msgstr "entspricht" diff --git a/web_advanced_search_wildcard/i18n/web_advanced_search_wildcard.pot b/web_advanced_search_wildcard/i18n/web_advanced_search_wildcard.pot index d6a1a5ac..e187a2da 100644 --- a/web_advanced_search_wildcard/i18n/web_advanced_search_wildcard.pot +++ b/web_advanced_search_wildcard/i18n/web_advanced_search_wildcard.pot @@ -14,9 +14,9 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: \n" -#. module: search_enhanced_operators +#. module: web_advanced_search_wildcard #. openerp-web -#: code:addons/search_enhanced_operators/static/src/js/search.js:4 +#: code:addons/web_advanced_search_wildcard/static/src/js/search.js:4 #, python-format msgid "matches" msgstr "" From 54e6169220b68bbe71d480412e64369feced8647 Mon Sep 17 00:00:00 2001 From: Rudolf Schnapka Date: Sun, 4 Jan 2015 14:51:33 +0100 Subject: [PATCH 04/50] initial german translations (and added pot-file) --- web_advanced_search_wildcard/i18n/de.po | 27 ++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/web_advanced_search_wildcard/i18n/de.po b/web_advanced_search_wildcard/i18n/de.po index bfc97d1a..4cfbc4f3 100644 --- a/web_advanced_search_wildcard/i18n/de.po +++ b/web_advanced_search_wildcard/i18n/de.po @@ -1,6 +1,27 @@ -#. module: web +# Translation of OpenERP Server. +# This file contains the translation of the following modules: +# +# Rudolf Schnapka , 2015. +msgid "" +msgstr "" +"Project-Id-Version: OpenERP Server 7.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2014-09-15 09:11+0000\n" +"PO-Revision-Date: 2015-01-04 14:07+0100\n" +"Last-Translator: Rudolf Schnapka \n" +"Language-Team: German \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: \n" +"Language: de\n" +"X-Generator: Lokalize 1.5\n" + +#. module: web_advanced_search_wildcard #. openerp-web -#: code:addons/web_advanced_search_wildcard/static/src/js/search.js:3 +#: code:addons/web_advanced_search_wildcard/static/src/js/search.js:4 #, python-format msgid "matches" -msgstr "entspricht" +msgstr "gleicht" + + From cb16cdf501e864c00eb734bb511a270178c38c93 Mon Sep 17 00:00:00 2001 From: Alexandre Fayolle Date: Mon, 2 Mar 2015 17:29:16 +0100 Subject: [PATCH 05/50] Add OCA as author of OCA addons In order to get visibility on https://www.odoo.com/apps the OCA board has decided to add the OCA as author of all the addons maintained as part of the association. --- web_advanced_search_wildcard/__openerp__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web_advanced_search_wildcard/__openerp__.py b/web_advanced_search_wildcard/__openerp__.py index 3308ec6f..dd4ee58e 100644 --- a/web_advanced_search_wildcard/__openerp__.py +++ b/web_advanced_search_wildcard/__openerp__.py @@ -24,7 +24,7 @@ "name": "Webmodule add wildcard operators for advanced search", "version": "0.1", "depends": ["web"], - 'author': 'initOS GmbH & Co. KG', + 'author': "initOS GmbH & Co. KG,Odoo Community Association (OCA)", "category": "", "summary": "Simular search in searchbar", 'license': 'AGPL-3', From c8d73ff2710f1b08015b66d2230b97d1d6a26e71 Mon Sep 17 00:00:00 2001 From: OCA Transbot Date: Sun, 11 Oct 2015 10:34:46 -0400 Subject: [PATCH 06/50] OCA Transbot updated translations from Transifex --- web_advanced_search_wildcard/i18n/en.po | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 web_advanced_search_wildcard/i18n/en.po diff --git a/web_advanced_search_wildcard/i18n/en.po b/web_advanced_search_wildcard/i18n/en.po new file mode 100644 index 00000000..e85bb958 --- /dev/null +++ b/web_advanced_search_wildcard/i18n/en.po @@ -0,0 +1,24 @@ +# Translation of OpenERP Server. +# This file contains the translation of the following modules: +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: web (7.0)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-10-07 17:50+0000\n" +"PO-Revision-Date: 2015-10-07 17:50+0000\n" +"Last-Translator: OCA Transbot \n" +"Language-Team: English (http://www.transifex.com/oca/OCA-web-7-0/language/en/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Language: en\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: web_advanced_search_wildcard +#. openerp-web +#: code:addons/web_advanced_search_wildcard/static/src/js/search.js:4 +#, python-format +msgid "matches" +msgstr "matches" From ec5d0a621a893a9ab5ab57b2340a90b45a75e615 Mon Sep 17 00:00:00 2001 From: lfreeke Date: Thu, 21 Jan 2016 11:21:48 +0100 Subject: [PATCH 07/50] Adept javascript to module name --- web_advanced_search_wildcard/static/src/js/search.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web_advanced_search_wildcard/static/src/js/search.js b/web_advanced_search_wildcard/static/src/js/search.js index 4a5318a8..1b43dc0c 100644 --- a/web_advanced_search_wildcard/static/src/js/search.js +++ b/web_advanced_search_wildcard/static/src/js/search.js @@ -1,4 +1,4 @@ -openerp.search_enhanced_operators = function(instance){ +openerp.web_advanced_search_wildcard = function(instance){ var _lt = instance.web._lt; instance.web.search.ExtendedSearchProposition.Char.prototype.operators.push( {value: '=ilike', text: _lt("matches")} From 4af119d60905b00e6d3ff0f3bdaf3ed20dc43fa0 Mon Sep 17 00:00:00 2001 From: lfreeke Date: Thu, 21 Jan 2016 13:30:57 +0100 Subject: [PATCH 08/50] port web_advanced_search_wildcard Conflicts: web_advanced_search_wildcard/__openerp__.py --- web_advanced_search_wildcard/README.rst | 43 +++++++++++++++++++ web_advanced_search_wildcard/__openerp__.py | 29 +++++-------- .../views/template.xml | 10 +++++ 3 files changed, 63 insertions(+), 19 deletions(-) create mode 100644 web_advanced_search_wildcard/README.rst create mode 100644 web_advanced_search_wildcard/views/template.xml diff --git a/web_advanced_search_wildcard/README.rst b/web_advanced_search_wildcard/README.rst new file mode 100644 index 00000000..9edc5fdf --- /dev/null +++ b/web_advanced_search_wildcard/README.rst @@ -0,0 +1,43 @@ +.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg + :alt: License: AGPL-3 + +============================ +Web advanced search wildcard +============================ + +Allows =ilike operator to advanced search option. + +Use % as a placeholder. +Example: "Zip matches 1%" gives all zip starting with 1 +Also allows insensitive exact search. +Example "Name matches john" will find "John" and "john" but not "Johnson". + + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues `_. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us smashing it by providing a detailed and welcomed feedback +`here `_. + + + +Contributors +------------ + +* Markus Schneider <> +* L Freeke + +Maintainer +---------- + +.. image:: http://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: http://odoo-community.org + +This module is maintained by the OCA. +OCA, or the Odoo Community Association, is a nonprofit organization whose mission is to support the collaborative development of Odoo features and promote its widespread use. +To contribute to this module, please visit http://odoo-community.org. + + diff --git a/web_advanced_search_wildcard/__openerp__.py b/web_advanced_search_wildcard/__openerp__.py index dd4ee58e..d2e6cd88 100644 --- a/web_advanced_search_wildcard/__openerp__.py +++ b/web_advanced_search_wildcard/__openerp__.py @@ -22,26 +22,17 @@ ############################################################################## { "name": "Webmodule add wildcard operators for advanced search", - "version": "0.1", - "depends": ["web"], - 'author': "initOS GmbH & Co. KG,Odoo Community Association (OCA)", - "category": "", "summary": "Simular search in searchbar", - 'license': 'AGPL-3', - "description": """ - Allows =ilike operator to advanced search option. - Use % as a placeholder. - Example: "Zip matches 1%" gives all zip starting with 1 - Also allows insensitive exact search. - Example "Name matches john" will find "John" and "john" but not "Johnson". - """, - 'data': [ - ], - 'demo': [ + "version": "8.0.1.0.0", + "category": "Uncategorized", + "license": 'AGPL-3', + "author": "initOS GmbH & Co. KG,Odoo Community Association (OCA), Therp BV", + "application": False, + "installable": True, + "depends": [ + "web" ], - 'test': [ + 'data': [ + "views/template.xml", ], - 'js': ['static/src/js/search.js'], - 'installable': True, - 'auto_install': False, } diff --git a/web_advanced_search_wildcard/views/template.xml b/web_advanced_search_wildcard/views/template.xml new file mode 100644 index 00000000..bfe353d5 --- /dev/null +++ b/web_advanced_search_wildcard/views/template.xml @@ -0,0 +1,10 @@ + + + + + + From 0a0a4a58f7c7791302289100dc6ccfb17914f1cd Mon Sep 17 00:00:00 2001 From: lfreeke Date: Thu, 21 Jan 2016 14:59:16 +0100 Subject: [PATCH 09/50] whitespace --- web_advanced_search_wildcard/README.rst | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/web_advanced_search_wildcard/README.rst b/web_advanced_search_wildcard/README.rst index 9edc5fdf..031b8007 100644 --- a/web_advanced_search_wildcard/README.rst +++ b/web_advanced_search_wildcard/README.rst @@ -4,14 +4,13 @@ ============================ Web advanced search wildcard ============================ - + Allows =ilike operator to advanced search option. Use % as a placeholder. Example: "Zip matches 1%" gives all zip starting with 1 Also allows insensitive exact search. Example "Name matches john" will find "John" and "john" but not "Johnson". - Bug Tracker =========== From ffd64ff2684c3d600bceb059d8780ba64457234e Mon Sep 17 00:00:00 2001 From: lfreeke Date: Thu, 21 Jan 2016 13:33:20 +0100 Subject: [PATCH 10/50] Add email address in README file --- web_advanced_search_wildcard/README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web_advanced_search_wildcard/README.rst b/web_advanced_search_wildcard/README.rst index 031b8007..8425e1d8 100644 --- a/web_advanced_search_wildcard/README.rst +++ b/web_advanced_search_wildcard/README.rst @@ -25,7 +25,7 @@ If you spotted it first, help us smashing it by providing a detailed and welcome Contributors ------------ -* Markus Schneider <> +* Markus Schneider * L Freeke Maintainer From 30367a046badd5b8a5f7d100a96e6fcc2b5c00a6 Mon Sep 17 00:00:00 2001 From: lfreeke Date: Thu, 21 Jan 2016 14:16:13 +0100 Subject: [PATCH 11/50] layout changes to readme file [MOD] Update manifest with latest OCA standard Conflicts: web_advanced_search_wildcard/__openerp__.py --- web_advanced_search_wildcard/README.rst | 20 +++++++++++---- web_advanced_search_wildcard/__openerp__.py | 27 ++++----------------- 2 files changed, 20 insertions(+), 27 deletions(-) diff --git a/web_advanced_search_wildcard/README.rst b/web_advanced_search_wildcard/README.rst index 8425e1d8..dcd65e33 100644 --- a/web_advanced_search_wildcard/README.rst +++ b/web_advanced_search_wildcard/README.rst @@ -20,23 +20,33 @@ In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us smashing it by providing a detailed and welcomed feedback `here `_. +Credits +======= +Images +------ + +* Odoo Community Association: `Icon `_. Contributors ------------ * Markus Schneider +* Thomas Rehn * L Freeke + Maintainer ---------- -.. image:: http://odoo-community.org/logo.png - :alt: Odoo Community Association - :target: http://odoo-community.org +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org This module is maintained by the OCA. -OCA, or the Odoo Community Association, is a nonprofit organization whose mission is to support the collaborative development of Odoo features and promote its widespread use. -To contribute to this module, please visit http://odoo-community.org. +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. +To contribute to this module, please visit https://odoo-community.org. diff --git a/web_advanced_search_wildcard/__openerp__.py b/web_advanced_search_wildcard/__openerp__.py index d2e6cd88..e54a77da 100644 --- a/web_advanced_search_wildcard/__openerp__.py +++ b/web_advanced_search_wildcard/__openerp__.py @@ -1,32 +1,15 @@ # -*- coding: utf-8 -*- -############################################################################## -# -# OpenERP, Open Source Management Solution -# Copyright (C) 2010-2013 OpenERP s.a. (). -# Copyright (C) 2014 initOS GmbH & Co. KG (). -# Author Thomas Rehn -# -# 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 . -# -############################################################################## +# © 2014 initOS GmbH & Co. KG (). +# © 2016 Therp BV . +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + { "name": "Webmodule add wildcard operators for advanced search", "summary": "Simular search in searchbar", "version": "8.0.1.0.0", "category": "Uncategorized", "license": 'AGPL-3', - "author": "initOS GmbH & Co. KG,Odoo Community Association (OCA), Therp BV", + "author": "initOS GmbH & Co. KG,Odoo Community Association (OCA),Therp BV", "application": False, "installable": True, "depends": [ From 2961a7e7ed50ac02914f9656a0b897274f5e9ec4 Mon Sep 17 00:00:00 2001 From: lfreeke Date: Wed, 3 Feb 2016 15:44:28 +0100 Subject: [PATCH 12/50] Manifest [MOD] README [ADD] Screenshot --- web_advanced_search_wildcard/README.rst | 17 +++++++++++++---- web_advanced_search_wildcard/__openerp__.py | 6 +++--- .../static/description/screenshot.png | Bin 0 -> 7164 bytes 3 files changed, 16 insertions(+), 7 deletions(-) create mode 100644 web_advanced_search_wildcard/static/description/screenshot.png diff --git a/web_advanced_search_wildcard/README.rst b/web_advanced_search_wildcard/README.rst index dcd65e33..8c6de995 100644 --- a/web_advanced_search_wildcard/README.rst +++ b/web_advanced_search_wildcard/README.rst @@ -2,15 +2,24 @@ :alt: License: AGPL-3 ============================ -Web advanced search wildcard +Wildcard in advanced search ============================ -Allows =ilike operator to advanced search option. +Allows =ilike ('matches') operator to advanced search option. + +Usage +===== Use % as a placeholder. -Example: "Zip matches 1%" gives all zip starting with 1 + +Example: "Zip" - 'matches' - "1%" gives all zip starting with 1 + +.. image:: /web_advanced_search_wildcard/static/description/screenshot.png + :alt: Screenshot + + Also allows insensitive exact search. -Example "Name matches john" will find "John" and "john" but not "Johnson". +Example "Name" - 'matches' - "john" will find "John" and "john" but not "Johnson". Bug Tracker =========== diff --git a/web_advanced_search_wildcard/__openerp__.py b/web_advanced_search_wildcard/__openerp__.py index e54a77da..797f3a60 100644 --- a/web_advanced_search_wildcard/__openerp__.py +++ b/web_advanced_search_wildcard/__openerp__.py @@ -4,10 +4,10 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). { - "name": "Webmodule add wildcard operators for advanced search", - "summary": "Simular search in searchbar", + "name": "Wildcard in advanced search", + "summary": "Webmodule to add wildcard operators in advanced search field", "version": "8.0.1.0.0", - "category": "Uncategorized", + "category": "web", "license": 'AGPL-3', "author": "initOS GmbH & Co. KG,Odoo Community Association (OCA),Therp BV", "application": False, diff --git a/web_advanced_search_wildcard/static/description/screenshot.png b/web_advanced_search_wildcard/static/description/screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..57848f902890b9aa4c78caf54ccfbcaed08e3cf4 GIT binary patch literal 7164 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 S=28L@A Date: Sun, 28 Feb 2016 05:11:25 -0500 Subject: [PATCH 13/50] OCA Transbot updated translations from Transifex --- web_advanced_search_wildcard/i18n/sl.po | 26 +++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 web_advanced_search_wildcard/i18n/sl.po diff --git a/web_advanced_search_wildcard/i18n/sl.po b/web_advanced_search_wildcard/i18n/sl.po new file mode 100644 index 00000000..f8aa6f65 --- /dev/null +++ b/web_advanced_search_wildcard/i18n/sl.po @@ -0,0 +1,26 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * web_advanced_search_wildcard +# +# Translators: +# Matjaž Mozetič , 2016 +msgid "" +msgstr "" +"Project-Id-Version: web (8.0)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-02-26 02:05+0000\n" +"PO-Revision-Date: 2016-02-27 16:56+0000\n" +"Last-Translator: Matjaž Mozetič \n" +"Language-Team: Slovenian (http://www.transifex.com/oca/OCA-web-8-0/language/sl/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Language: sl\n" +"Plural-Forms: nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);\n" + +#. module: web_advanced_search_wildcard +#. openerp-web +#: code:addons/web_advanced_search_wildcard/static/src/js/search.js:4 +#, python-format +msgid "matches" +msgstr "ujemanj" From 0b59f3c3918600c1809f2eb5df505c235200174d Mon Sep 17 00:00:00 2001 From: OCA Transbot Date: Sun, 13 Mar 2016 09:15:04 -0400 Subject: [PATCH 14/50] OCA Transbot updated translations from Transifex --- web_advanced_search_wildcard/i18n/fi.po | 26 ++++++++++++++++++++++ web_advanced_search_wildcard/i18n/pt_BR.po | 26 ++++++++++++++++++++++ 2 files changed, 52 insertions(+) create mode 100644 web_advanced_search_wildcard/i18n/fi.po create mode 100644 web_advanced_search_wildcard/i18n/pt_BR.po diff --git a/web_advanced_search_wildcard/i18n/fi.po b/web_advanced_search_wildcard/i18n/fi.po new file mode 100644 index 00000000..91f0ab2e --- /dev/null +++ b/web_advanced_search_wildcard/i18n/fi.po @@ -0,0 +1,26 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * web_advanced_search_wildcard +# +# Translators: +# Jarmo Kortetjärvi , 2016 +msgid "" +msgstr "" +"Project-Id-Version: web (8.0)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-03-11 02:17+0000\n" +"PO-Revision-Date: 2016-03-07 08:28+0000\n" +"Last-Translator: Jarmo Kortetjärvi \n" +"Language-Team: Finnish (http://www.transifex.com/oca/OCA-web-8-0/language/fi/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Language: fi\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: web_advanced_search_wildcard +#. openerp-web +#: code:addons/web_advanced_search_wildcard/static/src/js/search.js:4 +#, python-format +msgid "matches" +msgstr "osumat" diff --git a/web_advanced_search_wildcard/i18n/pt_BR.po b/web_advanced_search_wildcard/i18n/pt_BR.po new file mode 100644 index 00000000..0464430f --- /dev/null +++ b/web_advanced_search_wildcard/i18n/pt_BR.po @@ -0,0 +1,26 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * web_advanced_search_wildcard +# +# Translators: +# danimaribeiro , 2016 +msgid "" +msgstr "" +"Project-Id-Version: web (8.0)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-03-11 02:17+0000\n" +"PO-Revision-Date: 2016-03-05 16:05+0000\n" +"Last-Translator: danimaribeiro \n" +"Language-Team: Portuguese (Brazil) (http://www.transifex.com/oca/OCA-web-8-0/language/pt_BR/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Language: pt_BR\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" + +#. module: web_advanced_search_wildcard +#. openerp-web +#: code:addons/web_advanced_search_wildcard/static/src/js/search.js:4 +#, python-format +msgid "matches" +msgstr "resultados" From 2f49c04f0f1c74909e4b4654a2c30f4758b0177c Mon Sep 17 00:00:00 2001 From: OCA Transbot Date: Sun, 8 May 2016 15:21:29 -0400 Subject: [PATCH 15/50] OCA Transbot updated translations from Transifex --- web_advanced_search_wildcard/i18n/fr.po | 26 +++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 web_advanced_search_wildcard/i18n/fr.po diff --git a/web_advanced_search_wildcard/i18n/fr.po b/web_advanced_search_wildcard/i18n/fr.po new file mode 100644 index 00000000..302b2e39 --- /dev/null +++ b/web_advanced_search_wildcard/i18n/fr.po @@ -0,0 +1,26 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * web_advanced_search_wildcard +# +# Translators: +# Christophe CHAUVET , 2016 +msgid "" +msgstr "" +"Project-Id-Version: web (8.0)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-05-06 15:50+0000\n" +"PO-Revision-Date: 2016-05-06 08:19+0000\n" +"Last-Translator: Christophe CHAUVET \n" +"Language-Team: French (http://www.transifex.com/oca/OCA-web-8-0/language/fr/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Language: fr\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" + +#. module: web_advanced_search_wildcard +#. openerp-web +#: code:addons/web_advanced_search_wildcard/static/src/js/search.js:4 +#, python-format +msgid "matches" +msgstr "correspondances" From 93cfc97a3aff61e0927387e5e20387d4e12e47bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Bidoul=20=28ACSONE=29?= Date: Mon, 15 Aug 2016 22:15:57 +0200 Subject: [PATCH 16/50] remove en.po that was erroneously created by transbot --- web_advanced_search_wildcard/i18n/en.po | 24 ------------------------ 1 file changed, 24 deletions(-) delete mode 100644 web_advanced_search_wildcard/i18n/en.po diff --git a/web_advanced_search_wildcard/i18n/en.po b/web_advanced_search_wildcard/i18n/en.po deleted file mode 100644 index e85bb958..00000000 --- a/web_advanced_search_wildcard/i18n/en.po +++ /dev/null @@ -1,24 +0,0 @@ -# Translation of OpenERP Server. -# This file contains the translation of the following modules: -# -# Translators: -msgid "" -msgstr "" -"Project-Id-Version: web (7.0)\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-10-07 17:50+0000\n" -"PO-Revision-Date: 2015-10-07 17:50+0000\n" -"Last-Translator: OCA Transbot \n" -"Language-Team: English (http://www.transifex.com/oca/OCA-web-7-0/language/en/)\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: \n" -"Language: en\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" - -#. module: web_advanced_search_wildcard -#. openerp-web -#: code:addons/web_advanced_search_wildcard/static/src/js/search.js:4 -#, python-format -msgid "matches" -msgstr "matches" From af6574d7ea1df474fe398e91e10a2496f3c6562f Mon Sep 17 00:00:00 2001 From: OCA Transbot Date: Tue, 29 Nov 2016 14:34:08 -0500 Subject: [PATCH 17/50] OCA Transbot updated translations from Transifex --- web_advanced_search_wildcard/i18n/es.po | 26 +++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 web_advanced_search_wildcard/i18n/es.po diff --git a/web_advanced_search_wildcard/i18n/es.po b/web_advanced_search_wildcard/i18n/es.po new file mode 100644 index 00000000..2f9437ce --- /dev/null +++ b/web_advanced_search_wildcard/i18n/es.po @@ -0,0 +1,26 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * web_advanced_search_wildcard +# +# Translators: +# Pedro M. Baeza , 2016 +msgid "" +msgstr "" +"Project-Id-Version: web (8.0)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-11-26 01:59+0000\n" +"PO-Revision-Date: 2016-10-13 18:37+0000\n" +"Last-Translator: Pedro M. Baeza \n" +"Language-Team: Spanish (http://www.transifex.com/oca/OCA-web-8-0/language/es/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Language: es\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: web_advanced_search_wildcard +#. openerp-web +#: code:addons/web_advanced_search_wildcard/static/src/js/search.js:4 +#, python-format +msgid "matches" +msgstr "coincide con" From 318c66f8d40993e3b8298066103f315b7f54846a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Todorovich?= Date: Wed, 23 Nov 2016 13:12:43 -0300 Subject: [PATCH 18/50] [8.0][FIX] web_dashboard_tile security rule Rule was not being updated because of ``, hence the groups field of the tile was not working. Conflicts: web_dashboard_tile/__openerp__.py --- web_dashboard_tile/__openerp__.py | 4 +-- .../migrations/8.0.4.0/post-migration.py | 26 +++++++++++++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) create mode 100644 web_dashboard_tile/migrations/8.0.4.0/post-migration.py diff --git a/web_dashboard_tile/__openerp__.py b/web_dashboard_tile/__openerp__.py index 3e636b15..f84fd1b3 100644 --- a/web_dashboard_tile/__openerp__.py +++ b/web_dashboard_tile/__openerp__.py @@ -23,7 +23,7 @@ { "name": "Dashboard Tile", "summary": "Add Tiles to Dashboard", - "version": "8.0.1.0.0", + "version": "9.0.1.0.0", "depends": [ 'web', 'board', @@ -46,5 +46,5 @@ 'qweb': [ 'static/src/xml/custom_xml.xml', ], - 'installable': False, + 'installable': True, } diff --git a/web_dashboard_tile/migrations/8.0.4.0/post-migration.py b/web_dashboard_tile/migrations/8.0.4.0/post-migration.py new file mode 100644 index 00000000..570f814e --- /dev/null +++ b/web_dashboard_tile/migrations/8.0.4.0/post-migration.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- +# © 2016 Iván Todorovich +# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html + + +def migrate(cr, version): + if version is None: + return + + # Update ir.rule + cr.execute(""" + SELECT res_id FROM ir_model_data + WHERE name = 'model_tile_rule' + AND module = 'web_dashboard_tile'""") + rule_id = cr.fetchone()[0] + new_domain = """[ + "|", + ("user_id","=",user.id), + ("user_id","=",False), + "|", + ("group_ids","=",False), + ("group_ids","in",[g.id for g in user.groups_id]), + ]""" + cr.execute(""" + UPDATE ir_rule SET domain_force = '%(domain)s' + WHERE id = '%(id)s' """ % {'domain': new_domain, 'id': rule_id}) From d5eceaf1e2d7f80f889165ac3b2f5d043e1a0025 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Todorovich?= Date: Sat, 19 Nov 2016 14:07:01 -0300 Subject: [PATCH 20/50] [IMP][8.0][web_dashboard_tile] Refactor (see changes in description) (#476) Conflicts: web_dashboard_tile/README.rst web_dashboard_tile/__openerp__.py web_dashboard_tile/models/tile_tile.py web_dashboard_tile/static/src/css/tile.css --- web_dashboard_tile/README.rst | 36 +++ web_dashboard_tile/demo/tile_tile.yml | 4 +- .../migrations/8.0.3.0/post-migration.py | 13 + web_dashboard_tile/models/tile_tile.py | 237 ++++++++++++++++++ web_dashboard_tile/security/rules.xml | 11 +- web_dashboard_tile/static/src/css/tile.css | 50 ++++ .../static/src/img/screenshot_dashboard.png | Bin 45633 -> 20441 bytes web_dashboard_tile/tests/__init__.py | 6 + web_dashboard_tile/tests/test_tile.py | 52 ++++ web_dashboard_tile/views/tile.xml | 89 +++++-- 10 files changed, 468 insertions(+), 30 deletions(-) create mode 100644 web_dashboard_tile/migrations/8.0.3.0/post-migration.py create mode 100644 web_dashboard_tile/tests/__init__.py create mode 100644 web_dashboard_tile/tests/test_tile.py diff --git a/web_dashboard_tile/README.rst b/web_dashboard_tile/README.rst index c87fb47d..0337037b 100644 --- a/web_dashboard_tile/README.rst +++ b/web_dashboard_tile/README.rst @@ -1,6 +1,7 @@ Add Tiles to Dashboard ====================== +<<<<<<< HEAD module to give you a dashboard where you can configure tile from any view and add them as short cut. @@ -12,6 +13,24 @@ and add them as short cut. * 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; +======= +Adds a dashboard where you can configure tiles from any view and add them as short cut. + +By default, the tile displays items count of a given model restricted to a given domain. + +Optionally, the tile can display the result of a function on a field. + +- Function is one of `sum`, `avg`, `min`, `max` or `median`. +- Field must be integer or float. + +Tile can be: + +- Displayed only for a user. +- Global for all users. +- Restricted to some groups. + +*Note: The tile will be hidden if the current user doesn't have access to the given model.* +>>>>>>> 3ab676d... [IMP][8.0][web_dashboard_tile] Refactor (see changes in description) (#476) Usage ===== @@ -24,6 +43,7 @@ Usage Known issues / Roadmap ====================== +<<<<<<< HEAD * Can not edit tile from dashboard (color, sequence, function, ...); * Context are ignored; * Date filter can not be relative; @@ -31,6 +51,22 @@ Known issues / Roadmap * Support context_today; * Add icons; * Support client side action (like inbox); +======= +Known issues +============ +* Can not edit tile from dashboard (color, sequence, function, ...). +* Original context is ignored. +* Original domain and filter are not restored. +* To preserve a relative date domain, you have to manually edit the tile's domain from `Configuration > User Interface > Dashboard Tile`. You can use the same variables available in filters (`uid`, `context_today()`, `current_date`, `time`, `datetime`, `relativedelta`). + +Roadmap +======= +* Add icons. +* Support client side action (like inbox). +* Restore original Domain + Filter when an action is set. +* Posibility to hide the tile based on a field expression. +* Posibility to set the background color based on a field expression. +>>>>>>> 3ab676d... [IMP][8.0][web_dashboard_tile] Refactor (see changes in description) (#476) Bug Tracker =========== diff --git a/web_dashboard_tile/demo/tile_tile.yml b/web_dashboard_tile/demo/tile_tile.yml index 6b23b71b..dd9da016 100644 --- a/web_dashboard_tile/demo/tile_tile.yml +++ b/web_dashboard_tile/demo/tile_tile.yml @@ -36,5 +36,5 @@ name: Currencies (Max Rate) model_id: base.model_res_currency domain: [] - field_function: max - field_id: base.field_res_currency_rate + secondary_function: max + secondary_field_id: base.field_res_currency_rate diff --git a/web_dashboard_tile/migrations/8.0.3.0/post-migration.py b/web_dashboard_tile/migrations/8.0.3.0/post-migration.py new file mode 100644 index 00000000..7cfcc1c0 --- /dev/null +++ b/web_dashboard_tile/migrations/8.0.3.0/post-migration.py @@ -0,0 +1,13 @@ +# -*- coding: utf-8 -*- +# © 2016 Iván Todorovich +# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html + + +def migrate(cr, version): + if version is None: + return + + # Rename old fields + cr.execute("""UPDATE tile_tile SET primary_function = 'count'""") + cr.execute("""UPDATE tile_tile SET secondary_function = field_function""") + cr.execute("""UPDATE tile_tile SET secondary_field_id = field_id""") diff --git a/web_dashboard_tile/models/tile_tile.py b/web_dashboard_tile/models/tile_tile.py index 4743afcb..498d365b 100644 --- a/web_dashboard_tile/models/tile_tile.py +++ b/web_dashboard_tile/models/tile_tile.py @@ -1,4 +1,5 @@ # -*- coding: utf-8 -*- +<<<<<<< HEAD ############################################################################## # # OpenERP, Open Source Management Solution @@ -26,13 +27,74 @@ from openerp import api, fields from openerp.models import Model from openerp.exceptions import except_orm +======= +# © 2010-2013 OpenERP s.a. (). +# © 2014 initOS GmbH & Co. KG (). +# © 2015-Today GRAP +# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html + +import datetime +import time +from dateutil.relativedelta import relativedelta +from collections import OrderedDict + +from openerp import api, fields, models +from openerp.tools.safe_eval import safe_eval as eval +>>>>>>> 3ab676d... [IMP][8.0][web_dashboard_tile] Refactor (see changes in description) (#476) from openerp.tools.translate import _ +<<<<<<< HEAD class TileTile(Model): +======= +def median(vals): + # 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(vals) % 2 else 1) + 1 + half = (len(vals) - 1) / 2 + return sum(sorted(vals)[half:half + even]) / float(even) + + +FIELD_FUNCTIONS = OrderedDict([ + ('count', { + 'name': 'Count', + 'func': False, # its hardcoded in _compute_data + 'help': _('Number of records')}), + ('min', { + 'name': 'Minimum', + 'func': min, + 'help': _("Minimum value of '%s'")}), + ('max', { + 'name': 'Maximum', + 'func': max, + 'help': _("Maximum value of '%s'")}), + ('sum', { + 'name': 'Sum', + 'func': sum, + 'help': _("Total value of '%s'")}), + ('avg', { + 'name': 'Average', + 'func': lambda vals: sum(vals)/len(vals), + 'help': _("Minimum value of '%s'")}), + ('median', { + 'name': 'Median', + 'func': median, + 'help': _("Median value of '%s'")}), +]) + + +FIELD_FUNCTION_SELECTION = [ + (k, FIELD_FUNCTIONS[k].get('name')) for k in FIELD_FUNCTIONS] + + +class TileTile(models.Model): +>>>>>>> 3ab676d... [IMP][8.0][web_dashboard_tile] Refactor (see changes in description) (#476) _name = 'tile.tile' + _description = 'Dashboard Tile' _order = 'sequence, name' +<<<<<<< HEAD def median(self, aList): # https://docs.python.org/3/library/statistics.html#statistics.median # TODO : refactor, using statistics.median when Odoo will be available @@ -76,6 +138,154 @@ class TileTile(Model): r.computed_value = self.median(vals) r.helper = _("Median value of '%s'") % desc return res +======= + def _get_eval_context(self): + def _context_today(): + return fields.Date.from_string(fields.Date.context_today(self)) + context = self.env.context.copy() + context.update({ + 'time': time, + 'datetime': datetime, + 'relativedelta': relativedelta, + 'context_today': _context_today, + 'current_date': fields.Date.today(), + }) + return context + + # Column Section + name = fields.Char(required=True) + sequence = fields.Integer(default=0, required=True) + user_id = fields.Many2one('res.users', 'User') + background_color = fields.Char(default='#0E6C7E', oldname='color') + font_color = fields.Char(default='#FFFFFF') + + group_ids = fields.Many2many( + 'res.groups', + string='Groups', + help='If this field is set, only users of this group can view this ' + 'tile. Please note that it will only work for global tiles ' + '(that is, when User field is left empty)') + + model_id = fields.Many2one('ir.model', 'Model', required=True) + domain = fields.Text(default='[]') + action_id = fields.Many2one('ir.actions.act_window', 'Action') + + active = fields.Boolean( + compute='_compute_active', + search='_search_active', + readonly=True) + + # Primary Value + primary_function = fields.Selection( + FIELD_FUNCTION_SELECTION, + string='Function', + default='count') + primary_field_id = fields.Many2one( + 'ir.model.fields', + string='Field', + domain="[('model_id', '=', model_id)," + " ('ttype', 'in', ['float', 'integer'])]") + primary_format = fields.Char( + string='Format', + help='Python Format String valid with str.format()\n' + 'ie: \'{:,} Kgs\' will output \'1,000 Kgs\' if value is 1000.') + primary_value = fields.Char( + string='Value', + compute='_compute_data') + primary_helper = fields.Char( + string='Helper', + compute='_compute_helper') + + # Secondary Value + secondary_function = fields.Selection( + FIELD_FUNCTION_SELECTION, + string='Secondary Function') + secondary_field_id = fields.Many2one( + 'ir.model.fields', + string='Secondary Field', + domain="[('model_id', '=', model_id)," + " ('ttype', 'in', ['float', 'integer'])]") + secondary_format = fields.Char( + string='Secondary Format', + help='Python Format String valid with str.format()\n' + 'ie: \'{:,} Kgs\' will output \'1,000 Kgs\' if value is 1000.') + secondary_value = fields.Char( + string='Secondary Value', + compute='_compute_data') + secondary_helper = fields.Char( + string='Secondary Helper', + compute='_compute_helper') + + error = fields.Char( + string='Error Details', + compute='_compute_data') + + @api.one + def _compute_data(self): + if not self.active: + return + model = self.env[self.model_id.model] + eval_context = self._get_eval_context() + domain = self.domain or '[]' + try: + count = model.search_count(eval(domain, eval_context)) + except Exception as e: + self.primary_value = self.secondary_value = 'ERR!' + self.error = str(e) + return + if any([ + self.primary_function and + self.primary_function != 'count', + self.secondary_function and + self.secondary_function != 'count' + ]): + records = model.search(eval(domain, eval_context)) + for f in ['primary_', 'secondary_']: + f_function = f+'function' + f_field_id = f+'field_id' + f_format = f+'format' + f_value = f+'value' + value = 0 + if self[f_function] == 'count': + value = count + elif self[f_function]: + func = FIELD_FUNCTIONS[self[f_function]]['func'] + if func and self[f_field_id] and count: + vals = [x[self[f_field_id].name] for x in records] + value = func(vals) + if self[f_function]: + try: + self[f_value] = (self[f_format] or '{:,}').format(value) + except ValueError as e: + self[f_value] = 'F_ERR!' + self.error = str(e) + return + else: + self[f_value] = False + + @api.one + @api.onchange('primary_function', 'primary_field_id', + 'secondary_function', 'secondary_field_id') + def _compute_helper(self): + for f in ['primary_', 'secondary_']: + f_function = f+'function' + f_field_id = f+'field_id' + f_helper = f+'helper' + self[f_helper] = '' + field_func = FIELD_FUNCTIONS.get(self[f_function], {}) + help = field_func.get('help', False) + if help: + if self[f_function] != 'count' and self[f_field_id]: + desc = self[f_field_id].field_description + self[f_helper] = help % desc + else: + self[f_helper] = help + + @api.one + def _compute_active(self): + ima = self.env['ir.model.access'] + self.active = ima.check(self.model_id.model, 'read', False) +>>>>>>> 3ab676d... [IMP][8.0][web_dashboard_tile] Refactor (see changes in description) (#476) def _search_active(self, operator, value): cr = self.env.cr @@ -95,6 +305,7 @@ class TileTile(Model): ids.append(result[0]) return [('id', 'in', ids)] +<<<<<<< HEAD # Column Section name = fields.Char(required=True) model_id = fields.Many2one( @@ -123,6 +334,32 @@ class TileTile(Model): background_color = fields.Char(default='#0E6C7E', oldname='color') font_color = fields.Char(default='#FFFFFF') sequence = fields.Integer(default=0, required=True) +======= + # Constraints and onchanges + @api.one + @api.constrains('model_id', 'primary_field_id', 'secondary_field_id') + def _check_model_id_field_id(self): + if any([ + self.primary_field_id and + self.primary_field_id.model_id.id != self.model_id.id, + self.secondary_field_id and + self.secondary_field_id.model_id.id != self.model_id.id + ]): + raise ValidationError( + _("Please select a field from the selected model.")) + + @api.onchange('model_id') + def _onchange_model_id(self): + self.primary_field_id = False + self.secondary_field_id = False + + @api.onchange('primary_function', 'secondary_function') + def _onchange_function(self): + if self.primary_function in [False, 'count']: + self.primary_field_id = False + if self.secondary_function in [False, 'count']: + self.secondary_field_id = False +>>>>>>> 3ab676d... [IMP][8.0][web_dashboard_tile] Refactor (see changes in description) (#476) # Constraint Section def _check_model_id_field_id(self, cr, uid, ids, context=None): diff --git a/web_dashboard_tile/security/rules.xml b/web_dashboard_tile/security/rules.xml index 8d653b70..05637bfd 100644 --- a/web_dashboard_tile/security/rules.xml +++ b/web_dashboard_tile/security/rules.xml @@ -6,7 +6,16 @@ tile.owner - [('user_id','in',[False,user.id])] + + [ + '|', + ('user_id','=',user.id), + ('user_id','=',False), + '|', + ('group_ids','=',False), + ('group_ids','in',[g.id for g in user.groups_id]), + ] + diff --git a/web_dashboard_tile/static/src/css/tile.css b/web_dashboard_tile/static/src/css/tile.css index 1d057cee..4ec483d7 100644 --- a/web_dashboard_tile/static/src/css/tile.css +++ b/web_dashboard_tile/static/src/css/tile.css @@ -5,35 +5,71 @@ border-radius: 0; } +<<<<<<< HEAD .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; +======= +/* Disable default kanban style */ +.openerp .oe_kanban_view .oe_dashboard_tile .oe_kanban_content div:first-child { + margin-right: inherit!important; +} + +.openerp .oe_kanban_view .oe_dashboard_tile .tile_label, +.openerp .oe_kanban_view .oe_dashboard_tile .tile_primary_value, +.openerp .oe_kanban_view .oe_dashboard_tile .tile_secondary_value { +>>>>>>> 3ab676d... [IMP][8.0][web_dashboard_tile] Refactor (see changes in description) (#476) text-align: center; + font-weight: bold; } +<<<<<<< HEAD .openerp .oe_kanban_view .oe_dashbaord_tile .tile_label{ +======= +.openerp .oe_kanban_view .oe_dashboard_tile .tile_label { +>>>>>>> 3ab676d... [IMP][8.0][web_dashboard_tile] Refactor (see changes in description) (#476) padding: 5px; font-size: 15px; } +<<<<<<< HEAD .openerp .oe_kanban_view .oe_dashbaord_tile .tile_count_without_computed_value{ font-size: 52px; font-weight: bold; +======= +.openerp .oe_kanban_view .oe_dashboard_tile .tile_primary_value{ + font-size: 54px; +>>>>>>> 3ab676d... [IMP][8.0][web_dashboard_tile] Refactor (see changes in description) (#476) position: absolute; left: 5px; + right: 5px; bottom: 5px; } +<<<<<<< HEAD .openerp .oe_kanban_view .oe_dashbaord_tile .tile_count_with_computed_value{ font-size: 38px; font-weight: bold; +======= +.openerp .oe_kanban_view .oe_dashboard_tile .tile_secondary_value{ + display: none; + font-size: 18px; + font-style: italic; +>>>>>>> 3ab676d... [IMP][8.0][web_dashboard_tile] Refactor (see changes in description) (#476) position: absolute; left: 5px; + right: 5px; + bottom: 5px; +} + +.openerp .oe_kanban_view .oe_dashboard_tile .with_secondary .tile_primary_value{ + font-size: 38px; bottom: 30px; } +<<<<<<< HEAD .openerp .oe_kanban_view .oe_dashbaord_tile .tile_computed_value{ font-size: 18px; font-weight: bold; @@ -42,3 +78,17 @@ bottom: 5px; font-style: italic; } +======= +.openerp .oe_kanban_view .oe_dashboard_tile .with_secondary .tile_secondary_value{ + display: block; +} + +/* SearchView Drawer */ +.openerp .oe_searchview_drawer .oe_searchview_dashboard .oe_dashboard_tile_form { + display: none; +} + +.openerp .oe_searchview_drawer .oe_opened .oe_dashboard_tile_form { + display: block; +} +>>>>>>> 3ab676d... [IMP][8.0][web_dashboard_tile] Refactor (see changes in description) (#476) diff --git a/web_dashboard_tile/static/src/img/screenshot_dashboard.png b/web_dashboard_tile/static/src/img/screenshot_dashboard.png index 9cbdeecd3d601ffbea9c197ed5c71d2480371613..65cfc12753e9f451d432ff0cb54c85d3ff459a1f 100644 GIT binary patch literal 20441 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 GGywqSdE~|b literal 45633 zcmb??Q*>rQ({60r$;5fXiEZ1qZQHhOXJR{<*tTukXTFR7`_DSp=UHp--QBwyRTtgW z-A_fx%ZkCn;J^R@0l`a%3o8Nvf#Us37eYb&dr#0$#Q*z%ISEQAL;Zs{lyUgKJhZ*I zh7%AF!r*@%;1p^E+<%4G&LZm0N_M8sZU&AfKxVdfHYT)AMvf*Xwoc}D&NraFyg)!i zKoY_N%I?{hIcDzYOUwQ{8A=O6P{FCQf_4ys6le+L!f5i=lz}fW;j8@JP=U1J;9$ai zjuil+6%g^1ZLgaGFc2_7Psj7*o004!QxtiN`>79Z5BAA5udC*lKaJ12Or21bm6fOe z7dAl#xvKqR|BLDFC<6Qc`#)oJ2>syj@HRA$^LJjI@mQi^?}CloiK=4u)tPIV6ZM== z?sSgeiwCD$;Qr+`A~0lMq6mdu1taGVU&NKtLx;t)x03hCpP~mfi+k@e{L7DI__JE^q`pm76#!kBX1*;Z;q-u(J-U% z>u@rKjsv$o%bifU4|}*d+TVH37!`3;7f3xxkoso|ghI~jp)E2DFNFRkPgHQ@@TpE| zOCPR9#e|1ta$!ujb97D7k;IiAVg&f_$gqgTzqSJJH&1*IW5P6%(9uOMkhvUI+3s)3 zDGLh;OlYOmL=<2p&`KP3|Sk|+5FTi^k=%Gr2q7S*sE8n z_?km+$cf;_;7Yk&1)mh}=yGGyaxQC=7{|1AN zxrKN47oE~GSo~}>reZU9bJObn0Tan({$4?jr;CE~B8?(j;ZB1iZZnp(9yeGdr`X_y z-HXa~jUHvIkS6&sGj6=>f;pO)Z}q`4{T(IAf~TAe3jO;7l&;O<=t~0($vc3i4@?ls z9{e6r2v4*JCtYOI7aizFGCg=m9#HC zxY|>M@d%(kxvtX_lqwdV|CI&z8lErTcVE{gyUTU?ixJU6Ee5^P$dz25s|)A55$EnK z4_P->6wr?e!(RtvON4)meq-Hj$9BGy676|Tn|kujjoPLdvD4u1przW#bqzVpgB2>E zVkhYlxV!uMhhE*MANpuxu1v_pTRJVGTp=LJ5nb?)D42jqx5UvGIvfOY5fBj(PBc`Y zJU`)_Pw1M^$M3y-Q?hULDusTB++d-L^tWTqWxR|D#9G$Aw8RU2hVWcSXpq9Y>6H&x zl9FtL)v5`N#N&2-27j(FRIg_y%NeQ`c)vvYbuEVNKdi`T&p%BuCTV1pT46o3)CR1j z@)eR)0DwWTx;KAafF~rRAVed@FoS>pN|9X8yA-xJi|a3k5f=Qfi4cYUjL8htJ84|P znR~HZ!#97VPpS%pKve`FQHJ-xcqg+9AKV1GKl=QQY#Paj|3(nNltMy%@^C(`Vx8UT zuOSy^&@p}UGVD-yQbhIXxDLE`<^J3cHMwsBSgGP~Q%;d@M3(3AbAte$LtTe47qTkI z=Y3v~zJ5ltyP5UY)jzUSZpb@XoOY3RH^lF~evhrrVvuM(ORQZe*D_A;&luI!3<|BY1OW66G-+y0kO- zJFaT|)BP(>wGG!ccZDNu=vSUZIREWkZ9QRP-)18D z#Qs^2B~Q)@;Zgsb4Fk~lC$xG)%?VJy*l43;((TX4Js3+!Ghy^nAp8&3wq{e<>%v_& zS5K^j4*;m*&$l^Drwv=Jh_J#?ZZLH0XtHCE+_x95p;$n!_B}7JRRoHsVIs%S9kpCUY)Ka zcn-E%)AplqqHPa7zYTfC*Q1c%nsvxn1CY2ciATIKBwqN9xpUszGxRcsM#EDN9w2}W zOqM(~t6TM9_&^L z&Y&PmTlyi{dETU!i#NrypohGBKH4J)H2He~_fHV$471lk$8eFdgT>bZO}PgNtrtxB zF4#CL&wGlYd_;wu!m2XK9(6fE;|Z+iO$n!%X2-@Y$E1hU#9Jgb!D8dy-G4{>Aaj&s zniOi2#*1w*j9Vk9a+0v>M4asJ@@Pslcc_a^O7GR1n}gLhCZoYH@6lP*rY~j4L!Dh` zE&m{{MG)uwYiK3;?cFOOxB4o0#by3TgoJB4Gvm_^6W(gAd~`5zd?7-Vuc9__q=QnB%0`t@lYv-3w3SnMYliDD@E;a z{SdG^6z&6uVG-k{>j1A2=`wPjVxx#rpk-uwqp@(`DRIVl+r_yc0!SBb)iHIxBx~wM;uh?fjLD^#f z0xO)E)j+JVZhYPGc*Kz3hqU+m;=t>jE(o1pm5$vq>`$Jkp$`L!(8O^1&MV5!gVwEI zHE8Ma9@cd);e*=;13;69R&C{gtqb?q^ob|?uSqTX@Eg9Vzp;k zSP-v?vd(_Sk#mVFkWe;ScfOjKjiBZ@a6ww}-8=h_)A4@ywf=MeZiH`vvlQHd*!!2Q zlZjt;cO$pj-Jr_Ut&H!Q|BJ$pgyq03w^AW!bhKtt+P;YV=Q7~|j?Y$aR4cBjWaO1( zHR*VP4G>vQ4*K@(cW}B>0o`w?jhz>mL{&&djE7G zH(xD-rl3%L`h00_dLujG6IEhLaM=07Es}xVGNr7Sr3EK zl8tBWni8ISbAMFk;EnY{lYoINATP1Q6{axbOhV2XSzd11WnFf|_{xaMMS9vsOEG4Y0On|+a20XW9uDvx$Cg)e#(WvpX1w-KdjSCp@mB=~q zE#C2)ahR`>;YwVPo#pxG1l9B1J+*+sd0Swp81)u!=ch<>9*U|mX59ZpgSfnVY-Ji& zygC9cHo-rtN3cWM{x&kzcK%g%JeJY@gCzvvCsc)PVXVg`c(Pg%{PLMnt7cnZ_JbY# zk|~lFhfq&)29w118W74;ruY`|)^%$I$jIfL%5hAHaELPBcKg@6-kkTKXDPnpi7aMP zW9|JCMO64TPs;h1ukmW+;{J!0fUpBQ&sQ~KKrzW7Y2X(Q3qiQa`-a^8TsW3xrVLSE zGYKR%t2dnsL9V3xr85rPd(50wV?DZs*IyTxZcKSPTf=e3sS}q>)&w;p5C$05+p4|; z)Dfm8Bcn_<=EU^EEwClugpwk?5|tFzSJ)S1jBhN&-kw0CTu6=kp*#zcf9{=oBt3?Y z)D8qb6iQ*aycO2LvMEs~3YK0cc=w7q@6F&S0@yGO35ySWPRO}>NR2najcCtnlGyaZ zq~l)yp4F9j)OO>Vwt%6vs?dH4665Vj99!46}8*NR_OC^J5w?q+(%T{E4-- zlYn@Pyyn~5S|eYWh8<WMp3zq6ucL6)Nsuo>_QYe}C942@nS1gPlUS zGLuo|CIOdNJvd~&AtbQul)io5Fc)<(#+SA}`GDP07JK~7sH@I2eK(Nh40bd zU_3j#e(h!eZ>rTQs;`*mfsP=CpZE|mq0)5{8@n$8P0qK_YEjH@tl0egqh_e}$3knO zD5Fu5?S2zTBPL3EOVsU#6rI%r*nKpHSE%z)BvULA8lbYh0O0)F8kN%a;-y zc`Vuu)yL8&oLGgN2H~;9jk>6U8+@_5W_{KEHzjYk`(dk_`Ze3h{Jo@#h_<3QA8^Mw z7f8e~z>b z6x@F?wO82hK7?~W@S)0ukMzamc&2XhV)7LqhPt#(nT!biLU!iC{^D%OwJN5qw)s-! z{aEphHDWRrUZWo)c&0*+04Z@;1{c>^e?pRZV(hH*gx_uTt!FQFt+Pf-%B-WJZuxt{ z7n-jXP|*5_Y}&Hjm*}}W-3q&Q5EYv$X}*)!yZyNOV)39kP3d_wO8)9U!^Qe|oftaj z>`JifKV$h(216E`2amfFxff0j>`wq`Km|kY*N$}K!v>?=l?FA#a2lRAS`@&BD=|k? z33wzi)A)I?vu0mSMbBd`RsCnFi7rgHl-Y3k@l2;S=ij+<2i_5xPe3|hkK`unKd;Z+ z$+kODZXIevGxpm_GeCtRS-PP7jC$Vg8KjWGtO!6wCpuM$qh5N&NV@$X*LbnEYvOsd z{(4X;pucE&LQHo45OvKpM#D+$E~Q~UScUSd=e#>3N*WD3lMKdmji$(b{3d5i!Y=YN z*5=lSD>bdl8Cpn7(f0!3UBX2=a7t`$`RZDIfjYPln=cUHz*&yXS9!>Eegxjs5Lc69 zFn%O&Y5!Gh$)fpYTz7KHVJag%qFv2bM2+q}|Hqj8_I#ojqt?m>c#n|pNV3n@5^@9> zZjO6}3<{Y7zz6^l6lc!+{wB#U+!u7oIjXXayFG`PIuU7&BX#-URh4m1TC$>V@VV$M zPva6fWw7J+jBaSIL^hQnyE}x~zIlM2+83L162zmbjWr&Zpj`Oi^X6uU;oGzCp^_#B zftdM`yO+pgr#s?bLofy7w&P3g?&2WL1uXgWd&C6s$>cxC@yoL>NeY}dFMKk3gQ;-R z>;*|?y}2ziVCbS!?))L?meezTx+jZ1Z;LCIiNe}>gh?WB4^{X8a`HG&l{MJAeUWc*>lg=8M4R zYGLaBiBdnOKQ0;#d=cvI=rPvWcqQH>Q>wAu9}op~jE#ivTM-PWLLU{#Vz~x+0+f#k z@PJ#gwgkbTx|Qow4y>jiHa>oQX!MqnUHS0yWcHtM1&wAA8<$=rhpjz%VYYm32YvuC zW?Oe(%EdefG}Yv1XjDL$c$B9Eu371~D@AoVqDAwpH+XB&WQjr;qIbp4#hGC~8%~7g z(hwfj>Hw6Iz_X0jx@c3=s6pA+yy${qrLsRWVSMp7>TWNNyJH1jO#PO7*i8WDD6dph>@}X5=ey!5bGK2837L+W_~vzu`&IYT-hO4+=j_c4{c*Z z*=T)K&D))1LQ%ho*1q8^Dj>mO^< z^-AxkWt(*4i9UC7o%ML5>)_Lqn811`t@hm!d}*#~rw1WI{`EVGk(!T$0zdkSV(vUj zuHt78Z@otzyv?84h_;^IZzuY}^R`sQG>_^E9R$@z$e_bChI`Oup4^ApwP*jw%(Gt<^ku*IyW=fsx? zS-Y_2;lfJ63I0!N?aMl{u-yqRe_F-HYL6+p*7Ar2FTE2XSFL)*atmzrgq5pWrGZ%oD}5N5 z8%z?0{o$B{;Wnza!YeKOC#Uc9=a27r7^>;-n-Ty&@k5!-!TvOTx-Z=A&E%nsmU_1*>;<2tM&Jyn zU?-zPzk9BgRt^vz>9s~bA``E{;w;74YBBm3?*@NE@qULRa9-%#;A7s<4YluKn23`{ zBWs@s0y#U(Bqb791~qjLjljy4afI8zVpLW@_@%x1S2c@2Qa?f@th_)A6iROHn#P(MWO!6vk)e zZ+HE~0AaH^efNrg>CL3wseCP=N@l&UzHhl53)VI|?al?g<2Ux#YIny7r7F$)@8Mdb z#=R>#QNo!~3v#a|%)v8ofKIxTC-q0H_0gzWHRTyX6nf`xtAi1^Gvyp2yzH%}z_S~_ zNmw4jGF5$8g4Y>{L{jvPH(2#7(FKQ7>t{mk!AhB(J6%wjR{RnCa`1CnhilG`(n`0u zna&D3cDNqm9{!ds+0qR-a15PxeiskktTtD5V({G_&c{EV1dCNz6OaqNA*1guC}JJ<19H+d-XE}2@m(8?JQEki zHEtIqM7i5@f*>8+_8-L+zT_Q_BhV+ayJKr4YLFze7GBFpfC}xPMEkD9`;S1#^x_T_ zoB4pEi1z%f`Bs2%p2eVB>sH_kOgiMdGcqP{o#YX;|Ee!!aiQ#djN325mw;NLAc2ix zGmZi*Bz5h7RoTk~_!|rdkG?FqlhNu}6Ne$#9nYuV1 z2_K1;g2;?Drd#tn08>?&4xHMrDR=B`$QwQT_BSFf&FmYsr;t&-x7b)of9%Kjewk1deT+Gn?N8EvYU4-|j7qfE6Z6aRTPip#Zv4!*uH4%_y9nOb(XJc*ftx75y*=i&1 zw$TWHJcq`*QtLYxGbXy6QFfp@90QZbTfatSnbV1-1k z&RUqXFFgHLRpDLC6gBhrhyE_a58BAmXrCM|s8(}ed2BHvMQni<9gIcNOws&RN3AkUR#6V_ z+sFt&v8+Gn;_PC+7r;?joF8jHtDGz70k=odo?EC_wUgQ6XR9@k!quKi=FM zxZG}w{h87kobg&%{hYgqHt)>j*wQuIj-Hy#X-pQt=QW<0PSSRD*Hot3wCG^hDXbZ3 zKlF~DU+x?@*&6g0>enRmw=8y)mo%8G(dXpZ)!{6XxjEZm$&x`J0ri90!(L*VMZe51 z1ySR--}6x~+zomT1>+Y%OBCn^v(ztGi+{VR0jul`wu}JNpbyF{FBxjh_f{N*O~eb= zF51oIH8qxC+Ga#-HT9N5M`hFp@Ap3?(O35!OIn5?4akH5BfXNJf8LSn+KtrdzfRMHYivlLC1a-r)n^}Hn^9lwguNy z&!{P?N*XV{+)sWND*&-{mjY22tZYL3=usX_M?&MiAehGx%1d+Ls?z^7h5p`-1|g-g zR{?I7yjJoAMo)@QqeK-~;a3d?0kwj@=h>Kh7Nq_jDoLSf6p#FKG~v}s8V|gRUgyqK z1v17M4wL+(jRKCYC(-C)73Z*cp#Y73wUwg))GCLq-n^NWLyA4G%uoptxnU#6FS`8# zis?q?)NE)L=(#x1DhemiY}j@aVOD-?4#y>DQa~Uf2%SFJ^R2g6Oe0X=UGY9kMDw6~ zv`bYT^MGj}JakT{yW%Xx&PtNp20h6Kq@q%LkBDQro#;j(-rgi@#V_y)Uy+J2hx<=v?=U11^+G-OxIgtVJVCa(6Z_&s~1RQAT2l z;)tJ-Wx1ImASM>?qXTfKUm(vJwM=KhWij`^w8hkxv~wlNn+VVO@X`OI0F+{c@RFw+ zPUDkg=RgWiz5y9#r+n^YS=l96uM&K@ck3xc0o1U?H1aa-wB`Dwtq&q1$&LLf(2@ly zjFpKqV^q0k7DH=!5kx|)ZH(M+_g9MKW0a6V7KNud?6i z%0rDv+QLomhU#v8NvrVJ((#u>osxAtDaj;|uiyEo1==?6ZU8x9VJhNESK<~o+#b(s zoo&8@-C3##<{y?vZx_fDsA7#Ya|qW9;pe!AbZ?07I(0QPspTc(k_Lq~NNc&FGEpbX zhG?F7-eVi-lm4(TBp%j$Z4HSVPZABQxZNT62ao>FV}5yHHh^tk4%;;KB1c5wp#%x0 zr9t!TNurN#U2Sk6u1$Vknkv#(ZY#q!ECA#h1ULqWGWWY`Q;G2IXyJ&b)5d})=Tr^i zfH-aj)i{n@!V5}1aHg~6%OHn>%}`2Y*Ez zK3AYqm5D<}WBt)9IPJZg|G9W2f=fI45XBk&6CmF_s5aG_mh~E~FpP9O(8o%=YdUml zHOXfoBEav0^?GGQaWT)&7>c6A5j+b491L{HH<0MGew9YImfkD_9K9IRplF{5b#r@t zGcDqDJ5o?EPMA}6q6r)=%)A_0l~DnRSx-0LQ7uVzj(xI{t$VWORM7(812wke9_gsk z{2o-Hx};(4WB$vM&Q29{N1~MO!VWLO133;|Y(>GI4o4*4BFO+f;m8gN_7Y)mZN`GV zxFxRX>EI|rjPrqBdy#<#XSfXCvbGiTC$LD`tg@9EbZwQ_9rq!_8m#Y-Q*8DS(cVm4 z|Bq0`xNrIe>!Pj?L3YqVR~ckmSKU?ckF=RdEa z|CA_cWMr!Yp5p`g)x-m8$lUqy)s6W26s^;Uszz*8CT;B05o}y3bYU3~yll67=kcJP zo4=Oh>_O|)@^AZ9=I{ohB+wNQT#4~Rb0aE`RuY~sOnaw9fB|5cD($#$TsOM2Y5r;N4OaI(U@%o+c9OIAoT{|1L zZjAM~#|Nna3y-V9@6L}OkplI1_wM%Q^^84i0pb-er8KBhaMJQGEGPms4-ZECh+sk$ z6X2{Z!SMd1cO|}IDp&Wqm_2M<(*BuHj*s3O6b3`ltV%TX5@V}BEL?_|UrL%>rvSz{ zUxuYy-Km7}@Y&ZB0UxUFwrMW_HrlfyC&mc|iO(=CobySs*l8nf#-q^awP4el;iy<| zOI+T$UY+bflQ|ij;)=Sl0|zzEHrel@jm~RJ)SzHg$hOdz6YcQEyCMtWU%LfDVZ~o~ z->{uwax->=XhtNbEy8L~4=>jXtbyjhQXYBAx+L^huLl+4vf#D5+kHv*QGf8L`~u@yJ1a_U=8&S%famv%1NV{OpTd7ld6I|G_oz?_>vWr2lR<l-0>nQse9!FR9Y-QzX0p?sx^!pgyTTPdt7=@y#7MHXQLF{+rS~7?U&3 z^@B6<$a5y%ChxG@;ThkZ*35iF{Ke6!k6jiJZ&udeKAqL|tS(Yhf=1D5tizV=tdDd< zkmshfW3O+2JKOgD=hP$qXl%v(K>!Pz$Z%Sbn;wPM86Q{VqVE9)Epm`1Au^;RyW2&^9@?#hP5NLawb zgkq0@2ZXYW;rZGGoQ0WzBYMVbl41n?om6Y>D6Wj`!(J}lFkkk78nP)sy+NFv%z~>u zc*XSf%T!SDkAKvo2<~a_ZkU~5N0}4E6QUA;wDK9cY#`cb=oBZI51t?_fSPjh$N`8>9Duot03a6y_JxPM_`#i>0#0 zRK3&0Sfou5mEf_Uw_^Pf3>4U4G%>R!^~m$pz?-wqpk%YXW&?)@rvfg!nrG;(>(Q+g zH9YCw`xD2rwz>b_UscD%?s0UuA>&C(vQr%9hZsY*>352PN&sWY*|Py2H6g+D{ozs9 zh7|`P7?|PsxG=6R*uv3P0`m)`Q_ul5mQy&?$ot*ad5k^bAGX{NfLY7ApZo&^R}f9aaH+*u8c$i?@dDcIK7JY2PhIKyWc6P)0F*p6JUU%&RWv z6}0%P5l}7EKNWKkcIas|SD=5ZFLfGePV5MQ3t13+amMNug*`~kJL+23Wg7?ts53G) zvxtB#IE{<1g9o+0^VPO2sEh8Hd|?g+VV2``vVm!^_(qSXPB!>08P3QvnS{BW**;`(4bTa;L8(FKdwZ7k5C?cXtkvV0?hYW$m{2JW^GAiKPhH(UeeTHo*7rFU@Q~mpfC!Z&c^IHo;?a*6R z$HkDwj7C5WU7#ENBw*WDnMf%lxQ=)6+v3-p50_$xB&DD$grz*0Wb+qh45n?N^h>0+ z(r#t}PQb#-?6F=B6kSrR)e1rKu4b~AE6kK>k8o^+mZReNj)20ic5A}(Z}u3?YAYfF z9ogwrFq#;`vf)2^P|+~El@+{4reFL;u`czF$Y+&=N02>&WIKf>k^ti@D<#u)M@_^C zvSLLj!F`9#G9?BTYw;34xq`F6diF1A@i^)HF`=hAtOonsj$pYH_Dq-A?dLT$TY&v` ziZhSS4Q!v!%WGe6NFn8D0V1Qv8)DZ+Es4UCAaWyPLLjx`&G*Th^Oz^ODuK^Tv?dNFc#EJ-{QRad@$H(gUd+ENOCK*!xY2Vg*{l7+p)I|4g3QIyR+zOQoz#%wvX zI#$b2nG4*HGt%7cW#3VM4Psr~Jv&-|itJL15RK?3bc zb40yxwRWQMt>UJsi7)JYA)>uvFNuAb&5;%1_c7u@FRJC_=>3IVgSHx}`xi^G%3bFo z>pI|{ORQ`Rm*T~6v+GR`cP`$TS%AgJ=n$q{I2ZJ@f3b!8TBC<8Ena>s38&GX81i!_ zTm*xCsoR=I{j2%(a~bQ;0^sSGC1F)2^G6Q!C_B|F0~ZO z&Fu)osaPU^B$0Lc`!0tf_{j*KT@LToa-`$4okz)V_IUw|w;NJq%m&1cu zMii(?sT>y*V=`8leaLvC8-itE=T ziIm8O05xo|BtcFCf6Pm96xb*8S~1A4-1j%HbL)r2E5_aD#ookH)b$J2t5=pRawVC< zS&tc_WQc-5axS-8(6TZfx}Z#iz`U}W5}r5wTvsL_HU6pRWa|7Yh}4W5U9=J_gw_Y{ z(^Xy;jRs?hyPc8YhLf!QUV7-8JtqTVWd?pK1uGG3TC8@`0Tb{B9<8I$NF-Z-B!LYX zNkOf$1WKXE!lT+Nj~_SbKx)QhjDlDNDL+M!ESM!YBpS=N>4{x>ejXcGH(AMbxo%Tl z4vB_m9gZM!De%~~=B>uR@auY|AQU`jme~Drv&MQ#%=myvq}{U%Yk+oY^F3M9yO_Ik z;%uqI8&rIe<-2wwtVS-7iEz2OzdZ0{?p>Bth%!3exMn99l>Ab8b5=1%Q`bZ!Ip1df znYUmd9Qa?jp$khTyPJbx@|h6~E3f+c`mUev4?m3-%E)wSa%pl@(IVGM*8D5!BgZ}0 zPA9io#tiB7DN{HI&_YU240)+GZ8}nkzvj$_&6Ytpom;xQnM6?RcnD}B{f71W%s3A1 z+Uz;9|D<_&*8?gM!k%r(dhuE}Vu+y9rAt9pOf-hAS&dk;5=^km7BaHb(1t)fGo;Dk zAZ*Z+3e7KA{+$9;R$`Q6n#=iv3-BwT;UPfUws!7H92ADnnGagCVwyL8Uj3S2ETlYM zR?+G#JT84|samt1u5P87Xn!fB)QQT~b-lpi@qBdg*-m`X`gsBoMos_hM}rb2v>8VN zj3U@nhjPK9QRo9D(WeJBEwqXt-+)+ZV-u}4eJ(R*YJaH2J2s&!mcmX9e}^i)2BR`s**wbJSQ^aor<6i_DDe9uv(#?-4*&OXfb0f~}R> z+*wh9i}KCjptY9yfLF^#N+ksV#Tr*nb^k{%^c5TUb3-vZs<{(d?fbo*csgSJ`%moI zT%9U&*pBWC(xwg=EMx|fLoOdJt;gzWA0!4M&)6~*`$JvSTLFIleqc%{btH!TeZl?| z`aCxH@Z9<&@{yQlf}QYi#C2h6n->~nCJ@sZ*B%5pPMMxS*lIUM_s3_5RLP!>irfyb z)~zR5R5V~Ry*F?Q(UazkR$9si9%h}cvT!f8BAE6ofZ@2B9k$~}8>NojuwpRoN&RYT zRC8yRH+Lxv`#pSobw1AM2F^+-Yxpvp(guJH7mTo}APTM$zpjWDNDeaAUD(XRaZ!2~ zY(1Y-OlkzX323lpOwDAsoFdQ7pou9DFV3OdBIK}>2lUQa?rj^~x{T$^(WMdC;t(7n zI%(X z`_+d`l7&WJ5}~D*74$g}FzoQOeo`wB{9J*@U#+fcU69TvX$LM+6_KgaAFiVJU?LWg z}Ew^;pY09*e zbzZz&z+uJU^p%k#DJPl)i7;o9y50By_M?55ZZ{e^+*wb^<3dVeD8cJpb%o?jeb6R> z1~;NBnG=}%uwO5k3uiP8{?Da%$DrT0Kl_JXF5|sbsRMhX z@K{}biKG@3;g}r=hY(P2pkbc@YI_1bY*3>+7~9@&8v`F4ZhNg_vfr%F=QIJ!Dg$s{nZ z(b-`B>FN`>qw!aJaHg9z-EOh>T>smM9u7DeQ#Gl+LW3S`>bgN@UaL%A;obJ6Mk&W8 zyYQUJ&-a8lwhV}1tTgklI_xC&n2!p%r_Oymgn(NQ7Q2yEb5#!BwAvNkKv5l&DUw-! zDV-}m9xIUNWYNpG_BQcwalrt{LCm}ni!8}h`Sss)3kc^%f0nyr4qDkH@acU&-+t>& zzVNsQvC!Hl-Y;!bDcyB!({3L6gEm1pSom4iQ~%+1hZwbV5KCI)3HtnG=K;O>6v5bj z@8^=A$tx|tI*m-sJA&rDKcVFwlm9M40JldkSa^z$r0WE-l|xbm@f+0>_Sz~cKeP$( z;+b$N;`yStU2oVz^*G{Y#6lSICUP0Jv>$%^0`cv=UU zd9kR(=)e%$`<%Ww^`zg!fAxgy^<&Xd06i$Ikx=Y^5!&we*z;y1?xpmx753e`fjwy_ zV4F8(ODw&0d$G1xz^nXoHBF{xrqJN#udU5#cdM|Qd5BGOQgrL1iY^ax<*u$S>u_&k zrW>C~y`y^jQ+Y3j593X574*p$REehJYS7-$eJBAG@_@Od`$Dtbx9izRT9Y=-wMv&= z7LWKoz~%6S`1Va%X8tB}_8|5qqDL(;a^XZ`<63m}?&i||^*P}7cjdofN^|X5bN^q1 zo)Y|p#xOKECH5k6WzSa{6yA6-b8`I={aBMKu)Z^A@j&TC{==(Ac3TYV;)%6`BtFYB zxsGyXuuq|v3=P;$VExPEhhO?ev{#Wf(6_qmv7>^2D#TjatI-p{q}TbcCezvARm}$< zs?s!-w;9~P$yq8^R+y3b3f@C6gu&YtLuhYXQRz|-eBSdvnzEK5?^)LrM)`i{0gLop z^Y3c8Hz_`At7*WW|B$D-3?-6ls(OLhzMVSt!+n7!&Nj4mxI!$sCNi;$us)3u*G0tU zNK0|!;JuS1dUJ@hzN~18IG^ubrT?*ew=%rXUGp4j6Pt}_Uc{P@o1d`3S>w>~Ki+n~ z|FMq?!z14ixvXD?AE*T4#j`)y6%^v`r_MIEwp%fWa;N7Bm+uFwoGN~9l>sj~Qe~~a zCj%}P#@`}dLm7ioK4mBbTybqqZ!@TEJjI0SBR=(dO!i^H#89IgR5Y2*fi<8#C7PGY ze+jc>I`^m}HnP9c{F2y$fy{h0#N97J$a8wXuIwq~8>Vj`(p%5AUj+bIxO;?)A*MEB zx6j$A#*}{b-)mm(bZy8zf^4E!yP_!PGC(#>jmLhwcX4d&t|H7XN*z!hp z;Alzr`8?qC3J?zvws?52TV9AHGZWmr%$VFGgQmoc8I6%ywDw==a2Ldi7fgy%s^;_X z{b7k-J$bX57DnHq0w(l+jf^I@<`fGDKWKi)3&Z5v`I$OV&8yHN#Vbx(_a@#*{erta zx-lp|FG4@PzBzvQtx6}JdSUkF7tLaX%KLRQ^7b^-7E4h$PCnWm+;ziN{Cf+DPd(sF zj-ZbYNFdO)h1);QU5gfp@Wa=e?-QBK8>rxS$?s2z9eN;vLc)?twL#4i7~kUyF32MN z!cCF^=sT`}&p8m9)|=UPE}>%t^2dvz+q2&KuT>F76I4rAl(Odbq9JOk&aIJ5V*5^dG%82(BI$!D@{pD!*5KfmayyA0z|2xTquk+^LA_u!ke`yr8< z?-WRHh(%O6dY&GL68$eb_v$@DMjNp1Up@K4vcK+(xRbSjhH^{Ed2B0LZ{9L#unrf?Yj{9 zdK3bPh#V9E18E;5KWBTHY~sK3;dkxQ=5X3NhKDAjW{u@Zn`vP}W|Wj=**UK2Kp?Cs zHU}|ZmkEP=KSG5>DUU|tdw9h=lQLZU2z^?#=hByy1BVfbPiXXQB)70P+z)553AQ@3 zVryH5;3%WQ3|_y+^IG_$@^gR@^-*l~_^kQK-47^=^-!R2ZkY=;xJ*803g4Sc*Jm~? zx?Z(tj%xhK%L@Zh(1fbD(dA!!V(-MKd8}LlGy7ZOL>X@2b{CQjoLU?{t+~zQu8sG! zY@k8tzCST;zH=krDeSt4pgguEyL@OVp#T=RWsEn4{09PZN(+fUop=a8c03*<(Z_Wj zbHEKZ0cCBKmBe7J#t_>hH{g9ZV|CDk4vq`TD9b*RaX}ZB zK3A1HSUoC&-%8Jb!<@;O{G3IfPHRE`s?HXshe-aUGQ)Bkh>f!^X}%i&3XB5`>7&!a z-`2X^0nGy!`ry;F+hd{Gy&Jt4L6t;csz%~*isE5xj8}_1pQ%D)`bV=X8J=*rHshm5 z8{$cFMy)r;FAg?T;G~n@QT?z=@juSEQ0+f3t<8`M?e`a$-X5~~Ls?(tX5GHASz-m8 zkjy6+16k}Y-ke{=wz9i`WZSXZfTILfzp+7lx3IX*7&kTk9%6+kyL<08$J;d`o^P=v>lm8p3<0?IhO{~{_N#2ngb3R2DI)w?7 zb4s%-i;}^vUijw2`j-Ts*-u%2os}9T6vd?M3f=w7fx^Yg;tl6T9=mrku&A5@D={L^ zY}Foj;@(;e5`rbEtLRi_(N;g;(YZyh0mu}kg~Q&kM56hx485ZbB;3VSu`KPsI9pd7 z?tF%K3ToD+$&fdcgntW>mAJRhG$bAbZ--u1s)}8Cg7KQ@mDq#=IA&B2V^U?N-8b!L z7zxm~TH2l8<(8W_+R)GI-O6=}Hb8<1NwR!CD*ti2cqCE>t)BQ<_tpxyo~P4WZH7;s<(uPcfG zzSUhBgkSlR{SHflEGRJ$W{;gIaOqANW&ZCuo4?1Yd1d8+0+GfN=M_}e3lY2^x`FvKn9CVo$i2jj?E!`K-e19VdHlCiHg!$aK~JHb(Cdk@ zz{W6;`|DXyWbiYG&DxdCvK-yn60lAI`kuWH*d$!4!}do9^8@XMgOJ{6cFS2TdbFf# z@_Uc9n{%b`HtU;X(eMi%-yPR*9$uIPA_9ljCt;YjWqu>9&Zl0uGe3^`i>=dE6&J7f z6&qNq&HrjRo9^n+GkHjnhZbi4vJsem&hxMt)bD6z;d5J>lKbsofwIlW2^^U_`L}lE zpwV@|g&+mFBNoY2G`Xus6*M|RYVw{ab~b8j+y z$n60x*tFlzm8?w`P9#c6(M-BR__Hp!@L>ogbQY6uuBaU2CFp>Q46#@D6x_OnlaLRO zhGwGGl<2~vxx3-4w{kg#U6Y|EAv|=}$4MW!*q`9GR}Jayj<7IMUy&1uj5hMv$MgT; z0-(Wq>H_q-K45L^UV|Y9Om9yMqfuToZ%Zg1_S*DL?H?!xhx`P>%vA5!5C}8>W2TVF z?oRjfw+iOY<yB;P#*S@k$F_EC>o>M%$F^7~A>ZiFY=wn|&ik=nvxLh2*nk)ejwo z6M0e_&2a|Oor~6fY~=i0Gi&1y`j&a37sq@fJHx?3(1Vmx`RziNsE#WP95Efau=&5@ zS>pG7cfVPu6Pt;Qx8!+OU67Wlj*icCzrboHIb$j+%Urt2e0;q4^t34n!fFD*@h@)> zofUpj4mxt6^5aU(Xk9`(Jml@eCunB0rnT(X6eK@7_UG3eH$S_f%aPIw^b|KFb9rHZ zCPHu~0t1|TVX+FUGAF|jKEs>zegsHPk0#h18w(x7^k3O^rTDsI<7l}MBQJty!x0$I zm}vOiQM4_34a;LCiYDA%6K#Jv-e`?X1%;jV#_0eGuww3%z`<~U8gxLC5aJR)<|#*k zwkOKT;xYtYCmU1r8l=0R0_*Jq$}7OF~;r zu$O%mb#^nP?U{`QO1?wvcj%qk3DB0yS*h%*iq8x}USHzYzDLQW{z&QFF`b`+141WB zD!hV;XM{FP?E5&+xXZanH${02zNj;gExT_Efuta#Yq4K@BCF3{P^#2$SOI7t+x5phC$P%CZw!ehTz9Ui> z@auDBE_7D~xG$%Np|5}(MAb~AtAqh89y1>5ZY;}CN~X`Dk~9w-L7^rs#rhe5?G~eg zm2;6cTq_3y+1%&MP80){*pSCXtw)UutJzBu1cn>8J4;^zv>s+wjfLUzNO%2ZS>)!?A@+XfA6T-`~(YD!y8&jl;oLsd+PlwNHS-noY?{1e)x#bVc=ugiHjCv ztFfx%)0NR?#aTGfqghOOS+k&7Zewoqim)Jc$X(J48Z*f7(4aXL8_*mE?-E z4a%urSmv|ou6eeMtO2-GCj)&746&rzTMVxWO_16(O9O;5agZm#6Q!hlE_vcUD}jXscJvG^}k z&*%7XbT*!9C!DDH9Ti76>H=(li21O%YEfux!SwDW;EP8@yu%?@yW(v$EqfF5M7Qy| zW76Io9nRR%W)%6ayeMbnH)JCevmlZd(!L(Bj*if>WDBbgzSv2z-_P|PioIKX4DjnY zCQY1kc-$STP-_#@n*TP2b-Z^EB?h4e>8@o}aI2Hry*qAqS%A${(`|iWQ?@WVLCzWx zWf{YPiO)er-cru+HO8q(K)K5`crQafSOFMns&0|7!Nre+e7xVVx3|j;3#++Bd~~5^ z{x&49;hi#m!(u#;Hej>wg8FPbqj)8_KAa#$T75(C6Y@vY`MxQ@)bz<^cip10ztJd9 z8O9~GMlgx&n22FO!3E$r@0V-XS8MhDAl15~J4%5=X?1r&OVNZA+3-bw<$~gbSzG_@ zw+0KIE(1V{Efm64inKS_d-Gc9RR)>a@DpBx^joqxEIra`GY2i%4MXtis&etK4B25L zt(VX)^j!4fUb`BfmD=}C9K;HbqV<^+;)i>xm{s6Hm5mJ;cide*0Mh~PnXAt)OL8eh%+j~3fv z`I+RncwOtWsC+8-n96-1g(4Rg67&LdXOTa3CU4xEf=fQ?$_)9?B3`N>o7Smy!Pehv zq*^<|-&DH~G|BjL3SFTZ&0L73QXlZ}V>&NmJ2atekDPr~>+?1*Zgje=fjK^D<4&?b z@oPSlfp*t_D6Ag>n)vMK^he^!p({OlF!R1>OSJ|yYYdZtwzMK+9??fPhH@yIBHLYy zg{fhx@lrJP2MWSbUJcv@p^zX>Y_0S5zTVD`5;tHh`}C_q9?QKnIL~dCd9gyxv_S|7 zfrPbK9ELfQy#ME$pjpp-ye2-dxwXpSKS$Za@1+1quz6quMLljAFIjc^#0~gv+Z{O!+vjr{9?C(N&xLfEpT_H zPJJU16pT)E&HjX|F@(3Pk#LnlD^MBpa}-R8*pjgz0S|kt1Bf9X&V0$b5E9qom45V7 zfqcChBpPk#4-vzteseOxW#q9a4+N$66Z8D^usPO{pBDCS8R?^w5LOG)5a({G&#IS;;QpWbB02^&SJl@i}3HZl$F$D|xT?ZJ$OWOOj zR>tBf>4UTl_F8Xk{*sS{D>zatA(-WKrp{++HqUP72wvblP;RE;ZwopS^c%l_D0i_^Og~fYl@Lk zQ4PCQI$+Zff^`Z|*uTFZFb1(ff+wIX@CR%ORS@h%-N_{VgnJ+N|BcoFzgR_P~kAH8dEqt>%C z2n}zH^qtwjF#Y4W215w#dav1*ctKdp@hQ*>#{CgAwaVY7i8gFj@}NyM$7i1WG2ZSk z*Gc>1l&|g=TBcvzv1YaeBQclZg>M_e{zS&_81q1f<9iQP#ruvHDwjL~-Fvhz^q9NW zEA|W)>#8bs>tRvQ!1bJIlnQ7~j3;k)%Fr=zZ0A;b+?weK%YKf~p!#yjJ>4NlsMgT# zau_3gEgS`6?g&_NuGTV4*G>3d^OPj0nYNa0r-EJ+{P%hlIC$IH2!cNSD-U4|*{Jk~ ztdx(V^A_i}QQY)cNFC7@ly0~4VP@`SN^I>e*3-G#HT%WI2KR?(TXN{&Zm!)PHC5IF zG^{M{^E#r77NesZ9>?m)pX<%AFW>p<4mo z#M7~D#`U--C=zS>$2Es=MZBh564mG;df%s`{H)&1Qy(!>Z9QeIiZkbBU{~#XrFeCM z9F0#XhAzD;#V5-*sSd5tS=eMje(evCj#@%; z5+F{`-cW^xOG%Inm|fJcWCuDE>@T!vK1MUO(8(8p{A81^`#X+5Jifi3kr4cHsSS^& z_&WdM3D&muc7|bOeQFa`coD6VCd)gLl_{aoUFrIyhp+-8JBVfPxBkJe5BWo-9-;20#)_j60f85hL^?{~<3RHhkXKyKllLp$s> zeELH8%qU3Y1h4vTv2A|@-X7I7P}D>%za?bE5C3O3j$(=;w(F|5XC0Kthld*EaYEpzq zZ{@N^Z;-{&ZPu)BO!#Ek~pme^a5 z!88X~9$+avzY#Ason_8{$#KE)cJLn+Z}jX_sam*gHAS`V0qgAW4~@J7sS25YmFd%% z^E2qlf^PLH*~h9TvFM9w=fhto*YiLh={E#5EuQ# zaNo-4LT}YJAFW$~C>ue0>Z&EKmsFN39T6|M?RP_4HB3iw8TjumoepC1agi=b6Q^Ef zo&@gqy#iB6dm@jA{!pnh;$t5`!d+kzoJ5r-c3O22^sg1K)`r|&wlP0ClZzohCnP)K z?xT%bURk z33e#Pu|p-&=%yyNroEd^{~Jl`X)x%+NS2rV^SbzB^~}Sm#n_PoAFi9NpF zYup3~Qja<*(wL3e!7b}!WED-4Lp!eY$d^p-IL4JbN4>-c>+o zoHCW;xKvf6CS5K z^pBgoYq(M2N9HH}Z6>n#qRw`IWAGVky8AcyL}uL+(-xbtcd>0kV?o}W>7vq%404cp zm&BKx`(nOHiZ{AjVb>s3C0g@Vjq<2{xC_9P@EgtBN`3PoCBU;LXQ^;k+76V^LIA!zvrj_+;I5WU`Mug04)$>N$C`L7{{qJv|X_qG3 zn^gB|T!aKrxARx}2Z{X57zm!T?}?VBwrCyYA^1W~ubfV(DH!N$MM*uoDkOmH`^#8x z<1lv_{RqiN&J${i+cnSW_-WC}&gAu4M$@e~P+HT%ii`meOPPZ+5mlMZ%j3XZ;dW&( zjS3GW^l!WhSQ!}z4KJx8-DYKMvp*Dz#-cLotK`)Sp+bBrovlo<0D{eGnP?a|x6Wf2 zf;l+A5KDuhBiYIl2(p;bN19~T?;LX2km+Jj*W>F@0gX@sli`30$zwpY+vA$+3ST4e zA>h)ZPN`_kBnW6&U!eXY2;!u$`s=UB+Oa!4qGufy$W6SPzl$L6d8CuKv)vVERHf;?zvYL}Tqq;`;cs2UN@H&=P@(u!q zZuW?vp=*}s>@z=u>*0h#^o>HXK4fg$HHHGOk9YbG^&m2vsM)RGp87f8#CMX(Y4-{dy;aMn zvK(?{ca~9po0kInIh+U3A4w8O&CD$^6B)-&npvIyiF%q4Z~w#Uw%O2t$+ z=KOYQgzP_|aN_%#tA5SH!!}7j-gk*Mm5cH*b7q3Fmdf2r|B^%Fp$HpI7xIg()K_DA zF{dJyXjr}Sl_rAgExEf~ShHRtK6~@|eO{OGG7?k!mPBXj3b%KZ?y26eAKI~9no}mp@=?`-yCqG|% zb$!8AAGi5Zy=r-mCtzQHgQdI5SnZRFqc1QP9wf2KWdtmgH)3D26)dMq(&OE{y4)1J z0Y`<=PiykG*&c%n_V_PX1uC(k93W$IDlxFbwb!dvqo}%WB+OPTw3vdlkWozJ3M+ z1%a^y&FqWm+mgbpOVauZzhsTnOqMzq+K{yKl=&{2Cd>8SdchPlS99NQT%>lP6ZB_$ zuT7(F-tOcSNW_2do)DoZ@=A=6B3Kw_I_h6-p|ajs9Y|E&WbF7DNXzlfOEyq@d@V4y zc9d{PG~NWb!#9EYH(PV00M<8H{{DanJr#Y(=-p3S47zm8E|roYoonQ!Vn|ZU>!SqY z4R`Yw#o?93A8>eXAVsd;clN`Z12-+Z_dxGR#vBt_;8KQMyqL+=Yb{TVQjZz1Mp)QQ zz2&RxeDbyFX@DndKQ9@e~aHhar_qEjwPtxyTY8&e{q#3taecY)W_ILCD|Xuq2P}2$+8w6!Z~r zV_>1mWJ9qIQ8MJfi3Fn!c1ut_%-?kZ?RG5tZ_g$=;ZF>9)5u1CTcN9dh*-J?M<#cwe*rOv=xlKuwkFI-` z`kCoFF9v}7C3ui0et5rL!D3=u z)gDOu;q;ZiE~>b7mUnP}w9c_)y!kjMstLebFF|I%fzi9R+P-+6o*~`K&>6PDG>ATY zrL<vvd_d!g7Sxrbu@WG+GtoAp!f77va)|G&@ znK@a5O}n{4;$|6A|?2?ppk#J6NmfB z62_5^{TsWmwc`ps&|AtJ6n;-}Cm0(Nru$>a%Az1&+8rI{`0TCG4or;Y35%A@{mytn z0!^1lXz-$!QU4N>)Q*V%cnNM`Bt2{LqK3j0ruTp23(a=Dhvt5 zSJbf@5WNL_g%WY={t~MrR?6rbyueleYE$NF5IkV(HPJ}Ftec-6Z7jtoQn z$=I6;i{qqXXgw4>U6Q-!hh+8@fdri9g*;;32)@XP8l$pQ=Kse6a171XinAHcuejX{ zhMr-Ccce9NMcz#C+@HOSU~l#7U6I9v(LylYH~GL>qlqv3f6}el2PMv?KXh1;3Bbqp zA#;jpVrk_6Yi$R%cZbAnp!Wk_mb~&kmg4Uzp|7$E+LMzqUQxspS~_REsrJ%*88YDJ z$~1`Gdu6(Ps6mYi2>o3})6!$lg8y|K+6~j45UQDm(5J2=b)Q>btoHp3?VLz+>EXLT zQrwLt|D4QLR_MvpZ)CA-0u<}bk|V4CNW6Ro?+(!6Mn~RERaf(!p517@NkhbSlV09^z}heXM-ZW zQecJAt&fl_l!N%Ih(YtllO;f=x+dCYB)ZBk3sy7Z&F%XMJh`=ECT>Ro%GNoVIpt5m zc9$KCgN750wxiUhLwqgn@SS1j8pPF4065X9+z4h{q(UxNQ*UY$EISf zO|PM}JTk)tKe$dr_|b43?LO6cK=wj{kBfOpCYsvHz8Q*q;Duv}dm-t0I7R#U-~K)} zi|M51f`Te~#ZttU?T97)o4EY|G-OR;8(DWK*1G`&x;BAwvRMI2QT= z$g73ijy?>SW~kbi5F`FT*d}!lFHS1-InQT7K3Zc4u z&~y~Om#c%(Q_gTbUSIV1qD6 z!IeHdXi|gz^}#s?ee*{2{BG~ju>d|~@dNl0bcOvU%#nRIve^jvn_~7l@oIPe^vTm2 zyw*0uJ_(d(P`E@p>DNmSV?~q(aq-ZS#07j##0wG+KZ;?hU=S8yI{z_s@V4M^eq?k` zi(Y6xq%l4&F54h-}GqhR6l3$A?40a2|N32rZ>e>}wZMH}7|Hx-t9-^G2Ow;dj9)u7y6JE#%DU9wHT?GkZGvJer)Fa6 z6+x?P^=pLQssqN*@E!bjBSBVvRx(&HYzFKb_tA?*oiWIaAy{S!6($4-A`E{-Gb=Sz zn6$taCRDlZJs9aZ#myYg!m9VmK%?^sR%=Ao3>?mb-wF^fRAT?iXF|rrXiZNRuT|RA zY#@q7gkSHNiUNh=OIv>Dsb2+^{%OX`ZUw4FN6g+Bg6m*#n&6ATYp9yLrC@bWfj)u% z8W)3=QDpB$Y0hPA2hj_Dff3p!89zj_Y1WQzBY zM7L7xD73+6irBr|f&yaP4a_>}{PC~r=Q%eP9vZy6E1zMwZx6kz zEBC#di=zO>R4mu&d^4kioAEfc})46vJtC9=E*d%rpTtuUW=SH7Duw}pQN2j~o{*Cfe>InLjF**8u zXYl;--#xfB=qtk?2xOYQl%2^{!q8js-Q?N!D~5rz4Lz|s#pf%{i=Lg3Vhi`K6i>=q z6k@p9O;J7mpeovsbW(=y00zV_NGi26#IBtEmXLIzFb;zU@i#=qz>-oQJA0i@vAM)5 z8ULgZ`I+I*#^?ZQlWz#--BzN_)SZ3g145V9RruVa9NVNrLax{2(CNa+3G&@i1cU*+ z;L;NV&`ArevM&p*YL=)2$!|UIg<2I=dZ+cJ9>u;y2HAyai!%)=@ErQoZr5s3;rSlF zJy7}Nw&p>oRFo%qq>wg#QMXqK`9HgFJH`gP@T;_sJ3C)lJX1Yah31wk02C&itnLv44?aO({?z^!MXc6`Q+zYzU#hq3!gm)Z3k~?r#+&n%C*xjIBLPB zL!9p_Y^MUdzZZJGDk7HMKQcz`LKDcO;{S7%^^f|A{MVgSd?5@eD8hd~mWro|g5&(Z zZKTQ>nRny& z>B2GBK>BueEs_aaa)H~Z*Ebwede{nOk~1R)ql%$Q^sG|Yc6 zAR4mKxdQ=?s?C%9RCR{3)56qcsd@OR)@~5>@keb&qqn9(y}@WgFQ0rf)q> zyRRD?S@;<$weFj$$)c{*B0)$IWi5QJfbA^#4Z3GE6N~Ep@|RE}NApL>w4phH6~~8} zrjLhh9@f@F@b1qC@pbVr_Ur37#L{sR6<5Hi$*l4;b6_+xfA3!p%|S#}&4k0!lTE1< z#)?r=z*&~NcnZFCqNxF$54Q0O)&-Zin3;ULC^hFA$DyIEcix3T0c)T!?1;li7GeEq zW=u-qo%uy7Uyjgq@=rGk&U#DgTX{Pp*=)cl$){}p*s|MCNHV5AFnS&i;p+opi^r$; z?jd4&vq%a8uc-7-C2Q*^KEu`h=gHphD_`Q&h4wBIW(wVZDsUtydV_2}sK@x+c%L{- zro^t;PLjt{M3jbjh=7;l*A@?n;=6T%^0?AL%XYE^O%8vqM?!aQ(|beA4|Yn~UHYEZ&p zG-O&mCur56qDN23y@?SV1M5`K{WZJvHzDjYN?ngY#(bcq8qH&C7KCm(3f=tZ+6Qh& zG69upM-;lT1KvgCGNa@&?`dY)x}lGc8^31JcAa9)^X2Aj12q##(ja^flgS>iv>eWq z{u6-!-o-d+%2-T}bM^yX_p75D_OmwZBlq*akeH@Yl6t8RD^g{(Y%1>_-Ih#-*sUp8 z7q~bp?n0+SuE`SlNz#HvT=rkM&X6t7cEW6bhp$w7m@QmS*%_W!o>OZJcz#%re)Jsm zE5JgZ5$c;PAlG+eJPEW)wXeeE;S!{RyYBaPa%J4TB_-z$vpr%!I4mn}TfNn*jFS0w zph5Ea!`?O`(~T;1*@8K1u7KAD0ua2gDKM|SF~s2S0FtjWPMB548(uDjCh)jUn*QtR zOzb4xUjJ0Ctu|+IQe=fS@JLWqrMQAT4>GNLZ_miia0Zq z2k|wbOeaYxX|p5#y3es*IxErdY9GCR>R(if&&+8(+e6AOm#bo9_M-9QM{5m!gb0ZM zw)penUw`iKm+Fk0J;sfn?_XkL7p|Vb$pik8na)U?I-hfcjR`(y{(Rsejj{E8^0I>o z`s#zj7vu@ts={p}CQ9`lm{Us&K-nD=FD(vlrO;Z$ot= zfm!^khk-Wf(TV)>3ypH8&W%|kCQ}L1Y57ohC>$xa_gee|4WGudnQ}h_8^2OuOBN)O z_+#zuy5>*Gu6e_Y$2Y>A3DANoNu`R;^%AT++HhC1sCT8=d^5`y&o&dh_N6HkGEW8z z#wn-f+fe@4Z2c}Xqf_S{*l1B33PJUU^@jzG))FDy{~J=I%+*W{9(y62gXz%}Q5Wx{ z!SHAq9V0YYIz}|_hj%Yg=+73o3@^>$tkn#j5_is7=wv1`;KN$Ac;0teO@z)_Bof2u ztK=f7RIy*G&fSRArn!0mig}7h9U-^;cb=B0!p&MN=t^vX^~Z_1;=(FBK$~yjqIv3B za{OmM`DeKMJgP#*dOctaZYCMj1{VuPM_afo0Lq};pW z3(_;mEn?t%aq{nl_Xc7k>B^pKg<5O@yo%yes30vh&i0im5yEPGr#jRTy~^TUk)=2x zmRMna)JnooK}av1Mdw-cH0cJBov+fzLcr>JrxpsxNmUwf3}A9Is1Q<G%$(RZ3I{ zk=74|P6b5vCdszS@9il4vOF>zS2{N$f05t;}Ar6m`C9D-;g^CB}!ub4VR-&4<(QZtc&;JAjg zqI-k9!?3@VxELV{pQM=WA*6%7mWg$4aU2)xnNYQFpa?a-Fi9nYe9IAt?;jje($s$?UyzL6 zmWjlk-U^-mV1dX;n$U!5E1)&}gC?G3g&&~O`->(<>TxCUp-?`B+g}R2qyQHS_n#Gb zvWlt9N#}pIF~YFlM6gt;1VkSK5Lhs6C3`1^!Q{%D zzcnsskr5>vuaD_Zal0`8^b%)5=J>%0)m2G>S`tL;4aH|iJ-)DC2>6bU9fnG?Mn9Hv ze9?FQrLpB2B+e=b*cD!RRH^|ra37oD6uYa_t$edU(Wm26%Acwj36nBDB{0nOFlqf6 zG%xUodBq&fYis8Yo4al86_3v$o!p6onK(gT%$KTA_W+B#A@N5VALSRraN;uSFFSCHt~-6z<<{Q8C`e*Np%ILY$< z;rJ43>5Hm-)UQ6|i0l*&ZoJytl@EF(D{FMe%r;WnQQn@UeID=u7PXwjSvHYQnI)h& z?AjdR5P#Z&_-Aw5kzb{ZR^FQ_8##q%mN%PuA+C@Gb!f#Bjqxt+& z1m_yefjE5rQ;_=ANDAyk;&xRQZq;XlN7F#XGvp|;PkNYS7FC{d=To6)Q-p67nzf@W z25kGxhWU+K@NtdiG~9OE<0jR1okm(+1$NH;f2=d(br;u!v1T@>RbOPM*Gg#Mk8o}~ zQ6_fw+Oc_^4eYwxo<*=Sb(u`Nqmrq8@GXF0EA7lXA6i|(act0-h5O<8k|%iH21ecG zjvgThykqI$kWWj8$KAIFTm9hG`fk&Kj2ZRk!`p4bJgmEUY0R*^5Tk1+)JF)oLb;9N zpd`&_*MD9g>;cV(qv@2oSkh1_kGSJ(A`tT>#tV+?om+tKn?OMG7Ih%PX}_X1>&0?* z#k-EwHG5My{kccZHJE-EcgFKmfWxqDK3NtiTWayj)~GB8f|0?q=_1v+wliNx8s~wJ zo_w6m_G`Qq=XBD)qI=S&lS&of0AvD<_ea7gz%}QZ{|L4m1wXRfw-|y}DCc+Hq;$$p z39;bw?&ol2Vo`quJCs-DY~!Jk3hHJy|2oL)lUS(qTi;f^Zx!1jnP4F>b$-s|7_H4EO$)w%4vssd z7rPRE1D@sIe3!GAziYbg5n{_hBH48(fB8gh5d#K4g|0^re+ za5WSaRM3zwNQ}g&X-ZkC=Y^oyx@=sZlV87DIf%z>M?*+x?)hi<$F{w$Cas?iCNsIr zOgEXEq#c7wp&xwQ@k;i=R77v}Fn+h^R1DLRl~iW7{Vjo%H~C?6;9?VB@09$TkcYev zS_eDGjZ~qqnQ`i3#lqjoL#^U0&%W>-26}K>5>Glpxyu0hHEY-gF|qV^p#KeFwz*BC z;(l$7cMel@Bo%|TzzPi!_~ZSLh={nsW;=1*p8(j~ady3@YMz4@X`f4zNd%P%F=7JV zbImy-u1Z$W)o=G|-}34q)tJ2_VU(W9B*JaNVOM*mc_-9e20g*((n%+8P_;Ik1*0qGrI z;Lq3x6>tSwHS5U#(bkA%k8vEd+G(WrflO37YJoBK*T_bcVHVjODgY{Xsa7$QP+O5b zN8fix{4#`t)LP1RbSaA)^oKDoHMJQu zC7h)~3+G^=OhzFFafguw7WD3IoiEpEAAH%{-QSZ zaj|0|B1Q$2^!XZUfZmVH7ndFC(xcsA z5DHNOn}!JykZ2{F#hNI{dfvFzUJOOG{Zj4I&=rg`(m#PImtIQNPQ&?Rbg?=)+LU(6 zGLWU!F-SN4nJ5^~mD@70P6t=OC^ob(6da$RL#wlgSQ52r{3sKwyH~$Nr=Fox*Yxww zxCEbSVuYF1sv@GV#+H*G2`W1oGScdpRf^t(%;_P+b81tnU5%t5^eHEJ7}1d7h{q4j zERExVues*t9IG63SLbbqI}Giu;gq$&&NWn5_TsEmtE?_ryuD~gd|3jXr!JjNYzK;0 z@d4d&uYTT&E_{3;bfRd`nN*$>Rz{1-9tI$Z6OqJ>4YoN{Pu@CJW9VoPMGAWpniZh| z%yGY-1ZJREf;!cscWm3Ij>dOT#xqQ?QNz-K|yN9!nD%pt9bT&Og6r7 zTNU)wK5=NTQ2BZm^y}{U((EXiN|;x3pfBLKUK0mp=yAR&G(u+drkaddMM74|lNGAX z)`taoxX@A_j5(8;&xLroG&{!_44 z6RYcdlMlUw*G310ItGi|1^SWm4)d#b@_~_Mq<vR@-+f9@plKJ_WFUrZ0FyZhPD zb{_;AVmeMpVCR98XZ5{KZ9$#dOOgx)QFO^66nODqa{wsZW_BjlKZRht`Pr*C`dcA) z4%cg7L?+7Sl4ayTf_NijQJ{aN>v|#({|bGDEa1@_qi6W;FSlt!J0LLljJ?Nl8h+K` zMLUBn{(rmxd{I*}TnQC&w?u^l$V`s#5?mkdT4YXc@<}|&Dyj5yfJvXhkqep$1uhpA zC+-nj2<*K$(J;bM8&^_FH{VE;9u<4cMtF011Zr>GLT2@4p?^0#v-v^^-Zf+(zZV9V zoT1#F0ii!*Eq2HPn7=Ui%j(e}v&6TCsr5jW6S8W^gn#494@_@vy<%RyR0->sU7J18 z5{fPF=(!)Dgq#s1{eSI`X!J^xe~B`_nxlo5}K zvQHF&lmNz*GoRqP4OJK3#OCw(x&vgA5DH_Y$&l^Mf&HO%x#539qa4E5!>;B>mFlVm zel1?)mHP9ug-Y&q-tKcf+uLlXp?aLfa~ohW_Y;TX83M`u>U?LOhK9Zr7uT7wa{tod zkQ*SZ@ADT$A@H{+b6Pt`WONwK(Ct0v74MaV)SAqOl{R3c%eht}u2b%b&`W>F~ zD}<{Vv6K=CN1O1Y%ERP;jX^v>T$j63lkK7l6jQ})LP?sx!PaFvqdv=B6mmsTsDC0s z%e=8>W&+b5OHCff0%I3am`d7UOtNVr3}px)Q9#p$6u*5=9p6INI(HQo1)Qh|1>Bh} zOtb&1J242T#K3*(*Z#haMvdo8u`d5#@P=Ri$lQ?p8$FhUxbcX=gf1wXi^eMSpN;Qi zEf#D3@#d{2Pqm#VMZR8nFwhsY1dIwzGs%?8DD>)y7+NLdHGWw0ch#KB=%BYB+cJeU zC-~-GCa5>8RK?N9@yyAT2fO6AhIq~wb-qkt^7_i?Fk>jn!x3C@ z!QP5fAyf`EAg(K`a(~S7N&~obl)rBj>$X{K?gKcA@#&MS&+P@<40M#}!9cQBpHi5t zws^NYO9h`{1!|3!zs>P+MRQ3DaF;}?_n?G;_>npk_9NO3zKV4K>X6NJ zGsnlOuNPx*afJ5&r?PL1&Lrx(jBPvV7#-VuVs>oXwmNplM#r{o+jwGI9c%J_GxM#P zKeN`-5(WS&H$24) zThR|C))P)rbmNB^lg~O_eKiiP*^mZtmYl}r#SL1It&CO^hu)(Jb^@^rS|*CbbfGY_{56fkiWV0#-uq9AxHHd-5zDY2Bkm$T@af4MLdCOFlZ>Kc&`&1 z#>N`8w>}Pwue4JVYO|;zi6Tf-R)?XjxAt8E0qp#4I1D<>Dr4c6)F+2535m^Aq8HT* ze*7H#*sZX}96}qO++7P8tMF^B&)5{yG#xc>JMv@z!I zJnnzFp+y{|{UAj8pXYqM{^P)HCK)FBpJ@N(O~6_>@Z*0QlCik+yMO+B zg#YJo1D>7uC^YC=HgIi^y~9T%e<{$${^EYVw*IkZ+-5rBY81QEH{R;>{ILRsfa5@* zMf$?Xy4w#eQq6yJ8oWP?HWo4Mynhs`)8Ras_a8ID&&4(%r%V%{icRi^!7+AxhZF5ldPK z?S1j7>F|4HDOR$0y8eQ^ zpMO=gKy8iW*vq&j814j|yum41H4i(Ug5!w3<#m)ZQhiqhM&=3*BO9G$P1ZhTZgb{p zsxJdDG1*7@Cv_))DyP-8H>jx#G*VS+gh-KbrS$zR$=BO{$((}v z$6w-(PwbmzmuO2ViNVL=Z`ufIJ-lIo4Gos8?@-+*#37<-D15!yD}KGu zFJWFB>CnY`LshPFBCldYJ5TCn4s)s9wF=F6Zs7Vzk^MBXD0u!1T0;j4D-8}ZKLD}R zculrbmjmq%j=s=v`Cf-1egBS`t_!x)?mqM@Ct&uZssXw8UUw%$WsA-k-&a7uA6@C% z`7tXao7t1%%6q4jh&OAvbI8ZGEB(5}yLhugZokAg%+HotfB;xsHv z(2wgXL*O7dVMi#mO|xsOxpCZcR1)v%Xe6egM^QDlJzk=qu)EgcZ}?Cx()pm}usr2{ z^RJ7)^qUx+!mIaQL4X9ZIDkKT>WS2yfp$>6;@UeyI7gp<0zK9YL< z8|Tz3u|xVQN8(%Z(Tqf4u5GQ`ZP=R?==}CL-`zxMYGNQyPws~Y)X--(25xzgwwy3+ z$lYFjF}fQtO93{S7?GGvv~_}TJJX*;Gqu(<>w0D&sdYrY<0u4ujE-CLSY#sHWq=Xl zrIt|S9;9s=5jaBL#lAA?G()JD^;k`y+oAH$`_#6y)ah}BoV`%jkV#K>oGBf%L04)( z*fv)D2l@=q1OM8V*JH-tfNZ2+M4&LECiUQYB`(x^BgKDT!xz&p9E zz728a4Rw0+MI7PH6|cF03JEASf!jcXl@0fWk1wo0x<^(_?wm5) zp0UE#hC}n#mZuy_cb^7lZ^;|=cDh#kga7dasOWM1^Ob3>*@h{8_f&NE@#eT&8{oV* z|CR{x%ZHo`4?m2h`qBt92C|Aybg6sJz7ADR6U&-T!3$r#01fVuf(*t?&C&Sh`GU1r zlHa%Gs(l9)NYnyFKwB+0n2E6829j#>uGMh;tU=G&Bu|#&rI6W*Egi8~iFHSTZ^XfcJ)=HVCx__Hb4BrVU4s{_N{IP@8?` zPaE=LI3#UvkN_a(; z##6PZHe1NUZ#8JHmlGD%qX%$Z67R>{hOjMW1?|*u7}aS*?w&iBe#D7kO|+b=91#VM zGRPtjqB*Kfa-9O>P8|6iTf>DCH3t~>JW+aGiQZ-<1I0Bjr@eA)HN={PD0~;q)JLG* zMBZ_SVuRV!Co4pU?-}PFcB3#y7eR#AT~q7ll(TDHaWAN&u6HV!`@D`YEoR`Qdj1t@ zmFeuc-hPt?_gDErzNuu%L}hj;fIMny_KdsLL9=I7#^ryZfZb60*6SF==kTLRZRlBM zt)NJ&JnDl=?Wq;Wol6gzM5vNI`eQC0%gsShocEWpRD>@|I6TA-@SzDNfC?p8mn&b(Vwt3i#+${bid zZ4(0P%6x`t@&S=w?m67YMwGM}o?t9=^zz}MMhZogJ81H*-wEjRqmRXUWA6rn{+axk zVf*WE#bdzYpvV{Jry-=If~Z9<9;7#j?0ipV~ z1C$apt6ggE=z7d)Xixe~uA**WR9fXWqMLkW#EA>fg@P6@xGpoT#^2;?8ZMdrA|hOA zmhMGMmBerJ9^>aN=-eXV6Q5P8iCcp7hX9RDPBtvS`xXjvF0(x49s&}e2e6t$btrt9 zh#WmSPLH~cAN;Z-mhM49a#8Lxl(>~!5L;l2X8OVCd~MYI0iVbIB;d>IYlSbwa*Sj# zQP8kJ6KN%TPmWFdMph1ff3tz6^TeaTNDGzEeV;C+v%rm%Yyy>=-k;^p`qx2_J44!F zp)vg6J6GrKuU;#a_qTq1Hrz#8zN~iW5|+^tJ2k)|=|#;Jnu%r3OF7V{eRlsCcSW}E z4GUYa>j_hzcH4)=Ld!5BFxfTNzD1odU2!uvI45Z@+y6Nx$;>_*$yDERw>tTe=D~ga z_q??tQ;0o?4cCcK|ABVcT&SwuE{{6@j*0FpQe-aWknh$S<;Gz-%^GKUTC50E{V94s zNCB=_T{7jW*g}HbiNOI{MDQARJbt}%FZud@94~-8wEKg6K>jIDG4%(T{Nd+|APRXn zW2pgmr|H)b9ApJ{!x*8c&y+wX--p+9rD=dC-Upr`H;i2S9G4a(Yo@)vju@(x&i#oZ z1J7mz1N9PNAS})Sy(WgHry;c#Px4z&qs>~tX(Fy`vFU^zPEvogI_nRAV%#BGKt(Zt zq(sQ3=_^Sh*}riBHRWuwwG|ls-c3bT1`l`vEAYaQ;&wZmt}h>1Vt#$LYwr6VW<_De#ld>>v>qWhKB`VL}K~8x$MB z?e;5bLo|yj5|h;jb(94!3?hHc|a?>_qn~Dwb9H zh}4W>sV`k*Itl)y@w>W}OUlxnxnOu}tan%mg|bWXyAye7{3 zW{e$~*}9#`m1p8eY12#*AL$GZ-iI>j#G!^_p|RRIHl$LZHPT4(6fY;3#>q z-iOf;!!5-VU9XvM+8!#$m?SNM37O&ud&L}f1YW4(M~~$b=ukhfWZ5;CpA;&HV=QNy zE)i7xv8bT{ZI1_qbQxTX@nfE!zM^&h48Py`9h_#S*?_Sm+R#AZ5r zDI*6Jw0^~9Ai|1G(P&-?5AJMG~o zEXVbB$>GvC4LwvHIF}GpSDLGv|H1_uCZnktIs!C2(bMgs7WQ$^VhsMmwqPUe_PCxPn?H=c0opl`BL++gyg zL*s6=PT z%%xlq99gP^dPAf`YTgX^pj_N)O9F4s5qGy0QB=7C8GPnMd7qN@QdPhet6M2&oSQ7N z2yQkddAe9_Mr$A3|4P znjRr#{qA_D+uc#OeZ z$Ho4|g*=h|si47*2`e%B(yD?9g9;>=jf5$#G0L`e&Ty6OryD1q zhev0kCo4R@U4LdwPlcY-t=_vlw??fo{k@BP>5LhYEu&U10`f}KP4f^X%feB)Gc5sR z^J~M;<_qz83d&a3Zw$rW=GPEAYIcn#u2Q~!0M+?ZTIW0#2{R5~K-b52R9(NU-M-H4WAeX;lO5Q-$M^0g6G5Es}GcN?1_2|ydGCkSRxMxt`rQ*;= zwh!xYpC)IWYNX4S@nT8BZBX9E^mBufb|Hf(FzChVN;u^pvR4SvrU)UlflEwROG;XPX_$|ulirk}tcl$v-AWS|0-e&70B%ngbATdOY`AZyB~Bc%-eY`8=_O^ut^FFH6fU!(AEZ zws_zA43RDMg@bnN+#y=&GGqxA&cAsH&>4L4fE7uRAJ(p~+J*sF;Pkoga@v>O6_lHJ z6{Uuv49%xNY%>a^>KPu*Fo2~LFl(~!DKpA?eTtS;k;qF@V7f4|izpP&L~E0;d? zZWOrQg2$(F zduO5)TEJYHE{eG+xG!qqy)PB((M9XLVtj=#xLrpRhh4{3HMmacxpSMDia@4oh_X21 zUfdyet-&tfXR9D?KqoOLt7lPO=bifUkpmYs5UaOdUvIq;b_c^xXsCyO)T$#*&0M^% z`5oo}IEZ#2#vTyQ2G4NOisZBzI!}o!7oKO zv`MAhLD+jP>%N(PSA>WG&&C{HUY>-G`y+KW4G)xOCRwhVhU#RXTo{3GHTqS36cHX; zMJOmK@ebGT@qBOFB-IMmipQXWimb-jd;65>gUk;b&7=a0yiDucnSpClRgS6$(L%x!t9dp00kiMY&{ux|8z z@l7*Nhm|}-g8+c@3q_3W$K2=&-}6(ku_hm*Ill`X@?$hrmH5xEj(mQ#IP3g$yWk49 zrNdJ@MOuVJjFA4#4qN`HA~{xUdBdXcm!}JZCfhHqY&B@N%Wz2swX9WKNJH1#@LH%B z@z2~&-U~Rbf4=b{p7L7yUj#DP(S_dmv87hV9_qB}Gw*2+9sYYU_mu)_+OMFw_A7mx z-wm2?Dvk^k(r)_pedMhCaZ(_WbpwRhvi&I6@OKD=rzE9O*N}4vi_YTQy##s}FVFTYnSL z(+X%z@}|B|#-^S#-4kF^48lMB9X@ovuh7LcBmZ;ko`{0J^Te!wM=E3kUVWu9>0VI3 z3if9?rz8|oN=5BA?8AC{1UMWDhV`uwQBl+aovkxhmWeIw`dYZ2R$)>lw`0PmGBY%Y zq>&7AAQp>zZZoJ9_?&X49w z2OM<;!$0%YhO@V1xkzustJVU3XK-Kb#?hgB(D*_^-&&!L{VZg+%!gM8o9F7%`_kNc zPu59${jWu93Vk15O%q9(4C(NS>co(H8Q}4@#qo=F(GvO2Bpp{EnFZfWB zGEgYso8*83w!o%@A^aJrvw^f&teQQmW0tIgB`COAAA@Lr7;(O_`-rUsv1qfI#PwMS zg4pwyBsjbj=?78`eWcN!2G<_nCQ7+Pm0+gtiWgrQ|GG;x`04W$p{vd=)$xbxgkY!N z$TuYY?D$~|+mS|UHnkEwmh={T%R)7??r_A!J>6N^0S)_K9)%SVqIAKczKj$!+I>C~ zfy_a9rOzzzm)Csp%T0XG947J5JGN7^@=)c1=)ojunYI#Mi5B|XK}J|=x_WY)D!>H= zrP1|t`-#B?(!RzVb&PrSPt$Wv+900Rv5y}$R&9@V1o`E@zrQvJUeXyc=T<+K@DcD? zLLk$HrgEbF-f*wZ_0c&&A@Kex8{)nBYxfarLRrO#yIgC<;ZT5F;klfuB6kD9TEm^V zQD8^{YN^a1DdB$S|I$_qb9+#I{A!LCtp7(l(cpDaf62^M>!)8vZ>>9G$SaB0(fti_!0xw#Fw1PUV_`kW2_*Dp0*z;=w$8@M&t@%kSJQ!m8D(0rCi0+!SE}9!x+usGWzJfv-8NbEh}! z@ahs$(m&3NuF~{82zFk3zEJFE;&IQjPe(Bd8rS%4^j-S6(hl(U+X87aj9t;^Il6Lx z4Zp!L2oBcc81@v!efX11ymt1&@{;>=sE#0ME6Gk6Gz6%*-~n)2MWcyT%4*q6V+N*SzeKlQ@1LH5eOxQz1eGnzlPHkqk%z?tU%}PFzv*-7N^UW zzOZ7NlF}u&s4MNW~h@T8TBM}`LC-4@vrDA?O5&L{XgeyNPs4D9ThO% zAe+UiZEY89k6Umspq;pn58g^9JI#mkbG?VbEb`AA(F^WlmM2u`2Wz_$gSKH`Wx03i z#-62#OIwu``H8){rU2H_qe&bu0OYfg)(?GbFq$dP3m(K8t3N7ENPXkUK+Ymc^%k|& zM_*8M!P;o0J%BBa$`c4QqPD4R^A`3`&Q|+!uGJJ}6}0n?+N|K8dY+Ui>p=uIIf)~S z{2;f$e~P4Ku`ZL62U%}O{0lC>9od#GRYJjoT5BW}|IOE=1+4qwSbkX5f2=?rq&IJ* z`oPUq@fC_0W|!2x$t|vAqAiF6UhZ(4-wjXYE_S{|J&+%DX?LW)(h&%ILt2~%enATX zb~HZ-j-p+u#ftk>6NhKJHH^()m>+`7_+U-)6_%Wt2Uwg@?bY+{`hWDI;EUtn= za&~xgIVy0>=VFGY3 z;NvMaruRItp22gvUF4j! zb*9!HUjN<}yIFE#?D?h+vOy4W*v}^93oOG1Sk*sSDt-SkaHLc$t z>wIDVS)GN=ix&BiFRzP|a%))C6h>8WQJ8^-%qa^ZPApmlp{UKS_66tSG{==Nf*dcdLkd+LPf*B$aICJjS8i zT`r6yrE6DQhgxknA#_f~1dCwnpoGddYIRa1+)A%Q{@vkees&e~K~L1a$&+xKEvqu6 z;B+jYqw36iZPFWSf8@B&2_0p3*OTeloEjOF1Tz7jWIr*h(M#SmbDH&VWYhg1{OYdn z@ZnA|BR=PSz;tD?Cou;eKL)ALdCwX99NjcNs^3>ofVE!cjH2-hx1z71SGaZQtg+B$ zQYDJJh%w#e4HA($O%^8N=dsuA#KHI&Es^GUEY(_I?X(#)mHs$Lc~fJ!p8dpBr9zvr zg>HV=?^#D3$(w)2chF$=DB;7!30|r&G4eAr)opDG!Q%w!2(y3Mop`@~esg(`%X!{9 z`gBi3I7;#=H=*wCTBfYL8T-QQT;b7xpE&}l$%jD4hY%#*u!t+7N9cm`YXYpFTxfA*6O(!^S*h%;Y#Q9Uj9Xi_W%W+V@xvXeqbCv@8 zN`_HO!0Z@fI$93q+@Wudnmh-o--Iy4D4&p(rv33Gyf;I^h5IvbF%Af%$E93S*${R~ zN@kS*`FY_WW-K#Sm zuD|r~TX1T!ZDJx=VSC8i+eB7lD(56lhc`J_V(VLNB zmg^KRa(qt%3)G}kWHY6ow1!qnv|TjJqutNXPm$nlf52}T(lZU zs2~fsvKcyv1Vw-R*S(Fv6kk$s;<7K^KBBP@q~du#mB!5$)3mKFJRR3=@$y)S^Zo&M z<;NYKeC#p^HX)H;R83BI8iVC+%9V#QSKHSYv*#|_(dI@p4j`(Nk1Q-%FxjSlHc~Gp z9|dO7%bfLN1Xjmi3lH`?6Uf)x?&Ev=?pMZEPQxsX5{MeFa~QGc&-m31*bl1FOBf^h7Skf%Ew`Oa`BSY9O?x;SfVGw=ff<1xODsl z)!&*0#XyEZ9EGey9R$t8Q54#gsklGCU4}FdKr>#Vi46GuSy*Z7FmXxf63)R(fRMhC z_+t_L?$UetvFDb`JB_OZ8$H>hBNhyW_mT&$_E8{CQT|)dN=ebXQ@V!zPhlvrC{|kS zQh*EiZ|R@oYsm9=KxpnItjD#D13T6#-Rg07-8zq)jZse|>c*B$cInjD!i48fhIOu= z&_+Q>px`XBnC|y|gE68B{ON zq2@}enE#=eWdluM`c7 zyv>EJ9m>}(n_!qL@=So{aalMG(OLn-Op1aN*5p$*rX^?w>hmlO)XTXfWR0agoX3?+YM0F z&c`16qejjkoOi2TJqxrQG$ZagbSnK>#GI1nBFmD@Krj=zcr!)vK)&`wyoey=M616o zaSTI`#DzXBB!VOW*R4i8P*JzB{fT6HwVUD827GUA z%RXY#RRE@xXJi2qXVr6}ANq93+X^@r#WY?joGcoT?j)T|^$sS18zIFE)J5VXS@N6t zO$#?cSeID=>C)qGaG`eo(v@-?MSK#LIs!;Ow$wiP4DsL&Zs48|O(iJDk zBz}^t<@;yhBpXBP7S)5b%T?%pTm2QG=gW3lx7RR>25Klb4O7%cGBT(g@OY$yRab-U zmYGNDkIDG)>{j4%Q|B(Lz0Y3SqOk!ttTnrXs*yE2=zmy`uHD0Gpl=usbkNst7jKxy zWADB413dep4P@v=S|kRUpx)y^){FBFgi($@;}ujCMH7ji;{wDHS%rMx_drJ8ujG3C zGx(eAI^hWerG#NEQIzab#`K@ajLonXzWxrA!*~4bT4fMK#t1tkf!TDjnPlNUD>l32GsOtnt2cA{ z=17{!!KGAUMilZX2MKXlxQ#nUD3h_BJD&+CWH0{O+siS47eGGR2NapvdEJL#)||e*Lu)K{?<#1tIniw zK}ZzDmLFgM{(L;ZFc9P_e9hTADYW3sB29~lpRr|GOan}Vml})-cc~o_E*5-5t}~bO zHcQEE)dMGooKN4R|A4mW&4`wyl~Q~QlQtZl%?Yp2*-I22CKH(9cn!D_luL(2s$BKR zi5d44)XOA$2D84J5{8LRXv#~dx;2&GLEv5^mkfmSF=YJ1LZ68M&|v#U{JSSOJ^u85 zekxKSOwL9q50VzyR!KpwjL@D709R8Hy~`~IcJHJTXTpRX43eL3t}O|E?O0^R-NZ@! z9X_3@J9rn<(LhBMXuTLTB^r$2wkcgHRNsZFMWxPYQu}T6X=zA1#=K|0!afEo z>S~@4*XIfQ#fL$lH22+ATpUF+UaZ&AouoW&0^Y*Y%}bfWoKlkf3l;YB4kVOO*~ZZp6+KwkqQ43PZ5g$-@~(R491cH^1Vp` +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +# flake8: noqa + +from . import test_tile diff --git a/web_dashboard_tile/tests/test_tile.py b/web_dashboard_tile/tests/test_tile.py new file mode 100644 index 00000000..90604ab9 --- /dev/null +++ b/web_dashboard_tile/tests/test_tile.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# © 2016 Antonio Espinosa - +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from openerp.tests.common import TransactionCase + + +class TestTile(TransactionCase): + def test_tile(self): + tile_obj = self.env['tile.tile'] + model_id = self.env['ir.model'].search([ + ('model', '=', 'tile.tile')]) + field_id = self.env['ir.model.fields'].search([ + ('model_id', '=', model_id.id), + ('name', '=', 'sequence')]) + self.tile1 = tile_obj.create({ + 'name': 'Count / Sum', + 'sequence': 1, + 'model_id': model_id.id, + 'domain': "[('model_id', '=', %d)]" % model_id.id, + 'secondary_function': 'sum', + 'secondary_field_id': field_id.id}) + self.tile2 = tile_obj.create({ + 'name': 'Min / Max', + 'sequence': 2, + 'model_id': model_id.id, + 'domain': "[('model_id', '=', %d)]" % model_id.id, + 'primary_function': 'min', + 'primary_field_id': field_id.id, + 'secondary_function': 'max', + 'secondary_field_id': field_id.id}) + self.tile3 = tile_obj.create({ + 'name': 'Avg / Median', + 'sequence': 3, + 'model_id': model_id.id, + 'domain': "[('model_id', '=', %d)]" % model_id.id, + 'primary_function': 'avg', + 'primary_field_id': field_id.id, + 'secondary_function': 'median', + 'secondary_field_id': field_id.id}) + # count + self.assertEqual(self.tile1.primary_value, '3') + # sum + self.assertEqual(self.tile1.secondary_value, '6') + # min + self.assertEqual(self.tile2.primary_value, '1') + # max + self.assertEqual(self.tile2.secondary_value, '3') + # average + self.assertEqual(self.tile3.primary_value, '2') + # median + self.assertEqual(self.tile3.secondary_value, '2.0') diff --git a/web_dashboard_tile/views/tile.xml b/web_dashboard_tile/views/tile.xml index 36411ad8..cf9a003f 100644 --- a/web_dashboard_tile/views/tile.xml +++ b/web_dashboard_tile/views/tile.xml @@ -9,8 +9,10 @@ - - + + + + @@ -34,11 +36,50 @@ - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -53,37 +94,31 @@ - - - - + + + + +
-
- -
-
- -
- -
- +
+
+
-
From 13ea439bb202e805155d4fa3d828eab9b720fb8c Mon Sep 17 00:00:00 2001 From: Nicolas Mac Rouillon Date: Tue, 13 Dec 2016 15:04:14 -0300 Subject: [PATCH 21/50] FIX --- web_dashboard_tile/README.rst | 50 ++--- web_dashboard_tile/__init__.py | 27 +-- web_dashboard_tile/__openerp__.py | 14 +- web_dashboard_tile/models/__init__.py | 24 +-- web_dashboard_tile/models/tile_tile.py | 175 ++---------------- web_dashboard_tile/static/src/css/tile.css | 39 +--- web_dashboard_tile/static/src/js/custom_js.js | 8 +- .../static/src/xml/custom_xml.xml | 4 +- web_dashboard_tile/views/templates.xml | 2 +- web_dashboard_tile/views/tile.xml | 6 +- 10 files changed, 63 insertions(+), 286 deletions(-) diff --git a/web_dashboard_tile/README.rst b/web_dashboard_tile/README.rst index 0337037b..523dcadb 100644 --- a/web_dashboard_tile/README.rst +++ b/web_dashboard_tile/README.rst @@ -1,19 +1,6 @@ -Add Tiles to Dashboard -====================== - -<<<<<<< HEAD -module to give you a dashboard where you can configure tile from any view -and add them as short cut. - -* 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; -======= +Dashboard Tiles +=============== + Adds a dashboard where you can configure tiles from any view and add them as short cut. By default, the tile displays items count of a given model restricted to a given domain. @@ -30,28 +17,18 @@ Tile can be: - Restricted to some groups. *Note: The tile will be hidden if the current user doesn't have access to the given model.* ->>>>>>> 3ab676d... [IMP][8.0][web_dashboard_tile] Refactor (see changes in description) (#476) Usage ===== * Dashboad sample, displaying Sale Orders to invoice: -.. image:: /web_dashboard_tile/static/src/img/screenshot_dashboard.png + +.. image:: ./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 - -Known issues / Roadmap -====================== - -<<<<<<< HEAD -* 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; -* Support context_today; -* Add icons; -* Support client side action (like inbox); -======= + +.. image:: ./static/src/img/screenshot_action_click.png + Known issues ============ * Can not edit tile from dashboard (color, sequence, function, ...). @@ -66,7 +43,6 @@ Roadmap * Restore original Domain + Filter when an action is set. * Posibility to hide the tile based on a field expression. * Posibility to set the background color based on a field expression. ->>>>>>> 3ab676d... [IMP][8.0][web_dashboard_tile] Refactor (see changes in description) (#476) Bug Tracker =========== @@ -74,10 +50,7 @@ Bug Tracker Bugs are tracked on `GitHub Issues `_. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us smashing it by providing a detailed and welcomed feedback -`here `_. +`here `_. Credits @@ -88,6 +61,7 @@ Contributors * Markus Schneider * Sylvain Le Gal (https://twitter.com/legalsylvain) +* Iván Todorovich Maintainer ---------- @@ -100,4 +74,4 @@ This module is maintained by the OCA. OCA, or the Odoo Community Association, is a nonprofit organization whose mission is to support the collaborative development of Odoo features and promote its widespread use. -To contribute to this module, please visit http://odoo-community.org. +To contribute to this module, please visit http://odoo-community.org. \ No newline at end of file diff --git a/web_dashboard_tile/__init__.py b/web_dashboard_tile/__init__.py index 35d8f47b..1d098b58 100644 --- a/web_dashboard_tile/__init__.py +++ b/web_dashboard_tile/__init__.py @@ -1,26 +1,7 @@ # -*- 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 . -# -############################################################################## +# © 2010-2013 OpenERP s.a. (). +# © 2014 initOS GmbH & Co. KG (). +# © 2015-Today GRAP +# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html from . import models diff --git a/web_dashboard_tile/__openerp__.py b/web_dashboard_tile/__openerp__.py index f84fd1b3..bcba4eb5 100644 --- a/web_dashboard_tile/__openerp__.py +++ b/web_dashboard_tile/__openerp__.py @@ -20,6 +20,10 @@ # along with this program. If not, see . # ############################################################################## +# -*- coding: utf-8 -*- +# © 2010-2013 OpenERP s.a. (). +# © 2014 initOS GmbH & Co. KG (). +# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html { "name": "Dashboard Tile", "summary": "Add Tiles to Dashboard", @@ -30,9 +34,16 @@ 'mail', 'web_widget_color', ], - 'author': "initOS GmbH & Co. KG,GRAP,Odoo Community Association (OCA)", + 'author': 'initOS GmbH & Co. KG, ' + 'GRAP, ' + 'Odoo Community Association (OCA)', "category": "web", 'license': 'AGPL-3', + 'contributors': [ + 'initOS GmbH & Co. KG', + 'GRAP', + 'Iván Todorovich ' + ], 'data': [ 'views/tile.xml', 'views/templates.xml', @@ -46,5 +57,4 @@ 'qweb': [ 'static/src/xml/custom_xml.xml', ], - 'installable': True, } diff --git a/web_dashboard_tile/models/__init__.py b/web_dashboard_tile/models/__init__.py index fc23e732..97fec216 100644 --- a/web_dashboard_tile/models/__init__.py +++ b/web_dashboard_tile/models/__init__.py @@ -1,23 +1,7 @@ # -*- 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 . -# -############################################################################## +# © 2010-2013 OpenERP s.a. (). +# © 2014 initOS GmbH & Co. KG (). +# © 2015-Today GRAP +# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html from . import tile_tile diff --git a/web_dashboard_tile/models/tile_tile.py b/web_dashboard_tile/models/tile_tile.py index 498d365b..bc304b69 100644 --- a/web_dashboard_tile/models/tile_tile.py +++ b/web_dashboard_tile/models/tile_tile.py @@ -1,33 +1,4 @@ # -*- coding: utf-8 -*- -<<<<<<< HEAD -############################################################################## -# -# 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 openerp import api, fields -from openerp.models import Model -from openerp.exceptions import except_orm -======= # © 2010-2013 OpenERP s.a. (). # © 2014 initOS GmbH & Co. KG (). # © 2015-Today GRAP @@ -40,13 +11,10 @@ from collections import OrderedDict from openerp import api, fields, models from openerp.tools.safe_eval import safe_eval as eval ->>>>>>> 3ab676d... [IMP][8.0][web_dashboard_tile] Refactor (see changes in description) (#476) from openerp.tools.translate import _ +from openerp.exceptions import ValidationError, except_orm -<<<<<<< HEAD -class TileTile(Model): -======= def median(vals): # https://docs.python.org/3/library/statistics.html#statistics.median # TODO : refactor, using statistics.median when Odoo will be available @@ -75,7 +43,7 @@ FIELD_FUNCTIONS = OrderedDict([ 'help': _("Total value of '%s'")}), ('avg', { 'name': 'Average', - 'func': lambda vals: sum(vals)/len(vals), + 'func': lambda vals: sum(vals) / len(vals), 'help': _("Minimum value of '%s'")}), ('median', { 'name': 'Median', @@ -89,56 +57,10 @@ FIELD_FUNCTION_SELECTION = [ class TileTile(models.Model): ->>>>>>> 3ab676d... [IMP][8.0][web_dashboard_tile] Refactor (see changes in description) (#476) _name = 'tile.tile' _description = 'Dashboard Tile' _order = 'sequence, name' -<<<<<<< HEAD - 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): - ima_obj = self.env['ir.model.access'] - res = {} - for r in self: - r.active = False - r.count = 0 - r.computed_value = 0 - r.helper = '' - if ima_obj.check(r.model_id.model, 'read', False): - # Compute count item - model = self.env[r.model_id.model] - r.count = model.search_count(eval(r.domain)) - r.active = True - - # Compute datas for field_id depending of field_function - if r.field_function and r.field_id and r.count != 0: - records = model.search(eval(r.domain)) - vals = [x[r.field_id.name] for x in records] - desc = r.field_id.field_description - if r.field_function == 'min': - r.computed_value = min(vals) - r.helper = _("Minimum value of '%s'") % desc - elif r.field_function == 'max': - r.computed_value = max(vals) - r.helper = _("Maximum value of '%s'") % desc - elif r.field_function == 'sum': - r.computed_value = sum(vals) - r.helper = _("Total value of '%s'") % desc - elif r.field_function == 'avg': - r.computed_value = sum(vals) / len(vals) - r.helper = _("Average value of '%s'") % desc - elif r.field_function == 'median': - r.computed_value = self.median(vals) - r.helper = _("Median value of '%s'") % desc - return res -======= def _get_eval_context(self): def _context_today(): return fields.Date.from_string(fields.Date.context_today(self)) @@ -238,13 +160,13 @@ class TileTile(models.Model): self.primary_function != 'count', self.secondary_function and self.secondary_function != 'count' - ]): - records = model.search(eval(domain, eval_context)) + ]): + records = model.search(eval(domain, eval_context)) for f in ['primary_', 'secondary_']: - f_function = f+'function' - f_field_id = f+'field_id' - f_format = f+'format' - f_value = f+'value' + f_function = f + 'function' + f_field_id = f + 'field_id' + f_format = f + 'format' + f_value = f + 'value' value = 0 if self[f_function] == 'count': value = count @@ -268,9 +190,9 @@ class TileTile(models.Model): 'secondary_function', 'secondary_field_id') def _compute_helper(self): for f in ['primary_', 'secondary_']: - f_function = f+'function' - f_field_id = f+'field_id' - f_helper = f+'helper' + f_function = f + 'function' + f_field_id = f + 'field_id' + f_helper = f + 'helper' self[f_helper] = '' field_func = FIELD_FUNCTIONS.get(self[f_function], {}) help = field_func.get('help', False) @@ -285,15 +207,13 @@ class TileTile(models.Model): def _compute_active(self): ima = self.env['ir.model.access'] self.active = ima.check(self.model_id.model, 'read', False) ->>>>>>> 3ab676d... [IMP][8.0][web_dashboard_tile] Refactor (see changes in description) (#476) def _search_active(self, operator, value): cr = self.env.cr if operator != '=': raise except_orm( - 'Unimplemented Feature', - 'Search on Active field disabled.') - ima_obj = self.env['ir.model.access'] + _('Unimplemented Feature. Search on Active field disabled.')) + ima = self.env['ir.model.access'] ids = [] cr.execute(""" SELECT tt.id, im.model @@ -301,40 +221,10 @@ class TileTile(models.Model): INNER JOIN ir_model im ON tt.model_id = im.id""") for result in cr.fetchall(): - if (ima_obj.check(result[1], 'read', False) == value): + if (ima.check(result[1], 'read', False) == value): ids.append(result[0]) return [('id', 'in', ids)] -<<<<<<< HEAD - # Column Section - name = fields.Char(required=True) - model_id = fields.Many2one( - comodel_name='ir.model', string='Model', required=True) - user_id = fields.Many2one( - comodel_name='res.users', string='User') - domain = fields.Text(default='[]') - action_id = fields.Many2one( - comodel_name='ir.actions.act_window', string='Action') - count = fields.Integer(compute='_get_tile_info') - computed_value = fields.Float(compute='_get_tile_info') - helper = fields.Char(compute='_get_tile_info') - field_function = fields.Selection(selection=[ - ('min', 'Minimum'), - ('max', 'Maximum'), - ('sum', 'Sum'), - ('avg', 'Average'), - ('median', 'Median'), - ], string='Function') - field_id = fields.Many2one( - comodel_name='ir.model.fields', string='Field', - domain="[('model_id', '=', model_id)," - " ('ttype', 'in', ['float', 'int'])]") - active = fields.Boolean( - compute='_get_tile_info', readonly=True, search='_search_active') - background_color = fields.Char(default='#0E6C7E', oldname='color') - font_color = fields.Char(default='#FFFFFF') - sequence = fields.Integer(default=0, required=True) -======= # Constraints and onchanges @api.one @api.constrains('model_id', 'primary_field_id', 'secondary_field_id') @@ -344,9 +234,9 @@ class TileTile(models.Model): self.primary_field_id.model_id.id != self.model_id.id, self.secondary_field_id and self.secondary_field_id.model_id.id != self.model_id.id - ]): - raise ValidationError( - _("Please select a field from the selected model.")) + ]): + raise ValidationError( + _("Please select a field from the selected model.")) @api.onchange('model_id') def _onchange_model_id(self): @@ -359,34 +249,8 @@ class TileTile(models.Model): self.primary_field_id = False if self.secondary_function in [False, 'count']: self.secondary_field_id = False ->>>>>>> 3ab676d... [IMP][8.0][web_dashboard_tile] Refactor (see changes in description) (#476) - - # 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']), - ] - # View / action Section + # Action methods @api.multi def open_link(self): res = { @@ -403,8 +267,7 @@ class TileTile(models.Model): } if self.action_id: res.update(self.action_id.read( - ['view_type', 'view_mode', 'view_id', 'type'])[0]) - # FIXME: restore original Domain + Filter would be better + ['view_type', 'view_mode', 'type'])[0]) return res @api.model diff --git a/web_dashboard_tile/static/src/css/tile.css b/web_dashboard_tile/static/src/css/tile.css index 4ec483d7..73b811d3 100644 --- a/web_dashboard_tile/static/src/css/tile.css +++ b/web_dashboard_tile/static/src/css/tile.css @@ -1,17 +1,10 @@ -.openerp .oe_kanban_view .oe_dashbaord_tile{ +.openerp .oe_kanban_view .oe_dashboard_tile { width: 150px; height: 150px; border: 0; border-radius: 0; } -<<<<<<< HEAD -.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; -======= /* Disable default kanban style */ .openerp .oe_kanban_view .oe_dashboard_tile .oe_kanban_content div:first-child { margin-right: inherit!important; @@ -20,44 +13,27 @@ .openerp .oe_kanban_view .oe_dashboard_tile .tile_label, .openerp .oe_kanban_view .oe_dashboard_tile .tile_primary_value, .openerp .oe_kanban_view .oe_dashboard_tile .tile_secondary_value { ->>>>>>> 3ab676d... [IMP][8.0][web_dashboard_tile] Refactor (see changes in description) (#476) text-align: center; font-weight: bold; } -<<<<<<< HEAD -.openerp .oe_kanban_view .oe_dashbaord_tile .tile_label{ -======= .openerp .oe_kanban_view .oe_dashboard_tile .tile_label { ->>>>>>> 3ab676d... [IMP][8.0][web_dashboard_tile] Refactor (see changes in description) (#476) padding: 5px; font-size: 15px; } -<<<<<<< HEAD -.openerp .oe_kanban_view .oe_dashbaord_tile .tile_count_without_computed_value{ - font-size: 52px; - font-weight: bold; -======= .openerp .oe_kanban_view .oe_dashboard_tile .tile_primary_value{ font-size: 54px; ->>>>>>> 3ab676d... [IMP][8.0][web_dashboard_tile] Refactor (see changes in description) (#476) position: absolute; left: 5px; right: 5px; bottom: 5px; } -<<<<<<< HEAD -.openerp .oe_kanban_view .oe_dashbaord_tile .tile_count_with_computed_value{ - font-size: 38px; - font-weight: bold; -======= .openerp .oe_kanban_view .oe_dashboard_tile .tile_secondary_value{ display: none; font-size: 18px; font-style: italic; ->>>>>>> 3ab676d... [IMP][8.0][web_dashboard_tile] Refactor (see changes in description) (#476) position: absolute; left: 5px; right: 5px; @@ -69,16 +45,6 @@ bottom: 30px; } -<<<<<<< HEAD -.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_dashboard_tile .with_secondary .tile_secondary_value{ display: block; } @@ -90,5 +56,4 @@ .openerp .oe_searchview_drawer .oe_opened .oe_dashboard_tile_form { display: block; -} ->>>>>>> 3ab676d... [IMP][8.0][web_dashboard_tile] Refactor (see changes in description) (#476) +} \ No newline at end of file diff --git a/web_dashboard_tile/static/src/js/custom_js.js b/web_dashboard_tile/static/src/js/custom_js.js index c192ef29..9015f9a9 100644 --- a/web_dashboard_tile/static/src/js/custom_js.js +++ b/web_dashboard_tile/static/src/js/custom_js.js @@ -19,7 +19,7 @@ // //############################################################################# -openerp.web_dashboard_tile = function (instance) +odoo.web_dashboard_tile = function (instance) { var QWeb = instance.web.qweb, _t = instance.web._t, @@ -35,13 +35,13 @@ _.mixin({ var self = this; this.$('#add_dashboard_tile').on('click', this, function (){ self.save_tile(); - }) + }); }, render_data: function(dashboard_choices){ var selection = instance.web.qweb.render( "SearchView.addtodashboard.selection", { selections: dashboard_choices}); - this.$("form input").before(selection) + this.$("form input").before(selection); }, save_tile: function () { var self = this; @@ -97,4 +97,4 @@ _.mixin({ } }); -} +}; diff --git a/web_dashboard_tile/static/src/xml/custom_xml.xml b/web_dashboard_tile/static/src/xml/custom_xml.xml index 3e0c2316..11ecb179 100644 --- a/web_dashboard_tile/static/src/xml/custom_xml.xml +++ b/web_dashboard_tile/static/src/xml/custom_xml.xml @@ -2,11 +2,11 @@ -
+
- + \ No newline at end of file diff --git a/web_dashboard_tile/views/templates.xml b/web_dashboard_tile/views/templates.xml index e7a68b21..1fe51f0d 100644 --- a/web_dashboard_tile/views/templates.xml +++ b/web_dashboard_tile/views/templates.xml @@ -30,4 +30,4 @@ - + \ No newline at end of file diff --git a/web_dashboard_tile/views/tile.xml b/web_dashboard_tile/views/tile.xml index cf9a003f..a42d952f 100644 --- a/web_dashboard_tile/views/tile.xml +++ b/web_dashboard_tile/views/tile.xml @@ -103,7 +103,7 @@ -
+
@@ -152,9 +152,9 @@ Dashboard - + - + From 5f33d4868f486521b43aa5276d0111e7050c486d Mon Sep 17 00:00:00 2001 From: Nicolas Mac Rouillon Date: Tue, 13 Dec 2016 15:34:23 -0300 Subject: [PATCH 22/50] FIX __openerp__ --- web_dashboard_tile/__openerp__.py | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/web_dashboard_tile/__openerp__.py b/web_dashboard_tile/__openerp__.py index bcba4eb5..dbda3d3b 100644 --- a/web_dashboard_tile/__openerp__.py +++ b/web_dashboard_tile/__openerp__.py @@ -1,26 +1,4 @@ # -*- coding: utf-8 -*- -############################################################################## -# -# OpenERP, Open Source Management Solution -# Copyright (C) 2010-2013 OpenERP s.a. (). -# Copyright (C) 2014 initOS GmbH & Co. KG (). -# Author Markus Schneider -# -# 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 . -# -############################################################################## -# -*- coding: utf-8 -*- # © 2010-2013 OpenERP s.a. (). # © 2014 initOS GmbH & Co. KG (). # License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html From 66e5837c2887072ff2620c1cd83521796138fc74 Mon Sep 17 00:00:00 2001 From: Nicolas Mac Rouillon Date: Tue, 13 Dec 2016 15:44:42 -0300 Subject: [PATCH 23/50] FIX --- web_dashboard_tile/README.rst | 2 +- web_dashboard_tile/static/src/xml/custom_xml.xml | 2 +- web_dashboard_tile/views/templates.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/web_dashboard_tile/README.rst b/web_dashboard_tile/README.rst index 523dcadb..daa3a2eb 100644 --- a/web_dashboard_tile/README.rst +++ b/web_dashboard_tile/README.rst @@ -74,4 +74,4 @@ This module is maintained by the OCA. OCA, or the Odoo Community Association, is a nonprofit organization whose mission is to support the collaborative development of Odoo features and promote its widespread use. -To contribute to this module, please visit http://odoo-community.org. \ No newline at end of file +To contribute to this module, please visit http://odoo-community.org. diff --git a/web_dashboard_tile/static/src/xml/custom_xml.xml b/web_dashboard_tile/static/src/xml/custom_xml.xml index 11ecb179..38a0e3e9 100644 --- a/web_dashboard_tile/static/src/xml/custom_xml.xml +++ b/web_dashboard_tile/static/src/xml/custom_xml.xml @@ -9,4 +9,4 @@
- \ No newline at end of file + diff --git a/web_dashboard_tile/views/templates.xml b/web_dashboard_tile/views/templates.xml index 1fe51f0d..e7a68b21 100644 --- a/web_dashboard_tile/views/templates.xml +++ b/web_dashboard_tile/views/templates.xml @@ -30,4 +30,4 @@ - \ No newline at end of file + From 839262a11bda12c3f87fc6b584323d74e184d0fd Mon Sep 17 00:00:00 2001 From: Nicolas Mac Rouillon Date: Tue, 13 Dec 2016 16:02:54 -0300 Subject: [PATCH 24/50] FIX remove api.one --- web_advanced_search_wildcard/README.rst | 61 -------- web_advanced_search_wildcard/__init__.py | 0 web_advanced_search_wildcard/__openerp__.py | 21 --- web_advanced_search_wildcard/i18n/de.po | 27 ---- web_advanced_search_wildcard/i18n/es.po | 26 ---- web_advanced_search_wildcard/i18n/fi.po | 26 ---- web_advanced_search_wildcard/i18n/fr.po | 26 ---- web_advanced_search_wildcard/i18n/pt_BR.po | 26 ---- web_advanced_search_wildcard/i18n/sl.po | 26 ---- .../i18n/web_advanced_search_wildcard.pot | 23 --- .../static/description/screenshot.png | Bin 7164 -> 0 bytes .../static/src/js/search.js | 6 - .../views/template.xml | 10 -- web_dashboard_tile/models/tile_tile.py | 136 +++++++++--------- 14 files changed, 70 insertions(+), 344 deletions(-) delete mode 100644 web_advanced_search_wildcard/README.rst delete mode 100644 web_advanced_search_wildcard/__init__.py delete mode 100644 web_advanced_search_wildcard/__openerp__.py delete mode 100644 web_advanced_search_wildcard/i18n/de.po delete mode 100644 web_advanced_search_wildcard/i18n/es.po delete mode 100644 web_advanced_search_wildcard/i18n/fi.po delete mode 100644 web_advanced_search_wildcard/i18n/fr.po delete mode 100644 web_advanced_search_wildcard/i18n/pt_BR.po delete mode 100644 web_advanced_search_wildcard/i18n/sl.po delete mode 100644 web_advanced_search_wildcard/i18n/web_advanced_search_wildcard.pot delete mode 100644 web_advanced_search_wildcard/static/description/screenshot.png delete mode 100644 web_advanced_search_wildcard/static/src/js/search.js delete mode 100644 web_advanced_search_wildcard/views/template.xml diff --git a/web_advanced_search_wildcard/README.rst b/web_advanced_search_wildcard/README.rst deleted file mode 100644 index 8c6de995..00000000 --- a/web_advanced_search_wildcard/README.rst +++ /dev/null @@ -1,61 +0,0 @@ -.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg - :alt: License: AGPL-3 - -============================ -Wildcard in advanced search -============================ - -Allows =ilike ('matches') operator to advanced search option. - - -Usage -===== -Use % as a placeholder. - -Example: "Zip" - 'matches' - "1%" gives all zip starting with 1 - -.. image:: /web_advanced_search_wildcard/static/description/screenshot.png - :alt: Screenshot - - -Also allows insensitive exact search. -Example "Name" - 'matches' - "john" will find "John" and "john" but not "Johnson". - -Bug Tracker -=========== - -Bugs are tracked on `GitHub Issues `_. -In case of trouble, please check there if your issue has already been reported. -If you spotted it first, help us smashing it by providing a detailed and welcomed feedback -`here `_. - -Credits -======= - -Images ------- - -* Odoo Community Association: `Icon `_. - -Contributors ------------- - -* Markus Schneider -* Thomas Rehn -* L Freeke - - -Maintainer ----------- - -.. image:: https://odoo-community.org/logo.png - :alt: Odoo Community Association - :target: https://odoo-community.org - -This module is maintained by the OCA. - -OCA, or the Odoo Community Association, is a nonprofit organization whose -mission is to support the collaborative development of Odoo features and -promote its widespread use. - -To contribute to this module, please visit https://odoo-community.org. diff --git a/web_advanced_search_wildcard/__init__.py b/web_advanced_search_wildcard/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/web_advanced_search_wildcard/__openerp__.py b/web_advanced_search_wildcard/__openerp__.py deleted file mode 100644 index 797f3a60..00000000 --- a/web_advanced_search_wildcard/__openerp__.py +++ /dev/null @@ -1,21 +0,0 @@ -# -*- coding: utf-8 -*- -# © 2014 initOS GmbH & Co. KG (). -# © 2016 Therp BV . -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). - -{ - "name": "Wildcard in advanced search", - "summary": "Webmodule to add wildcard operators in advanced search field", - "version": "8.0.1.0.0", - "category": "web", - "license": 'AGPL-3', - "author": "initOS GmbH & Co. KG,Odoo Community Association (OCA),Therp BV", - "application": False, - "installable": True, - "depends": [ - "web" - ], - 'data': [ - "views/template.xml", - ], -} diff --git a/web_advanced_search_wildcard/i18n/de.po b/web_advanced_search_wildcard/i18n/de.po deleted file mode 100644 index 4cfbc4f3..00000000 --- a/web_advanced_search_wildcard/i18n/de.po +++ /dev/null @@ -1,27 +0,0 @@ -# Translation of OpenERP Server. -# This file contains the translation of the following modules: -# -# Rudolf Schnapka , 2015. -msgid "" -msgstr "" -"Project-Id-Version: OpenERP Server 7.0\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2014-09-15 09:11+0000\n" -"PO-Revision-Date: 2015-01-04 14:07+0100\n" -"Last-Translator: Rudolf Schnapka \n" -"Language-Team: German \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: \n" -"Language: de\n" -"X-Generator: Lokalize 1.5\n" - -#. module: web_advanced_search_wildcard -#. openerp-web -#: code:addons/web_advanced_search_wildcard/static/src/js/search.js:4 -#, python-format -msgid "matches" -msgstr "gleicht" - - diff --git a/web_advanced_search_wildcard/i18n/es.po b/web_advanced_search_wildcard/i18n/es.po deleted file mode 100644 index 2f9437ce..00000000 --- a/web_advanced_search_wildcard/i18n/es.po +++ /dev/null @@ -1,26 +0,0 @@ -# Translation of Odoo Server. -# This file contains the translation of the following modules: -# * web_advanced_search_wildcard -# -# Translators: -# Pedro M. Baeza , 2016 -msgid "" -msgstr "" -"Project-Id-Version: web (8.0)\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2016-11-26 01:59+0000\n" -"PO-Revision-Date: 2016-10-13 18:37+0000\n" -"Last-Translator: Pedro M. Baeza \n" -"Language-Team: Spanish (http://www.transifex.com/oca/OCA-web-8-0/language/es/)\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: \n" -"Language: es\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" - -#. module: web_advanced_search_wildcard -#. openerp-web -#: code:addons/web_advanced_search_wildcard/static/src/js/search.js:4 -#, python-format -msgid "matches" -msgstr "coincide con" diff --git a/web_advanced_search_wildcard/i18n/fi.po b/web_advanced_search_wildcard/i18n/fi.po deleted file mode 100644 index 91f0ab2e..00000000 --- a/web_advanced_search_wildcard/i18n/fi.po +++ /dev/null @@ -1,26 +0,0 @@ -# Translation of Odoo Server. -# This file contains the translation of the following modules: -# * web_advanced_search_wildcard -# -# Translators: -# Jarmo Kortetjärvi , 2016 -msgid "" -msgstr "" -"Project-Id-Version: web (8.0)\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2016-03-11 02:17+0000\n" -"PO-Revision-Date: 2016-03-07 08:28+0000\n" -"Last-Translator: Jarmo Kortetjärvi \n" -"Language-Team: Finnish (http://www.transifex.com/oca/OCA-web-8-0/language/fi/)\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: \n" -"Language: fi\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" - -#. module: web_advanced_search_wildcard -#. openerp-web -#: code:addons/web_advanced_search_wildcard/static/src/js/search.js:4 -#, python-format -msgid "matches" -msgstr "osumat" diff --git a/web_advanced_search_wildcard/i18n/fr.po b/web_advanced_search_wildcard/i18n/fr.po deleted file mode 100644 index 302b2e39..00000000 --- a/web_advanced_search_wildcard/i18n/fr.po +++ /dev/null @@ -1,26 +0,0 @@ -# Translation of Odoo Server. -# This file contains the translation of the following modules: -# * web_advanced_search_wildcard -# -# Translators: -# Christophe CHAUVET , 2016 -msgid "" -msgstr "" -"Project-Id-Version: web (8.0)\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2016-05-06 15:50+0000\n" -"PO-Revision-Date: 2016-05-06 08:19+0000\n" -"Last-Translator: Christophe CHAUVET \n" -"Language-Team: French (http://www.transifex.com/oca/OCA-web-8-0/language/fr/)\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: \n" -"Language: fr\n" -"Plural-Forms: nplurals=2; plural=(n > 1);\n" - -#. module: web_advanced_search_wildcard -#. openerp-web -#: code:addons/web_advanced_search_wildcard/static/src/js/search.js:4 -#, python-format -msgid "matches" -msgstr "correspondances" diff --git a/web_advanced_search_wildcard/i18n/pt_BR.po b/web_advanced_search_wildcard/i18n/pt_BR.po deleted file mode 100644 index 0464430f..00000000 --- a/web_advanced_search_wildcard/i18n/pt_BR.po +++ /dev/null @@ -1,26 +0,0 @@ -# Translation of Odoo Server. -# This file contains the translation of the following modules: -# * web_advanced_search_wildcard -# -# Translators: -# danimaribeiro , 2016 -msgid "" -msgstr "" -"Project-Id-Version: web (8.0)\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2016-03-11 02:17+0000\n" -"PO-Revision-Date: 2016-03-05 16:05+0000\n" -"Last-Translator: danimaribeiro \n" -"Language-Team: Portuguese (Brazil) (http://www.transifex.com/oca/OCA-web-8-0/language/pt_BR/)\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: \n" -"Language: pt_BR\n" -"Plural-Forms: nplurals=2; plural=(n > 1);\n" - -#. module: web_advanced_search_wildcard -#. openerp-web -#: code:addons/web_advanced_search_wildcard/static/src/js/search.js:4 -#, python-format -msgid "matches" -msgstr "resultados" diff --git a/web_advanced_search_wildcard/i18n/sl.po b/web_advanced_search_wildcard/i18n/sl.po deleted file mode 100644 index f8aa6f65..00000000 --- a/web_advanced_search_wildcard/i18n/sl.po +++ /dev/null @@ -1,26 +0,0 @@ -# Translation of Odoo Server. -# This file contains the translation of the following modules: -# * web_advanced_search_wildcard -# -# Translators: -# Matjaž Mozetič , 2016 -msgid "" -msgstr "" -"Project-Id-Version: web (8.0)\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2016-02-26 02:05+0000\n" -"PO-Revision-Date: 2016-02-27 16:56+0000\n" -"Last-Translator: Matjaž Mozetič \n" -"Language-Team: Slovenian (http://www.transifex.com/oca/OCA-web-8-0/language/sl/)\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: \n" -"Language: sl\n" -"Plural-Forms: nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);\n" - -#. module: web_advanced_search_wildcard -#. openerp-web -#: code:addons/web_advanced_search_wildcard/static/src/js/search.js:4 -#, python-format -msgid "matches" -msgstr "ujemanj" diff --git a/web_advanced_search_wildcard/i18n/web_advanced_search_wildcard.pot b/web_advanced_search_wildcard/i18n/web_advanced_search_wildcard.pot deleted file mode 100644 index e187a2da..00000000 --- a/web_advanced_search_wildcard/i18n/web_advanced_search_wildcard.pot +++ /dev/null @@ -1,23 +0,0 @@ -# Translation of OpenERP Server. -# This file contains the translation of the following modules: -# -msgid "" -msgstr "" -"Project-Id-Version: OpenERP Server 7.0\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2014-09-15 09:11+0000\n" -"PO-Revision-Date: 2014-09-15 11:12+0100\n" -"Last-Translator: M\n" -"Language-Team: \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: \n" - -#. module: web_advanced_search_wildcard -#. openerp-web -#: code:addons/web_advanced_search_wildcard/static/src/js/search.js:4 -#, python-format -msgid "matches" -msgstr "" - diff --git a/web_advanced_search_wildcard/static/description/screenshot.png b/web_advanced_search_wildcard/static/description/screenshot.png deleted file mode 100644 index 57848f902890b9aa4c78caf54ccfbcaed08e3cf4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7164 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 S=28L@A - - - - - diff --git a/web_dashboard_tile/models/tile_tile.py b/web_dashboard_tile/models/tile_tile.py index bc304b69..38ce5c66 100644 --- a/web_dashboard_tile/models/tile_tile.py +++ b/web_dashboard_tile/models/tile_tile.py @@ -142,71 +142,74 @@ class TileTile(models.Model): string='Error Details', compute='_compute_data') - @api.one + @api.multi def _compute_data(self): - if not self.active: - return - model = self.env[self.model_id.model] - eval_context = self._get_eval_context() - domain = self.domain or '[]' - try: - count = model.search_count(eval(domain, eval_context)) - except Exception as e: - self.primary_value = self.secondary_value = 'ERR!' - self.error = str(e) - return - if any([ - self.primary_function and - self.primary_function != 'count', - self.secondary_function and - self.secondary_function != 'count' - ]): - records = model.search(eval(domain, eval_context)) - for f in ['primary_', 'secondary_']: - f_function = f + 'function' - f_field_id = f + 'field_id' - f_format = f + 'format' - f_value = f + 'value' - value = 0 - if self[f_function] == 'count': - value = count - elif self[f_function]: - func = FIELD_FUNCTIONS[self[f_function]]['func'] - if func and self[f_field_id] and count: - vals = [x[self[f_field_id].name] for x in records] - value = func(vals) - if self[f_function]: - try: - self[f_value] = (self[f_format] or '{:,}').format(value) - except ValueError as e: - self[f_value] = 'F_ERR!' - self.error = str(e) - return - else: - self[f_value] = False + for rec in self: + if not rec.active: + return + model = self.env[rec.model_id.model] + eval_context = self._get_eval_context() + domain = rec.domain or '[]' + try: + count = model.search_count(eval(domain, eval_context)) + except Exception as e: + rec.primary_value = rec.secondary_value = 'ERR!' + rec.error = str(e) + return + if any([ + rec.primary_function and + rec.primary_function != 'count', + rec.secondary_function and + rec.secondary_function != 'count' + ]): + records = model.search(eval(domain, eval_context)) + for f in ['primary_', 'secondary_']: + f_function = f + 'function' + f_field_id = f + 'field_id' + f_format = f + 'format' + f_value = f + 'value' + value = 0 + if rec[f_function] == 'count': + value = count + elif rec[f_function]: + func = FIELD_FUNCTIONS[rec[f_function]]['func'] + if func and rec[f_field_id] and count: + vals = [x[rec[f_field_id].name] for x in records] + value = func(vals) + if rec[f_function]: + try: + rec[f_value] = (rec[f_format] or '{:,}').format(value) + except ValueError as e: + rec[f_value] = 'F_ERR!' + rec.error = str(e) + return + else: + rec[f_value] = False - @api.one + @api.multi @api.onchange('primary_function', 'primary_field_id', 'secondary_function', 'secondary_field_id') def _compute_helper(self): - for f in ['primary_', 'secondary_']: - f_function = f + 'function' - f_field_id = f + 'field_id' - f_helper = f + 'helper' - self[f_helper] = '' - field_func = FIELD_FUNCTIONS.get(self[f_function], {}) - help = field_func.get('help', False) - if help: - if self[f_function] != 'count' and self[f_field_id]: - desc = self[f_field_id].field_description - self[f_helper] = help % desc - else: - self[f_helper] = help + for rec in self: + for f in ['primary_', 'secondary_']: + f_function = f + 'function' + f_field_id = f + 'field_id' + f_helper = f + 'helper' + rec[f_helper] = '' + field_func = FIELD_FUNCTIONS.get(rec[f_function], {}) + help = field_func.get('help', False) + if help: + if rec[f_function] != 'count' and rec[f_field_id]: + desc = rec[f_field_id].field_description + rec[f_helper] = help % desc + else: + rec[f_helper] = help - @api.one + @api.multi def _compute_active(self): ima = self.env['ir.model.access'] - self.active = ima.check(self.model_id.model, 'read', False) + for rec in self: + rec.active = ima.check(rec.model_id.model, 'read', False) def _search_active(self, operator, value): cr = self.env.cr @@ -226,17 +229,18 @@ class TileTile(models.Model): return [('id', 'in', ids)] # Constraints and onchanges - @api.one + @api.multi @api.constrains('model_id', 'primary_field_id', 'secondary_field_id') def _check_model_id_field_id(self): - if any([ - self.primary_field_id and - self.primary_field_id.model_id.id != self.model_id.id, - self.secondary_field_id and - self.secondary_field_id.model_id.id != self.model_id.id - ]): - raise ValidationError( - _("Please select a field from the selected model.")) + for rec in self: + if any([ + rec.primary_field_id and + rec.primary_field_id.model_id.id != rec.model_id.id, + rec.secondary_field_id and + rec.secondary_field_id.model_id.id != rec.model_id.id + ]): + raise ValidationError( + _("Please select a field from the selected model.")) @api.onchange('model_id') def _onchange_model_id(self): From 6491de1889bb3916181116e58a3fb3c8c9843cca Mon Sep 17 00:00:00 2001 From: Markus Schneider Date: Mon, 15 Sep 2014 16:13:51 +0200 Subject: [PATCH 25/50] add web_advanced_search_wildcard module --- web_advanced_search_wildcard/__init__.py | 0 web_advanced_search_wildcard/__openerp__.py | 47 +++++++++++++++++++ web_advanced_search_wildcard/i18n/de.po | 6 +++ .../i18n/search_enhanced_operators.po | 23 +++++++++ .../static/src/js/search.js | 6 +++ 5 files changed, 82 insertions(+) create mode 100644 web_advanced_search_wildcard/__init__.py create mode 100644 web_advanced_search_wildcard/__openerp__.py create mode 100644 web_advanced_search_wildcard/i18n/de.po create mode 100644 web_advanced_search_wildcard/i18n/search_enhanced_operators.po create mode 100644 web_advanced_search_wildcard/static/src/js/search.js diff --git a/web_advanced_search_wildcard/__init__.py b/web_advanced_search_wildcard/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/web_advanced_search_wildcard/__openerp__.py b/web_advanced_search_wildcard/__openerp__.py new file mode 100644 index 00000000..3308ec6f --- /dev/null +++ b/web_advanced_search_wildcard/__openerp__.py @@ -0,0 +1,47 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2010-2013 OpenERP s.a. (). +# Copyright (C) 2014 initOS GmbH & Co. KG (). +# Author Thomas Rehn +# +# 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 . +# +############################################################################## +{ + "name": "Webmodule add wildcard operators for advanced search", + "version": "0.1", + "depends": ["web"], + 'author': 'initOS GmbH & Co. KG', + "category": "", + "summary": "Simular search in searchbar", + 'license': 'AGPL-3', + "description": """ + Allows =ilike operator to advanced search option. + Use % as a placeholder. + Example: "Zip matches 1%" gives all zip starting with 1 + Also allows insensitive exact search. + Example "Name matches john" will find "John" and "john" but not "Johnson". + """, + 'data': [ + ], + 'demo': [ + ], + 'test': [ + ], + 'js': ['static/src/js/search.js'], + 'installable': True, + 'auto_install': False, +} diff --git a/web_advanced_search_wildcard/i18n/de.po b/web_advanced_search_wildcard/i18n/de.po new file mode 100644 index 00000000..314c4df2 --- /dev/null +++ b/web_advanced_search_wildcard/i18n/de.po @@ -0,0 +1,6 @@ +#. module: web +#. openerp-web +#: code:addons/search_enhanced_operators/static/src/js/search.js:3 +#, python-format +msgid "matches" +msgstr "entspricht" diff --git a/web_advanced_search_wildcard/i18n/search_enhanced_operators.po b/web_advanced_search_wildcard/i18n/search_enhanced_operators.po new file mode 100644 index 00000000..d6a1a5ac --- /dev/null +++ b/web_advanced_search_wildcard/i18n/search_enhanced_operators.po @@ -0,0 +1,23 @@ +# Translation of OpenERP Server. +# This file contains the translation of the following modules: +# +msgid "" +msgstr "" +"Project-Id-Version: OpenERP Server 7.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2014-09-15 09:11+0000\n" +"PO-Revision-Date: 2014-09-15 11:12+0100\n" +"Last-Translator: M\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: \n" + +#. module: search_enhanced_operators +#. openerp-web +#: code:addons/search_enhanced_operators/static/src/js/search.js:4 +#, python-format +msgid "matches" +msgstr "" + diff --git a/web_advanced_search_wildcard/static/src/js/search.js b/web_advanced_search_wildcard/static/src/js/search.js new file mode 100644 index 00000000..4a5318a8 --- /dev/null +++ b/web_advanced_search_wildcard/static/src/js/search.js @@ -0,0 +1,6 @@ +openerp.search_enhanced_operators = function(instance){ + var _lt = instance.web._lt; + instance.web.search.ExtendedSearchProposition.Char.prototype.operators.push( + {value: '=ilike', text: _lt("matches")} + ); +}; From 01e76cbe5b4b5118652eed693cab42db59e9b1ae Mon Sep 17 00:00:00 2001 From: Markus Schneider Date: Thu, 18 Sep 2014 13:07:44 +0200 Subject: [PATCH 26/50] rename empty translation file --- ...rch_enhanced_operators.po => web_advanced_search_wildcard.pot} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename web_advanced_search_wildcard/i18n/{search_enhanced_operators.po => web_advanced_search_wildcard.pot} (100%) diff --git a/web_advanced_search_wildcard/i18n/search_enhanced_operators.po b/web_advanced_search_wildcard/i18n/web_advanced_search_wildcard.pot similarity index 100% rename from web_advanced_search_wildcard/i18n/search_enhanced_operators.po rename to web_advanced_search_wildcard/i18n/web_advanced_search_wildcard.pot From 6329c2b7171aef0de85610fdfe7c80448bf502c9 Mon Sep 17 00:00:00 2001 From: Markus Schneider Date: Mon, 22 Sep 2014 11:13:21 +0200 Subject: [PATCH 27/50] rename module inside translation file --- web_advanced_search_wildcard/i18n/de.po | 2 +- .../i18n/web_advanced_search_wildcard.pot | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/web_advanced_search_wildcard/i18n/de.po b/web_advanced_search_wildcard/i18n/de.po index 314c4df2..bfc97d1a 100644 --- a/web_advanced_search_wildcard/i18n/de.po +++ b/web_advanced_search_wildcard/i18n/de.po @@ -1,6 +1,6 @@ #. module: web #. openerp-web -#: code:addons/search_enhanced_operators/static/src/js/search.js:3 +#: code:addons/web_advanced_search_wildcard/static/src/js/search.js:3 #, python-format msgid "matches" msgstr "entspricht" diff --git a/web_advanced_search_wildcard/i18n/web_advanced_search_wildcard.pot b/web_advanced_search_wildcard/i18n/web_advanced_search_wildcard.pot index d6a1a5ac..e187a2da 100644 --- a/web_advanced_search_wildcard/i18n/web_advanced_search_wildcard.pot +++ b/web_advanced_search_wildcard/i18n/web_advanced_search_wildcard.pot @@ -14,9 +14,9 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: \n" -#. module: search_enhanced_operators +#. module: web_advanced_search_wildcard #. openerp-web -#: code:addons/search_enhanced_operators/static/src/js/search.js:4 +#: code:addons/web_advanced_search_wildcard/static/src/js/search.js:4 #, python-format msgid "matches" msgstr "" From 92ac4559d2748ea9c70d472ebd0da4a3ab1f85f8 Mon Sep 17 00:00:00 2001 From: Rudolf Schnapka Date: Sun, 4 Jan 2015 14:51:33 +0100 Subject: [PATCH 28/50] initial german translations (and added pot-file) --- web_advanced_search_wildcard/i18n/de.po | 27 ++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/web_advanced_search_wildcard/i18n/de.po b/web_advanced_search_wildcard/i18n/de.po index bfc97d1a..4cfbc4f3 100644 --- a/web_advanced_search_wildcard/i18n/de.po +++ b/web_advanced_search_wildcard/i18n/de.po @@ -1,6 +1,27 @@ -#. module: web +# Translation of OpenERP Server. +# This file contains the translation of the following modules: +# +# Rudolf Schnapka , 2015. +msgid "" +msgstr "" +"Project-Id-Version: OpenERP Server 7.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2014-09-15 09:11+0000\n" +"PO-Revision-Date: 2015-01-04 14:07+0100\n" +"Last-Translator: Rudolf Schnapka \n" +"Language-Team: German \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: \n" +"Language: de\n" +"X-Generator: Lokalize 1.5\n" + +#. module: web_advanced_search_wildcard #. openerp-web -#: code:addons/web_advanced_search_wildcard/static/src/js/search.js:3 +#: code:addons/web_advanced_search_wildcard/static/src/js/search.js:4 #, python-format msgid "matches" -msgstr "entspricht" +msgstr "gleicht" + + From ec5c2d095c56865ada2303afece815aff0819525 Mon Sep 17 00:00:00 2001 From: Alexandre Fayolle Date: Mon, 2 Mar 2015 17:29:16 +0100 Subject: [PATCH 29/50] Add OCA as author of OCA addons In order to get visibility on https://www.odoo.com/apps the OCA board has decided to add the OCA as author of all the addons maintained as part of the association. --- web_advanced_search_wildcard/__openerp__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web_advanced_search_wildcard/__openerp__.py b/web_advanced_search_wildcard/__openerp__.py index 3308ec6f..dd4ee58e 100644 --- a/web_advanced_search_wildcard/__openerp__.py +++ b/web_advanced_search_wildcard/__openerp__.py @@ -24,7 +24,7 @@ "name": "Webmodule add wildcard operators for advanced search", "version": "0.1", "depends": ["web"], - 'author': 'initOS GmbH & Co. KG', + 'author': "initOS GmbH & Co. KG,Odoo Community Association (OCA)", "category": "", "summary": "Simular search in searchbar", 'license': 'AGPL-3', From 744e26410e84f6115ee1491f7a951b4e127b7e98 Mon Sep 17 00:00:00 2001 From: OCA Transbot Date: Sun, 11 Oct 2015 10:34:46 -0400 Subject: [PATCH 30/50] OCA Transbot updated translations from Transifex --- web_advanced_search_wildcard/i18n/en.po | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 web_advanced_search_wildcard/i18n/en.po diff --git a/web_advanced_search_wildcard/i18n/en.po b/web_advanced_search_wildcard/i18n/en.po new file mode 100644 index 00000000..e85bb958 --- /dev/null +++ b/web_advanced_search_wildcard/i18n/en.po @@ -0,0 +1,24 @@ +# Translation of OpenERP Server. +# This file contains the translation of the following modules: +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: web (7.0)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-10-07 17:50+0000\n" +"PO-Revision-Date: 2015-10-07 17:50+0000\n" +"Last-Translator: OCA Transbot \n" +"Language-Team: English (http://www.transifex.com/oca/OCA-web-7-0/language/en/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Language: en\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: web_advanced_search_wildcard +#. openerp-web +#: code:addons/web_advanced_search_wildcard/static/src/js/search.js:4 +#, python-format +msgid "matches" +msgstr "matches" From 164010006f400da8ca1616faddad3ecb69dad854 Mon Sep 17 00:00:00 2001 From: lfreeke Date: Thu, 21 Jan 2016 11:21:48 +0100 Subject: [PATCH 31/50] Adept javascript to module name --- web_advanced_search_wildcard/static/src/js/search.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web_advanced_search_wildcard/static/src/js/search.js b/web_advanced_search_wildcard/static/src/js/search.js index 4a5318a8..1b43dc0c 100644 --- a/web_advanced_search_wildcard/static/src/js/search.js +++ b/web_advanced_search_wildcard/static/src/js/search.js @@ -1,4 +1,4 @@ -openerp.search_enhanced_operators = function(instance){ +openerp.web_advanced_search_wildcard = function(instance){ var _lt = instance.web._lt; instance.web.search.ExtendedSearchProposition.Char.prototype.operators.push( {value: '=ilike', text: _lt("matches")} From b535374da8317a815516971d3ad9449578999466 Mon Sep 17 00:00:00 2001 From: lfreeke Date: Thu, 21 Jan 2016 13:30:57 +0100 Subject: [PATCH 32/50] port web_advanced_search_wildcard Conflicts: web_advanced_search_wildcard/__openerp__.py --- web_advanced_search_wildcard/README.rst | 43 +++++++++++++++++++ web_advanced_search_wildcard/__openerp__.py | 29 +++++-------- .../views/template.xml | 10 +++++ 3 files changed, 63 insertions(+), 19 deletions(-) create mode 100644 web_advanced_search_wildcard/README.rst create mode 100644 web_advanced_search_wildcard/views/template.xml diff --git a/web_advanced_search_wildcard/README.rst b/web_advanced_search_wildcard/README.rst new file mode 100644 index 00000000..9edc5fdf --- /dev/null +++ b/web_advanced_search_wildcard/README.rst @@ -0,0 +1,43 @@ +.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg + :alt: License: AGPL-3 + +============================ +Web advanced search wildcard +============================ + +Allows =ilike operator to advanced search option. + +Use % as a placeholder. +Example: "Zip matches 1%" gives all zip starting with 1 +Also allows insensitive exact search. +Example "Name matches john" will find "John" and "john" but not "Johnson". + + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues `_. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us smashing it by providing a detailed and welcomed feedback +`here `_. + + + +Contributors +------------ + +* Markus Schneider <> +* L Freeke + +Maintainer +---------- + +.. image:: http://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: http://odoo-community.org + +This module is maintained by the OCA. +OCA, or the Odoo Community Association, is a nonprofit organization whose mission is to support the collaborative development of Odoo features and promote its widespread use. +To contribute to this module, please visit http://odoo-community.org. + + diff --git a/web_advanced_search_wildcard/__openerp__.py b/web_advanced_search_wildcard/__openerp__.py index dd4ee58e..d2e6cd88 100644 --- a/web_advanced_search_wildcard/__openerp__.py +++ b/web_advanced_search_wildcard/__openerp__.py @@ -22,26 +22,17 @@ ############################################################################## { "name": "Webmodule add wildcard operators for advanced search", - "version": "0.1", - "depends": ["web"], - 'author': "initOS GmbH & Co. KG,Odoo Community Association (OCA)", - "category": "", "summary": "Simular search in searchbar", - 'license': 'AGPL-3', - "description": """ - Allows =ilike operator to advanced search option. - Use % as a placeholder. - Example: "Zip matches 1%" gives all zip starting with 1 - Also allows insensitive exact search. - Example "Name matches john" will find "John" and "john" but not "Johnson". - """, - 'data': [ - ], - 'demo': [ + "version": "8.0.1.0.0", + "category": "Uncategorized", + "license": 'AGPL-3', + "author": "initOS GmbH & Co. KG,Odoo Community Association (OCA), Therp BV", + "application": False, + "installable": True, + "depends": [ + "web" ], - 'test': [ + 'data': [ + "views/template.xml", ], - 'js': ['static/src/js/search.js'], - 'installable': True, - 'auto_install': False, } diff --git a/web_advanced_search_wildcard/views/template.xml b/web_advanced_search_wildcard/views/template.xml new file mode 100644 index 00000000..bfe353d5 --- /dev/null +++ b/web_advanced_search_wildcard/views/template.xml @@ -0,0 +1,10 @@ + + + + + + From 93b5b770dfdf682854cc5c3373540ad6a51954af Mon Sep 17 00:00:00 2001 From: lfreeke Date: Thu, 21 Jan 2016 14:59:16 +0100 Subject: [PATCH 33/50] whitespace --- web_advanced_search_wildcard/README.rst | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/web_advanced_search_wildcard/README.rst b/web_advanced_search_wildcard/README.rst index 9edc5fdf..031b8007 100644 --- a/web_advanced_search_wildcard/README.rst +++ b/web_advanced_search_wildcard/README.rst @@ -4,14 +4,13 @@ ============================ Web advanced search wildcard ============================ - + Allows =ilike operator to advanced search option. Use % as a placeholder. Example: "Zip matches 1%" gives all zip starting with 1 Also allows insensitive exact search. Example "Name matches john" will find "John" and "john" but not "Johnson". - Bug Tracker =========== From d9f07c43904494cc831e43b17e8c4571406dc58e Mon Sep 17 00:00:00 2001 From: lfreeke Date: Thu, 21 Jan 2016 13:33:20 +0100 Subject: [PATCH 34/50] Add email address in README file --- web_advanced_search_wildcard/README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web_advanced_search_wildcard/README.rst b/web_advanced_search_wildcard/README.rst index 031b8007..8425e1d8 100644 --- a/web_advanced_search_wildcard/README.rst +++ b/web_advanced_search_wildcard/README.rst @@ -25,7 +25,7 @@ If you spotted it first, help us smashing it by providing a detailed and welcome Contributors ------------ -* Markus Schneider <> +* Markus Schneider * L Freeke Maintainer From 68e4f299e6b8a752c8f3b3983f8d61f6c0af6f5a Mon Sep 17 00:00:00 2001 From: lfreeke Date: Thu, 21 Jan 2016 14:16:13 +0100 Subject: [PATCH 35/50] layout changes to readme file [MOD] Update manifest with latest OCA standard Conflicts: web_advanced_search_wildcard/__openerp__.py --- web_advanced_search_wildcard/README.rst | 20 +++++++++++---- web_advanced_search_wildcard/__openerp__.py | 27 ++++----------------- 2 files changed, 20 insertions(+), 27 deletions(-) diff --git a/web_advanced_search_wildcard/README.rst b/web_advanced_search_wildcard/README.rst index 8425e1d8..dcd65e33 100644 --- a/web_advanced_search_wildcard/README.rst +++ b/web_advanced_search_wildcard/README.rst @@ -20,23 +20,33 @@ In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us smashing it by providing a detailed and welcomed feedback `here `_. +Credits +======= +Images +------ + +* Odoo Community Association: `Icon `_. Contributors ------------ * Markus Schneider +* Thomas Rehn * L Freeke + Maintainer ---------- -.. image:: http://odoo-community.org/logo.png - :alt: Odoo Community Association - :target: http://odoo-community.org +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org This module is maintained by the OCA. -OCA, or the Odoo Community Association, is a nonprofit organization whose mission is to support the collaborative development of Odoo features and promote its widespread use. -To contribute to this module, please visit http://odoo-community.org. +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. +To contribute to this module, please visit https://odoo-community.org. diff --git a/web_advanced_search_wildcard/__openerp__.py b/web_advanced_search_wildcard/__openerp__.py index d2e6cd88..e54a77da 100644 --- a/web_advanced_search_wildcard/__openerp__.py +++ b/web_advanced_search_wildcard/__openerp__.py @@ -1,32 +1,15 @@ # -*- coding: utf-8 -*- -############################################################################## -# -# OpenERP, Open Source Management Solution -# Copyright (C) 2010-2013 OpenERP s.a. (). -# Copyright (C) 2014 initOS GmbH & Co. KG (). -# Author Thomas Rehn -# -# 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 . -# -############################################################################## +# © 2014 initOS GmbH & Co. KG (). +# © 2016 Therp BV . +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + { "name": "Webmodule add wildcard operators for advanced search", "summary": "Simular search in searchbar", "version": "8.0.1.0.0", "category": "Uncategorized", "license": 'AGPL-3', - "author": "initOS GmbH & Co. KG,Odoo Community Association (OCA), Therp BV", + "author": "initOS GmbH & Co. KG,Odoo Community Association (OCA),Therp BV", "application": False, "installable": True, "depends": [ From 1eb897eb1a82accae69e14a4d16bf7b23a6532f5 Mon Sep 17 00:00:00 2001 From: lfreeke Date: Wed, 3 Feb 2016 15:44:28 +0100 Subject: [PATCH 36/50] Manifest [MOD] README [ADD] Screenshot --- web_advanced_search_wildcard/README.rst | 17 +++++++++++++---- web_advanced_search_wildcard/__openerp__.py | 6 +++--- .../static/description/screenshot.png | Bin 0 -> 7164 bytes 3 files changed, 16 insertions(+), 7 deletions(-) create mode 100644 web_advanced_search_wildcard/static/description/screenshot.png diff --git a/web_advanced_search_wildcard/README.rst b/web_advanced_search_wildcard/README.rst index dcd65e33..8c6de995 100644 --- a/web_advanced_search_wildcard/README.rst +++ b/web_advanced_search_wildcard/README.rst @@ -2,15 +2,24 @@ :alt: License: AGPL-3 ============================ -Web advanced search wildcard +Wildcard in advanced search ============================ -Allows =ilike operator to advanced search option. +Allows =ilike ('matches') operator to advanced search option. + +Usage +===== Use % as a placeholder. -Example: "Zip matches 1%" gives all zip starting with 1 + +Example: "Zip" - 'matches' - "1%" gives all zip starting with 1 + +.. image:: /web_advanced_search_wildcard/static/description/screenshot.png + :alt: Screenshot + + Also allows insensitive exact search. -Example "Name matches john" will find "John" and "john" but not "Johnson". +Example "Name" - 'matches' - "john" will find "John" and "john" but not "Johnson". Bug Tracker =========== diff --git a/web_advanced_search_wildcard/__openerp__.py b/web_advanced_search_wildcard/__openerp__.py index e54a77da..797f3a60 100644 --- a/web_advanced_search_wildcard/__openerp__.py +++ b/web_advanced_search_wildcard/__openerp__.py @@ -4,10 +4,10 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). { - "name": "Webmodule add wildcard operators for advanced search", - "summary": "Simular search in searchbar", + "name": "Wildcard in advanced search", + "summary": "Webmodule to add wildcard operators in advanced search field", "version": "8.0.1.0.0", - "category": "Uncategorized", + "category": "web", "license": 'AGPL-3', "author": "initOS GmbH & Co. KG,Odoo Community Association (OCA),Therp BV", "application": False, diff --git a/web_advanced_search_wildcard/static/description/screenshot.png b/web_advanced_search_wildcard/static/description/screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..57848f902890b9aa4c78caf54ccfbcaed08e3cf4 GIT binary patch literal 7164 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 S=28L@A Date: Sun, 28 Feb 2016 05:11:25 -0500 Subject: [PATCH 37/50] OCA Transbot updated translations from Transifex --- web_advanced_search_wildcard/i18n/sl.po | 26 +++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 web_advanced_search_wildcard/i18n/sl.po diff --git a/web_advanced_search_wildcard/i18n/sl.po b/web_advanced_search_wildcard/i18n/sl.po new file mode 100644 index 00000000..f8aa6f65 --- /dev/null +++ b/web_advanced_search_wildcard/i18n/sl.po @@ -0,0 +1,26 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * web_advanced_search_wildcard +# +# Translators: +# Matjaž Mozetič , 2016 +msgid "" +msgstr "" +"Project-Id-Version: web (8.0)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-02-26 02:05+0000\n" +"PO-Revision-Date: 2016-02-27 16:56+0000\n" +"Last-Translator: Matjaž Mozetič \n" +"Language-Team: Slovenian (http://www.transifex.com/oca/OCA-web-8-0/language/sl/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Language: sl\n" +"Plural-Forms: nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);\n" + +#. module: web_advanced_search_wildcard +#. openerp-web +#: code:addons/web_advanced_search_wildcard/static/src/js/search.js:4 +#, python-format +msgid "matches" +msgstr "ujemanj" From 91418388cdcfc8c75907d48c90db710a6aea6733 Mon Sep 17 00:00:00 2001 From: OCA Transbot Date: Sun, 13 Mar 2016 09:15:04 -0400 Subject: [PATCH 38/50] OCA Transbot updated translations from Transifex --- web_advanced_search_wildcard/i18n/fi.po | 26 ++++++++++++++++++++++ web_advanced_search_wildcard/i18n/pt_BR.po | 26 ++++++++++++++++++++++ 2 files changed, 52 insertions(+) create mode 100644 web_advanced_search_wildcard/i18n/fi.po create mode 100644 web_advanced_search_wildcard/i18n/pt_BR.po diff --git a/web_advanced_search_wildcard/i18n/fi.po b/web_advanced_search_wildcard/i18n/fi.po new file mode 100644 index 00000000..91f0ab2e --- /dev/null +++ b/web_advanced_search_wildcard/i18n/fi.po @@ -0,0 +1,26 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * web_advanced_search_wildcard +# +# Translators: +# Jarmo Kortetjärvi , 2016 +msgid "" +msgstr "" +"Project-Id-Version: web (8.0)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-03-11 02:17+0000\n" +"PO-Revision-Date: 2016-03-07 08:28+0000\n" +"Last-Translator: Jarmo Kortetjärvi \n" +"Language-Team: Finnish (http://www.transifex.com/oca/OCA-web-8-0/language/fi/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Language: fi\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: web_advanced_search_wildcard +#. openerp-web +#: code:addons/web_advanced_search_wildcard/static/src/js/search.js:4 +#, python-format +msgid "matches" +msgstr "osumat" diff --git a/web_advanced_search_wildcard/i18n/pt_BR.po b/web_advanced_search_wildcard/i18n/pt_BR.po new file mode 100644 index 00000000..0464430f --- /dev/null +++ b/web_advanced_search_wildcard/i18n/pt_BR.po @@ -0,0 +1,26 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * web_advanced_search_wildcard +# +# Translators: +# danimaribeiro , 2016 +msgid "" +msgstr "" +"Project-Id-Version: web (8.0)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-03-11 02:17+0000\n" +"PO-Revision-Date: 2016-03-05 16:05+0000\n" +"Last-Translator: danimaribeiro \n" +"Language-Team: Portuguese (Brazil) (http://www.transifex.com/oca/OCA-web-8-0/language/pt_BR/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Language: pt_BR\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" + +#. module: web_advanced_search_wildcard +#. openerp-web +#: code:addons/web_advanced_search_wildcard/static/src/js/search.js:4 +#, python-format +msgid "matches" +msgstr "resultados" From 30025324a223d243748a8d4b40aeb03485035d95 Mon Sep 17 00:00:00 2001 From: OCA Transbot Date: Sun, 8 May 2016 15:21:29 -0400 Subject: [PATCH 39/50] OCA Transbot updated translations from Transifex --- web_advanced_search_wildcard/i18n/fr.po | 26 +++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 web_advanced_search_wildcard/i18n/fr.po diff --git a/web_advanced_search_wildcard/i18n/fr.po b/web_advanced_search_wildcard/i18n/fr.po new file mode 100644 index 00000000..302b2e39 --- /dev/null +++ b/web_advanced_search_wildcard/i18n/fr.po @@ -0,0 +1,26 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * web_advanced_search_wildcard +# +# Translators: +# Christophe CHAUVET , 2016 +msgid "" +msgstr "" +"Project-Id-Version: web (8.0)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-05-06 15:50+0000\n" +"PO-Revision-Date: 2016-05-06 08:19+0000\n" +"Last-Translator: Christophe CHAUVET \n" +"Language-Team: French (http://www.transifex.com/oca/OCA-web-8-0/language/fr/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Language: fr\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" + +#. module: web_advanced_search_wildcard +#. openerp-web +#: code:addons/web_advanced_search_wildcard/static/src/js/search.js:4 +#, python-format +msgid "matches" +msgstr "correspondances" From aa1b5586d285b42decd556a7a0d2d20b8a6b7723 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Bidoul=20=28ACSONE=29?= Date: Mon, 15 Aug 2016 22:15:57 +0200 Subject: [PATCH 40/50] remove en.po that was erroneously created by transbot --- web_advanced_search_wildcard/i18n/en.po | 24 ------------------------ 1 file changed, 24 deletions(-) delete mode 100644 web_advanced_search_wildcard/i18n/en.po diff --git a/web_advanced_search_wildcard/i18n/en.po b/web_advanced_search_wildcard/i18n/en.po deleted file mode 100644 index e85bb958..00000000 --- a/web_advanced_search_wildcard/i18n/en.po +++ /dev/null @@ -1,24 +0,0 @@ -# Translation of OpenERP Server. -# This file contains the translation of the following modules: -# -# Translators: -msgid "" -msgstr "" -"Project-Id-Version: web (7.0)\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-10-07 17:50+0000\n" -"PO-Revision-Date: 2015-10-07 17:50+0000\n" -"Last-Translator: OCA Transbot \n" -"Language-Team: English (http://www.transifex.com/oca/OCA-web-7-0/language/en/)\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: \n" -"Language: en\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" - -#. module: web_advanced_search_wildcard -#. openerp-web -#: code:addons/web_advanced_search_wildcard/static/src/js/search.js:4 -#, python-format -msgid "matches" -msgstr "matches" From 61ec225a3c946de084e1127b554a61ed246ce671 Mon Sep 17 00:00:00 2001 From: OCA Transbot Date: Tue, 29 Nov 2016 14:34:08 -0500 Subject: [PATCH 41/50] OCA Transbot updated translations from Transifex --- web_advanced_search_wildcard/i18n/es.po | 26 +++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 web_advanced_search_wildcard/i18n/es.po diff --git a/web_advanced_search_wildcard/i18n/es.po b/web_advanced_search_wildcard/i18n/es.po new file mode 100644 index 00000000..2f9437ce --- /dev/null +++ b/web_advanced_search_wildcard/i18n/es.po @@ -0,0 +1,26 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * web_advanced_search_wildcard +# +# Translators: +# Pedro M. Baeza , 2016 +msgid "" +msgstr "" +"Project-Id-Version: web (8.0)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-11-26 01:59+0000\n" +"PO-Revision-Date: 2016-10-13 18:37+0000\n" +"Last-Translator: Pedro M. Baeza \n" +"Language-Team: Spanish (http://www.transifex.com/oca/OCA-web-8-0/language/es/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Language: es\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: web_advanced_search_wildcard +#. openerp-web +#: code:addons/web_advanced_search_wildcard/static/src/js/search.js:4 +#, python-format +msgid "matches" +msgstr "coincide con" From cefa0fcb8def22f459a0b2e0d08cb577091d5ae5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Todorovich?= Date: Wed, 23 Nov 2016 13:12:43 -0300 Subject: [PATCH 42/50] [8.0][FIX] web_dashboard_tile security rule Rule was not being updated because of ``, hence the groups field of the tile was not working. Conflicts: web_dashboard_tile/__openerp__.py --- web_dashboard_tile/__openerp__.py | 4 +-- .../migrations/8.0.4.0/post-migration.py | 26 +++++++++++++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) create mode 100644 web_dashboard_tile/migrations/8.0.4.0/post-migration.py diff --git a/web_dashboard_tile/__openerp__.py b/web_dashboard_tile/__openerp__.py index 3e636b15..f84fd1b3 100644 --- a/web_dashboard_tile/__openerp__.py +++ b/web_dashboard_tile/__openerp__.py @@ -23,7 +23,7 @@ { "name": "Dashboard Tile", "summary": "Add Tiles to Dashboard", - "version": "8.0.1.0.0", + "version": "9.0.1.0.0", "depends": [ 'web', 'board', @@ -46,5 +46,5 @@ 'qweb': [ 'static/src/xml/custom_xml.xml', ], - 'installable': False, + 'installable': True, } diff --git a/web_dashboard_tile/migrations/8.0.4.0/post-migration.py b/web_dashboard_tile/migrations/8.0.4.0/post-migration.py new file mode 100644 index 00000000..570f814e --- /dev/null +++ b/web_dashboard_tile/migrations/8.0.4.0/post-migration.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- +# © 2016 Iván Todorovich +# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html + + +def migrate(cr, version): + if version is None: + return + + # Update ir.rule + cr.execute(""" + SELECT res_id FROM ir_model_data + WHERE name = 'model_tile_rule' + AND module = 'web_dashboard_tile'""") + rule_id = cr.fetchone()[0] + new_domain = """[ + "|", + ("user_id","=",user.id), + ("user_id","=",False), + "|", + ("group_ids","=",False), + ("group_ids","in",[g.id for g in user.groups_id]), + ]""" + cr.execute(""" + UPDATE ir_rule SET domain_force = '%(domain)s' + WHERE id = '%(id)s' """ % {'domain': new_domain, 'id': rule_id}) From 780481ac99b8ef02b13725ca92120986343ecaf5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Todorovich?= Date: Sat, 19 Nov 2016 14:07:01 -0300 Subject: [PATCH 43/50] [IMP][8.0][web_dashboard_tile] Refactor (see changes in description) (#476) Conflicts: web_dashboard_tile/README.rst web_dashboard_tile/__openerp__.py web_dashboard_tile/models/tile_tile.py web_dashboard_tile/static/src/css/tile.css --- web_dashboard_tile/README.rst | 36 +++ web_dashboard_tile/demo/tile_tile.yml | 4 +- .../migrations/8.0.3.0/post-migration.py | 13 + web_dashboard_tile/models/tile_tile.py | 237 ++++++++++++++++++ web_dashboard_tile/security/rules.xml | 11 +- web_dashboard_tile/static/src/css/tile.css | 50 ++++ .../static/src/img/screenshot_dashboard.png | Bin 45633 -> 20441 bytes web_dashboard_tile/tests/__init__.py | 6 + web_dashboard_tile/tests/test_tile.py | 52 ++++ web_dashboard_tile/views/tile.xml | 89 +++++-- 10 files changed, 468 insertions(+), 30 deletions(-) create mode 100644 web_dashboard_tile/migrations/8.0.3.0/post-migration.py create mode 100644 web_dashboard_tile/tests/__init__.py create mode 100644 web_dashboard_tile/tests/test_tile.py diff --git a/web_dashboard_tile/README.rst b/web_dashboard_tile/README.rst index c87fb47d..0337037b 100644 --- a/web_dashboard_tile/README.rst +++ b/web_dashboard_tile/README.rst @@ -1,6 +1,7 @@ Add Tiles to Dashboard ====================== +<<<<<<< HEAD module to give you a dashboard where you can configure tile from any view and add them as short cut. @@ -12,6 +13,24 @@ and add them as short cut. * 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; +======= +Adds a dashboard where you can configure tiles from any view and add them as short cut. + +By default, the tile displays items count of a given model restricted to a given domain. + +Optionally, the tile can display the result of a function on a field. + +- Function is one of `sum`, `avg`, `min`, `max` or `median`. +- Field must be integer or float. + +Tile can be: + +- Displayed only for a user. +- Global for all users. +- Restricted to some groups. + +*Note: The tile will be hidden if the current user doesn't have access to the given model.* +>>>>>>> 3ab676d... [IMP][8.0][web_dashboard_tile] Refactor (see changes in description) (#476) Usage ===== @@ -24,6 +43,7 @@ Usage Known issues / Roadmap ====================== +<<<<<<< HEAD * Can not edit tile from dashboard (color, sequence, function, ...); * Context are ignored; * Date filter can not be relative; @@ -31,6 +51,22 @@ Known issues / Roadmap * Support context_today; * Add icons; * Support client side action (like inbox); +======= +Known issues +============ +* Can not edit tile from dashboard (color, sequence, function, ...). +* Original context is ignored. +* Original domain and filter are not restored. +* To preserve a relative date domain, you have to manually edit the tile's domain from `Configuration > User Interface > Dashboard Tile`. You can use the same variables available in filters (`uid`, `context_today()`, `current_date`, `time`, `datetime`, `relativedelta`). + +Roadmap +======= +* Add icons. +* Support client side action (like inbox). +* Restore original Domain + Filter when an action is set. +* Posibility to hide the tile based on a field expression. +* Posibility to set the background color based on a field expression. +>>>>>>> 3ab676d... [IMP][8.0][web_dashboard_tile] Refactor (see changes in description) (#476) Bug Tracker =========== diff --git a/web_dashboard_tile/demo/tile_tile.yml b/web_dashboard_tile/demo/tile_tile.yml index 6b23b71b..dd9da016 100644 --- a/web_dashboard_tile/demo/tile_tile.yml +++ b/web_dashboard_tile/demo/tile_tile.yml @@ -36,5 +36,5 @@ name: Currencies (Max Rate) model_id: base.model_res_currency domain: [] - field_function: max - field_id: base.field_res_currency_rate + secondary_function: max + secondary_field_id: base.field_res_currency_rate diff --git a/web_dashboard_tile/migrations/8.0.3.0/post-migration.py b/web_dashboard_tile/migrations/8.0.3.0/post-migration.py new file mode 100644 index 00000000..7cfcc1c0 --- /dev/null +++ b/web_dashboard_tile/migrations/8.0.3.0/post-migration.py @@ -0,0 +1,13 @@ +# -*- coding: utf-8 -*- +# © 2016 Iván Todorovich +# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html + + +def migrate(cr, version): + if version is None: + return + + # Rename old fields + cr.execute("""UPDATE tile_tile SET primary_function = 'count'""") + cr.execute("""UPDATE tile_tile SET secondary_function = field_function""") + cr.execute("""UPDATE tile_tile SET secondary_field_id = field_id""") diff --git a/web_dashboard_tile/models/tile_tile.py b/web_dashboard_tile/models/tile_tile.py index 4743afcb..498d365b 100644 --- a/web_dashboard_tile/models/tile_tile.py +++ b/web_dashboard_tile/models/tile_tile.py @@ -1,4 +1,5 @@ # -*- coding: utf-8 -*- +<<<<<<< HEAD ############################################################################## # # OpenERP, Open Source Management Solution @@ -26,13 +27,74 @@ from openerp import api, fields from openerp.models import Model from openerp.exceptions import except_orm +======= +# © 2010-2013 OpenERP s.a. (). +# © 2014 initOS GmbH & Co. KG (). +# © 2015-Today GRAP +# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html + +import datetime +import time +from dateutil.relativedelta import relativedelta +from collections import OrderedDict + +from openerp import api, fields, models +from openerp.tools.safe_eval import safe_eval as eval +>>>>>>> 3ab676d... [IMP][8.0][web_dashboard_tile] Refactor (see changes in description) (#476) from openerp.tools.translate import _ +<<<<<<< HEAD class TileTile(Model): +======= +def median(vals): + # 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(vals) % 2 else 1) + 1 + half = (len(vals) - 1) / 2 + return sum(sorted(vals)[half:half + even]) / float(even) + + +FIELD_FUNCTIONS = OrderedDict([ + ('count', { + 'name': 'Count', + 'func': False, # its hardcoded in _compute_data + 'help': _('Number of records')}), + ('min', { + 'name': 'Minimum', + 'func': min, + 'help': _("Minimum value of '%s'")}), + ('max', { + 'name': 'Maximum', + 'func': max, + 'help': _("Maximum value of '%s'")}), + ('sum', { + 'name': 'Sum', + 'func': sum, + 'help': _("Total value of '%s'")}), + ('avg', { + 'name': 'Average', + 'func': lambda vals: sum(vals)/len(vals), + 'help': _("Minimum value of '%s'")}), + ('median', { + 'name': 'Median', + 'func': median, + 'help': _("Median value of '%s'")}), +]) + + +FIELD_FUNCTION_SELECTION = [ + (k, FIELD_FUNCTIONS[k].get('name')) for k in FIELD_FUNCTIONS] + + +class TileTile(models.Model): +>>>>>>> 3ab676d... [IMP][8.0][web_dashboard_tile] Refactor (see changes in description) (#476) _name = 'tile.tile' + _description = 'Dashboard Tile' _order = 'sequence, name' +<<<<<<< HEAD def median(self, aList): # https://docs.python.org/3/library/statistics.html#statistics.median # TODO : refactor, using statistics.median when Odoo will be available @@ -76,6 +138,154 @@ class TileTile(Model): r.computed_value = self.median(vals) r.helper = _("Median value of '%s'") % desc return res +======= + def _get_eval_context(self): + def _context_today(): + return fields.Date.from_string(fields.Date.context_today(self)) + context = self.env.context.copy() + context.update({ + 'time': time, + 'datetime': datetime, + 'relativedelta': relativedelta, + 'context_today': _context_today, + 'current_date': fields.Date.today(), + }) + return context + + # Column Section + name = fields.Char(required=True) + sequence = fields.Integer(default=0, required=True) + user_id = fields.Many2one('res.users', 'User') + background_color = fields.Char(default='#0E6C7E', oldname='color') + font_color = fields.Char(default='#FFFFFF') + + group_ids = fields.Many2many( + 'res.groups', + string='Groups', + help='If this field is set, only users of this group can view this ' + 'tile. Please note that it will only work for global tiles ' + '(that is, when User field is left empty)') + + model_id = fields.Many2one('ir.model', 'Model', required=True) + domain = fields.Text(default='[]') + action_id = fields.Many2one('ir.actions.act_window', 'Action') + + active = fields.Boolean( + compute='_compute_active', + search='_search_active', + readonly=True) + + # Primary Value + primary_function = fields.Selection( + FIELD_FUNCTION_SELECTION, + string='Function', + default='count') + primary_field_id = fields.Many2one( + 'ir.model.fields', + string='Field', + domain="[('model_id', '=', model_id)," + " ('ttype', 'in', ['float', 'integer'])]") + primary_format = fields.Char( + string='Format', + help='Python Format String valid with str.format()\n' + 'ie: \'{:,} Kgs\' will output \'1,000 Kgs\' if value is 1000.') + primary_value = fields.Char( + string='Value', + compute='_compute_data') + primary_helper = fields.Char( + string='Helper', + compute='_compute_helper') + + # Secondary Value + secondary_function = fields.Selection( + FIELD_FUNCTION_SELECTION, + string='Secondary Function') + secondary_field_id = fields.Many2one( + 'ir.model.fields', + string='Secondary Field', + domain="[('model_id', '=', model_id)," + " ('ttype', 'in', ['float', 'integer'])]") + secondary_format = fields.Char( + string='Secondary Format', + help='Python Format String valid with str.format()\n' + 'ie: \'{:,} Kgs\' will output \'1,000 Kgs\' if value is 1000.') + secondary_value = fields.Char( + string='Secondary Value', + compute='_compute_data') + secondary_helper = fields.Char( + string='Secondary Helper', + compute='_compute_helper') + + error = fields.Char( + string='Error Details', + compute='_compute_data') + + @api.one + def _compute_data(self): + if not self.active: + return + model = self.env[self.model_id.model] + eval_context = self._get_eval_context() + domain = self.domain or '[]' + try: + count = model.search_count(eval(domain, eval_context)) + except Exception as e: + self.primary_value = self.secondary_value = 'ERR!' + self.error = str(e) + return + if any([ + self.primary_function and + self.primary_function != 'count', + self.secondary_function and + self.secondary_function != 'count' + ]): + records = model.search(eval(domain, eval_context)) + for f in ['primary_', 'secondary_']: + f_function = f+'function' + f_field_id = f+'field_id' + f_format = f+'format' + f_value = f+'value' + value = 0 + if self[f_function] == 'count': + value = count + elif self[f_function]: + func = FIELD_FUNCTIONS[self[f_function]]['func'] + if func and self[f_field_id] and count: + vals = [x[self[f_field_id].name] for x in records] + value = func(vals) + if self[f_function]: + try: + self[f_value] = (self[f_format] or '{:,}').format(value) + except ValueError as e: + self[f_value] = 'F_ERR!' + self.error = str(e) + return + else: + self[f_value] = False + + @api.one + @api.onchange('primary_function', 'primary_field_id', + 'secondary_function', 'secondary_field_id') + def _compute_helper(self): + for f in ['primary_', 'secondary_']: + f_function = f+'function' + f_field_id = f+'field_id' + f_helper = f+'helper' + self[f_helper] = '' + field_func = FIELD_FUNCTIONS.get(self[f_function], {}) + help = field_func.get('help', False) + if help: + if self[f_function] != 'count' and self[f_field_id]: + desc = self[f_field_id].field_description + self[f_helper] = help % desc + else: + self[f_helper] = help + + @api.one + def _compute_active(self): + ima = self.env['ir.model.access'] + self.active = ima.check(self.model_id.model, 'read', False) +>>>>>>> 3ab676d... [IMP][8.0][web_dashboard_tile] Refactor (see changes in description) (#476) def _search_active(self, operator, value): cr = self.env.cr @@ -95,6 +305,7 @@ class TileTile(Model): ids.append(result[0]) return [('id', 'in', ids)] +<<<<<<< HEAD # Column Section name = fields.Char(required=True) model_id = fields.Many2one( @@ -123,6 +334,32 @@ class TileTile(Model): background_color = fields.Char(default='#0E6C7E', oldname='color') font_color = fields.Char(default='#FFFFFF') sequence = fields.Integer(default=0, required=True) +======= + # Constraints and onchanges + @api.one + @api.constrains('model_id', 'primary_field_id', 'secondary_field_id') + def _check_model_id_field_id(self): + if any([ + self.primary_field_id and + self.primary_field_id.model_id.id != self.model_id.id, + self.secondary_field_id and + self.secondary_field_id.model_id.id != self.model_id.id + ]): + raise ValidationError( + _("Please select a field from the selected model.")) + + @api.onchange('model_id') + def _onchange_model_id(self): + self.primary_field_id = False + self.secondary_field_id = False + + @api.onchange('primary_function', 'secondary_function') + def _onchange_function(self): + if self.primary_function in [False, 'count']: + self.primary_field_id = False + if self.secondary_function in [False, 'count']: + self.secondary_field_id = False +>>>>>>> 3ab676d... [IMP][8.0][web_dashboard_tile] Refactor (see changes in description) (#476) # Constraint Section def _check_model_id_field_id(self, cr, uid, ids, context=None): diff --git a/web_dashboard_tile/security/rules.xml b/web_dashboard_tile/security/rules.xml index 8d653b70..05637bfd 100644 --- a/web_dashboard_tile/security/rules.xml +++ b/web_dashboard_tile/security/rules.xml @@ -6,7 +6,16 @@ tile.owner - [('user_id','in',[False,user.id])] + + [ + '|', + ('user_id','=',user.id), + ('user_id','=',False), + '|', + ('group_ids','=',False), + ('group_ids','in',[g.id for g in user.groups_id]), + ] + diff --git a/web_dashboard_tile/static/src/css/tile.css b/web_dashboard_tile/static/src/css/tile.css index 1d057cee..4ec483d7 100644 --- a/web_dashboard_tile/static/src/css/tile.css +++ b/web_dashboard_tile/static/src/css/tile.css @@ -5,35 +5,71 @@ border-radius: 0; } +<<<<<<< HEAD .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; +======= +/* Disable default kanban style */ +.openerp .oe_kanban_view .oe_dashboard_tile .oe_kanban_content div:first-child { + margin-right: inherit!important; +} + +.openerp .oe_kanban_view .oe_dashboard_tile .tile_label, +.openerp .oe_kanban_view .oe_dashboard_tile .tile_primary_value, +.openerp .oe_kanban_view .oe_dashboard_tile .tile_secondary_value { +>>>>>>> 3ab676d... [IMP][8.0][web_dashboard_tile] Refactor (see changes in description) (#476) text-align: center; + font-weight: bold; } +<<<<<<< HEAD .openerp .oe_kanban_view .oe_dashbaord_tile .tile_label{ +======= +.openerp .oe_kanban_view .oe_dashboard_tile .tile_label { +>>>>>>> 3ab676d... [IMP][8.0][web_dashboard_tile] Refactor (see changes in description) (#476) padding: 5px; font-size: 15px; } +<<<<<<< HEAD .openerp .oe_kanban_view .oe_dashbaord_tile .tile_count_without_computed_value{ font-size: 52px; font-weight: bold; +======= +.openerp .oe_kanban_view .oe_dashboard_tile .tile_primary_value{ + font-size: 54px; +>>>>>>> 3ab676d... [IMP][8.0][web_dashboard_tile] Refactor (see changes in description) (#476) position: absolute; left: 5px; + right: 5px; bottom: 5px; } +<<<<<<< HEAD .openerp .oe_kanban_view .oe_dashbaord_tile .tile_count_with_computed_value{ font-size: 38px; font-weight: bold; +======= +.openerp .oe_kanban_view .oe_dashboard_tile .tile_secondary_value{ + display: none; + font-size: 18px; + font-style: italic; +>>>>>>> 3ab676d... [IMP][8.0][web_dashboard_tile] Refactor (see changes in description) (#476) position: absolute; left: 5px; + right: 5px; + bottom: 5px; +} + +.openerp .oe_kanban_view .oe_dashboard_tile .with_secondary .tile_primary_value{ + font-size: 38px; bottom: 30px; } +<<<<<<< HEAD .openerp .oe_kanban_view .oe_dashbaord_tile .tile_computed_value{ font-size: 18px; font-weight: bold; @@ -42,3 +78,17 @@ bottom: 5px; font-style: italic; } +======= +.openerp .oe_kanban_view .oe_dashboard_tile .with_secondary .tile_secondary_value{ + display: block; +} + +/* SearchView Drawer */ +.openerp .oe_searchview_drawer .oe_searchview_dashboard .oe_dashboard_tile_form { + display: none; +} + +.openerp .oe_searchview_drawer .oe_opened .oe_dashboard_tile_form { + display: block; +} +>>>>>>> 3ab676d... [IMP][8.0][web_dashboard_tile] Refactor (see changes in description) (#476) diff --git a/web_dashboard_tile/static/src/img/screenshot_dashboard.png b/web_dashboard_tile/static/src/img/screenshot_dashboard.png index 9cbdeecd3d601ffbea9c197ed5c71d2480371613..65cfc12753e9f451d432ff0cb54c85d3ff459a1f 100644 GIT binary patch literal 20441 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 GGywqSdE~|b literal 45633 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 +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +# flake8: noqa + +from . import test_tile diff --git a/web_dashboard_tile/tests/test_tile.py b/web_dashboard_tile/tests/test_tile.py new file mode 100644 index 00000000..90604ab9 --- /dev/null +++ b/web_dashboard_tile/tests/test_tile.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# © 2016 Antonio Espinosa - +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from openerp.tests.common import TransactionCase + + +class TestTile(TransactionCase): + def test_tile(self): + tile_obj = self.env['tile.tile'] + model_id = self.env['ir.model'].search([ + ('model', '=', 'tile.tile')]) + field_id = self.env['ir.model.fields'].search([ + ('model_id', '=', model_id.id), + ('name', '=', 'sequence')]) + self.tile1 = tile_obj.create({ + 'name': 'Count / Sum', + 'sequence': 1, + 'model_id': model_id.id, + 'domain': "[('model_id', '=', %d)]" % model_id.id, + 'secondary_function': 'sum', + 'secondary_field_id': field_id.id}) + self.tile2 = tile_obj.create({ + 'name': 'Min / Max', + 'sequence': 2, + 'model_id': model_id.id, + 'domain': "[('model_id', '=', %d)]" % model_id.id, + 'primary_function': 'min', + 'primary_field_id': field_id.id, + 'secondary_function': 'max', + 'secondary_field_id': field_id.id}) + self.tile3 = tile_obj.create({ + 'name': 'Avg / Median', + 'sequence': 3, + 'model_id': model_id.id, + 'domain': "[('model_id', '=', %d)]" % model_id.id, + 'primary_function': 'avg', + 'primary_field_id': field_id.id, + 'secondary_function': 'median', + 'secondary_field_id': field_id.id}) + # count + self.assertEqual(self.tile1.primary_value, '3') + # sum + self.assertEqual(self.tile1.secondary_value, '6') + # min + self.assertEqual(self.tile2.primary_value, '1') + # max + self.assertEqual(self.tile2.secondary_value, '3') + # average + self.assertEqual(self.tile3.primary_value, '2') + # median + self.assertEqual(self.tile3.secondary_value, '2.0') diff --git a/web_dashboard_tile/views/tile.xml b/web_dashboard_tile/views/tile.xml index 36411ad8..cf9a003f 100644 --- a/web_dashboard_tile/views/tile.xml +++ b/web_dashboard_tile/views/tile.xml @@ -9,8 +9,10 @@ - - + + + + @@ -34,11 +36,50 @@ - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -53,37 +94,31 @@ - - - - + + + + +
-
- -
-
- -
- -
- +
+
+
-
From 45750d6030482956ccdf99a44e7833b7127eced1 Mon Sep 17 00:00:00 2001 From: Nicolas Mac Rouillon Date: Tue, 13 Dec 2016 15:04:14 -0300 Subject: [PATCH 44/50] FIX --- web_dashboard_tile/README.rst | 50 ++--- web_dashboard_tile/__init__.py | 27 +-- web_dashboard_tile/__openerp__.py | 14 +- web_dashboard_tile/models/__init__.py | 24 +-- web_dashboard_tile/models/tile_tile.py | 175 ++---------------- web_dashboard_tile/static/src/css/tile.css | 39 +--- web_dashboard_tile/static/src/js/custom_js.js | 8 +- .../static/src/xml/custom_xml.xml | 4 +- web_dashboard_tile/views/templates.xml | 2 +- web_dashboard_tile/views/tile.xml | 6 +- 10 files changed, 63 insertions(+), 286 deletions(-) diff --git a/web_dashboard_tile/README.rst b/web_dashboard_tile/README.rst index 0337037b..523dcadb 100644 --- a/web_dashboard_tile/README.rst +++ b/web_dashboard_tile/README.rst @@ -1,19 +1,6 @@ -Add Tiles to Dashboard -====================== - -<<<<<<< HEAD -module to give you a dashboard where you can configure tile from any view -and add them as short cut. - -* 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; -======= +Dashboard Tiles +=============== + Adds a dashboard where you can configure tiles from any view and add them as short cut. By default, the tile displays items count of a given model restricted to a given domain. @@ -30,28 +17,18 @@ Tile can be: - Restricted to some groups. *Note: The tile will be hidden if the current user doesn't have access to the given model.* ->>>>>>> 3ab676d... [IMP][8.0][web_dashboard_tile] Refactor (see changes in description) (#476) Usage ===== * Dashboad sample, displaying Sale Orders to invoice: -.. image:: /web_dashboard_tile/static/src/img/screenshot_dashboard.png + +.. image:: ./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 - -Known issues / Roadmap -====================== - -<<<<<<< HEAD -* 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; -* Support context_today; -* Add icons; -* Support client side action (like inbox); -======= + +.. image:: ./static/src/img/screenshot_action_click.png + Known issues ============ * Can not edit tile from dashboard (color, sequence, function, ...). @@ -66,7 +43,6 @@ Roadmap * Restore original Domain + Filter when an action is set. * Posibility to hide the tile based on a field expression. * Posibility to set the background color based on a field expression. ->>>>>>> 3ab676d... [IMP][8.0][web_dashboard_tile] Refactor (see changes in description) (#476) Bug Tracker =========== @@ -74,10 +50,7 @@ Bug Tracker Bugs are tracked on `GitHub Issues `_. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us smashing it by providing a detailed and welcomed feedback -`here `_. +`here `_. Credits @@ -88,6 +61,7 @@ Contributors * Markus Schneider * Sylvain Le Gal (https://twitter.com/legalsylvain) +* Iván Todorovich Maintainer ---------- @@ -100,4 +74,4 @@ This module is maintained by the OCA. OCA, or the Odoo Community Association, is a nonprofit organization whose mission is to support the collaborative development of Odoo features and promote its widespread use. -To contribute to this module, please visit http://odoo-community.org. +To contribute to this module, please visit http://odoo-community.org. \ No newline at end of file diff --git a/web_dashboard_tile/__init__.py b/web_dashboard_tile/__init__.py index 35d8f47b..1d098b58 100644 --- a/web_dashboard_tile/__init__.py +++ b/web_dashboard_tile/__init__.py @@ -1,26 +1,7 @@ # -*- 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 . -# -############################################################################## +# © 2010-2013 OpenERP s.a. (). +# © 2014 initOS GmbH & Co. KG (). +# © 2015-Today GRAP +# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html from . import models diff --git a/web_dashboard_tile/__openerp__.py b/web_dashboard_tile/__openerp__.py index f84fd1b3..bcba4eb5 100644 --- a/web_dashboard_tile/__openerp__.py +++ b/web_dashboard_tile/__openerp__.py @@ -20,6 +20,10 @@ # along with this program. If not, see . # ############################################################################## +# -*- coding: utf-8 -*- +# © 2010-2013 OpenERP s.a. (). +# © 2014 initOS GmbH & Co. KG (). +# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html { "name": "Dashboard Tile", "summary": "Add Tiles to Dashboard", @@ -30,9 +34,16 @@ 'mail', 'web_widget_color', ], - 'author': "initOS GmbH & Co. KG,GRAP,Odoo Community Association (OCA)", + 'author': 'initOS GmbH & Co. KG, ' + 'GRAP, ' + 'Odoo Community Association (OCA)', "category": "web", 'license': 'AGPL-3', + 'contributors': [ + 'initOS GmbH & Co. KG', + 'GRAP', + 'Iván Todorovich ' + ], 'data': [ 'views/tile.xml', 'views/templates.xml', @@ -46,5 +57,4 @@ 'qweb': [ 'static/src/xml/custom_xml.xml', ], - 'installable': True, } diff --git a/web_dashboard_tile/models/__init__.py b/web_dashboard_tile/models/__init__.py index fc23e732..97fec216 100644 --- a/web_dashboard_tile/models/__init__.py +++ b/web_dashboard_tile/models/__init__.py @@ -1,23 +1,7 @@ # -*- 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 . -# -############################################################################## +# © 2010-2013 OpenERP s.a. (). +# © 2014 initOS GmbH & Co. KG (). +# © 2015-Today GRAP +# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html from . import tile_tile diff --git a/web_dashboard_tile/models/tile_tile.py b/web_dashboard_tile/models/tile_tile.py index 498d365b..bc304b69 100644 --- a/web_dashboard_tile/models/tile_tile.py +++ b/web_dashboard_tile/models/tile_tile.py @@ -1,33 +1,4 @@ # -*- coding: utf-8 -*- -<<<<<<< HEAD -############################################################################## -# -# 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 openerp import api, fields -from openerp.models import Model -from openerp.exceptions import except_orm -======= # © 2010-2013 OpenERP s.a. (). # © 2014 initOS GmbH & Co. KG (). # © 2015-Today GRAP @@ -40,13 +11,10 @@ from collections import OrderedDict from openerp import api, fields, models from openerp.tools.safe_eval import safe_eval as eval ->>>>>>> 3ab676d... [IMP][8.0][web_dashboard_tile] Refactor (see changes in description) (#476) from openerp.tools.translate import _ +from openerp.exceptions import ValidationError, except_orm -<<<<<<< HEAD -class TileTile(Model): -======= def median(vals): # https://docs.python.org/3/library/statistics.html#statistics.median # TODO : refactor, using statistics.median when Odoo will be available @@ -75,7 +43,7 @@ FIELD_FUNCTIONS = OrderedDict([ 'help': _("Total value of '%s'")}), ('avg', { 'name': 'Average', - 'func': lambda vals: sum(vals)/len(vals), + 'func': lambda vals: sum(vals) / len(vals), 'help': _("Minimum value of '%s'")}), ('median', { 'name': 'Median', @@ -89,56 +57,10 @@ FIELD_FUNCTION_SELECTION = [ class TileTile(models.Model): ->>>>>>> 3ab676d... [IMP][8.0][web_dashboard_tile] Refactor (see changes in description) (#476) _name = 'tile.tile' _description = 'Dashboard Tile' _order = 'sequence, name' -<<<<<<< HEAD - 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): - ima_obj = self.env['ir.model.access'] - res = {} - for r in self: - r.active = False - r.count = 0 - r.computed_value = 0 - r.helper = '' - if ima_obj.check(r.model_id.model, 'read', False): - # Compute count item - model = self.env[r.model_id.model] - r.count = model.search_count(eval(r.domain)) - r.active = True - - # Compute datas for field_id depending of field_function - if r.field_function and r.field_id and r.count != 0: - records = model.search(eval(r.domain)) - vals = [x[r.field_id.name] for x in records] - desc = r.field_id.field_description - if r.field_function == 'min': - r.computed_value = min(vals) - r.helper = _("Minimum value of '%s'") % desc - elif r.field_function == 'max': - r.computed_value = max(vals) - r.helper = _("Maximum value of '%s'") % desc - elif r.field_function == 'sum': - r.computed_value = sum(vals) - r.helper = _("Total value of '%s'") % desc - elif r.field_function == 'avg': - r.computed_value = sum(vals) / len(vals) - r.helper = _("Average value of '%s'") % desc - elif r.field_function == 'median': - r.computed_value = self.median(vals) - r.helper = _("Median value of '%s'") % desc - return res -======= def _get_eval_context(self): def _context_today(): return fields.Date.from_string(fields.Date.context_today(self)) @@ -238,13 +160,13 @@ class TileTile(models.Model): self.primary_function != 'count', self.secondary_function and self.secondary_function != 'count' - ]): - records = model.search(eval(domain, eval_context)) + ]): + records = model.search(eval(domain, eval_context)) for f in ['primary_', 'secondary_']: - f_function = f+'function' - f_field_id = f+'field_id' - f_format = f+'format' - f_value = f+'value' + f_function = f + 'function' + f_field_id = f + 'field_id' + f_format = f + 'format' + f_value = f + 'value' value = 0 if self[f_function] == 'count': value = count @@ -268,9 +190,9 @@ class TileTile(models.Model): 'secondary_function', 'secondary_field_id') def _compute_helper(self): for f in ['primary_', 'secondary_']: - f_function = f+'function' - f_field_id = f+'field_id' - f_helper = f+'helper' + f_function = f + 'function' + f_field_id = f + 'field_id' + f_helper = f + 'helper' self[f_helper] = '' field_func = FIELD_FUNCTIONS.get(self[f_function], {}) help = field_func.get('help', False) @@ -285,15 +207,13 @@ class TileTile(models.Model): def _compute_active(self): ima = self.env['ir.model.access'] self.active = ima.check(self.model_id.model, 'read', False) ->>>>>>> 3ab676d... [IMP][8.0][web_dashboard_tile] Refactor (see changes in description) (#476) def _search_active(self, operator, value): cr = self.env.cr if operator != '=': raise except_orm( - 'Unimplemented Feature', - 'Search on Active field disabled.') - ima_obj = self.env['ir.model.access'] + _('Unimplemented Feature. Search on Active field disabled.')) + ima = self.env['ir.model.access'] ids = [] cr.execute(""" SELECT tt.id, im.model @@ -301,40 +221,10 @@ class TileTile(models.Model): INNER JOIN ir_model im ON tt.model_id = im.id""") for result in cr.fetchall(): - if (ima_obj.check(result[1], 'read', False) == value): + if (ima.check(result[1], 'read', False) == value): ids.append(result[0]) return [('id', 'in', ids)] -<<<<<<< HEAD - # Column Section - name = fields.Char(required=True) - model_id = fields.Many2one( - comodel_name='ir.model', string='Model', required=True) - user_id = fields.Many2one( - comodel_name='res.users', string='User') - domain = fields.Text(default='[]') - action_id = fields.Many2one( - comodel_name='ir.actions.act_window', string='Action') - count = fields.Integer(compute='_get_tile_info') - computed_value = fields.Float(compute='_get_tile_info') - helper = fields.Char(compute='_get_tile_info') - field_function = fields.Selection(selection=[ - ('min', 'Minimum'), - ('max', 'Maximum'), - ('sum', 'Sum'), - ('avg', 'Average'), - ('median', 'Median'), - ], string='Function') - field_id = fields.Many2one( - comodel_name='ir.model.fields', string='Field', - domain="[('model_id', '=', model_id)," - " ('ttype', 'in', ['float', 'int'])]") - active = fields.Boolean( - compute='_get_tile_info', readonly=True, search='_search_active') - background_color = fields.Char(default='#0E6C7E', oldname='color') - font_color = fields.Char(default='#FFFFFF') - sequence = fields.Integer(default=0, required=True) -======= # Constraints and onchanges @api.one @api.constrains('model_id', 'primary_field_id', 'secondary_field_id') @@ -344,9 +234,9 @@ class TileTile(models.Model): self.primary_field_id.model_id.id != self.model_id.id, self.secondary_field_id and self.secondary_field_id.model_id.id != self.model_id.id - ]): - raise ValidationError( - _("Please select a field from the selected model.")) + ]): + raise ValidationError( + _("Please select a field from the selected model.")) @api.onchange('model_id') def _onchange_model_id(self): @@ -359,34 +249,8 @@ class TileTile(models.Model): self.primary_field_id = False if self.secondary_function in [False, 'count']: self.secondary_field_id = False ->>>>>>> 3ab676d... [IMP][8.0][web_dashboard_tile] Refactor (see changes in description) (#476) - - # 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']), - ] - # View / action Section + # Action methods @api.multi def open_link(self): res = { @@ -403,8 +267,7 @@ class TileTile(models.Model): } if self.action_id: res.update(self.action_id.read( - ['view_type', 'view_mode', 'view_id', 'type'])[0]) - # FIXME: restore original Domain + Filter would be better + ['view_type', 'view_mode', 'type'])[0]) return res @api.model diff --git a/web_dashboard_tile/static/src/css/tile.css b/web_dashboard_tile/static/src/css/tile.css index 4ec483d7..73b811d3 100644 --- a/web_dashboard_tile/static/src/css/tile.css +++ b/web_dashboard_tile/static/src/css/tile.css @@ -1,17 +1,10 @@ -.openerp .oe_kanban_view .oe_dashbaord_tile{ +.openerp .oe_kanban_view .oe_dashboard_tile { width: 150px; height: 150px; border: 0; border-radius: 0; } -<<<<<<< HEAD -.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; -======= /* Disable default kanban style */ .openerp .oe_kanban_view .oe_dashboard_tile .oe_kanban_content div:first-child { margin-right: inherit!important; @@ -20,44 +13,27 @@ .openerp .oe_kanban_view .oe_dashboard_tile .tile_label, .openerp .oe_kanban_view .oe_dashboard_tile .tile_primary_value, .openerp .oe_kanban_view .oe_dashboard_tile .tile_secondary_value { ->>>>>>> 3ab676d... [IMP][8.0][web_dashboard_tile] Refactor (see changes in description) (#476) text-align: center; font-weight: bold; } -<<<<<<< HEAD -.openerp .oe_kanban_view .oe_dashbaord_tile .tile_label{ -======= .openerp .oe_kanban_view .oe_dashboard_tile .tile_label { ->>>>>>> 3ab676d... [IMP][8.0][web_dashboard_tile] Refactor (see changes in description) (#476) padding: 5px; font-size: 15px; } -<<<<<<< HEAD -.openerp .oe_kanban_view .oe_dashbaord_tile .tile_count_without_computed_value{ - font-size: 52px; - font-weight: bold; -======= .openerp .oe_kanban_view .oe_dashboard_tile .tile_primary_value{ font-size: 54px; ->>>>>>> 3ab676d... [IMP][8.0][web_dashboard_tile] Refactor (see changes in description) (#476) position: absolute; left: 5px; right: 5px; bottom: 5px; } -<<<<<<< HEAD -.openerp .oe_kanban_view .oe_dashbaord_tile .tile_count_with_computed_value{ - font-size: 38px; - font-weight: bold; -======= .openerp .oe_kanban_view .oe_dashboard_tile .tile_secondary_value{ display: none; font-size: 18px; font-style: italic; ->>>>>>> 3ab676d... [IMP][8.0][web_dashboard_tile] Refactor (see changes in description) (#476) position: absolute; left: 5px; right: 5px; @@ -69,16 +45,6 @@ bottom: 30px; } -<<<<<<< HEAD -.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_dashboard_tile .with_secondary .tile_secondary_value{ display: block; } @@ -90,5 +56,4 @@ .openerp .oe_searchview_drawer .oe_opened .oe_dashboard_tile_form { display: block; -} ->>>>>>> 3ab676d... [IMP][8.0][web_dashboard_tile] Refactor (see changes in description) (#476) +} \ No newline at end of file diff --git a/web_dashboard_tile/static/src/js/custom_js.js b/web_dashboard_tile/static/src/js/custom_js.js index c192ef29..9015f9a9 100644 --- a/web_dashboard_tile/static/src/js/custom_js.js +++ b/web_dashboard_tile/static/src/js/custom_js.js @@ -19,7 +19,7 @@ // //############################################################################# -openerp.web_dashboard_tile = function (instance) +odoo.web_dashboard_tile = function (instance) { var QWeb = instance.web.qweb, _t = instance.web._t, @@ -35,13 +35,13 @@ _.mixin({ var self = this; this.$('#add_dashboard_tile').on('click', this, function (){ self.save_tile(); - }) + }); }, render_data: function(dashboard_choices){ var selection = instance.web.qweb.render( "SearchView.addtodashboard.selection", { selections: dashboard_choices}); - this.$("form input").before(selection) + this.$("form input").before(selection); }, save_tile: function () { var self = this; @@ -97,4 +97,4 @@ _.mixin({ } }); -} +}; diff --git a/web_dashboard_tile/static/src/xml/custom_xml.xml b/web_dashboard_tile/static/src/xml/custom_xml.xml index 3e0c2316..11ecb179 100644 --- a/web_dashboard_tile/static/src/xml/custom_xml.xml +++ b/web_dashboard_tile/static/src/xml/custom_xml.xml @@ -2,11 +2,11 @@ -
+
- + \ No newline at end of file diff --git a/web_dashboard_tile/views/templates.xml b/web_dashboard_tile/views/templates.xml index e7a68b21..1fe51f0d 100644 --- a/web_dashboard_tile/views/templates.xml +++ b/web_dashboard_tile/views/templates.xml @@ -30,4 +30,4 @@ - + \ No newline at end of file diff --git a/web_dashboard_tile/views/tile.xml b/web_dashboard_tile/views/tile.xml index cf9a003f..a42d952f 100644 --- a/web_dashboard_tile/views/tile.xml +++ b/web_dashboard_tile/views/tile.xml @@ -103,7 +103,7 @@ -
+
@@ -152,9 +152,9 @@ Dashboard - + - + From 38a521a3e6801085b58d0086c6b9a951055e42a7 Mon Sep 17 00:00:00 2001 From: Nicolas Mac Rouillon Date: Tue, 13 Dec 2016 15:34:23 -0300 Subject: [PATCH 45/50] FIX __openerp__ --- web_dashboard_tile/__openerp__.py | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/web_dashboard_tile/__openerp__.py b/web_dashboard_tile/__openerp__.py index bcba4eb5..dbda3d3b 100644 --- a/web_dashboard_tile/__openerp__.py +++ b/web_dashboard_tile/__openerp__.py @@ -1,26 +1,4 @@ # -*- coding: utf-8 -*- -############################################################################## -# -# OpenERP, Open Source Management Solution -# Copyright (C) 2010-2013 OpenERP s.a. (). -# Copyright (C) 2014 initOS GmbH & Co. KG (). -# Author Markus Schneider -# -# 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 . -# -############################################################################## -# -*- coding: utf-8 -*- # © 2010-2013 OpenERP s.a. (). # © 2014 initOS GmbH & Co. KG (). # License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html From 04b88d62c9a8203bb8f996af8215eae452092898 Mon Sep 17 00:00:00 2001 From: Nicolas Mac Rouillon Date: Tue, 13 Dec 2016 15:44:42 -0300 Subject: [PATCH 46/50] FIX --- web_dashboard_tile/README.rst | 2 +- web_dashboard_tile/static/src/xml/custom_xml.xml | 2 +- web_dashboard_tile/views/templates.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/web_dashboard_tile/README.rst b/web_dashboard_tile/README.rst index 523dcadb..daa3a2eb 100644 --- a/web_dashboard_tile/README.rst +++ b/web_dashboard_tile/README.rst @@ -74,4 +74,4 @@ This module is maintained by the OCA. OCA, or the Odoo Community Association, is a nonprofit organization whose mission is to support the collaborative development of Odoo features and promote its widespread use. -To contribute to this module, please visit http://odoo-community.org. \ No newline at end of file +To contribute to this module, please visit http://odoo-community.org. diff --git a/web_dashboard_tile/static/src/xml/custom_xml.xml b/web_dashboard_tile/static/src/xml/custom_xml.xml index 11ecb179..38a0e3e9 100644 --- a/web_dashboard_tile/static/src/xml/custom_xml.xml +++ b/web_dashboard_tile/static/src/xml/custom_xml.xml @@ -9,4 +9,4 @@
- \ No newline at end of file + diff --git a/web_dashboard_tile/views/templates.xml b/web_dashboard_tile/views/templates.xml index 1fe51f0d..e7a68b21 100644 --- a/web_dashboard_tile/views/templates.xml +++ b/web_dashboard_tile/views/templates.xml @@ -30,4 +30,4 @@ - \ No newline at end of file + From a7521442c593894a1a83049cac86b7223925915f Mon Sep 17 00:00:00 2001 From: Nicolas Mac Rouillon Date: Tue, 13 Dec 2016 16:02:54 -0300 Subject: [PATCH 47/50] FIX remove api.one --- web_advanced_search_wildcard/README.rst | 61 -------- web_advanced_search_wildcard/__init__.py | 0 web_advanced_search_wildcard/__openerp__.py | 21 --- web_advanced_search_wildcard/i18n/de.po | 27 ---- web_advanced_search_wildcard/i18n/es.po | 26 ---- web_advanced_search_wildcard/i18n/fi.po | 26 ---- web_advanced_search_wildcard/i18n/fr.po | 26 ---- web_advanced_search_wildcard/i18n/pt_BR.po | 26 ---- web_advanced_search_wildcard/i18n/sl.po | 26 ---- .../i18n/web_advanced_search_wildcard.pot | 23 --- .../static/description/screenshot.png | Bin 7164 -> 0 bytes .../static/src/js/search.js | 6 - .../views/template.xml | 10 -- web_dashboard_tile/models/tile_tile.py | 136 +++++++++--------- 14 files changed, 70 insertions(+), 344 deletions(-) delete mode 100644 web_advanced_search_wildcard/README.rst delete mode 100644 web_advanced_search_wildcard/__init__.py delete mode 100644 web_advanced_search_wildcard/__openerp__.py delete mode 100644 web_advanced_search_wildcard/i18n/de.po delete mode 100644 web_advanced_search_wildcard/i18n/es.po delete mode 100644 web_advanced_search_wildcard/i18n/fi.po delete mode 100644 web_advanced_search_wildcard/i18n/fr.po delete mode 100644 web_advanced_search_wildcard/i18n/pt_BR.po delete mode 100644 web_advanced_search_wildcard/i18n/sl.po delete mode 100644 web_advanced_search_wildcard/i18n/web_advanced_search_wildcard.pot delete mode 100644 web_advanced_search_wildcard/static/description/screenshot.png delete mode 100644 web_advanced_search_wildcard/static/src/js/search.js delete mode 100644 web_advanced_search_wildcard/views/template.xml diff --git a/web_advanced_search_wildcard/README.rst b/web_advanced_search_wildcard/README.rst deleted file mode 100644 index 8c6de995..00000000 --- a/web_advanced_search_wildcard/README.rst +++ /dev/null @@ -1,61 +0,0 @@ -.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg - :alt: License: AGPL-3 - -============================ -Wildcard in advanced search -============================ - -Allows =ilike ('matches') operator to advanced search option. - - -Usage -===== -Use % as a placeholder. - -Example: "Zip" - 'matches' - "1%" gives all zip starting with 1 - -.. image:: /web_advanced_search_wildcard/static/description/screenshot.png - :alt: Screenshot - - -Also allows insensitive exact search. -Example "Name" - 'matches' - "john" will find "John" and "john" but not "Johnson". - -Bug Tracker -=========== - -Bugs are tracked on `GitHub Issues `_. -In case of trouble, please check there if your issue has already been reported. -If you spotted it first, help us smashing it by providing a detailed and welcomed feedback -`here `_. - -Credits -======= - -Images ------- - -* Odoo Community Association: `Icon `_. - -Contributors ------------- - -* Markus Schneider -* Thomas Rehn -* L Freeke - - -Maintainer ----------- - -.. image:: https://odoo-community.org/logo.png - :alt: Odoo Community Association - :target: https://odoo-community.org - -This module is maintained by the OCA. - -OCA, or the Odoo Community Association, is a nonprofit organization whose -mission is to support the collaborative development of Odoo features and -promote its widespread use. - -To contribute to this module, please visit https://odoo-community.org. diff --git a/web_advanced_search_wildcard/__init__.py b/web_advanced_search_wildcard/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/web_advanced_search_wildcard/__openerp__.py b/web_advanced_search_wildcard/__openerp__.py deleted file mode 100644 index 797f3a60..00000000 --- a/web_advanced_search_wildcard/__openerp__.py +++ /dev/null @@ -1,21 +0,0 @@ -# -*- coding: utf-8 -*- -# © 2014 initOS GmbH & Co. KG (). -# © 2016 Therp BV . -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). - -{ - "name": "Wildcard in advanced search", - "summary": "Webmodule to add wildcard operators in advanced search field", - "version": "8.0.1.0.0", - "category": "web", - "license": 'AGPL-3', - "author": "initOS GmbH & Co. KG,Odoo Community Association (OCA),Therp BV", - "application": False, - "installable": True, - "depends": [ - "web" - ], - 'data': [ - "views/template.xml", - ], -} diff --git a/web_advanced_search_wildcard/i18n/de.po b/web_advanced_search_wildcard/i18n/de.po deleted file mode 100644 index 4cfbc4f3..00000000 --- a/web_advanced_search_wildcard/i18n/de.po +++ /dev/null @@ -1,27 +0,0 @@ -# Translation of OpenERP Server. -# This file contains the translation of the following modules: -# -# Rudolf Schnapka , 2015. -msgid "" -msgstr "" -"Project-Id-Version: OpenERP Server 7.0\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2014-09-15 09:11+0000\n" -"PO-Revision-Date: 2015-01-04 14:07+0100\n" -"Last-Translator: Rudolf Schnapka \n" -"Language-Team: German \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: \n" -"Language: de\n" -"X-Generator: Lokalize 1.5\n" - -#. module: web_advanced_search_wildcard -#. openerp-web -#: code:addons/web_advanced_search_wildcard/static/src/js/search.js:4 -#, python-format -msgid "matches" -msgstr "gleicht" - - diff --git a/web_advanced_search_wildcard/i18n/es.po b/web_advanced_search_wildcard/i18n/es.po deleted file mode 100644 index 2f9437ce..00000000 --- a/web_advanced_search_wildcard/i18n/es.po +++ /dev/null @@ -1,26 +0,0 @@ -# Translation of Odoo Server. -# This file contains the translation of the following modules: -# * web_advanced_search_wildcard -# -# Translators: -# Pedro M. Baeza , 2016 -msgid "" -msgstr "" -"Project-Id-Version: web (8.0)\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2016-11-26 01:59+0000\n" -"PO-Revision-Date: 2016-10-13 18:37+0000\n" -"Last-Translator: Pedro M. Baeza \n" -"Language-Team: Spanish (http://www.transifex.com/oca/OCA-web-8-0/language/es/)\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: \n" -"Language: es\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" - -#. module: web_advanced_search_wildcard -#. openerp-web -#: code:addons/web_advanced_search_wildcard/static/src/js/search.js:4 -#, python-format -msgid "matches" -msgstr "coincide con" diff --git a/web_advanced_search_wildcard/i18n/fi.po b/web_advanced_search_wildcard/i18n/fi.po deleted file mode 100644 index 91f0ab2e..00000000 --- a/web_advanced_search_wildcard/i18n/fi.po +++ /dev/null @@ -1,26 +0,0 @@ -# Translation of Odoo Server. -# This file contains the translation of the following modules: -# * web_advanced_search_wildcard -# -# Translators: -# Jarmo Kortetjärvi , 2016 -msgid "" -msgstr "" -"Project-Id-Version: web (8.0)\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2016-03-11 02:17+0000\n" -"PO-Revision-Date: 2016-03-07 08:28+0000\n" -"Last-Translator: Jarmo Kortetjärvi \n" -"Language-Team: Finnish (http://www.transifex.com/oca/OCA-web-8-0/language/fi/)\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: \n" -"Language: fi\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" - -#. module: web_advanced_search_wildcard -#. openerp-web -#: code:addons/web_advanced_search_wildcard/static/src/js/search.js:4 -#, python-format -msgid "matches" -msgstr "osumat" diff --git a/web_advanced_search_wildcard/i18n/fr.po b/web_advanced_search_wildcard/i18n/fr.po deleted file mode 100644 index 302b2e39..00000000 --- a/web_advanced_search_wildcard/i18n/fr.po +++ /dev/null @@ -1,26 +0,0 @@ -# Translation of Odoo Server. -# This file contains the translation of the following modules: -# * web_advanced_search_wildcard -# -# Translators: -# Christophe CHAUVET , 2016 -msgid "" -msgstr "" -"Project-Id-Version: web (8.0)\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2016-05-06 15:50+0000\n" -"PO-Revision-Date: 2016-05-06 08:19+0000\n" -"Last-Translator: Christophe CHAUVET \n" -"Language-Team: French (http://www.transifex.com/oca/OCA-web-8-0/language/fr/)\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: \n" -"Language: fr\n" -"Plural-Forms: nplurals=2; plural=(n > 1);\n" - -#. module: web_advanced_search_wildcard -#. openerp-web -#: code:addons/web_advanced_search_wildcard/static/src/js/search.js:4 -#, python-format -msgid "matches" -msgstr "correspondances" diff --git a/web_advanced_search_wildcard/i18n/pt_BR.po b/web_advanced_search_wildcard/i18n/pt_BR.po deleted file mode 100644 index 0464430f..00000000 --- a/web_advanced_search_wildcard/i18n/pt_BR.po +++ /dev/null @@ -1,26 +0,0 @@ -# Translation of Odoo Server. -# This file contains the translation of the following modules: -# * web_advanced_search_wildcard -# -# Translators: -# danimaribeiro , 2016 -msgid "" -msgstr "" -"Project-Id-Version: web (8.0)\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2016-03-11 02:17+0000\n" -"PO-Revision-Date: 2016-03-05 16:05+0000\n" -"Last-Translator: danimaribeiro \n" -"Language-Team: Portuguese (Brazil) (http://www.transifex.com/oca/OCA-web-8-0/language/pt_BR/)\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: \n" -"Language: pt_BR\n" -"Plural-Forms: nplurals=2; plural=(n > 1);\n" - -#. module: web_advanced_search_wildcard -#. openerp-web -#: code:addons/web_advanced_search_wildcard/static/src/js/search.js:4 -#, python-format -msgid "matches" -msgstr "resultados" diff --git a/web_advanced_search_wildcard/i18n/sl.po b/web_advanced_search_wildcard/i18n/sl.po deleted file mode 100644 index f8aa6f65..00000000 --- a/web_advanced_search_wildcard/i18n/sl.po +++ /dev/null @@ -1,26 +0,0 @@ -# Translation of Odoo Server. -# This file contains the translation of the following modules: -# * web_advanced_search_wildcard -# -# Translators: -# Matjaž Mozetič , 2016 -msgid "" -msgstr "" -"Project-Id-Version: web (8.0)\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2016-02-26 02:05+0000\n" -"PO-Revision-Date: 2016-02-27 16:56+0000\n" -"Last-Translator: Matjaž Mozetič \n" -"Language-Team: Slovenian (http://www.transifex.com/oca/OCA-web-8-0/language/sl/)\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: \n" -"Language: sl\n" -"Plural-Forms: nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);\n" - -#. module: web_advanced_search_wildcard -#. openerp-web -#: code:addons/web_advanced_search_wildcard/static/src/js/search.js:4 -#, python-format -msgid "matches" -msgstr "ujemanj" diff --git a/web_advanced_search_wildcard/i18n/web_advanced_search_wildcard.pot b/web_advanced_search_wildcard/i18n/web_advanced_search_wildcard.pot deleted file mode 100644 index e187a2da..00000000 --- a/web_advanced_search_wildcard/i18n/web_advanced_search_wildcard.pot +++ /dev/null @@ -1,23 +0,0 @@ -# Translation of OpenERP Server. -# This file contains the translation of the following modules: -# -msgid "" -msgstr "" -"Project-Id-Version: OpenERP Server 7.0\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2014-09-15 09:11+0000\n" -"PO-Revision-Date: 2014-09-15 11:12+0100\n" -"Last-Translator: M\n" -"Language-Team: \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: \n" - -#. module: web_advanced_search_wildcard -#. openerp-web -#: code:addons/web_advanced_search_wildcard/static/src/js/search.js:4 -#, python-format -msgid "matches" -msgstr "" - diff --git a/web_advanced_search_wildcard/static/description/screenshot.png b/web_advanced_search_wildcard/static/description/screenshot.png deleted file mode 100644 index 57848f902890b9aa4c78caf54ccfbcaed08e3cf4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7164 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 S=28L@A - - - - - diff --git a/web_dashboard_tile/models/tile_tile.py b/web_dashboard_tile/models/tile_tile.py index bc304b69..38ce5c66 100644 --- a/web_dashboard_tile/models/tile_tile.py +++ b/web_dashboard_tile/models/tile_tile.py @@ -142,71 +142,74 @@ class TileTile(models.Model): string='Error Details', compute='_compute_data') - @api.one + @api.multi def _compute_data(self): - if not self.active: - return - model = self.env[self.model_id.model] - eval_context = self._get_eval_context() - domain = self.domain or '[]' - try: - count = model.search_count(eval(domain, eval_context)) - except Exception as e: - self.primary_value = self.secondary_value = 'ERR!' - self.error = str(e) - return - if any([ - self.primary_function and - self.primary_function != 'count', - self.secondary_function and - self.secondary_function != 'count' - ]): - records = model.search(eval(domain, eval_context)) - for f in ['primary_', 'secondary_']: - f_function = f + 'function' - f_field_id = f + 'field_id' - f_format = f + 'format' - f_value = f + 'value' - value = 0 - if self[f_function] == 'count': - value = count - elif self[f_function]: - func = FIELD_FUNCTIONS[self[f_function]]['func'] - if func and self[f_field_id] and count: - vals = [x[self[f_field_id].name] for x in records] - value = func(vals) - if self[f_function]: - try: - self[f_value] = (self[f_format] or '{:,}').format(value) - except ValueError as e: - self[f_value] = 'F_ERR!' - self.error = str(e) - return - else: - self[f_value] = False + for rec in self: + if not rec.active: + return + model = self.env[rec.model_id.model] + eval_context = self._get_eval_context() + domain = rec.domain or '[]' + try: + count = model.search_count(eval(domain, eval_context)) + except Exception as e: + rec.primary_value = rec.secondary_value = 'ERR!' + rec.error = str(e) + return + if any([ + rec.primary_function and + rec.primary_function != 'count', + rec.secondary_function and + rec.secondary_function != 'count' + ]): + records = model.search(eval(domain, eval_context)) + for f in ['primary_', 'secondary_']: + f_function = f + 'function' + f_field_id = f + 'field_id' + f_format = f + 'format' + f_value = f + 'value' + value = 0 + if rec[f_function] == 'count': + value = count + elif rec[f_function]: + func = FIELD_FUNCTIONS[rec[f_function]]['func'] + if func and rec[f_field_id] and count: + vals = [x[rec[f_field_id].name] for x in records] + value = func(vals) + if rec[f_function]: + try: + rec[f_value] = (rec[f_format] or '{:,}').format(value) + except ValueError as e: + rec[f_value] = 'F_ERR!' + rec.error = str(e) + return + else: + rec[f_value] = False - @api.one + @api.multi @api.onchange('primary_function', 'primary_field_id', 'secondary_function', 'secondary_field_id') def _compute_helper(self): - for f in ['primary_', 'secondary_']: - f_function = f + 'function' - f_field_id = f + 'field_id' - f_helper = f + 'helper' - self[f_helper] = '' - field_func = FIELD_FUNCTIONS.get(self[f_function], {}) - help = field_func.get('help', False) - if help: - if self[f_function] != 'count' and self[f_field_id]: - desc = self[f_field_id].field_description - self[f_helper] = help % desc - else: - self[f_helper] = help + for rec in self: + for f in ['primary_', 'secondary_']: + f_function = f + 'function' + f_field_id = f + 'field_id' + f_helper = f + 'helper' + rec[f_helper] = '' + field_func = FIELD_FUNCTIONS.get(rec[f_function], {}) + help = field_func.get('help', False) + if help: + if rec[f_function] != 'count' and rec[f_field_id]: + desc = rec[f_field_id].field_description + rec[f_helper] = help % desc + else: + rec[f_helper] = help - @api.one + @api.multi def _compute_active(self): ima = self.env['ir.model.access'] - self.active = ima.check(self.model_id.model, 'read', False) + for rec in self: + rec.active = ima.check(rec.model_id.model, 'read', False) def _search_active(self, operator, value): cr = self.env.cr @@ -226,17 +229,18 @@ class TileTile(models.Model): return [('id', 'in', ids)] # Constraints and onchanges - @api.one + @api.multi @api.constrains('model_id', 'primary_field_id', 'secondary_field_id') def _check_model_id_field_id(self): - if any([ - self.primary_field_id and - self.primary_field_id.model_id.id != self.model_id.id, - self.secondary_field_id and - self.secondary_field_id.model_id.id != self.model_id.id - ]): - raise ValidationError( - _("Please select a field from the selected model.")) + for rec in self: + if any([ + rec.primary_field_id and + rec.primary_field_id.model_id.id != rec.model_id.id, + rec.secondary_field_id and + rec.secondary_field_id.model_id.id != rec.model_id.id + ]): + raise ValidationError( + _("Please select a field from the selected model.")) @api.onchange('model_id') def _onchange_model_id(self): From d75755dab503de1021d3aeeeba3c6fbbe5f6cfd1 Mon Sep 17 00:00:00 2001 From: Nicolas Mac Rouillon Date: Tue, 13 Dec 2016 16:45:28 -0300 Subject: [PATCH 48/50] IMP implementation of iteration --- web_dashboard_tile/models/tile_tile.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/web_dashboard_tile/models/tile_tile.py b/web_dashboard_tile/models/tile_tile.py index 38ce5c66..0ee69ef6 100644 --- a/web_dashboard_tile/models/tile_tile.py +++ b/web_dashboard_tile/models/tile_tile.py @@ -144,12 +144,12 @@ class TileTile(models.Model): @api.multi def _compute_data(self): + eval_context = self._get_eval_context() for rec in self: if not rec.active: return - model = self.env[rec.model_id.model] - eval_context = self._get_eval_context() domain = rec.domain or '[]' + model = rec.env[rec.model_id.model] try: count = model.search_count(eval(domain, eval_context)) except Exception as e: From 6524ddcbd40702ef7f3824516cce59a563e1ec19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Todorovich?= Date: Sat, 19 Nov 2016 14:07:01 -0300 Subject: [PATCH 49/50] [IMP][8.0][web_dashboard_tile] Refactor (see changes in description) (#476) Conflicts: web_dashboard_tile/__openerp__.py web_dashboard_tile/models/tile_tile.py --- web_dashboard_tile/models/tile_tile.py | 112 ++++++++++----------- web_dashboard_tile/static/src/css/tile.css | 2 +- 2 files changed, 56 insertions(+), 58 deletions(-) diff --git a/web_dashboard_tile/models/tile_tile.py b/web_dashboard_tile/models/tile_tile.py index 0ee69ef6..7f4866bc 100644 --- a/web_dashboard_tile/models/tile_tile.py +++ b/web_dashboard_tile/models/tile_tile.py @@ -142,70 +142,68 @@ class TileTile(models.Model): string='Error Details', compute='_compute_data') - @api.multi + @api.one def _compute_data(self): + if not self.active: + return + model = self.env[self.model_id.model] eval_context = self._get_eval_context() - for rec in self: - if not rec.active: - return - domain = rec.domain or '[]' - model = rec.env[rec.model_id.model] - try: - count = model.search_count(eval(domain, eval_context)) - except Exception as e: - rec.primary_value = rec.secondary_value = 'ERR!' - rec.error = str(e) - return - if any([ - rec.primary_function and - rec.primary_function != 'count', - rec.secondary_function and - rec.secondary_function != 'count' - ]): - records = model.search(eval(domain, eval_context)) - for f in ['primary_', 'secondary_']: - f_function = f + 'function' - f_field_id = f + 'field_id' - f_format = f + 'format' - f_value = f + 'value' - value = 0 - if rec[f_function] == 'count': - value = count - elif rec[f_function]: - func = FIELD_FUNCTIONS[rec[f_function]]['func'] - if func and rec[f_field_id] and count: - vals = [x[rec[f_field_id].name] for x in records] - value = func(vals) - if rec[f_function]: - try: - rec[f_value] = (rec[f_format] or '{:,}').format(value) - except ValueError as e: - rec[f_value] = 'F_ERR!' - rec.error = str(e) - return - else: - rec[f_value] = False + domain = self.domain or '[]' + try: + count = model.search_count(eval(domain, eval_context)) + except Exception as e: + self.primary_value = self.secondary_value = 'ERR!' + self.error = str(e) + return + if any([ + self.primary_function and + self.primary_function != 'count', + self.secondary_function and + self.secondary_function != 'count' + ]): + records = model.search(eval(domain, eval_context)) + for f in ['primary_', 'secondary_']: + f_function = f + 'function' + f_field_id = f + 'field_id' + f_format = f + 'format' + f_value = f + 'value' + value = 0 + if self[f_function] == 'count': + value = count + elif self[f_function]: + func = FIELD_FUNCTIONS[self[f_function]]['func'] + if func and self[f_field_id] and count: + vals = [x[self[f_field_id].name] for x in records] + value = func(vals) + if self[f_function]: + try: + self[f_value] = (self[f_format] or '{:,}').format(value) + except ValueError as e: + self[f_value] = 'F_ERR!' + self.error = str(e) + return + else: + self[f_value] = False - @api.multi + @api.one @api.onchange('primary_function', 'primary_field_id', 'secondary_function', 'secondary_field_id') def _compute_helper(self): - for rec in self: - for f in ['primary_', 'secondary_']: - f_function = f + 'function' - f_field_id = f + 'field_id' - f_helper = f + 'helper' - rec[f_helper] = '' - field_func = FIELD_FUNCTIONS.get(rec[f_function], {}) - help = field_func.get('help', False) - if help: - if rec[f_function] != 'count' and rec[f_field_id]: - desc = rec[f_field_id].field_description - rec[f_helper] = help % desc - else: - rec[f_helper] = help + for f in ['primary_', 'secondary_']: + f_function = f + 'function' + f_field_id = f + 'field_id' + f_helper = f + 'helper' + self[f_helper] = '' + field_func = FIELD_FUNCTIONS.get(self[f_function], {}) + help = field_func.get('help', False) + if help: + if self[f_function] != 'count' and self[f_field_id]: + desc = self[f_field_id].field_description + self[f_helper] = help % desc + else: + self[f_helper] = help - @api.multi + @api.one def _compute_active(self): ima = self.env['ir.model.access'] for rec in self: diff --git a/web_dashboard_tile/static/src/css/tile.css b/web_dashboard_tile/static/src/css/tile.css index 73b811d3..0620a9c6 100644 --- a/web_dashboard_tile/static/src/css/tile.css +++ b/web_dashboard_tile/static/src/css/tile.css @@ -56,4 +56,4 @@ .openerp .oe_searchview_drawer .oe_opened .oe_dashboard_tile_form { display: block; -} \ No newline at end of file +} From ca0840d97a05579023e25f8205e7cc9f7b3d3f48 Mon Sep 17 00:00:00 2001 From: Nicolas Mac Rouillon Date: Tue, 27 Dec 2016 16:57:47 -0300 Subject: [PATCH 50/50] FIX --- web_dashboard_tile/models/tile_tile.py | 4 ++-- web_dashboard_tile/static/src/js/custom_js.js | 9 +++++---- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/web_dashboard_tile/models/tile_tile.py b/web_dashboard_tile/models/tile_tile.py index 7f4866bc..218cec40 100644 --- a/web_dashboard_tile/models/tile_tile.py +++ b/web_dashboard_tile/models/tile_tile.py @@ -106,7 +106,7 @@ class TileTile(models.Model): 'ir.model.fields', string='Field', domain="[('model_id', '=', model_id)," - " ('ttype', 'in', ['float', 'integer'])]") + " ('ttype', 'in', ['float', 'integer', 'monetary'])]") primary_format = fields.Char( string='Format', help='Python Format String valid with str.format()\n' @@ -126,7 +126,7 @@ class TileTile(models.Model): 'ir.model.fields', string='Secondary Field', domain="[('model_id', '=', model_id)," - " ('ttype', 'in', ['float', 'integer'])]") + " ('ttype', 'in', ['float', 'integer', 'monetary'])]") secondary_format = fields.Char( string='Secondary Format', help='Python Format String valid with str.format()\n' diff --git a/web_dashboard_tile/static/src/js/custom_js.js b/web_dashboard_tile/static/src/js/custom_js.js index 9015f9a9..615a74d6 100644 --- a/web_dashboard_tile/static/src/js/custom_js.js +++ b/web_dashboard_tile/static/src/js/custom_js.js @@ -19,11 +19,12 @@ // //############################################################################# -odoo.web_dashboard_tile = function (instance) +odoo.web_dashboard_tile = function (require) { -var QWeb = instance.web.qweb, - _t = instance.web._t, - _lt = instance.web._lt; +var QWeb = require('web.qweb') +var _t = require('web._t') +var _lt = require('web._lt') + _.mixin({ sum: function (obj) { return _.reduce(obj, function (a, b) { return a + b; }, 0); } });