From f9f9d80a8d66bab81609479c74cfb4796ee304d7 Mon Sep 17 00:00:00 2001 From: Markus Schneider <schnueptus@schnueptus.de> 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 000000000..e69de29bb diff --git a/web_advanced_search_wildcard/__openerp__.py b/web_advanced_search_wildcard/__openerp__.py new file mode 100644 index 000000000..3308ec6f5 --- /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. (<http://openerp.com>). +# Copyright (C) 2014 initOS GmbH & Co. KG (<http://www.initos.com>). +# Author Thomas Rehn <thomas.rehn at initos.com> +# +# 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 <http://www.gnu.org/licenses/>. +# +############################################################################## +{ + "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 000000000..314c4df2a --- /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 000000000..d6a1a5ac7 --- /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 000000000..4a5318a8d --- /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 <schnueptus@schnueptus.de> 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 <schnueptus@schnueptus.de> 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 314c4df2a..bfc97d1ac 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 d6a1a5ac7..e187a2da3 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 <rs@techno-flex.de> 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 bfc97d1ac..4cfbc4f35 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 <schnapkar@golive-saar.de>, 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 <schnapkar@golive-saar.de>\n" +"Language-Team: German <kde-i18n-de@kde.org>\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 <alexandre.fayolle@camptocamp.com> 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 3308ec6f5..dd4ee58ea 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 <transbot@odoo-community.org> 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 000000000..e85bb9586 --- /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 <transbot@odoo-community.org>\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 <lfreeke@therp.nl> 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 4a5318a8d..1b43dc0c5 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 <lfreeke@therp.nl> 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 000000000..9edc5fdfe --- /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 <https://github.com/OCA/web/issues>`_. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us smashing it by providing a detailed and welcomed feedback +`here <https://github.com/OCA/web/issues/new?body=module:%20web_advanced_search_wildcard%0Aversion:%208.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_. + + + +Contributors +------------ + +* Markus Schneider <> +* L Freeke <lfreeke@therp.nl> + +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 dd4ee58ea..d2e6cd884 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". - """, + "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" + ], 'data': [ + "views/template.xml", ], - 'demo': [ - ], - 'test': [ - ], - '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 000000000..bfe353d55 --- /dev/null +++ b/web_advanced_search_wildcard/views/template.xml @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="UTF-8"?> +<openerp> + <data> + <template id="assets_backend" name="web_advanced_search_wildcard assets" inherit_id="web.assets_backend"> + <xpath expr="." position="inside"> + <script type="text/javascript" src="/web_advanced_search_wildcard/static/src/js/search.js"></script> + </xpath> + </template> + </data> +</openerp> From 0a0a4a58f7c7791302289100dc6ccfb17914f1cd Mon Sep 17 00:00:00 2001 From: lfreeke <lfreeke@therp.nl> 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 9edc5fdfe..031b8007b 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 <lfreeke@therp.nl> 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 031b8007b..8425e1d87 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 <markus.schneider@initos.com> * L Freeke <lfreeke@therp.nl> Maintainer From 30367a046badd5b8a5f7d100a96e6fcc2b5c00a6 Mon Sep 17 00:00:00 2001 From: lfreeke <lfreeke@therp.nl> 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 8425e1d87..dcd65e33a 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 <https://github.com/OCA/web/issues/new?body=module:%20web_advanced_search_wildcard%0Aversion:%208.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_. +Credits +======= +Images +------ + +* Odoo Community Association: `Icon <https://github.com/OCA/maintainer-tools/blob/master/template/module/static/description/icon.svg>`_. Contributors ------------ * Markus Schneider <markus.schneider@initos.com> +* Thomas Rehn <thomas.rehn@initos.com> * L Freeke <lfreeke@therp.nl> + 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 d2e6cd884..e54a77dac 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. (<http://openerp.com>). -# Copyright (C) 2014 initOS GmbH & Co. KG (<http://www.initos.com>). -# Author Thomas Rehn <thomas.rehn at initos.com> -# -# 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 <http://www.gnu.org/licenses/>. -# -############################################################################## +# © 2014 initOS GmbH & Co. KG (<http://www.initos.com>). +# © 2016 Therp BV <http://therp.nl>. +# 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 <lfreeke@therp.nl> 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 dcd65e33a..8c6de995d 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 e54a77dac..797f3a604 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<FV<w{p-AUi=RvC<yKV literal 0 HcmV?d00001 From 72f012ab3d79f658dc4ccff9022cbc2282422530 Mon Sep 17 00:00:00 2001 From: OCA Transbot <transbot@odoo-community.org> 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 000000000..f8aa6f658 --- /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č <m.mozetic@matmoz.si>, 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č <m.mozetic@matmoz.si>\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 <transbot@odoo-community.org> 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 000000000..91f0ab2e7 --- /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 <jarmo.kortetjarvi@gmail.com>, 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 <jarmo.kortetjarvi@gmail.com>\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 000000000..0464430f9 --- /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 <danimaribeiro@gmail.com>, 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 <danimaribeiro@gmail.com>\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 <transbot@odoo-community.org> 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 000000000..302b2e39e --- /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 <christophe.chauvet@gmail.com>, 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 <christophe.chauvet@gmail.com>\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?= <stephane.bidoul@acsone.eu> 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 e85bb9586..000000000 --- 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 <transbot@odoo-community.org>\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 <transbot@odoo-community.org> 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 000000000..2f9437ce7 --- /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 <pedro.baeza@gmail.com>, 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 <pedro.baeza@gmail.com>\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?= <ivan.todorovich@gmail.com> 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 `<data noupdate="1">`, 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 3e636b152..f84fd1b37 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 000000000..570f814e4 --- /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 <ivan.todorovich@gmail.com> +# 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?= <ivan.todorovich@gmail.com> 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 | 52 +++- .../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 | 93 ++++--- 10 files changed, 471 insertions(+), 33 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 c87fb47d6..0337037b1 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 6b23b71bd..dd9da0165 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 000000000..7cfcc1c00 --- /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 <ivan.todorovich@gmail.com> +# 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 4743afcb5..498d365bb 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. (<http://openerp.com>). +# © 2014 initOS GmbH & Co. KG (<http://www.initos.com>). +# © 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 8d653b70c..05637bfdc 100644 --- a/web_dashboard_tile/security/rules.xml +++ b/web_dashboard_tile/security/rules.xml @@ -6,7 +6,16 @@ <field name="name">tile.owner</field> <field name="model_id" ref="model_tile_tile" /> <field name="groups" eval="[(4, ref('base.group_user'))]"/> - <field name="domain_force">[('user_id','in',[False,user.id])]</field> + <field name="domain_force"> + [ + '|', + ('user_id','=',user.id), + ('user_id','=',False), + '|', + ('group_ids','=',False), + ('group_ids','in',[g.id for g in user.groups_id]), + ] + </field> </record> </data> diff --git a/web_dashboard_tile/static/src/css/tile.css b/web_dashboard_tile/static/src/css/tile.css index 1d057ceea..4ec483d72 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; - text-align: center; +======= +/* 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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 diff --git a/web_dashboard_tile/tests/__init__.py b/web_dashboard_tile/tests/__init__.py new file mode 100644 index 000000000..4f8c7e8bf --- /dev/null +++ b/web_dashboard_tile/tests/__init__.py @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +# © 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com> +# 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 000000000..90604ab9a --- /dev/null +++ b/web_dashboard_tile/tests/test_tile.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# © 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com> +# 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 36411ad84..cf9a003f4 100644 --- a/web_dashboard_tile/views/tile.xml +++ b/web_dashboard_tile/views/tile.xml @@ -9,8 +9,10 @@ <field name="name"/> <field name="domain"/> <field name="model_id"/> - <field name="field_function"/> - <field name="field_id"/> + <field name="primary_function"/> + <field name="primary_field_id"/> + <field name="secondary_function"/> + <field name="secondary_field_id"/> <field name="user_id"/> <field name="background_color" widget="color"/> </tree> @@ -34,11 +36,50 @@ <field name="model_id"/> <field name="action_id"/> <field name="domain" colspan="4"/> - <separator string="Optional Field Informations" colspan="4"/> - <field name="field_function"/> - <field name="field_id"/> - <field name="helper" colspan="4"/> + <separator colspan="4"/> + <field name="error" attrs="{'invisible':[('error','=',False)]}"/> </group> + <notebook> + <page string="Main Value"> + <group> + <group> + <field name="primary_function"/> + <field name="primary_field_id" attrs="{ + 'invisible':[('primary_function','in',[False,'count'])], + 'required':[('primary_function','not in',[False,'count'])], + }"/> + </group> + <group> + <field name="primary_format"/> + </group> + <group> + <field name="primary_helper"/> + <field name="primary_value" attrs="{'invisible':[('primary_value','=',False)]}"/> + </group> + </group> + </page> + <page string="Secondary Value"> + <group> + <group> + <field name="secondary_function"/> + <field name="secondary_field_id" attrs="{ + 'invisible':[('secondary_function','in',[False,'count'])], + 'required':[('secondary_function','not in',[False,'count'])], + }"/> + </group> + <group> + <field name="secondary_format"/> + </group> + <group> + <field name="secondary_helper"/> + <field name="secondary_value" attrs="{'invisible':[('secondary_value','=',False)]}"/> + </group> + </group> + </page> + <page string="Groups"> + <field name="group_ids"/> + </page> + </notebook> </sheet> </form> </field> @@ -53,37 +94,31 @@ <field name="domain"/> <field name="model_id"/> <field name="action_id"/> - <field name="count"/> <field name="background_color"/> <field name="font_color"/> - <field name="field_id" /> - <field name="field_function" /> - <field name="helper" /> + <field name="primary_function"/> + <field name="primary_helper"/> + <field name="secondary_function"/> + <field name="secondary_helper"/> + <templates> <t t-name="kanban-box"> <div t-attf-class="oe_dashbaord_tile oe_kanban_global_click" t-attf-style="background-color:#{record.background_color.raw_value}" > <div class="oe_kanban_content"> <a type="object" name="open_link" args="[]" t-attf-style="color:#{record.font_color.raw_value};"> - <div class="tile_label"> - <b><field name="name"/></b> + <div style="height:100%;" t-att-class="record.secondary_function.raw_value and 'with_secondary' or 'simple'"> + <div class="tile_label"> + <field name="name"/> + </div> + <div class="tile_primary_value" t-att-title="record.primary_helper.raw_value"> + <t t-set="l" t-value="record.primary_value.raw_value.length" /> + <t t-set="s" t-value="l>=12 and 35 or l>=10 and 45 or l>=8 and 55 or l>=6 and 75 or l>4 and 85 or 100"/> + <span t-attf-style="font-size: #{s}%;"><field name="primary_value"/></span> + </div> + <div class="tile_secondary_value" t-att-title="record.secondary_helper.raw_value"> + <span><field name="secondary_value"/></span> + </div> </div> - <div style="padding-left: 0.5em; height: 115px;"> - - </div> - <t t-if="record.field_id.raw_value != '' and record.field_function.raw_value != '' and record.count.raw_value !=0"> - <div class="tile_count_with_computed_value"> - <span><field name="count"/></span> - </div> - <div class="tile_computed_value" t-att-title="record.helper.raw_value"> - <img t-att-src="_s + '/web_dashboard_tile/static/src/img/' + record.field_function.raw_value + '.png'"/> - <span><field name="computed_value"/></span> - </div> - </t> - <t t-if="!(record.field_id.raw_value != '' and record.field_function.raw_value != '' and record.count.raw_value !=0)"> - <div class="tile_count_without_computed_value"> - <span><field name="count"/></span> - </div> - </t> </a> </div> <div class="oe_clear"></div> From 13ea439bb202e805155d4fa3d828eab9b720fb8c Mon Sep 17 00:00:00 2001 From: Nicolas Mac Rouillon <nmr@adhoc.com.ar> Date: Tue, 13 Dec 2016 15:04:14 -0300 Subject: [PATCH 21/50] FIX --- web_dashboard_tile/README.rst | 44 +---- 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, 60 insertions(+), 283 deletions(-) diff --git a/web_dashboard_tile/README.rst b/web_dashboard_tile/README.rst index 0337037b1..523dcadb5 100644 --- a/web_dashboard_tile/README.rst +++ b/web_dashboard_tile/README.rst @@ -1,19 +1,6 @@ -Add Tiles to Dashboard -====================== +Dashboard Tiles +=============== -<<<<<<< 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; -======= 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 -====================== +.. image:: ./static/src/img/screenshot_action_click.png -<<<<<<< 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); -======= 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 <https://github.com/OCA/web/issues>`_. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us smashing it by providing a detailed and welcomed feedback -`here <https://github.com/OCA/ -web/issues/new?body=module:%20 -web_dashboard_tile%0Aversion:%20 -8.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_. +`here <https://github.com/OCA/web/issues/new?body=module:%20web_dashboard_tile%0Aversion:%208.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_. Credits @@ -88,6 +61,7 @@ Contributors * Markus Schneider <markus.schneider at initos.com> * Sylvain Le Gal (https://twitter.com/legalsylvain) +* Iván Todorovich <ivan.todorovich@gmail.com> 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 35d8f47b1..1d098b583 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. (<http://openerp.com>). -# Copyright (C) 2014 initOS GmbH & Co. KG (<http://www.initos.com>). -# Copyright (C) 2015-Today GRAP -# Author Markus Schneider <markus.schneider at initos.com> -# @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 <http://www.gnu.org/licenses/>. -# -############################################################################## +# © 2010-2013 OpenERP s.a. (<http://openerp.com>). +# © 2014 initOS GmbH & Co. KG (<http://www.initos.com>). +# © 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 f84fd1b37..bcba4eb5d 100644 --- a/web_dashboard_tile/__openerp__.py +++ b/web_dashboard_tile/__openerp__.py @@ -20,6 +20,10 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. # ############################################################################## +# -*- coding: utf-8 -*- +# © 2010-2013 OpenERP s.a. (<http://openerp.com>). +# © 2014 initOS GmbH & Co. KG (<http://www.initos.com>). +# 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 <ivan.todorovich@gmail.com>' + ], '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 fc23e732e..97fec216c 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 <http://www.gnu.org/licenses/>. -# -############################################################################## +# © 2010-2013 OpenERP s.a. (<http://openerp.com>). +# © 2014 initOS GmbH & Co. KG (<http://www.initos.com>). +# © 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 498d365bb..bc304b691 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. (<http://openerp.com>). -# Copyright (C) 2014 initOS GmbH & Co. KG (<http://www.initos.com>). -# Copyright (C) 2015-Today GRAP -# Author Markus Schneider <markus.schneider at initos.com> -# @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 <http://www.gnu.org/licenses/>. -# -############################################################################## - -from openerp import api, fields -from openerp.models import Model -from openerp.exceptions import except_orm -======= # © 2010-2013 OpenERP s.a. (<http://openerp.com>). # © 2014 initOS GmbH & Co. KG (<http://www.initos.com>). # © 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 4ec483d72..73b811d3f 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 c192ef293..9015f9a9d 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 3e0c23167..11ecb179c 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 @@ <templates id="template" xml:space="preserve"> <t t-extend="SearchView.addtodashboard"> <t t-jquery="form" t-operation="after"> - <div> + <div class="oe_dashboard_tile_form"> <label for="dashboard_tile_new_name">Tile:</label> <input id="dashboard_tile_new_name" /> <button id="add_dashboard_tile">Create</button> </div> </t> </t> -</templates> +</templates> \ No newline at end of file diff --git a/web_dashboard_tile/views/templates.xml b/web_dashboard_tile/views/templates.xml index e7a68b213..1fe51f0d1 100644 --- a/web_dashboard_tile/views/templates.xml +++ b/web_dashboard_tile/views/templates.xml @@ -30,4 +30,4 @@ </xpath> </template> </data> -</openerp> +</openerp> \ No newline at end of file diff --git a/web_dashboard_tile/views/tile.xml b/web_dashboard_tile/views/tile.xml index cf9a003f4..a42d952f8 100644 --- a/web_dashboard_tile/views/tile.xml +++ b/web_dashboard_tile/views/tile.xml @@ -103,7 +103,7 @@ <templates> <t t-name="kanban-box"> - <div t-attf-class="oe_dashbaord_tile oe_kanban_global_click" t-attf-style="background-color:#{record.background_color.raw_value}" > + <div t-attf-class="oe_dashboard_tile oe_kanban_global_click" t-attf-style="background-color:#{record.background_color.raw_value}" > <div class="oe_kanban_content"> <a type="object" name="open_link" args="[]" t-attf-style="color:#{record.font_color.raw_value};"> <div style="height:100%;" t-att-class="record.secondary_function.raw_value and 'with_secondary' or 'simple'"> @@ -152,9 +152,9 @@ <record id="mail_dashboard" model="ir.ui.menu"> <field name="name">Dashboard</field> - <field name="sequence" eval="9"/> + <field name="sequence" eval="0"/> <field name="action" ref="action_kanban_dashboard_tile"/> - <field name="parent_id" ref="mail.mail_feeds"/> + <field name="parent_id" ref=""/> </record> </data> From 5f33d4868f486521b43aa5276d0111e7050c486d Mon Sep 17 00:00:00 2001 From: Nicolas Mac Rouillon <nmr@adhoc.com.ar> 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 bcba4eb5d..dbda3d3b7 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. (<http://openerp.com>). -# Copyright (C) 2014 initOS GmbH & Co. KG (<http://www.initos.com>). -# Author Markus Schneider <markus.schneider at initos.com> -# -# 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 <http://www.gnu.org/licenses/>. -# -############################################################################## -# -*- coding: utf-8 -*- # © 2010-2013 OpenERP s.a. (<http://openerp.com>). # © 2014 initOS GmbH & Co. KG (<http://www.initos.com>). # 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 <nmr@adhoc.com.ar> 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 523dcadb5..daa3a2ebf 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 11ecb179c..38a0e3e96 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 @@ </div> </t> </t> -</templates> \ No newline at end of file +</templates> diff --git a/web_dashboard_tile/views/templates.xml b/web_dashboard_tile/views/templates.xml index 1fe51f0d1..e7a68b213 100644 --- a/web_dashboard_tile/views/templates.xml +++ b/web_dashboard_tile/views/templates.xml @@ -30,4 +30,4 @@ </xpath> </template> </data> -</openerp> \ No newline at end of file +</openerp> From 839262a11bda12c3f87fc6b584323d74e184d0fd Mon Sep 17 00:00:00 2001 From: Nicolas Mac Rouillon <nmr@adhoc.com.ar> 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 8c6de995d..000000000 --- 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 <https://github.com/OCA/web/issues>`_. -In case of trouble, please check there if your issue has already been reported. -If you spotted it first, help us smashing it by providing a detailed and welcomed feedback -`here <https://github.com/OCA/web/issues/new?body=module:%20web_advanced_search_wildcard%0Aversion:%208.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_. - -Credits -======= - -Images ------- - -* Odoo Community Association: `Icon <https://github.com/OCA/maintainer-tools/blob/master/template/module/static/description/icon.svg>`_. - -Contributors ------------- - -* Markus Schneider <markus.schneider@initos.com> -* Thomas Rehn <thomas.rehn@initos.com> -* L Freeke <lfreeke@therp.nl> - - -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 e69de29bb..000000000 diff --git a/web_advanced_search_wildcard/__openerp__.py b/web_advanced_search_wildcard/__openerp__.py deleted file mode 100644 index 797f3a604..000000000 --- a/web_advanced_search_wildcard/__openerp__.py +++ /dev/null @@ -1,21 +0,0 @@ -# -*- coding: utf-8 -*- -# © 2014 initOS GmbH & Co. KG (<http://www.initos.com>). -# © 2016 Therp BV <http://therp.nl>. -# 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 4cfbc4f35..000000000 --- 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 <schnapkar@golive-saar.de>, 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 <schnapkar@golive-saar.de>\n" -"Language-Team: German <kde-i18n-de@kde.org>\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 2f9437ce7..000000000 --- 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 <pedro.baeza@gmail.com>, 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 <pedro.baeza@gmail.com>\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 91f0ab2e7..000000000 --- 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 <jarmo.kortetjarvi@gmail.com>, 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 <jarmo.kortetjarvi@gmail.com>\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 302b2e39e..000000000 --- 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 <christophe.chauvet@gmail.com>, 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 <christophe.chauvet@gmail.com>\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 0464430f9..000000000 --- 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 <danimaribeiro@gmail.com>, 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 <danimaribeiro@gmail.com>\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 f8aa6f658..000000000 --- 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č <m.mozetic@matmoz.si>, 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č <m.mozetic@matmoz.si>\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 e187a2da3..000000000 --- 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<FV<w{p-AUi=RvC<yKV diff --git a/web_advanced_search_wildcard/static/src/js/search.js b/web_advanced_search_wildcard/static/src/js/search.js deleted file mode 100644 index 1b43dc0c5..000000000 --- a/web_advanced_search_wildcard/static/src/js/search.js +++ /dev/null @@ -1,6 +0,0 @@ -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")} - ); -}; diff --git a/web_advanced_search_wildcard/views/template.xml b/web_advanced_search_wildcard/views/template.xml deleted file mode 100644 index bfe353d55..000000000 --- a/web_advanced_search_wildcard/views/template.xml +++ /dev/null @@ -1,10 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<openerp> - <data> - <template id="assets_backend" name="web_advanced_search_wildcard assets" inherit_id="web.assets_backend"> - <xpath expr="." position="inside"> - <script type="text/javascript" src="/web_advanced_search_wildcard/static/src/js/search.js"></script> - </xpath> - </template> - </data> -</openerp> diff --git a/web_dashboard_tile/models/tile_tile.py b/web_dashboard_tile/models/tile_tile.py index bc304b691..38ce5c66c 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 <schnueptus@schnueptus.de> 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 000000000..e69de29bb diff --git a/web_advanced_search_wildcard/__openerp__.py b/web_advanced_search_wildcard/__openerp__.py new file mode 100644 index 000000000..3308ec6f5 --- /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. (<http://openerp.com>). +# Copyright (C) 2014 initOS GmbH & Co. KG (<http://www.initos.com>). +# Author Thomas Rehn <thomas.rehn at initos.com> +# +# 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 <http://www.gnu.org/licenses/>. +# +############################################################################## +{ + "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 000000000..314c4df2a --- /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 000000000..d6a1a5ac7 --- /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 000000000..4a5318a8d --- /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 <schnueptus@schnueptus.de> 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 <schnueptus@schnueptus.de> 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 314c4df2a..bfc97d1ac 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 d6a1a5ac7..e187a2da3 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 <rs@techno-flex.de> 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 bfc97d1ac..4cfbc4f35 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 <schnapkar@golive-saar.de>, 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 <schnapkar@golive-saar.de>\n" +"Language-Team: German <kde-i18n-de@kde.org>\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 <alexandre.fayolle@camptocamp.com> 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 3308ec6f5..dd4ee58ea 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 <transbot@odoo-community.org> 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 000000000..e85bb9586 --- /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 <transbot@odoo-community.org>\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 <lfreeke@therp.nl> 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 4a5318a8d..1b43dc0c5 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 <lfreeke@therp.nl> 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 000000000..9edc5fdfe --- /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 <https://github.com/OCA/web/issues>`_. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us smashing it by providing a detailed and welcomed feedback +`here <https://github.com/OCA/web/issues/new?body=module:%20web_advanced_search_wildcard%0Aversion:%208.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_. + + + +Contributors +------------ + +* Markus Schneider <> +* L Freeke <lfreeke@therp.nl> + +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 dd4ee58ea..d2e6cd884 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". - """, + "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" + ], 'data': [ + "views/template.xml", ], - 'demo': [ - ], - 'test': [ - ], - '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 000000000..bfe353d55 --- /dev/null +++ b/web_advanced_search_wildcard/views/template.xml @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="UTF-8"?> +<openerp> + <data> + <template id="assets_backend" name="web_advanced_search_wildcard assets" inherit_id="web.assets_backend"> + <xpath expr="." position="inside"> + <script type="text/javascript" src="/web_advanced_search_wildcard/static/src/js/search.js"></script> + </xpath> + </template> + </data> +</openerp> From 93b5b770dfdf682854cc5c3373540ad6a51954af Mon Sep 17 00:00:00 2001 From: lfreeke <lfreeke@therp.nl> 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 9edc5fdfe..031b8007b 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 <lfreeke@therp.nl> 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 031b8007b..8425e1d87 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 <markus.schneider@initos.com> * L Freeke <lfreeke@therp.nl> Maintainer From 68e4f299e6b8a752c8f3b3983f8d61f6c0af6f5a Mon Sep 17 00:00:00 2001 From: lfreeke <lfreeke@therp.nl> 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 8425e1d87..dcd65e33a 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 <https://github.com/OCA/web/issues/new?body=module:%20web_advanced_search_wildcard%0Aversion:%208.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_. +Credits +======= +Images +------ + +* Odoo Community Association: `Icon <https://github.com/OCA/maintainer-tools/blob/master/template/module/static/description/icon.svg>`_. Contributors ------------ * Markus Schneider <markus.schneider@initos.com> +* Thomas Rehn <thomas.rehn@initos.com> * L Freeke <lfreeke@therp.nl> + 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 d2e6cd884..e54a77dac 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. (<http://openerp.com>). -# Copyright (C) 2014 initOS GmbH & Co. KG (<http://www.initos.com>). -# Author Thomas Rehn <thomas.rehn at initos.com> -# -# 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 <http://www.gnu.org/licenses/>. -# -############################################################################## +# © 2014 initOS GmbH & Co. KG (<http://www.initos.com>). +# © 2016 Therp BV <http://therp.nl>. +# 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 <lfreeke@therp.nl> 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 dcd65e33a..8c6de995d 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 e54a77dac..797f3a604 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 zcmZ`;cRba7-~Y9cc?u~)wrnArIx>qgvPU9h@2qHWWMm`>aYDF^W0S2MLUu;>9$6uK zKOfg~zh2jK-}meJ{=pf)^E==1`MlQ&x~HZ{ModeLAPAYV(k%@HIY|YN1Bp(;->+^u z?(pxF3tCx=h=^!#{O%Y$MY+oBx@tODxIQs;euQXRxw*PNayEO>aTY=7-Yeg_spT=S zH0)_eX?ap~#nKtYLVT{CMV*J}euSKQr1d#|sjPw={q`5kxF7dX>RLrT^W_XY#3v1S zYm-yCi+h7<sBhk^yB-|u>@Qat;mk=E$TZus*Rb9iPt$S#wq9P%GUJYaQxpfjMb3Av zg|uBRLyHThx+390ihsb3AYT>&2m|q7wPBwAgb1>q&l#7NPmLgB8?~o?O2L1(@elCy z3Oq!{Pap^p1%ll0fG4%55ac6EfTEgOTbzi^OiOIxgRd{Dytlqj{|PHNQ>?#~rWzl| zQ|Whf_#^dp43FNMhzQ5+6;pKMx7T!qg@pz@q)5m3$^c$P`1<wVLuEo@VjjObl2lT! zv9q%?Gfxz@%PgP_?xl22O;3yHc^vF+M6xL6=;lxCtj$U!{GJXtfuI=p-zFy7J2;HO z*Us=~^jPDxxg(W0gU=HO7#kali;Me5U@(}*#>UJ{t}?@sT$36yy6c}(Q-`a(pWrcM z{t=6diw-ph?pwcy<>loC1qF!%&{t4AM&;cjBO`f#3N72&+1S*nHrgbYxA*q2Ql1(( zZEtUHN;ESwv#qUdnp%Q{-=Pm7Az|#D3$(QJ%gecbiShB?^W9hD(pp<v5BB$4T3baO zMut8+jL!c(#_@rE>z#^(6bzppd%>D2+?O6UctxtDHZ?T~tFG<%P*O&fmrF1*GP*w^ zC5d_aR#<PTuCA`OwiZ58T3VW|n|~5V2`it1BMoPieW%1478a(;T-V+0y7OoH`Sa)J zgX-Ga>|rPE?d|;|T3YVp>sFfL3F6XV9v`BkMcfzrQWV3vsDj%PB-7K<ygWQ$|6!Nx zhs*EtT+q?dvK=ZFl#tNpq$&_;HZNGN-m@RAe##ul$;HLR#x^Z)gxwnTlNA$t-!M6c zjd}MjQQXA>_79!3@;#b+e0*HeeeprFLw|vM(!K5N?K=q)8&P*<%3SAuBuaa)7nhZm z4%PV8<mYz|4(@HQPGT58@efT{Q=&67GszjGl+>x>*rC=AYluAmOa<Lyc5-&UCM49w zkCkxC3=9ms!`|H9el(wz%X+>E$|(I#tcI?x$L3=HpX1@2s`1#?R?264B}*qaj8=q; zgTr!TzK4yCO+-ZGc&8UkFV4We_4f8IhJUsnrWJSoq{PbX@3T9X?jPY$y^~f?O()^X z8Qvh|lbDcTWMo8t`ErZ)-u{k@J0}esGg@i3Euq3~LEFG!5NcYqj~rHRQ$661f~t_g zhP$6dh{Dr2gRjBZ53Ym@)zv!#8GWrBj>q!cT$xp8vWf2wn~;zYH@D6Aw^!kioXb8O z{N7wyQMz;I)8m2q`c%zyHHn0_p&=<|<`=lk^74T^1N^k}MmrrX?OPQ#`GcDA$|8N- zVGmTFh-XgMoWg6`>Dk$aciA}HBgxadBBI&zZpEbo{r&xztP@Cweev9|HkG`dzJA+# zL9_K=okkVzJ^Z4gqDO~&%ejVSe_(mhDsD>yA}lN{FtH3R3744`*rt&Bi5D+Ux+4!1 z6&up;ViRTkM)3HTsE2lTMg|6ZYwfa>Xkro)9h`ou7T1P|q=dvssZ&Z)(sPvaRAc1S zlsT00n>Xh%rf~4zjP*PtljH)8%bZgS3f`dJynRbWOFQsTkT2$TSCJ`sm4Ee0vko1C zNQaN=>gz)#^wrgU+PVF7Z*#clu_hXg_V5s6s{8iMVz9*S<nsrB7fw!2vWMF&-X)op zl^;|;u1+?XRQvR|wS}P`+S*<|f8Kd}WgH6KS?t4WI#KuELwY7_A8)?2XiscS^eQMQ z(69C>Q%HfvlaY~mnBUjmzr)5Y<*_mrF0*U3(2FzV(_uY-hJc_%w*}y%zu$9pqCSwE z-g@=3xB7TY_I2cjWFS-j31qBzT($*J@xPD}#Q+fb4_2lGef##!b8SXmL7`;Z`qr&F zK(RsRr#?@gHh=$48l$DH?Ymk}vo_Nj4{ZvS9TE~^uuyoOlCobs1wkbIOXw1(07j{) zsdpLeY;7?VjP|-$q@{=Z`^8yU@X$-Gn9PHefWW}P!9j<Cq9FYEr%#`3hs#Cy_}Us9 ziCT#OGW@6{B_-XvozO(`>Ln#5s>G}u9PL<HlT;0(Qb$v0B3qNGFV9ca*VoU?%-D{6 zkoGRwF~4`|(j{eOWtCKo3@tvrg1X^hX+gnNfHAJ<%<AfDo1ZxgKXYk_PM4LH0e*5t zfA8z-8y&4NsqxLo$WWc};^O8WgoZ~a<rNfYWc8@_=9QFaGe_pJe7>6~)!*3oDuFG} zQ#v&@b@A3+=dvL{&4vaJSy@?jc7?1S4Jv8|h7t2%F0_)KUVpjU0-!{8c6M*BNiO!y zY2>5y!-0+f5}GguX)ma2c!!-oU#=jlXMTNs{ZaF~Iadjc>EXe$UtmB$r?8QxW}(OG zgv)H3h_JBF_ITi8H*Lj}Wi@4G^{gJ7-fYj!#Y=dBCr~LRw(y`KjNYKwI$AsH(M5Jv zR#p*_`>+9qr2_o?;im74ii-U9Cm90*0#2MbK^*YH^nGY(XhZ}GW7?Zz<UL+{24f1S zdGM8xQOb9}&yj8I&!2bvCckHAX{f2ABO{YEGA?2s=O-TQZ5{2ewUgq7g@s$<MRN-Z zuJQA?cXbseC!<q3si>$tyuFWh7jjAQw-gi-CEVuw^39-LYYum_w6n;FiB(ipA0fy< z{`G`*d}pU18(Tm!r@Krl`!G4Qw+wc9ex8<^nk`xdkj!DUdTD7%Rb2~kPa*8GGSOq1 zOH|l)fc8D;55V@|;NbOB@q_*S`B9!qtZxPe1|}vRMk>{j*GbwBl{!s+JD8O{dVKAt zrkR<Ularw2%_tbUJoY1=60W~GUJ_FLSzFW8)P%V$baZrFm<`<>96fZ0ijLyAE914U zl+{yU!*(IWdt+W+KQ5U|P|&IF)w#v<+}v3M1NxVH5k$@4AWbLNSlWAYaiG{H>NYKL z0JF5T5hs;}rDdVXS17`qoE*%f^)3mKSkla#9KI`89<;m{d`Up&?C99hPBm!$ogJ^2 zWEIB;(CU=KffvM(jiQO*SoI7Ihv1gHe-A*iYG_0#++yAK61&0B*RNrF5)u+zoSplu zHz=h=u*t!wWNgFAR*T>nq~rR)u6-7h9Hwt@P*l$YICiAUn^D>eNb`8W!HJ4)K|6q) zxUH<5^timb`fzt+VfS~)xcNO`hsm`akRmYiYq6mT0-0q`Mm*DVa>A-)=jVH})Ya8n zXT9dTGoo;~rTP$>vrHgERPBqeiHJlunV&s-7I;e^SCW^v0`LaK;$R%EomJ(w@Gd+& zyrQB)BO^N}$G$+jHT^HN+-YQ8$~esu@QsF@gTvd)Yu>LYFVE4*N&M+<QEsk-tLr)t zv^=x=(c!@c;S46~X8+*e*7B$yFr-nrtCPF?jH4KD;@UalfUjS_9_{|D0g}njce-)o z23F>2T>A#q#fzm-MM9QsP#)~*I1j0jFnY;{W@fSn>zb(=S1*Lb@ETlq9J_&5it>Ut zljTDIw_93T>K^8&q?mbndP3=~--qp;2k~MRf^<9|BLxXud3`@n{Qnb}{|&5%Jo<jN z+{OAvT3VkpGV+{~5>P~^L8avQwkZm$+xC6-;4g~pWgO%Z6$RB*z1U5KEIl{m<LBn? zqL>Y34<_5YupDr`Yd0OI#YL@8QN+z0*|_3(QI(2rlXrxKUhG)%;sRIxC5Qi!z2QHL z9(SdQ6IisoR|n0pzrBhNq%gbtg^o_ro#)Ym#lC#Iow@w{{4;0H@Ky^0o&ey>?qJ{? zeSLiwUE<OJS<37NOHL7z=iLUelAMy#iIHSBHt_8OCAQJd!pwY(ZaCcD=2BMITpq{R zYrElcH)uVKY{_)`XqihxPY*R+iFktA6Q~$U4mH=`L$OBATfdEDur)9>oWbW2Kw8k- zP&jaeR(PCR(mlqorYXn2rmO9L=0qR5;#}XQN8#+SVYCchK|w(<*QBH*L%yw{G8Z>D zH-HvEM|vTPP>l?q-Ss&*!OQgYohQerDI$i4hr7DE&NBV}{ktZ8HWG{V1AYZ&2Q8J^ zGp`)QZdBu2m7Q(-E%Z`XnyQVJ)vM6Z?99wJ&C{TA2lGtj^z{b-31HO+2M17v=H}+| z@@K*u3@SZVy_c&LiFN?z9EM7hI<4OE8O_hkr1e-&PENuJs&=i9eSHaBZ^jT#LqqfA zVAqW=1~}z-$Y77$ZTq~pen&?~pCKe%*t>M{`3;;lC0dIs`o<L{RaJT!pVEwss{@W% z3q$?CUS3iQYRJLvANJw{+b>^c#l>Hq@^fyTgjNJtI0Ptu{rWXo3=jx3e73=7fS57t z(LTpuBVxRIv8=e99vWtAb91E3CH)>}OH&i<bbrC4+i3JjCRQOKO`Z$DH1&0LR>E;W zMsr>1w^`2vm(kJ1!>N-pNNvMHn3$NLN@!nWP(MJP0B-K??9?|jP@><wd85U3-^0Vh z+?<tZsxF9fdU_hjH!?Ev+_`gUX=&lWayHi&E0(J(yf&=ywiku1B6N8UCqnoYLN9j0 z>4(tpw|x+&#BEVLeB3`=Kb=5Gkr?})NSeLB*z3S<c#ZSwRdL6$FP7M+y})~E;@`&e z2yLG3t_zBY@Ls)|Usxzd@=Qlo!2-MAmdScvIoG&~h{?jj0#MEt0h~jj)Ba0tXZX>m zc7e~jdGn?}DqnZMN5>?;nM3V^5)rI11BYYthx$zc_jTpUGgNY?6%Q}(F|x$P#Sst? zkTc5oz}u$?NIeWhd2Hr>q%KBnZ+qOmdpGuu`$XN@q<f`4JI<g;i>7+-8~juv@;o%W zZ<4z>GF*BpP*GL272roZ$8g6)^JYq?qgW{=>B!W@ohK8{WxO&R{+DHarT&k`u52oG z#PF76XNO8lO{{wOqk?zsP|!=Wu*)+u3UKdzalC*O13wSX9rh?_yoF`IqrDerNZ3{5 z*0t?*<)Feqr2v+Lw-_mRvoSUv38Lfx0oNI7&^au5m-taMi$bN#-sa>dO>yIqWhXH$ z?%vTfla9g94&WTGd0*+etlIVX@nio8$tS-#sfcZCY!-bzaAs4oyE5GWA-dzz`k#R+ zxlG>h_3Jq3zC}?pM@Pqy*<+r%i<QA?WLU+KlaSn2QQ_j@F|2UM6&G(nw|)zw-#hLV zJmz&s2xtywf2(5sq<ipXf)^YX-Zax`YW%4`-?@GE<+s<2x_WvsiN@W}y&1qDft8eT zn(+5+0xM5S0+u^L+y#Rl_xJbD3$#U+8UP?BCnkLNR~607CV}o^Vqz%KhK7b9tS?bf z6<POW{`&Q+yITvb^x(nA!wW2O;GN$!Pahs0QpxuZ47A0IhBr@3NJ!-97prhm#l3$I ze!6BOUJyVUAV*tU+dtwA$pzcd>ID4wvBxFLrVhGQ`=yxSXe*+=w!c5QM>csQ(7e5^ zjp4d&A6=zWZ?+yNG)m%tzSWL-()ejQQS~nvyCd(U*0FMkH!4fqU9Eq0XK3~@A_)CS zFHqyp0Mnm^U1R`+;EOS9M(;7jG@m(nB98O=BG&YnGinAw<x<noOy<~G$(}y>9I)V! zg7iO#!RB9g`a3N7haDgk`R`Z$j!FLQnqOl2e&j9*YFl^;SrF(T`(Z0Wp|Qtn1Av6T zmJlEwHbsAY7=%>;`3}Gc_@hWjLclW0r*yump8#?6J}&N|%PFLiUVo>kCsxR^Z|aKw zVt*mvmyCY|@QPd@d9iLa5cf!>CtwF}HSM``PKW!Rcs97gsK8vA&Vj|mWE7+(gcc~& z4WcH<2vk&<j~ixxWgKrM2RpT0#b;E0i)eh+Ly93BRXe-pDa9bKuBWGGU0m+Dv%c<X zX*mmu7h(hV>Qn;Ki+P@F7HB0?Q&TfD7AEt7qQ`Kk@^mMk$tG!6&#W%?LlYN5Yi}Nl z7)mr+P7b&P>L1j8{M)-~YG5s^RZ`0x$7^9F{nd@nPZ0)(g!I<}^!P_$eRr?Q$RxJU zQqT(jwG;TQp<#AvO3LqWsIie#K%nEt4~?TY3Ms&5O>J#6&SgMQBs6>=jKYG0!7NNU zia{wR3YemSh9R>7RD&RfidY_WO^xrt_wU~~mq&B&aROfV^#Lr7#K2}ZabSU;9Lo$N zm9%t@$L!?fTCiJk@d>0h<q?<-PCmXwAxrYTgle!Eis1~8g=rbWf9}UAf-9Amug^2Z zcU!yp_*AB+a|GgdHU}Mcd=A0>PC4%Y)tqJ8*w}!i1ilTVosyE0l|~cn%kA5@K`%B> zJJ;;Y#6t#<&k>_5yT2lL|9%h5DWhxdy8V#Y!@5^su+&o&THgz%q@}TQa=toH<LBii zBPYKuDth<MoqaI%z_7qmvYvm;DJa4}eE0z8^)vt+pV_xi0NG|xU(oJte552K-q8}B z1E6<0zo+A%*c6G>AsviXIr2}N>r7FkyL3rp*}b%^Y<0&+N9QL7Ly)1RLR1E(9Fm)> z!SlVi!Ny3IvrN}wTOgpSt$l&I<~HBW9t{p2NG&xjjX~V`7FRUf5U=9^Uesyg7DG4( ziU=;{;o&jA)(?v6Z;AmT1WnG)^a)DTR#A~Tvb(nztRxta%_oomoe!z!--*7@)sxj7 zltzI3@~rGwpX+iMscbS9q97*D{OhkP{;%pELRGV~Q4`C1d6fe>x3#hR3y?;=eLFQj zZ>@`Ip1$s>v&IHC6%<dQMJsp)RM0IDrTknbMn<jE&ScAcW*5P8o=0!{$W-_z`&JyZ z<ms+a*iBF`oJMZ6PoC*<5(9U>`R5PJ2aGtxl#D(rH?6F!)?Bn>z}*d3Y{901J%S-8 zC+Fhg0t6>!+m{DnM_k&%!UE)vYDB=Z+}zyWD`O{^Sb2GI%F<x?UESRen@tWUe*JnM z6(!eIG@b>a-rU@ru&Rx4+|uA@=uD5XFV7((^hcE$`hsEyeIk6s3y#p-#>RVfLLRLI zUIO|v>c+LoZGIGyajF_}YzSc8ZLvauRg0_V;nRtUiMx!vz!-*xYFL@2g#|i#`YPvX zl}M#-&{ODFfExGib%4Ry@u`OVE6PhsN(yoTN-8R7hpDNlw~>*i+nMR<mUr&7WZuuZ zh=~<2eGwI<xja&pl9B>hLT=X_1i@ww4p=O9)Mw-5sZ(1^gHL8!E(P8CF;&zP!6fIt zG*B-PdXKZ4#y48x1TsP^mI82{OJ-&ODavuAd>ot{L-jv!`fsne-opt<oy7})bd8OT z1yWwT@@#2Vo%Ouxdx5XLz3-Aa7j2Pe?o@!FCKc{>Aj`pF?P9ZXa^9(=f(qNuWtlvQ ze95v2=+c%*$f>R#85$aL6j*crV`XoDxIU+upcW`ihIIV)Vj#umnI(P3?|0-vFjbVY z(&4B0xqTFcCpd)^jjnurTwZ0wYsq*H=8MY_ap-x}PG0<35kaid$CGMuI>;G2*AV2_ ziZn$4Iv@CvMKP?>p5TMb(_K(-a_y&(F}nrN%I_&!TyBnz5h|%<WMsLAe4Co<KLw0e zjdm3mEs$ruJ!wx2)T!L2zenp8T4eOhgZ5DSAQp*oKHT2{;3E%&V#&yu+us3zPOPap zdUcLPi>oKM=1>B9{pL%8d=aUqyRJZ#kbXiY2>}dL@V|7fNws}nE0AO9tP@y5Xc9@u zimegv<zu;l4o;qOE`vj?sgXS{)7QzIuN8!j<1yL8J_u;|_|$OPg*)Alqubalz&)># zMkOTJSz21!+J+_)A~ym_Dez|dF;bu(%S%fg#V$j78h~~Jv$FYG4nvy6sgi!I8>y+N zP-wBsZ5>H+ZW2ZSe=yJ8U!5!m>7^AFmKGKoRB*x~7A+T_rq9ZUBS^>m!0#ieZtG$# zuBGmbt^~;^eV-xE7Z(#lp{?S2t&43h9S~vkaqm#IldDDgyn$;5jdQN$Utbb(u(CFq z7wqoto;XEdB}}`I{ohGmh-c*YdaIHO#5z=BN4IBZtgfC9m=0m`=IL&LIZr8L3yT?; zUq2_L#8^WkBNAd_S~|MDjfEI2Hn&Fq5CE4^+}V7hE@<)Nef}fEMKh?s;k7IL(of#T z#)<>z73;UYTkK2;jEd@-ZjJ%ix3{+T8vAl006ji7Cg8PhRdPdFxe4A9zuX2MUHo#` zIOlynK0XMW=^&z3OZSe>$K}PJKn5OrRPIa0CI1Cc6Z(}xis|hi!c`CJiP4P^CqiG( zv?VlKyoAWAf&@5_is<wrIzdg;Za^6QN;|7(&K1y)MIjVq5v8~FLQM{xyU^b!RTA<* z_fC4(9Dh`vj%1%?%0-On?8pPnTSt6P+u5b03{yI{cXs9~=poL0Mt+GQ_YeKBj|SOh z+~z0cs6KC(4G{rSN^0uVPAgK$3yWD)^58|n@Z(m+13Gi?YuJs7-=3BIf0gf!U}SFh zF>Xjl&rEO7(}!k~AS*RLh>vD(s%!nsF|x6?9<g0SU+0M9u`Jd#&g!Y2>R}Iu0A#r0 zNrSWwf-L3CejRsYzw_R4@*5fanls`n4L}P)*FjAXd`s3x-y=Qx1hw=Y>kXaC!Omp` zb&$^xFg8r)(?C4?vC5y2$-gST<SB+Qrdb{u@S`;5_y@0yv53q60XvmshZJ>1Z%ULO S=28L@A<FV<w{p-AUi=RvC<yKV literal 0 HcmV?d00001 From 436a121da2872496c921d01659d67b053ecbd10a Mon Sep 17 00:00:00 2001 From: OCA Transbot <transbot@odoo-community.org> 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 000000000..f8aa6f658 --- /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č <m.mozetic@matmoz.si>, 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č <m.mozetic@matmoz.si>\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 <transbot@odoo-community.org> 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 000000000..91f0ab2e7 --- /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 <jarmo.kortetjarvi@gmail.com>, 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 <jarmo.kortetjarvi@gmail.com>\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 000000000..0464430f9 --- /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 <danimaribeiro@gmail.com>, 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 <danimaribeiro@gmail.com>\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 <transbot@odoo-community.org> 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 000000000..302b2e39e --- /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 <christophe.chauvet@gmail.com>, 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 <christophe.chauvet@gmail.com>\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?= <stephane.bidoul@acsone.eu> 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 e85bb9586..000000000 --- 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 <transbot@odoo-community.org>\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 <transbot@odoo-community.org> 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 000000000..2f9437ce7 --- /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 <pedro.baeza@gmail.com>, 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 <pedro.baeza@gmail.com>\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?= <ivan.todorovich@gmail.com> 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 `<data noupdate="1">`, 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 3e636b152..f84fd1b37 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 000000000..570f814e4 --- /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 <ivan.todorovich@gmail.com> +# 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?= <ivan.todorovich@gmail.com> 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 | 52 +++- .../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 | 93 ++++--- 10 files changed, 471 insertions(+), 33 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 c87fb47d6..0337037b1 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 6b23b71bd..dd9da0165 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 000000000..7cfcc1c00 --- /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 <ivan.todorovich@gmail.com> +# 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 4743afcb5..498d365bb 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. (<http://openerp.com>). +# © 2014 initOS GmbH & Co. KG (<http://www.initos.com>). +# © 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 8d653b70c..05637bfdc 100644 --- a/web_dashboard_tile/security/rules.xml +++ b/web_dashboard_tile/security/rules.xml @@ -6,7 +6,16 @@ <field name="name">tile.owner</field> <field name="model_id" ref="model_tile_tile" /> <field name="groups" eval="[(4, ref('base.group_user'))]"/> - <field name="domain_force">[('user_id','in',[False,user.id])]</field> + <field name="domain_force"> + [ + '|', + ('user_id','=',user.id), + ('user_id','=',False), + '|', + ('group_ids','=',False), + ('group_ids','in',[g.id for g in user.groups_id]), + ] + </field> </record> </data> diff --git a/web_dashboard_tile/static/src/css/tile.css b/web_dashboard_tile/static/src/css/tile.css index 1d057ceea..4ec483d72 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; - text-align: center; +======= +/* 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 zcmeFZWmKHavoD&2AcH#zL4pqM!7W2@7$mrc;O_38KyW7mgy8NH+}+)s;O>4O-gp1c zx#!zncinZr+|63ZFx^$ZuBW=Hx~h7<%R|M{kO`4rym)~oDe+11#S1t%;P0PEuYjLr zDI?v$ub1|U;*b}`Lqt2ki`T{<Wj_LMMWEd4!2_>BHWKRgFJ7RxKYzdMw$3$p@j}i@ z^3z8p7o7voK{=xC%WAHhcZbnoR}5<cisfITI^}fq4E1S4-y33Oeu|=^uU9)oQw;FK zW$0F{b;1o}JU1IbL;lqEYMI-IQ9ltgQJDX&zu1qPW7IbvMTW(jwYOlqd4h{)hQnV} z>q!KnlZtnD>Clh)1(hcqyI5KN{c_RNgGKuO^VK?!Vh5SpGDfYU?!r158h&D%NXC_D zN%DTTD~q?Ba+8)ml_~s+>75BWa;7aLimVH()nHPdPx1Xr85Oju3}otppt-15p!Yl< zM(}YZ)&s~zeo*-J=BGOWvl0sl&BXDZ$5Fsz3)`9fVx)=e0*MB_5q}+{EOH>>`<g}l z!$dgUKjV-oeKsb9HRa!j;e?>Fh9mtK;V<Q8xx~u<jKh_9(VOR6{Y#h-jQjR05!QbZ zZh6L&|Iawu$QRL{;VeJ;azJU=I=IRIL--kw(tmJM<{-@Zy)uQ#8+^0<^dG{{cyj-P zTLOw!2@gNUo!*1F{_Q`6pYbTb{}=8^7@-Nue?uTW_<ZTsZlOsQvt86Fr;iZZ%$RA@ z__Eb8tZL&pqaf+EP=lyRQ<S@vKR07E_2>;_nhSjiqQ*qsLkVf9uu^20<q?lVV2eQ& zXz6ZkXi23>;$WjFi|_lDON!AS8$L-P?5VZ!dC8N`Ia!q)#(O&rerM}jIVWQ7o6Zz} z0cnRW+YtAi#XVAhQqJrdK2JI+Y=#}I`^)JR5o$p$pQ9emBY9iQgAze}oyy%_2zBR% zA5KZ$n1&CA%@m6~&~fiL=KNGfI_7XM_Ukpn+1Jw4<mQQAzF*&O)i~lW8E0S??B6VF z92=@K<~ixqiw4$`X3$}ek|gLvJX2O3&oB~Eq&$<>cb}lV!atZ=(*r^ar{>fpk}TqP zD@%GqocTMUtLL86G^>$^tC_KBCN-zL`YQufs(UP9#<1Xd1a<YM@Ii*w?jsAHQoHG8 z12J^_ZZ-Nx!K(s?68~w7pg`0Q8^0Zn&}<>Zfj{p3DHWhPs7jyn{Be@&Q({RZe5(?9 zyUjV<t*>&)2txC?IzTCRDs}HMW{c$DCY5&o1{`ur?)WM(@S{#x1i=mG5))W`w*H2r z=pNXU?LsUz2$R36AbRq3RG53~(gM)wgg5Ky9BO&D7C^$l)Iur^AH41jpPx4|2tpgS z4mQbZbZt(fYrs9URup04JZdI`<~}`AlkSF2V$q=nFF|t)YT?m{2l2m>V>s+@+Ff>A z>ihwHt=P=6n)W8rUClZ$Km!L<Q|l7ii_e(~1wJVsL`=(|G~PhB?+4*(XT2OeKW_Lg zY1cM>6KbDYjBwec{x)b-L7??y>lB?(9rFQ(IhWk{2hTb4NPEavz2eZTryy@)0EBkb zHW+VjDdVwEWREW|g#ioo?F+;CIanN0!WZNrdSLX-)yPT8!xQv$<gjx78dy;uh$?z! z@&0j4GzziK^JEtNuU+{t*!7tsNml~EvB3X793hv{d}B9B>ZND1Tg|6tbQg9IF8SS* zjEg^5QHX>@Nz0##3b(M#;C_0R@$cV8JgS~54gL<oX@e3M$<<O2!_<Opo7BP-Olc~e zAR@Mjbba{EC0hJVT=djEV)fxWQqE*avG&F)uJlIU{?l2~wOpcEPE8!^8l>ms*y5k7 zhvinLcgA80ucuQPe?UKyj%8(04r#`*PeVI6@abMugXHf2DxUB>lG*l&_pW^#(C`$J zcMFdzvSU*j2Jvj>z=2=dJFSJc?Nz5RgPB{8AE3D!h&sMAgn+_}z;37*triJW3bgot zy2Vz-AKtq@GHCxfKA1{|@l~86p2!`pI@*CU@|MTdG!`^HcK<<jd6af@|JtjOwGqXt z=6ZWx$UE4&ugk#+t(otp@yUbbrgQrx0{nacc<Ih;Ez(XlzR?LxR-s})or6K^w^MYj zMGW59u%8w}O{~CJP;gmfI?SqRa;vcmb$}@Iwj64E+?L%>eGoT$2^a>l#|>eQl<Snf z&hTL9Wy^P2UgFa}VW}j(c}F+zUwhYs--R5;)HE=0^bQ@*$zS*HoZW%$-OPv|X}RHI z&=G9S;+lGd?CXMI+!`E-TJ7B_H?40IzKirLW*;ANe?E2N-5h8eH|I|G=-L4#R#-XX z>eQh8PJwRX+x>&Zk#FB~FZnm%2GGjPjdd5?qIZk68a|YICkm+TNiY1SmkwPIwmU3z zfGwmRcI<6nE5hA)GE^b+O>6D>>wF?ldm7vVADh#&JHC24WWL;tIFY)?Y_bU_;Cz}d zi<eqkhFIXF&fE<1J}htt-mhwu3}`qSvzZoZ&5<q-h2%`zK!#2%{!aVw+?DVlm&~i^ zdEcka$7yEb<d3~{IvT3NyD2gcpLpf7QAxX?7PRE2AGO`w{J7R>^mRXogQfjSHI6pR z(t7uYR@>==61wz3#vo4(8K78gF}Yr^nuoF!nLC;<Z$0x<r5VRPl1;L_9g-B4XQ;o} zeElFUD<VWkeC`&hDeKdow;G^D?;wQFV*DGeWd2gYN_mFrFd*N-XR)4#z@mvv9)-~! z;%ppvgK0!1{|Plo0sA5_=Dq%^c)3d!7MQY3$O{6M2vinSB;BpvS=zRq3QS=@57Z{e z<>QNI7C0=pPES`W#mHi<kvMRzLT|v%qkR!G8FYO`!Ahy8@=CNL@-3BuE;on`->YyD zX3+tXRC5-h1ZTGO&F_jVaxT7m7_6fyUW9?_ndF_FESQsSPCbV)20KPYXiER8ERa`i zDf6;Cq14*pDXY*<QY@l<DWAhM)*D4l#M7aC3j@%$N(P9Iza=s20b!xTNOl60HXejN zTKzl>YckTtg{`Kw6~pZgg;S}*n1(SV#dBYM7B?Gi=VRG@{af8IPEi2x&vTe1hbVdk z|L6L<^~y7V^+$O=(({nvWvw^d%GbzViFsEr6}B6w&N%wkRp<w5?Mp74iD=KSASuU| zC;W?cq{3bzO+ZOKODV#E>-q7@l!OYADC1AQfEdMo@+7-3V7Q-2J+cNw(V!M~QvkP5 zVLch`GoS6Q|0}goz?)*fPIx<VqO4Xdd+ma0S>m-9+rb5>M)<%r4!tA3bv!Tk0<Gv} zUA-Z6o9tc>c)VUjh@oHNNObrg?*~pKh{lCByS3wRrNuJU!n<3PBvJe-^s|Czpx<!l zgc=?0UAKC#QsNyTo81E4Y0d;`?TBFQ`?B?GaT)cGKd-)6-J4XiOz3Iv(6ub6@XU%B z4Henf^jnU2{rH|G4|eFP8&l2P$7+ERh{L(2&?k(X2yexus_yx?S)burO0lS0etT!W zHbe+Dd1ONJuc|%SsTX?MTkK#?e3UdEQdMMdC+|Ex?4!8W{6zi2xI6mYGp@d^Cbz4t zE5StfBjTNav80IMM-RQ&M+eJ=Bq8T`8HCCt4Q$=Hh^ADYtD%jX5<M&W`U}=1o|>WM zt>MS}CGn&Ww{LbusheTH_OX7|vYr@!;hES_jZ|(Mq8BKcdb#gyyQ8Vsuk-!4CkU_x zCm6LAK{(ND&Bwt#Q4Ub~TW}+}6fM*6r;sdrscff~*DL#Krx<34=J`;XG%PfyW!oVM z@J99Qi8YuhhN(;;M?_G&@&>c199B?#^Tw{YZ6RK5(;tu%JH1tNExAyTTU5G~qWG_s zABY8L3MwEz-5p?Ke0f3{dNEV3n*MB%Y~Og{m~p44Zpmj<vfoc1us_u=*8A_IJ*fST z{;G~i8$X|L**X#lYMCutV5!Dg3kWxU`r~Qz*t~eQED5e8)%@dVL@SCguCeE86AH+O z=SB0u&BIMG;<6*<Up=cm8;`&NnC6z*+Emg_?+lqI>IFHm+!U?*>(auDrWU*0aPRj8 z0V%3(Iz@0Z-g{pZ09?OKbo~Hb{WUU;c{oFtZN<6OxiP!4%|@+j2bz8rnZq-OON-Al z|H(2Bz3oYIiRy1ILU1smfPa*9?I5atG_ue|Os@~8?dIs{ZRMWst+h=1c*g{OGEYr7 z%^M=gFLZf*k+<C{&k*bjR(3qLbE1TupB3lD<?>Pkv&Ag^$4U&7C>(OflEZ)zI)MoH zP}6<zu|Mo>Bvb1dQ6ih^2#6LM2*Zr;yQ~RHuN<S+Hnu5Hz|gm28lDbgae^(pD=~21 z4}4`5RO~RzexgXdla-N(lRx)TcU?AS?&Y&$W*$zaU}|Kw>n<gz3eLly%+@n$`)%>C z7>@nIQG_A$kTJv^kS+v`N&R$4X)O{H_|Xrd)#Yk)Ic%TM{!@ZRglZH-J?wpXp0Lwc zRVX9Q3RbFuGea+|O%S+#7+Nkdb&|<<R|W^Dm=5nmtKQnE>?K_jifNqu3tkx(;s8;T zIyh3yoBjuTFNqtDq8S%t_N=tLM3(!_04f@fXGBV#F;oTrKcrU-oKxPoupQZkeTD~& zs>H6&A}C#1>ZoHgZaKTfl))fV`j{UvTZYg967rc09FSH1u)$7KR4F<AcEN0--I9lF zb5HCI={@hU)}c8ZqJL6)c!%}06B|l!FdK0vOnwqQmxramCUKxd+f%ke{~rPI`Yx2` zoNj1x9`&;w88JM|Jt7l7&uRv&kW|cGJDD2{+A;B1L=y3q8MyrZ^L0bk>H}BT-}uiz z=a;B?w;@?u%6z~6w(MsR%;$BSzhmS3TZ9urOVFL&L7rGI(55-z4B7aS>;T#6YfwxC zOwx}3m>bl@`##{Rv=|5CG>1VzH%qY~Y@8#FQ8Fi_C7L!7iIZQkQYV;4{Onk0ra`g{ zGz6+%!}I1DG+P%bm^_KpDI;CE2_HfBkefy3^vYD6av;ETSDOZrE#DdFgHlmG*urVs z>bvP5#{~OtTM*hoYFCoACd8T~=#Y8XFKp4Ujzpgo#7@P8C|(*Tr(;8jXtUuZH~_uN z@H3R=&``b&ChwIZwa1+fmjfPYuY)4Z-UUZ@w4ph`8}DM|Ts<kEpz)At*)VFy)+8g_ z8x1NxKP~`jk**SxP9NzO#^?V9H8Sp$jYbc;?XnAsowA2KN2VlGj*y<4omGD+Y!t2$ zbrmBQ{o5zbky(z70Grkie`xk*$O+*812huG3I7M$Q^V^<?&wh2_`?n=m=T0SKHSFe zty$(lsYo<`&s_B8Q`H-t!Y&v0M}+*ZHnH(RBC>!;w-nFDGlZb@#QEn9W{3+K8^7(u zIq$=q>M87uWZ{k+N6Eps<<9$ro6`I0Q8XcwDa7tP;Elz}T%1$t(~gZ;=Mw3<#>f2` z*6J_JxTcx4oDvh131|G&**6QUAs7oF<%5<2g-Y61gDO^ptMCWJtsvN1M!!{HAmA#Q zw*ngK2^}FzpHdTHr-zP`HPdOte4&iE307kgww95(H=sILdu`%h`)(RRo9C@1*d#6; zMUyj0)ER~?qw>zc=IG53+Mnu`XidFB07O3z*-<e<N+eelm^!DyUAu37Zz$aH3ktlk zS~zaT->H4kgbKuQkHa^sIQ9@_z7;T|Xf#hzHgJ?S(?>ldp6~cW);*VIORrVP$9HK5 z?Wr$N0B^`{eD9?_(n)Y|f0!-Pobhvv%#2!_d#_+ms10?~lsWsOk4swnY*k3NOlh$< zE0Z&76#%oz^ZF`$aCHH*DCTV*A0PE%__E)1|AgE=)9}|3yyhqc!BtOgP_~~{i4fmZ z1mlSOC*^OkxjZ43E%&fD8P`6<if)=kaDu2~ij;;PVIm7iCUH3VkAmsJ#nZO*wJM;e zSlVB+mE(>O3o_1M_qFr4_g`5{Nrv}=B2*C|V#xYDu0OmjJZXfSh$F`4^NEr8bKfe8 zyr3=!EAP7th<=wiX;Y;5-jCy_QyughV+TSeJHgV;&G>g=M3IyczL;qOe~Q4ehP2sV z5y)e2r%z}ai^hB_^0HRWbmgEuhH+OQSL&d`Xk?zB2owU0;12w+a3hgn86U1FwgVRM z@%@0w4n-qiyoCeh9pP?~Qyn^;|C+ZM#9FYbL3It6;b$}sod%T!&iFjcj5!-WYKZS0 zh<wAjEvBfzA)@_3MS^mJzu&FZopD|*g=mFF^x9kOnTROBeAUdLRLXZvzGmF&AKrG~ z^@a;?$ll3gRbRiO4`N8f533Is-?5BC52(Hk+6eHu4mY(JRd#+1H+^Edl|khU|HH2h z-tfBj`bEiA7D{{<;cjXfSsUJLp>iX+;2fIPEfj*kAyITX<>ISDI-(uf{B7;S%f!cC zEk2{hqA6e1_f-f$i1_-1czi<Un0UNN`+T<X8eF-#>yQ$8XM1>CxzKTldlj9;Y{C;> z3&oN-dVF;xf@}`~;-38mlaG&vRi}u~%~{ikTD48$jG@!7zuX!h2^p(fZ$bEM4n@jB zb*guDhS$*Vvn3f{Bo=ah^yudJfO8sd>PX;unKVvcqtz-Q*AMzb8n<`~{b=#{dy{*Y z>DJMWR1pwhjhf%VRP3_ziI~sJn_C}qJIy2)*%#T~soyU>pPwTMAcGCMgBI&}AeZ%D zq&>PTtqC4h+b%gQ|L{JG2Dg55Q!Y-qr*jHeLS3kr8RAkf?%#l+`y-VIlaHJVyih^i z%xOdhM#*7%9UPyXw7@~l!kSfLm*avN(FkInJ=+D}WsW@f7ri^uFP2$l2VXC<9?Xj} zBh!NI>YzP=b($$hU%MY?|4gvSxCQc%O%HT@LgBz2?a24&JwGOD6qB@|d)FywHFQz2 z6y*GVWS8x*#hP#e5}FdZx<~OpdA;X+<bOA>_uoi#=Bx%BBcb2u?4K%B_qJ2rBN|pF z5(nnQA0a)^H+C|*{s>B87JBQ_NwG#Bz;4nnSJHIbN|@fkM3Gono$5jp%wN}EUW3oB z%VA#_@U;B{|7>A;?He_}5@|#aW@L_2tr8T?{rkGYDy0TJm&BHPW$=Um;JK?Yhc}PI zX-Z*%aetxl$0@0!W;%o4x=yqnq=YwHiJ9mTgIhs)_X`p7ZEq`8#8UT1q5mAsPGD#} zU64luaP`!HB-Z0Ni^c%rSp}6B)Qf=R=Ps_%Q=XPb29og<z7f|pWuy@j1w|yRiQ{-6 ztS=qwek9E8IPJ&i*K@g&dVzNKvy<1TFE{lZjDmgaqQwPrJ<*Ba#&B28+1)+sx^@a3 z$x<;)DsYg6;wNdX(YW?m=5_*tR^Hrf+0G_~L%QyMO3{FsZ>?Nio$%7?53+!yhkEGu z#^=z1wH?FEvCw~>v@}_H77FHoL+mGgJZ-vGvxS5^UWw!jg9lI=20or_iFdk+zsqod zs%w606agj*6u>6U4tN&}jU1~-K@YEudyaUtkIS$};Bv%^d`uQV5A)yK)%9&%A?kO} zuFEqht#KDOdib&5OvR8d1v5GI9IEx_O+-J5=G|G}1=siQvDfKkiVnZkaXO;NB%r$J zt6QZZ{%Sj4if>JFaM~yo?fY$tO*=t<rf3j06RbyGp1vyS1Sw$H^`m(=`(X|vR!)K( zS8wvdQ<%aXL$!Li7BAN+jkGr2UO3K*fepZ&H$9tFC14k*Srf;UsppcZ5T3UX?BPTu zD-asr!JNjATiuDP9S2xU#nf&b<&?Fq?LK%QQ|G*DXN1=DIh?<$iD`a2KyVIQ$bN_6 z@^wn2A!x6fm6w7J)+wTl#k?Nyc;Tf2Q!SxP(vaIH2A13}89YV+yT;w{^|E0q8d=R- zk}PnX6$Cr5QfWX-#>5?X@YQOr<<_JSQwu^~fG6J9t8@~ZS>?$BdG#t192bfFI|^7` zCFQAbiZpwf2!F6L$tT?eO9x2II@oIb&bA8dvfmKrpL(R_{tLJ9<EMIRj3`ULuS(dI zIn4g=44C#8PCH6_;Ly<JD60dfK;|PWWxK#^mj(W}WaSLijE`31RbHLMjfFUF%D?d3 z;;MgLy*h9J5{4`S3mw0nB9q>5knW7()S3+AFNE$U9rq><gFNl?Xyj~}NvT39h)0Yh zD8N_Qeb@S%Z9@r0Zm-4_$MnNoR7;6-?j2SFhI)-fmqxEbgfiHV$Fr!|TsH@*a9I0; zL~KYGWy5|54`$H*Bs8U3Rew!gP((?kRQvto)9P@Ch0IY~=URsKVyJx|?TO|I&m?H^ z&J2>eXEkf?jJ@@1Fj7nq6Wkao_o}n8Glvv0J2$giYDL__fDv?P$x6lKg%Tk}g2d$y z{r2JK5;kH_nk?h@L;Pv0kcHvEpNMNQjy9U8EH91!&Nq9jxLSqMx{(9Y?u-TD8GRk` zE|nR;g@KRUvR_{Pc9Zw$OA4G(q!8j>FYhU*LtH_8w{uB)*>ucpP#nS^-yB6*TN4<( z*7pL&8KLUOLw3)5D2Q~XbBt@TJMj9AVE;~ggynNJ$8n|#Zd~TSM9Tktu}`K|)ZBZt zF_+|Cuqj13MSe?Y?=<%k@@P{;kRl~P@q`y#11wKPZ);BK3zMW<q0T0Gsz%yUxb7T5 zgl#kCG>-YPef+!lE|V8t;EG}JVu^0G^xgU?|4pBZTshp^v@;azd++57h|t;1^09t< zM>Zy)5ig~3ZLq|jCA^_XTWeCX>|Bx;+)_e4rL4-zT}BsSsTv-JVfsm6d9kRDhX6%} zMY5SKgtRQ`!1CJo^ZEMegKWd=bzv~>k}siWw$Z3qna-xliHmD~g_ddiLFvG&u%`SX zKYVz=@*FaL%l2=Ro6`H3NMb68ME=sB+W%#W{I4D;esCM%4VG+Th_K4{AB0YDc|+lw z(h+yKLQ2!1ywW~#9X_ULQ8VKggpwj@nldh!zP)DjKneu|DcMJ;m55uq?L60Bk*T9H zwwxp9l>@|=eA?sNhU~AX8{L+zd?bUoo?JaHt!Ny=K!)(RcOF|?tvmx5hGgs;yks!h zv({uy+arOigH)v7dtQRGYB;)h2~8;-MkUN4X0Zllh@xjew5~Z2eEj3ryTr`ONEU%H zIm|B_`Q;qqFL}vylx%{?T-)Eh#iMt8<Dw!-_+dXt+JX{&hlrk{c))L9HO>tBP0!_< zhJUkstfm<$P+uz&sYLl$C04UagfuP^{*nCdUX_gobsP1S=#*YLePL88F)L_a<bA;> zF|_)RFs%Ndk&`cW-{LVB34<<s-Uz7qSqo6c5FRQLFbXNk_vzS~ule)GBCml<FI}{a zoL1~Z1UaQl0)_2vv4u&oVr?AW8*q-imiT5$OLqyU3BsLC)IjFI)<lrYBp<<GGn+vp z7z=MPboabHHB|ewp;2u(JfO5E941H)MFOvTlum;icv0uiHp-9hXg;eB!fD_DX4ehL zI}oDyKEL2S&Sx*To$Irqm?OTT`id_Mr&;ydhj>6}o$6mWX`z?fUN@%fGh1L+4$j1K z0AE7VgSJ|D3*A+3Lt?{U&Frk@COhSC2J}U^hYKAAbqX_$b&~Rh_eQ!>qaKw@IiKj$ z)231Y8!@gUFDudk$u<0ETuF+@VS%%^*OC99tEHPeEDyP>>?c9*OCaCY=Tjz3Dl)Y@ zI?cYdl*Iq!2&Kd+*CY+*@H6VKqWEx+IF;uhciGp!HV}F-w1z^2^pp7KJ#w@%)DBK? zD3|_sVJ9wif!1&LiocKXT-C|f60c(>@o{qE+fK=^A5<Sc2~uPa*Bx;i8!hs^&NdRo z-&zZ~-@bigT2x$j`Slw<pYdnCuwS!u+;AU$AWbRMi8r2(@tEW+Fx$LWhRHuBjk9k! zK%*MZ?(vhWXVq_KsDXGuBY2wxa*Dr=jUEH6Y<<?-DlO^B`s&_UmF(@hhHt@lP2;~{ z{owOaM+AeS%dL76kLjpHL;_dtChRe!WX8QOWkCupyiJGcjofOxn53TU^29&4`KJ~T zCQIHODQ?nQp*#uy?yu5HWwtPDu%a-DmYOY)sz8(Hp!xW$Af6bKMl^qglYKHSzPI-K zx3~Kn2rbNKTc7Ka5J|2;C`<wiC+lc-npx4l6R3^hn7mH;4piQP+*^3#4tsT6c@p1H zmMkzgJgPiv%pF3(FYi}}U9V=J2Jcv}yy#Bc#Qd?A_Osp-!ZmckB6kB~1JG`Bwpe+R zluw8*aqjv4c2C(zP^iZ4N2M@Z%i<j&7<K0pR)xp7ulF6Gz(<Yd?FHn1<E3@mEK#}H zjwM;^R#B{^e^!UW7#ziv$mr6K^R{miV$|atA!!GFuDEz@zg`n2DV2+NHtx3`IX|Kg zgxh9Nr$oxY%Ubkq0091XzAMa+DP?5%$&Iw);~}H_beyq*T!R@Sm_G)n^mG;`;3z(P zqSEuP)-Pd8+APA^ZSQ49==`Nb_*Su893EW1*U_S?K+E=Jq7<t}H4&LGSe-wLD1Rp) z@j{REoi6%?-LtPo-`faK0%uZM7+i`%jnX$lk(*^(ox{j(7&4>KseXRNLyx(sD)5~x z^HHdGMB^R!axg4Rn;m+&4(h{Tw5UVl9HmMi{=Qs%V1SQ~adv$5CIvHWTC-}g$EDG1 z<kjK~W;*B<a6<V7g-SR=q^KGqrF%?sLiEz_-h5*B6}yeAyBrNYQ2NTt!q;WpHf&`d zi>#rI*NTPkDPHM7_(G6=@YSvLk3q&9&YH$W2l<w|-%E#{=gB67YevF+De{IXnAytT zHt_EE0_bqWHUb(Rv@T$giSj5MYo}5P0yxZuV}`WWo86Be=9E(~%g4QHe;GI&W6iEb zsD+$qDW^ng;S=+KmDIr-R1&XyN3N$q%G41(AicbPH>iY6E<B;FWV|7TZf0UO`#&T` znoZKVgt^}ggH}~)*SgNTR=^mD5BOVJS?*RpIX?VlgFtipc*)o}9vvZZ>XbVHr4xq4 z;MX{24Oj^x&}DsNso9n^9R(?E6=z80$h-H2GP2+R-Fl!Zt2_njon#coc6s7W?_-dw z7!v-MeRVr;b&u12_q}=LADrKv!XHQKOf`5aWBhVgI;rad=C>K>*&A3Nyx-xGp0TZ8 z<Tq0PvmACZ%Kc{yd8A(HUs1Nj5Tas09BY33;)h7_!l7#cLLWQ!5k2v};F=*yf~xiq zE5z$FdQX*~St$-qOdo^<Zr3?Dv$@HJcXMmpN$EQWAq%L0NzLCU?vFQO8e1yM;<!ez zK6=w%<<doN;Uwcmz{>Y`k^q%sO&?tJn9d(YDJWqJ>7Hq7l>gxv62Us7e`F8ghM%Gp zKLN5ncQaBUOcFpKPTSb1uQ@I!l+~y|i+253Hzd4R7I;JU-tb48QFo>@R)xNfXR9!U zU{i3Y%k{ZR)hz3uRg@QpQoQMMJ?))Bu>0wH(A<{@{H?-$Cz4044d-Umzm?m6in3i& z0jn54KF`N_p>{~D>DU<TV~n*juXci?(?w(OAH0aCV)q?^!zPAwg`9lU&R%2z^=|Os z4y`Z!c|Zs(;O5>9Wt)Ed-KcN7z_TUAeT(gYnn?O;Dv>dINpt|;^#UF)?3%l|*2nuR z>re7tqwYEz;t1<md47cDuNowo4BJuPe|Ob$$Ua)%O@}`%9*RaF33drBnchB5kd*X? z=po}y{x*^K+c-B|IUshAN`9B#sNY{n4FJ}sZW(_lO`<Lgr4oEic%pawNL|_5m$WQT zNQMG_ao9zlHw8p8D#@LuT+>nCX-gH{5FA1-geE}BymJhn=6$Mp)5Vs+xE!nmp}vl` zhr{JI7`w29PdB#CrBUndi9;v8TLHztMiodr4c}+h7{s~dU*?0r0S_|$@DoLuCThUy zL)D)=As=zhc3w+mVXRP2@GyUO_zNk;nj6?e90tj*of;o8WnpQNZL~c;;9O-mK#q+0 zgOxt=+7Im|vIwWfWXQbXthddHrZQvwH#iwaSON#w6(%R1l$v7d(E<cP1Lvh;yd=@y zimmn#k=XLn!+ef4#@cF_&egg!P#6g7g`co|t|edmi=|x!lS24(5<v1WqgWcH35VE9 zikynGE4(M-JQ`jd_@fz}3G~}>y!k6}4cC%1!Mj83Bs!r>{o>A(h-tbOO&arvX-mxc znyD|6pVtF8k$}K5`1T0rD|HL}0pl5*hY#--6;N4WJQ2I?y}NF)hdk7J&DKkszE(y0 z(-LN=BRPq#bW|~B(c@=oTW_AP_LOwdI@Y(KS%K*cH@6?4HRamvpvEh{DEdTs$d2<{ z;?ZQ@byle~3VlYD+1q|0SvuhwFb!Nl9*G@De_dvUmiK9{!{3m1tYhteN2&Q>XzjfY zMRFdkIfNIb6D6R0KKVN?u@XB#9<|Twn;AmV5R*P*iP~Z3*Cq^jyv$4ZLa`-?JHKcs zvzV-2wx}IXE`-qE={zbzQLBXH97$WDFQf}(zvPBVJA_*I+$nVRihJtruqy9gX2;ru zqfYC(mzY_=byhqx3cOfi9lQ_t1tg*t)qP4M+vP)Gelc3<lR~XxZuj-uF$GP*<fC?F z+UGM!On7a?2EduoX13}osH+<2f|?9c+aezS2;Nv06{@PB=%S4w{oNDlKt`bH|4e}7 zp02u3pF*CUsisi1_7(nX=g}DA*|+laNK9>RqwOcn9o<YEa*xi6Tyt4jS@8KlVJWrC z1A~Dx|HpLs)ZKk=>T%a5lUp*ax!(*nuwSwi0B!@XUrZ41<Za4M;^)qf(AUrShn;tS z>g@YmlVICihx~_pt~r#1Fr8|oQc9f>boA`{ty2A85v)NOW?_3<4_AC-GE}X7#|i!> z??$}9=Lqb_MxB?@ONBG#2`YC;dXy~co(0?96<;;K;aCD4LbDh6*liMD%5STq8r91J zJ8nKKOi!r*(NR8M`%<CH?kBnR<m_6tanHLkK@WcQBhZA>x4XHXv=1Vq)vtR^aaX-7 z*4`n*^4sA)>Y!ta`PR&VddE4x9!QM6rjeUBY3~ovg1iCAs4O#$nZC3A!&|?}?=60> z>#z=;*P-6{m-W=B_na8YTmKH_!Y-0W{OA6&gYP^f8VKig*K$++3~nvXoGMgIhe4M2 z4Y}xLt^i-kk2#j5rWIVsjN9Y^3M&UrkX9VE`EHt&mRqsU0=`vfKQ=&x)|`_#YMNqU z&@Y}DZ=GK4<(;Vv8*$R-w7|w}d7IVlgv+=#UQclm?gB$8-&<z&f(nCjME|F=?|)hy z|EKr!|HT~f|G%1H{~Jm3|8E5HqZEgiWS3r0GCrb^Eqo-<GA?Zx|LBqkkxtx)Lk!5G zBOUJ#Byc%TmscB(ViM<=Y+{gxJwBYw3U4Asb|HN!Cw%F2zkyo9r{16UsbXd03U*yM zj+IOF5^xTLFPC=RqG7!J0}03+pH!hz-8&BxlX059eOT|qu!QXh$<CMG{FJk7<}SA+ z{9W)9XchBx<(-mKCWj}~|CA!{yee7u)yHopjnQM+YBZID<3)_}pzG@VVpxa)f}X&w zQ~2U<0aFv8?pSC4MVnRlBM~>8^EG1~(7K>J_@|QFP#IMobM~Rr$|>|RGySCml)`WI zE>ElT1^mg^hesCWFjNy01qaAtXOV`tDafh(4I}%f^;azFlSu?tBpjH7YjcApNo0fs zKE3%<L`zv8Cn2qG!{gs7wi+lKGf~A*5h|mp1^50tWP=0wP3m&-rXSMfrAOreW*EI2 zbbCV&TU?3sZry3c$y3t*nR3FBb>V2_Zd=`*!vFrCw)e=l-Sw6~Z)&x5pM5IxdV4TO zW?he98tOtZv#C7L$o*ie@AWfCiGW!}d^?-Q2LX=<>`+!40T&Gjr=u?1c6LN1l}Rer zi1!uawiF>YfVleJ!Ee*QP<)zTC@s)X#2Ni^`*+9MxV<mF0~H#m#Xwm%oOI+H65>!5 zYZ*)KIv9-KgU87Kw`NZo=u)rR)ZJ4j#3HM2c3`zdiAO7<y7@6XRE7BOWMR8}0WlR_ zU^esAmYCIfdwF`tC6;#V3@mggnv76!0yeT8Ywa2-pjrD{1?f6-z(+Bk%k<Opb2=Sf z_MED^-rkd}g0z4Sv{j`psKbx|G^$YECKG&Efk+eb0$AWI&P*17;b^G)n27MY^m2=D z0{LZHWu(GC!vX$$U5bJg`XzFAh0qqT<x&pz!$*pcWSkIfMkd*~>M#9?2eE1AWypa! zUMCBLMtJ8`|1x1hUFv;oaw(0kW-QnSPD}=PO+z;st~NiFM-n*50rk@6`P-qA5~vNf z<WXtuEjdG0W#`aoV=DQ@4CDnT;|RE>)^1WZR=t{(N@44H;KH{1LT`}5>Dz)|%)kPp zKQFSfrKmwIt*p1gE#{rV74;pozq&0p2bj30BA+9M(U?JVNkTQbwLmdAV@X`<_^lfO z4%E6bmUa+c_TG5&WLV_TO6WHksD!l_slMjkATL=M4}sjc4ag`Zva4ae)FjyvLRjJc zlTn0aFMy-VhFrXzD$x-#2ORi4of`%?LCKB!$#$pr;@-=$1g530E1YFMqw^3Lr*LR~ zHNOlu?F;YNnB2Ovc$qfKmrV;~7i3CKRZ)|GNzudK$ijbL+KE2vyIE|HaR;W;gif)< z^M(k+Zr5ct5Ixuo0cyHp-#x@oqax<|@l3T|M32*uduTo={4>%G1txF({pe+7pBw_z z!@cjfFd-2@E8x15!}~5FZmIDx-C9l^SHd6enPiUIX^ZXH9yG#RPW|<Br755`9@LO! z;7xZ{@L$6sVPcpWj|V_SL~GaU9J=tUwGke=ZAN?jSB6j1ZQ)(nc(=*(_QzUVA^M4H zudtvo;BmrKlE?LrQBYX3IL-|6t0-M_Krs79pC~%QELx^{r+T3l2b}*7iylYvvnIeP z)wQ4&L(GGG5*BesfsNQq60{x3&0_VTj{bTfqe9U!ue|);>fup6fK7yh2C#}WWo8^0 zuqGtKASGZem}zB>Rd@zx&7w5ypZs4v!=7B`c_9CQpFV(zMt2J}$(<&-5lTeat2EA@ z`Mq;Gbqp#fVKkKhu#c_|5TsEtH8B$nyORn$2<#1Gs3X=0eYvRmXPbWDz3<)mX;as7 zqUEt~@Nh$BKD}dfQI!Rp3`g~*=d2t1ZC73Xf=f0r9&XYhr?cMbo|cj#&k!)U#Ja`2 zaha2v__^5<+*YRtX@~{IMBIQoE`lT#3G(756arz0Ee0R*`TKPs#OYz@93;TXa?AZ2 z19&0tb^wJBqq8pi&p^OjJD&e%+Lom~a8ZWXgI--phh4TEXm$%@8a^p9P;edOKzpXy zwxQYk`!v}U*u)wAi2rLG0E_g&qnd%PBq@8f!4tYYAUWnuJ~XPtu|)UjA2KXL3#aci z@2-YlIXY1OOKM+oG!hg)PLP{H@r;SZn^-8FmE!bf`QITx9v%OE*ANK`NpCvXgxfkD zr<~;Wso*Ota%w>>gO%b3&RDWH(AwAqG96qMA!KjkCM#-<hID}%TlZ=CiI^>^q=(N8 z=jr&Mu6gwGTR$E;nh9IE)45_vy&G+v55F+F)*9n6_S=rlp84`V-5NMYbp2p~Zp&^? z3c+Tz!GFNvx_F~nn|NB6#pBOh8q>9sNWD^JN&b!n`YF?K4|(xp<(@U~&^{5mtOqQ~ zcVus=PS@<*E6>~7^>gKZdg<L9X$!GtaSz$A{8_ZxBJE!nGMpEQ87HD<$_*%p+vz&! z(k<G5-q<zeEaUOXN$fAC3L!dR;<Jg2>Fb<Q!i7_6m#3cp3rPE7qp!~UyKjt#Q|Pp0 z=C!097EeH25Zrs7$#))W{j;eU48cuh1H&YtJ!FL(FcY41;im511Tjy|_VA-2z<AUh zv&SFVUS>a?TcYvZT~Qdt4=j~&#d|U=uXBHnX+kEhAXm+7+b4F{zj@bx#T_V<W^F!G zRB%@qG|P9{MPACj|E-ZNSLirZw8D9R(8vPzmbkkYNSlRRfwXtZNx`nBO4(gnW8Z*X z<+$0VeJLc@J)7))o9B`?vT-xaW`4i<sE|ZxFG=z2E#vf|?~{l2^?^4d$7|YZM#PQG z2A);F?sUyQKFkpovtQNRaTmag-Q0;ji+|fA6ZR()3vl#~-AKd8JVT+ty^9mU^v8Gl z-z~k4#hy8jeEa=3K=24DGtkV(_(vsm*t09tOhx%WUh5)^Lq4>yiD^7X5|%gbBk}WJ zrm~JDb5H}ft}c<9SaK0ux+Kg;63Mp$w44ZP)ZztjZ^mStS9HQ8+y7SpfjtP+ISF1} znaL31KZg*gLLP!XJp-X+&#oj%y4PSb;|DITQ!yj_;bbBQ!wcY?%);MH%x}u@Eo1PH z1hJT0d&qAbyIE84xUVT2yi+;%*xOoZ>#-3)b|1Ff6KXik{-m$XnXEOoXuHJ(0X;+c ze9T$bZtqEvp&owAzxkf|z|Pp$Rf;Ae9TRs`Fcz|&Eo1cfx96UH)qb?u`F;gHpATzL zq-$C0lU~S;ghdW`M&;(l;^eUNTM8s1lNGqQCgyw9RQsnswz|{F4KmtCDoFTnH~xQn zSBSfP4?3sFpwQZT#B(y63(NzO>mQK!wWOiM`&+;)KV@F%QBLtAUfJjEC?KlrHH~HA z=1rT!eYb1+t=MW#{LjVaPE>Bv`xjxXeb8;j|LMT_=SJZFoUS4P`}hCgs^Nd*bd|Fg zP#kZO;}D_EVS)C~70ZLw6|GTqnX=HJA~JaF7K4iq<>r&N=&;ll$M!iup)ZtbqpDyj zFP%n@sU)A<qf+Uzr!9@o1U*??MCIShb%GpcA_)4#uZg;Oq~eX-B3x76^Fc|#{Z<cK zCpZmu)-T^7{XUm(9L-?SAp$OIsjf;{v&P^>*ywFZM@;HW)+e0&Tv}5}P3D!t7w7#+ zV~GXiuz*DV=>j+@tMF>DY&tv5%Qk)*bh;3n^r64V`?~+G0g3x6P1Iz(5ABqE?GMK1 z=A2FYGsI@CrY(A9cf(n8oIDh%yl%He;pZ!pt*N<x+jQz<TuQ!=;bZ+22XcI94eLLS zcsUHZdj;*87C{qH`)`!#2w(<%J1X?3JaBtZ66wWkHt2Aq;_eBe@vg8^VhS2A?Y`@F zreV$4UPInoR*od#bmn^z$IJXhj@(m(2DCKmJNI00t-e#FrTv|ZY>G#@X}|EL%Bpnw zEGw|>z3f<AM1=yRIcul*mOq)gf0GjdB#Ce<j`Ne5j;$^w`Q1Uz@An9ked5fVI3IQ) z2L}|ld#0q8%yOuTzCO>A%Tu5$^0a<oc93z<k=tx{Fn0MO?eFgcXph(01Cxrp*I0Lc z9{;25uXC7}c0+Rd!Hcm@vgL!0QCc=q<UY9)#htjO=&R47rBeD~i~ZLRHZ7cnp=DiC zn&M{ffXZUvy@hi`YWn-;JF0^0)BXF49gz?tm%(1<oXr}V6rOHrUs4Mne+Ap?e#CN) zLRI&1@7v`3Wwecj0|P8`*O_EBlfp{J%xd69u-s1}9?57zczEOM9AVi6X9(REJ2beE zr9qlNKy8>Vt7j=LL^(vchS_sZsoQ@}>0s=0HsIP0)~!FcmhyCemQ(xi6*&InE6FD= zu1xyqF%qzOV&p;&vXfm$oEL}f?x!CO9=_^lSyBif3){_k{m81-`ok?1rcj3QpciNV zU60NPso>$OV}O(hsYQvLzFvy^+n}wQKe%*p<_Xnk=egB<>Gac5BOb1Ks%lAF>z$~N zahf!x$t~+MlWXzACrZ6nfRn2vO4j3*G)jkT`|~2pojB9z67E$ty%nxd^s)odPc$Ty z)n60s)&*I7G7Yi#d@!bhoeBY3vDl!G#tIzPSrxiSXSOa^e@QeVv#ix+SL#vxGY|zM zq8C;ifsWv|LAax%*{KeGdibFQD5T60^T`I#Zn=aN1am8RDKLE&>7qTc96uUqO5>i3 zyZ)lEPObenWlk}iqelCqTk>m?q`Z9XIjOeKNPxVP2tJR1`rp2BTsS&w3yDD>9>{i) zO-NvqpDnta*#Yj&2xLUCmdX-G?C9Hx#&%`W6N=TdZ=64T48vi_nO<({4wtl(zA+}B z9j`zpB?5<I<g2^gK9`BL_h%Nc<meB&rvq#yh2)r4oG-sbO}>8Q^-|23=ngmL$<>gs zl5=`IQW?G!^l-puQ%eVwoqu~^jPQY4GjHkUh?kx3*qqrCkPjy|iPU=@ORn23&dzb5 z(JS|u<j>@dtiyY~3Ii_eH}9t<exU1+5NUh9OxwQz<*&3O;gM!hFZAJTSnx;SWvq?t z)bd{4vNF_fqPG=!dgEluC+E*)S-$31`ZWms7ERx~wnbbFrUARVz{jZuwQ_=DSKpD1 zfrSwA{{%_?wdj+(&6lZkjDnvfM9*Wv&6tlNaE<yh=>E3bC@(L|szGtVZ}@Kgt73_h zsWj*S8z_$a@P0&pRpE5DWnT>LvGN?C&y7Xs3>0;Z1xjd^k?Xjmo(J?)O=*ihYhj~r z8_45n{`4GqkqIi605N2T;wYD||NNT1$YP|HYe1u<v8mkw^}s0i)FQ@Se0A&ylW*@X zElvgZjpG*TOsKCgd|dILGOgA{`?}*kQkECpNy)gR%tdVulfL#?Ql0q}3@MnT^y)A_ zn3g+2SO9C#Q1yzIC;?T`a9jIrR*u}WDH4@xB%&VXw;^s{y+$rs(I*cqCci1XJx`*n z(&{;1#Tyk|LLoKhnjG+FI>>OIj~JiO#P*J<81^pGoP)OM1BI~zge;xvE#|BG@YPPU zAH~6Kj+E7ws#*a9^R>>1C+k{fcY&JT_UJjo8(MFao63G57`h7@I28>wddbM^StZ$h zKAS&&i}<;|GR3DGsd5&C*4c`zwwa}tcWAfcj<T6yvC~^BFd?Z!>0ufUo3WEFDJAa> z$@?vozgd*1s-EouJH?9E*aXAjnJb>@2=O7Gr>z($sJt(saMP)eEv^iCmYP{V_ZiAP zamCo|_1DGCu{^5&C8@)uM~lA#<<!qtZg*iB>P2e^j4yb91T*p6;s+Ml)o%rSi4J8` zE@r=5(=LN;V*#B>>kTwT%V-f>#h?G09Q>u!rYxbb%F~uo)etpF06bu<E1q`{<Ccb0 zVq$i@^mwCQZ{iTE@k{SU<RPkBwx+FrvwgH-(r%s3(t-NukFQX?gH$&ddxdu6*5byW zBlUx?)99IIQg<f@DRuo>hRNMU5l=+mnjF4YlaaBOc8im92kaPL#53Kq#S1pCq|7-d zJN!u)M(ak}GYf@vz-doKP+DzMoK@D>(c@13sNYjGp%$F=T5gF0G7tAsPhqV2z(rcF z738<rS627pg-al9Tik|eL@Bep_>g4$x0!QU2k`u2z}}FkeR+y=C?XYc2hDdSAl>xa zELs&FO^Ttqw+>XUn{N%FL)FyLULr)OrzrpYQ7N8jvM#~a$1A<ja53#FS{g?^Z7$0t z%P_zRC{t;6+b{Q3wH;mwJzpN(0hvYrK%p}Iwk6nW^{qO@-1)BnJx;2@T9E!KlVpn4 z;n~Z<1lQ6rP2EO%>jcz;puW8sG(&+4f=VAr15dMrwYYe!IVu))0ZS=;GMg1GVicv^ zwnL$fC&~ugsLX^cd*2=MI0jW*0}SX)-d>*Jsp+a-iejBz-Lq}7^eC+r_V&`6j|vs| zu4>Q8gm_Fa5DYn0hbhP0A63CQqJO?FI`OvBHw7Gri#)<Ze9Tf*mU(3<<X_fKSR^8V zJ>t7Ht&?b3g8o=Us-pO)gnz1(L=^KT?m}y3{wy}>j~u#apk^Nodfh146J*zas^c2d zb34Ig$-Kh)3aF|Xci=PrxmRB?Nk8`dg}(j`c8@%it(}*cNodsO^~$^P${0n+Nln!) zM04gP%=~Ohs(xsHtxQv@>zfMvWW)4uAEkCl1I?Lak}q$TLzZDj5b${xn!UZuVw-jP zFWq-;wSJ-NzcMcI5EC!<3343dXfzyrC|bxmZf6|GJQyr$xEd0ufjgGuCQBraxf`OR zv04BXe?<pwt4yHH7XE^%&)4hZ06XW$42xgy?oP#B`q!WZ>o56_W9x_Au|c-2jo||$ zwQ4T=%&*)E@(Tt#T=9Z7<8*i`I0ZFwa7$opz(LBAf^SOEbQtxIP%WbLqAzbt60KT& z%%bkT>#=rsp9c03ulmvI2l#p}=Z0%C26Nfs&&7*MI2h3=1ra$@8=^^a8a)%VS@Z|w zf`}jO+>p0PwTEcE|AupJ<rn%C|MIrDfM3L}WcK<d$<-FB%)G}Q<>x5OJayE4%Y4<1 zU749Q8*}XL8R;c6YfoJv`}1lqw)*Wg5y62oM0k0q<l$t_UZgvsu@HlqH~qJVX)M9y znn)k4O`A=5oyw?T3~LiVqRCw(G*-R2eyQzOF)yIWjsZc>nhagmVca_u_eG`~HnNG6 z>)eLL(YxcPg}`&!y_Gkd`fg8Mt1tZmU$EcP_%g$KYZ&mm^tUc=jPEx57grY4{E_<# zmzM#WXO2=QQhP{fIEjT#B<MWXp~1N+T6qTk`7SB!LQ3({>tD^{KD*ezkJ*T#qxtM; zd+*A?t-1$TiGPEhZ0j`D%Nv7V5TxLfX2K<@_i=JG7tx4Z<2M+dGS<Q1NV5;h6|o_) zu8jo%vrj3C4P%^b_JFa@foE=~kass$etI+ahTt-Evh0>8^YPvIgxln~!X#~h+Z94s znAT^?G2trdc~qD1mK|;~HKvEm2pudX%jNpag_$^p)8C<@3%SQYQ{H~`@SyzHY&K%C ztkr^wcQ%kXa?|TCK2_3<Vj7=Jl7RSd5?4C<tX_Al-jxm|sr}}IrK5Jeq^e+Q3yNND zb@PJ-d1{9)x-qj{vB`S)-NFR6mzsx^``;|-_4(OXi%5|T;Wejo=Ew+Y^%Lfqq5<*1 zBhbYli(<cryFsPL$$dXtp*V~{R#3Ef^PNG}Fiy^A!_jFojx5=#U1yTXlks`S590PG zMdYO36Y{;z_>xtp7RWNiLSyG<zD0PDlmIR0(<xO2dY{N|-oJqyD3(NBVv>A%&m%zf zZ9mjp#K11QPVV^9_Jf%}CR_byOGl_Oc;olqM&EZ?S^i|ehGt*+_zGw>r@a4)81GSk zj<-;$+-Z;L-gEexV7%uhdram655i=O-&cLNHNsA`q(KFH`aR1!42n7_Hx@Nbaevs* z*}@)NNLMJ(o->1t10CXwWT2<kgNmj3EU;~}+eML@-`JH)sOfgG&4jn<MW)ta#T98; zL-M=WGv#<u#5ycW>s@*`%<KfSgzDrG4j?`-#rF2gp$05xHnEPflcVw=LfH3%leH@; zCconSTw~x)x^_vF(^s7wb9h1Cp?#%?v1!P2An>sq{;M~z2nWPNM~t7rbx!i73s3Ld zNZK^N;2K%g!b^^Hv1;XL)#s_YjR>6!ipdC00_$Iue0DT`7QSjS42o3bwvghCK61iM zDxoUNk%c-&&Lm|b2}9L}#O&mG+$=o4wIXF~?Oc0ixGUZz6;?GZ?fS|=A26tr9sJ3? zr$}+^fn58Cc4h)-wxY_YyN5Bb!9o155<arUY*h{U7ArU9k$(Br^%?XhwnE57D<h+L z#U+<<cz44jzr4ns&Tz=8X1Eto&RACJI=w((&WwO5;4T2Ma03B=xdgyqV=AMtg0=3L zwoxYcdYi2vPw_T2pLsF;!K9DRYa@int$*#a2NMH!^8GdXL0!TTdn^yx9JiP$-IcAb zf_cw~RS)85#+E6W6Yt&0Y;Q#KpkAN22H@z5s5zit%H5JP54PjktLW|M7Av6mpEx~K z6UwW3Yo*QO?GT|y7;6F(6>oC<*jK!rf7c}FEL#0_gwti_@F}6SJ9=o{f&Eg&RIlgw zsZxJlB@gt;R7W}`CfKdt1s9*yUK2FR^vtE{ebDavz!ki1UNbZxr+6vR<gXBa*!><v zX%DHil~G|DcpP{6TqSMaK2ngnW#V+XPG7^Tg1?jV4@gUD{!rlHqY}wlTBAA*bo&?> z1n5xX3Swmy7C9BcSA5hdry@h%2o2sJ{G;}?`O%sTTeiNpuk_m3=2I~?q<w6qu`*q! zDUPOwXzwUuQMViNk9gl6Gx$33rVrO|+UesJ<K-reMunP6VW@vdqVLnvFS&`@3*nE! zI$bz@bTI@saB$!$ac)f4)ttW9P?*5WwTO#Zq7Mh2QsVh*Ae)Xq`gBO@XAa-Cj4T@) zY8w4cIX@~ck1~G4kHnM>f)7&fMLS{%>$}UNFZF)<!N`NWC${+!)L<vbA`E=wK-R*H zZhd8ECK$M-mrC8Jikokv9e4zM{ML~`2x=`<U6#NV37R&VOwzyenduZ%@}-1fE7|#l z#KG9~$LB53o<+$hrm{*1e?w?ODndt4KJ4w^XjJp{y68$KNDG`vp4Q!0_0#P9W1|`m zR<0H=kvI7=M5(^AF%$8X1av+$vW7W$mdHnD(58iuNYEeeGQ@-`4EJ<F%5>139^?1x z(J<l9W_9^artTjxEGmFhrM85kMyIC)kU-SS%tp&^*ax%t|J@8>ImwX!8xkGoD7r6G zw((-V(VHLt$|*9Ao%QZrR^@G@9>y*$e_UL|SeCnhU<MF5XLSU>2hJYh1Wk(?G2Wn} z`_+uS@5!9G<p%}3sD!e0v`0#@d)9O)ZeOA>dvlfV-m@4p*Z*G=|F5#)lhqdKgY0{a ze}4Qrr)2%NV<oSW=U-eIdn@RXvjC`zC@XxfY5Vt`4^+Yr=T7jR<MlY;n&x+#vOUJj zfu}&}<V?2Nd(dfa?d0yQSEoA94feZ~ofZCM=AK2npq-0jOOJkZKC@|u-b0JM`>#l6 zH8;p+XLGC12rpdYlxOpK^_?R9>-S~U_MUnb81MJ6;NX9!1+RRs>hV?v96xnw&6+ve zjhMB;9-Mn5T?rV%eGh-HzJ00U25<m0E4^=}^sUebBI2j7aPau)tUlhhwktMC^gv{K zsQ2po(w`RmyK!e%&MS@SpSFiA-!k_=`mT)a!bP2@m+qbW<gLP<!y9<@Uta70ohNp6 zn$UFbYU`7?9V^-srQ<Fw76cv!rnY*0<BphFz~QbLz)8GqlXt}2x}E;7sHI$D+kaJC zDe$>vw!9rS-Y=Bqq%piV$ocPGWx~YzDP+!s7`?OWw|CtwGm0(y|M>HUuhExHl|XwW zw=SJ>dg;%vVIL1Y)%|$PwaWR+Z7<-_WxyuZ<!HUL>!i&*K#9<EXUwel{5jsnj~{&z zsjA<iI01A-nl0~%r<e5mA9jXroVEPi>ehQk;32fFGas4u{4Dwu^jmG-76p(cq3UXN z=dG#}^E>KxBb}1A@8X-Y@>Z><elO;21RsVbCgHocps#4PaPya&4h>9_tm-KogW=dS zBE}-AvC^Z;@5BKJc%a)-=)?vA`T9M=MzC}49$NgD-!#+b_hs=f3Bcp{7(8A5T-G@y GGywqSdE~|b literal 45633 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 diff --git a/web_dashboard_tile/tests/__init__.py b/web_dashboard_tile/tests/__init__.py new file mode 100644 index 000000000..4f8c7e8bf --- /dev/null +++ b/web_dashboard_tile/tests/__init__.py @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +# © 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com> +# 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 000000000..90604ab9a --- /dev/null +++ b/web_dashboard_tile/tests/test_tile.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# © 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com> +# 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 36411ad84..cf9a003f4 100644 --- a/web_dashboard_tile/views/tile.xml +++ b/web_dashboard_tile/views/tile.xml @@ -9,8 +9,10 @@ <field name="name"/> <field name="domain"/> <field name="model_id"/> - <field name="field_function"/> - <field name="field_id"/> + <field name="primary_function"/> + <field name="primary_field_id"/> + <field name="secondary_function"/> + <field name="secondary_field_id"/> <field name="user_id"/> <field name="background_color" widget="color"/> </tree> @@ -34,11 +36,50 @@ <field name="model_id"/> <field name="action_id"/> <field name="domain" colspan="4"/> - <separator string="Optional Field Informations" colspan="4"/> - <field name="field_function"/> - <field name="field_id"/> - <field name="helper" colspan="4"/> + <separator colspan="4"/> + <field name="error" attrs="{'invisible':[('error','=',False)]}"/> </group> + <notebook> + <page string="Main Value"> + <group> + <group> + <field name="primary_function"/> + <field name="primary_field_id" attrs="{ + 'invisible':[('primary_function','in',[False,'count'])], + 'required':[('primary_function','not in',[False,'count'])], + }"/> + </group> + <group> + <field name="primary_format"/> + </group> + <group> + <field name="primary_helper"/> + <field name="primary_value" attrs="{'invisible':[('primary_value','=',False)]}"/> + </group> + </group> + </page> + <page string="Secondary Value"> + <group> + <group> + <field name="secondary_function"/> + <field name="secondary_field_id" attrs="{ + 'invisible':[('secondary_function','in',[False,'count'])], + 'required':[('secondary_function','not in',[False,'count'])], + }"/> + </group> + <group> + <field name="secondary_format"/> + </group> + <group> + <field name="secondary_helper"/> + <field name="secondary_value" attrs="{'invisible':[('secondary_value','=',False)]}"/> + </group> + </group> + </page> + <page string="Groups"> + <field name="group_ids"/> + </page> + </notebook> </sheet> </form> </field> @@ -53,37 +94,31 @@ <field name="domain"/> <field name="model_id"/> <field name="action_id"/> - <field name="count"/> <field name="background_color"/> <field name="font_color"/> - <field name="field_id" /> - <field name="field_function" /> - <field name="helper" /> + <field name="primary_function"/> + <field name="primary_helper"/> + <field name="secondary_function"/> + <field name="secondary_helper"/> + <templates> <t t-name="kanban-box"> <div t-attf-class="oe_dashbaord_tile oe_kanban_global_click" t-attf-style="background-color:#{record.background_color.raw_value}" > <div class="oe_kanban_content"> <a type="object" name="open_link" args="[]" t-attf-style="color:#{record.font_color.raw_value};"> - <div class="tile_label"> - <b><field name="name"/></b> + <div style="height:100%;" t-att-class="record.secondary_function.raw_value and 'with_secondary' or 'simple'"> + <div class="tile_label"> + <field name="name"/> + </div> + <div class="tile_primary_value" t-att-title="record.primary_helper.raw_value"> + <t t-set="l" t-value="record.primary_value.raw_value.length" /> + <t t-set="s" t-value="l>=12 and 35 or l>=10 and 45 or l>=8 and 55 or l>=6 and 75 or l>4 and 85 or 100"/> + <span t-attf-style="font-size: #{s}%;"><field name="primary_value"/></span> + </div> + <div class="tile_secondary_value" t-att-title="record.secondary_helper.raw_value"> + <span><field name="secondary_value"/></span> + </div> </div> - <div style="padding-left: 0.5em; height: 115px;"> - - </div> - <t t-if="record.field_id.raw_value != '' and record.field_function.raw_value != '' and record.count.raw_value !=0"> - <div class="tile_count_with_computed_value"> - <span><field name="count"/></span> - </div> - <div class="tile_computed_value" t-att-title="record.helper.raw_value"> - <img t-att-src="_s + '/web_dashboard_tile/static/src/img/' + record.field_function.raw_value + '.png'"/> - <span><field name="computed_value"/></span> - </div> - </t> - <t t-if="!(record.field_id.raw_value != '' and record.field_function.raw_value != '' and record.count.raw_value !=0)"> - <div class="tile_count_without_computed_value"> - <span><field name="count"/></span> - </div> - </t> </a> </div> <div class="oe_clear"></div> From 45750d6030482956ccdf99a44e7833b7127eced1 Mon Sep 17 00:00:00 2001 From: Nicolas Mac Rouillon <nmr@adhoc.com.ar> Date: Tue, 13 Dec 2016 15:04:14 -0300 Subject: [PATCH 44/50] FIX --- web_dashboard_tile/README.rst | 44 +---- 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, 60 insertions(+), 283 deletions(-) diff --git a/web_dashboard_tile/README.rst b/web_dashboard_tile/README.rst index 0337037b1..523dcadb5 100644 --- a/web_dashboard_tile/README.rst +++ b/web_dashboard_tile/README.rst @@ -1,19 +1,6 @@ -Add Tiles to Dashboard -====================== +Dashboard Tiles +=============== -<<<<<<< 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; -======= 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 -====================== +.. image:: ./static/src/img/screenshot_action_click.png -<<<<<<< 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); -======= 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 <https://github.com/OCA/web/issues>`_. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us smashing it by providing a detailed and welcomed feedback -`here <https://github.com/OCA/ -web/issues/new?body=module:%20 -web_dashboard_tile%0Aversion:%20 -8.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_. +`here <https://github.com/OCA/web/issues/new?body=module:%20web_dashboard_tile%0Aversion:%208.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_. Credits @@ -88,6 +61,7 @@ Contributors * Markus Schneider <markus.schneider at initos.com> * Sylvain Le Gal (https://twitter.com/legalsylvain) +* Iván Todorovich <ivan.todorovich@gmail.com> 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 35d8f47b1..1d098b583 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. (<http://openerp.com>). -# Copyright (C) 2014 initOS GmbH & Co. KG (<http://www.initos.com>). -# Copyright (C) 2015-Today GRAP -# Author Markus Schneider <markus.schneider at initos.com> -# @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 <http://www.gnu.org/licenses/>. -# -############################################################################## +# © 2010-2013 OpenERP s.a. (<http://openerp.com>). +# © 2014 initOS GmbH & Co. KG (<http://www.initos.com>). +# © 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 f84fd1b37..bcba4eb5d 100644 --- a/web_dashboard_tile/__openerp__.py +++ b/web_dashboard_tile/__openerp__.py @@ -20,6 +20,10 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. # ############################################################################## +# -*- coding: utf-8 -*- +# © 2010-2013 OpenERP s.a. (<http://openerp.com>). +# © 2014 initOS GmbH & Co. KG (<http://www.initos.com>). +# 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 <ivan.todorovich@gmail.com>' + ], '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 fc23e732e..97fec216c 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 <http://www.gnu.org/licenses/>. -# -############################################################################## +# © 2010-2013 OpenERP s.a. (<http://openerp.com>). +# © 2014 initOS GmbH & Co. KG (<http://www.initos.com>). +# © 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 498d365bb..bc304b691 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. (<http://openerp.com>). -# Copyright (C) 2014 initOS GmbH & Co. KG (<http://www.initos.com>). -# Copyright (C) 2015-Today GRAP -# Author Markus Schneider <markus.schneider at initos.com> -# @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 <http://www.gnu.org/licenses/>. -# -############################################################################## - -from openerp import api, fields -from openerp.models import Model -from openerp.exceptions import except_orm -======= # © 2010-2013 OpenERP s.a. (<http://openerp.com>). # © 2014 initOS GmbH & Co. KG (<http://www.initos.com>). # © 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 4ec483d72..73b811d3f 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 c192ef293..9015f9a9d 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 3e0c23167..11ecb179c 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 @@ <templates id="template" xml:space="preserve"> <t t-extend="SearchView.addtodashboard"> <t t-jquery="form" t-operation="after"> - <div> + <div class="oe_dashboard_tile_form"> <label for="dashboard_tile_new_name">Tile:</label> <input id="dashboard_tile_new_name" /> <button id="add_dashboard_tile">Create</button> </div> </t> </t> -</templates> +</templates> \ No newline at end of file diff --git a/web_dashboard_tile/views/templates.xml b/web_dashboard_tile/views/templates.xml index e7a68b213..1fe51f0d1 100644 --- a/web_dashboard_tile/views/templates.xml +++ b/web_dashboard_tile/views/templates.xml @@ -30,4 +30,4 @@ </xpath> </template> </data> -</openerp> +</openerp> \ No newline at end of file diff --git a/web_dashboard_tile/views/tile.xml b/web_dashboard_tile/views/tile.xml index cf9a003f4..a42d952f8 100644 --- a/web_dashboard_tile/views/tile.xml +++ b/web_dashboard_tile/views/tile.xml @@ -103,7 +103,7 @@ <templates> <t t-name="kanban-box"> - <div t-attf-class="oe_dashbaord_tile oe_kanban_global_click" t-attf-style="background-color:#{record.background_color.raw_value}" > + <div t-attf-class="oe_dashboard_tile oe_kanban_global_click" t-attf-style="background-color:#{record.background_color.raw_value}" > <div class="oe_kanban_content"> <a type="object" name="open_link" args="[]" t-attf-style="color:#{record.font_color.raw_value};"> <div style="height:100%;" t-att-class="record.secondary_function.raw_value and 'with_secondary' or 'simple'"> @@ -152,9 +152,9 @@ <record id="mail_dashboard" model="ir.ui.menu"> <field name="name">Dashboard</field> - <field name="sequence" eval="9"/> + <field name="sequence" eval="0"/> <field name="action" ref="action_kanban_dashboard_tile"/> - <field name="parent_id" ref="mail.mail_feeds"/> + <field name="parent_id" ref=""/> </record> </data> From 38a521a3e6801085b58d0086c6b9a951055e42a7 Mon Sep 17 00:00:00 2001 From: Nicolas Mac Rouillon <nmr@adhoc.com.ar> 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 bcba4eb5d..dbda3d3b7 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. (<http://openerp.com>). -# Copyright (C) 2014 initOS GmbH & Co. KG (<http://www.initos.com>). -# Author Markus Schneider <markus.schneider at initos.com> -# -# 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 <http://www.gnu.org/licenses/>. -# -############################################################################## -# -*- coding: utf-8 -*- # © 2010-2013 OpenERP s.a. (<http://openerp.com>). # © 2014 initOS GmbH & Co. KG (<http://www.initos.com>). # 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 <nmr@adhoc.com.ar> 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 523dcadb5..daa3a2ebf 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 11ecb179c..38a0e3e96 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 @@ </div> </t> </t> -</templates> \ No newline at end of file +</templates> diff --git a/web_dashboard_tile/views/templates.xml b/web_dashboard_tile/views/templates.xml index 1fe51f0d1..e7a68b213 100644 --- a/web_dashboard_tile/views/templates.xml +++ b/web_dashboard_tile/views/templates.xml @@ -30,4 +30,4 @@ </xpath> </template> </data> -</openerp> \ No newline at end of file +</openerp> From a7521442c593894a1a83049cac86b7223925915f Mon Sep 17 00:00:00 2001 From: Nicolas Mac Rouillon <nmr@adhoc.com.ar> 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 8c6de995d..000000000 --- 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 <https://github.com/OCA/web/issues>`_. -In case of trouble, please check there if your issue has already been reported. -If you spotted it first, help us smashing it by providing a detailed and welcomed feedback -`here <https://github.com/OCA/web/issues/new?body=module:%20web_advanced_search_wildcard%0Aversion:%208.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_. - -Credits -======= - -Images ------- - -* Odoo Community Association: `Icon <https://github.com/OCA/maintainer-tools/blob/master/template/module/static/description/icon.svg>`_. - -Contributors ------------- - -* Markus Schneider <markus.schneider@initos.com> -* Thomas Rehn <thomas.rehn@initos.com> -* L Freeke <lfreeke@therp.nl> - - -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 e69de29bb..000000000 diff --git a/web_advanced_search_wildcard/__openerp__.py b/web_advanced_search_wildcard/__openerp__.py deleted file mode 100644 index 797f3a604..000000000 --- a/web_advanced_search_wildcard/__openerp__.py +++ /dev/null @@ -1,21 +0,0 @@ -# -*- coding: utf-8 -*- -# © 2014 initOS GmbH & Co. KG (<http://www.initos.com>). -# © 2016 Therp BV <http://therp.nl>. -# 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 4cfbc4f35..000000000 --- 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 <schnapkar@golive-saar.de>, 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 <schnapkar@golive-saar.de>\n" -"Language-Team: German <kde-i18n-de@kde.org>\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 2f9437ce7..000000000 --- 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 <pedro.baeza@gmail.com>, 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 <pedro.baeza@gmail.com>\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 91f0ab2e7..000000000 --- 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 <jarmo.kortetjarvi@gmail.com>, 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 <jarmo.kortetjarvi@gmail.com>\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 302b2e39e..000000000 --- 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 <christophe.chauvet@gmail.com>, 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 <christophe.chauvet@gmail.com>\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 0464430f9..000000000 --- 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 <danimaribeiro@gmail.com>, 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 <danimaribeiro@gmail.com>\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 f8aa6f658..000000000 --- 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č <m.mozetic@matmoz.si>, 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č <m.mozetic@matmoz.si>\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 e187a2da3..000000000 --- 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<FV<w{p-AUi=RvC<yKV diff --git a/web_advanced_search_wildcard/static/src/js/search.js b/web_advanced_search_wildcard/static/src/js/search.js deleted file mode 100644 index 1b43dc0c5..000000000 --- a/web_advanced_search_wildcard/static/src/js/search.js +++ /dev/null @@ -1,6 +0,0 @@ -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")} - ); -}; diff --git a/web_advanced_search_wildcard/views/template.xml b/web_advanced_search_wildcard/views/template.xml deleted file mode 100644 index bfe353d55..000000000 --- a/web_advanced_search_wildcard/views/template.xml +++ /dev/null @@ -1,10 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<openerp> - <data> - <template id="assets_backend" name="web_advanced_search_wildcard assets" inherit_id="web.assets_backend"> - <xpath expr="." position="inside"> - <script type="text/javascript" src="/web_advanced_search_wildcard/static/src/js/search.js"></script> - </xpath> - </template> - </data> -</openerp> diff --git a/web_dashboard_tile/models/tile_tile.py b/web_dashboard_tile/models/tile_tile.py index bc304b691..38ce5c66c 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 <nmr@adhoc.com.ar> 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 38ce5c66c..0ee69ef62 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?= <ivan.todorovich@gmail.com> 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 0ee69ef62..7f4866bca 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 73b811d3f..0620a9c65 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 <nmr@adhoc.com.ar> 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 7f4866bca..218cec406 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 9015f9a9d..615a74d6b 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); } });