+% for line in object.event_id.event_mail_ids:
+% if line.interval_type == 'after_change_tracks':
+% for rec in line.mail_track_ids:
+% if not rec.mail_sent:
+
+
+ Track ${rec.track_id.name} changed From ${rec.change_date_from} To ${rec.change_date_to}
+
+% endif
+% endfor
+% endif
+% endfor
+
+
+
+
+ % if 'website_url' in object.website_url and object.event_id.website_url:
+ View Event
+ % endif
+
+
+
+
+
+ ]]>
+
+
+
+
diff --git a/odex-event/event_custom/i18n/ar_SY.po b/odex-event/event_custom/i18n/ar_SY.po
new file mode 100644
index 000000000..ae1c60ae8
--- /dev/null
+++ b/odex-event/event_custom/i18n/ar_SY.po
@@ -0,0 +1,495 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * event_custom
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 11.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2023-02-10 21:22+0000\n"
+"PO-Revision-Date: 2023-02-10 21:22+0000\n"
+"Last-Translator: <>\n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: \n"
+
+#. module: event_custom
+#: model:mail.template,body_html:event_custom.event_subscription
+msgid "\n"
+"
\n"
+"% set date_begin = format_tz(object.event_id.date_begin, tz='UTC', format='%Y%m%dT%H%M%SZ')\n"
+"% set date_end = format_tz(object.event_id.date_end, tz='UTC', format='%Y%m%dT%H%M%SZ')\n"
+"
\n"
+"% for line in object.event_id.event_mail_ids:\n"
+"% if line.interval_type == 'after_change_tracks':\n"
+"% for rec in line.mail_track_ids:\n"
+"% if not rec.mail_sent:\n"
+"\n"
+"
\n"
+" Track ${rec.track_id.name} changed From ${rec.change_date_from} To ${rec.change_date_to}\n"
+"
\n"
+"% for line in object.event_id.event_mail_ids:\n"
+"% if line.interval_type == 'after_change_tracks':\n"
+"% for rec in line.mail_track_ids:\n"
+"% if not rec.mail_sent:\n"
+"\n"
+"
\n"
+" Track ${rec.track_id.name} changed From ${rec.change_date_from} To ${rec.change_date_to}\n"
+"
+
+
+ col-lg-9
+
+
+
+
+
diff --git a/odex-event/muk_autovacuum/LICENSE b/odex-event/muk_autovacuum/LICENSE
new file mode 100644
index 000000000..153d416dc
--- /dev/null
+++ b/odex-event/muk_autovacuum/LICENSE
@@ -0,0 +1,165 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+
+ This version of the GNU Lesser General Public License incorporates
+the terms and conditions of version 3 of the GNU General Public
+License, supplemented by the additional permissions listed below.
+
+ 0. Additional Definitions.
+
+ As used herein, "this License" refers to version 3 of the GNU Lesser
+General Public License, and the "GNU GPL" refers to version 3 of the GNU
+General Public License.
+
+ "The Library" refers to a covered work governed by this License,
+other than an Application or a Combined Work as defined below.
+
+ An "Application" is any work that makes use of an interface provided
+by the Library, but which is not otherwise based on the Library.
+Defining a subclass of a class defined by the Library is deemed a mode
+of using an interface provided by the Library.
+
+ A "Combined Work" is a work produced by combining or linking an
+Application with the Library. The particular version of the Library
+with which the Combined Work was made is also called the "Linked
+Version".
+
+ The "Minimal Corresponding Source" for a Combined Work means the
+Corresponding Source for the Combined Work, excluding any source code
+for portions of the Combined Work that, considered in isolation, are
+based on the Application, and not on the Linked Version.
+
+ The "Corresponding Application Code" for a Combined Work means the
+object code and/or source code for the Application, including any data
+and utility programs needed for reproducing the Combined Work from the
+Application, but excluding the System Libraries of the Combined Work.
+
+ 1. Exception to Section 3 of the GNU GPL.
+
+ You may convey a covered work under sections 3 and 4 of this License
+without being bound by section 3 of the GNU GPL.
+
+ 2. Conveying Modified Versions.
+
+ If you modify a copy of the Library, and, in your modifications, a
+facility refers to a function or data to be supplied by an Application
+that uses the facility (other than as an argument passed when the
+facility is invoked), then you may convey a copy of the modified
+version:
+
+ a) under this License, provided that you make a good faith effort to
+ ensure that, in the event an Application does not supply the
+ function or data, the facility still operates, and performs
+ whatever part of its purpose remains meaningful, or
+
+ b) under the GNU GPL, with none of the additional permissions of
+ this License applicable to that copy.
+
+ 3. Object Code Incorporating Material from Library Header Files.
+
+ The object code form of an Application may incorporate material from
+a header file that is part of the Library. You may convey such object
+code under terms of your choice, provided that, if the incorporated
+material is not limited to numerical parameters, data structure
+layouts and accessors, or small macros, inline functions and templates
+(ten or fewer lines in length), you do both of the following:
+
+ a) Give prominent notice with each copy of the object code that the
+ Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the object code with a copy of the GNU GPL and this license
+ document.
+
+ 4. Combined Works.
+
+ You may convey a Combined Work under terms of your choice that,
+taken together, effectively do not restrict modification of the
+portions of the Library contained in the Combined Work and reverse
+engineering for debugging such modifications, if you also do each of
+the following:
+
+ a) Give prominent notice with each copy of the Combined Work that
+ the Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the Combined Work with a copy of the GNU GPL and this license
+ document.
+
+ c) For a Combined Work that displays copyright notices during
+ execution, include the copyright notice for the Library among
+ these notices, as well as a reference directing the user to the
+ copies of the GNU GPL and this license document.
+
+ d) Do one of the following:
+
+ 0) Convey the Minimal Corresponding Source under the terms of this
+ License, and the Corresponding Application Code in a form
+ suitable for, and under terms that permit, the user to
+ recombine or relink the Application with a modified version of
+ the Linked Version to produce a modified Combined Work, in the
+ manner specified by section 6 of the GNU GPL for conveying
+ Corresponding Source.
+
+ 1) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (a) uses at run time
+ a copy of the Library already present on the user's computer
+ system, and (b) will operate properly with a modified version
+ of the Library that is interface-compatible with the Linked
+ Version.
+
+ e) Provide Installation Information, but only if you would otherwise
+ be required to provide such information under section 6 of the
+ GNU GPL, and only to the extent that such information is
+ necessary to install and execute a modified version of the
+ Combined Work produced by recombining or relinking the
+ Application with a modified version of the Linked Version. (If
+ you use option 4d0, the Installation Information must accompany
+ the Minimal Corresponding Source and Corresponding Application
+ Code. If you use option 4d1, you must provide the Installation
+ Information in the manner specified by section 6 of the GNU GPL
+ for conveying Corresponding Source.)
+
+ 5. Combined Libraries.
+
+ You may place library facilities that are a work based on the
+Library side by side in a single library together with other library
+facilities that are not Applications and are not covered by this
+License, and convey such a combined library under terms of your
+choice, if you do both of the following:
+
+ a) Accompany the combined library with a copy of the same work based
+ on the Library, uncombined with any other library facilities,
+ conveyed under the terms of this License.
+
+ b) Give prominent notice with the combined library that part of it
+ is a work based on the Library, and explaining where to find the
+ accompanying uncombined form of the same work.
+
+ 6. Revised Versions of the GNU Lesser General Public License.
+
+ The Free Software Foundation may publish revised and/or new versions
+of the GNU Lesser General Public License from time to time. Such new
+versions will be similar in spirit to the present version, but may
+differ in detail to address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Library as you received it specifies that a certain numbered version
+of the GNU Lesser General Public License "or any later version"
+applies to it, you have the option of following the terms and
+conditions either of that published version or of any later version
+published by the Free Software Foundation. If the Library as you
+received it does not specify a version number of the GNU Lesser
+General Public License, you may choose any version of the GNU Lesser
+General Public License ever published by the Free Software Foundation.
+
+ If the Library as you received it specifies that a proxy can decide
+whether future versions of the GNU Lesser General Public License shall
+apply, that proxy's public statement of acceptance of any version is
+permanent authorization for you to choose that version for the
+Library.
\ No newline at end of file
diff --git a/odex-event/muk_autovacuum/README.rst b/odex-event/muk_autovacuum/README.rst
new file mode 100644
index 000000000..d81dcd908
--- /dev/null
+++ b/odex-event/muk_autovacuum/README.rst
@@ -0,0 +1,120 @@
+==============
+MuK Autovacuum
+==============
+
+Allows the administrator to create rules to automatically garbage collect
+a certain model. Every rule can have a different time interval additional
+constraints. An extra constraint can be for example to only delete inactive
+records.
+
+Installation
+============
+
+To install this module, you need to:
+
+Download the module and add it to your Odoo addons folder. Afterward, log on to
+your Odoo server and go to the Apps menu. Trigger the debug mode and update the
+list by clicking on the "Update Apps List" link. Now install the module by
+clicking on the install button.
+
+Another way to install this module is via the package management for Python
+(`PyPI `_).
+
+To install our modules using the package manager make sure
+`odoo-autodiscover `_ is installed
+correctly. Then open a console and install the module by entering the following
+command:
+
+``pip install --extra-index-url https://nexus.mukit.at/repository/odoo/simple ``
+
+The module name consists of the Odoo version and the module name, where
+underscores are replaced by a dash.
+
+**Module:**
+
+``odoo-addon-``
+
+**Example:**
+
+``sudo -H pip3 install --extra-index-url https://nexus.mukit.at/repository/odoo/simple odoo11-addon-muk-utils``
+
+Once the installation has been successfully completed, the app is already in the
+correct folder. Log on to your Odoo server and go to the Apps menu. Trigger the
+debug mode and update the list by clicking on the "Update Apps List" link. Now
+install the module by clicking on the install button.
+
+The biggest advantage of this variant is that you can now also update the app
+using the "pip" command. To do this, enter the following command in your console:
+
+``pip install --upgrade --extra-index-url https://nexus.mukit.at/repository/odoo/simple ``
+
+When the process is finished, restart your server and update the application in
+Odoo. The steps are the same as for the installation only the button has changed
+from "Install" to "Upgrade".
+
+You can also view available Apps directly in our `repository `_
+and find a more detailed installation guide on our `website `_.
+
+For modules licensed under OPL-1, you will receive access data when you purchase
+the module. If the modules were not purchased directly from
+`MuK IT `_ please contact our support (support@mukit.at)
+with a confirmation of purchase to receive the corresponding access data.
+
+Upgrade
+============
+
+To upgrade this module, you need to:
+
+Download the module and add it to your Odoo addons folder. Restart the server
+and log on to your Odoo server. Select the Apps menu and upgrade the module by
+clicking on the upgrade button.
+
+If you installed the module using the "pip" command, you can also update the
+module in the same way. Just type the following command into the console:
+
+``pip install --upgrade --extra-index-url https://nexus.mukit.at/repository/odoo/simple ``
+
+When the process is finished, restart your server and update the application in
+Odoo, just like you would normally.
+
+Configuration
+=============
+
+To configure this module, you need to:
+
+#. Go to *Settings* while being in debug mode.
+#. Afterwards go to *Technical -> Automation -> Auto Vacuum Rules*.
+#. And create a new rule.
+
+Usage
+=============
+
+This module has no direct visible effect on the system. The garbage collections
+happens during the autovacuum cron job.
+
+Credits
+=======
+
+Contributors
+------------
+
+* Mathias Markl
+
+Images
+------------
+
+Some pictures are based on or inspired by the icon set of Font Awesome:
+
+* `Font Awesome `_
+
+Author & Maintainer
+-------------------
+
+This module is maintained by the `MuK IT GmbH `_.
+
+MuK IT is an Austrian company specialized in customizing and extending Odoo.
+We develop custom solutions for your individual needs to help you focus on
+your strength and expertise to grow your business.
+
+If you want to get in touch please contact us via mail
+(sale@mukit.at) or visit our website (https://mukit.at).
diff --git a/odex-event/muk_autovacuum/__init__.py b/odex-event/muk_autovacuum/__init__.py
new file mode 100644
index 000000000..57c50e8ca
--- /dev/null
+++ b/odex-event/muk_autovacuum/__init__.py
@@ -0,0 +1,23 @@
+###################################################################################
+#
+# Copyright (c) 2017-2019 MuK IT GmbH.
+#
+# This file is part of MuK Autovacuum
+# (see https://mukit.at).
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see .
+#
+###################################################################################
+
+from . import models
diff --git a/odex-event/muk_autovacuum/__manifest__.py b/odex-event/muk_autovacuum/__manifest__.py
new file mode 100644
index 000000000..ab525fb9e
--- /dev/null
+++ b/odex-event/muk_autovacuum/__manifest__.py
@@ -0,0 +1,56 @@
+###################################################################################
+#
+# Copyright (c) 2017-2019 MuK IT GmbH.
+#
+# This file is part of MuK Autovacuum
+# (see https://mukit.at).
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see .
+#
+###################################################################################
+
+{
+ 'name': 'MuK Autovacuum',
+ 'summary': 'Configure automatic garbage collection',
+ 'version': '12.0.3.0.1',
+ 'category': 'Extra Tools',
+ 'license': 'LGPL-3',
+ 'author': 'MuK IT',
+ 'website': 'https://www.mukit.at',
+ 'live_test_url': 'https://mukit.at/r/SgN',
+ 'contributors': [
+ 'Mathias Markl ',
+ ],
+ 'depends': [
+ 'muk_utils',
+ ],
+ 'data': [
+ 'security/ir.model.access.csv',
+ 'views/rules.xml',
+ 'data/rules.xml',
+ ],
+ 'qweb': [
+ 'static/src/xml/*.xml',
+ ],
+ 'images': [
+ 'static/description/banner.png'
+ ],
+ 'external_dependencies': {
+ 'python': [],
+ 'bin': [],
+ },
+ 'application': False,
+ 'installable': True,
+ 'auto_install': False,
+}
\ No newline at end of file
diff --git a/odex-event/muk_autovacuum/data/rules.xml b/odex-event/muk_autovacuum/data/rules.xml
new file mode 100644
index 000000000..c2cea2d79
--- /dev/null
+++ b/odex-event/muk_autovacuum/data/rules.xml
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+ Delete Logs after 2 Weeks
+
+
+
+ time
+ weeks
+ 2
+
+
+
+
\ No newline at end of file
diff --git a/odex-event/muk_autovacuum/doc/changelog.rst b/odex-event/muk_autovacuum/doc/changelog.rst
new file mode 100644
index 000000000..75ffd703c
--- /dev/null
+++ b/odex-event/muk_autovacuum/doc/changelog.rst
@@ -0,0 +1,20 @@
+`2.1.0`
+-------
+
+- Added Python Expressions
+
+`2.0.0`
+-------
+
+- Migrated to Python 3
+
+`1.1.0`
+-------
+
+- Add field selector
+
+
+`1.0.0`
+-------
+
+- Init version
diff --git a/odex-event/muk_autovacuum/doc/index.rst b/odex-event/muk_autovacuum/doc/index.rst
new file mode 100644
index 000000000..d81dcd908
--- /dev/null
+++ b/odex-event/muk_autovacuum/doc/index.rst
@@ -0,0 +1,120 @@
+==============
+MuK Autovacuum
+==============
+
+Allows the administrator to create rules to automatically garbage collect
+a certain model. Every rule can have a different time interval additional
+constraints. An extra constraint can be for example to only delete inactive
+records.
+
+Installation
+============
+
+To install this module, you need to:
+
+Download the module and add it to your Odoo addons folder. Afterward, log on to
+your Odoo server and go to the Apps menu. Trigger the debug mode and update the
+list by clicking on the "Update Apps List" link. Now install the module by
+clicking on the install button.
+
+Another way to install this module is via the package management for Python
+(`PyPI `_).
+
+To install our modules using the package manager make sure
+`odoo-autodiscover `_ is installed
+correctly. Then open a console and install the module by entering the following
+command:
+
+``pip install --extra-index-url https://nexus.mukit.at/repository/odoo/simple ``
+
+The module name consists of the Odoo version and the module name, where
+underscores are replaced by a dash.
+
+**Module:**
+
+``odoo-addon-``
+
+**Example:**
+
+``sudo -H pip3 install --extra-index-url https://nexus.mukit.at/repository/odoo/simple odoo11-addon-muk-utils``
+
+Once the installation has been successfully completed, the app is already in the
+correct folder. Log on to your Odoo server and go to the Apps menu. Trigger the
+debug mode and update the list by clicking on the "Update Apps List" link. Now
+install the module by clicking on the install button.
+
+The biggest advantage of this variant is that you can now also update the app
+using the "pip" command. To do this, enter the following command in your console:
+
+``pip install --upgrade --extra-index-url https://nexus.mukit.at/repository/odoo/simple ``
+
+When the process is finished, restart your server and update the application in
+Odoo. The steps are the same as for the installation only the button has changed
+from "Install" to "Upgrade".
+
+You can also view available Apps directly in our `repository `_
+and find a more detailed installation guide on our `website `_.
+
+For modules licensed under OPL-1, you will receive access data when you purchase
+the module. If the modules were not purchased directly from
+`MuK IT `_ please contact our support (support@mukit.at)
+with a confirmation of purchase to receive the corresponding access data.
+
+Upgrade
+============
+
+To upgrade this module, you need to:
+
+Download the module and add it to your Odoo addons folder. Restart the server
+and log on to your Odoo server. Select the Apps menu and upgrade the module by
+clicking on the upgrade button.
+
+If you installed the module using the "pip" command, you can also update the
+module in the same way. Just type the following command into the console:
+
+``pip install --upgrade --extra-index-url https://nexus.mukit.at/repository/odoo/simple ``
+
+When the process is finished, restart your server and update the application in
+Odoo, just like you would normally.
+
+Configuration
+=============
+
+To configure this module, you need to:
+
+#. Go to *Settings* while being in debug mode.
+#. Afterwards go to *Technical -> Automation -> Auto Vacuum Rules*.
+#. And create a new rule.
+
+Usage
+=============
+
+This module has no direct visible effect on the system. The garbage collections
+happens during the autovacuum cron job.
+
+Credits
+=======
+
+Contributors
+------------
+
+* Mathias Markl
+
+Images
+------------
+
+Some pictures are based on or inspired by the icon set of Font Awesome:
+
+* `Font Awesome `_
+
+Author & Maintainer
+-------------------
+
+This module is maintained by the `MuK IT GmbH `_.
+
+MuK IT is an Austrian company specialized in customizing and extending Odoo.
+We develop custom solutions for your individual needs to help you focus on
+your strength and expertise to grow your business.
+
+If you want to get in touch please contact us via mail
+(sale@mukit.at) or visit our website (https://mukit.at).
diff --git a/odex-event/muk_autovacuum/i18n/ar.po b/odex-event/muk_autovacuum/i18n/ar.po
new file mode 100644
index 000000000..b23e93315
--- /dev/null
+++ b/odex-event/muk_autovacuum/i18n/ar.po
@@ -0,0 +1,402 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * muk_autovacuum
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 12.0-20190522\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2019-07-12 23:43+0000\n"
+"PO-Revision-Date: 2019-07-12 23:43+0000\n"
+"Last-Translator: <>\n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: \n"
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "Warning: Warning Exception to use with raise"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "b64encode, b64decode: Base64 converter"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "date_format, datetime_format: server date and time formats"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "env: Odoo Environment on which the rule is triggered"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "logger.info(message): Python logging framework"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "model: Odoo Model of the record on which the rule is triggered"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "time, datetime, dateutil, timezone: useful Python libraries"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "uid, user: User on which the rule is triggered"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__active
+msgid "Active"
+msgstr "نشط"
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_search
+msgid "All"
+msgstr "الكل"
+
+#. module: muk_autovacuum
+#: model:ir.actions.act_window,name:muk_autovacuum.action_autovacuum_rule
+#: model:ir.model,name:muk_autovacuum.model_muk_autovacuum_rules
+#: model:ir.ui.menu,name:muk_autovacuum.menu_autovacuum_rules
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_search
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_tree
+msgid "Auto Vacuum Rules"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model,name:muk_autovacuum.model_ir_autovacuum
+msgid "Automatic Vacuum"
+msgstr "تفريغ تلقائي"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__code
+msgid "Code"
+msgstr ""
+
+#. module: muk_autovacuum
+#: selection:muk_autovacuum.rules,state:0
+msgid "Code Based"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "Code Settings"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules__code
+msgid "Code which will be executed during the clean up."
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__create_uid
+msgid "Created by"
+msgstr "أنشئ بواسطة"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__create_date
+msgid "Created on"
+msgstr "أنشئ في"
+
+#. module: muk_autovacuum
+#: selection:muk_autovacuum.rules,time_type:0
+msgid "Days"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules__domain
+msgid "Delete all records which match the domain."
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules__time
+msgid "Delete older data than x."
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules__size
+#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules__size_parameter_value
+msgid "Delete records with am index greater than x."
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__display_name
+msgid "Display Name"
+msgstr "اسم العرض"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules__protect_starred
+msgid "Do not delete starred records.\n"
+" Checks for the following fields:\n"
+" - starred\n"
+" - favorite\n"
+" - is_starred\n"
+" - is_favorite"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__domain
+msgid "Domain"
+msgstr "النطاق"
+
+#. module: muk_autovacuum
+#: selection:muk_autovacuum.rules,state:0
+msgid "Domain Based"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "Domain Settings"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "Enter Python code here. Help about Python expression is available in the help tab of this document."
+msgstr ""
+
+#. module: muk_autovacuum
+#: selection:muk_autovacuum.rules,size_type:0
+msgid "Fixed Value"
+msgstr ""
+
+#. module: muk_autovacuum
+#: code:addons/muk_autovacuum/models/ir_autovacuum.py:64
+#: code:addons/muk_autovacuum/models/ir_autovacuum.py:74
+#, python-format
+msgid "GC domain: %s"
+msgstr ""
+
+#. module: muk_autovacuum
+#: code:addons/muk_autovacuum/models/ir_autovacuum.py:71
+#, python-format
+msgid "GC domain: [] order: %s limit: %s"
+msgstr ""
+
+#. module: muk_autovacuum
+#: code:addons/muk_autovacuum/models/ir_autovacuum.py:87
+#, python-format
+msgid "GC'd %s %s records"
+msgstr ""
+
+#. module: muk_autovacuum
+#: code:addons/muk_autovacuum/models/ir_autovacuum.py:83
+#, python-format
+msgid "GC'd %s attachments from %s entries"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_search
+msgid "Group By"
+msgstr "تجميع حسب"
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "Help"
+msgstr "المساعدة"
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "Help with Python expressions"
+msgstr ""
+
+#. module: muk_autovacuum
+#: selection:muk_autovacuum.rules,time_type:0
+msgid "Hours"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__id
+msgid "ID"
+msgstr "المعرف"
+
+#. module: muk_autovacuum
+#: code:addons/muk_autovacuum/models/rules.py:290
+#, python-format
+msgid "Import Template for Auto Vacuum Rules"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules____last_update
+msgid "Last Modified on"
+msgstr "آخر تعديل في"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__write_uid
+msgid "Last Updated by"
+msgstr "آخر تحديث بواسطة"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__write_date
+msgid "Last Updated on"
+msgstr "آخر تحديث في"
+
+#. module: muk_autovacuum
+#: selection:muk_autovacuum.rules,time_type:0
+msgid "Minutes"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__model
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_search
+msgid "Model"
+msgstr "النموذج"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__model_name
+msgid "Model Name"
+msgstr "إسم النموذج"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules__model
+msgid "Model on which the rule is applied."
+msgstr ""
+
+#. module: muk_autovacuum
+#: selection:muk_autovacuum.rules,time_type:0
+msgid "Months"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__name
+msgid "Name"
+msgstr "الاسم"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__only_inactive
+msgid "Only Archived"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__only_attachments
+msgid "Only Attachments"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules__only_inactive
+msgid "Only delete archived records."
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules__only_attachments
+msgid "Only delete record attachments."
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules__size_order
+msgid "Order by which the index is defined."
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__protect_starred
+msgid "Protect Starred"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__state
+msgid "Rule Type"
+msgstr ""
+
+#. module: muk_autovacuum
+#: code:addons/muk_autovacuum/models/rules.py:330
+#, python-format
+msgid "Rule validation has failed!"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__sequence
+msgid "Sequence"
+msgstr "التسلسل"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__size
+msgid "Size"
+msgstr "الحجم"
+
+#. module: muk_autovacuum
+#: selection:muk_autovacuum.rules,state:0
+msgid "Size Based"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__size_order
+msgid "Size Order"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "Size Settings"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__size_type
+msgid "Size Type"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__size_parameter_value
+msgid "Size Value"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__size_parameter
+#: selection:muk_autovacuum.rules,size_type:0
+msgid "System Parameter"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__time
+msgid "Time"
+msgstr ""
+
+#. module: muk_autovacuum
+#: selection:muk_autovacuum.rules,state:0
+msgid "Time Based"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__time_field
+msgid "Time Field"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "Time Settings"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__time_type
+msgid "Time Unit"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "Various fields may use Python code or Python expressions. The following variables can be used:"
+msgstr ""
+
+#. module: muk_autovacuum
+#: selection:muk_autovacuum.rules,time_type:0
+msgid "Weeks"
+msgstr ""
+
+#. module: muk_autovacuum
+#: selection:muk_autovacuum.rules,time_type:0
+msgid "Years"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "e.g. Delete Logs after 30 Days"
+msgstr ""
+
diff --git a/odex-event/muk_autovacuum/i18n/de.po b/odex-event/muk_autovacuum/i18n/de.po
new file mode 100644
index 000000000..cf9d8de6d
--- /dev/null
+++ b/odex-event/muk_autovacuum/i18n/de.po
@@ -0,0 +1,408 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * muk_autovacuum
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 12.0-20190522\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2019-07-12 23:43+0000\n"
+"PO-Revision-Date: 2019-07-12 23:43+0000\n"
+"Last-Translator: <>\n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: \n"
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "Warning: Warning Exception to use with raise"
+msgstr "Warnung: Warnausnahme, die bei einer Erhöhung Anwendung findet"
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "b64encode, b64decode: Base64 converter"
+msgstr "b64encode, b64decode: Base64 Converter"
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "date_format, datetime_format: server date and time formats"
+msgstr "date_format, datetime_format: Serverdatum und Zeitformate"
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "env: Odoo Environment on which the rule is triggered"
+msgstr "env: Odoo Umgebung in welcher die Regel angewendet wird"
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "logger.info(message): Python logging framework"
+msgstr "logger.info(message): Python-Protokollierungs-Framework"
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "model: Odoo Model of the record on which the rule is triggered"
+msgstr "model: Odoo Modell des Datensatzes, auf dem die Regel angewendet wird"
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "time, datetime, dateutil, timezone: useful Python libraries"
+msgstr "time, datetime, dateutil, timezone: nützliche Python-Bibliotheken"
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "uid, user: User on which the rule is triggered"
+msgstr "uid, Benutzer: Benutzer an dem die Regel angewendet wird"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__active
+msgid "Active"
+msgstr "Aktiv"
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_search
+msgid "All"
+msgstr "Alle"
+
+#. module: muk_autovacuum
+#: model:ir.actions.act_window,name:muk_autovacuum.action_autovacuum_rule
+#: model:ir.model,name:muk_autovacuum.model_muk_autovacuum_rules
+#: model:ir.ui.menu,name:muk_autovacuum.menu_autovacuum_rules
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_search
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_tree
+msgid "Auto Vacuum Rules"
+msgstr "Auto Vacuum Regeln"
+
+#. module: muk_autovacuum
+#: model:ir.model,name:muk_autovacuum.model_ir_autovacuum
+msgid "Automatic Vacuum"
+msgstr "Automatisch aufräumen"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__code
+msgid "Code"
+msgstr ""
+
+#. module: muk_autovacuum
+#: selection:muk_autovacuum.rules,state:0
+msgid "Code Based"
+msgstr "Codebasiert"
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "Code Settings"
+msgstr "Codeeinstellungen"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules__code
+msgid "Code which will be executed during the clean up."
+msgstr "Code, der während der Bereinigung ausgeführt wird."
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__create_uid
+msgid "Created by"
+msgstr "Erstellt von"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__create_date
+msgid "Created on"
+msgstr "Erstellt am"
+
+#. module: muk_autovacuum
+#: selection:muk_autovacuum.rules,time_type:0
+msgid "Days"
+msgstr "Tage"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules__domain
+msgid "Delete all records which match the domain."
+msgstr "Löschen Sie alle Datensätze, die mit der Domäne übereinstimmen."
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules__time
+msgid "Delete older data than x."
+msgstr "Ältere Daten als x löschen."
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules__size
+#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules__size_parameter_value
+msgid "Delete records with am index greater than x."
+msgstr "Datensätze mit einem Index größer als x löschen."
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__display_name
+msgid "Display Name"
+msgstr "Anzeigename"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules__protect_starred
+msgid "Do not delete starred records.\n"
+" Checks for the following fields:\n"
+" - starred\n"
+" - favorite\n"
+" - is_starred\n"
+" - is_favorite"
+msgstr "Löscht keine markierten Datensätze.\n"
+" Überprüft die folgenden Felder:\n"
+" - mit Sternen übersät\n"
+" - starred\n"
+" - favorite\n"
+" - is_starred\n"
+" - is_favorite"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__domain
+msgid "Domain"
+msgstr ""
+
+#. module: muk_autovacuum
+#: selection:muk_autovacuum.rules,state:0
+msgid "Domain Based"
+msgstr "Domainenbasiert"
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "Domain Settings"
+msgstr "Domaineinstellungen"
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "Enter Python code here. Help about Python expression is available in the help tab of this document."
+msgstr "Geben Sie Pyhton-Code hier ein. Hife zu Python-Ausdrücken ist in der Hilfe-Registerkarte dieses Dokuments verfügbar."
+
+#. module: muk_autovacuum
+#: selection:muk_autovacuum.rules,size_type:0
+msgid "Fixed Value"
+msgstr "Fixpunktwert"
+
+#. module: muk_autovacuum
+#: code:addons/muk_autovacuum/models/ir_autovacuum.py:64
+#: code:addons/muk_autovacuum/models/ir_autovacuum.py:74
+#, python-format
+msgid "GC domain: %s"
+msgstr "GC Domain: %s"
+
+#. module: muk_autovacuum
+#: code:addons/muk_autovacuum/models/ir_autovacuum.py:71
+#, python-format
+msgid "GC domain: [] order: %s limit: %s"
+msgstr "GC Domain: [] order: %s limit: %s"
+
+#. module: muk_autovacuum
+#: code:addons/muk_autovacuum/models/ir_autovacuum.py:87
+#, python-format
+msgid "GC'd %s %s records"
+msgstr "GC'd %s %s Aufnahmen"
+
+#. module: muk_autovacuum
+#: code:addons/muk_autovacuum/models/ir_autovacuum.py:83
+#, python-format
+msgid "GC'd %s attachments from %s entries"
+msgstr "GC'd %s Anhänge aus %s Einträgen"
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_search
+msgid "Group By"
+msgstr "Gruppieren nach"
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "Help"
+msgstr "Hilfe"
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "Help with Python expressions"
+msgstr "Hilfe mit Python-Ausdrücken"
+
+#. module: muk_autovacuum
+#: selection:muk_autovacuum.rules,time_type:0
+msgid "Hours"
+msgstr "Stunden"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__id
+msgid "ID"
+msgstr ""
+
+#. module: muk_autovacuum
+#: code:addons/muk_autovacuum/models/rules.py:290
+#, python-format
+msgid "Import Template for Auto Vacuum Rules"
+msgstr "Importvorlage für die automatischen Aufräumregeln"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules____last_update
+msgid "Last Modified on"
+msgstr "Zuletzt geändert am"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__write_uid
+msgid "Last Updated by"
+msgstr "Zuletzt aktualisiert durch"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__write_date
+msgid "Last Updated on"
+msgstr "Zuletzt aktualisiert am"
+
+#. module: muk_autovacuum
+#: selection:muk_autovacuum.rules,time_type:0
+msgid "Minutes"
+msgstr "Minuten"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__model
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_search
+msgid "Model"
+msgstr "Modell"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__model_name
+msgid "Model Name"
+msgstr "Modellname"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules__model
+msgid "Model on which the rule is applied."
+msgstr "Modell, auf das die Regel angewendet wird."
+
+#. module: muk_autovacuum
+#: selection:muk_autovacuum.rules,time_type:0
+msgid "Months"
+msgstr "Monate"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__name
+msgid "Name"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__only_inactive
+msgid "Only Archived"
+msgstr "Nur Archiviert"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__only_attachments
+msgid "Only Attachments"
+msgstr "Nur Anhänge"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules__only_inactive
+msgid "Only delete archived records."
+msgstr "Löschen Sie nur archivierte Sätze."
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules__only_attachments
+msgid "Only delete record attachments."
+msgstr "Löschen Sie nur Datensatzanhänge."
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules__size_order
+msgid "Order by which the index is defined."
+msgstr "Reihenfolge, in der der Index definiert ist."
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__protect_starred
+msgid "Protect Starred"
+msgstr "Schützt Favoriten"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__state
+msgid "Rule Type"
+msgstr "Regeltyp"
+
+#. module: muk_autovacuum
+#: code:addons/muk_autovacuum/models/rules.py:330
+#, python-format
+msgid "Rule validation has failed!"
+msgstr "Die Regelvalidierung ist fehlgeschlagen!"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__sequence
+msgid "Sequence"
+msgstr "Nummernfolge"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__size
+msgid "Size"
+msgstr "Größe"
+
+#. module: muk_autovacuum
+#: selection:muk_autovacuum.rules,state:0
+msgid "Size Based"
+msgstr "Größenbasierend"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__size_order
+msgid "Size Order"
+msgstr "Größensortierung"
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "Size Settings"
+msgstr "Größeneinstellung"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__size_type
+msgid "Size Type"
+msgstr "Größe Typ"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__size_parameter_value
+msgid "Size Value"
+msgstr "Größenwert"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__size_parameter
+#: selection:muk_autovacuum.rules,size_type:0
+msgid "System Parameter"
+msgstr "Systemparameter"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__time
+msgid "Time"
+msgstr "Zeit"
+
+#. module: muk_autovacuum
+#: selection:muk_autovacuum.rules,state:0
+msgid "Time Based"
+msgstr "Zeitbasiert"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__time_field
+msgid "Time Field"
+msgstr "Zeitfeld"
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "Time Settings"
+msgstr "Zeiteinstellungen"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__time_type
+msgid "Time Unit"
+msgstr "Zeiteinheit"
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "Various fields may use Python code or Python expressions. The following variables can be used:"
+msgstr "Einige Felder erlauben Python Code oder Python Ausdrücke. Die folgenden Variablen können verwendet werden:"
+
+#. module: muk_autovacuum
+#: selection:muk_autovacuum.rules,time_type:0
+msgid "Weeks"
+msgstr "Wochen"
+
+#. module: muk_autovacuum
+#: selection:muk_autovacuum.rules,time_type:0
+msgid "Years"
+msgstr "Jahre"
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "e.g. Delete Logs after 30 Days"
+msgstr "z.B. Protokolle nach 30 Tagen löschen"
+
diff --git a/odex-event/muk_autovacuum/i18n/es.po b/odex-event/muk_autovacuum/i18n/es.po
new file mode 100644
index 000000000..f0b9e06e4
--- /dev/null
+++ b/odex-event/muk_autovacuum/i18n/es.po
@@ -0,0 +1,407 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * muk_autovacuum
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 12.0-20190522\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2019-07-12 23:43+0000\n"
+"PO-Revision-Date: 2019-07-12 23:43+0000\n"
+"Last-Translator: <>\n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: \n"
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "Warning: Warning Exception to use with raise"
+msgstr "Advertencia: Excepción de Advertencia para usar con aumento"
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "b64encode, b64decode: Base64 converter"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "date_format, datetime_format: server date and time formats"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "env: Odoo Environment on which the rule is triggered"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "logger.info(message): Python logging framework"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "model: Odoo Model of the record on which the rule is triggered"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "time, datetime, dateutil, timezone: useful Python libraries"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "uid, user: User on which the rule is triggered"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__active
+msgid "Active"
+msgstr "Activo"
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_search
+msgid "All"
+msgstr "Todos"
+
+#. module: muk_autovacuum
+#: model:ir.actions.act_window,name:muk_autovacuum.action_autovacuum_rule
+#: model:ir.model,name:muk_autovacuum.model_muk_autovacuum_rules
+#: model:ir.ui.menu,name:muk_autovacuum.menu_autovacuum_rules
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_search
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_tree
+msgid "Auto Vacuum Rules"
+msgstr "Reglas de vacío automático"
+
+#. module: muk_autovacuum
+#: model:ir.model,name:muk_autovacuum.model_ir_autovacuum
+msgid "Automatic Vacuum"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__code
+msgid "Code"
+msgstr "Código"
+
+#. module: muk_autovacuum
+#: selection:muk_autovacuum.rules,state:0
+msgid "Code Based"
+msgstr "Basado en código"
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "Code Settings"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules__code
+msgid "Code which will be executed during the clean up."
+msgstr "Código que se ejecutará durante la limpieza."
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__create_uid
+msgid "Created by"
+msgstr "Creado por"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__create_date
+msgid "Created on"
+msgstr "Creado el"
+
+#. module: muk_autovacuum
+#: selection:muk_autovacuum.rules,time_type:0
+msgid "Days"
+msgstr "Días"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules__domain
+msgid "Delete all records which match the domain."
+msgstr "Elimina todos los registros que coincidan con el dominio."
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules__time
+msgid "Delete older data than x."
+msgstr "Borrar datos anteriores a x."
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules__size
+#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules__size_parameter_value
+msgid "Delete records with am index greater than x."
+msgstr "Eliminar registros con un índice am mayor que x."
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__display_name
+msgid "Display Name"
+msgstr "Nombre mostrado"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules__protect_starred
+msgid "Do not delete starred records.\n"
+" Checks for the following fields:\n"
+" - starred\n"
+" - favorite\n"
+" - is_starred\n"
+" - is_favorite"
+msgstr "No borre los registros marcados con asterisco.\n"
+" Verifica los siguientes campos:\n"
+" - marcado\n"
+" - preferido\n"
+" - is_starred\n"
+" - is_favorite"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__domain
+msgid "Domain"
+msgstr "Dominio"
+
+#. module: muk_autovacuum
+#: selection:muk_autovacuum.rules,state:0
+msgid "Domain Based"
+msgstr "Basado en dominio"
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "Domain Settings"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "Enter Python code here. Help about Python expression is available in the help tab of this document."
+msgstr "Introduzca código Python aquí. Ayuda disponible sobre expresiones Python en la pestaña de ayuda de este documento."
+
+#. module: muk_autovacuum
+#: selection:muk_autovacuum.rules,size_type:0
+msgid "Fixed Value"
+msgstr "Valor Fijo"
+
+#. module: muk_autovacuum
+#: code:addons/muk_autovacuum/models/ir_autovacuum.py:64
+#: code:addons/muk_autovacuum/models/ir_autovacuum.py:74
+#, python-format
+msgid "GC domain: %s"
+msgstr "Dominio GC: %s"
+
+#. module: muk_autovacuum
+#: code:addons/muk_autovacuum/models/ir_autovacuum.py:71
+#, python-format
+msgid "GC domain: [] order: %s limit: %s"
+msgstr "Dominio GC: [] orden: Límite en %s: %s"
+
+#. module: muk_autovacuum
+#: code:addons/muk_autovacuum/models/ir_autovacuum.py:87
+#, python-format
+msgid "GC'd %s %s records"
+msgstr "GC'd %s %s registros"
+
+#. module: muk_autovacuum
+#: code:addons/muk_autovacuum/models/ir_autovacuum.py:83
+#, python-format
+msgid "GC'd %s attachments from %s entries"
+msgstr "GC'd %s adjuntos de las entradas %s"
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_search
+msgid "Group By"
+msgstr "Agrupar por"
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "Help"
+msgstr "Ayuda"
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "Help with Python expressions"
+msgstr "Ayuda con expresiones Python"
+
+#. module: muk_autovacuum
+#: selection:muk_autovacuum.rules,time_type:0
+msgid "Hours"
+msgstr "Horas"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__id
+msgid "ID"
+msgstr ""
+
+#. module: muk_autovacuum
+#: code:addons/muk_autovacuum/models/rules.py:290
+#, python-format
+msgid "Import Template for Auto Vacuum Rules"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules____last_update
+msgid "Last Modified on"
+msgstr "Última modificación en"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__write_uid
+msgid "Last Updated by"
+msgstr "Última actualización por"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__write_date
+msgid "Last Updated on"
+msgstr "Última actualización el"
+
+#. module: muk_autovacuum
+#: selection:muk_autovacuum.rules,time_type:0
+msgid "Minutes"
+msgstr "Actas"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__model
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_search
+msgid "Model"
+msgstr "Modelo"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__model_name
+msgid "Model Name"
+msgstr "Nombre del modelo"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules__model
+msgid "Model on which the rule is applied."
+msgstr "Modelo sobre el que se aplica la norma."
+
+#. module: muk_autovacuum
+#: selection:muk_autovacuum.rules,time_type:0
+msgid "Months"
+msgstr "Meses"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__name
+msgid "Name"
+msgstr "Nombre"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__only_inactive
+msgid "Only Archived"
+msgstr "Sólo archivado"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__only_attachments
+msgid "Only Attachments"
+msgstr "Sólo archivos adjuntos"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules__only_inactive
+msgid "Only delete archived records."
+msgstr "Borrar sólo registros archivados."
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules__only_attachments
+msgid "Only delete record attachments."
+msgstr "Sólo borre los archivos adjuntos de los registros."
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules__size_order
+msgid "Order by which the index is defined."
+msgstr "Orden por el que se define el índice."
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__protect_starred
+msgid "Protect Starred"
+msgstr "Proteger Estrellado"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__state
+msgid "Rule Type"
+msgstr "Clase de regla"
+
+#. module: muk_autovacuum
+#: code:addons/muk_autovacuum/models/rules.py:330
+#, python-format
+msgid "Rule validation has failed!"
+msgstr "La validación de reglas ha fallado!"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__sequence
+msgid "Sequence"
+msgstr "Secuencia"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__size
+msgid "Size"
+msgstr "Tamaño"
+
+#. module: muk_autovacuum
+#: selection:muk_autovacuum.rules,state:0
+msgid "Size Based"
+msgstr "Basado en el tamaño"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__size_order
+msgid "Size Order"
+msgstr "Orden de tallas"
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "Size Settings"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__size_type
+msgid "Size Type"
+msgstr "Tamaño Tipo"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__size_parameter_value
+msgid "Size Value"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__size_parameter
+#: selection:muk_autovacuum.rules,size_type:0
+msgid "System Parameter"
+msgstr "Parámetros del sistema"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__time
+msgid "Time"
+msgstr "Tiempo"
+
+#. module: muk_autovacuum
+#: selection:muk_autovacuum.rules,state:0
+msgid "Time Based"
+msgstr "Basado en el tiempo"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__time_field
+msgid "Time Field"
+msgstr "Campo de tiempo"
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "Time Settings"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__time_type
+msgid "Time Unit"
+msgstr "Unidad de tiempo"
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "Various fields may use Python code or Python expressions. The following variables can be used:"
+msgstr "Varios campos pueden usar código Python o expresiones Python. Se pueden usar las siguientes variables:"
+
+#. module: muk_autovacuum
+#: selection:muk_autovacuum.rules,time_type:0
+msgid "Weeks"
+msgstr "Semanas"
+
+#. module: muk_autovacuum
+#: selection:muk_autovacuum.rules,time_type:0
+msgid "Years"
+msgstr "Años"
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "e.g. Delete Logs after 30 Days"
+msgstr ""
+
diff --git a/odex-event/muk_autovacuum/i18n/fr.po b/odex-event/muk_autovacuum/i18n/fr.po
new file mode 100644
index 000000000..e4a6c8271
--- /dev/null
+++ b/odex-event/muk_autovacuum/i18n/fr.po
@@ -0,0 +1,407 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * muk_autovacuum
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 12.0-20190522\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2019-07-12 23:43+0000\n"
+"PO-Revision-Date: 2019-07-12 23:43+0000\n"
+"Last-Translator: <>\n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: \n"
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "Warning: Warning Exception to use with raise"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "b64encode, b64decode: Base64 converter"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "date_format, datetime_format: server date and time formats"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "env: Odoo Environment on which the rule is triggered"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "logger.info(message): Python logging framework"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "model: Odoo Model of the record on which the rule is triggered"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "time, datetime, dateutil, timezone: useful Python libraries"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "uid, user: User on which the rule is triggered"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__active
+msgid "Active"
+msgstr "Actif"
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_search
+msgid "All"
+msgstr "Tous"
+
+#. module: muk_autovacuum
+#: model:ir.actions.act_window,name:muk_autovacuum.action_autovacuum_rule
+#: model:ir.model,name:muk_autovacuum.model_muk_autovacuum_rules
+#: model:ir.ui.menu,name:muk_autovacuum.menu_autovacuum_rules
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_search
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_tree
+msgid "Auto Vacuum Rules"
+msgstr "Règles de l'aspirateur automatique"
+
+#. module: muk_autovacuum
+#: model:ir.model,name:muk_autovacuum.model_ir_autovacuum
+msgid "Automatic Vacuum"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__code
+msgid "Code"
+msgstr ""
+
+#. module: muk_autovacuum
+#: selection:muk_autovacuum.rules,state:0
+msgid "Code Based"
+msgstr "Basé sur le code"
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "Code Settings"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules__code
+msgid "Code which will be executed during the clean up."
+msgstr "Code qui sera exécuté pendant le nettoyage."
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__create_uid
+msgid "Created by"
+msgstr "Créé par"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__create_date
+msgid "Created on"
+msgstr "Créé le"
+
+#. module: muk_autovacuum
+#: selection:muk_autovacuum.rules,time_type:0
+msgid "Days"
+msgstr "Jours"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules__domain
+msgid "Delete all records which match the domain."
+msgstr "Supprimer tous les enregistrements qui correspondent au domaine."
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules__time
+msgid "Delete older data than x."
+msgstr "Supprimer les données plus anciennes que x."
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules__size
+#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules__size_parameter_value
+msgid "Delete records with am index greater than x."
+msgstr "Supprimer les enregistrements dont l'index am est supérieur à x."
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__display_name
+msgid "Display Name"
+msgstr "Nom affiché"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules__protect_starred
+msgid "Do not delete starred records.\n"
+" Checks for the following fields:\n"
+" - starred\n"
+" - favorite\n"
+" - is_starred\n"
+" - is_favorite"
+msgstr "Ne supprimez pas les disques marqués d'une étoile.\n"
+" Vérification des champs suivants :\n"
+" - étoilés\n"
+" - favori\n"
+" - is_starred\n"
+" - is_favorite"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__domain
+msgid "Domain"
+msgstr "Domaine"
+
+#. module: muk_autovacuum
+#: selection:muk_autovacuum.rules,state:0
+msgid "Domain Based"
+msgstr "Basé sur le domaine"
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "Domain Settings"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "Enter Python code here. Help about Python expression is available in the help tab of this document."
+msgstr "Entrer du code Python ici. Une aide sur l'expression Python est disponible dans l'onglet d'aide de ce document."
+
+#. module: muk_autovacuum
+#: selection:muk_autovacuum.rules,size_type:0
+msgid "Fixed Value"
+msgstr "Valeur fixe"
+
+#. module: muk_autovacuum
+#: code:addons/muk_autovacuum/models/ir_autovacuum.py:64
+#: code:addons/muk_autovacuum/models/ir_autovacuum.py:74
+#, python-format
+msgid "GC domain: %s"
+msgstr "Domaine GC : %s"
+
+#. module: muk_autovacuum
+#: code:addons/muk_autovacuum/models/ir_autovacuum.py:71
+#, python-format
+msgid "GC domain: [] order: %s limit: %s"
+msgstr "GC : (] Ordre : Limite %s : %s"
+
+#. module: muk_autovacuum
+#: code:addons/muk_autovacuum/models/ir_autovacuum.py:87
+#, python-format
+msgid "GC'd %s %s records"
+msgstr ""
+
+#. module: muk_autovacuum
+#: code:addons/muk_autovacuum/models/ir_autovacuum.py:83
+#, python-format
+msgid "GC'd %s attachments from %s entries"
+msgstr "GC'd %s pièces jointes à partir d'entrées %s"
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_search
+msgid "Group By"
+msgstr "Regrouper par"
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "Help"
+msgstr "Aide"
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "Help with Python expressions"
+msgstr "Aide sur les expressions Python"
+
+#. module: muk_autovacuum
+#: selection:muk_autovacuum.rules,time_type:0
+msgid "Hours"
+msgstr "Heures"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__id
+msgid "ID"
+msgstr ""
+
+#. module: muk_autovacuum
+#: code:addons/muk_autovacuum/models/rules.py:290
+#, python-format
+msgid "Import Template for Auto Vacuum Rules"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules____last_update
+msgid "Last Modified on"
+msgstr "Dernière modification le"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__write_uid
+msgid "Last Updated by"
+msgstr "Dernière mise à jour par"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__write_date
+msgid "Last Updated on"
+msgstr "Dernière mise à jour le"
+
+#. module: muk_autovacuum
+#: selection:muk_autovacuum.rules,time_type:0
+msgid "Minutes"
+msgstr "Procès-verbal"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__model
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_search
+msgid "Model"
+msgstr "Modèle"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__model_name
+msgid "Model Name"
+msgstr "Nom de Modèle"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules__model
+msgid "Model on which the rule is applied."
+msgstr "Modèle sur lequel la règle est appliquée."
+
+#. module: muk_autovacuum
+#: selection:muk_autovacuum.rules,time_type:0
+msgid "Months"
+msgstr "Mois"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__name
+msgid "Name"
+msgstr "Nom"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__only_inactive
+msgid "Only Archived"
+msgstr "Uniquement archivé"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__only_attachments
+msgid "Only Attachments"
+msgstr "Uniquement les pièces jointes"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules__only_inactive
+msgid "Only delete archived records."
+msgstr "Ne supprimez que les enregistrements archivés."
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules__only_attachments
+msgid "Only delete record attachments."
+msgstr "Ne supprimez que les pièces jointes d'enregistrement."
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules__size_order
+msgid "Order by which the index is defined."
+msgstr "Ordre dans lequel l'indice est défini."
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__protect_starred
+msgid "Protect Starred"
+msgstr "Protéger Starred"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__state
+msgid "Rule Type"
+msgstr "Type de règle"
+
+#. module: muk_autovacuum
+#: code:addons/muk_autovacuum/models/rules.py:330
+#, python-format
+msgid "Rule validation has failed!"
+msgstr "La validation des règles a échoué !"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__sequence
+msgid "Sequence"
+msgstr "Séquence"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__size
+msgid "Size"
+msgstr "Taille"
+
+#. module: muk_autovacuum
+#: selection:muk_autovacuum.rules,state:0
+msgid "Size Based"
+msgstr "Basé sur la taille"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__size_order
+msgid "Size Order"
+msgstr "Taille Commande"
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "Size Settings"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__size_type
+msgid "Size Type"
+msgstr "Taille Type"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__size_parameter_value
+msgid "Size Value"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__size_parameter
+#: selection:muk_autovacuum.rules,size_type:0
+msgid "System Parameter"
+msgstr "Paramètres du système"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__time
+msgid "Time"
+msgstr "Temps"
+
+#. module: muk_autovacuum
+#: selection:muk_autovacuum.rules,state:0
+msgid "Time Based"
+msgstr "Basé sur le temps"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__time_field
+msgid "Time Field"
+msgstr "Champ horaire"
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "Time Settings"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__time_type
+msgid "Time Unit"
+msgstr "Unité de temps"
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "Various fields may use Python code or Python expressions. The following variables can be used:"
+msgstr "Divers champs peuvent utiliser du code ou des expressions Python. Les variables suivantes peuvent être utilisées :"
+
+#. module: muk_autovacuum
+#: selection:muk_autovacuum.rules,time_type:0
+msgid "Weeks"
+msgstr "Semaines"
+
+#. module: muk_autovacuum
+#: selection:muk_autovacuum.rules,time_type:0
+msgid "Years"
+msgstr "Années"
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "e.g. Delete Logs after 30 Days"
+msgstr ""
+
diff --git a/odex-event/muk_autovacuum/i18n/hi.po b/odex-event/muk_autovacuum/i18n/hi.po
new file mode 100644
index 000000000..ceeed8664
--- /dev/null
+++ b/odex-event/muk_autovacuum/i18n/hi.po
@@ -0,0 +1,402 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * muk_autovacuum
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 12.0-20190522\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2019-07-12 23:44+0000\n"
+"PO-Revision-Date: 2019-07-12 23:44+0000\n"
+"Last-Translator: <>\n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: \n"
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "Warning: Warning Exception to use with raise"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "b64encode, b64decode: Base64 converter"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "date_format, datetime_format: server date and time formats"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "env: Odoo Environment on which the rule is triggered"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "logger.info(message): Python logging framework"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "model: Odoo Model of the record on which the rule is triggered"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "time, datetime, dateutil, timezone: useful Python libraries"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "uid, user: User on which the rule is triggered"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__active
+msgid "Active"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_search
+msgid "All"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.actions.act_window,name:muk_autovacuum.action_autovacuum_rule
+#: model:ir.model,name:muk_autovacuum.model_muk_autovacuum_rules
+#: model:ir.ui.menu,name:muk_autovacuum.menu_autovacuum_rules
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_search
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_tree
+msgid "Auto Vacuum Rules"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model,name:muk_autovacuum.model_ir_autovacuum
+msgid "Automatic Vacuum"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__code
+msgid "Code"
+msgstr ""
+
+#. module: muk_autovacuum
+#: selection:muk_autovacuum.rules,state:0
+msgid "Code Based"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "Code Settings"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules__code
+msgid "Code which will be executed during the clean up."
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__create_uid
+msgid "Created by"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__create_date
+msgid "Created on"
+msgstr ""
+
+#. module: muk_autovacuum
+#: selection:muk_autovacuum.rules,time_type:0
+msgid "Days"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules__domain
+msgid "Delete all records which match the domain."
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules__time
+msgid "Delete older data than x."
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules__size
+#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules__size_parameter_value
+msgid "Delete records with am index greater than x."
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__display_name
+msgid "Display Name"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules__protect_starred
+msgid "Do not delete starred records.\n"
+" Checks for the following fields:\n"
+" - starred\n"
+" - favorite\n"
+" - is_starred\n"
+" - is_favorite"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__domain
+msgid "Domain"
+msgstr ""
+
+#. module: muk_autovacuum
+#: selection:muk_autovacuum.rules,state:0
+msgid "Domain Based"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "Domain Settings"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "Enter Python code here. Help about Python expression is available in the help tab of this document."
+msgstr ""
+
+#. module: muk_autovacuum
+#: selection:muk_autovacuum.rules,size_type:0
+msgid "Fixed Value"
+msgstr ""
+
+#. module: muk_autovacuum
+#: code:addons/muk_autovacuum/models/ir_autovacuum.py:64
+#: code:addons/muk_autovacuum/models/ir_autovacuum.py:74
+#, python-format
+msgid "GC domain: %s"
+msgstr ""
+
+#. module: muk_autovacuum
+#: code:addons/muk_autovacuum/models/ir_autovacuum.py:71
+#, python-format
+msgid "GC domain: [] order: %s limit: %s"
+msgstr ""
+
+#. module: muk_autovacuum
+#: code:addons/muk_autovacuum/models/ir_autovacuum.py:87
+#, python-format
+msgid "GC'd %s %s records"
+msgstr ""
+
+#. module: muk_autovacuum
+#: code:addons/muk_autovacuum/models/ir_autovacuum.py:83
+#, python-format
+msgid "GC'd %s attachments from %s entries"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_search
+msgid "Group By"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "Help"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "Help with Python expressions"
+msgstr ""
+
+#. module: muk_autovacuum
+#: selection:muk_autovacuum.rules,time_type:0
+msgid "Hours"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__id
+msgid "ID"
+msgstr ""
+
+#. module: muk_autovacuum
+#: code:addons/muk_autovacuum/models/rules.py:290
+#, python-format
+msgid "Import Template for Auto Vacuum Rules"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules____last_update
+msgid "Last Modified on"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__write_uid
+msgid "Last Updated by"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__write_date
+msgid "Last Updated on"
+msgstr ""
+
+#. module: muk_autovacuum
+#: selection:muk_autovacuum.rules,time_type:0
+msgid "Minutes"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__model
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_search
+msgid "Model"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__model_name
+msgid "Model Name"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules__model
+msgid "Model on which the rule is applied."
+msgstr ""
+
+#. module: muk_autovacuum
+#: selection:muk_autovacuum.rules,time_type:0
+msgid "Months"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__name
+msgid "Name"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__only_inactive
+msgid "Only Archived"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__only_attachments
+msgid "Only Attachments"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules__only_inactive
+msgid "Only delete archived records."
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules__only_attachments
+msgid "Only delete record attachments."
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules__size_order
+msgid "Order by which the index is defined."
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__protect_starred
+msgid "Protect Starred"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__state
+msgid "Rule Type"
+msgstr ""
+
+#. module: muk_autovacuum
+#: code:addons/muk_autovacuum/models/rules.py:330
+#, python-format
+msgid "Rule validation has failed!"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__sequence
+msgid "Sequence"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__size
+msgid "Size"
+msgstr ""
+
+#. module: muk_autovacuum
+#: selection:muk_autovacuum.rules,state:0
+msgid "Size Based"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__size_order
+msgid "Size Order"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "Size Settings"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__size_type
+msgid "Size Type"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__size_parameter_value
+msgid "Size Value"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__size_parameter
+#: selection:muk_autovacuum.rules,size_type:0
+msgid "System Parameter"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__time
+msgid "Time"
+msgstr ""
+
+#. module: muk_autovacuum
+#: selection:muk_autovacuum.rules,state:0
+msgid "Time Based"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__time_field
+msgid "Time Field"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "Time Settings"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__time_type
+msgid "Time Unit"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "Various fields may use Python code or Python expressions. The following variables can be used:"
+msgstr ""
+
+#. module: muk_autovacuum
+#: selection:muk_autovacuum.rules,time_type:0
+msgid "Weeks"
+msgstr ""
+
+#. module: muk_autovacuum
+#: selection:muk_autovacuum.rules,time_type:0
+msgid "Years"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "e.g. Delete Logs after 30 Days"
+msgstr ""
+
diff --git a/odex-event/muk_autovacuum/i18n/nl.po b/odex-event/muk_autovacuum/i18n/nl.po
new file mode 100644
index 000000000..acd392a58
--- /dev/null
+++ b/odex-event/muk_autovacuum/i18n/nl.po
@@ -0,0 +1,402 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * muk_autovacuum
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 12.0-20190522\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2019-07-12 23:44+0000\n"
+"PO-Revision-Date: 2019-07-12 23:44+0000\n"
+"Last-Translator: <>\n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: \n"
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "Warning: Warning Exception to use with raise"
+msgstr "Waarschuwing: Waarschuwingsfout te gebruiken met roep op"
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "b64encode, b64decode: Base64 converter"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "date_format, datetime_format: server date and time formats"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "env: Odoo Environment on which the rule is triggered"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "logger.info(message): Python logging framework"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "model: Odoo Model of the record on which the rule is triggered"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "time, datetime, dateutil, timezone: useful Python libraries"
+msgstr "time, datetime, dateutil, timezone: handige Python libraries"
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "uid, user: User on which the rule is triggered"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__active
+msgid "Active"
+msgstr "Actief"
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_search
+msgid "All"
+msgstr "Alle"
+
+#. module: muk_autovacuum
+#: model:ir.actions.act_window,name:muk_autovacuum.action_autovacuum_rule
+#: model:ir.model,name:muk_autovacuum.model_muk_autovacuum_rules
+#: model:ir.ui.menu,name:muk_autovacuum.menu_autovacuum_rules
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_search
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_tree
+msgid "Auto Vacuum Rules"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model,name:muk_autovacuum.model_ir_autovacuum
+msgid "Automatic Vacuum"
+msgstr "Automatisch vacuum"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__code
+msgid "Code"
+msgstr ""
+
+#. module: muk_autovacuum
+#: selection:muk_autovacuum.rules,state:0
+msgid "Code Based"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "Code Settings"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules__code
+msgid "Code which will be executed during the clean up."
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__create_uid
+msgid "Created by"
+msgstr "Aangemaakt door"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__create_date
+msgid "Created on"
+msgstr "Aangemaakt op"
+
+#. module: muk_autovacuum
+#: selection:muk_autovacuum.rules,time_type:0
+msgid "Days"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules__domain
+msgid "Delete all records which match the domain."
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules__time
+msgid "Delete older data than x."
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules__size
+#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules__size_parameter_value
+msgid "Delete records with am index greater than x."
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__display_name
+msgid "Display Name"
+msgstr "Weergavenaam"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules__protect_starred
+msgid "Do not delete starred records.\n"
+" Checks for the following fields:\n"
+" - starred\n"
+" - favorite\n"
+" - is_starred\n"
+" - is_favorite"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__domain
+msgid "Domain"
+msgstr "Domein"
+
+#. module: muk_autovacuum
+#: selection:muk_autovacuum.rules,state:0
+msgid "Domain Based"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "Domain Settings"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "Enter Python code here. Help about Python expression is available in the help tab of this document."
+msgstr "Geef hier Python code in. Help over het gebruik van Python expressies is beschikbaar in de help tab van dit document."
+
+#. module: muk_autovacuum
+#: selection:muk_autovacuum.rules,size_type:0
+msgid "Fixed Value"
+msgstr ""
+
+#. module: muk_autovacuum
+#: code:addons/muk_autovacuum/models/ir_autovacuum.py:64
+#: code:addons/muk_autovacuum/models/ir_autovacuum.py:74
+#, python-format
+msgid "GC domain: %s"
+msgstr ""
+
+#. module: muk_autovacuum
+#: code:addons/muk_autovacuum/models/ir_autovacuum.py:71
+#, python-format
+msgid "GC domain: [] order: %s limit: %s"
+msgstr ""
+
+#. module: muk_autovacuum
+#: code:addons/muk_autovacuum/models/ir_autovacuum.py:87
+#, python-format
+msgid "GC'd %s %s records"
+msgstr ""
+
+#. module: muk_autovacuum
+#: code:addons/muk_autovacuum/models/ir_autovacuum.py:83
+#, python-format
+msgid "GC'd %s attachments from %s entries"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_search
+msgid "Group By"
+msgstr "Groepeer op"
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "Help"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "Help with Python expressions"
+msgstr "Help met Python expressies"
+
+#. module: muk_autovacuum
+#: selection:muk_autovacuum.rules,time_type:0
+msgid "Hours"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__id
+msgid "ID"
+msgstr ""
+
+#. module: muk_autovacuum
+#: code:addons/muk_autovacuum/models/rules.py:290
+#, python-format
+msgid "Import Template for Auto Vacuum Rules"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules____last_update
+msgid "Last Modified on"
+msgstr "Laatst gewijzigd op"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__write_uid
+msgid "Last Updated by"
+msgstr "Laatst bijgewerkt door"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__write_date
+msgid "Last Updated on"
+msgstr "Laatst bijgewerkt op"
+
+#. module: muk_autovacuum
+#: selection:muk_autovacuum.rules,time_type:0
+msgid "Minutes"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__model
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_search
+msgid "Model"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__model_name
+msgid "Model Name"
+msgstr "Modelnaam"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules__model
+msgid "Model on which the rule is applied."
+msgstr ""
+
+#. module: muk_autovacuum
+#: selection:muk_autovacuum.rules,time_type:0
+msgid "Months"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__name
+msgid "Name"
+msgstr "Naam"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__only_inactive
+msgid "Only Archived"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__only_attachments
+msgid "Only Attachments"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules__only_inactive
+msgid "Only delete archived records."
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules__only_attachments
+msgid "Only delete record attachments."
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules__size_order
+msgid "Order by which the index is defined."
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__protect_starred
+msgid "Protect Starred"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__state
+msgid "Rule Type"
+msgstr ""
+
+#. module: muk_autovacuum
+#: code:addons/muk_autovacuum/models/rules.py:330
+#, python-format
+msgid "Rule validation has failed!"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__sequence
+msgid "Sequence"
+msgstr "Volgorde"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__size
+msgid "Size"
+msgstr "Grootte"
+
+#. module: muk_autovacuum
+#: selection:muk_autovacuum.rules,state:0
+msgid "Size Based"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__size_order
+msgid "Size Order"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "Size Settings"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__size_type
+msgid "Size Type"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__size_parameter_value
+msgid "Size Value"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__size_parameter
+#: selection:muk_autovacuum.rules,size_type:0
+msgid "System Parameter"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__time
+msgid "Time"
+msgstr ""
+
+#. module: muk_autovacuum
+#: selection:muk_autovacuum.rules,state:0
+msgid "Time Based"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__time_field
+msgid "Time Field"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "Time Settings"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__time_type
+msgid "Time Unit"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "Various fields may use Python code or Python expressions. The following variables can be used:"
+msgstr "Verschillende velden mogen Python code of Python expressies gebruiken. De volgende variabelen mogen worden gebruikt:"
+
+#. module: muk_autovacuum
+#: selection:muk_autovacuum.rules,time_type:0
+msgid "Weeks"
+msgstr ""
+
+#. module: muk_autovacuum
+#: selection:muk_autovacuum.rules,time_type:0
+msgid "Years"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "e.g. Delete Logs after 30 Days"
+msgstr ""
+
diff --git a/odex-event/muk_autovacuum/i18n/pt.po b/odex-event/muk_autovacuum/i18n/pt.po
new file mode 100644
index 000000000..7487fb78a
--- /dev/null
+++ b/odex-event/muk_autovacuum/i18n/pt.po
@@ -0,0 +1,402 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * muk_autovacuum
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 12.0-20190522\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2019-07-12 23:44+0000\n"
+"PO-Revision-Date: 2019-07-12 23:44+0000\n"
+"Last-Translator: <>\n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: \n"
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "Warning: Warning Exception to use with raise"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "b64encode, b64decode: Base64 converter"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "date_format, datetime_format: server date and time formats"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "env: Odoo Environment on which the rule is triggered"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "logger.info(message): Python logging framework"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "model: Odoo Model of the record on which the rule is triggered"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "time, datetime, dateutil, timezone: useful Python libraries"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "uid, user: User on which the rule is triggered"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__active
+msgid "Active"
+msgstr "Ativo"
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_search
+msgid "All"
+msgstr "Todas"
+
+#. module: muk_autovacuum
+#: model:ir.actions.act_window,name:muk_autovacuum.action_autovacuum_rule
+#: model:ir.model,name:muk_autovacuum.model_muk_autovacuum_rules
+#: model:ir.ui.menu,name:muk_autovacuum.menu_autovacuum_rules
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_search
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_tree
+msgid "Auto Vacuum Rules"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model,name:muk_autovacuum.model_ir_autovacuum
+msgid "Automatic Vacuum"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__code
+msgid "Code"
+msgstr ""
+
+#. module: muk_autovacuum
+#: selection:muk_autovacuum.rules,state:0
+msgid "Code Based"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "Code Settings"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules__code
+msgid "Code which will be executed during the clean up."
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__create_uid
+msgid "Created by"
+msgstr "Criado por"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__create_date
+msgid "Created on"
+msgstr "Criada em"
+
+#. module: muk_autovacuum
+#: selection:muk_autovacuum.rules,time_type:0
+msgid "Days"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules__domain
+msgid "Delete all records which match the domain."
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules__time
+msgid "Delete older data than x."
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules__size
+#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules__size_parameter_value
+msgid "Delete records with am index greater than x."
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__display_name
+msgid "Display Name"
+msgstr "Nome a Exibir"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules__protect_starred
+msgid "Do not delete starred records.\n"
+" Checks for the following fields:\n"
+" - starred\n"
+" - favorite\n"
+" - is_starred\n"
+" - is_favorite"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__domain
+msgid "Domain"
+msgstr "Domínio"
+
+#. module: muk_autovacuum
+#: selection:muk_autovacuum.rules,state:0
+msgid "Domain Based"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "Domain Settings"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "Enter Python code here. Help about Python expression is available in the help tab of this document."
+msgstr ""
+
+#. module: muk_autovacuum
+#: selection:muk_autovacuum.rules,size_type:0
+msgid "Fixed Value"
+msgstr ""
+
+#. module: muk_autovacuum
+#: code:addons/muk_autovacuum/models/ir_autovacuum.py:64
+#: code:addons/muk_autovacuum/models/ir_autovacuum.py:74
+#, python-format
+msgid "GC domain: %s"
+msgstr ""
+
+#. module: muk_autovacuum
+#: code:addons/muk_autovacuum/models/ir_autovacuum.py:71
+#, python-format
+msgid "GC domain: [] order: %s limit: %s"
+msgstr ""
+
+#. module: muk_autovacuum
+#: code:addons/muk_autovacuum/models/ir_autovacuum.py:87
+#, python-format
+msgid "GC'd %s %s records"
+msgstr ""
+
+#. module: muk_autovacuum
+#: code:addons/muk_autovacuum/models/ir_autovacuum.py:83
+#, python-format
+msgid "GC'd %s attachments from %s entries"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_search
+msgid "Group By"
+msgstr "Agrupar Por"
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "Help"
+msgstr "Ajuda"
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "Help with Python expressions"
+msgstr ""
+
+#. module: muk_autovacuum
+#: selection:muk_autovacuum.rules,time_type:0
+msgid "Hours"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__id
+msgid "ID"
+msgstr "Id."
+
+#. module: muk_autovacuum
+#: code:addons/muk_autovacuum/models/rules.py:290
+#, python-format
+msgid "Import Template for Auto Vacuum Rules"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules____last_update
+msgid "Last Modified on"
+msgstr "Última Modificação em"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__write_uid
+msgid "Last Updated by"
+msgstr "Última Atualização por"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__write_date
+msgid "Last Updated on"
+msgstr "Última Atualização em"
+
+#. module: muk_autovacuum
+#: selection:muk_autovacuum.rules,time_type:0
+msgid "Minutes"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__model
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_search
+msgid "Model"
+msgstr "Modelo"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__model_name
+msgid "Model Name"
+msgstr "Nome do Modelo"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules__model
+msgid "Model on which the rule is applied."
+msgstr ""
+
+#. module: muk_autovacuum
+#: selection:muk_autovacuum.rules,time_type:0
+msgid "Months"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__name
+msgid "Name"
+msgstr "Nome"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__only_inactive
+msgid "Only Archived"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__only_attachments
+msgid "Only Attachments"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules__only_inactive
+msgid "Only delete archived records."
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules__only_attachments
+msgid "Only delete record attachments."
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules__size_order
+msgid "Order by which the index is defined."
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__protect_starred
+msgid "Protect Starred"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__state
+msgid "Rule Type"
+msgstr ""
+
+#. module: muk_autovacuum
+#: code:addons/muk_autovacuum/models/rules.py:330
+#, python-format
+msgid "Rule validation has failed!"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__sequence
+msgid "Sequence"
+msgstr "Sequência"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__size
+msgid "Size"
+msgstr "Tamanho"
+
+#. module: muk_autovacuum
+#: selection:muk_autovacuum.rules,state:0
+msgid "Size Based"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__size_order
+msgid "Size Order"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "Size Settings"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__size_type
+msgid "Size Type"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__size_parameter_value
+msgid "Size Value"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__size_parameter
+#: selection:muk_autovacuum.rules,size_type:0
+msgid "System Parameter"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__time
+msgid "Time"
+msgstr ""
+
+#. module: muk_autovacuum
+#: selection:muk_autovacuum.rules,state:0
+msgid "Time Based"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__time_field
+msgid "Time Field"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "Time Settings"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__time_type
+msgid "Time Unit"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "Various fields may use Python code or Python expressions. The following variables can be used:"
+msgstr ""
+
+#. module: muk_autovacuum
+#: selection:muk_autovacuum.rules,time_type:0
+msgid "Weeks"
+msgstr ""
+
+#. module: muk_autovacuum
+#: selection:muk_autovacuum.rules,time_type:0
+msgid "Years"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "e.g. Delete Logs after 30 Days"
+msgstr ""
+
diff --git a/odex-event/muk_autovacuum/i18n/ru.po b/odex-event/muk_autovacuum/i18n/ru.po
new file mode 100644
index 000000000..ea2864df1
--- /dev/null
+++ b/odex-event/muk_autovacuum/i18n/ru.po
@@ -0,0 +1,402 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * muk_autovacuum
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 12.0-20190522\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2019-07-12 23:45+0000\n"
+"PO-Revision-Date: 2019-07-12 23:45+0000\n"
+"Last-Translator: <>\n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: \n"
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "Warning: Warning Exception to use with raise"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "b64encode, b64decode: Base64 converter"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "date_format, datetime_format: server date and time formats"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "env: Odoo Environment on which the rule is triggered"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "logger.info(message): Python logging framework"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "model: Odoo Model of the record on which the rule is triggered"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "time, datetime, dateutil, timezone: useful Python libraries"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "uid, user: User on which the rule is triggered"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__active
+msgid "Active"
+msgstr "Активно"
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_search
+msgid "All"
+msgstr "Все"
+
+#. module: muk_autovacuum
+#: model:ir.actions.act_window,name:muk_autovacuum.action_autovacuum_rule
+#: model:ir.model,name:muk_autovacuum.model_muk_autovacuum_rules
+#: model:ir.ui.menu,name:muk_autovacuum.menu_autovacuum_rules
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_search
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_tree
+msgid "Auto Vacuum Rules"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model,name:muk_autovacuum.model_ir_autovacuum
+msgid "Automatic Vacuum"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__code
+msgid "Code"
+msgstr ""
+
+#. module: muk_autovacuum
+#: selection:muk_autovacuum.rules,state:0
+msgid "Code Based"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "Code Settings"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules__code
+msgid "Code which will be executed during the clean up."
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__create_uid
+msgid "Created by"
+msgstr "Создано"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__create_date
+msgid "Created on"
+msgstr "Создан"
+
+#. module: muk_autovacuum
+#: selection:muk_autovacuum.rules,time_type:0
+msgid "Days"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules__domain
+msgid "Delete all records which match the domain."
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules__time
+msgid "Delete older data than x."
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules__size
+#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules__size_parameter_value
+msgid "Delete records with am index greater than x."
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__display_name
+msgid "Display Name"
+msgstr "Отображаемое Имя"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules__protect_starred
+msgid "Do not delete starred records.\n"
+" Checks for the following fields:\n"
+" - starred\n"
+" - favorite\n"
+" - is_starred\n"
+" - is_favorite"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__domain
+msgid "Domain"
+msgstr "Домен"
+
+#. module: muk_autovacuum
+#: selection:muk_autovacuum.rules,state:0
+msgid "Domain Based"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "Domain Settings"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "Enter Python code here. Help about Python expression is available in the help tab of this document."
+msgstr "Введите код Python здесь. Помощь о Python доступна в колонке справка в этом документе."
+
+#. module: muk_autovacuum
+#: selection:muk_autovacuum.rules,size_type:0
+msgid "Fixed Value"
+msgstr ""
+
+#. module: muk_autovacuum
+#: code:addons/muk_autovacuum/models/ir_autovacuum.py:64
+#: code:addons/muk_autovacuum/models/ir_autovacuum.py:74
+#, python-format
+msgid "GC domain: %s"
+msgstr ""
+
+#. module: muk_autovacuum
+#: code:addons/muk_autovacuum/models/ir_autovacuum.py:71
+#, python-format
+msgid "GC domain: [] order: %s limit: %s"
+msgstr ""
+
+#. module: muk_autovacuum
+#: code:addons/muk_autovacuum/models/ir_autovacuum.py:87
+#, python-format
+msgid "GC'd %s %s records"
+msgstr ""
+
+#. module: muk_autovacuum
+#: code:addons/muk_autovacuum/models/ir_autovacuum.py:83
+#, python-format
+msgid "GC'd %s attachments from %s entries"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_search
+msgid "Group By"
+msgstr "Группировать по"
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "Help"
+msgstr "Помощь"
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "Help with Python expressions"
+msgstr ""
+
+#. module: muk_autovacuum
+#: selection:muk_autovacuum.rules,time_type:0
+msgid "Hours"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__id
+msgid "ID"
+msgstr "Номер"
+
+#. module: muk_autovacuum
+#: code:addons/muk_autovacuum/models/rules.py:290
+#, python-format
+msgid "Import Template for Auto Vacuum Rules"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules____last_update
+msgid "Last Modified on"
+msgstr "Последнее изменение"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__write_uid
+msgid "Last Updated by"
+msgstr "Последний раз обновил"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__write_date
+msgid "Last Updated on"
+msgstr "Последнее обновление"
+
+#. module: muk_autovacuum
+#: selection:muk_autovacuum.rules,time_type:0
+msgid "Minutes"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__model
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_search
+msgid "Model"
+msgstr "Модель"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__model_name
+msgid "Model Name"
+msgstr "Название модели"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules__model
+msgid "Model on which the rule is applied."
+msgstr ""
+
+#. module: muk_autovacuum
+#: selection:muk_autovacuum.rules,time_type:0
+msgid "Months"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__name
+msgid "Name"
+msgstr "Название"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__only_inactive
+msgid "Only Archived"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__only_attachments
+msgid "Only Attachments"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules__only_inactive
+msgid "Only delete archived records."
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules__only_attachments
+msgid "Only delete record attachments."
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules__size_order
+msgid "Order by which the index is defined."
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__protect_starred
+msgid "Protect Starred"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__state
+msgid "Rule Type"
+msgstr ""
+
+#. module: muk_autovacuum
+#: code:addons/muk_autovacuum/models/rules.py:330
+#, python-format
+msgid "Rule validation has failed!"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__sequence
+msgid "Sequence"
+msgstr "Нумерация"
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__size
+msgid "Size"
+msgstr "Размер"
+
+#. module: muk_autovacuum
+#: selection:muk_autovacuum.rules,state:0
+msgid "Size Based"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__size_order
+msgid "Size Order"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "Size Settings"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__size_type
+msgid "Size Type"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__size_parameter_value
+msgid "Size Value"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__size_parameter
+#: selection:muk_autovacuum.rules,size_type:0
+msgid "System Parameter"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__time
+msgid "Time"
+msgstr ""
+
+#. module: muk_autovacuum
+#: selection:muk_autovacuum.rules,state:0
+msgid "Time Based"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__time_field
+msgid "Time Field"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "Time Settings"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__time_type
+msgid "Time Unit"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "Various fields may use Python code or Python expressions. The following variables can be used:"
+msgstr "Различные поля могут использовать код Python или выражения Python. Могут использоваться следующие переменные:"
+
+#. module: muk_autovacuum
+#: selection:muk_autovacuum.rules,time_type:0
+msgid "Weeks"
+msgstr ""
+
+#. module: muk_autovacuum
+#: selection:muk_autovacuum.rules,time_type:0
+msgid "Years"
+msgstr ""
+
+#. module: muk_autovacuum
+#: model_terms:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form
+msgid "e.g. Delete Logs after 30 Days"
+msgstr ""
+
diff --git a/odex-event/muk_autovacuum/models/__init__.py b/odex-event/muk_autovacuum/models/__init__.py
new file mode 100644
index 000000000..b8a051f07
--- /dev/null
+++ b/odex-event/muk_autovacuum/models/__init__.py
@@ -0,0 +1,24 @@
+###################################################################################
+#
+# Copyright (c) 2017-2019 MuK IT GmbH.
+#
+# This file is part of MuK Autovacuum
+# (see https://mukit.at).
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see .
+#
+###################################################################################
+
+from . import rules
+from . import ir_autovacuum
\ No newline at end of file
diff --git a/odex-event/muk_autovacuum/models/ir_autovacuum.py b/odex-event/muk_autovacuum/models/ir_autovacuum.py
new file mode 100644
index 000000000..1b0875ed9
--- /dev/null
+++ b/odex-event/muk_autovacuum/models/ir_autovacuum.py
@@ -0,0 +1,90 @@
+###################################################################################
+#
+# Copyright (c) 2017-2019 MuK IT GmbH.
+#
+# This file is part of MuK Autovacuum
+# (see https://mukit.at).
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see .
+#
+###################################################################################
+
+import time
+import logging
+import datetime
+import dateutil
+
+from odoo import _
+from odoo import models, api, fields
+from odoo.tools.safe_eval import safe_eval
+
+_logger = logging.getLogger(__name__)
+
+_types = {
+ 'days': lambda interval: datetime.timedelta(days=interval),
+ 'years': lambda interval: datetime.timedelta(weeks=interval*52),
+ 'hours': lambda interval: datetime.timedelta(hours=interval),
+ 'weeks': lambda interval: datetime.timedelta(weeks=interval),
+ 'months': lambda interval: datetime.timedelta(days=interval*30),
+ 'minutes': lambda interval: datetime.timedelta(minutes=interval),
+}
+
+class AutoVacuum(models.AbstractModel):
+
+ _inherit = 'ir.autovacuum'
+
+ @api.model
+ def power_on(self, *args, **kwargs):
+ res = super(AutoVacuum, self).power_on(*args, **kwargs)
+ rules = self.env['muk_autovacuum.rules'].sudo().search([], order='sequence asc')
+ for rule in rules:
+ if rule.state in ['time', 'size', 'domain']:
+ model = self.env[rule.model.model].sudo()
+ records = self.env[rule.model.model]
+ if rule.state == 'time':
+ computed_time = datetime.datetime.utcnow() - _types[rule.time_type](rule.time)
+ domain = [(rule.time_field.name, '<', fields.Datetime.to_string(computed_time))]
+ if rule.protect_starred:
+ for field in rule.model.field_id:
+ if field.name in ['starred', 'favorite', 'is_starred', 'is_favorite']:
+ domain.append((field.name, '=', False))
+ if rule.only_inactive and "active" in rule.model.field_id.mapped("name"):
+ domain.append(('active', '=', False))
+ _logger.info(_("GC domain: %s"), domain)
+ records = model.with_context(active_test=False).search(domain)
+ elif rule.state == 'size':
+ size = rule.size if rule.size_type == 'fixed' else rule.size_parameter_value
+ count = model.with_context(active_test=False).search([], count=True)
+ if size and size > 0 and count > size:
+ limit = count - size
+ _logger.info(_("GC domain: [] order: %s limit: %s"), rule.size_order, limit)
+ records = model.with_context(active_test=False).search([], order=rule.size_order, limit=limit)
+ elif rule.state == 'domain':
+ _logger.info(_("GC domain: %s"), rule.domain)
+ domain = safe_eval(rule.domain or "[]", rules._get_eval_domain_context())
+ records = model.with_context(active_test=False).search(domain)
+ if rule.only_attachments:
+ attachments = self.env['ir.attachment'].sudo().search([
+ ('res_model', '=', rule.model.model),
+ ('res_id', 'in', records.mapped('id'))])
+ count = len(attachments)
+ attachments.unlink()
+ _logger.info(_("GC'd %s attachments from %s entries"), count, rule.model.model)
+ else:
+ count = len(records)
+ records.unlink()
+ _logger.info(_("GC'd %s %s records"), count, rule.model.model)
+ elif rule.state == 'code':
+ safe_eval(rule.code.strip(), rules._get_eval_code_context(rule), mode="exec")
+ return res
\ No newline at end of file
diff --git a/odex-event/muk_autovacuum/models/rules.py b/odex-event/muk_autovacuum/models/rules.py
new file mode 100644
index 000000000..c2dccf3b8
--- /dev/null
+++ b/odex-event/muk_autovacuum/models/rules.py
@@ -0,0 +1,330 @@
+###################################################################################
+#
+# Copyright (c) 2017-2019 MuK IT GmbH.
+#
+# This file is part of MuK Autovacuum
+# (see https://mukit.at).
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see .
+#
+###################################################################################
+
+import time
+import base64
+import logging
+import datetime
+import dateutil
+
+from pytz import timezone
+
+from odoo import _
+from odoo import models, api, fields
+from odoo.exceptions import ValidationError, Warning
+from odoo.tools import DEFAULT_SERVER_DATE_FORMAT
+from odoo.tools import DEFAULT_SERVER_DATETIME_FORMAT
+from odoo.tools.safe_eval import safe_eval, test_python_expr
+
+_logger = logging.getLogger(__name__)
+
+class AutoVacuumRules(models.Model):
+
+ _name = 'muk_autovacuum.rules'
+ _description = "Auto Vacuum Rules"
+ _order = "sequence asc"
+
+ #----------------------------------------------------------
+ # Defaults
+ #----------------------------------------------------------
+
+ def _default_sequence(self):
+ record = self.sudo().search([], order='sequence desc', limit=1)
+ if record.exists():
+ return record.sequence + 1
+ else:
+ return 1
+
+ #----------------------------------------------------------
+ # Database
+ #----------------------------------------------------------
+
+ name = fields.Char(
+ string='Name',
+ required=True)
+
+ active = fields.Boolean(
+ string='Active',
+ default=True)
+
+ state = fields.Selection(
+ selection=[
+ ('time', 'Time Based'),
+ ('size', 'Size Based'),
+ ('domain', 'Domain Based'),
+ ('code', 'Code Based')],
+ string='Rule Type',
+ default='time',
+ required=True)
+
+ sequence = fields.Integer(
+ string='Sequence',
+ default=lambda self: self._default_sequence(),
+ required=True)
+
+ model = fields.Many2one(
+ comodel_name='ir.model',
+ string="Model",
+ required=True,
+ ondelete='cascade',
+ help="Model on which the rule is applied.")
+
+ model_name = fields.Char(
+ related='model.model',
+ string="Model Name",
+ readonly=True,
+ store=True)
+
+ time_field = fields.Many2one(
+ comodel_name='ir.model.fields',
+ domain="[('model_id', '=', model), ('ttype', '=', 'datetime')]",
+ string='Time Field',
+ ondelete='cascade',
+ states={
+ 'time': [('required', True)],
+ 'size': [('invisible', True)],
+ 'domain': [('invisible', True)],
+ 'code': [('invisible', True)]})
+
+ time_type = fields.Selection(
+ selection=[
+ ('minutes', 'Minutes'),
+ ('hours', 'Hours'),
+ ('days', 'Days'),
+ ('weeks', 'Weeks'),
+ ('months', 'Months'),
+ ('years', 'Years')],
+ string='Time Unit',
+ default='months',
+ states={
+ 'time': [('required', True)],
+ 'size': [('invisible', True)],
+ 'domain': [('invisible', True)],
+ 'code': [('invisible', True)]})
+
+ time = fields.Integer(
+ string='Time',
+ default=1,
+ states={
+ 'time': [('required', True)],
+ 'size': [('invisible', True)],
+ 'domain': [('invisible', True)],
+ 'code': [('invisible', True)]},
+ help="Delete older data than x.")
+
+ size_type = fields.Selection(
+ selection=[
+ ('fixed', 'Fixed Value'),
+ ('parameter', 'System Parameter')],
+ string='Size Type',
+ default='fixed',
+ states={
+ 'time': [('invisible', True)],
+ 'size': [('required', True)],
+ 'domain': [('invisible', True)],
+ 'code': [('invisible', True)]})
+
+ size_parameter = fields.Many2one(
+ comodel_name='ir.config_parameter',
+ string='System Parameter',
+ ondelete='cascade',
+ states={
+ 'time': [('invisible', True)],
+ 'size': [('required', True)],
+ 'domain': [('invisible', True)],
+ 'code': [('invisible', True)]})
+
+ size_parameter_value = fields.Integer(
+ compute='_compute_size_parameter_value',
+ string='Size Value',
+ states={
+ 'time': [('invisible', True)],
+ 'size': [('readonly', True)],
+ 'domain': [('invisible', True)],
+ 'code': [('invisible', True)]},
+ help="Delete records with am index greater than x.")
+
+ size_order = fields.Char(
+ string='Size Order',
+ default='create_date desc',
+ states={
+ 'time': [('invisible', True)],
+ 'size': [('required', True)],
+ 'domain': [('invisible', True)],
+ 'code': [('invisible', True)]},
+ help="Order by which the index is defined.")
+
+ size = fields.Integer(
+ string='Size',
+ default=200,
+ states={
+ 'time': [('invisible', True)],
+ 'size': [('required', True)],
+ 'domain': [('invisible', True)],
+ 'code': [('invisible', True)]},
+ help="Delete records with am index greater than x.")
+
+ domain = fields.Char(
+ string='Domain',
+ states={
+ 'time': [('invisible', True)],
+ 'size': [('invisible', True)],
+ 'domain': [('required', True)],
+ 'code': [('invisible', True)]},
+ help="Delete all records which match the domain.")
+
+ code = fields.Text(
+ string='Code',
+ states={
+ 'time': [('invisible', True)],
+ 'size': [('invisible', True)],
+ 'domain': [('invisible', True)] ,
+ 'code': [('required', True)]},
+ default="# Enter Python code here. Help about Python expression is available in the help tab of this document.",
+ help="Code which will be executed during the clean up.")
+
+ protect_starred = fields.Boolean(
+ string='Protect Starred',
+ default=True,
+ states={
+ 'time': [('invisible', False)],
+ 'size': [('invisible', True)],
+ 'domain': [('invisible', True)],
+ 'code': [('invisible', True)]},
+ help="""Do not delete starred records.
+ Checks for the following fields:
+ - starred
+ - favorite
+ - is_starred
+ - is_favorite""")
+
+ only_inactive = fields.Boolean(
+ string='Only Archived',
+ default=False,
+ states={
+ 'time': [('invisible', False)],
+ 'size': [('invisible', True)],
+ 'domain': [('invisible', True)],
+ 'code': [('invisible', True)]},
+ help="Only delete archived records.")
+
+ only_attachments = fields.Boolean(
+ string='Only Attachments',
+ default=False,
+ states={
+ 'time': [('invisible', False)],
+ 'size': [('invisible', False)],
+ 'domain': [('invisible', False)],
+ 'code': [('invisible', True)]},
+ help="Only delete record attachments.")
+
+ #----------------------------------------------------------
+ # Functions
+ #----------------------------------------------------------
+
+ @api.model
+ def _get_eval_domain_context(self):
+ return {
+ 'datetime': datetime,
+ 'dateutil': dateutil,
+ 'timezone': timezone,
+ 'time': time,
+ 'uid': self.env.uid,
+ 'user': self.env.user
+ }
+
+ @api.model
+ def _get_eval_code_context(self, rule):
+ return {
+ 'env': self.env,
+ 'model': self.env[rule.model_name],
+ 'uid': self.env.user.id,
+ 'user': self.env.user,
+ 'time': time,
+ 'datetime': datetime,
+ 'dateutil': dateutil,
+ 'timezone': timezone,
+ 'b64encode': base64.b64encode,
+ 'b64decode': base64.b64decode,
+ 'date_format': DEFAULT_SERVER_DATE_FORMAT,
+ 'datetime_format': DEFAULT_SERVER_DATETIME_FORMAT,
+ 'Warning': Warning,
+ 'logger': logging.getLogger("%s (%s)" % (__name__, rule.name)),
+ }
+
+ #----------------------------------------------------------
+ # View
+ #----------------------------------------------------------
+
+ @api.onchange('model')
+ def _onchange_model(self):
+ field_domain = [
+ ('model_id', '=', self.model.id),
+ ('ttype', '=', 'datetime'),
+ ('name', '=', 'create_date')]
+ model = self.env['ir.model.fields'].sudo()
+ self.time_field = model.search(field_domain, limit=1)
+
+ @api.model
+ def get_import_templates(self):
+ return [{
+ 'label': _('Import Template for Auto Vacuum Rules'),
+ 'template': '/muk_autovacuum/static/xls/muk_autovacuum_rules.xls'
+ }]
+
+ #----------------------------------------------------------
+ # Read
+ #----------------------------------------------------------
+
+ @api.depends('size_parameter')
+ def _compute_size_parameter_value(self):
+ for record in self:
+ try:
+ record.size_parameter_value = int(record.size_parameter.value)
+ except ValueError:
+ record.size_parameter_value = None
+
+ #----------------------------------------------------------
+ # Create, Update, Delete
+ #----------------------------------------------------------
+
+ @api.constrains('code')
+ def _check_code(self):
+ for record in self.sudo().filtered('code'):
+ message = test_python_expr(expr=record.code.strip(), mode="exec")
+ if message:
+ raise ValidationError(message)
+
+ @api.constrains(
+ 'state', 'model', 'domain', 'code',
+ 'time_field', 'time_type', 'time',
+ 'size_type', 'size_parameter', 'size_order', 'size')
+ def _validate(self):
+ validators = {
+ 'time': lambda rec: rec.time_field and rec.time_type and rec.time,
+ 'size': lambda rec: rec.size_order and (rec.size_parameter or rec.size),
+ 'domain': lambda rec: rec.domain,
+ 'code': lambda rec: rec.code,
+ }
+ for record in self:
+ if not validators[record.state](record):
+ raise ValidationError(_("Rule validation has failed!"))
\ No newline at end of file
diff --git a/odex-event/muk_autovacuum/security/ir.model.access.csv b/odex-event/muk_autovacuum/security/ir.model.access.csv
new file mode 100644
index 000000000..a3690893a
--- /dev/null
+++ b/odex-event/muk_autovacuum/security/ir.model.access.csv
@@ -0,0 +1,3 @@
+id,name,model_id/id,group_id/id,perm_read,perm_write,perm_create,perm_unlink
+
+access_muk_autovacuum_rules_group_cron,muk_autovacuum_rules group_rules,model_muk_autovacuum_rules,base.group_system,1,1,1,1
\ No newline at end of file
diff --git a/odex-event/muk_autovacuum/static/description/banner.png b/odex-event/muk_autovacuum/static/description/banner.png
new file mode 100644
index 000000000..488c2ebe8
Binary files /dev/null and b/odex-event/muk_autovacuum/static/description/banner.png differ
diff --git a/odex-event/muk_autovacuum/static/description/icon.png b/odex-event/muk_autovacuum/static/description/icon.png
new file mode 100644
index 000000000..e7654ddf6
Binary files /dev/null and b/odex-event/muk_autovacuum/static/description/icon.png differ
diff --git a/odex-event/muk_autovacuum/static/description/icon.svg b/odex-event/muk_autovacuum/static/description/icon.svg
new file mode 100644
index 000000000..a2f1e299e
--- /dev/null
+++ b/odex-event/muk_autovacuum/static/description/icon.svg
@@ -0,0 +1,38 @@
+
+
+
\ No newline at end of file
diff --git a/odex-event/muk_autovacuum/static/description/index.html b/odex-event/muk_autovacuum/static/description/index.html
new file mode 100644
index 000000000..635dbdfb1
--- /dev/null
+++ b/odex-event/muk_autovacuum/static/description/index.html
@@ -0,0 +1,128 @@
+
+
+
MuK Auto Vacuum
+
Configure automatic garbage collection
+
MuK IT GmbH -
+ www.mukit.at
+
+
+
+
+
+
+
+
+
+
Overview
+
Allows the administrator to create rules to
+ automatically garbage collect a certain model. Every rule can have a
+ different time interval additional constraints. An extra constraint
+ can be for example to only delete inactive records.
+
+
\ No newline at end of file
diff --git a/odex-event/muk_autovacuum/static/description/logo.png b/odex-event/muk_autovacuum/static/description/logo.png
new file mode 100644
index 000000000..9427ce33e
Binary files /dev/null and b/odex-event/muk_autovacuum/static/description/logo.png differ
diff --git a/odex-event/muk_autovacuum/static/description/preview.png b/odex-event/muk_autovacuum/static/description/preview.png
new file mode 100644
index 000000000..1deb1ccef
Binary files /dev/null and b/odex-event/muk_autovacuum/static/description/preview.png differ
diff --git a/odex-event/muk_autovacuum/static/description/screenshot.png b/odex-event/muk_autovacuum/static/description/screenshot.png
new file mode 100644
index 000000000..ef9395f88
Binary files /dev/null and b/odex-event/muk_autovacuum/static/description/screenshot.png differ
diff --git a/odex-event/muk_autovacuum/static/description/service_customization.png b/odex-event/muk_autovacuum/static/description/service_customization.png
new file mode 100644
index 000000000..3eac66488
Binary files /dev/null and b/odex-event/muk_autovacuum/static/description/service_customization.png differ
diff --git a/odex-event/muk_autovacuum/static/description/service_development.png b/odex-event/muk_autovacuum/static/description/service_development.png
new file mode 100644
index 000000000..580d46046
Binary files /dev/null and b/odex-event/muk_autovacuum/static/description/service_development.png differ
diff --git a/odex-event/muk_autovacuum/static/description/service_implementation.png b/odex-event/muk_autovacuum/static/description/service_implementation.png
new file mode 100644
index 000000000..d64b66bda
Binary files /dev/null and b/odex-event/muk_autovacuum/static/description/service_implementation.png differ
diff --git a/odex-event/muk_autovacuum/static/description/service_integration.png b/odex-event/muk_autovacuum/static/description/service_integration.png
new file mode 100644
index 000000000..76c5e80f4
Binary files /dev/null and b/odex-event/muk_autovacuum/static/description/service_integration.png differ
diff --git a/odex-event/muk_autovacuum/static/description/service_support.png b/odex-event/muk_autovacuum/static/description/service_support.png
new file mode 100644
index 000000000..4c530fafd
Binary files /dev/null and b/odex-event/muk_autovacuum/static/description/service_support.png differ
diff --git a/odex-event/muk_autovacuum/static/xls/muk_autovacuum_rules.xls b/odex-event/muk_autovacuum/static/xls/muk_autovacuum_rules.xls
new file mode 100644
index 000000000..59686137f
Binary files /dev/null and b/odex-event/muk_autovacuum/static/xls/muk_autovacuum_rules.xls differ
diff --git a/odex-event/muk_autovacuum/tests/__init__.py b/odex-event/muk_autovacuum/tests/__init__.py
new file mode 100644
index 000000000..895ce0444
--- /dev/null
+++ b/odex-event/muk_autovacuum/tests/__init__.py
@@ -0,0 +1,23 @@
+###################################################################################
+#
+# Copyright (c) 2017-2019 MuK IT GmbH.
+#
+# This file is part of MuK Autovacuum
+# (see https://mukit.at).
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see .
+#
+###################################################################################
+
+from . import test_autovacuum
\ No newline at end of file
diff --git a/odex-event/muk_autovacuum/tests/test_autovacuum.py b/odex-event/muk_autovacuum/tests/test_autovacuum.py
new file mode 100644
index 000000000..cfaf2cc15
--- /dev/null
+++ b/odex-event/muk_autovacuum/tests/test_autovacuum.py
@@ -0,0 +1,99 @@
+###################################################################################
+#
+# Copyright (c) 2017-2019 MuK IT GmbH.
+#
+# This file is part of MuK Autovacuum
+# (see https://mukit.at).
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see .
+#
+###################################################################################
+
+import logging
+import datetime
+
+from odoo.tests import common
+
+_logger = logging.getLogger(__name__)
+
+class AutoVacuumTestCase(common.TransactionCase):
+
+ def setUp(self):
+ super(AutoVacuumTestCase, self).setUp()
+ self.logs = self.env['ir.logging']
+ self.rules = self.env['muk_autovacuum.rules']
+ self.model_model = self.env['ir.model']
+ self.model_fields = self.env['ir.model.fields']
+ self.model_logs = self.model_model.search([('model', '=', 'ir.logging')], limit=1)
+ time_field_domain = [
+ ('model_id', '=', self.model_logs.id),
+ ('ttype', '=', 'datetime'),
+ ('name', '=', 'create_date')]
+ self.time_field_logs = self.model_fields.search(time_field_domain, limit=1)
+
+ def test_autovacuum_time(self):
+ self.create_logs()
+ self.rules.create({
+ 'name': "Delete Logs after 1 Minute",
+ 'state': 'time',
+ 'model': self.model_logs.id,
+ 'time_field': self.time_field_logs.id,
+ 'time_type': 'minutes',
+ 'time': 1})
+ self.run_autovacuum()
+
+ def test_autovacuum_size(self):
+ self.create_logs()
+ self.rules.create({
+ 'name': "Delete Logs Count > 1",
+ 'state': 'size',
+ 'model': self.model_logs.id,
+ 'size': 1,
+ 'size_order': "id desc",
+ 'size_type': 'fixed'})
+ self.run_autovacuum()
+
+ def test_autovacuum_domain(self):
+ self.create_logs()
+ self.rules.create({
+ 'name': "Delete Logs with Domain",
+ 'state': 'domain',
+ 'model': self.model_logs.id,
+ 'domain': "[]"})
+ self.run_autovacuum()
+
+ def create_logs(self):
+ ids = []
+ time = datetime.datetime.utcnow()
+ for index in range(0, 10):
+ log = self.logs.create({
+ 'create_date': time - datetime.timedelta(days=index),
+ 'create_uid': self.env.user.id,
+ 'name': "Test %s" % index,
+ 'type': 'server',
+ 'dbname': self.env.cr.dbname,
+ 'level': "INFO",
+ 'message': "TEST",
+ 'path': "PATH",
+ 'func': "TEST",
+ 'line': 1})
+ ids.append(log.id)
+ return ids
+
+ def run_autovacuum(self):
+ count_before = self.env['ir.logging'].search([], count=True)
+ self.env['ir.cron'].search([('model_id', '=', 'ir.autovacuum')]).ir_actions_server_id.run()
+ count_after = self.env['ir.logging'].search([], count=True)
+ self.assertTrue(count_before > count_after)
+
\ No newline at end of file
diff --git a/odex-event/muk_autovacuum/views/rules.xml b/odex-event/muk_autovacuum/views/rules.xml
new file mode 100644
index 000000000..05eda69e6
--- /dev/null
+++ b/odex-event/muk_autovacuum/views/rules.xml
@@ -0,0 +1,161 @@
+
+
+
+
+
+
+
+ muk_autovacuum_rules.search
+ muk_autovacuum.rules
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ muk_autovacuum_rules.tree
+ muk_autovacuum.rules
+
+
+
+
+
+
+
+
+
+
+
+
+ muk_autovacuum_rules.form
+ muk_autovacuum.rules
+
+
+
+
+
+
+ Auto Vacuum Rules
+ muk_autovacuum.rules
+ tree,form
+ {'search_default_all': 1}
+
+
+
+
+
\ No newline at end of file
diff --git a/odex-event/muk_dms/LICENSE b/odex-event/muk_dms/LICENSE
new file mode 100644
index 000000000..153d416dc
--- /dev/null
+++ b/odex-event/muk_dms/LICENSE
@@ -0,0 +1,165 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+
+ This version of the GNU Lesser General Public License incorporates
+the terms and conditions of version 3 of the GNU General Public
+License, supplemented by the additional permissions listed below.
+
+ 0. Additional Definitions.
+
+ As used herein, "this License" refers to version 3 of the GNU Lesser
+General Public License, and the "GNU GPL" refers to version 3 of the GNU
+General Public License.
+
+ "The Library" refers to a covered work governed by this License,
+other than an Application or a Combined Work as defined below.
+
+ An "Application" is any work that makes use of an interface provided
+by the Library, but which is not otherwise based on the Library.
+Defining a subclass of a class defined by the Library is deemed a mode
+of using an interface provided by the Library.
+
+ A "Combined Work" is a work produced by combining or linking an
+Application with the Library. The particular version of the Library
+with which the Combined Work was made is also called the "Linked
+Version".
+
+ The "Minimal Corresponding Source" for a Combined Work means the
+Corresponding Source for the Combined Work, excluding any source code
+for portions of the Combined Work that, considered in isolation, are
+based on the Application, and not on the Linked Version.
+
+ The "Corresponding Application Code" for a Combined Work means the
+object code and/or source code for the Application, including any data
+and utility programs needed for reproducing the Combined Work from the
+Application, but excluding the System Libraries of the Combined Work.
+
+ 1. Exception to Section 3 of the GNU GPL.
+
+ You may convey a covered work under sections 3 and 4 of this License
+without being bound by section 3 of the GNU GPL.
+
+ 2. Conveying Modified Versions.
+
+ If you modify a copy of the Library, and, in your modifications, a
+facility refers to a function or data to be supplied by an Application
+that uses the facility (other than as an argument passed when the
+facility is invoked), then you may convey a copy of the modified
+version:
+
+ a) under this License, provided that you make a good faith effort to
+ ensure that, in the event an Application does not supply the
+ function or data, the facility still operates, and performs
+ whatever part of its purpose remains meaningful, or
+
+ b) under the GNU GPL, with none of the additional permissions of
+ this License applicable to that copy.
+
+ 3. Object Code Incorporating Material from Library Header Files.
+
+ The object code form of an Application may incorporate material from
+a header file that is part of the Library. You may convey such object
+code under terms of your choice, provided that, if the incorporated
+material is not limited to numerical parameters, data structure
+layouts and accessors, or small macros, inline functions and templates
+(ten or fewer lines in length), you do both of the following:
+
+ a) Give prominent notice with each copy of the object code that the
+ Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the object code with a copy of the GNU GPL and this license
+ document.
+
+ 4. Combined Works.
+
+ You may convey a Combined Work under terms of your choice that,
+taken together, effectively do not restrict modification of the
+portions of the Library contained in the Combined Work and reverse
+engineering for debugging such modifications, if you also do each of
+the following:
+
+ a) Give prominent notice with each copy of the Combined Work that
+ the Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the Combined Work with a copy of the GNU GPL and this license
+ document.
+
+ c) For a Combined Work that displays copyright notices during
+ execution, include the copyright notice for the Library among
+ these notices, as well as a reference directing the user to the
+ copies of the GNU GPL and this license document.
+
+ d) Do one of the following:
+
+ 0) Convey the Minimal Corresponding Source under the terms of this
+ License, and the Corresponding Application Code in a form
+ suitable for, and under terms that permit, the user to
+ recombine or relink the Application with a modified version of
+ the Linked Version to produce a modified Combined Work, in the
+ manner specified by section 6 of the GNU GPL for conveying
+ Corresponding Source.
+
+ 1) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (a) uses at run time
+ a copy of the Library already present on the user's computer
+ system, and (b) will operate properly with a modified version
+ of the Library that is interface-compatible with the Linked
+ Version.
+
+ e) Provide Installation Information, but only if you would otherwise
+ be required to provide such information under section 6 of the
+ GNU GPL, and only to the extent that such information is
+ necessary to install and execute a modified version of the
+ Combined Work produced by recombining or relinking the
+ Application with a modified version of the Linked Version. (If
+ you use option 4d0, the Installation Information must accompany
+ the Minimal Corresponding Source and Corresponding Application
+ Code. If you use option 4d1, you must provide the Installation
+ Information in the manner specified by section 6 of the GNU GPL
+ for conveying Corresponding Source.)
+
+ 5. Combined Libraries.
+
+ You may place library facilities that are a work based on the
+Library side by side in a single library together with other library
+facilities that are not Applications and are not covered by this
+License, and convey such a combined library under terms of your
+choice, if you do both of the following:
+
+ a) Accompany the combined library with a copy of the same work based
+ on the Library, uncombined with any other library facilities,
+ conveyed under the terms of this License.
+
+ b) Give prominent notice with the combined library that part of it
+ is a work based on the Library, and explaining where to find the
+ accompanying uncombined form of the same work.
+
+ 6. Revised Versions of the GNU Lesser General Public License.
+
+ The Free Software Foundation may publish revised and/or new versions
+of the GNU Lesser General Public License from time to time. Such new
+versions will be similar in spirit to the present version, but may
+differ in detail to address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Library as you received it specifies that a certain numbered version
+of the GNU Lesser General Public License "or any later version"
+applies to it, you have the option of following the terms and
+conditions either of that published version or of any later version
+published by the Free Software Foundation. If the Library as you
+received it does not specify a version number of the GNU Lesser
+General Public License, you may choose any version of the GNU Lesser
+General Public License ever published by the Free Software Foundation.
+
+ If the Library as you received it specifies that a proxy can decide
+whether future versions of the GNU Lesser General Public License shall
+apply, that proxy's public statement of acceptance of any version is
+permanent authorization for you to choose that version for the
+Library.
\ No newline at end of file
diff --git a/odex-event/muk_dms/README.rst b/odex-event/muk_dms/README.rst
new file mode 100644
index 000000000..dc2b70be9
--- /dev/null
+++ b/odex-event/muk_dms/README.rst
@@ -0,0 +1,123 @@
+==============================
+MuK Document Management System
+==============================
+
+MuK Documents is a module to create, manage and view files directly within Odoo.
+In addition to views for files and folders, it offers its own all in one view
+to make working with documents easier. This module is only the basis for an
+entire ecosystem of apps that extend and seamlessly integrate with the document
+management system.
+
+Installation
+============
+
+To install this module, you need to:
+
+Download the module and add it to your Odoo addons folder. Afterward, log on to
+your Odoo server and go to the Apps menu. Trigger the debug mode and update the
+list by clicking on the "Update Apps List" link. Now install the module by
+clicking on the install button.
+
+Another way to install this module is via the package management for Python
+(`PyPI `_).
+
+To install our modules using the package manager make sure
+`odoo-autodiscover `_ is installed
+correctly. Then open a console and install the module by entering the following
+command:
+
+``pip install --extra-index-url https://nexus.mukit.at/repository/odoo/simple ``
+
+The module name consists of the Odoo version and the module name, where
+underscores are replaced by a dash.
+
+**Module:**
+
+``odoo-addon-``
+
+**Example:**
+
+``sudo -H pip3 install --extra-index-url https://nexus.mukit.at/repository/odoo/simple odoo11-addon-muk-utils``
+
+Once the installation has been successfully completed, the app is already in the
+correct folder. Log on to your Odoo server and go to the Apps menu. Trigger the
+debug mode and update the list by clicking on the "Update Apps List" link. Now
+install the module by clicking on the install button.
+
+The biggest advantage of this variant is that you can now also update the app
+using the "pip" command. To do this, enter the following command in your console:
+
+``pip install --upgrade --extra-index-url https://nexus.mukit.at/repository/odoo/simple ``
+
+When the process is finished, restart your server and update the application in
+Odoo. The steps are the same as for the installation only the button has changed
+from "Install" to "Upgrade".
+
+You can also view available Apps directly in our `repository `_
+and find a more detailed installation guide on our `website `_.
+
+For modules licensed under OPL-1, you will receive access data when you purchase
+the module. If the modules were not purchased directly from
+`MuK IT `_ please contact our support (support@mukit.at)
+with a confirmation of purchase to receive the corresponding access data.
+
+Upgrade
+============
+
+To upgrade this module, you need to:
+
+Download the module and add it to your Odoo addons folder. Restart the server
+and log on to your Odoo server. Select the Apps menu and upgrade the module by
+clicking on the upgrade button.
+
+If you installed the module using the "pip" command, you can also update the
+module in the same way. Just type the following command into the console:
+
+``pip install --upgrade --extra-index-url https://nexus.mukit.at/repository/odoo/simple ``
+
+When the process is finished, restart your server and update the application in
+Odoo, just like you would normally.
+
+Configuration
+=============
+
+To configure this module, you need to:
+
+#. Go to *Documents -> Configuration -> Storages*.
+#. Create a new document setting.
+#. Afterwards go to *Documents -> Directories*.
+#. Create a new directory, mark it as root and select the previously created setting.
+
+Usage
+=============
+
+The best way to manage the documents is to switch to the Documents view. Existing
+documents can be managed there and new documents can be created.
+
+Credits
+=======
+
+Contributors
+------------
+
+* Mathias Markl
+
+Images
+------------
+
+Some pictures are based on or inspired by:
+
+* `Roundicons `_
+* `Smashicons `_
+
+Author & Maintainer
+-------------------
+
+This module is maintained by the `MuK IT GmbH `_.
+
+MuK IT is an Austrian company specialized in customizing and extending Odoo.
+We develop custom solutions for your individual needs to help you focus on
+your strength and expertise to grow your business.
+
+If you want to get in touch please contact us via mail
+(sale@mukit.at) or visit our website (https://mukit.at).
diff --git a/odex-event/muk_dms/__init__.py b/odex-event/muk_dms/__init__.py
new file mode 100644
index 000000000..f57be46a0
--- /dev/null
+++ b/odex-event/muk_dms/__init__.py
@@ -0,0 +1,24 @@
+###################################################################################
+#
+# Copyright (c) 2017-2019 MuK IT GmbH.
+#
+# This file is part of MuK Documents
+# (see https://mukit.at).
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see .
+#
+###################################################################################
+
+from . import models
+from . import controllers
\ No newline at end of file
diff --git a/odex-event/muk_dms/__manifest__.py b/odex-event/muk_dms/__manifest__.py
new file mode 100644
index 000000000..7b7b6a253
--- /dev/null
+++ b/odex-event/muk_dms/__manifest__.py
@@ -0,0 +1,73 @@
+###################################################################################
+#
+# Copyright (c) 2017-2019 MuK IT GmbH.
+#
+# This file is part of MuK Documents
+# (see https://mukit.at).
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see .
+#
+###################################################################################
+
+{
+ "name": "MuK Documents",
+ "summary": """Document Management System""",
+ "version": '12.0.3.0.12',
+ "category": 'Document Management',
+ "license": "LGPL-3",
+ "website": "http://www.mukit.at",
+ 'live_test_url': 'https://mukit.at/r/SgN',
+ "author": "MuK IT",
+ "contributors": [
+ "Mathias Markl ",
+ ],
+ "depends": [
+ "muk_security",
+ "muk_web_searchpanel",
+ ],
+ "data": [
+ "security/security.xml",
+ "security/ir.model.access.csv",
+ "actions/file.xml",
+ "template/assets.xml",
+ "template/onboarding.xml",
+ "views/menu.xml",
+ "views/tag.xml",
+ "views/category.xml",
+ "views/file.xml",
+ "views/directory.xml",
+ "views/storage.xml",
+ "views/res_config_settings.xml",
+ ],
+ "demo": [
+ "demo/res_users.xml",
+ "demo/category.xml",
+ "demo/tag.xml",
+ "demo/storage.xml",
+ "demo/directory.xml",
+ "demo/file.xml",
+ ],
+ "qweb": [
+ "static/src/xml/*.xml",
+ ],
+ "images": [
+ 'static/description/banner.png'
+ ],
+ "external_dependencies": {
+ "python": [],
+ "bin": [],
+ },
+ "application": True,
+ "installable": True,
+}
diff --git a/odex-event/muk_dms/actions/file.xml b/odex-event/muk_dms/actions/file.xml
new file mode 100644
index 000000000..e83cd0223
--- /dev/null
+++ b/odex-event/muk_dms/actions/file.xml
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+ Migrate
+
+
+ code
+ records.action_migrate()
+
+
+
diff --git a/odex-event/muk_dms/controllers/__init__.py b/odex-event/muk_dms/controllers/__init__.py
new file mode 100644
index 000000000..a27027ddc
--- /dev/null
+++ b/odex-event/muk_dms/controllers/__init__.py
@@ -0,0 +1,24 @@
+###################################################################################
+#
+# Copyright (c) 2017-2019 MuK IT GmbH.
+#
+# This file is part of MuK Documents
+# (see https://mukit.at).
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see .
+#
+###################################################################################
+
+from . import backend
+from . import onboarding
\ No newline at end of file
diff --git a/odex-event/muk_dms/controllers/backend.py b/odex-event/muk_dms/controllers/backend.py
new file mode 100644
index 000000000..77799463c
--- /dev/null
+++ b/odex-event/muk_dms/controllers/backend.py
@@ -0,0 +1,37 @@
+###################################################################################
+#
+# Copyright (c) 2017-2019 MuK IT GmbH.
+#
+# This file is part of MuK Documents
+# (see https://mukit.at).
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see .
+#
+###################################################################################
+
+import logging
+
+from odoo import _, http
+from odoo.http import request
+
+_logger = logging.getLogger(__name__)
+
+class BackendController(http.Controller):
+
+ @http.route('/config/muk_dms.forbidden_extensions', type='json', auth="user")
+ def forbidden_extensions(self, **kw):
+ params = request.env['ir.config_parameter'].sudo()
+ return {
+ 'forbidden_extensions': params.get_param("muk_dms.forbidden_extensions", default="")
+ }
\ No newline at end of file
diff --git a/odex-event/muk_dms/controllers/onboarding.py b/odex-event/muk_dms/controllers/onboarding.py
new file mode 100644
index 000000000..43f4859d5
--- /dev/null
+++ b/odex-event/muk_dms/controllers/onboarding.py
@@ -0,0 +1,56 @@
+###################################################################################
+#
+# Copyright (c) 2017-2019 MuK IT GmbH.
+#
+# This file is part of MuK Documents
+# (see https://mukit.at).
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see .
+#
+###################################################################################
+
+from odoo import http
+from odoo.http import request
+
+class OnboardingController(http.Controller):
+
+ @http.route('/dms/document_onboarding/directory', auth='user', type='json')
+ def document_onboarding_directory(self):
+ company = request.env.user.company_id
+ closed = company.documents_onboarding_state == 'closed'
+ check = request.env.user.has_group('muk_dms.group_dms_manager')
+ if check and not closed:
+ return {
+ 'html': request.env.ref('muk_dms.document_onboarding_directory_panel').render({
+ 'state': company.get_and_update_documents_onboarding_state(),
+ 'company': company,
+ })
+ }
+ return {}
+
+ @http.route('/dms/document_onboarding/file', auth='user', type='json')
+ def document_onboarding_file(self):
+ company = request.env.user.company_id
+ closed = company.documents_onboarding_state == 'closed'
+ check = request.env.user.has_group('muk_dms.group_dms_manager')
+ if check and not closed:
+ return {
+ 'html': request.env.ref('muk_dms.document_onboarding_file_panel').render({
+ 'state': company.get_and_update_documents_onboarding_state(),
+ 'company': company,
+ })
+ }
+ return {}
+
+
\ No newline at end of file
diff --git a/odex-event/muk_dms/demo/category.xml b/odex-event/muk_dms/demo/category.xml
new file mode 100644
index 000000000..b1ad68c92
--- /dev/null
+++ b/odex-event/muk_dms/demo/category.xml
@@ -0,0 +1,55 @@
+
+
+
+
+
+
+
+ Internal
+
+
+
+ Human Resource
+
+
+
+
+ Contracts
+
+
+
+
+ Traveling
+
+
+
+
+ External
+
+
+
+ News
+
+
+
+
\ No newline at end of file
diff --git a/odex-event/muk_dms/demo/data/audio01.wav b/odex-event/muk_dms/demo/data/audio01.wav
new file mode 100644
index 000000000..2a479fc16
Binary files /dev/null and b/odex-event/muk_dms/demo/data/audio01.wav differ
diff --git a/odex-event/muk_dms/demo/data/audio02.wav b/odex-event/muk_dms/demo/data/audio02.wav
new file mode 100644
index 000000000..179a8d3ab
Binary files /dev/null and b/odex-event/muk_dms/demo/data/audio02.wav differ
diff --git a/odex-event/muk_dms/demo/data/audio03.mp3 b/odex-event/muk_dms/demo/data/audio03.mp3
new file mode 100644
index 000000000..397abc2e6
Binary files /dev/null and b/odex-event/muk_dms/demo/data/audio03.mp3 differ
diff --git a/odex-event/muk_dms/demo/data/audio04.mp3 b/odex-event/muk_dms/demo/data/audio04.mp3
new file mode 100644
index 000000000..4667276e7
Binary files /dev/null and b/odex-event/muk_dms/demo/data/audio04.mp3 differ
diff --git a/odex-event/muk_dms/demo/data/code01.aj b/odex-event/muk_dms/demo/data/code01.aj
new file mode 100644
index 000000000..bcbd327c5
--- /dev/null
+++ b/odex-event/muk_dms/demo/data/code01.aj
@@ -0,0 +1,10 @@
+// HelloWorld.java
+public class HelloWorld {
+ public static void say(String message) {
+ System.out.println(message);
+ }
+
+ public static void sayToPerson(String message, String name) {
+ System.out.println(name + ", " + message);
+ }
+}
diff --git a/odex-event/muk_dms/demo/data/code02.sh b/odex-event/muk_dms/demo/data/code02.sh
new file mode 100644
index 000000000..ffc7ac1d3
--- /dev/null
+++ b/odex-event/muk_dms/demo/data/code02.sh
@@ -0,0 +1,24 @@
+#!/bin/bash
+##
+##
+## Copyright (c) 2017-2019 MuK IT GmbH.
+##
+## This file is part of MuK Documents
+## (see https://mukit.at).
+##
+## This program is free software: you can redistribute it and/or modify
+## it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+##
+## You should have received a copy of the GNU Lesser General Public License
+## along with this program. If not, see .
+##
+##
+STR="Hello World!"
+echo $STR
\ No newline at end of file
diff --git a/odex-event/muk_dms/demo/data/code03.c b/odex-event/muk_dms/demo/data/code03.c
new file mode 100644
index 000000000..3df0a0e09
--- /dev/null
+++ b/odex-event/muk_dms/demo/data/code03.c
@@ -0,0 +1,27 @@
+/*
+ *
+ * Copyright (c) 2017-2019 MuK IT GmbH.
+ *
+ * This file is part of MuK Documents
+ * (see https://mukit.at).
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see .
+ *
+ */
+#include
+
+int main(void)
+{
+ printf("hello, world\n");
+}
\ No newline at end of file
diff --git a/odex-event/muk_dms/demo/data/code04.cc b/odex-event/muk_dms/demo/data/code04.cc
new file mode 100644
index 000000000..fceff0985
--- /dev/null
+++ b/odex-event/muk_dms/demo/data/code04.cc
@@ -0,0 +1,28 @@
+/*
+ *
+ * Copyright (c) 2017-2019 MuK IT GmbH.
+ *
+ * This file is part of MuK Documents
+ * (see https://mukit.at).
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see .
+ *
+ */
+#include
+
+int main()
+{
+ std::cout << "Hello, world!\n";
+ return 0;
+}
\ No newline at end of file
diff --git a/odex-event/muk_dms/demo/data/code05.cs b/odex-event/muk_dms/demo/data/code05.cs
new file mode 100644
index 000000000..f4bfff3fe
--- /dev/null
+++ b/odex-event/muk_dms/demo/data/code05.cs
@@ -0,0 +1,28 @@
+//
+// Copyright (c) 2017-2019 MuK IT GmbH.
+//
+// This file is part of MuK Documents
+// (see https://mukit.at).
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this program. If not, see .
+//
+using System;
+
+class Program
+{
+ static void Main(string[] args)
+ {
+ Console.WriteLine("Hello, world!");
+ }
+}
\ No newline at end of file
diff --git a/odex-event/muk_dms/demo/data/code06.cbl b/odex-event/muk_dms/demo/data/code06.cbl
new file mode 100644
index 000000000..6479586ce
--- /dev/null
+++ b/odex-event/muk_dms/demo/data/code06.cbl
@@ -0,0 +1,5 @@
+IDENTIFICATION DIVISION.
+PROGRAM-ID. hello-world.
+PROCEDURE DIVISION.
+ DISPLAY "Hello, world!"
+ .
\ No newline at end of file
diff --git a/odex-event/muk_dms/demo/data/code07.coffee b/odex-event/muk_dms/demo/data/code07.coffee
new file mode 100644
index 000000000..fe8d71b49
--- /dev/null
+++ b/odex-event/muk_dms/demo/data/code07.coffee
@@ -0,0 +1 @@
+console.log "Hello, World!"
\ No newline at end of file
diff --git a/odex-event/muk_dms/demo/data/code08.f b/odex-event/muk_dms/demo/data/code08.f
new file mode 100644
index 000000000..642ce75ee
--- /dev/null
+++ b/odex-event/muk_dms/demo/data/code08.f
@@ -0,0 +1,3 @@
+program helloworld
+ print *, "Hello world!"
+end program helloworld
\ No newline at end of file
diff --git a/odex-event/muk_dms/demo/data/code09.go b/odex-event/muk_dms/demo/data/code09.go
new file mode 100644
index 000000000..0e358fccd
--- /dev/null
+++ b/odex-event/muk_dms/demo/data/code09.go
@@ -0,0 +1,7 @@
+package main
+
+import "fmt"
+
+func main() {
+ fmt.Println("Hello, World")
+}
\ No newline at end of file
diff --git a/odex-event/muk_dms/demo/data/code10.groovy b/odex-event/muk_dms/demo/data/code10.groovy
new file mode 100644
index 000000000..a61e6a022
--- /dev/null
+++ b/odex-event/muk_dms/demo/data/code10.groovy
@@ -0,0 +1,22 @@
+/**********************************************************************************
+*
+* Copyright (c) 2017-2019 MuK IT GmbH.
+*
+* This file is part of MuK Documents
+* (see https://mukit.at).
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program. If not, see .
+*
+**********************************************************************************/
+println "Hello World"
\ No newline at end of file
diff --git a/odex-event/muk_dms/demo/data/code11.java b/odex-event/muk_dms/demo/data/code11.java
new file mode 100644
index 000000000..64e836844
--- /dev/null
+++ b/odex-event/muk_dms/demo/data/code11.java
@@ -0,0 +1,26 @@
+/**********************************************************************************
+*
+* Copyright (c) 2017-2019 MuK IT GmbH.
+*
+* This file is part of MuK Documents
+* (see https://mukit.at).
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program. If not, see .
+*
+**********************************************************************************/
+class HelloWorldApp {
+ public static void main(String[] args) {
+ System.out.println("Hello World!"); // Prints the string to the console.
+ }
+}
\ No newline at end of file
diff --git a/odex-event/muk_dms/demo/data/code12.sc b/odex-event/muk_dms/demo/data/code12.sc
new file mode 100644
index 000000000..49eae568d
--- /dev/null
+++ b/odex-event/muk_dms/demo/data/code12.sc
@@ -0,0 +1,3 @@
+object HelloWorld extends App {
+ println("Hello, World!")
+ }
\ No newline at end of file
diff --git a/odex-event/muk_dms/demo/data/document01.pdf b/odex-event/muk_dms/demo/data/document01.pdf
new file mode 100644
index 000000000..99d31cef1
Binary files /dev/null and b/odex-event/muk_dms/demo/data/document01.pdf differ
diff --git a/odex-event/muk_dms/demo/data/document02.doc b/odex-event/muk_dms/demo/data/document02.doc
new file mode 100644
index 000000000..9cb3f019e
Binary files /dev/null and b/odex-event/muk_dms/demo/data/document02.doc differ
diff --git a/odex-event/muk_dms/demo/data/document03.odt b/odex-event/muk_dms/demo/data/document03.odt
new file mode 100644
index 000000000..c963be926
Binary files /dev/null and b/odex-event/muk_dms/demo/data/document03.odt differ
diff --git a/odex-event/muk_dms/demo/data/document04.rtf b/odex-event/muk_dms/demo/data/document04.rtf
new file mode 100644
index 000000000..83bf162d4
--- /dev/null
+++ b/odex-event/muk_dms/demo/data/document04.rtf
@@ -0,0 +1,23 @@
+{\rtf1\ansi\ansicpg1252\uc1 \deff0\deflang1033\deflangfe1033{\fonttbl{\f0\froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f1\fswiss\fcharset0\fprq2{\*\panose 020b0604020202020204}Arial;}
+{\f73\froman\fcharset238\fprq2 Times New Roman CE;}{\f74\froman\fcharset204\fprq2 Times New Roman Cyr;}{\f76\froman\fcharset161\fprq2 Times New Roman Greek;}{\f77\froman\fcharset162\fprq2 Times New Roman Tur;}
+{\f78\froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\f79\froman\fcharset178\fprq2 Times New Roman (Arabic);}{\f80\froman\fcharset186\fprq2 Times New Roman Baltic;}{\f81\fswiss\fcharset238\fprq2 Arial CE;}{\f82\fswiss\fcharset204\fprq2 Arial Cyr;}
+{\f84\fswiss\fcharset161\fprq2 Arial Greek;}{\f85\fswiss\fcharset162\fprq2 Arial Tur;}{\f86\fswiss\fcharset177\fprq2 Arial (Hebrew);}{\f87\fswiss\fcharset178\fprq2 Arial (Arabic);}{\f88\fswiss\fcharset186\fprq2 Arial Baltic;}}
+{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;
+\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;\red51\green102\blue255;}{\stylesheet{\ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0
+\fs24\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 \snext0 Normal;}{\s1\ql \li0\ri0\sb240\sa60\keepn\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \b\f1\fs32\lang2057\langfe1033\kerning32\cgrid\langnp2057\langfenp1033
+\sbasedon0 \snext0 heading 1;}{\s3\ql \li0\ri0\sb240\sa60\keepn\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \b\f1\fs26\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 \sbasedon0 \snext0 heading 3;}{\*\cs10 \additive
+Default Paragraph Font;}}{\info{\title The power of technology lies in the ability to match learning styles to the needs of individual learners}{\author Les Mason}{\operator Les Mason}{\creatim\yr2005\mo3\dy15\hr18\min11}
+{\revtim\yr2005\mo3\dy15\hr18\min12}{\version1}{\edmins1}{\nofpages1}{\nofwords0}{\nofchars0}{\nofcharsws0}{\vern8203}}\paperw11906\paperh16838 \widowctrl\ftnbj\aenddoc\noxlattoyen\expshrtn\noultrlspc\dntblnsbdb\nospaceforul\formshade\horzdoc\dgmargin
+\dghspace180\dgvspace180\dghorigin1800\dgvorigin1440\dghshow1\dgvshow1\jexpand\viewkind1\viewscale117\viewzk2\pgbrdrhead\pgbrdrfoot\splytwnine\ftnlytwnine\htmautsp\nolnhtadjtbl\useltbaln\alntblind\lytcalctblwd\lyttblrtgr\lnbrkrule \fet0\sectd
+\linex0\headery708\footery708\colsx708\endnhere\sectlinegrid360\sectdefaultcl {\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang
+{\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang{\pntxta )}}{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl7
+\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}\pard\plain
+\s1\ql \li0\ri0\sb240\sa60\keepn\widctlpar\aspalpha\aspnum\faauto\outlinelevel0\adjustright\rin0\lin0\itap0 \b\f1\fs32\lang2057\langfe1033\kerning32\cgrid\langnp2057\langfenp1033 {
+The power of technology lies in the ability to match learning styles to the needs of individual learners
+\par }\pard\plain \ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \fs24\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {
+\par }\pard\plain \s3\ql \li720\ri0\sb240\sa60\keepn\widctlpar\aspalpha\aspnum\faauto\outlinelevel2\adjustright\rin0\lin720\itap0 \b\f1\fs26\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {\cf17 The more I study the more I l}{\cf17 earn.
+\par The more I learn the more I know
+\par The more I know the more I forget
+\par The more I forget the less I know
+\par So why study?}{
+\par }}
\ No newline at end of file
diff --git a/odex-event/muk_dms/demo/data/image01.jpg b/odex-event/muk_dms/demo/data/image01.jpg
new file mode 100644
index 000000000..586ceb89d
Binary files /dev/null and b/odex-event/muk_dms/demo/data/image01.jpg differ
diff --git a/odex-event/muk_dms/demo/data/image02.jpg b/odex-event/muk_dms/demo/data/image02.jpg
new file mode 100644
index 000000000..7467c6f61
Binary files /dev/null and b/odex-event/muk_dms/demo/data/image02.jpg differ
diff --git a/odex-event/muk_dms/demo/data/image03.jpg b/odex-event/muk_dms/demo/data/image03.jpg
new file mode 100644
index 000000000..a35fc1ae8
Binary files /dev/null and b/odex-event/muk_dms/demo/data/image03.jpg differ
diff --git a/odex-event/muk_dms/demo/data/image04.jpg b/odex-event/muk_dms/demo/data/image04.jpg
new file mode 100644
index 000000000..25a3abe27
Binary files /dev/null and b/odex-event/muk_dms/demo/data/image04.jpg differ
diff --git a/odex-event/muk_dms/demo/data/mail01.eml b/odex-event/muk_dms/demo/data/mail01.eml
new file mode 100644
index 000000000..4f23ca299
--- /dev/null
+++ b/odex-event/muk_dms/demo/data/mail01.eml
@@ -0,0 +1,171 @@
+Return-Path:
+To: Manuel Lemos
+Subject: Testing Manuel Lemos' MIME E-mail composing and sending PHP class: HTML message
+From: mlemos
+Reply-To: mlemos
+Sender: mlemos@acm.org
+X-Mailer: http://www.phpclasses.org/mimemessage $Revision: 1.63 $ (mail)
+MIME-Version: 1.0
+Content-Type: multipart/mixed; boundary="652b8c4dcb00cdcdda1e16af36781caf"
+Message-ID: <20050430192829.0489.mlemos@acm.org>
+Date: Sat, 30 Apr 2005 19:28:29 -0300
+
+
+--652b8c4dcb00cdcdda1e16af36781caf
+Content-Type: multipart/related; boundary="6a82fb459dcaacd40ab3404529e808dc"
+
+
+--6a82fb459dcaacd40ab3404529e808dc
+Content-Type: multipart/alternative; boundary="69c1683a3ee16ef7cf16edd700694a2f"
+
+
+--69c1683a3ee16ef7cf16edd700694a2f
+Content-Type: text/plain; charset=ISO-8859-1
+Content-Transfer-Encoding: quoted-printable
+
+This is an HTML message. Please use an HTML capable mail program to read
+this message.
+
+--69c1683a3ee16ef7cf16edd700694a2f
+Content-Type: text/html; charset=ISO-8859-1
+Content-Transfer-Encoding: quoted-printable
+
+
+
+Testing Manuel Lemos' MIME E-mail composing and sending PHP class: H=
+TML message
+
+
+
+
+
+
+
Testing Manuel Lemos' MIME E-mail composing and sending PHP cla=
+ss: HTML message
Here is an image embedded in a message as a separate part:
=
+
+
Than=
+k you,
+mlemos
+
+
+
+
+
+--69c1683a3ee16ef7cf16edd700694a2f--
+
+--6a82fb459dcaacd40ab3404529e808dc
+Content-Type: image/gif; name="logo.gif"
+Content-Transfer-Encoding: base64
+Content-Disposition: inline; filename="logo.gif"
+Content-ID:
+
+R0lGODlhlgAjAPMJAAAAAAAA/y8vLz8/P19fX19f339/f4+Pj4+Pz7+/v///////////////////
+/////yH5BAEAAAkALAAAAACWACMAQwT+MMlJq7046827/2AoHYChGAChAkBylgKgKClFyEl6xDMg
+qLFBj3C5uXKplVAxIOxkA8BhdFCpDlMK1urMTrZWbAV8tVS5YsxtxmZHBVOSCcW9zaXyNhslVcto
+RBp5NQYxLAYGLi8oSwoJBlE+BiSNj5E/PDQsmy4pAJWQLAKJY5+hXhZ2dDYldFWtNSFPiXssXnZR
+k5+1pjpBiDMJUXG/Jo7DI4eKfMSmxsJ9GAUB1NXW19jZ2tvc3d7f4OHi2AgZN5vom1kk6F7s6u/p
+m3Ab7AOIiCxOyZuBIv8AOeTJIaYQjiR/kKTr5GQNE3pYSjCJ9mUXClRUsLxaZGciC0X+OlpoOuQo
+ZKdNJnIoKfnxRUQh6FLG0iLxIoYnJd0JEKISJyAQDodp3EUDC48oDnUY7HFI3wEDRjzycQJVZCQT
+Ol7NK+G0qgtkAcOKHUu2rNmzYTVqRMt2bB49bHompSchqg6HcGeANSMxr8sEa2y2HexnSEUTuWri
+SSbkYh7BgGVAnhB1b2REibESYaRoBgqIMYx59tFM9AvQffVG49P5NMZkMlHKhJPJb0knmSKZ6kSX
+JtbeF3Am7ocok6c7cM7pU5xcXiJJETUz16qPrzEfaFgZpvzn7h86YV5r/1mxXeAUMVyEIpnVUGpN
+RlG2ka9b3lP3pm2l6u7P+l/YLj3+RlEHbz1C0kRxSITQaAcilVBMEzmkkEQO8oSOBNg9SN+AX6hV
+z1pjgJiAhwCRsY8ZIp6xj1ruqCgeGeKNGEZwLnIwzTg45qjjjjz2GEA5hAUp5JBEFmnkkSCoWEcZ
+X8yohZNK1pFGPQS4hx0qNSLJlk9wCQORYu5QiMd7bUzGVyNlRiOHSlpuKdGEItHQ3HZ18beRRyws
+YSY/waDTiHf/tWlWUBAJiMJ1/Z0XXU7N0FnREpKM4NChCgbyRDq9XYpOplaKopN9NMkDnBbG+UMC
+QwLWIeaiglES6AjGARcPHCWoVAiatcTnGTABZoLPaPG1phccPv366mEvWEFSLnj+2QaonECwcJt/
+e1Zw3lJvVMmftBdVNQS3UngLCA85YHIQOy6JO9N4eZW7KJwtOUZmGwOMWqejwVW6RQzaikRHX3yI
+osKhDAq8wmnKSmdMwNidSOof9ZG2DoV0RfTVmLFtGmNk+CoZna0HQnPHS3AhRbIeDpqmR09E0bsu
+soeaw994z+rwQVInvqLenBftYjLOVphLFHhV9qsnez8AEUbQRgO737AxChjmyANxuEFHSGi7hFCV
+4jxLst2N8sRJYU+SHiAKjlmCgz2IffbLI5aaQR71hnkxq1ZfHSfKata6YDCJDMAQwY7wOgzhjxgj
+VFQnKB5uX4mr9qJ79pann+VcfcSzsSCd2mw5scqRRvlQ6TgcUelYhu75iPE4JejrsJOFQAG01277
+7bjnrvvuvPfu++/ABy887hfc6OPxyCevPDdAVoDA89BHL/301Fdv/fXYZ6/99tx3Pz0FEQAAOw==
+
+--6a82fb459dcaacd40ab3404529e808dc
+Content-Type: image/gif; name="background.gif"
+Content-Transfer-Encoding: base64
+Content-Disposition: inline; filename="background.gif"
+Content-ID: <4c837ed463ad29c820668e835a270e8a.gif>
+
+R0lGODlh+wHCAPMAAKPFzKLEy6HDyqHCyaDByJ/Ax56/xp2+xZ28xJy7w5u6wpq5wZm4wJm3v5i2
+vpe1vSwAAAAA+wHCAEME/hDISau9OOvNu/9gKI5kaZ5oqq5s675wLM90bd94ru987//AoHBILBqP
+yKRyyWw6n9CodEqtWq+gwSHReHgfjobY8X00FIc019tIHAYS7dqcQCDm3vC4fD4QAhUBBFsMZF8O
+hnkLCAYFW11tb1iTlJWWOXJdZZtmC24Eg3hgYntfbXainJ2fgBSZbG5wFAG0E6+RoAZ3CbwJCgya
+p3cMbAyevQcFAgMGCcRmxr1uyszOxQq+wF4MdcPFx7zJApfk5eYhr3SSGemRsu3dc+4iAqELhZwO
+0X6hkHUHCBRoGtUg0RkEAAUeKhhGAcICBQIODIPooIEBzCTmKcjGYSNd/go3VvQo65zJkyhTqlzJ
+sqXLlzBjypxJs6bNmzhz6tzJs6fPn0CDCh1KtKjRo0iTKl3KtKnTp1CXBhhAwECaq1gPNCIwANDU
+qmkMcG311apWULmyZt3alcPXAma1FgAlgCxVq2LbRt3LF0Y7hwWoEjLEDZUmff8AOjMkTB5gwYu3
+JbhIQUDEZw+4+aE1aNc0R2vcDYjoDBgpBoUDj95yzzRqbH7qgW4t5vUnAfVAoj7NwOOf1QloN7Ad
+u1Xf41b+IlCNsa6rR7DWwTPccTnG5sYvCEKwgPGiZI64A9OsK/Q/BM/0YfuFz13VOwsULLhHps+f
+98Hl0zeDRk0X9Qih/vLPWPjFN197aPyB3IJVBLDMdc5t4OB1A0QowYQQ0vIgdilgyGEgG1roYV0j
+GufhhyBSWGF2s2yIYosqWsjgjDTWaOONOOao44489ujjj0AGKeSQRBZp5JFIJqnkkkw26eSTUMJU
+llpYseXVXWGNdSGWZ6EVF5VWukUVXFdtRUCEU+bFYpRslqNcYKHgk1k8hxWWxjCM0VkdnINJRtkE
+lqH3hWZ/CKJYOBBBJxppu/FWh2qzNUrcmQRE6lpvt+UWUKPD9cbIb5bWhmlxbbL5JoUywiMddHRQ
+x591GWqwXXdsfJeoeMO5UZ4/AaaHKXv1xVKgfghuNuyB9fUHHYAA/u2CEIHlGbiffWuWyuSJMmKA
+bXbbbtuhi9kCUOIEJY57oYsraoduuOfGWO2J6Vor77z01mvvvfjmq+++/Pbr778AByzwwAQXbPDB
+CCfcZDobldLRVfLEEgerjQ1EEEemJMiioZEdkggYizSiqMQKl5wCw6qswg+rDTvc6h0Wq9KAJ5tV
+oGpJF9YysXn8lCfNL8HE88xw4EyzTDNDR4MMNUhfk40mhXkDTdHimHzjzRpgDcB0MEeHswf1sCZn
+GfrQDMrIAYZEkEEOJTQRQweBp5FIDTGCEUiHYWwRXHOPMpLdVgcu+OCEF2744YgnrvjijDfu+OOQ
+Ry755JRXbvnl/phnrvnmnHfu+eegZ57RAqSUzptv75E+M+Bb66L6InZwZ7rpr31aLQBhb2pap548
+e7TsIX8dOr/pIIZQQphFHfGqEbtq/J2/DDrZ13Ga0jt8h/XX9TxvfRmmuPVUatb34INCplxakjtm
+XOQ7aP74c+k1fE4MD7fefvxBbLEeLldsyq/4o9ZzHOOHylBFS7f4RJxQMx/8MeB4ggIDA02ziLno
+wlfGoOByKnUAhZQNWfkzwAXzMEExVFB+86NJ/TDVC4SIZRzFs5Ni5OQ/p7XwLOOwQDXSswgFiYuD
+Z4GMP8AjtvGgJk9aYU2davdCeyzRU2LpBwkb2KjvWCU4T/TN/u1S+BKtYUBrXFue8DYQKFoVAzXa
+eJh/XiYPpZEOFhAMTnzkk8aQWQU+c7yHJkIGkGd4SkDhMJ9i5qMAOu4RAWfiYk1yxwvfaYCRA8oh
+JF14x0bGhgSyaZY07JCMRDLyWWnxTOyc1UmweMaSL5zSKf/xQgnk5lA3TCWWVunCRCrylrjMpS53
+ycte+vKXwAymMIdJzGIa85jITKYyl8nMZjrzmdCMpjSnSc1qWvOa2MymvkY3u9IxMReyW92fuLm6
+2Kmum53SIgZyxx7e9C423AyeNnkUw8RsSnqumsfWKKYnCdozen6iHiGsF483gkF7PIND96oUP7KE
+73zteyj8/tK3JfGVqaHkkmhYMDrPJqzwfjRUlij4hzE4ds1pdGSMxgYYjAQZEBRtSeDKSmMMEGYG
+ghjU4+osGEF9ZNCEG3SEB2s6LTSIsKcl3CkKO2qEj24Sh/ucw/NmmCdXQQMbsbSlzZoGMkSSBYh5
+kWIkEhWc3aARiVc0qE+hSCklkvCbUpQgFTWYRCy+la1bZGoQvHgBMPIznyT7QBkNgsY05m+NNSQa
+Lwx6ijvJsZB69IIdB5nHOjKij9twCCAVGJ7HGlKyiMyhXo0wyUtmoLS2LK0ID+XIEWRys5ycyzg+
+yQ9TtjB2lpyLbZ8qy91mVZK+ReWZVCkNVmp1tMhNrnKX/svc5jr3udCNrnSnS93qWve62M2udrfL
+3e5697vgDa94x0ve8pr3vOhNr3rXy972uve98I2vfOdLXxrBS0Uv8lZGUaUh/OKXXRmAV7jMVV+X
+QLK4vD0TaoHLWq1UEsEJFu0FXknLh3iyM5EssEtQlrK98ZN5QbNqyl71pwqEza752MfZEqrhljg1
+pYMKkBh3FuKTXtUX+LupMkwcETNCA40D6QNiA3tfdunXAkdOEX+1Ba68tjiqLbVOnKp60oNAam6J
+fcyUvTYLAnDHOw8Jjx7Js71YTKWzxX1IV76iyayuWTCwDSIgKJxmqLI5zmp6sg5ZNdV7bkPGQWYh
+0EzR/s8+A1THEt6hIrx6IbByRawKHKjfpEfExVREpUEdzKX3dJe5UaQ6UdT0p18VGCfPF2X8S4QD
+QgaamI24hi1TtTxZyuVZ6AzK6gBnIbE66DmhImlzxAYouUq0XQ+oUhG039P+rAZgG7u1erYFyy6W
+Tt85ddkmHak3PWVaWuePAC9F4Mh6dgdjB/A8tCqbscUxWLmumxp8jsa5A5RuY7xbwtHGtT+Phz69
+nGo0WC60DPt9u0AljxWG8kylh9hsRKw1jbiwx24cDsUKSRwYFPdIq2347NoWkSEAKnG++brnGes7
+sYH1QPVqVdDsOZZXUlN2WYO1soCA9JBoScjNQdvs/n3fKXaxYefOH9BDfD+Z5Db78Dv+WuWUd4Bj
+YwPDx1bNiI03BoO7yRi9CzJBBLlQdj5tTbKIOFQqikHjruN6Bovlw5GnXZxjtMXbZ01O2NnhdawL
+ASOFw8BIxpOSuutUYWfmBjW0U1S+gczhqy0Wzuhmd7Ur5RYW/01Tz3dKcpYVl/Isrs2jBSyZJ4H7
+LIq+4VYUL2NZaCMgQiY1LXSjFH09wWexvovGvvawX2q+d8/73vv+98APvvCHT/ziG//4yE++8pfP
+/OY7//nQj770p0/96lv/+tjPvva3z/3ue//74A+/+MdP/vKb//zoT7/6e3Lf/3KryTDKUPvdBQIB
+/q+JwOuPwYEhbFzcYDjDuPN/lARL/FdLRlcZwdUNnTRbGAZt+fcCHCYzGqd0NJZtrsYJFjFGJ2ZQ
+m1A2kcZiD+gXLKNsMMZsTQdiFvg/IJUID7RjldFjhAVkGaM/6lASRfYu8KcuS6aDO4hkOfh7p7Jl
+bBRlVxYSWSZlfVKDXfZltRJmADFmulJmb3BmBJhbb9YZp1RLV9hmwtUWdBZhnYeFCaZ7Rxdv/5Q8
+gKaCvNBrQ0hCZxhjLhgHXEV1PiQIjhBEkDZT6VFSmkFWhbBppMZBljZqVtZpIUGIqCNqevMYlhdf
+qEYKslZ10zZibbgQDkN1IndyTkcLxiFTulZI/muYRsrjbKA4bNYwNR1nPsn2K6J4PKdYbKXYbSM3
+bSQVeWdybWwIa9Rmi0b3FwUEKAcUU+MGTr4AivP2hGSgbqDIbjDobssIb1IlbzSEbslob894gGUY
+jYkxeyf3GABnhAK3jeTDYxE0J5uRcEtjdYUnaoMXHStGGxlnNxs4cYgARRt3Y8UobB5XVhhXjyTR
+e0jnbfoURkGzDh+wcquACmqFUDD3iiw0LZFmczhmWTknkZ9FdK5IDH0GdArWGaB4kUXHewEpbSZH
+kLX2AVA3dVPHamgjNQ8XZG0Ddl2XLF9HOmF3RPmTKGV3IGdXdWl3k2zXiPBVd3nXV3PHOkRpgk5A
+lYlgg2F8Fw3WlnZW9HiCB2Q0Y3ic8k2Kl5V4JQhUiXgWFgqUh1e9h3mcpy2epxdm+XnjQ1EiMHoQ
+pVtogiWuV3urBxGod4Xnw41huJfjKHvtg3t8GYKEWZiGeZiImZiKuZiM2ZiO+ZiQGZmSOZmUWZmW
+eZmYmZmauZmc2ZlCEQEAOw==
+
+--6a82fb459dcaacd40ab3404529e808dc--
+
+--652b8c4dcb00cdcdda1e16af36781caf
+Content-Type: text/plain; name="attachment.txt"
+Content-Transfer-Encoding: base64
+Content-Disposition: attachment; filename="attachment.txt"
+
+VGhpcyBpcyBqdXN0IGEgcGxhaW4gdGV4dCBhdHRhY2htZW50IGZpbGUgbmFtZWQgYXR0YWNobWVu
+dC50eHQgLg==
+
+--652b8c4dcb00cdcdda1e16af36781caf--
+
diff --git a/odex-event/muk_dms/demo/data/mail02.eml b/odex-event/muk_dms/demo/data/mail02.eml
new file mode 100644
index 000000000..b5b23c1be
--- /dev/null
+++ b/odex-event/muk_dms/demo/data/mail02.eml
@@ -0,0 +1,44 @@
+MIME-Version: 1.0
+Received: by 10.220.191.194 with HTTP; Wed, 11 May 2011 12:27:12 -0700 (PDT)
+Date: Wed, 11 May 2011 13:27:12 -0600
+Delivered-To: jncjkq@gmail.com
+Message-ID:
+Subject: Test
+From: Bill Jncjkq
+To: bookmarks@jncjkq.net
+Content-Type: multipart/mixed; boundary=bcaec54eecc63acce904a3050f79
+
+--bcaec54eecc63acce904a3050f79
+Content-Type: multipart/alternative; boundary=bcaec54eecc63acce604a3050f77
+
+--bcaec54eecc63acce604a3050f77
+Content-Type: text/plain; charset=ISO-8859-1
+
+--
+Bill Jncjkq
+
+--bcaec54eecc63acce604a3050f77
+Content-Type: text/html; charset=ISO-8859-1
+
+ -- Bill Jncjkq
+
+--bcaec54eecc63acce604a3050f77--
+--bcaec54eecc63acce904a3050f79
+Content-Type: text/html; charset=US-ASCII; name="bookmarks-really-short.html"
+Content-Disposition: attachment; filename="bookmarks-really-short.html"
+Content-Transfer-Encoding: base64
+X-Attachment-Id: f_gnknv6u70
+
+PCFET0NUWVBFIE5FVFNDQVBFLUJvb2ttYXJrLWZpbGUtMT4KCTxIVE1MPgoJPE1FVEEgSFRUUC1F
+UVVJVj0iQ29udGVudC1UeXBlIiBDT05URU5UPSJ0ZXh0L2h0bWw7IGNoYXJzZXQ9VVRGLTgiPgoJ
+PFRpdGxlPkJvb2ttYXJrczwvVGl0bGU+Cgk8SDE+Qm9va21hcmtzPC9IMT4KCQk8RFQ+PEgzIEZP
+TERFRD5UZWNoIE5ld3M8L0gzPgoJCTxETD48cD4KCQkJPERUPjxBIEhSRUY9Imh0dHA6Ly93d3cu
+Y25ldC5jb20vIj5DTmV0PC9BPgoJCQk8RFQ+PEEgSFJFRj0iaHR0cDovL3d3dy53aXJlZC5jb20v
+Ij5XaXJlZCBOZXdzPC9BPgoJCTwvREw+PHA+CgkJPERUPjxIMyBGT0xERUQ+VG9vbHMgYW5kIFJl
+ZmVyZW5jZTwvSDM+CgkJPERMPjxwPgoJCQk8RFQ+PEEgSFJFRj0iaHR0cDovL3d3dy5tb25zdGVy
+LmNvbS8iPk1vbnN0ZXIuY29tPC9BPgoJCQk8RFQ+PEEgSFJFRj0iaHR0cDovL3d3dy53ZWJtZC5j
+b20vIj5XZWJNRDwvQT4KCQk8L0RMPjxwPgoJCTxEVD48SDMgRk9MREVEPlRyYXZlbDwvSDM+CgkJ
+PERMPjxwPgoJCQk8RFQ+PEEgSFJFRj0iaHR0cDovL2ZvZG9ycy5jb20vIj5Gb2RvcnM8L0E+CgkJ
+CTxEVD48QSBIUkVGPSJodHRwOi8vd3d3LnRyYXZlbG9jaXR5LmNvbS8iPlRyYXZlbG9jaXR5PC9B
+PgoJCTwvREw+PHA+Cgk8L0RMPjxwPgo8L0hUTUw+
+--bcaec54eecc63acce904a3050f79--
\ No newline at end of file
diff --git a/odex-event/muk_dms/demo/data/markdown.md b/odex-event/muk_dms/demo/data/markdown.md
new file mode 100644
index 000000000..d3343e4e3
--- /dev/null
+++ b/odex-event/muk_dms/demo/data/markdown.md
@@ -0,0 +1,157 @@
+An h1 header
+============
+
+Paragraphs are separated by a blank line.
+
+2nd paragraph. *Italic*, **bold**, and `monospace`. Itemized lists
+look like:
+
+ * this one
+ * that one
+ * the other one
+
+Note that --- not considering the asterisk --- the actual text
+content starts at 4-columns in.
+
+> Block quotes are
+> written like so.
+>
+> They can span multiple paragraphs,
+> if you like.
+
+Use 3 dashes for an em-dash. Use 2 dashes for ranges (ex., "it's all
+in chapters 12--14"). Three dots ... will be converted to an ellipsis.
+Unicode is supported.
+
+
+
+An h2 header
+------------
+
+Here's a numbered list:
+
+ 1. first item
+ 2. second item
+ 3. third item
+
+Note again how the actual text starts at 4 columns in (4 characters
+from the left side). Here's a code sample:
+
+ # Let me re-iterate ...
+ for i in 1 .. 10 { do-something(i) }
+
+As you probably guessed, indented 4 spaces. By the way, instead of
+indenting the block, you can use delimited blocks, if you like:
+
+~~~
+define foobar() {
+ print "Welcome to flavor country!";
+}
+~~~
+
+(which makes copying & pasting easier). You can optionally mark the
+delimited block for Pandoc to syntax highlight it:
+
+~~~python
+import time
+# Quick, count to ten!
+for i in range(10):
+ # (but not *too* quick)
+ time.sleep(0.5)
+ print i
+~~~
+
+
+
+### An h3 header ###
+
+Now a nested list:
+
+ 1. First, get these ingredients:
+
+ * carrots
+ * celery
+ * lentils
+
+ 2. Boil some water.
+
+ 3. Dump everything in the pot and follow
+ this algorithm:
+
+ find wooden spoon
+ uncover pot
+ stir
+ cover pot
+ balance wooden spoon precariously on pot handle
+ wait 10 minutes
+ goto first step (or shut off burner when done)
+
+ Do not bump wooden spoon or it will fall.
+
+Notice again how text always lines up on 4-space indents (including
+that last line which continues item 3 above).
+
+Here's a link to [a website](http://foo.bar), to a [local
+doc](local-doc.html), and to a [section heading in the current
+doc](#an-h2-header). Here's a footnote [^1].
+
+[^1]: Footnote text goes here.
+
+Tables can look like this:
+
+size material color
+---- ------------ ------------
+9 leather brown
+10 hemp canvas natural
+11 glass transparent
+
+Table: Shoes, their sizes, and what they're made of
+
+(The above is the caption for the table.) Pandoc also supports
+multi-line tables:
+
+-------- -----------------------
+keyword text
+-------- -----------------------
+red Sunsets, apples, and
+ other red or reddish
+ things.
+
+green Leaves, grass, frogs
+ and other things it's
+ not easy being.
+-------- -----------------------
+
+A horizontal rule follows.
+
+***
+
+Here's a definition list:
+
+apples
+ : Good for making applesauce.
+oranges
+ : Citrus!
+tomatoes
+ : There's no "e" in tomatoe.
+
+Again, text is indented 4 spaces. (Put a blank line between each
+term/definition pair to spread things out more.)
+
+Here's a "line block":
+
+| Line one
+| Line too
+| Line tree
+
+and images can be specified like so:
+
+
+
+Inline math equations go in like so: $\omega = d\phi / dt$. Display
+math should get its own line and be put in in double-dollarsigns:
+
+$$I = \int \rho R^{2} dV$$
+
+And note that you can backslash-escape any punctuation characters
+which you wish to be displayed literally, ex.: \`foo\`, \*bar\*, etc.
\ No newline at end of file
diff --git a/odex-event/muk_dms/demo/data/sheet01.xls b/odex-event/muk_dms/demo/data/sheet01.xls
new file mode 100644
index 000000000..795ff7c49
Binary files /dev/null and b/odex-event/muk_dms/demo/data/sheet01.xls differ
diff --git a/odex-event/muk_dms/demo/data/sheet02.csv b/odex-event/muk_dms/demo/data/sheet02.csv
new file mode 100644
index 000000000..f9cf38669
--- /dev/null
+++ b/odex-event/muk_dms/demo/data/sheet02.csv
@@ -0,0 +1,100 @@
+1,"Eldon Base for stackable storage shelf, platinum",Muhammed MacIntyre,3,-213.25,38.94,35,Nunavut,Storage & Organization,0.8
+2,"1.7 Cubic Foot Compact ""Cube"" Office Refrigerators",Barry French,293,457.81,208.16,68.02,Nunavut,Appliances,0.58
+3,"Cardinal Slant-D Ring Binder, Heavy Gauge Vinyl",Barry French,293,46.71,8.69,2.99,Nunavut,Binders and Binder Accessories,0.39
+4,R380,Clay Rozendal,483,1198.97,195.99,3.99,Nunavut,Telephones and Communication,0.58
+5,Holmes HEPA Air Purifier,Carlos Soltero,515,30.94,21.78,5.94,Nunavut,Appliances,0.5
+6,G.E. Longer-Life Indoor Recessed Floodlight Bulbs,Carlos Soltero,515,4.43,6.64,4.95,Nunavut,Office Furnishings,0.37
+7,"Angle-D Binders with Locking Rings, Label Holders",Carl Jackson,613,-54.04,7.3,7.72,Nunavut,Binders and Binder Accessories,0.38
+8,"SAFCO Mobile Desk Side File, Wire Frame",Carl Jackson,613,127.70,42.76,6.22,Nunavut,Storage & Organization,
+9,"SAFCO Commercial Wire Shelving, Black",Monica Federle,643,-695.26,138.14,35,Nunavut,Storage & Organization,
+10,Xerox 198,Dorothy Badders,678,-226.36,4.98,8.33,Nunavut,Paper,0.38
+11,Xerox 1980,Neola Schneider,807,-166.85,4.28,6.18,Nunavut,Paper,0.4
+12,Advantus Map Pennant Flags and Round Head Tacks,Neola Schneider,807,-14.33,3.95,2,Nunavut,Rubber Bands,0.53
+13,Holmes HEPA Air Purifier,Carlos Daly,868,134.72,21.78,5.94,Nunavut,Appliances,0.5
+14,"DS/HD IBM Formatted Diskettes, 200/Pack - Staples",Carlos Daly,868,114.46,47.98,3.61,Nunavut,Computer Peripherals,0.71
+15,"Wilson Jones 1"" Hanging DublLock Ring Binders",Claudia Miner,933,-4.72,5.28,2.99,Nunavut,Binders and Binder Accessories,0.37
+16,Ultra Commercial Grade Dual Valve Door Closer,Neola Schneider,995,782.91,39.89,3.04,Nunavut,Office Furnishings,0.53
+17,"#10-4 1/8"" x 9 1/2"" Premium Diagonal Seam Envelopes",Allen Rosenblatt,998,93.80,15.74,1.39,Nunavut,Envelopes,0.4
+18,Hon 4-Shelf Metal Bookcases,Sylvia Foulston,1154,440.72,100.98,26.22,Nunavut,Bookcases,0.6
+19,"Lesro Sheffield Collection Coffee Table, End Table, Center Table, Corner Table",Sylvia Foulston,1154,-481.04,71.37,69,Nunavut,Tables,0.68
+20,g520,Jim Radford,1344,-11.68,65.99,5.26,Nunavut,Telephones and Communication,0.59
+21,LX 788,Jim Radford,1344,313.58,155.99,8.99,Nunavut,Telephones and Communication,0.58
+22,Avery 52,Carlos Soltero,1412,26.92,3.69,0.5,Nunavut,Labels,0.38
+23,Plymouth Boxed Rubber Bands by Plymouth,Carlos Soltero,1412,-5.77,4.71,0.7,Nunavut,Rubber Bands,0.8
+24,"GBC Pre-Punched Binding Paper, Plastic, White, 8-1/2"" x 11""",Carl Ludwig,1539,-172.88,15.99,13.18,Nunavut,Binders and Binder Accessories,0.37
+25,"Maxell 3.5"" DS/HD IBM-Formatted Diskettes, 10/Pack",Carl Ludwig,1539,-144.55,4.89,4.93,Nunavut,Computer Peripherals,0.66
+26,Newell 335,Don Miller,1540,5.76,2.88,0.7,Nunavut,Pens & Art Supplies,0.56
+27,SANFORD Liquid Accent Tank-Style Highlighters,Annie Cyprus,1702,4.90,2.84,0.93,Nunavut,Pens & Art Supplies,0.54
+28,Canon PC940 Copier,Carl Ludwig,1761,-547.61,449.99,49,Nunavut,Copiers and Fax,0.38
+29,"Tenex Personal Project File with Scoop Front Design, Black",Carlos Soltero,1792,-5.45,13.48,4.51,Nunavut,Storage & Organization,0.59
+30,Col-Erase Pencils with Erasers,Grant Carroll,2275,41.67,6.08,1.17,Nunavut,Pens & Art Supplies,0.56
+31,"Imation 3.5"" DS/HD IBM Formatted Diskettes, 10/Pack",Don Miller,2277,-46.03,5.98,4.38,Nunavut,Computer Peripherals,0.75
+32,"White Dual Perf Computer Printout Paper, 2700 Sheets, 1 Part, Heavyweight, 20 lbs., 14 7/8 x 11",Don Miller,2277,33.67,40.99,19.99,Nunavut,Paper,0.36
+33,Self-Adhesive Address Labels for Typewriters by Universal,Alan Barnes,2532,140.01,7.31,0.49,Nunavut,Labels,0.38
+34,Accessory37,Alan Barnes,2532,-78.96,20.99,2.5,Nunavut,Telephones and Communication,0.81
+35,Fuji 5.2GB DVD-RAM,Jack Garza,2631,252.66,40.96,1.99,Nunavut,Computer Peripherals,0.55
+36,Bevis Steel Folding Chairs,Julia West,2757,-1766.01,95.95,74.35,Nunavut,Chairs & Chairmats,0.57
+37,Avery Binder Labels,Eugene Barchas,2791,-236.27,3.89,7.01,Nunavut,Binders and Binder Accessories,0.37
+38,Hon Every-Day Chair Series Swivel Task Chairs,Eugene Barchas,2791,80.44,120.98,30,Nunavut,Chairs & Chairmats,0.64
+39,"IBM Multi-Purpose Copy Paper, 8 1/2 x 11"", Case",Eugene Barchas,2791,118.94,30.98,5.76,Nunavut,Paper,0.4
+40,Global Troy Executive Leather Low-Back Tilter,Edward Hooks,2976,3424.22,500.98,26,Nunavut,Chairs & Chairmats,0.6
+41,XtraLife ClearVue Slant-D Ring Binders by Cardinal,Brad Eason,3232,-11.83,7.84,4.71,Nunavut,Binders and Binder Accessories,0.35
+42,Computer Printout Paper with Letter-Trim Perforations,Nicole Hansen,3524,52.35,18.97,9.03,Nunavut,Paper,0.37
+43,6160,Dorothy Wardle,3908,-180.20,115.99,2.5,Nunavut,Telephones and Communication,0.57
+44,Avery 49,Aaron Bergman,4132,1.32,2.88,0.5,Nunavut,Labels,0.36
+45,Hoover Portapower Portable Vacuum,Jim Radford,4612,-375.64,4.48,49,Nunavut,Appliances,0.6
+46,Timeport L7089,Annie Cyprus,4676,-104.25,125.99,7.69,Nunavut,Telephones and Communication,0.58
+47,Avery 510,Annie Cyprus,4676,85.96,3.75,0.5,Nunavut,Labels,0.37
+48,Xerox 1881,Annie Cyprus,4676,-8.38,12.28,6.47,Nunavut,Paper,0.38
+49,LX 788,Annie Cyprus,4676,1115.69,155.99,8.99,Nunavut,Telephones and Communication,0.58
+50,"Cardinal Slant-D Ring Binder, Heavy Gauge Vinyl",Annie Cyprus,5284,-3.05,8.69,2.99,Nunavut,Binders and Binder Accessories,0.39
+51,"Memorex 4.7GB DVD-RAM, 3/Pack",Clay Rozendal,5316,514.07,31.78,1.99,Nunavut,Computer Peripherals,0.42
+52,Unpadded Memo Slips,Don Jones,5409,-7.04,3.98,2.97,Nunavut,Paper,0.35
+53,"Adams Telephone Message Book W/Dividers/Space For Phone Numbers, 5 1/4""X8 1/2"", 300/Messages",Beth Thompson,5506,4.41,5.88,3.04,Nunavut,Paper,0.36
+54,"Eldon Expressions Desk Accessory, Wood Pencil Holder, Oak",Frank Price,5569,-0.06,9.65,6.22,Nunavut,Office Furnishings,0.55
+55,Bell Sonecor JB700 Caller ID,Michelle Lonsdale,5607,-50.33,7.99,5.03,Nunavut,Telephones and Communication,0.6
+56,Avery Arch Ring Binders,Ann Chong,5894,87.68,58.1,1.49,Nunavut,Binders and Binder Accessories,0.38
+57,APC 7 Outlet Network SurgeArrest Surge Protector,Ann Chong,5894,-68.22,80.48,4.5,Nunavut,Appliances,0.55
+58,"Deflect-o RollaMat Studded, Beveled Mat for Medium Pile Carpeting",Joy Bell,5925,-354.90,92.23,39.61,Nunavut,Office Furnishings,0.67
+59,Accessory4,Joy Bell,5925,-267.01,85.99,0.99,Nunavut,Telephones and Communication,0.85
+60,Personal Creations Ink Jet Cards and Labels,Skye Norling,6016,3.63,11.48,5.43,Nunavut,Paper,0.36
+61,High Speed Automatic Electric Letter Opener,Barry Weirich,6116,-1759.58,1637.53,24.49,Nunavut,"Scissors, Rulers and Trimmers",0.81
+62,Xerox 1966,Grant Carroll,6182,-116.79,6.48,6.65,Nunavut,Paper,0.36
+63,Xerox 213,Grant Carroll,6182,-67.28,6.48,7.86,Nunavut,Paper,0.37
+64,"Boston Electric Pencil Sharpener, Model 1818, Charcoal Black",Adrian Hane,6535,-19.33,28.15,8.99,Nunavut,Pens & Art Supplies,0.57
+65,Hammermill CopyPlus Copy Paper (20Lb. and 84 Bright),Skye Norling,6884,-61.21,4.98,4.75,Nunavut,Paper,0.36
+66,"Telephone Message Books with Fax/Mobile Section, 5 1/2"" x 3 3/16""",Skye Norling,6884,119.09,6.35,1.02,Nunavut,Paper,0.39
+67,Crate-A-Files,Andrew Gjertsen,6916,-141.27,10.9,7.46,Nunavut,Storage & Organization,0.59
+68,"Angle-D Binders with Locking Rings, Label Holders",Ralph Knight,6980,-77.28,7.3,7.72,Nunavut,Binders and Binder Accessories,0.38
+69,"80 Minute CD-R Spindle, 100/Pack - Staples",Dorothy Wardle,6982,407.44,39.48,1.99,Nunavut,Computer Peripherals,0.54
+70,"Bush Westfield Collection Bookcases, Dark Cherry Finish, Fully Assembled",Dorothy Wardle,6982,-338.27,100.98,57.38,Nunavut,Bookcases,0.78
+71,12-1/2 Diameter Round Wall Clock,Dorothy Wardle,6982,52.56,19.98,10.49,Nunavut,Office Furnishings,0.49
+72,SAFCO Arco Folding Chair,Grant Carroll,7110,1902.24,276.2,24.49,Nunavut,Chairs & Chairmats,
+73,"#10 White Business Envelopes,4 1/8 x 9 1/2",Barry Weirich,7430,353.20,15.67,1.39,Nunavut,Envelopes,0.38
+74,3M Office Air Cleaner,Beth Paige,7906,271.78,25.98,5.37,Nunavut,Appliances,0.5
+75,"Global Leather and Oak Executive Chair, Black",Sylvia Foulston,8391,-268.36,300.98,64.73,Nunavut,Chairs & Chairmats,0.56
+76,Xerox 1936,Nicole Hansen,8419,70.39,19.98,5.97,Nunavut,Paper,0.38
+77,Xerox 214,Nicole Hansen,8419,-86.62,6.48,7.03,Nunavut,Paper,0.37
+78,Carina Double Wide Media Storage Towers in Natural & Black,Nicole Hansen,8833,-846.73,80.98,35,Nunavut,Storage & Organization,0.81
+79,Staples General Use 3-Ring Binders,Beth Paige,8995,8.05,1.88,1.49,Nunavut,Binders and Binder Accessories,0.37
+80,Xerox 1904,Beth Paige,8995,-78.02,6.48,5.86,Northwest Territories,Paper,0.36
+81,Luxo Professional Combination Clamp-On Lamps,Beth Paige,8995,737.94,102.3,21.26,Northwest Territories,Office Furnishings,0.59
+82,Xerox 217,Beth Paige,8995,-191.28,6.48,8.19,Northwest Territories,Paper,0.37
+83,Revere Boxed Rubber Bands by Revere,Beth Paige,8995,-21.49,1.89,0.76,Northwest Territories,Rubber Bands,0.83
+84,"Acco Smartsocket Table Surge Protector, 6 Color-Coded Adapter Outlets",Sylvia Foulston,9126,884.08,62.05,3.99,Northwest Territories,Appliances,0.55
+85,"Tennsco Snap-Together Open Shelving Units, Starter Sets and Add-On Units",Bryan Davis,9127,-329.49,279.48,35,Northwest Territories,Storage & Organization,0.8
+86,Hon 4070 Series Pagoda Round Back Stacking Chairs,Joy Bell,9509,2825.15,320.98,58.95,Northwest Territories,Chairs & Chairmats,0.57
+87,Xerox 1887,Joy Bell,9509,2.13,18.97,5.21,Northwest Territories,Paper,0.37
+88,Xerox 1891,Joy Bell,9509,707.15,48.91,5.81,Northwest Territories,Paper,0.38
+89,Avery 506,Alan Barnes,9763,75.13,4.13,0.5,Northwest Territories,Labels,0.39
+90,"Bush Heritage Pine Collection 5-Shelf Bookcase, Albany Pine Finish, *Special Order",Grant Carroll,9927,-270.63,140.98,53.48,Northwest Territories,Bookcases,0.65
+91,"Lifetime Advantage Folding Chairs, 4/Carton",Grant Carroll,9927,3387.35,218.08,18.06,Northwest Territories,Chairs & Chairmats,0.57
+92,Microsoft Natural Multimedia Keyboard,Grant Carroll,9927,-82.16,50.98,6.5,Northwest Territories,Computer Peripherals,0.73
+93,"Staples Wirebound Steno Books, 6"" x 9"", 12/Pack",Delfina Latchford,10022,-3.88,10.14,2.27,Northwest Territories,Paper,0.36
+94,"GBC Pre-Punched Binding Paper, Plastic, White, 8-1/2"" x 11""",Don Jones,10437,-191.22,15.99,13.18,Northwest Territories,Binders and Binder Accessories,0.37
+95,Bevis Boat-Shaped Conference Table,Doug Bickford,10499,31.21,262.11,62.74,Northwest Territories,Tables,0.75
+96,"Linden 12"" Wall Clock With Oak Frame",Doug Bickford,10535,-44.14,33.98,19.99,Northwest Territories,Office Furnishings,0.55
+97,Newell 326,Doug Bickford,10535,-0.79,1.76,0.7,Northwest Territories,Pens & Art Supplies,0.56
+98,Prismacolor Color Pencil Set,Jamie Kunitz,10789,76.42,19.84,4.1,Northwest Territories,Pens & Art Supplies,0.44
+99,Xerox Blank Computer Paper,Anthony Johnson,10791,93.36,19.98,5.77,Northwest Territories,Paper,0.38
+100,600 Series Flip,Ralph Knight,10945,4.22,95.99,8.99,Northwest Territories,Telephones and Communication,0.57
diff --git a/odex-event/muk_dms/demo/data/sheet03.ods b/odex-event/muk_dms/demo/data/sheet03.ods
new file mode 100644
index 000000000..b0c9c6831
Binary files /dev/null and b/odex-event/muk_dms/demo/data/sheet03.ods differ
diff --git a/odex-event/muk_dms/demo/data/slide01.odp b/odex-event/muk_dms/demo/data/slide01.odp
new file mode 100644
index 000000000..bf8cb46e6
Binary files /dev/null and b/odex-event/muk_dms/demo/data/slide01.odp differ
diff --git a/odex-event/muk_dms/demo/data/slide02.ppt b/odex-event/muk_dms/demo/data/slide02.ppt
new file mode 100644
index 000000000..0cd4ac593
Binary files /dev/null and b/odex-event/muk_dms/demo/data/slide02.ppt differ
diff --git a/odex-event/muk_dms/demo/data/text.rst b/odex-event/muk_dms/demo/data/text.rst
new file mode 100644
index 000000000..33ebb9deb
--- /dev/null
+++ b/odex-event/muk_dms/demo/data/text.rst
@@ -0,0 +1,404 @@
+A ReStructuredText Primer
+=========================
+
+:Author: Richard Jones
+:Version: $Revision: 5801 $
+:Copyright: This document has been placed in the public domain.
+
+.. contents::
+
+
+The text below **contains** links that look like "(quickref__)". These
+are relative links that point to the `Quick reStructuredText`_ user
+reference. If these links don't work, please refer to the `master
+quick reference`_ document.
+
+__
+.. _Quick reStructuredText: quickref.html
+.. _master quick reference:
+ http://docutils.sourceforge.net/docs/user/rst/quickref.html
+
+.. Note:: This document is an informal introduction to
+ reStructuredText. The `What Next?`_ section below has links to
+ further resources, including a formal reference.
+
+
+Structure
+---------
+
+From the **outset**, let me say that "Structured Text" is probably a bit
+of a misnomer. It's more like "Relaxed Text" that uses certain
+consistent patterns. These patterns are interpreted by a HTML
+converter to produce "Very Structured Text" that can be used by a web
+browser.
+
+The most basic pattern recognised is a **paragraph** (quickref__).
+That's a chunk of text that is separated by blank lines (one is
+enough). Paragraphs must have the same indentation -- that is, line
+up at their left edge. Paragraphs that start indented will result in
+indented quote paragraphs. For example::
+
+ This is a paragraph. It's quite
+ short.
+
+ This paragraph will result in an indented block of
+ text, typically used for quoting other text.
+
+ This is another one.
+
+Results in:
+
+ This is a paragraph. It's quite
+ short.
+
+ This paragraph will result in an indented block of
+ text, typically used for quoting other text.
+
+ This is another one.
+
+__ quickref.html#paragraphs
+
+
+Text styles
+-----------
+
+(quickref__)
+
+__ quickref.html#inline-markup
+
+Inside paragraphs and other bodies of text, you may additionally mark
+text for *italics* with "``*italics*``" or **bold** with
+"``**bold**``". This is called "inline markup".
+
+If you want something to appear as a fixed-space literal, use
+"````double back-quotes````". Note that no further fiddling is done
+inside the double back-quotes -- so asterisks "``*``" etc. are left
+alone.
+
+If you find that you want to use one of the "special" characters in
+text, it will generally be OK -- reStructuredText is pretty smart.
+For example, this lone asterisk * is handled just fine, as is the
+asterisk in this equation: 5*6=30. If you actually
+want text \*surrounded by asterisks* to **not** be italicised, then
+you need to indicate that the asterisk is not special. You do this by
+placing a backslash just before it, like so "``\*``" (quickref__), or
+by enclosing it in double back-quotes (inline literals), like this::
+
+ ``*``
+
+__ quickref.html#escaping
+
+.. Tip:: Think of inline markup as a form of (parentheses) and use it
+ the same way: immediately before and after the text being marked
+ up. Inline markup by itself (surrounded by whitespace) or in the
+ middle of a word won't be recognized. See the `markup spec`__ for
+ full details.
+
+__ ../../ref/rst/restructuredtext.html#inline-markup
+
+
+Lists
+-----
+
+Lists of items come in three main flavours: **enumerated**,
+**bulleted** and **definitions**. In all list cases, you may have as
+many paragraphs, sublists, etc. as you want, as long as the left-hand
+side of the paragraph or whatever aligns with the first line of text
+in the list item.
+
+Lists must always start a new paragraph -- that is, they must appear
+after a blank line.
+
+**enumerated** lists (numbers, letters or roman numerals; quickref__)
+ __ quickref.html#enumerated-lists
+
+ Start a line off with a number or letter followed by a period ".",
+ right bracket ")" or surrounded by brackets "( )" -- whatever you're
+ comfortable with. All of the following forms are recognised::
+
+ 1. numbers
+
+ A. upper-case letters
+ and it goes over many lines
+
+ with two paragraphs and all!
+
+ a. lower-case letters
+
+ 3. with a sub-list starting at a different number
+ 4. make sure the numbers are in the correct sequence though!
+
+ I. upper-case roman numerals
+
+ i. lower-case roman numerals
+
+ (1) numbers again
+
+ 1) and again
+
+ Results in (note: the different enumerated list styles are not
+ always supported by every web browser, so you may not get the full
+ effect here):
+
+ 1. numbers
+
+ A. upper-case letters
+ and it goes over many lines
+
+ with two paragraphs and all!
+
+ a. lower-case letters
+
+ 3. with a sub-list starting at a different number
+ 4. make sure the numbers are in the correct sequence though!
+
+ I. upper-case roman numerals
+
+ i. lower-case roman numerals
+
+ (1) numbers again
+
+ 1) and again
+
+**bulleted** lists (quickref__)
+ __ quickref.html#bullet-lists
+
+ Just like enumerated lists, start the line off with a bullet point
+ character - either "-", "+" or "*"::
+
+ * a bullet point using "*"
+
+ - a sub-list using "-"
+
+ + yet another sub-list
+
+ - another item
+
+ Results in:
+
+ * a bullet point using "*"
+
+ - a sub-list using "-"
+
+ + yet another sub-list
+
+ - another item
+
+**definition** lists (quickref__)
+ __ quickref.html#definition-lists
+
+ Unlike the other two, the definition lists consist of a term, and
+ the definition of that term. The format of a definition list is::
+
+ what
+ Definition lists associate a term with a definition.
+
+ *how*
+ The term is a one-line phrase, and the definition is one or more
+ paragraphs or body elements, indented relative to the term.
+ Blank lines are not allowed between term and definition.
+
+ Results in:
+
+ what
+ Definition lists associate a term with a definition.
+
+ *how*
+ The term is a one-line phrase, and the definition is one or more
+ paragraphs or body elements, indented relative to the term.
+ Blank lines are not allowed between term and definition.
+
+
+Preformatting (code samples)
+----------------------------
+(quickref__)
+
+__ quickref.html#literal-blocks
+
+To just include a chunk of preformatted, never-to-be-fiddled-with
+text, finish the prior paragraph with "``::``". The preformatted
+block is finished when the text falls back to the same indentation
+level as a paragraph prior to the preformatted block. For example::
+
+ An example::
+
+ Whitespace, newlines, blank lines, and all kinds of markup
+ (like *this* or \this) is preserved by literal blocks.
+ Lookie here, I've dropped an indentation level
+ (but not far enough)
+
+ no more example
+
+Results in:
+
+ An example::
+
+ Whitespace, newlines, blank lines, and all kinds of markup
+ (like *this* or \this) is preserved by literal blocks.
+ Lookie here, I've dropped an indentation level
+ (but not far enough)
+
+ no more example
+
+Note that if a paragraph consists only of "``::``", then it's removed
+from the output::
+
+ ::
+
+ This is preformatted text, and the
+ last "::" paragraph is removed
+
+Results in:
+
+::
+
+ This is preformatted text, and the
+ last "::" paragraph is removed
+
+
+Sections
+--------
+
+(quickref__)
+
+__ quickref.html#section-structure
+
+To break longer text up into sections, you use **section headers**.
+These are a single line of text (one or more words) with adornment: an
+underline alone, or an underline and an overline together, in dashes
+"``-----``", equals "``======``", tildes "``~~~~~~``" or any of the
+non-alphanumeric characters ``= - ` : ' " ~ ^ _ * + # < >`` that you
+feel comfortable with. An underline-only adornment is distinct from
+an overline-and-underline adornment using the same character. The
+underline/overline must be at least as long as the title text. Be
+consistent, since all sections marked with the same adornment style
+are deemed to be at the same level::
+
+ Chapter 1 Title
+ ===============
+
+ Section 1.1 Title
+ -----------------
+
+ Subsection 1.1.1 Title
+ ~~~~~~~~~~~~~~~~~~~~~~
+
+ Section 1.2 Title
+ -----------------
+
+ Chapter 2 Title
+ ===============
+
+This results in the following structure, illustrated by simplified
+pseudo-XML::
+
+
+
+ Chapter 1 Title
+
+
+ Section 1.1 Title
+
+
+ Subsection 1.1.1 Title
+
+
+ Section 1.2 Title
+
+
+ Chapter 2 Title
+
+(Pseudo-XML uses indentation for nesting and has no end-tags. It's
+not possible to show actual processed output, as in the other
+examples, because sections cannot exist inside block quotes. For a
+concrete example, compare the section structure of this document's
+source text and processed output.)
+
+Note that section headers are available as link targets, just using
+their name. To link to the Lists_ heading, I write "``Lists_``". If
+the heading has a space in it like `text styles`_, we need to quote
+the heading "```text styles`_``".
+
+
+Document Title / Subtitle
+`````````````````````````
+
+The title of the whole document is distinct from section titles and
+may be formatted somewhat differently (e.g. the HTML writer by default
+shows it as a centered heading).
+
+To indicate the document title in reStructuredText, use a unique adornment
+style at the beginning of the document. To indicate the document subtitle,
+use another unique adornment style immediately after the document title. For
+example::
+
+ ================
+ Document Title
+ ================
+ ----------
+ Subtitle
+ ----------
+
+ Section Title
+ =============
+
+ ...
+
+Note that "Document Title" and "Section Title" above both use equals
+signs, but are distict and unrelated styles. The text of
+overline-and-underlined titles (but not underlined-only) may be inset
+for aesthetics.
+
+
+Images
+------
+
+(quickref__)
+
+__ quickref.html#directives
+
+To include an image in your document, you use the the ``image`` directive__.
+For example::
+
+ .. image:: https://picsum.photos/200/300/?random
+
+results in:
+
+.. image:: https://picsum.photos/200/300/?random
+
+The ``images/biohazard.png`` part indicates the filename of the image
+you wish to appear in the document. There's no restriction placed on
+the image (format, size etc). If the image is to appear in HTML and
+you wish to supply additional information, you may::
+
+ .. image:: images/biohazard.png
+ :height: 100
+ :width: 200
+ :scale: 50
+ :alt: alternate text
+
+See the full `image directive documentation`__ for more info.
+
+__ ../../ref/rst/directives.html
+__ ../../ref/rst/directives.html#images
+
+
+What Next?
+----------
+
+This primer introduces the most common features of reStructuredText,
+but there are a lot more to explore. The `Quick reStructuredText`_
+user reference is a good place to go next. For complete details, the
+`reStructuredText Markup Specification`_ is the place to go [#]_.
+
+Users who have questions or need assistance with Docutils or
+reStructuredText should post a message to the Docutils-users_ mailing
+list.
+
+.. [#] If that relative link doesn't work, try the master document:
+ http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html.
+
+.. _reStructuredText Markup Specification:
+ ../../ref/rst/restructuredtext.html
+.. _Docutils-users: ../mailing-lists.html#docutils-users
+.. _Docutils project web site: http://docutils.sourceforge.net/
\ No newline at end of file
diff --git a/odex-event/muk_dms/demo/data/text.txt b/odex-event/muk_dms/demo/data/text.txt
new file mode 100644
index 000000000..e0f98f53f
--- /dev/null
+++ b/odex-event/muk_dms/demo/data/text.txt
@@ -0,0 +1,27 @@
+Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus condimentum sagittis lacus, laoreet luctus ligula laoreet ut. Vestibulum ullamcorper accumsan velit vel vehicula. Proin tempor lacus arcu. Nunc at elit condimentum, semper nisi et, condimentum mi. In venenatis blandit nibh at sollicitudin. Vestibulum dapibus mauris at orci maximus pellentesque. Nullam id elementum ipsum. Suspendisse cursus lobortis viverra. Proin et erat at mauris tincidunt porttitor vitae ac dui.
+
+Donec vulputate lorem tortor, nec fermentum nibh bibendum vel. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent dictum luctus massa, non euismod lacus. Pellentesque condimentum dolor est, ut dapibus lectus luctus ac. Ut sagittis commodo arcu. Integer nisi nulla, facilisis sit amet nulla quis, eleifend suscipit purus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Aliquam euismod ultrices lorem, sit amet imperdiet est tincidunt vel. Phasellus dictum justo sit amet ligula varius aliquet auctor et metus. Fusce vitae tortor et nisi pulvinar vestibulum eget in risus. Donec ante ex, placerat a lorem eget, ultricies bibendum purus. Nam sit amet neque non ante laoreet rutrum. Nullam aliquet commodo urna, sed ullamcorper odio feugiat id. Mauris nisi sapien, porttitor in condimentum nec, venenatis eu urna. Pellentesque feugiat diam est, at rhoncus orci porttitor non.
+
+Nulla luctus sem sit amet nisi consequat, id ornare ipsum dignissim. Sed elementum elit nibh, eu condimentum orci viverra quis. Aenean suscipit vitae felis non suscipit. Suspendisse pharetra turpis non eros semper dictum. Etiam tincidunt venenatis venenatis. Praesent eget gravida lorem, ut congue diam. Etiam facilisis elit at porttitor egestas. Praesent consequat, velit non vulputate convallis, ligula diam sagittis urna, in venenatis nisi justo ut mauris. Vestibulum posuere sollicitudin mi, et vulputate nisl fringilla non. Nulla ornare pretium velit a euismod. Nunc sagittis venenatis vestibulum. Nunc sodales libero a est ornare ultricies. Sed sed leo sed orci pellentesque ultrices. Mauris sollicitudin, sem quis placerat ornare, velit arcu convallis ligula, pretium finibus nisl sapien vel sem. Vivamus sit amet tortor id lorem consequat hendrerit. Nullam at dui risus.
+
+Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed feugiat semper velit consequat facilisis. Etiam facilisis justo non iaculis dictum. Fusce turpis neque, pharetra ut odio eu, hendrerit rhoncus lacus. Nunc orci felis, imperdiet vel interdum quis, porta eu ipsum. Pellentesque dictum sem lacinia, auctor dui in, malesuada nunc. Maecenas sit amet mollis eros. Proin fringilla viverra ligula, sollicitudin viverra ante sollicitudin congue. Donec mollis felis eu libero malesuada, et lacinia risus interdum.
+
+Etiam vitae accumsan augue. Ut urna orci, malesuada ut nisi a, condimentum gravida magna. Nulla bibendum ex in vulputate sagittis. Nulla facilisi. Nullam faucibus et metus ac consequat. Quisque tempor eros velit, id mattis nibh aliquet a. Aenean tempor elit ut finibus auctor. Sed at imperdiet mauris. Vestibulum pharetra non lacus sed pulvinar. Sed pellentesque magna a eros volutpat ullamcorper. In hac habitasse platea dictumst. Donec ipsum mi, feugiat in eros sed, varius lacinia turpis. Donec vulputate tincidunt dui ac laoreet. Sed in eros dui. Pellentesque placerat tristique ligula eu finibus. Proin nec faucibus felis, eu commodo ipsum.
+
+Integer eu hendrerit diam, sed consectetur nunc. Aliquam a sem vitae leo fermentum faucibus quis at sem. Etiam blandit, quam quis fermentum varius, ante urna ultricies lectus, vel pellentesque ligula arcu nec elit. Donec placerat ante in enim scelerisque pretium. Donec et rhoncus erat. Aenean tempor nisi vitae augue tincidunt luctus. Nam condimentum dictum ante, et laoreet neque pellentesque id. Curabitur consectetur cursus neque aliquam porta. Ut interdum nunc nec nibh vestibulum, in sagittis metus facilisis. Pellentesque feugiat condimentum metus. Etiam venenatis quam at ante rhoncus vestibulum. Maecenas suscipit congue pellentesque. Vestibulum suscipit scelerisque fermentum. Nulla iaculis risus ac vulputate porttitor.
+
+Mauris nec metus vel dolor blandit faucibus et vel magna. Ut tincidunt ipsum non nunc dapibus, sed blandit mi condimentum. Quisque pharetra interdum quam nec feugiat. Sed pellentesque nulla et turpis blandit interdum. Curabitur at metus vitae augue elementum viverra. Sed mattis lorem non enim fermentum finibus. Sed at dui in magna dignissim accumsan. Proin tincidunt ultricies cursus. Maecenas tincidunt magna at urna faucibus lacinia.
+
+Quisque venenatis justo sit amet tortor condimentum, nec tincidunt tellus viverra. Morbi risus ipsum, consequat convallis malesuada non, fermentum non velit. Nulla facilisis orci eget ligula mattis fermentum. Aliquam vel velit ultricies, sollicitudin nibh eu, congue velit. Donec nulla lorem, euismod id cursus at, sollicitudin et arcu. Proin vitae tincidunt ipsum. Vivamus elementum eleifend justo, placerat interdum nulla rutrum id.
+
+Phasellus fringilla luctus magna, a finibus justo dapibus a. Nam risus felis, rhoncus eget diam sit amet, congue facilisis nibh. Interdum et malesuada fames ac ante ipsum primis in faucibus. Praesent consequat euismod diam, eget volutpat magna convallis at. Mauris placerat pellentesque imperdiet. Nulla porta scelerisque enim, et scelerisque neque bibendum in. Proin eget turpis nisi. Suspendisse ut est a erat egestas eleifend at euismod arcu. Donec aliquet, nisi sed faucibus condimentum, nisi metus dictum eros, nec dignissim justo odio id nulla. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Maecenas sollicitudin, justo id elementum eleifend, justo neque aliquet nibh, finibus malesuada metus erat eget neque. Suspendisse nec auctor orci. Aenean et vestibulum nulla. Nullam hendrerit augue tristique, commodo metus id, sodales lorem. Etiam feugiat dui est, vitae auctor risus convallis non.
+
+Maecenas turpis enim, consectetur eget lectus eu, hendrerit posuere lacus. Praesent efficitur, felis eget dapibus consectetur, nisi massa dignissim enim, nec semper dolor est eu urna. Nullam ut sodales lorem. Aliquam dapibus faucibus diam. Vestibulum vel magna et dolor gravida imperdiet ut sit amet sem. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur elementum metus tincidunt nulla euismod ultricies. Duis elementum nec neque in porttitor. Nulla sagittis lorem elit, et consectetur ante laoreet eu. Maecenas nulla tellus, scelerisque ac erat sed, fermentum dapibus metus. Donec tincidunt fermentum molestie.
+
+Sed consequat mi at maximus faucibus. Pellentesque aliquet tincidunt sapien vel auctor. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Praesent accumsan nunc eget leo aliquam, facilisis hendrerit turpis egestas. Morbi in ultricies mauris, a eleifend turpis. Quisque fringilla massa iaculis risus ultrices, sit amet tincidunt dui varius. Quisque maximus porta tristique. Proin tincidunt, turpis ut tempor pretium, lectus ipsum ullamcorper leo, ac tincidunt felis dui non leo. Aenean porta augue ligula, non consequat ipsum aliquet et. Suspendisse ut suscipit ex. Pellentesque vitae lacinia arcu. Curabitur eget tincidunt nulla, non bibendum metus. Nullam mi ipsum, eleifend vitae tortor pulvinar, facilisis sollicitudin ipsum.
+
+Vestibulum molestie risus lorem, at feugiat lorem congue sed. Phasellus ullamcorper laoreet enim, nec aliquam turpis scelerisque et. Etiam dictum metus in elit aliquam dapibus. Vivamus vel lectus velit. Nam sed purus luctus, commodo dui quis, malesuada dui. Nulla porttitor aliquet elit sit amet viverra. Proin tempor nulla urna, non aliquet metus maximus quis. Aliquam ac lectus nec mi aliquam sagittis. Quisque venenatis quam eget nisl tempor, egestas rutrum eros eleifend. Nullam venenatis commodo velit, non tempor mauris fermentum ut. In a metus quis erat cursus sagittis. Donec congue nisl in viverra egestas.
+
+Vestibulum facilisis ligula magna, eu ornare lectus varius et. Mauris facilisis faucibus quam, quis mollis eros convallis non. Interdum et malesuada fames ac ante ipsum primis in faucibus. Praesent sit amet rutrum erat. Suspendisse potenti. Donec lorem mi, sagittis a fringilla sit amet, sagittis bibendum mauris. In in diam et lorem rutrum eleifend a et felis. Sed ac magna quis enim faucibus dictum. Suspendisse blandit enim eu ex laoreet gravida.
+
+Suspendisse sed semper felis. Etiam mattis magna mi, suscipit ullamcorper tellus euismod sed. Aenean congue scelerisque ligula id sodales. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Nunc sem lectus, gravida ac dui non, pharetra posuere leo. Maecenas lacus libero, facilisis et elit vitae, commodo facilisis sem. Vivamus id nisl nulla. Integer at maximus dui. Ut a tincidunt lorem. Vivamus vitae ligula vel lacus cursus condimentum. Phasellus quis mauris lobortis, finibus lorem in, vulputate ex. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed faucibus aliquam metus, quis varius elit porttitor id. Vivamus dignissim sollicitudin scelerisque. Morbi tincidunt, dolor quis vehicula consequat, dui diam condimentum nunc, vitae scelerisque odio libero nec ligula. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae;
diff --git a/odex-event/muk_dms/demo/data/vector.svg b/odex-event/muk_dms/demo/data/vector.svg
new file mode 100644
index 000000000..56900714f
--- /dev/null
+++ b/odex-event/muk_dms/demo/data/vector.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/odex-event/muk_dms/demo/data/video.mp4 b/odex-event/muk_dms/demo/data/video.mp4
new file mode 100644
index 000000000..20733f83b
Binary files /dev/null and b/odex-event/muk_dms/demo/data/video.mp4 differ
diff --git a/odex-event/muk_dms/demo/directory.xml b/odex-event/muk_dms/demo/directory.xml
new file mode 100644
index 000000000..77315eb61
--- /dev/null
+++ b/odex-event/muk_dms/demo/directory.xml
@@ -0,0 +1,136 @@
+
+
+
+
+
+
+
+ Documents
+
+
+
+
+
+
+
+
+ Media
+
+
+
+
+
+
+
+ Sheets
+
+
+
+
+
+
+
+ Templates
+
+
+
+
+
+
+
+
+ Photos
+
+
+
+
+
+
+
+ 2017
+
+
+
+
+
+
+
+ 2018
+
+
+
+
+
+
+
+ Videos
+
+
+
+
+
+
+ Music
+
+
+
+
+
+
+ Graphics
+
+
+
+
+
+ Mails
+
+
+
+
+
+
+
+ Data
+
+
+
+
+
+
+
+ Code
+
+
+
+
+
+
+
+ Slides
+
+
+
+
+
+
\ No newline at end of file
diff --git a/odex-event/muk_dms/demo/file.xml b/odex-event/muk_dms/demo/file.xml
new file mode 100644
index 000000000..e8821172f
--- /dev/null
+++ b/odex-event/muk_dms/demo/file.xml
@@ -0,0 +1,274 @@
+
+
+
+
+
+
+
+ Sydney.jpg
+
+
+
+
+
+
+
+ Logo_01.jpg
+
+
+
+
+
+
+ Logo_02.jpg
+
+
+
+
+
+
+
+ Logo_03.jpg
+
+
+
+
+
+
+ Logo.svg
+
+
+
+
+
+
+
+ Loop_01.wav
+
+
+
+
+
+
+
+ Loop_02.wav
+
+
+
+
+
+
+
+ Loop_03.mp3
+
+
+
+
+
+
+
+ Loop_04.mp3
+
+
+
+
+
+
+
+ Video.mp4
+
+
+
+
+
+
+
+ Mail_01.eml
+
+
+
+
+
+
+
+ Mail_02.eml
+
+
+
+
+
+
+ Text.txt
+
+
+
+
+
+
+ ASPECTJ.aj
+
+
+
+
+
+
+ Bash.sh
+
+
+
+
+
+ C.c
+
+
+
+
+
+ Cplusplus.cc
+
+
+
+
+
+ CSharp.cs
+
+
+
+
+
+ COBOL.cbl
+
+
+
+
+
+ CoffeeScript.coffee
+
+
+
+
+
+ Fortran.f
+
+
+
+
+
+ Go.go
+
+
+
+
+
+ Groovy.groovy
+
+
+
+
+
+ Java.java
+
+
+
+
+
+ Scala.sc
+
+
+
+
+
+ Sample.md
+
+
+
+
+
+ Document_05.pdf
+
+
+
+
+
+
+ Slide_01.odp
+
+
+
+
+
+ Slide_02.ppt
+
+
+
+
+
+ Document_02.doc
+
+
+
+
+
+
+ Document_03.odt
+
+
+
+
+
+
+ Sheet_01.xls
+
+
+
+
+
+
+ Sheet_02.csv
+
+
+
+
+
+
+ Sheet_03.ods
+
+
+
+
+
+
+ Document_04.rtf
+
+
+
+
+
+
+ Text.rst
+
+
+
+
+
+
\ No newline at end of file
diff --git a/odex-event/muk_dms/demo/res_users.xml b/odex-event/muk_dms/demo/res_users.xml
new file mode 100644
index 000000000..db3873e8e
--- /dev/null
+++ b/odex-event/muk_dms/demo/res_users.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/odex-event/muk_dms/demo/storage.xml b/odex-event/muk_dms/demo/storage.xml
new file mode 100644
index 000000000..07cb8becb
--- /dev/null
+++ b/odex-event/muk_dms/demo/storage.xml
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+ Documents Storage
+ database
+
+
+
\ No newline at end of file
diff --git a/odex-event/muk_dms/demo/tag.xml b/odex-event/muk_dms/demo/tag.xml
new file mode 100644
index 000000000..ccaebb130
--- /dev/null
+++ b/odex-event/muk_dms/demo/tag.xml
@@ -0,0 +1,93 @@
+
+
+
+
+
+
+
+ Customer
+ 1
+
+
+
+
+ Partner
+ 2
+
+
+
+
+ Project
+ 3
+
+
+
+
+ Sales
+ 4
+
+
+
+
+ Portal
+ 5
+
+
+
+
+ Apps
+ 6
+
+
+
+
+ Accounting
+ 7
+
+
+
+
+ Customer Invoice
+ 8
+
+
+
+
+ Vendor Bill
+ 9
+
+
+
+
+ Product
+ 10
+
+
+
+
+ Contract
+ 11
+
+
+
+
\ No newline at end of file
diff --git a/odex-event/muk_dms/doc/changelog.rst b/odex-event/muk_dms/doc/changelog.rst
new file mode 100644
index 000000000..48b69e6d3
--- /dev/null
+++ b/odex-event/muk_dms/doc/changelog.rst
@@ -0,0 +1,62 @@
+`2.7.0`
+-------
+
+- Added Kanban Search Panel
+
+`2.6.0`
+-------
+
+- Added Kanban Mega Menu
+
+`2.5.0`
+-------
+
+- Added Onboarding
+
+`2.4.0`
+-------
+
+- Added migration view
+
+`2.3.0`
+-------
+
+- Restructuring
+
+`2.2.0`
+-------
+
+- Moved document view to a separate module
+
+`2.1.0`
+-------
+
+- Added small and medium thumbnail size fields
+
+`2.0.0`
+-------
+
+- Migrated to Python 3
+- Updated dependencies
+- Updated document views and widgets
+- Updated database models (no automatic migration!)
+
+`1.3.0`
+-------
+
+- Updated dependencies
+
+`1.2.0`
+-------
+
+- Updated database models
+
+`1.1.0`
+-------
+
+- Updated database models
+
+`1.0.0`
+-------
+
+- Init version
diff --git a/odex-event/muk_dms/doc/index.rst b/odex-event/muk_dms/doc/index.rst
new file mode 100644
index 000000000..dc2b70be9
--- /dev/null
+++ b/odex-event/muk_dms/doc/index.rst
@@ -0,0 +1,123 @@
+==============================
+MuK Document Management System
+==============================
+
+MuK Documents is a module to create, manage and view files directly within Odoo.
+In addition to views for files and folders, it offers its own all in one view
+to make working with documents easier. This module is only the basis for an
+entire ecosystem of apps that extend and seamlessly integrate with the document
+management system.
+
+Installation
+============
+
+To install this module, you need to:
+
+Download the module and add it to your Odoo addons folder. Afterward, log on to
+your Odoo server and go to the Apps menu. Trigger the debug mode and update the
+list by clicking on the "Update Apps List" link. Now install the module by
+clicking on the install button.
+
+Another way to install this module is via the package management for Python
+(`PyPI `_).
+
+To install our modules using the package manager make sure
+`odoo-autodiscover `_ is installed
+correctly. Then open a console and install the module by entering the following
+command:
+
+``pip install --extra-index-url https://nexus.mukit.at/repository/odoo/simple ``
+
+The module name consists of the Odoo version and the module name, where
+underscores are replaced by a dash.
+
+**Module:**
+
+``odoo-addon-``
+
+**Example:**
+
+``sudo -H pip3 install --extra-index-url https://nexus.mukit.at/repository/odoo/simple odoo11-addon-muk-utils``
+
+Once the installation has been successfully completed, the app is already in the
+correct folder. Log on to your Odoo server and go to the Apps menu. Trigger the
+debug mode and update the list by clicking on the "Update Apps List" link. Now
+install the module by clicking on the install button.
+
+The biggest advantage of this variant is that you can now also update the app
+using the "pip" command. To do this, enter the following command in your console:
+
+``pip install --upgrade --extra-index-url https://nexus.mukit.at/repository/odoo/simple ``
+
+When the process is finished, restart your server and update the application in
+Odoo. The steps are the same as for the installation only the button has changed
+from "Install" to "Upgrade".
+
+You can also view available Apps directly in our `repository `_
+and find a more detailed installation guide on our `website `_.
+
+For modules licensed under OPL-1, you will receive access data when you purchase
+the module. If the modules were not purchased directly from
+`MuK IT `_ please contact our support (support@mukit.at)
+with a confirmation of purchase to receive the corresponding access data.
+
+Upgrade
+============
+
+To upgrade this module, you need to:
+
+Download the module and add it to your Odoo addons folder. Restart the server
+and log on to your Odoo server. Select the Apps menu and upgrade the module by
+clicking on the upgrade button.
+
+If you installed the module using the "pip" command, you can also update the
+module in the same way. Just type the following command into the console:
+
+``pip install --upgrade --extra-index-url https://nexus.mukit.at/repository/odoo/simple ``
+
+When the process is finished, restart your server and update the application in
+Odoo, just like you would normally.
+
+Configuration
+=============
+
+To configure this module, you need to:
+
+#. Go to *Documents -> Configuration -> Storages*.
+#. Create a new document setting.
+#. Afterwards go to *Documents -> Directories*.
+#. Create a new directory, mark it as root and select the previously created setting.
+
+Usage
+=============
+
+The best way to manage the documents is to switch to the Documents view. Existing
+documents can be managed there and new documents can be created.
+
+Credits
+=======
+
+Contributors
+------------
+
+* Mathias Markl
+
+Images
+------------
+
+Some pictures are based on or inspired by:
+
+* `Roundicons `_
+* `Smashicons `_
+
+Author & Maintainer
+-------------------
+
+This module is maintained by the `MuK IT GmbH `_.
+
+MuK IT is an Austrian company specialized in customizing and extending Odoo.
+We develop custom solutions for your individual needs to help you focus on
+your strength and expertise to grow your business.
+
+If you want to get in touch please contact us via mail
+(sale@mukit.at) or visit our website (https://mukit.at).
diff --git a/odex-event/muk_dms/i18n/de.po b/odex-event/muk_dms/i18n/de.po
new file mode 100644
index 000000000..2532f0a28
--- /dev/null
+++ b/odex-event/muk_dms/i18n/de.po
@@ -0,0 +1,1512 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * muk_dms
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 12.0-20190128\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2019-03-05 18:29+0000\n"
+"PO-Revision-Date: 2019-06-25 11:04+0000\n"
+"Last-Translator: MuK IT \n"
+"Language-Team: German \n"
+"Language: de\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+"X-Generator: Weblate 3.7\n"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.document_onboarding_directory_panel
+msgid "/muk_dms/static/src/img/banner/documents_onboarding_directory.png"
+msgstr "/muk_dms/static/src/img/banner/documents_onboarding_directory.png"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.document_onboarding_file_panel
+msgid "/muk_dms/static/src/img/banner/documents_onboarding_file.png"
+msgstr "/muk_dms/static/src/img/banner/documents_onboarding_file.png"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_kanban
+msgid " Download"
+msgstr " Herunterladen"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_kanban
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_kanban
+msgid " Open"
+msgstr " Öffnen"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_kanban
+msgid " Lock"
+msgstr " Sperren"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_kanban
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_kanban
+msgid " Edit"
+msgstr " Bearbeiten"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_kanban
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_kanban
+msgid " Delete"
+msgstr " Löschen"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_kanban
+msgid " Unlock"
+msgstr " Entsperren"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "File Extensions"
+msgstr "Dateiendungen"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "File Size"
+msgstr "Dateigröße"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "Save this page and come back here to set up the feature."
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_form
+msgid "This file is locked!"
+msgstr "Diese Datei ist gesperrt!"
+
+#. module: muk_dms
+#: code:addons/muk_dms/models/directory.py:332
+#, python-format
+msgid "A directory can't be a root and have a parent directory."
+msgstr "Ein Wurzelverzeichnis kann kein Elternelement besitzen."
+
+#. module: muk_dms
+#: code:addons/muk_dms/models/directory.py:330
+#, python-format
+msgid "A directory has to have a parent directory."
+msgstr "Ein Verzeichnis muss ein übergeordnetes Verzeichnis haben."
+
+#. module: muk_dms
+#: code:addons/muk_dms/models/directory.py:350
+#, python-format
+msgid "A directory with the same name already exists."
+msgstr "Ein Verzeichnis mit dem gleichen Namen existiert bereits."
+
+#. module: muk_dms
+#: code:addons/muk_dms/models/directory.py:414
+#, python-format
+msgid "A file is locked, the folder cannot be deleted."
+msgstr "Eine Datei ist gesperrt, der Ordner kann nicht gelöscht werden."
+
+#. module: muk_dms
+#: code:addons/muk_dms/models/file.py:402
+#, python-format
+msgid "A file with the same name already exists."
+msgstr "Eine Datei mit dem gleichen Namen existiert bereits."
+
+#. module: muk_dms
+#: code:addons/muk_dms/models/directory.py:328
+#, python-format
+msgid "A root directory has to have a root storage."
+msgstr "Ein Root-Verzeichnis muss einen Root-Speicher haben."
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_config_settings__module_muk_dms_access
+msgid "Access Control"
+msgstr "Zugriffskontrolle"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_form
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_form
+msgid "Access Information"
+msgstr "Zugriffsinformationen"
+
+#. module: muk_dms
+#: model:muk_dms.tag,name:muk_dms.tag_07_demo
+msgid "Accounting"
+msgstr "Buchhaltung"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "Activates a file trash to restore deleted files"
+msgstr "Aktiviert einen Papierkorb, um gelöschte Dateien wiederherzustellen"
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_res_config_settings__module_muk_dms_trash
+msgid "Activates a file trash to restore deleted files."
+msgstr "Aktiviert einen Papierkorb, um gelöschte Dateien wiederherzustellen."
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "Activates the preview function on files"
+msgstr "Aktiviert die Vorschaufunktion für Dateien"
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_res_config_settings__module_muk_dms_preview
+msgid "Activates the preview function on files."
+msgstr "Aktiviert die Vorschaufunktion für Dateien."
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_category__active
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_tag__active
+msgid "Active"
+msgstr "Aktiv"
+
+#. module: muk_dms
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_directory
+msgid "Add a new Directory."
+msgstr "Füge ein neues Verzeichnis hinzu."
+
+#. module: muk_dms
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_file
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_file_migration
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_file_storage_migration
+msgid "Add a new File."
+msgstr "Fügt eine neue Datei hinzu."
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "Adds support for messages and activities on directories and files"
+msgstr ""
+"Aktiviert Unterstützung für Nachrichten und Aktivitäten in Verzeichnissen "
+"und Dateien"
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_res_config_settings__module_muk_dms_mail
+msgid "Adds support for messages and activities on directories and files."
+msgstr ""
+"Aktiviert Unterstützung für Nachrichten und Aktivitäten in Verzeichnissen "
+"und Dateien."
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_category_search
+msgid "All"
+msgstr "Alle"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_file
+msgid "All Files"
+msgstr "Alle Dateien"
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_res_config_settings__module_muk_dms_attachment_rules
+msgid "Allows attachments to be automatically placed in the right directory."
+msgstr ""
+"Ermöglicht es, Anhänge automatisch in das richtige Verzeichnis zu "
+"verschieben."
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "Allows attachments to be stored inside of Documents"
+msgstr ""
+"Ermöglicht das Speichern von Anhängen innerhalb der Dokumentenverwaltung"
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_res_config_settings__module_muk_dms_attachment
+msgid "Allows attachments to be stored inside of Documents."
+msgstr ""
+"Ermöglicht das Speichern von Anhängen innerhalb der Dokumentenverwaltung."
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_res_config_settings__module_muk_dms_attachment_wizard
+msgid "Allows documents to be used as attachments."
+msgstr "Ermöglicht die Verwendung von Dokumenten als Anhang."
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_res_config_settings__module_muk_dms_export
+msgid "Allows the conversion of existing files."
+msgstr "Ermöglicht die Konvertierung vorhandener Dateien."
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "Allows the creation of groups to define access rights"
+msgstr ""
+"Ermöglicht die Erstellung von Gruppen zur Definition von Zugriffsrechten"
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_res_config_settings__module_muk_dms_access
+msgid "Allows the creation of groups to define access rights."
+msgstr ""
+"Ermöglicht die Erstellung von Gruppen zur Definition von Zugriffsrechten."
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_res_config_settings__module_muk_dms_thumbnails
+msgid "Allows the creation of thumbnails for files."
+msgstr "Ermöglicht die Erstellung von Miniaturansichten für Dateien."
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_res_config_settings__module_muk_dms_widget
+msgid "Allows the user to use DMS documents as input for any binary field."
+msgstr ""
+"Ermöglicht es dem Benutzer, DMS-Dokumente als Eingabe für jedes Binärfeld zu "
+"verwenden."
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_res_config_settings__module_muk_archive
+msgid "Allows to download directories as a archive file."
+msgstr "Ermöglicht das Herunterladen von Verzeichnissen als Archivdatei."
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "Allows to placed attachments in the right directory"
+msgstr "Ermöglicht das Platzieren von Anhängen im rechten Verzeichnis"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "Allows you to create rule templates to create attachment rules"
+msgstr ""
+"Ermöglicht es Ihnen, Regelvorlagen zu erstellen, um Anlagenregeln zu "
+"erstellen"
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_res_config_settings__module_muk_dms_attachment_automation
+msgid "Allows you to create rule templates to create attachment rules."
+msgstr ""
+"Ermöglicht es Ihnen, Regelvorlagen zu erstellen, um Anlagenregeln zu "
+"erstellen."
+
+#. module: muk_dms
+#: model:muk_dms.tag,name:muk_dms.tag_06_demo
+msgid "Apps"
+msgstr "Apps"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__active
+msgid "Archived"
+msgstr "Archiviert"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_config_settings__module_muk_dms_attachment_automation
+msgid "Attachment Rule Automation"
+msgstr "Automatisierung von Anlagenregeln"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_config_settings__module_muk_dms_attachment_wizard
+msgid "Attachment Wizard"
+msgstr "Assistent für Anhänge"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "Attachments"
+msgstr "Dateianhänge"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_config_settings__module_muk_dms_thumbnails
+msgid "Automatic Thumbnails"
+msgstr "Automatische Miniaturansichten"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_config_settings__module_muk_dms_widget
+msgid "Binary Widget Support"
+msgstr "Binary Widget Unterstützung"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_new_form
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_new_form
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_storage_new_form
+msgid "Cancel"
+msgstr "Abbrechen"
+
+#. module: muk_dms
+#. openerp-web
+#: code:addons/muk_dms/static/src/xml/views.xml:46
+#: model:ir.actions.act_window,name:muk_dms.action_dms_category
+#: model:ir.ui.menu,name:muk_dms.menu_dms_category
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_category_search
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_category_tree
+#, python-format
+msgid "Categories"
+msgstr "Kategorien"
+
+#. module: muk_dms
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_category
+msgid "Categories are used to categorize Documents."
+msgstr "Kategorien werden verwendet, um Dokumente zu kategorisieren."
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__category
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__category
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_directory
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_file
+msgid "Category"
+msgstr "Kategorie"
+
+#. module: muk_dms
+#: sql_constraint:muk_dms.category:0
+msgid "Category name already exists!"
+msgstr "Der Kategoriename existiert bereits!"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__checksum
+msgid "Checksum/SHA1"
+msgstr "Checksumme/SHA1"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_category__child_categories
+msgid "Child Categories"
+msgstr "Kinderkategorien"
+
+#. module: muk_dms
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_directories_all_directory
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_directories_directory
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_directories_storage
+msgid "Click to add a new directory."
+msgstr "Klicken Sie hier, um ein neues Verzeichnis hinzuzufügen."
+
+#. module: muk_dms
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_files_all_directory
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_files_directory
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_files_storage
+msgid "Click to add a new file."
+msgstr "Klicken Sie hier, um eine neue Datei hinzuzufügen."
+
+#. module: muk_dms
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_tag
+msgid "Click to create a new tag."
+msgstr "Klicken Sie hier, um ein neues Tag zu erstellen."
+
+#. module: muk_dms
+#: selection:res.company,documents_onboarding_directory_state:0
+#: selection:res.company,documents_onboarding_file_state:0
+#: selection:res.company,documents_onboarding_state:0
+#: selection:res.company,documents_onboarding_storage_state:0
+msgid "Closed"
+msgstr "Geschlossen"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__color
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__color
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_directory
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_file
+msgid "Color"
+msgstr "Farbe"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_tag__color
+msgid "Color Index"
+msgstr "Farbkennzeichnung"
+
+#. module: muk_dms
+#: model:ir.model,name:muk_dms.model_res_company
+msgid "Companies"
+msgstr "Unternehmen"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__company
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__company
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_storage__company
+msgid "Company"
+msgstr "Unternehmen"
+
+#. module: muk_dms
+#: model:ir.model,name:muk_dms.model_res_config_settings
+msgid "Config Settings"
+msgstr "Konfiguration"
+
+#. module: muk_dms
+#: model:ir.ui.menu,name:muk_dms.cat_menu_muk_dms_config
+msgid "Configuration"
+msgstr "Konfiguration"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__content
+msgid "Content"
+msgstr "Inhalt"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__content_binary
+msgid "Content Binary"
+msgstr "Inhalt Binär"
+
+#. module: muk_dms
+#: model:muk_dms.tag,name:muk_dms.tag_11_demo
+msgid "Contract"
+msgstr "Vertrag"
+
+#. module: muk_dms
+#: model:muk_dms.category,name:muk_dms.category_03_demo
+msgid "Contracts"
+msgstr "Verträge"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_storage__count_storage_directories
+msgid "Count Directories"
+msgstr "Zählverzeichnisse"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__count_elements
+msgid "Count Elements"
+msgstr "Elemente zählen"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__count_files
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_storage__count_storage_files
+msgid "Count Files"
+msgstr "Dateien zählen"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__count_directories
+msgid "Count Subdirectories"
+msgstr "Unterverzeichnisse zählen"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_new_form
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_new_form
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_storage_new_form
+msgid "Create"
+msgstr "Erstellen"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__permission_create
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__permission_create
+msgid "Create Access"
+msgstr "Objekterzeugung erlauben"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.onboarding_directory_step
+msgid "Create Directory"
+msgstr "Verzeichnis erstellen"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.onboarding_storage_step
+msgid "Create Storage"
+msgstr "Speicher anlegen"
+
+#. module: muk_dms
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_category
+msgid "Create a new Category."
+msgstr "Erstellen Sie eine neue Kategorie."
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.onboarding_storage_step
+msgid "Create a new Document Storage."
+msgstr "Erstellen Sie einen neuen Dokumentenspeicher."
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.onboarding_directory_step
+msgid "Create a new Root Directory."
+msgstr "Erstellen Sie ein neues Stammverzeichnis."
+
+#. module: muk_dms
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_storage
+msgid "Create a new Storage object."
+msgstr "Erstellen Sie ein neues Speicherobjekt."
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_category__create_uid
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__create_uid
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__create_uid
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_storage__create_uid
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_tag__create_uid
+msgid "Created by"
+msgstr "Erstellt von"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_category__create_date
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__create_date
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__create_date
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_storage__create_date
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_tag__create_date
+msgid "Created on"
+msgstr "Erstellt am"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_directory
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_file
+msgid "Creation Date"
+msgstr "Erzeugt am"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__save_type
+msgid "Current Save Type"
+msgstr "Aktueller Speichertyp"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__custom_thumbnail
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__custom_thumbnail
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_mixins_thumbnail__custom_thumbnail
+msgid "Custom Thumbnail"
+msgstr "Benutzerdefinierte Miniaturansicht"
+
+#. module: muk_dms
+#: model:muk_dms.tag,name:muk_dms.tag_01_demo
+msgid "Customer"
+msgstr "Kunde"
+
+#. module: muk_dms
+#: model:muk_dms.tag,name:muk_dms.tag_08_demo
+msgid "Customer Invoice"
+msgstr "Kundenrechnung"
+
+#. module: muk_dms
+#: code:addons/muk_dms/models/storage.py:42
+#: selection:muk_dms.storage,save_type:0
+#, python-format
+msgid "Database"
+msgstr "Datenbank"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "Define forbidden file extensions"
+msgstr "Verbotene Dateierweiterungen definieren"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "Define the maximum upload size of a file in MB"
+msgstr "Definieren Sie die maximale Upload-Größe einer Datei in MB"
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_res_config_settings__documents_forbidden_extensions
+msgid "Defines a list of forbidden file extensions. (Example: 'exe,msi')"
+msgstr "Definiert eine Liste der verbotenen Dateiendungen. (Beispiel:'exe,msi')"
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_res_config_settings__documents_binary_max_size
+msgid "Defines the maximum upload size in MB. Default (25MB)"
+msgstr "Definiert die maximale Upload-Größe in MB. Standard (25MB)"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__permission_unlink
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__permission_unlink
+msgid "Delete Access"
+msgstr "Zugang löschen"
+
+#. module: muk_dms
+#. openerp-web
+#: code:addons/muk_dms/static/src/xml/views.xml:37
+#: model:ir.actions.act_window,name:muk_dms.action_dms_directories_storage
+#: model:ir.actions.act_window,name:muk_dms.action_dms_directory
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_category__directories
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_storage__storage_directories
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_tag__directories
+#: model:ir.ui.menu,name:muk_dms.menu_dms_directory
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_file
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_form
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_tree
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_storage_form
+#, python-format
+msgid "Directories"
+msgstr "Verzeichnisse"
+
+#. module: muk_dms
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_directories_all_directory
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_directories_directory
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_directories_storage
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_directory
+msgid "Directories can be used to structure and organize\n"
+" files directly in Odoo."
+msgstr ""
+"Verzeichnisse können verwendet werden, um zu strukturieren und zu "
+"organisieren._x000D_\n"
+"\t\t\tDateien direkt in Odoo."
+
+#. module: muk_dms
+#: model:ir.model,name:muk_dms.model_muk_dms_directory
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__directory
+#: model_terms:ir.ui.view,arch_db:muk_dms.onboarding_directory_step
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_form
+msgid "Directory"
+msgstr "Verzeichnis"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_category__display_name
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__display_name
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__display_name
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_mixins_thumbnail__display_name
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_storage__display_name
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_tag__display_name
+msgid "Display Name"
+msgstr "Anzeigename"
+
+#. module: muk_dms
+#: model:ir.model,name:muk_dms.model_muk_dms_category
+msgid "Document Category"
+msgstr "Dokumenttyp"
+
+#. module: muk_dms
+#: model:ir.model,name:muk_dms.model_muk_dms_tag
+msgid "Document Tag"
+msgstr "Dokumenten-Tag"
+
+#. module: muk_dms
+#: model:ir.module.category,name:muk_dms.category_dms_security
+#: model:ir.ui.menu,name:muk_dms.main_menu_muk_dms
+msgid "Documents"
+msgstr "Dokumente"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_company__documents_onboarding_directory_state
+msgid "Documents Onboarding Directory State"
+msgstr "Dokumente Onboarding Verzeichnisstatus"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_company__documents_onboarding_file_state
+msgid "Documents Onboarding File State"
+msgstr "Dokumente Onboarding Dateistatus"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_company__documents_onboarding_state
+msgid "Documents Onboarding State"
+msgstr "Dokumente Onboarding-Status"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_company__documents_onboarding_storage_state
+msgid "Documents Onboarding Storage State"
+msgstr "Dokumente Onboarding Speicherzustand"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_config_settings__module_muk_dms_attachment
+msgid "Documents Storage Location"
+msgstr "Dokumente Speicherort"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_config_settings__module_muk_dms_attachment_rules
+msgid "Documents Storage Rules"
+msgstr "Aufbewahrungsregeln für Dokumente"
+
+#. module: muk_dms
+#: selection:res.company,documents_onboarding_directory_state:0
+#: selection:res.company,documents_onboarding_file_state:0
+#: selection:res.company,documents_onboarding_state:0
+#: selection:res.company,documents_onboarding_storage_state:0
+msgid "Done"
+msgstr "Erledigt"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_config_settings__module_muk_archive
+msgid "Download Directories"
+msgstr "Verzeichnisse herunterladen"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_kanban
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_kanban
+msgid "Dropdown menu"
+msgstr "Dropdownmenu"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__is_lock_editor
+msgid "Editor"
+msgstr "Redakteur"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_form
+msgid "Elements"
+msgstr "Elemente"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "Enables a new save option to store files into a filestore"
+msgstr ""
+"Ermöglicht eine neue Speicheroption zum Speichern von Dateien in einem "
+"Filestore"
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_res_config_settings__module_muk_dms_file
+msgid "Enables a new save option to store files into a filestore."
+msgstr ""
+"Ermöglicht eine neue Speicheroption zum Speichern von Dateien in einem "
+"Filestore."
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "Enables a new save option to store files into large objects"
+msgstr ""
+"Ermöglicht eine neue Speicheroption zum Speichern von Dateien in großen "
+"Objekten"
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_res_config_settings__module_muk_dms_lobject
+msgid "Enables a new save option to store files into large objects."
+msgstr ""
+"Ermöglicht eine neue Speicheroption zum Speichern von Dateien in großen "
+"Objekten."
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_res_config_settings__module_muk_dms_finder
+msgid "Enables the Document Finder."
+msgstr "Aktiviert den Document Finder."
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "Enables version control for files"
+msgstr "Ermöglicht Versionskontrolle für Dateien"
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_res_config_settings__module_muk_dms_version
+msgid "Enables version control for files."
+msgstr "Ermöglicht die Versionskontrolle von Dateien."
+
+#. module: muk_dms
+#: code:addons/muk_dms/models/category.py:123
+#, python-format
+msgid "Error! You cannot create recursive categories."
+msgstr "Fehler! Sie können keine rekursiven Kategorien erstellen."
+
+#. module: muk_dms
+#: code:addons/muk_dms/models/directory.py:321
+#, python-format
+msgid "Error! You cannot create recursive directories."
+msgstr "Fehler! Sie können keine rekursiven Verzeichnisse erstellen."
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_config_settings__module_muk_dms_export
+msgid "Export Files"
+msgstr "Dateien exportieren"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__extension
+msgid "Extension"
+msgstr "Erweiterung"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_config_settings__documents_forbidden_extensions
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "Extensions"
+msgstr "Erweiterungen"
+
+#. module: muk_dms
+#: model:muk_dms.category,name:muk_dms.category_05_demo
+msgid "External"
+msgstr "Extern"
+
+#. module: muk_dms
+#: model:ir.model,name:muk_dms.model_muk_dms_file
+#: model_terms:ir.ui.view,arch_db:muk_dms.onboarding_file_step
+msgid "File"
+msgstr "Datei"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_config_settings__module_muk_dms_preview
+msgid "File Preview"
+msgstr "Dateivorschau"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "File Upload"
+msgstr "Datei-Upload"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__name
+msgid "Filename"
+msgstr "Dateiname"
+
+#. module: muk_dms
+#: model:ir.actions.act_window,name:muk_dms.action_dms_file
+#: model:ir.actions.act_window,name:muk_dms.action_dms_file_migration
+#: model:ir.actions.act_window,name:muk_dms.action_dms_file_storage_migration
+#: model:ir.actions.act_window,name:muk_dms.action_dms_files_all_directory
+#: model:ir.actions.act_window,name:muk_dms.action_dms_files_directory
+#: model:ir.actions.act_window,name:muk_dms.action_dms_files_storage
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_category__files
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__files
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_storage__storage_files
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_tag__files
+#: model:ir.ui.menu,name:muk_dms.menu_dms_file
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_form
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_tree
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_form
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_migration_tree
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_tree
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_storage_form
+msgid "Files"
+msgstr "Dateien"
+
+#. module: muk_dms
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_file
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_file_migration
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_file_storage_migration
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_files_all_directory
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_files_directory
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_files_storage
+msgid "Files are used to save content directly in Odoo."
+msgstr "Dateien werden verwendet, um Inhalte direkt in Odoo zu speichern."
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_config_settings__module_muk_dms_file
+msgid "Filestore Storage"
+msgstr "Filestore Speicher"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_config_settings__module_muk_dms_finder
+msgid "Finder"
+msgstr "Finder"
+
+#. module: muk_dms
+#: model:ir.actions.act_window,name:muk_dms.action_dms_settings_general
+#: model:ir.ui.menu,name:muk_dms.menu_dms_settings_general
+msgid "General Settings"
+msgstr "Allgemeine Einstellungen"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_directory
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_file
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_file_migration
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_storage_search
+msgid "Group By"
+msgstr "Gruppieren nach"
+
+#. module: muk_dms
+#: model:ir.model,name:muk_dms.model_ir_http
+msgid "HTTP Routing"
+msgstr "HTTP-Routing"
+
+#. module: muk_dms
+#: model:muk_dms.category,name:muk_dms.category_02_demo
+msgid "Human Resource"
+msgstr "Personalwesen"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_category__id
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__id
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__id
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_mixins_thumbnail__id
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_storage__id
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_tag__id
+msgid "ID"
+msgstr "ID"
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_muk_dms_file__active
+msgid "If a file is set to archived, it is not displayed, but still exists."
+msgstr ""
+"Wenn eine Datei auf archiviert gesetzt ist, wird sie nicht angezeigt, "
+"existiert aber noch."
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_muk_dms_directory__company
+#: model:ir.model.fields,help:muk_dms.field_muk_dms_file__company
+#: model:ir.model.fields,help:muk_dms.field_muk_dms_storage__company
+msgid "If set, directories and files will only be available for the selected company."
+msgstr ""
+"Wenn gesetzt, sind Verzeichnisse und Dateien nur für das ausgewählte "
+"Unternehmen verfügbar."
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_muk_dms_directory__is_hidden
+#: model:ir.model.fields,help:muk_dms.field_muk_dms_file__is_hidden
+#: model:ir.model.fields,help:muk_dms.field_muk_dms_storage__is_hidden
+msgid "Indicates if directories and files are hidden by default."
+msgstr "Zeigt an, ob Verzeichnisse und Dateien standardmäßig ausgeblendet sind."
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_muk_dms_directory__is_root_directory
+msgid "Indicates if the directory is a root directory. A root directory has a settings object,\n"
+" while a directory with a set parent inherits the settings form its parent."
+msgstr ""
+"Zeigt an, ob es sich bei dem Verzeichnis um ein Stammverzeichnis handelt. "
+"Ein Stammverzeichnis hat ein Einstellungsobjekt,_x000D_\n"
+" während ein Verzeichnis mit einem gesetzten Elternteil die "
+"Einstellungen von seinem Elternteil übernimmt."
+
+#. module: muk_dms
+#: model:muk_dms.category,name:muk_dms.category_01_demo
+msgid "Internal"
+msgstr "Intern"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_form
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_new_form
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_form
+msgid "Internal / Human Resource"
+msgstr "Intern / Personalwesen"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__is_root_directory
+msgid "Is Root Directory"
+msgstr "Ist Wurzelverzeichnis"
+
+#. module: muk_dms
+#: selection:res.company,documents_onboarding_directory_state:0
+#: selection:res.company,documents_onboarding_file_state:0
+#: selection:res.company,documents_onboarding_state:0
+#: selection:res.company,documents_onboarding_storage_state:0
+msgid "Just done"
+msgstr "Gerade fertig"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_config_settings__module_muk_dms_lobject
+msgid "Large Objects Storage"
+msgstr "Speicherung großer Objekte"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_category____last_update
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory____last_update
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file____last_update
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_mixins_thumbnail____last_update
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_storage____last_update
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_tag____last_update
+msgid "Last Modified on"
+msgstr "Zuletzt geändert am"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_category__write_uid
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__write_uid
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__write_uid
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_storage__write_uid
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_tag__write_uid
+msgid "Last Updated by"
+msgstr "Zuletzt aktualisiert durch"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_category__write_date
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__write_date
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__write_date
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_storage__write_date
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_tag__write_date
+msgid "Last Updated on"
+msgstr "Zuletzt aktualisiert am"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_form
+msgid "Lock"
+msgstr "Sperren"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__is_locked
+msgid "Locked"
+msgstr "Gesperrt"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__locked_by
+msgid "Locked by"
+msgstr "Gesperrt durch"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_config_settings__module_muk_dms_mail
+msgid "Mail Support"
+msgstr "Mail-Support"
+
+#. module: muk_dms
+#: model:res.groups,name:muk_dms.group_dms_manager
+msgid "Manager"
+msgstr "Manager"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_storage_form
+msgid "Manual File Migration"
+msgstr "Manuelle Datei-Migration"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__custom_thumbnail_medium
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__custom_thumbnail_medium
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_mixins_thumbnail__custom_thumbnail_medium
+msgid "Medium Custom Thumbnail"
+msgstr "Mittleres benutzerdefiniertes Miniaturbild"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__thumbnail_medium
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__thumbnail_medium
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_mixins_thumbnail__thumbnail_medium
+msgid "Medium Thumbnail"
+msgstr "Mittleres Miniaturbild"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_form
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_form
+msgid "Meta Information"
+msgstr "Meta-Informationen"
+
+#. module: muk_dms
+#: model:ir.actions.server,name:muk_dms.action_dms_attachment_migrate
+msgid "Migrate"
+msgstr "Migrieren"
+
+#. module: muk_dms
+#: code:addons/muk_dms/models/file.py:221
+#, python-format
+msgid "Migrate File %s of %s [ %s ]"
+msgstr "Datei migrieren %s von %s [ %s ]"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_storage_form
+msgid "Migrate Files"
+msgstr "Dateien migrieren"
+
+#. module: muk_dms
+#: model:ir.ui.menu,name:muk_dms.menu_dms_file_migration
+msgid "Migration"
+msgstr "Migration"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__migration
+msgid "Migration Status"
+msgstr "Migrationsstatus"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_directory
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_file
+msgid "Modification Date"
+msgstr "Änderungsdatum"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_directory
+msgid "My Directories"
+msgstr "Meine Verzeichnisse"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_form
+msgid "My Documents"
+msgstr "Meine Dokumente"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_file
+msgid "My Files"
+msgstr "Meine Dateien"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_category__name
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__name
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_storage__name
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_tag__name
+msgid "Name"
+msgstr "Name"
+
+#. module: muk_dms
+#: model:ir.actions.act_window,name:muk_dms.action_dms_directory_new
+#: model:ir.actions.act_window,name:muk_dms.action_dms_file_new
+msgid "New Root Directory"
+msgstr "Neues Stammverzeichnis"
+
+#. module: muk_dms
+#: model:ir.actions.act_window,name:muk_dms.action_dms_storage_new
+msgid "New Storage"
+msgstr "Neuer Speicher"
+
+#. module: muk_dms
+#: model:muk_dms.category,name:muk_dms.category_06_demo
+msgid "News"
+msgstr "Neuigkeiten"
+
+#. module: muk_dms
+#. openerp-web
+#: code:addons/muk_dms/static/src/js/views/file/kanban/file_kanban_controller.js:92
+#, python-format
+msgid "No Directory has been selected!"
+msgstr "Es wurde kein Verzeichnis ausgewählt!"
+
+#. module: muk_dms
+#: selection:res.company,documents_onboarding_directory_state:0
+#: selection:res.company,documents_onboarding_file_state:0
+#: selection:res.company,documents_onboarding_state:0
+#: selection:res.company,documents_onboarding_storage_state:0
+msgid "Not done"
+msgstr "Nicht erledigt"
+
+#. module: muk_dms
+#: code:addons/muk_dms/models/storage.py:99
+#, python-format
+msgid "Only managers can execute this action."
+msgstr "Nur Manager können diese Aktion ausführen."
+
+#. module: muk_dms
+#: model:ir.ui.menu,name:muk_dms.cat_menu_muk_dms_config_organizing
+msgid "Organizing"
+msgstr "Organisieren"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_category__parent_category
+msgid "Parent Category"
+msgstr "Oberkategorie"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__parent_directory
+msgid "Parent Directory"
+msgstr "Übergeordnetes Verzeichnis"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_category__parent_path
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__parent_path
+msgid "Parent Path"
+msgstr "Übergeordneter Pfad"
+
+#. module: muk_dms
+#: model:muk_dms.tag,name:muk_dms.tag_02_demo
+msgid "Partner"
+msgstr "Partner"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_tree
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_tree
+msgid "Path"
+msgstr "Pfad"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_category__parent_path_json
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__parent_path_json
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__path_json
+msgid "Path Json"
+msgstr "Pfad Json"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_category__parent_path_names
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__parent_path_names
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__path_names
+msgid "Path Names"
+msgstr "Pfadnamen"
+
+#. module: muk_dms
+#: model:muk_dms.tag,name:muk_dms.tag_05_demo
+msgid "Portal"
+msgstr "Portal"
+
+#. module: muk_dms
+#: model:muk_dms.tag,name:muk_dms.tag_10_demo
+msgid "Product"
+msgstr "Produkt"
+
+#. module: muk_dms
+#: model:muk_dms.tag,name:muk_dms.tag_03_demo
+msgid "Project"
+msgstr "Projekt"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__permission_read
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__permission_read
+msgid "Read Access"
+msgstr "Leserecht"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_config_settings__module_muk_dms_trash
+msgid "Restore Files"
+msgstr "Dateien wiederherstellen"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_storage__root_directories
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_directory
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_storage_form
+msgid "Root Directories"
+msgstr "Wurzelverzeichnisse"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__root_storage
+msgid "Root Storage"
+msgstr "Wurzelspeicher"
+
+#. module: muk_dms
+#: model:muk_dms.tag,name:muk_dms.tag_04_demo
+msgid "Sales"
+msgstr "Umsatz"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_storage__save_type
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_storage_search
+msgid "Save Type"
+msgstr "Speichertyp"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__size
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__size
+#: model:ir.model.fields,field_description:muk_dms.field_res_config_settings__documents_binary_max_size
+msgid "Size"
+msgstr "Größe"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__custom_thumbnail_small
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__custom_thumbnail_small
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_mixins_thumbnail__custom_thumbnail_small
+msgid "Small Custom Thumbnail"
+msgstr "Kleines benutzerdefiniertes Miniaturbild"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__thumbnail_small
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__thumbnail_small
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_mixins_thumbnail__thumbnail_small
+msgid "Small Thumbnail"
+msgstr "Kleines Miniaturbild"
+
+#. module: muk_dms
+#. openerp-web
+#: code:addons/muk_dms/static/src/xml/views.xml:28
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__starred
+#, python-format
+msgid "Starred"
+msgstr "Sternenhimmel"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_directory
+msgid "Starred Directories"
+msgstr "Sternenverzeichnisse"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__user_stars
+msgid "Stars"
+msgstr "Sterne"
+
+#. module: muk_dms
+#: model:ir.model,name:muk_dms.model_muk_dms_storage
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__storage
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__storage
+#: model_terms:ir.ui.view,arch_db:muk_dms.onboarding_storage_step
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_directory
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_file
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_file_migration
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_storage_form
+msgid "Storage"
+msgstr "Lagerung"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__is_hidden
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__is_hidden
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_storage__is_hidden
+msgid "Storage is Hidden"
+msgstr "Lagerung ist versteckt"
+
+#. module: muk_dms
+#: model:ir.actions.act_window,name:muk_dms.action_dms_storage
+#: model:ir.ui.menu,name:muk_dms.menu_dms_storage
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_storage_tree
+msgid "Storages"
+msgstr "Lager"
+
+#. module: muk_dms
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_storage
+msgid "Storages are used to configure your Documents."
+msgstr "Speicher werden verwendet, um Ihre Dokumente zu konfigurieren."
+
+#. module: muk_dms
+#: model:ir.actions.act_window,name:muk_dms.action_dms_directories_all_directory
+#: model:ir.actions.act_window,name:muk_dms.action_dms_directories_directory
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__child_directories
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_form
+msgid "Subdirectories"
+msgstr "Unterverzeichnisse"
+
+#. module: muk_dms
+#: model:ir.ui.menu,name:muk_dms.cat_menu_muk_dms_config_system
+msgid "System"
+msgstr "System"
+
+#. module: muk_dms
+#: sql_constraint:muk_dms.tag:0
+msgid "Tag name already exists!"
+msgstr "Tag-Name existiert bereits!"
+
+#. module: muk_dms
+#. openerp-web
+#: code:addons/muk_dms/static/src/xml/views.xml:55
+#: model:ir.actions.act_window,name:muk_dms.action_dms_tag
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__tags
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__tags
+#: model:ir.ui.menu,name:muk_dms.menu_dms_tag
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_tag_tree
+#, python-format
+msgid "Tags"
+msgstr "Stichwörter"
+
+#. module: muk_dms
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_tag
+msgid "Tags are used to categorize Documents."
+msgstr "Tags werden verwendet, um Dokumente zu kategorisieren."
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_form
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_new_form
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_form
+msgid "Tags..."
+msgstr "Tags....."
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_form
+msgid "Technical Information"
+msgstr "Technische Informationen"
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_muk_dms_category__active
+msgid "The active field allows you to hide the category without removing it."
+msgstr "Das \"Aktiv\" Feld erlaubt das Verstecken der Kategorie ohne diese zu löschen."
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_muk_dms_tag__active
+msgid "The active field allows you to hide the tag without removing it."
+msgstr ""
+"Das aktive Feld ermöglicht es Ihnen, das Tag auszublenden, ohne es zu "
+"entfernen."
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.document_onboarding_directory_panel
+#: model_terms:ir.ui.view,arch_db:muk_dms.document_onboarding_file_panel
+msgid "The configuration is done!"
+msgstr "Die Konfiguration ist abgeschlossen!"
+
+#. module: muk_dms
+#: code:addons/muk_dms/models/file.py:420
+#, python-format
+msgid "The directory has to have the permission to create files."
+msgstr "Das Verzeichnis muss die Berechtigung haben, Dateien zu erstellen."
+
+#. module: muk_dms
+#: code:addons/muk_dms/models/directory.py:344
+#, python-format
+msgid "The directory name is invalid."
+msgstr "Der Verzeichnisname ist ungültig."
+
+#. module: muk_dms
+#: code:addons/muk_dms/models/file.py:408
+#, python-format
+msgid "The file has a forbidden file extension."
+msgstr "Die Datei hat eine verbotene Dateiendung."
+
+#. module: muk_dms
+#: code:addons/muk_dms/models/file.py:399
+#, python-format
+msgid "The file name is invalid."
+msgstr "Der Dateiname ist ungültig."
+
+#. module: muk_dms
+#: code:addons/muk_dms/models/file.py:414
+#, python-format
+msgid "The maximum upload size is %s MB)."
+msgstr "Die maximale Upload-Größe beträgt %s MB)."
+
+#. module: muk_dms
+#: code:addons/muk_dms/models/directory.py:338
+#, python-format
+msgid "The parent directory has to have the permission to create directories."
+msgstr ""
+"Das übergeordnete Verzeichnis muss die Berechtigung zum Erstellen von "
+"Verzeichnissen haben."
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_muk_dms_storage__save_type
+msgid "The save type is used to determine how a file is saved by the system. If you change \n"
+" this setting, you can migrate existing files manually by triggering the action."
+msgstr ""
+"Der Speichertyp wird verwendet, um festzulegen, wie eine Datei vom System "
+"gespeichert wird. Wenn du dich änderst _x000D_\n"
+" Mit dieser Einstellung können Sie bestehende Dateien manuell "
+"migrieren, indem Sie die Aktion auslösen."
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__thumbnail
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__thumbnail
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_mixins_thumbnail__thumbnail
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_kanban
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_kanban
+msgid "Thumbnail"
+msgstr "Vorschaubild"
+
+#. module: muk_dms
+#: model:ir.model,name:muk_dms.model_muk_dms_mixins_thumbnail
+msgid "Thumbnail Mixin"
+msgstr "Miniaturansicht Mixin"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__count_total_elements
+msgid "Total Elements"
+msgstr "Gesamte Elemente"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__count_total_files
+msgid "Total Files"
+msgstr "Gesamtzahl der Dateien"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__count_total_directories
+msgid "Total Subdirectories"
+msgstr "Gesamtzahl der Unterverzeichnisse"
+
+#. module: muk_dms
+#: model:muk_dms.category,name:muk_dms.category_04_demo
+msgid "Traveling"
+msgstr "Reisen"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__mimetype
+msgid "Type"
+msgstr "Typ"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_form
+msgid "Unlock"
+msgstr "Freischalten"
+
+#. module: muk_dms
+#. openerp-web
+#: code:addons/muk_dms/static/src/js/views/file/kanban/file_kanban_controller.js:92
+#, python-format
+msgid "Upload Error"
+msgstr "Upload-Fehler"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.onboarding_file_step
+msgid "Upload File"
+msgstr "Datei hochladen"
+
+#. module: muk_dms
+#. openerp-web
+#: code:addons/muk_dms/static/src/js/views/mixins/file_upload.js:63
+#, python-format
+msgid "Upload Files"
+msgstr "Dateien hochladen"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.onboarding_file_step
+msgid "Upload your first File."
+msgstr "Lade deine erste Datei hoch."
+
+#. module: muk_dms
+#. openerp-web
+#: code:addons/muk_dms/static/src/js/views/mixins/file_upload.js:64
+#, python-format
+msgid "Uploading..."
+msgstr "Hochladen....."
+
+#. module: muk_dms
+#: model:res.groups,name:muk_dms.group_dms_user
+msgid "User"
+msgstr "Benutzer"
+
+#. module: muk_dms
+#: model:muk_dms.tag,name:muk_dms.tag_09_demo
+msgid "Vendor Bill"
+msgstr "Lieferantenrechnung"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_config_settings__module_muk_dms_version
+msgid "Versioning"
+msgstr "Versionierung"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "Views"
+msgstr "Ansichten"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__permission_write
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__permission_write
+msgid "Write Access"
+msgstr "Schreibrechte"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.document_onboarding_directory_panel
+#: model_terms:ir.ui.view,arch_db:muk_dms.document_onboarding_file_panel
+msgid "action_close_documents_onboarding"
+msgstr "action_close_dokumente_onboarding"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "exe,msi"
+msgstr "exe,msi"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.document_onboarding_file_panel
+msgid "o_onboarding_blue"
+msgstr "o_onboarding_blau_blau"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.document_onboarding_directory_panel
+msgid "o_onboarding_orange"
+msgstr "o_onboarding_orange"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.document_onboarding_directory_panel
+#: model_terms:ir.ui.view,arch_db:muk_dms.document_onboarding_file_panel
+msgid "res.company"
+msgstr "res.company"
diff --git a/odex-event/muk_dms/i18n/es.po b/odex-event/muk_dms/i18n/es.po
new file mode 100644
index 000000000..840a0bee5
--- /dev/null
+++ b/odex-event/muk_dms/i18n/es.po
@@ -0,0 +1,1465 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * muk_dms
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 12.0-20190128\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2019-03-05 18:29+0000\n"
+"PO-Revision-Date: 2019-06-25 08:16+0000\n"
+"Last-Translator: MuK IT \n"
+"Language-Team: Spanish "
+"\n"
+"Language: es\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+"X-Generator: Weblate 3.7\n"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.document_onboarding_directory_panel
+msgid "/muk_dms/static/src/img/banner/documents_onboarding_directory.png"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.document_onboarding_file_panel
+msgid "/muk_dms/static/src/img/banner/documents_onboarding_file.png"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_kanban
+msgid " Download"
+msgstr " Descargar"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_kanban
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_kanban
+msgid " Open"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_kanban
+msgid " Lock"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_kanban
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_kanban
+msgid " Edit"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_kanban
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_kanban
+msgid " Delete"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_kanban
+msgid " Unlock"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "File Extensions"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "File Size"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "Save this page and come back here to set up the feature."
+msgstr "Guarde esa página y regrese aquí para configurar la función."
+
+#. module: muk_dms
+#: code:addons/muk_dms/models/directory.py:332
+#, python-format
+msgid "A directory can't be a root and have a parent directory."
+msgstr ""
+
+#. module: muk_dms
+#: code:addons/muk_dms/models/directory.py:330
+#, python-format
+msgid "A directory has to have a parent directory."
+msgstr ""
+
+#. module: muk_dms
+#: code:addons/muk_dms/models/directory.py:350
+#, python-format
+msgid "A directory with the same name already exists."
+msgstr ""
+
+#. module: muk_dms
+#: code:addons/muk_dms/models/directory.py:414
+#, python-format
+msgid "A file is locked, the folder cannot be deleted."
+msgstr ""
+
+#. module: muk_dms
+#: code:addons/muk_dms/models/file.py:402
+#, python-format
+msgid "A file with the same name already exists."
+msgstr ""
+
+#. module: muk_dms
+#: code:addons/muk_dms/models/directory.py:328
+#, python-format
+msgid "A root directory has to have a root storage."
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_config_settings__module_muk_dms_access
+msgid "Access Control"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_form
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_form
+msgid "Access Information"
+msgstr ""
+
+#. module: muk_dms
+#: model:muk_dms.tag,name:muk_dms.tag_07_demo
+msgid "Accounting"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "Activates a file trash to restore deleted files"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_res_config_settings__module_muk_dms_trash
+msgid "Activates a file trash to restore deleted files."
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "Activates the preview function on files"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_res_config_settings__module_muk_dms_preview
+msgid "Activates the preview function on files."
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_category__active
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_tag__active
+msgid "Active"
+msgstr "Activo"
+
+#. module: muk_dms
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_directory
+msgid "Add a new Directory."
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_file
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_file_migration
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_file_storage_migration
+msgid "Add a new File."
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "Adds support for messages and activities on directories and files"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_res_config_settings__module_muk_dms_mail
+msgid "Adds support for messages and activities on directories and files."
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_category_search
+msgid "All"
+msgstr "Todos"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_file
+msgid "All Files"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_res_config_settings__module_muk_dms_attachment_rules
+msgid "Allows attachments to be automatically placed in the right directory."
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "Allows attachments to be stored inside of Documents"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_res_config_settings__module_muk_dms_attachment
+msgid "Allows attachments to be stored inside of Documents."
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_res_config_settings__module_muk_dms_attachment_wizard
+msgid "Allows documents to be used as attachments."
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_res_config_settings__module_muk_dms_export
+msgid "Allows the conversion of existing files."
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "Allows the creation of groups to define access rights"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_res_config_settings__module_muk_dms_access
+msgid "Allows the creation of groups to define access rights."
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_res_config_settings__module_muk_dms_thumbnails
+msgid "Allows the creation of thumbnails for files."
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_res_config_settings__module_muk_dms_widget
+msgid "Allows the user to use DMS documents as input for any binary field."
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_res_config_settings__module_muk_archive
+msgid "Allows to download directories as a archive file."
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "Allows to placed attachments in the right directory"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "Allows you to create rule templates to create attachment rules"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_res_config_settings__module_muk_dms_attachment_automation
+msgid "Allows you to create rule templates to create attachment rules."
+msgstr ""
+
+#. module: muk_dms
+#: model:muk_dms.tag,name:muk_dms.tag_06_demo
+msgid "Apps"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__active
+msgid "Archived"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_config_settings__module_muk_dms_attachment_automation
+msgid "Attachment Rule Automation"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_config_settings__module_muk_dms_attachment_wizard
+msgid "Attachment Wizard"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "Attachments"
+msgstr "Adjuntos"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_config_settings__module_muk_dms_thumbnails
+msgid "Automatic Thumbnails"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_config_settings__module_muk_dms_widget
+msgid "Binary Widget Support"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_new_form
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_new_form
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_storage_new_form
+msgid "Cancel"
+msgstr "Cancelar"
+
+#. module: muk_dms
+#. openerp-web
+#: code:addons/muk_dms/static/src/xml/views.xml:46
+#: model:ir.actions.act_window,name:muk_dms.action_dms_category
+#: model:ir.ui.menu,name:muk_dms.menu_dms_category
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_category_search
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_category_tree
+#, python-format
+msgid "Categories"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_category
+msgid "Categories are used to categorize Documents."
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__category
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__category
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_directory
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_file
+msgid "Category"
+msgstr "Categoría"
+
+#. module: muk_dms
+#: sql_constraint:muk_dms.category:0
+msgid "Category name already exists!"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__checksum
+msgid "Checksum/SHA1"
+msgstr "Suma de verificación/SHA1"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_category__child_categories
+msgid "Child Categories"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_directories_all_directory
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_directories_directory
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_directories_storage
+msgid "Click to add a new directory."
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_files_all_directory
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_files_directory
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_files_storage
+msgid "Click to add a new file."
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_tag
+msgid "Click to create a new tag."
+msgstr ""
+
+#. module: muk_dms
+#: selection:res.company,documents_onboarding_directory_state:0
+#: selection:res.company,documents_onboarding_file_state:0
+#: selection:res.company,documents_onboarding_state:0
+#: selection:res.company,documents_onboarding_storage_state:0
+msgid "Closed"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__color
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__color
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_directory
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_file
+msgid "Color"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_tag__color
+msgid "Color Index"
+msgstr "Índice de Colores"
+
+#. module: muk_dms
+#: model:ir.model,name:muk_dms.model_res_company
+msgid "Companies"
+msgstr "Compañías"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__company
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__company
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_storage__company
+msgid "Company"
+msgstr "Compañía"
+
+#. module: muk_dms
+#: model:ir.model,name:muk_dms.model_res_config_settings
+msgid "Config Settings"
+msgstr "Opciones de Configuración"
+
+#. module: muk_dms
+#: model:ir.ui.menu,name:muk_dms.cat_menu_muk_dms_config
+msgid "Configuration"
+msgstr "Configuración"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__content
+msgid "Content"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__content_binary
+msgid "Content Binary"
+msgstr ""
+
+#. module: muk_dms
+#: model:muk_dms.tag,name:muk_dms.tag_11_demo
+msgid "Contract"
+msgstr ""
+
+#. module: muk_dms
+#: model:muk_dms.category,name:muk_dms.category_03_demo
+msgid "Contracts"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_storage__count_storage_directories
+msgid "Count Directories"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__count_elements
+msgid "Count Elements"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__count_files
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_storage__count_storage_files
+msgid "Count Files"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__count_directories
+msgid "Count Subdirectories"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_new_form
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_new_form
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_storage_new_form
+msgid "Create"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__permission_create
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__permission_create
+msgid "Create Access"
+msgstr "Acceso para crear"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.onboarding_directory_step
+msgid "Create Directory"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.onboarding_storage_step
+msgid "Create Storage"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_category
+msgid "Create a new Category."
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.onboarding_storage_step
+msgid "Create a new Document Storage."
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.onboarding_directory_step
+msgid "Create a new Root Directory."
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_storage
+msgid "Create a new Storage object."
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_category__create_uid
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__create_uid
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__create_uid
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_storage__create_uid
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_tag__create_uid
+msgid "Created by"
+msgstr "Creado por"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_category__create_date
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__create_date
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__create_date
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_storage__create_date
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_tag__create_date
+msgid "Created on"
+msgstr "Creado el"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_directory
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_file
+msgid "Creation Date"
+msgstr "Fecha de Creación"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__save_type
+msgid "Current Save Type"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__custom_thumbnail
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__custom_thumbnail
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_mixins_thumbnail__custom_thumbnail
+msgid "Custom Thumbnail"
+msgstr ""
+
+#. module: muk_dms
+#: model:muk_dms.tag,name:muk_dms.tag_01_demo
+msgid "Customer"
+msgstr ""
+
+#. module: muk_dms
+#: model:muk_dms.tag,name:muk_dms.tag_08_demo
+msgid "Customer Invoice"
+msgstr ""
+
+#. module: muk_dms
+#: code:addons/muk_dms/models/storage.py:42
+#: selection:muk_dms.storage,save_type:0
+#, python-format
+msgid "Database"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "Define forbidden file extensions"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "Define the maximum upload size of a file in MB"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_res_config_settings__documents_forbidden_extensions
+msgid "Defines a list of forbidden file extensions. (Example: 'exe,msi')"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_res_config_settings__documents_binary_max_size
+msgid "Defines the maximum upload size in MB. Default (25MB)"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__permission_unlink
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__permission_unlink
+msgid "Delete Access"
+msgstr "Permiso para eliminar"
+
+#. module: muk_dms
+#. openerp-web
+#: code:addons/muk_dms/static/src/xml/views.xml:37
+#: model:ir.actions.act_window,name:muk_dms.action_dms_directories_storage
+#: model:ir.actions.act_window,name:muk_dms.action_dms_directory
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_category__directories
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_storage__storage_directories
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_tag__directories
+#: model:ir.ui.menu,name:muk_dms.menu_dms_directory
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_file
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_form
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_tree
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_storage_form
+#, python-format
+msgid "Directories"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_directories_all_directory
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_directories_directory
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_directories_storage
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_directory
+msgid "Directories can be used to structure and organize\n"
+" files directly in Odoo."
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model,name:muk_dms.model_muk_dms_directory
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__directory
+#: model_terms:ir.ui.view,arch_db:muk_dms.onboarding_directory_step
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_form
+msgid "Directory"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_category__display_name
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__display_name
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__display_name
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_mixins_thumbnail__display_name
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_storage__display_name
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_tag__display_name
+msgid "Display Name"
+msgstr "Nombre mostrado"
+
+#. module: muk_dms
+#: model:ir.model,name:muk_dms.model_muk_dms_category
+msgid "Document Category"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model,name:muk_dms.model_muk_dms_tag
+msgid "Document Tag"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.module.category,name:muk_dms.category_dms_security
+#: model:ir.ui.menu,name:muk_dms.main_menu_muk_dms
+msgid "Documents"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_company__documents_onboarding_directory_state
+msgid "Documents Onboarding Directory State"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_company__documents_onboarding_file_state
+msgid "Documents Onboarding File State"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_company__documents_onboarding_state
+msgid "Documents Onboarding State"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_company__documents_onboarding_storage_state
+msgid "Documents Onboarding Storage State"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_config_settings__module_muk_dms_attachment
+msgid "Documents Storage Location"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_config_settings__module_muk_dms_attachment_rules
+msgid "Documents Storage Rules"
+msgstr ""
+
+#. module: muk_dms
+#: selection:res.company,documents_onboarding_directory_state:0
+#: selection:res.company,documents_onboarding_file_state:0
+#: selection:res.company,documents_onboarding_state:0
+#: selection:res.company,documents_onboarding_storage_state:0
+msgid "Done"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_config_settings__module_muk_archive
+msgid "Download Directories"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_kanban
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_kanban
+msgid "Dropdown menu"
+msgstr "Menú desplegable"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__is_lock_editor
+msgid "Editor"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_form
+msgid "Elements"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "Enables a new save option to store files into a filestore"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_res_config_settings__module_muk_dms_file
+msgid "Enables a new save option to store files into a filestore."
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "Enables a new save option to store files into large objects"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_res_config_settings__module_muk_dms_lobject
+msgid "Enables a new save option to store files into large objects."
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_res_config_settings__module_muk_dms_finder
+msgid "Enables the Document Finder."
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "Enables version control for files"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_res_config_settings__module_muk_dms_version
+msgid "Enables version control for files."
+msgstr ""
+
+#. module: muk_dms
+#: code:addons/muk_dms/models/category.py:123
+#, python-format
+msgid "Error! You cannot create recursive categories."
+msgstr ""
+
+#. module: muk_dms
+#: code:addons/muk_dms/models/directory.py:321
+#, python-format
+msgid "Error! You cannot create recursive directories."
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_config_settings__module_muk_dms_export
+msgid "Export Files"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__extension
+msgid "Extension"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_config_settings__documents_forbidden_extensions
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "Extensions"
+msgstr ""
+
+#. module: muk_dms
+#: model:muk_dms.category,name:muk_dms.category_05_demo
+msgid "External"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model,name:muk_dms.model_muk_dms_file
+#: model_terms:ir.ui.view,arch_db:muk_dms.onboarding_file_step
+msgid "File"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_config_settings__module_muk_dms_preview
+msgid "File Preview"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "File Upload"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__name
+msgid "Filename"
+msgstr "Nombre de archivo"
+
+#. module: muk_dms
+#: model:ir.actions.act_window,name:muk_dms.action_dms_file
+#: model:ir.actions.act_window,name:muk_dms.action_dms_file_migration
+#: model:ir.actions.act_window,name:muk_dms.action_dms_file_storage_migration
+#: model:ir.actions.act_window,name:muk_dms.action_dms_files_all_directory
+#: model:ir.actions.act_window,name:muk_dms.action_dms_files_directory
+#: model:ir.actions.act_window,name:muk_dms.action_dms_files_storage
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_category__files
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__files
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_storage__storage_files
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_tag__files
+#: model:ir.ui.menu,name:muk_dms.menu_dms_file
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_form
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_tree
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_form
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_migration_tree
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_tree
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_storage_form
+msgid "Files"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_file
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_file_migration
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_file_storage_migration
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_files_all_directory
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_files_directory
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_files_storage
+msgid "Files are used to save content directly in Odoo."
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_config_settings__module_muk_dms_file
+msgid "Filestore Storage"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_config_settings__module_muk_dms_finder
+msgid "Finder"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.actions.act_window,name:muk_dms.action_dms_settings_general
+#: model:ir.ui.menu,name:muk_dms.menu_dms_settings_general
+msgid "General Settings"
+msgstr "Opciones Generales"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_directory
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_file
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_file_migration
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_storage_search
+msgid "Group By"
+msgstr "Agrupar por"
+
+#. module: muk_dms
+#: model:ir.model,name:muk_dms.model_ir_http
+msgid "HTTP Routing"
+msgstr ""
+
+#. module: muk_dms
+#: model:muk_dms.category,name:muk_dms.category_02_demo
+msgid "Human Resource"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_category__id
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__id
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__id
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_mixins_thumbnail__id
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_storage__id
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_tag__id
+msgid "ID"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_muk_dms_file__active
+msgid "If a file is set to archived, it is not displayed, but still exists."
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_muk_dms_directory__company
+#: model:ir.model.fields,help:muk_dms.field_muk_dms_file__company
+#: model:ir.model.fields,help:muk_dms.field_muk_dms_storage__company
+msgid "If set, directories and files will only be available for the selected company."
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_muk_dms_directory__is_hidden
+#: model:ir.model.fields,help:muk_dms.field_muk_dms_file__is_hidden
+#: model:ir.model.fields,help:muk_dms.field_muk_dms_storage__is_hidden
+msgid "Indicates if directories and files are hidden by default."
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_muk_dms_directory__is_root_directory
+msgid "Indicates if the directory is a root directory. A root directory has a settings object,\n"
+" while a directory with a set parent inherits the settings form its parent."
+msgstr ""
+
+#. module: muk_dms
+#: model:muk_dms.category,name:muk_dms.category_01_demo
+msgid "Internal"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_form
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_new_form
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_form
+msgid "Internal / Human Resource"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__is_root_directory
+msgid "Is Root Directory"
+msgstr ""
+
+#. module: muk_dms
+#: selection:res.company,documents_onboarding_directory_state:0
+#: selection:res.company,documents_onboarding_file_state:0
+#: selection:res.company,documents_onboarding_state:0
+#: selection:res.company,documents_onboarding_storage_state:0
+msgid "Just done"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_config_settings__module_muk_dms_lobject
+msgid "Large Objects Storage"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_category____last_update
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory____last_update
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file____last_update
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_mixins_thumbnail____last_update
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_storage____last_update
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_tag____last_update
+msgid "Last Modified on"
+msgstr "Última modificación en"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_category__write_uid
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__write_uid
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__write_uid
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_storage__write_uid
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_tag__write_uid
+msgid "Last Updated by"
+msgstr "Última actualización por"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_category__write_date
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__write_date
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__write_date
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_storage__write_date
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_tag__write_date
+msgid "Last Updated on"
+msgstr "Última actualización el"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_form
+msgid "Lock"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__is_locked
+msgid "Locked"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__locked_by
+msgid "Locked by"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_config_settings__module_muk_dms_mail
+msgid "Mail Support"
+msgstr ""
+
+#. module: muk_dms
+#: model:res.groups,name:muk_dms.group_dms_manager
+msgid "Manager"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_storage_form
+msgid "Manual File Migration"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__custom_thumbnail_medium
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__custom_thumbnail_medium
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_mixins_thumbnail__custom_thumbnail_medium
+msgid "Medium Custom Thumbnail"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__thumbnail_medium
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__thumbnail_medium
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_mixins_thumbnail__thumbnail_medium
+msgid "Medium Thumbnail"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_form
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_form
+msgid "Meta Information"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.actions.server,name:muk_dms.action_dms_attachment_migrate
+msgid "Migrate"
+msgstr ""
+
+#. module: muk_dms
+#: code:addons/muk_dms/models/file.py:221
+#, python-format
+msgid "Migrate File %s of %s [ %s ]"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_storage_form
+msgid "Migrate Files"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.ui.menu,name:muk_dms.menu_dms_file_migration
+msgid "Migration"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__migration
+msgid "Migration Status"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_directory
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_file
+msgid "Modification Date"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_directory
+msgid "My Directories"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_form
+msgid "My Documents"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_file
+msgid "My Files"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_category__name
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__name
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_storage__name
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_tag__name
+msgid "Name"
+msgstr "Nombre"
+
+#. module: muk_dms
+#: model:ir.actions.act_window,name:muk_dms.action_dms_directory_new
+#: model:ir.actions.act_window,name:muk_dms.action_dms_file_new
+msgid "New Root Directory"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.actions.act_window,name:muk_dms.action_dms_storage_new
+msgid "New Storage"
+msgstr ""
+
+#. module: muk_dms
+#: model:muk_dms.category,name:muk_dms.category_06_demo
+msgid "News"
+msgstr ""
+
+#. module: muk_dms
+#. openerp-web
+#: code:addons/muk_dms/static/src/js/views/file/kanban/file_kanban_controller.js:92
+#, python-format
+msgid "No Directory has been selected!"
+msgstr ""
+
+#. module: muk_dms
+#: selection:res.company,documents_onboarding_directory_state:0
+#: selection:res.company,documents_onboarding_file_state:0
+#: selection:res.company,documents_onboarding_state:0
+#: selection:res.company,documents_onboarding_storage_state:0
+msgid "Not done"
+msgstr ""
+
+#. module: muk_dms
+#: code:addons/muk_dms/models/storage.py:99
+#, python-format
+msgid "Only managers can execute this action."
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.ui.menu,name:muk_dms.cat_menu_muk_dms_config_organizing
+msgid "Organizing"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_category__parent_category
+msgid "Parent Category"
+msgstr "Categoría padre"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__parent_directory
+msgid "Parent Directory"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_category__parent_path
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__parent_path
+msgid "Parent Path"
+msgstr ""
+
+#. module: muk_dms
+#: model:muk_dms.tag,name:muk_dms.tag_02_demo
+msgid "Partner"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_tree
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_tree
+msgid "Path"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_category__parent_path_json
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__parent_path_json
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__path_json
+msgid "Path Json"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_category__parent_path_names
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__parent_path_names
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__path_names
+msgid "Path Names"
+msgstr ""
+
+#. module: muk_dms
+#: model:muk_dms.tag,name:muk_dms.tag_05_demo
+msgid "Portal"
+msgstr ""
+
+#. module: muk_dms
+#: model:muk_dms.tag,name:muk_dms.tag_10_demo
+msgid "Product"
+msgstr ""
+
+#. module: muk_dms
+#: model:muk_dms.tag,name:muk_dms.tag_03_demo
+msgid "Project"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__permission_read
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__permission_read
+msgid "Read Access"
+msgstr "Permiso para leer"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_config_settings__module_muk_dms_trash
+msgid "Restore Files"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_storage__root_directories
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_directory
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_storage_form
+msgid "Root Directories"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__root_storage
+msgid "Root Storage"
+msgstr ""
+
+#. module: muk_dms
+#: model:muk_dms.tag,name:muk_dms.tag_04_demo
+msgid "Sales"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_storage__save_type
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_storage_search
+msgid "Save Type"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__size
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__size
+#: model:ir.model.fields,field_description:muk_dms.field_res_config_settings__documents_binary_max_size
+msgid "Size"
+msgstr "Tamaño"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__custom_thumbnail_small
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__custom_thumbnail_small
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_mixins_thumbnail__custom_thumbnail_small
+msgid "Small Custom Thumbnail"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__thumbnail_small
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__thumbnail_small
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_mixins_thumbnail__thumbnail_small
+msgid "Small Thumbnail"
+msgstr ""
+
+#. module: muk_dms
+#. openerp-web
+#: code:addons/muk_dms/static/src/xml/views.xml:28
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__starred
+#, python-format
+msgid "Starred"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_directory
+msgid "Starred Directories"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__user_stars
+msgid "Stars"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model,name:muk_dms.model_muk_dms_storage
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__storage
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__storage
+#: model_terms:ir.ui.view,arch_db:muk_dms.onboarding_storage_step
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_directory
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_file
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_file_migration
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_storage_form
+msgid "Storage"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__is_hidden
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__is_hidden
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_storage__is_hidden
+msgid "Storage is Hidden"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.actions.act_window,name:muk_dms.action_dms_storage
+#: model:ir.ui.menu,name:muk_dms.menu_dms_storage
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_storage_tree
+msgid "Storages"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_storage
+msgid "Storages are used to configure your Documents."
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.actions.act_window,name:muk_dms.action_dms_directories_all_directory
+#: model:ir.actions.act_window,name:muk_dms.action_dms_directories_directory
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__child_directories
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_form
+msgid "Subdirectories"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.ui.menu,name:muk_dms.cat_menu_muk_dms_config_system
+msgid "System"
+msgstr ""
+
+#. module: muk_dms
+#: sql_constraint:muk_dms.tag:0
+msgid "Tag name already exists!"
+msgstr ""
+
+#. module: muk_dms
+#. openerp-web
+#: code:addons/muk_dms/static/src/xml/views.xml:55
+#: model:ir.actions.act_window,name:muk_dms.action_dms_tag
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__tags
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__tags
+#: model:ir.ui.menu,name:muk_dms.menu_dms_tag
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_tag_tree
+#, python-format
+msgid "Tags"
+msgstr "Etiquetas"
+
+#. module: muk_dms
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_tag
+msgid "Tags are used to categorize Documents."
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_form
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_new_form
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_form
+msgid "Tags..."
+msgstr "Etiquetas..."
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_form
+msgid "Technical Information"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_muk_dms_category__active
+msgid "The active field allows you to hide the category without removing it."
+msgstr "El campo activo le permite ocultar la categoría sin tener que eliminarla."
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_muk_dms_tag__active
+msgid "The active field allows you to hide the tag without removing it."
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.document_onboarding_directory_panel
+#: model_terms:ir.ui.view,arch_db:muk_dms.document_onboarding_file_panel
+msgid "The configuration is done!"
+msgstr ""
+
+#. module: muk_dms
+#: code:addons/muk_dms/models/file.py:420
+#, python-format
+msgid "The directory has to have the permission to create files."
+msgstr ""
+
+#. module: muk_dms
+#: code:addons/muk_dms/models/directory.py:344
+#, python-format
+msgid "The directory name is invalid."
+msgstr ""
+
+#. module: muk_dms
+#: code:addons/muk_dms/models/file.py:408
+#, python-format
+msgid "The file has a forbidden file extension."
+msgstr ""
+
+#. module: muk_dms
+#: code:addons/muk_dms/models/file.py:399
+#, python-format
+msgid "The file name is invalid."
+msgstr ""
+
+#. module: muk_dms
+#: code:addons/muk_dms/models/file.py:414
+#, python-format
+msgid "The maximum upload size is %s MB)."
+msgstr ""
+
+#. module: muk_dms
+#: code:addons/muk_dms/models/directory.py:338
+#, python-format
+msgid "The parent directory has to have the permission to create directories."
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_muk_dms_storage__save_type
+msgid "The save type is used to determine how a file is saved by the system. If you change \n"
+" this setting, you can migrate existing files manually by triggering the action."
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__thumbnail
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__thumbnail
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_mixins_thumbnail__thumbnail
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_kanban
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_kanban
+msgid "Thumbnail"
+msgstr "Miniatura"
+
+#. module: muk_dms
+#: model:ir.model,name:muk_dms.model_muk_dms_mixins_thumbnail
+msgid "Thumbnail Mixin"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__count_total_elements
+msgid "Total Elements"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__count_total_files
+msgid "Total Files"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__count_total_directories
+msgid "Total Subdirectories"
+msgstr ""
+
+#. module: muk_dms
+#: model:muk_dms.category,name:muk_dms.category_04_demo
+msgid "Traveling"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__mimetype
+msgid "Type"
+msgstr "Tipo"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_form
+msgid "Unlock"
+msgstr ""
+
+#. module: muk_dms
+#. openerp-web
+#: code:addons/muk_dms/static/src/js/views/file/kanban/file_kanban_controller.js:92
+#, python-format
+msgid "Upload Error"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.onboarding_file_step
+msgid "Upload File"
+msgstr ""
+
+#. module: muk_dms
+#. openerp-web
+#: code:addons/muk_dms/static/src/js/views/mixins/file_upload.js:63
+#, python-format
+msgid "Upload Files"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.onboarding_file_step
+msgid "Upload your first File."
+msgstr ""
+
+#. module: muk_dms
+#. openerp-web
+#: code:addons/muk_dms/static/src/js/views/mixins/file_upload.js:64
+#, python-format
+msgid "Uploading..."
+msgstr ""
+
+#. module: muk_dms
+#: model:res.groups,name:muk_dms.group_dms_user
+msgid "User"
+msgstr ""
+
+#. module: muk_dms
+#: model:muk_dms.tag,name:muk_dms.tag_09_demo
+msgid "Vendor Bill"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_config_settings__module_muk_dms_version
+msgid "Versioning"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "Views"
+msgstr "Vistas"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__permission_write
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__permission_write
+msgid "Write Access"
+msgstr "Permiso de escritura"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.document_onboarding_directory_panel
+#: model_terms:ir.ui.view,arch_db:muk_dms.document_onboarding_file_panel
+msgid "action_close_documents_onboarding"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "exe,msi"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.document_onboarding_file_panel
+msgid "o_onboarding_blue"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.document_onboarding_directory_panel
+msgid "o_onboarding_orange"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.document_onboarding_directory_panel
+#: model_terms:ir.ui.view,arch_db:muk_dms.document_onboarding_file_panel
+msgid "res.company"
+msgstr ""
diff --git a/odex-event/muk_dms/i18n/fr.po b/odex-event/muk_dms/i18n/fr.po
new file mode 100644
index 000000000..afa996ad2
--- /dev/null
+++ b/odex-event/muk_dms/i18n/fr.po
@@ -0,0 +1,1463 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * muk_dms
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 12.0-20190128\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2019-03-05 18:29+0000\n"
+"PO-Revision-Date: 2019-03-05 18:29+0000\n"
+"Last-Translator: <>\n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: \n"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.document_onboarding_directory_panel
+msgid "/muk_dms/static/src/img/banner/documents_onboarding_directory.png"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.document_onboarding_file_panel
+msgid "/muk_dms/static/src/img/banner/documents_onboarding_file.png"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_kanban
+msgid " Download"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_kanban
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_kanban
+msgid " Open"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_kanban
+msgid " Lock"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_kanban
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_kanban
+msgid " Edit"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_kanban
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_kanban
+msgid " Delete"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_kanban
+msgid " Unlock"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "File Extensions"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "File Size"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "Save this page and come back here to set up the feature."
+msgstr "Sauvegardez cette page et revenez ici pour configurer la fonctionnalité."
+
+#. module: muk_dms
+#: code:addons/muk_dms/models/directory.py:332
+#, python-format
+msgid "A directory can't be a root and have a parent directory."
+msgstr ""
+
+#. module: muk_dms
+#: code:addons/muk_dms/models/directory.py:330
+#, python-format
+msgid "A directory has to have a parent directory."
+msgstr ""
+
+#. module: muk_dms
+#: code:addons/muk_dms/models/directory.py:350
+#, python-format
+msgid "A directory with the same name already exists."
+msgstr ""
+
+#. module: muk_dms
+#: code:addons/muk_dms/models/directory.py:414
+#, python-format
+msgid "A file is locked, the folder cannot be deleted."
+msgstr ""
+
+#. module: muk_dms
+#: code:addons/muk_dms/models/file.py:402
+#, python-format
+msgid "A file with the same name already exists."
+msgstr ""
+
+#. module: muk_dms
+#: code:addons/muk_dms/models/directory.py:328
+#, python-format
+msgid "A root directory has to have a root storage."
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_config_settings__module_muk_dms_access
+msgid "Access Control"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_form
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_form
+msgid "Access Information"
+msgstr ""
+
+#. module: muk_dms
+#: model:muk_dms.tag,name:muk_dms.tag_07_demo
+msgid "Accounting"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "Activates a file trash to restore deleted files"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_res_config_settings__module_muk_dms_trash
+msgid "Activates a file trash to restore deleted files."
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "Activates the preview function on files"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_res_config_settings__module_muk_dms_preview
+msgid "Activates the preview function on files."
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_category__active
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_tag__active
+msgid "Active"
+msgstr "Actif"
+
+#. module: muk_dms
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_directory
+msgid "Add a new Directory."
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_file
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_file_migration
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_file_storage_migration
+msgid "Add a new File."
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "Adds support for messages and activities on directories and files"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_res_config_settings__module_muk_dms_mail
+msgid "Adds support for messages and activities on directories and files."
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_category_search
+msgid "All"
+msgstr "Tous"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_file
+msgid "All Files"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_res_config_settings__module_muk_dms_attachment_rules
+msgid "Allows attachments to be automatically placed in the right directory."
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "Allows attachments to be stored inside of Documents"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_res_config_settings__module_muk_dms_attachment
+msgid "Allows attachments to be stored inside of Documents."
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_res_config_settings__module_muk_dms_attachment_wizard
+msgid "Allows documents to be used as attachments."
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_res_config_settings__module_muk_dms_export
+msgid "Allows the conversion of existing files."
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "Allows the creation of groups to define access rights"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_res_config_settings__module_muk_dms_access
+msgid "Allows the creation of groups to define access rights."
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_res_config_settings__module_muk_dms_thumbnails
+msgid "Allows the creation of thumbnails for files."
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_res_config_settings__module_muk_dms_widget
+msgid "Allows the user to use DMS documents as input for any binary field."
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_res_config_settings__module_muk_archive
+msgid "Allows to download directories as a archive file."
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "Allows to placed attachments in the right directory"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "Allows you to create rule templates to create attachment rules"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_res_config_settings__module_muk_dms_attachment_automation
+msgid "Allows you to create rule templates to create attachment rules."
+msgstr ""
+
+#. module: muk_dms
+#: model:muk_dms.tag,name:muk_dms.tag_06_demo
+msgid "Apps"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__active
+msgid "Archived"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_config_settings__module_muk_dms_attachment_automation
+msgid "Attachment Rule Automation"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_config_settings__module_muk_dms_attachment_wizard
+msgid "Attachment Wizard"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "Attachments"
+msgstr "Pièces jointes"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_config_settings__module_muk_dms_thumbnails
+msgid "Automatic Thumbnails"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_config_settings__module_muk_dms_widget
+msgid "Binary Widget Support"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_new_form
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_new_form
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_storage_new_form
+msgid "Cancel"
+msgstr "Annuler"
+
+#. module: muk_dms
+#. openerp-web
+#: code:addons/muk_dms/static/src/xml/views.xml:46
+#: model:ir.actions.act_window,name:muk_dms.action_dms_category
+#: model:ir.ui.menu,name:muk_dms.menu_dms_category
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_category_search
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_category_tree
+#, python-format
+msgid "Categories"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_category
+msgid "Categories are used to categorize Documents."
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__category
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__category
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_directory
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_file
+msgid "Category"
+msgstr "Catégorie"
+
+#. module: muk_dms
+#: sql_constraint:muk_dms.category:0
+msgid "Category name already exists!"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__checksum
+msgid "Checksum/SHA1"
+msgstr "Somme de Contrôle/SHA1"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_category__child_categories
+msgid "Child Categories"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_directories_all_directory
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_directories_directory
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_directories_storage
+msgid "Click to add a new directory."
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_files_all_directory
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_files_directory
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_files_storage
+msgid "Click to add a new file."
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_tag
+msgid "Click to create a new tag."
+msgstr ""
+
+#. module: muk_dms
+#: selection:res.company,documents_onboarding_directory_state:0
+#: selection:res.company,documents_onboarding_file_state:0
+#: selection:res.company,documents_onboarding_state:0
+#: selection:res.company,documents_onboarding_storage_state:0
+msgid "Closed"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__color
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__color
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_directory
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_file
+msgid "Color"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_tag__color
+msgid "Color Index"
+msgstr "Couleur"
+
+#. module: muk_dms
+#: model:ir.model,name:muk_dms.model_res_company
+msgid "Companies"
+msgstr "Sociétés"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__company
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__company
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_storage__company
+msgid "Company"
+msgstr "Société"
+
+#. module: muk_dms
+#: model:ir.model,name:muk_dms.model_res_config_settings
+msgid "Config Settings"
+msgstr "Paramètres de config"
+
+#. module: muk_dms
+#: model:ir.ui.menu,name:muk_dms.cat_menu_muk_dms_config
+msgid "Configuration"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__content
+msgid "Content"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__content_binary
+msgid "Content Binary"
+msgstr ""
+
+#. module: muk_dms
+#: model:muk_dms.tag,name:muk_dms.tag_11_demo
+msgid "Contract"
+msgstr ""
+
+#. module: muk_dms
+#: model:muk_dms.category,name:muk_dms.category_03_demo
+msgid "Contracts"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_storage__count_storage_directories
+msgid "Count Directories"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__count_elements
+msgid "Count Elements"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__count_files
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_storage__count_storage_files
+msgid "Count Files"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__count_directories
+msgid "Count Subdirectories"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_new_form
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_new_form
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_storage_new_form
+msgid "Create"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__permission_create
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__permission_create
+msgid "Create Access"
+msgstr "Droit de création"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.onboarding_directory_step
+msgid "Create Directory"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.onboarding_storage_step
+msgid "Create Storage"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_category
+msgid "Create a new Category."
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.onboarding_storage_step
+msgid "Create a new Document Storage."
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.onboarding_directory_step
+msgid "Create a new Root Directory."
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_storage
+msgid "Create a new Storage object."
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_category__create_uid
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__create_uid
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__create_uid
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_storage__create_uid
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_tag__create_uid
+msgid "Created by"
+msgstr "Créé par"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_category__create_date
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__create_date
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__create_date
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_storage__create_date
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_tag__create_date
+msgid "Created on"
+msgstr "Créé le"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_directory
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_file
+msgid "Creation Date"
+msgstr "Date de création"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__save_type
+msgid "Current Save Type"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__custom_thumbnail
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__custom_thumbnail
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_mixins_thumbnail__custom_thumbnail
+msgid "Custom Thumbnail"
+msgstr ""
+
+#. module: muk_dms
+#: model:muk_dms.tag,name:muk_dms.tag_01_demo
+msgid "Customer"
+msgstr ""
+
+#. module: muk_dms
+#: model:muk_dms.tag,name:muk_dms.tag_08_demo
+msgid "Customer Invoice"
+msgstr ""
+
+#. module: muk_dms
+#: code:addons/muk_dms/models/storage.py:42
+#: selection:muk_dms.storage,save_type:0
+#, python-format
+msgid "Database"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "Define forbidden file extensions"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "Define the maximum upload size of a file in MB"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_res_config_settings__documents_forbidden_extensions
+msgid "Defines a list of forbidden file extensions. (Example: 'exe,msi')"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_res_config_settings__documents_binary_max_size
+msgid "Defines the maximum upload size in MB. Default (25MB)"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__permission_unlink
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__permission_unlink
+msgid "Delete Access"
+msgstr "Droit de suppression"
+
+#. module: muk_dms
+#. openerp-web
+#: code:addons/muk_dms/static/src/xml/views.xml:37
+#: model:ir.actions.act_window,name:muk_dms.action_dms_directories_storage
+#: model:ir.actions.act_window,name:muk_dms.action_dms_directory
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_category__directories
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_storage__storage_directories
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_tag__directories
+#: model:ir.ui.menu,name:muk_dms.menu_dms_directory
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_file
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_form
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_tree
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_storage_form
+#, python-format
+msgid "Directories"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_directories_all_directory
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_directories_directory
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_directories_storage
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_directory
+msgid "Directories can be used to structure and organize\n"
+" files directly in Odoo."
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model,name:muk_dms.model_muk_dms_directory
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__directory
+#: model_terms:ir.ui.view,arch_db:muk_dms.onboarding_directory_step
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_form
+msgid "Directory"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_category__display_name
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__display_name
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__display_name
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_mixins_thumbnail__display_name
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_storage__display_name
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_tag__display_name
+msgid "Display Name"
+msgstr "Nom affiché"
+
+#. module: muk_dms
+#: model:ir.model,name:muk_dms.model_muk_dms_category
+msgid "Document Category"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model,name:muk_dms.model_muk_dms_tag
+msgid "Document Tag"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.module.category,name:muk_dms.category_dms_security
+#: model:ir.ui.menu,name:muk_dms.main_menu_muk_dms
+msgid "Documents"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_company__documents_onboarding_directory_state
+msgid "Documents Onboarding Directory State"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_company__documents_onboarding_file_state
+msgid "Documents Onboarding File State"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_company__documents_onboarding_state
+msgid "Documents Onboarding State"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_company__documents_onboarding_storage_state
+msgid "Documents Onboarding Storage State"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_config_settings__module_muk_dms_attachment
+msgid "Documents Storage Location"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_config_settings__module_muk_dms_attachment_rules
+msgid "Documents Storage Rules"
+msgstr ""
+
+#. module: muk_dms
+#: selection:res.company,documents_onboarding_directory_state:0
+#: selection:res.company,documents_onboarding_file_state:0
+#: selection:res.company,documents_onboarding_state:0
+#: selection:res.company,documents_onboarding_storage_state:0
+msgid "Done"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_config_settings__module_muk_archive
+msgid "Download Directories"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_kanban
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_kanban
+msgid "Dropdown menu"
+msgstr "Menu déroulant"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__is_lock_editor
+msgid "Editor"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_form
+msgid "Elements"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "Enables a new save option to store files into a filestore"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_res_config_settings__module_muk_dms_file
+msgid "Enables a new save option to store files into a filestore."
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "Enables a new save option to store files into large objects"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_res_config_settings__module_muk_dms_lobject
+msgid "Enables a new save option to store files into large objects."
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_res_config_settings__module_muk_dms_finder
+msgid "Enables the Document Finder."
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "Enables version control for files"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_res_config_settings__module_muk_dms_version
+msgid "Enables version control for files."
+msgstr ""
+
+#. module: muk_dms
+#: code:addons/muk_dms/models/category.py:123
+#, python-format
+msgid "Error! You cannot create recursive categories."
+msgstr ""
+
+#. module: muk_dms
+#: code:addons/muk_dms/models/directory.py:321
+#, python-format
+msgid "Error! You cannot create recursive directories."
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_config_settings__module_muk_dms_export
+msgid "Export Files"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__extension
+msgid "Extension"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_config_settings__documents_forbidden_extensions
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "Extensions"
+msgstr ""
+
+#. module: muk_dms
+#: model:muk_dms.category,name:muk_dms.category_05_demo
+msgid "External"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model,name:muk_dms.model_muk_dms_file
+#: model_terms:ir.ui.view,arch_db:muk_dms.onboarding_file_step
+msgid "File"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_config_settings__module_muk_dms_preview
+msgid "File Preview"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "File Upload"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__name
+msgid "Filename"
+msgstr "Nom du fichier"
+
+#. module: muk_dms
+#: model:ir.actions.act_window,name:muk_dms.action_dms_file
+#: model:ir.actions.act_window,name:muk_dms.action_dms_file_migration
+#: model:ir.actions.act_window,name:muk_dms.action_dms_file_storage_migration
+#: model:ir.actions.act_window,name:muk_dms.action_dms_files_all_directory
+#: model:ir.actions.act_window,name:muk_dms.action_dms_files_directory
+#: model:ir.actions.act_window,name:muk_dms.action_dms_files_storage
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_category__files
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__files
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_storage__storage_files
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_tag__files
+#: model:ir.ui.menu,name:muk_dms.menu_dms_file
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_form
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_tree
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_form
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_migration_tree
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_tree
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_storage_form
+msgid "Files"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_file
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_file_migration
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_file_storage_migration
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_files_all_directory
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_files_directory
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_files_storage
+msgid "Files are used to save content directly in Odoo."
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_config_settings__module_muk_dms_file
+msgid "Filestore Storage"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_config_settings__module_muk_dms_finder
+msgid "Finder"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.actions.act_window,name:muk_dms.action_dms_settings_general
+#: model:ir.ui.menu,name:muk_dms.menu_dms_settings_general
+msgid "General Settings"
+msgstr "Paramètres Généraux"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_directory
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_file
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_file_migration
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_storage_search
+msgid "Group By"
+msgstr "Regrouper par"
+
+#. module: muk_dms
+#: model:ir.model,name:muk_dms.model_ir_http
+msgid "HTTP Routing"
+msgstr ""
+
+#. module: muk_dms
+#: model:muk_dms.category,name:muk_dms.category_02_demo
+msgid "Human Resource"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_category__id
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__id
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__id
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_mixins_thumbnail__id
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_storage__id
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_tag__id
+msgid "ID"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_muk_dms_file__active
+msgid "If a file is set to archived, it is not displayed, but still exists."
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_muk_dms_directory__company
+#: model:ir.model.fields,help:muk_dms.field_muk_dms_file__company
+#: model:ir.model.fields,help:muk_dms.field_muk_dms_storage__company
+msgid "If set, directories and files will only be available for the selected company."
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_muk_dms_directory__is_hidden
+#: model:ir.model.fields,help:muk_dms.field_muk_dms_file__is_hidden
+#: model:ir.model.fields,help:muk_dms.field_muk_dms_storage__is_hidden
+msgid "Indicates if directories and files are hidden by default."
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_muk_dms_directory__is_root_directory
+msgid "Indicates if the directory is a root directory. A root directory has a settings object,\n"
+" while a directory with a set parent inherits the settings form its parent."
+msgstr ""
+
+#. module: muk_dms
+#: model:muk_dms.category,name:muk_dms.category_01_demo
+msgid "Internal"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_form
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_new_form
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_form
+msgid "Internal / Human Resource"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__is_root_directory
+msgid "Is Root Directory"
+msgstr ""
+
+#. module: muk_dms
+#: selection:res.company,documents_onboarding_directory_state:0
+#: selection:res.company,documents_onboarding_file_state:0
+#: selection:res.company,documents_onboarding_state:0
+#: selection:res.company,documents_onboarding_storage_state:0
+msgid "Just done"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_config_settings__module_muk_dms_lobject
+msgid "Large Objects Storage"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_category____last_update
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory____last_update
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file____last_update
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_mixins_thumbnail____last_update
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_storage____last_update
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_tag____last_update
+msgid "Last Modified on"
+msgstr "Dernière modification le"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_category__write_uid
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__write_uid
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__write_uid
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_storage__write_uid
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_tag__write_uid
+msgid "Last Updated by"
+msgstr "Dernière mise à jour par"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_category__write_date
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__write_date
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__write_date
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_storage__write_date
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_tag__write_date
+msgid "Last Updated on"
+msgstr "Dernière mise à jour le"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_form
+msgid "Lock"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__is_locked
+msgid "Locked"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__locked_by
+msgid "Locked by"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_config_settings__module_muk_dms_mail
+msgid "Mail Support"
+msgstr ""
+
+#. module: muk_dms
+#: model:res.groups,name:muk_dms.group_dms_manager
+msgid "Manager"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_storage_form
+msgid "Manual File Migration"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__custom_thumbnail_medium
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__custom_thumbnail_medium
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_mixins_thumbnail__custom_thumbnail_medium
+msgid "Medium Custom Thumbnail"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__thumbnail_medium
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__thumbnail_medium
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_mixins_thumbnail__thumbnail_medium
+msgid "Medium Thumbnail"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_form
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_form
+msgid "Meta Information"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.actions.server,name:muk_dms.action_dms_attachment_migrate
+msgid "Migrate"
+msgstr ""
+
+#. module: muk_dms
+#: code:addons/muk_dms/models/file.py:221
+#, python-format
+msgid "Migrate File %s of %s [ %s ]"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_storage_form
+msgid "Migrate Files"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.ui.menu,name:muk_dms.menu_dms_file_migration
+msgid "Migration"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__migration
+msgid "Migration Status"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_directory
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_file
+msgid "Modification Date"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_directory
+msgid "My Directories"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_form
+msgid "My Documents"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_file
+msgid "My Files"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_category__name
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__name
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_storage__name
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_tag__name
+msgid "Name"
+msgstr "Nom"
+
+#. module: muk_dms
+#: model:ir.actions.act_window,name:muk_dms.action_dms_directory_new
+#: model:ir.actions.act_window,name:muk_dms.action_dms_file_new
+msgid "New Root Directory"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.actions.act_window,name:muk_dms.action_dms_storage_new
+msgid "New Storage"
+msgstr ""
+
+#. module: muk_dms
+#: model:muk_dms.category,name:muk_dms.category_06_demo
+msgid "News"
+msgstr ""
+
+#. module: muk_dms
+#. openerp-web
+#: code:addons/muk_dms/static/src/js/views/file/kanban/file_kanban_controller.js:92
+#, python-format
+msgid "No Directory has been selected!"
+msgstr ""
+
+#. module: muk_dms
+#: selection:res.company,documents_onboarding_directory_state:0
+#: selection:res.company,documents_onboarding_file_state:0
+#: selection:res.company,documents_onboarding_state:0
+#: selection:res.company,documents_onboarding_storage_state:0
+msgid "Not done"
+msgstr ""
+
+#. module: muk_dms
+#: code:addons/muk_dms/models/storage.py:99
+#, python-format
+msgid "Only managers can execute this action."
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.ui.menu,name:muk_dms.cat_menu_muk_dms_config_organizing
+msgid "Organizing"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_category__parent_category
+msgid "Parent Category"
+msgstr "Catégorie mère"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__parent_directory
+msgid "Parent Directory"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_category__parent_path
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__parent_path
+msgid "Parent Path"
+msgstr "Chemin parent"
+
+#. module: muk_dms
+#: model:muk_dms.tag,name:muk_dms.tag_02_demo
+msgid "Partner"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_tree
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_tree
+msgid "Path"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_category__parent_path_json
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__parent_path_json
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__path_json
+msgid "Path Json"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_category__parent_path_names
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__parent_path_names
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__path_names
+msgid "Path Names"
+msgstr ""
+
+#. module: muk_dms
+#: model:muk_dms.tag,name:muk_dms.tag_05_demo
+msgid "Portal"
+msgstr ""
+
+#. module: muk_dms
+#: model:muk_dms.tag,name:muk_dms.tag_10_demo
+msgid "Product"
+msgstr ""
+
+#. module: muk_dms
+#: model:muk_dms.tag,name:muk_dms.tag_03_demo
+msgid "Project"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__permission_read
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__permission_read
+msgid "Read Access"
+msgstr "Accès en lecture"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_config_settings__module_muk_dms_trash
+msgid "Restore Files"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_storage__root_directories
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_directory
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_storage_form
+msgid "Root Directories"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__root_storage
+msgid "Root Storage"
+msgstr ""
+
+#. module: muk_dms
+#: model:muk_dms.tag,name:muk_dms.tag_04_demo
+msgid "Sales"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_storage__save_type
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_storage_search
+msgid "Save Type"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__size
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__size
+#: model:ir.model.fields,field_description:muk_dms.field_res_config_settings__documents_binary_max_size
+msgid "Size"
+msgstr "Taille"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__custom_thumbnail_small
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__custom_thumbnail_small
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_mixins_thumbnail__custom_thumbnail_small
+msgid "Small Custom Thumbnail"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__thumbnail_small
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__thumbnail_small
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_mixins_thumbnail__thumbnail_small
+msgid "Small Thumbnail"
+msgstr ""
+
+#. module: muk_dms
+#. openerp-web
+#: code:addons/muk_dms/static/src/xml/views.xml:28
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__starred
+#, python-format
+msgid "Starred"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_directory
+msgid "Starred Directories"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__user_stars
+msgid "Stars"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model,name:muk_dms.model_muk_dms_storage
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__storage
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__storage
+#: model_terms:ir.ui.view,arch_db:muk_dms.onboarding_storage_step
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_directory
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_file
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_file_migration
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_storage_form
+msgid "Storage"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__is_hidden
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__is_hidden
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_storage__is_hidden
+msgid "Storage is Hidden"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.actions.act_window,name:muk_dms.action_dms_storage
+#: model:ir.ui.menu,name:muk_dms.menu_dms_storage
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_storage_tree
+msgid "Storages"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_storage
+msgid "Storages are used to configure your Documents."
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.actions.act_window,name:muk_dms.action_dms_directories_all_directory
+#: model:ir.actions.act_window,name:muk_dms.action_dms_directories_directory
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__child_directories
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_form
+msgid "Subdirectories"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.ui.menu,name:muk_dms.cat_menu_muk_dms_config_system
+msgid "System"
+msgstr ""
+
+#. module: muk_dms
+#: sql_constraint:muk_dms.tag:0
+msgid "Tag name already exists!"
+msgstr ""
+
+#. module: muk_dms
+#. openerp-web
+#: code:addons/muk_dms/static/src/xml/views.xml:55
+#: model:ir.actions.act_window,name:muk_dms.action_dms_tag
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__tags
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__tags
+#: model:ir.ui.menu,name:muk_dms.menu_dms_tag
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_tag_tree
+#, python-format
+msgid "Tags"
+msgstr "Étiquettes"
+
+#. module: muk_dms
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_tag
+msgid "Tags are used to categorize Documents."
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_form
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_new_form
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_form
+msgid "Tags..."
+msgstr "Étiquettes..."
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_form
+msgid "Technical Information"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_muk_dms_category__active
+msgid "The active field allows you to hide the category without removing it."
+msgstr "Décochez le champ 'Actif' pour cacher la catégorie sans la supprimer."
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_muk_dms_tag__active
+msgid "The active field allows you to hide the tag without removing it."
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.document_onboarding_directory_panel
+#: model_terms:ir.ui.view,arch_db:muk_dms.document_onboarding_file_panel
+msgid "The configuration is done!"
+msgstr ""
+
+#. module: muk_dms
+#: code:addons/muk_dms/models/file.py:420
+#, python-format
+msgid "The directory has to have the permission to create files."
+msgstr ""
+
+#. module: muk_dms
+#: code:addons/muk_dms/models/directory.py:344
+#, python-format
+msgid "The directory name is invalid."
+msgstr ""
+
+#. module: muk_dms
+#: code:addons/muk_dms/models/file.py:408
+#, python-format
+msgid "The file has a forbidden file extension."
+msgstr ""
+
+#. module: muk_dms
+#: code:addons/muk_dms/models/file.py:399
+#, python-format
+msgid "The file name is invalid."
+msgstr ""
+
+#. module: muk_dms
+#: code:addons/muk_dms/models/file.py:414
+#, python-format
+msgid "The maximum upload size is %s MB)."
+msgstr ""
+
+#. module: muk_dms
+#: code:addons/muk_dms/models/directory.py:338
+#, python-format
+msgid "The parent directory has to have the permission to create directories."
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_muk_dms_storage__save_type
+msgid "The save type is used to determine how a file is saved by the system. If you change \n"
+" this setting, you can migrate existing files manually by triggering the action."
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__thumbnail
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__thumbnail
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_mixins_thumbnail__thumbnail
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_kanban
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_kanban
+msgid "Thumbnail"
+msgstr "Miniature"
+
+#. module: muk_dms
+#: model:ir.model,name:muk_dms.model_muk_dms_mixins_thumbnail
+msgid "Thumbnail Mixin"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__count_total_elements
+msgid "Total Elements"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__count_total_files
+msgid "Total Files"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__count_total_directories
+msgid "Total Subdirectories"
+msgstr ""
+
+#. module: muk_dms
+#: model:muk_dms.category,name:muk_dms.category_04_demo
+msgid "Traveling"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__mimetype
+msgid "Type"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_form
+msgid "Unlock"
+msgstr ""
+
+#. module: muk_dms
+#. openerp-web
+#: code:addons/muk_dms/static/src/js/views/file/kanban/file_kanban_controller.js:92
+#, python-format
+msgid "Upload Error"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.onboarding_file_step
+msgid "Upload File"
+msgstr ""
+
+#. module: muk_dms
+#. openerp-web
+#: code:addons/muk_dms/static/src/js/views/mixins/file_upload.js:63
+#, python-format
+msgid "Upload Files"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.onboarding_file_step
+msgid "Upload your first File."
+msgstr ""
+
+#. module: muk_dms
+#. openerp-web
+#: code:addons/muk_dms/static/src/js/views/mixins/file_upload.js:64
+#, python-format
+msgid "Uploading..."
+msgstr ""
+
+#. module: muk_dms
+#: model:res.groups,name:muk_dms.group_dms_user
+msgid "User"
+msgstr ""
+
+#. module: muk_dms
+#: model:muk_dms.tag,name:muk_dms.tag_09_demo
+msgid "Vendor Bill"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_config_settings__module_muk_dms_version
+msgid "Versioning"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "Views"
+msgstr "Vues"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__permission_write
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__permission_write
+msgid "Write Access"
+msgstr "Accès en écriture"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.document_onboarding_directory_panel
+#: model_terms:ir.ui.view,arch_db:muk_dms.document_onboarding_file_panel
+msgid "action_close_documents_onboarding"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "exe,msi"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.document_onboarding_file_panel
+msgid "o_onboarding_blue"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.document_onboarding_directory_panel
+msgid "o_onboarding_orange"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.document_onboarding_directory_panel
+#: model_terms:ir.ui.view,arch_db:muk_dms.document_onboarding_file_panel
+msgid "res.company"
+msgstr ""
+
diff --git a/odex-event/muk_dms/i18n/nl.po b/odex-event/muk_dms/i18n/nl.po
new file mode 100644
index 000000000..6ec7fc7ad
--- /dev/null
+++ b/odex-event/muk_dms/i18n/nl.po
@@ -0,0 +1,1463 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * muk_dms
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 12.0-20190128\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2019-03-05 18:29+0000\n"
+"PO-Revision-Date: 2019-03-05 18:29+0000\n"
+"Last-Translator: <>\n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: \n"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.document_onboarding_directory_panel
+msgid "/muk_dms/static/src/img/banner/documents_onboarding_directory.png"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.document_onboarding_file_panel
+msgid "/muk_dms/static/src/img/banner/documents_onboarding_file.png"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_kanban
+msgid " Download"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_kanban
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_kanban
+msgid " Open"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_kanban
+msgid " Lock"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_kanban
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_kanban
+msgid " Edit"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_kanban
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_kanban
+msgid " Delete"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_kanban
+msgid " Unlock"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "File Extensions"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "File Size"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "Save this page and come back here to set up the feature."
+msgstr "Bewaar deze pagina en kom terug naar deze pagina om de optie op te zetten."
+
+#. module: muk_dms
+#: code:addons/muk_dms/models/directory.py:332
+#, python-format
+msgid "A directory can't be a root and have a parent directory."
+msgstr ""
+
+#. module: muk_dms
+#: code:addons/muk_dms/models/directory.py:330
+#, python-format
+msgid "A directory has to have a parent directory."
+msgstr ""
+
+#. module: muk_dms
+#: code:addons/muk_dms/models/directory.py:350
+#, python-format
+msgid "A directory with the same name already exists."
+msgstr ""
+
+#. module: muk_dms
+#: code:addons/muk_dms/models/directory.py:414
+#, python-format
+msgid "A file is locked, the folder cannot be deleted."
+msgstr ""
+
+#. module: muk_dms
+#: code:addons/muk_dms/models/file.py:402
+#, python-format
+msgid "A file with the same name already exists."
+msgstr ""
+
+#. module: muk_dms
+#: code:addons/muk_dms/models/directory.py:328
+#, python-format
+msgid "A root directory has to have a root storage."
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_config_settings__module_muk_dms_access
+msgid "Access Control"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_form
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_form
+msgid "Access Information"
+msgstr ""
+
+#. module: muk_dms
+#: model:muk_dms.tag,name:muk_dms.tag_07_demo
+msgid "Accounting"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "Activates a file trash to restore deleted files"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_res_config_settings__module_muk_dms_trash
+msgid "Activates a file trash to restore deleted files."
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "Activates the preview function on files"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_res_config_settings__module_muk_dms_preview
+msgid "Activates the preview function on files."
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_category__active
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_tag__active
+msgid "Active"
+msgstr "Actief"
+
+#. module: muk_dms
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_directory
+msgid "Add a new Directory."
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_file
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_file_migration
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_file_storage_migration
+msgid "Add a new File."
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "Adds support for messages and activities on directories and files"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_res_config_settings__module_muk_dms_mail
+msgid "Adds support for messages and activities on directories and files."
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_category_search
+msgid "All"
+msgstr "Alle"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_file
+msgid "All Files"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_res_config_settings__module_muk_dms_attachment_rules
+msgid "Allows attachments to be automatically placed in the right directory."
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "Allows attachments to be stored inside of Documents"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_res_config_settings__module_muk_dms_attachment
+msgid "Allows attachments to be stored inside of Documents."
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_res_config_settings__module_muk_dms_attachment_wizard
+msgid "Allows documents to be used as attachments."
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_res_config_settings__module_muk_dms_export
+msgid "Allows the conversion of existing files."
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "Allows the creation of groups to define access rights"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_res_config_settings__module_muk_dms_access
+msgid "Allows the creation of groups to define access rights."
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_res_config_settings__module_muk_dms_thumbnails
+msgid "Allows the creation of thumbnails for files."
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_res_config_settings__module_muk_dms_widget
+msgid "Allows the user to use DMS documents as input for any binary field."
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_res_config_settings__module_muk_archive
+msgid "Allows to download directories as a archive file."
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "Allows to placed attachments in the right directory"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "Allows you to create rule templates to create attachment rules"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_res_config_settings__module_muk_dms_attachment_automation
+msgid "Allows you to create rule templates to create attachment rules."
+msgstr ""
+
+#. module: muk_dms
+#: model:muk_dms.tag,name:muk_dms.tag_06_demo
+msgid "Apps"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__active
+msgid "Archived"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_config_settings__module_muk_dms_attachment_automation
+msgid "Attachment Rule Automation"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_config_settings__module_muk_dms_attachment_wizard
+msgid "Attachment Wizard"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "Attachments"
+msgstr "Bijlagen"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_config_settings__module_muk_dms_thumbnails
+msgid "Automatic Thumbnails"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_config_settings__module_muk_dms_widget
+msgid "Binary Widget Support"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_new_form
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_new_form
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_storage_new_form
+msgid "Cancel"
+msgstr "Annuleren"
+
+#. module: muk_dms
+#. openerp-web
+#: code:addons/muk_dms/static/src/xml/views.xml:46
+#: model:ir.actions.act_window,name:muk_dms.action_dms_category
+#: model:ir.ui.menu,name:muk_dms.menu_dms_category
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_category_search
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_category_tree
+#, python-format
+msgid "Categories"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_category
+msgid "Categories are used to categorize Documents."
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__category
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__category
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_directory
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_file
+msgid "Category"
+msgstr "Categorie"
+
+#. module: muk_dms
+#: sql_constraint:muk_dms.category:0
+msgid "Category name already exists!"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__checksum
+msgid "Checksum/SHA1"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_category__child_categories
+msgid "Child Categories"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_directories_all_directory
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_directories_directory
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_directories_storage
+msgid "Click to add a new directory."
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_files_all_directory
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_files_directory
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_files_storage
+msgid "Click to add a new file."
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_tag
+msgid "Click to create a new tag."
+msgstr ""
+
+#. module: muk_dms
+#: selection:res.company,documents_onboarding_directory_state:0
+#: selection:res.company,documents_onboarding_file_state:0
+#: selection:res.company,documents_onboarding_state:0
+#: selection:res.company,documents_onboarding_storage_state:0
+msgid "Closed"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__color
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__color
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_directory
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_file
+msgid "Color"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_tag__color
+msgid "Color Index"
+msgstr "Kleurindex"
+
+#. module: muk_dms
+#: model:ir.model,name:muk_dms.model_res_company
+msgid "Companies"
+msgstr "Bedrijven"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__company
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__company
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_storage__company
+msgid "Company"
+msgstr "Bedrijf"
+
+#. module: muk_dms
+#: model:ir.model,name:muk_dms.model_res_config_settings
+msgid "Config Settings"
+msgstr "Configuratie instellingen"
+
+#. module: muk_dms
+#: model:ir.ui.menu,name:muk_dms.cat_menu_muk_dms_config
+msgid "Configuration"
+msgstr "Instellingen"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__content
+msgid "Content"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__content_binary
+msgid "Content Binary"
+msgstr ""
+
+#. module: muk_dms
+#: model:muk_dms.tag,name:muk_dms.tag_11_demo
+msgid "Contract"
+msgstr ""
+
+#. module: muk_dms
+#: model:muk_dms.category,name:muk_dms.category_03_demo
+msgid "Contracts"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_storage__count_storage_directories
+msgid "Count Directories"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__count_elements
+msgid "Count Elements"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__count_files
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_storage__count_storage_files
+msgid "Count Files"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__count_directories
+msgid "Count Subdirectories"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_new_form
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_new_form
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_storage_new_form
+msgid "Create"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__permission_create
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__permission_create
+msgid "Create Access"
+msgstr "Aanmaken"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.onboarding_directory_step
+msgid "Create Directory"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.onboarding_storage_step
+msgid "Create Storage"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_category
+msgid "Create a new Category."
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.onboarding_storage_step
+msgid "Create a new Document Storage."
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.onboarding_directory_step
+msgid "Create a new Root Directory."
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_storage
+msgid "Create a new Storage object."
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_category__create_uid
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__create_uid
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__create_uid
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_storage__create_uid
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_tag__create_uid
+msgid "Created by"
+msgstr "Aangemaakt door"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_category__create_date
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__create_date
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__create_date
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_storage__create_date
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_tag__create_date
+msgid "Created on"
+msgstr "Aangemaakt op"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_directory
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_file
+msgid "Creation Date"
+msgstr "Aanmaakdatum"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__save_type
+msgid "Current Save Type"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__custom_thumbnail
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__custom_thumbnail
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_mixins_thumbnail__custom_thumbnail
+msgid "Custom Thumbnail"
+msgstr ""
+
+#. module: muk_dms
+#: model:muk_dms.tag,name:muk_dms.tag_01_demo
+msgid "Customer"
+msgstr ""
+
+#. module: muk_dms
+#: model:muk_dms.tag,name:muk_dms.tag_08_demo
+msgid "Customer Invoice"
+msgstr ""
+
+#. module: muk_dms
+#: code:addons/muk_dms/models/storage.py:42
+#: selection:muk_dms.storage,save_type:0
+#, python-format
+msgid "Database"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "Define forbidden file extensions"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "Define the maximum upload size of a file in MB"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_res_config_settings__documents_forbidden_extensions
+msgid "Defines a list of forbidden file extensions. (Example: 'exe,msi')"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_res_config_settings__documents_binary_max_size
+msgid "Defines the maximum upload size in MB. Default (25MB)"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__permission_unlink
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__permission_unlink
+msgid "Delete Access"
+msgstr "Verwijderen"
+
+#. module: muk_dms
+#. openerp-web
+#: code:addons/muk_dms/static/src/xml/views.xml:37
+#: model:ir.actions.act_window,name:muk_dms.action_dms_directories_storage
+#: model:ir.actions.act_window,name:muk_dms.action_dms_directory
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_category__directories
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_storage__storage_directories
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_tag__directories
+#: model:ir.ui.menu,name:muk_dms.menu_dms_directory
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_file
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_form
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_tree
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_storage_form
+#, python-format
+msgid "Directories"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_directories_all_directory
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_directories_directory
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_directories_storage
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_directory
+msgid "Directories can be used to structure and organize\n"
+" files directly in Odoo."
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model,name:muk_dms.model_muk_dms_directory
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__directory
+#: model_terms:ir.ui.view,arch_db:muk_dms.onboarding_directory_step
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_form
+msgid "Directory"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_category__display_name
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__display_name
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__display_name
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_mixins_thumbnail__display_name
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_storage__display_name
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_tag__display_name
+msgid "Display Name"
+msgstr "Weergave naam"
+
+#. module: muk_dms
+#: model:ir.model,name:muk_dms.model_muk_dms_category
+msgid "Document Category"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model,name:muk_dms.model_muk_dms_tag
+msgid "Document Tag"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.module.category,name:muk_dms.category_dms_security
+#: model:ir.ui.menu,name:muk_dms.main_menu_muk_dms
+msgid "Documents"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_company__documents_onboarding_directory_state
+msgid "Documents Onboarding Directory State"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_company__documents_onboarding_file_state
+msgid "Documents Onboarding File State"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_company__documents_onboarding_state
+msgid "Documents Onboarding State"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_company__documents_onboarding_storage_state
+msgid "Documents Onboarding Storage State"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_config_settings__module_muk_dms_attachment
+msgid "Documents Storage Location"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_config_settings__module_muk_dms_attachment_rules
+msgid "Documents Storage Rules"
+msgstr ""
+
+#. module: muk_dms
+#: selection:res.company,documents_onboarding_directory_state:0
+#: selection:res.company,documents_onboarding_file_state:0
+#: selection:res.company,documents_onboarding_state:0
+#: selection:res.company,documents_onboarding_storage_state:0
+msgid "Done"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_config_settings__module_muk_archive
+msgid "Download Directories"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_kanban
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_kanban
+msgid "Dropdown menu"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__is_lock_editor
+msgid "Editor"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_form
+msgid "Elements"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "Enables a new save option to store files into a filestore"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_res_config_settings__module_muk_dms_file
+msgid "Enables a new save option to store files into a filestore."
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "Enables a new save option to store files into large objects"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_res_config_settings__module_muk_dms_lobject
+msgid "Enables a new save option to store files into large objects."
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_res_config_settings__module_muk_dms_finder
+msgid "Enables the Document Finder."
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "Enables version control for files"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_res_config_settings__module_muk_dms_version
+msgid "Enables version control for files."
+msgstr ""
+
+#. module: muk_dms
+#: code:addons/muk_dms/models/category.py:123
+#, python-format
+msgid "Error! You cannot create recursive categories."
+msgstr ""
+
+#. module: muk_dms
+#: code:addons/muk_dms/models/directory.py:321
+#, python-format
+msgid "Error! You cannot create recursive directories."
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_config_settings__module_muk_dms_export
+msgid "Export Files"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__extension
+msgid "Extension"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_config_settings__documents_forbidden_extensions
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "Extensions"
+msgstr ""
+
+#. module: muk_dms
+#: model:muk_dms.category,name:muk_dms.category_05_demo
+msgid "External"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model,name:muk_dms.model_muk_dms_file
+#: model_terms:ir.ui.view,arch_db:muk_dms.onboarding_file_step
+msgid "File"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_config_settings__module_muk_dms_preview
+msgid "File Preview"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "File Upload"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__name
+msgid "Filename"
+msgstr "Bestandsnaam"
+
+#. module: muk_dms
+#: model:ir.actions.act_window,name:muk_dms.action_dms_file
+#: model:ir.actions.act_window,name:muk_dms.action_dms_file_migration
+#: model:ir.actions.act_window,name:muk_dms.action_dms_file_storage_migration
+#: model:ir.actions.act_window,name:muk_dms.action_dms_files_all_directory
+#: model:ir.actions.act_window,name:muk_dms.action_dms_files_directory
+#: model:ir.actions.act_window,name:muk_dms.action_dms_files_storage
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_category__files
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__files
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_storage__storage_files
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_tag__files
+#: model:ir.ui.menu,name:muk_dms.menu_dms_file
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_form
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_tree
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_form
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_migration_tree
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_tree
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_storage_form
+msgid "Files"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_file
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_file_migration
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_file_storage_migration
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_files_all_directory
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_files_directory
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_files_storage
+msgid "Files are used to save content directly in Odoo."
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_config_settings__module_muk_dms_file
+msgid "Filestore Storage"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_config_settings__module_muk_dms_finder
+msgid "Finder"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.actions.act_window,name:muk_dms.action_dms_settings_general
+#: model:ir.ui.menu,name:muk_dms.menu_dms_settings_general
+msgid "General Settings"
+msgstr "Algemene instellingen"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_directory
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_file
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_file_migration
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_storage_search
+msgid "Group By"
+msgstr "Groepeer op"
+
+#. module: muk_dms
+#: model:ir.model,name:muk_dms.model_ir_http
+msgid "HTTP Routing"
+msgstr "HTTP routing"
+
+#. module: muk_dms
+#: model:muk_dms.category,name:muk_dms.category_02_demo
+msgid "Human Resource"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_category__id
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__id
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__id
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_mixins_thumbnail__id
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_storage__id
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_tag__id
+msgid "ID"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_muk_dms_file__active
+msgid "If a file is set to archived, it is not displayed, but still exists."
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_muk_dms_directory__company
+#: model:ir.model.fields,help:muk_dms.field_muk_dms_file__company
+#: model:ir.model.fields,help:muk_dms.field_muk_dms_storage__company
+msgid "If set, directories and files will only be available for the selected company."
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_muk_dms_directory__is_hidden
+#: model:ir.model.fields,help:muk_dms.field_muk_dms_file__is_hidden
+#: model:ir.model.fields,help:muk_dms.field_muk_dms_storage__is_hidden
+msgid "Indicates if directories and files are hidden by default."
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_muk_dms_directory__is_root_directory
+msgid "Indicates if the directory is a root directory. A root directory has a settings object,\n"
+" while a directory with a set parent inherits the settings form its parent."
+msgstr ""
+
+#. module: muk_dms
+#: model:muk_dms.category,name:muk_dms.category_01_demo
+msgid "Internal"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_form
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_new_form
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_form
+msgid "Internal / Human Resource"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__is_root_directory
+msgid "Is Root Directory"
+msgstr ""
+
+#. module: muk_dms
+#: selection:res.company,documents_onboarding_directory_state:0
+#: selection:res.company,documents_onboarding_file_state:0
+#: selection:res.company,documents_onboarding_state:0
+#: selection:res.company,documents_onboarding_storage_state:0
+msgid "Just done"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_config_settings__module_muk_dms_lobject
+msgid "Large Objects Storage"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_category____last_update
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory____last_update
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file____last_update
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_mixins_thumbnail____last_update
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_storage____last_update
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_tag____last_update
+msgid "Last Modified on"
+msgstr "Laatst gewijzigd op"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_category__write_uid
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__write_uid
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__write_uid
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_storage__write_uid
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_tag__write_uid
+msgid "Last Updated by"
+msgstr "Laatst bijgewerkt door"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_category__write_date
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__write_date
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__write_date
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_storage__write_date
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_tag__write_date
+msgid "Last Updated on"
+msgstr "Laatst bijgewerkt op"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_form
+msgid "Lock"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__is_locked
+msgid "Locked"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__locked_by
+msgid "Locked by"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_config_settings__module_muk_dms_mail
+msgid "Mail Support"
+msgstr ""
+
+#. module: muk_dms
+#: model:res.groups,name:muk_dms.group_dms_manager
+msgid "Manager"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_storage_form
+msgid "Manual File Migration"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__custom_thumbnail_medium
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__custom_thumbnail_medium
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_mixins_thumbnail__custom_thumbnail_medium
+msgid "Medium Custom Thumbnail"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__thumbnail_medium
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__thumbnail_medium
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_mixins_thumbnail__thumbnail_medium
+msgid "Medium Thumbnail"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_form
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_form
+msgid "Meta Information"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.actions.server,name:muk_dms.action_dms_attachment_migrate
+msgid "Migrate"
+msgstr ""
+
+#. module: muk_dms
+#: code:addons/muk_dms/models/file.py:221
+#, python-format
+msgid "Migrate File %s of %s [ %s ]"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_storage_form
+msgid "Migrate Files"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.ui.menu,name:muk_dms.menu_dms_file_migration
+msgid "Migration"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__migration
+msgid "Migration Status"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_directory
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_file
+msgid "Modification Date"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_directory
+msgid "My Directories"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_form
+msgid "My Documents"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_file
+msgid "My Files"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_category__name
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__name
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_storage__name
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_tag__name
+msgid "Name"
+msgstr "Naam"
+
+#. module: muk_dms
+#: model:ir.actions.act_window,name:muk_dms.action_dms_directory_new
+#: model:ir.actions.act_window,name:muk_dms.action_dms_file_new
+msgid "New Root Directory"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.actions.act_window,name:muk_dms.action_dms_storage_new
+msgid "New Storage"
+msgstr ""
+
+#. module: muk_dms
+#: model:muk_dms.category,name:muk_dms.category_06_demo
+msgid "News"
+msgstr ""
+
+#. module: muk_dms
+#. openerp-web
+#: code:addons/muk_dms/static/src/js/views/file/kanban/file_kanban_controller.js:92
+#, python-format
+msgid "No Directory has been selected!"
+msgstr ""
+
+#. module: muk_dms
+#: selection:res.company,documents_onboarding_directory_state:0
+#: selection:res.company,documents_onboarding_file_state:0
+#: selection:res.company,documents_onboarding_state:0
+#: selection:res.company,documents_onboarding_storage_state:0
+msgid "Not done"
+msgstr ""
+
+#. module: muk_dms
+#: code:addons/muk_dms/models/storage.py:99
+#, python-format
+msgid "Only managers can execute this action."
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.ui.menu,name:muk_dms.cat_menu_muk_dms_config_organizing
+msgid "Organizing"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_category__parent_category
+msgid "Parent Category"
+msgstr "Hoofdcategorie"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__parent_directory
+msgid "Parent Directory"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_category__parent_path
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__parent_path
+msgid "Parent Path"
+msgstr "Bovenliggend pad"
+
+#. module: muk_dms
+#: model:muk_dms.tag,name:muk_dms.tag_02_demo
+msgid "Partner"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_tree
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_tree
+msgid "Path"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_category__parent_path_json
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__parent_path_json
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__path_json
+msgid "Path Json"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_category__parent_path_names
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__parent_path_names
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__path_names
+msgid "Path Names"
+msgstr ""
+
+#. module: muk_dms
+#: model:muk_dms.tag,name:muk_dms.tag_05_demo
+msgid "Portal"
+msgstr ""
+
+#. module: muk_dms
+#: model:muk_dms.tag,name:muk_dms.tag_10_demo
+msgid "Product"
+msgstr ""
+
+#. module: muk_dms
+#: model:muk_dms.tag,name:muk_dms.tag_03_demo
+msgid "Project"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__permission_read
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__permission_read
+msgid "Read Access"
+msgstr "Lezen"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_config_settings__module_muk_dms_trash
+msgid "Restore Files"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_storage__root_directories
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_directory
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_storage_form
+msgid "Root Directories"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__root_storage
+msgid "Root Storage"
+msgstr ""
+
+#. module: muk_dms
+#: model:muk_dms.tag,name:muk_dms.tag_04_demo
+msgid "Sales"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_storage__save_type
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_storage_search
+msgid "Save Type"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__size
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__size
+#: model:ir.model.fields,field_description:muk_dms.field_res_config_settings__documents_binary_max_size
+msgid "Size"
+msgstr "Grootte"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__custom_thumbnail_small
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__custom_thumbnail_small
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_mixins_thumbnail__custom_thumbnail_small
+msgid "Small Custom Thumbnail"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__thumbnail_small
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__thumbnail_small
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_mixins_thumbnail__thumbnail_small
+msgid "Small Thumbnail"
+msgstr ""
+
+#. module: muk_dms
+#. openerp-web
+#: code:addons/muk_dms/static/src/xml/views.xml:28
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__starred
+#, python-format
+msgid "Starred"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_directory
+msgid "Starred Directories"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__user_stars
+msgid "Stars"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model,name:muk_dms.model_muk_dms_storage
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__storage
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__storage
+#: model_terms:ir.ui.view,arch_db:muk_dms.onboarding_storage_step
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_directory
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_file
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_file_migration
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_storage_form
+msgid "Storage"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__is_hidden
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__is_hidden
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_storage__is_hidden
+msgid "Storage is Hidden"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.actions.act_window,name:muk_dms.action_dms_storage
+#: model:ir.ui.menu,name:muk_dms.menu_dms_storage
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_storage_tree
+msgid "Storages"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_storage
+msgid "Storages are used to configure your Documents."
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.actions.act_window,name:muk_dms.action_dms_directories_all_directory
+#: model:ir.actions.act_window,name:muk_dms.action_dms_directories_directory
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__child_directories
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_form
+msgid "Subdirectories"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.ui.menu,name:muk_dms.cat_menu_muk_dms_config_system
+msgid "System"
+msgstr ""
+
+#. module: muk_dms
+#: sql_constraint:muk_dms.tag:0
+msgid "Tag name already exists!"
+msgstr ""
+
+#. module: muk_dms
+#. openerp-web
+#: code:addons/muk_dms/static/src/xml/views.xml:55
+#: model:ir.actions.act_window,name:muk_dms.action_dms_tag
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__tags
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__tags
+#: model:ir.ui.menu,name:muk_dms.menu_dms_tag
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_tag_tree
+#, python-format
+msgid "Tags"
+msgstr "Labels"
+
+#. module: muk_dms
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_tag
+msgid "Tags are used to categorize Documents."
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_form
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_new_form
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_form
+msgid "Tags..."
+msgstr "Labels..."
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_form
+msgid "Technical Information"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_muk_dms_category__active
+msgid "The active field allows you to hide the category without removing it."
+msgstr "Het veld actief staat toe categorieën te verbergen zonder deze te verwijderen."
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_muk_dms_tag__active
+msgid "The active field allows you to hide the tag without removing it."
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.document_onboarding_directory_panel
+#: model_terms:ir.ui.view,arch_db:muk_dms.document_onboarding_file_panel
+msgid "The configuration is done!"
+msgstr ""
+
+#. module: muk_dms
+#: code:addons/muk_dms/models/file.py:420
+#, python-format
+msgid "The directory has to have the permission to create files."
+msgstr ""
+
+#. module: muk_dms
+#: code:addons/muk_dms/models/directory.py:344
+#, python-format
+msgid "The directory name is invalid."
+msgstr ""
+
+#. module: muk_dms
+#: code:addons/muk_dms/models/file.py:408
+#, python-format
+msgid "The file has a forbidden file extension."
+msgstr ""
+
+#. module: muk_dms
+#: code:addons/muk_dms/models/file.py:399
+#, python-format
+msgid "The file name is invalid."
+msgstr ""
+
+#. module: muk_dms
+#: code:addons/muk_dms/models/file.py:414
+#, python-format
+msgid "The maximum upload size is %s MB)."
+msgstr ""
+
+#. module: muk_dms
+#: code:addons/muk_dms/models/directory.py:338
+#, python-format
+msgid "The parent directory has to have the permission to create directories."
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_muk_dms_storage__save_type
+msgid "The save type is used to determine how a file is saved by the system. If you change \n"
+" this setting, you can migrate existing files manually by triggering the action."
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__thumbnail
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__thumbnail
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_mixins_thumbnail__thumbnail
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_kanban
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_kanban
+msgid "Thumbnail"
+msgstr "Miniatuur"
+
+#. module: muk_dms
+#: model:ir.model,name:muk_dms.model_muk_dms_mixins_thumbnail
+msgid "Thumbnail Mixin"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__count_total_elements
+msgid "Total Elements"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__count_total_files
+msgid "Total Files"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__count_total_directories
+msgid "Total Subdirectories"
+msgstr ""
+
+#. module: muk_dms
+#: model:muk_dms.category,name:muk_dms.category_04_demo
+msgid "Traveling"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__mimetype
+msgid "Type"
+msgstr "Soort"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_form
+msgid "Unlock"
+msgstr ""
+
+#. module: muk_dms
+#. openerp-web
+#: code:addons/muk_dms/static/src/js/views/file/kanban/file_kanban_controller.js:92
+#, python-format
+msgid "Upload Error"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.onboarding_file_step
+msgid "Upload File"
+msgstr ""
+
+#. module: muk_dms
+#. openerp-web
+#: code:addons/muk_dms/static/src/js/views/mixins/file_upload.js:63
+#, python-format
+msgid "Upload Files"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.onboarding_file_step
+msgid "Upload your first File."
+msgstr ""
+
+#. module: muk_dms
+#. openerp-web
+#: code:addons/muk_dms/static/src/js/views/mixins/file_upload.js:64
+#, python-format
+msgid "Uploading..."
+msgstr ""
+
+#. module: muk_dms
+#: model:res.groups,name:muk_dms.group_dms_user
+msgid "User"
+msgstr ""
+
+#. module: muk_dms
+#: model:muk_dms.tag,name:muk_dms.tag_09_demo
+msgid "Vendor Bill"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_config_settings__module_muk_dms_version
+msgid "Versioning"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "Views"
+msgstr "Weergaven"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__permission_write
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__permission_write
+msgid "Write Access"
+msgstr "Schrijven"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.document_onboarding_directory_panel
+#: model_terms:ir.ui.view,arch_db:muk_dms.document_onboarding_file_panel
+msgid "action_close_documents_onboarding"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "exe,msi"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.document_onboarding_file_panel
+msgid "o_onboarding_blue"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.document_onboarding_directory_panel
+msgid "o_onboarding_orange"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.document_onboarding_directory_panel
+#: model_terms:ir.ui.view,arch_db:muk_dms.document_onboarding_file_panel
+msgid "res.company"
+msgstr ""
+
diff --git a/odex-event/muk_dms/i18n/pt_BR.po b/odex-event/muk_dms/i18n/pt_BR.po
new file mode 100644
index 000000000..c0989aac4
--- /dev/null
+++ b/odex-event/muk_dms/i18n/pt_BR.po
@@ -0,0 +1,1502 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * muk_dms
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 12.0-20190128\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2019-03-05 18:28+0000\n"
+"PO-Revision-Date: 2019-09-27 20:22-0300\n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n > 1);\n"
+"X-Generator: Poedit 2.2.3\n"
+"Last-Translator: \n"
+"Language: pt_BR\n"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.document_onboarding_directory_panel
+msgid "/muk_dms/static/src/img/banner/documents_onboarding_directory.png"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.document_onboarding_file_panel
+msgid "/muk_dms/static/src/img/banner/documents_onboarding_file.png"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_kanban
+msgid " Download"
+msgstr " Download"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_kanban
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_kanban
+msgid " Open"
+msgstr " Aberto"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_kanban
+msgid " Lock"
+msgstr " Trancar"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_kanban
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_kanban
+msgid " Edit"
+msgstr " Editar"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_kanban
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_kanban
+msgid " Delete"
+msgstr " Excluir"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_kanban
+msgid " Unlock"
+msgstr " Desbloquear"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "File Extensions"
+msgstr "Extensões de Arquivo"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "File Size"
+msgstr "Tamanho do Arquivo"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid ""
+"Save this page and come back here to set up the feature."
+msgstr ""
+"Salvar esta página e volte aqui para configurar a "
+"funcionalidade."
+
+#. module: muk_dms
+#: code:addons/muk_dms/models/directory.py:332
+#, python-format
+msgid "A directory can't be a root and have a parent directory."
+msgstr "Um diretório não pode ser uma raiz e ter um diretório pai."
+
+#. module: muk_dms
+#: code:addons/muk_dms/models/directory.py:330
+#, python-format
+msgid "A directory has to have a parent directory."
+msgstr "Um diretório precisa ter um diretório pai."
+
+#. module: muk_dms
+#: code:addons/muk_dms/models/directory.py:350
+#, python-format
+msgid "A directory with the same name already exists."
+msgstr "Um diretório com o mesmo nome já existe."
+
+#. module: muk_dms
+#: code:addons/muk_dms/models/directory.py:414
+#, python-format
+msgid "A file is locked, the folder cannot be deleted."
+msgstr "Um arquivo está bloqueado, a pasta não pode ser excluída."
+
+#. module: muk_dms
+#: code:addons/muk_dms/models/file.py:402
+#, python-format
+msgid "A file with the same name already exists."
+msgstr "Um arquivo com o mesmo nome já existe."
+
+#. module: muk_dms
+#: code:addons/muk_dms/models/directory.py:328
+#, python-format
+msgid "A root directory has to have a root storage."
+msgstr "Um diretório raiz precisa ter um armazenamento raiz."
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_config_settings__module_muk_dms_access
+msgid "Access Control"
+msgstr "Controle de Acesso"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_form
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_form
+msgid "Access Information"
+msgstr "Información para el acceso"
+
+#. module: muk_dms
+#: model:muk_dms.tag,name:muk_dms.tag_07_demo
+msgid "Accounting"
+msgstr "Contabilidade"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "Activates a file trash to restore deleted files"
+msgstr "Ativa uma lixeira de arquivo para restaurar arquivos apagados"
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_res_config_settings__module_muk_dms_trash
+msgid "Activates a file trash to restore deleted files."
+msgstr "Ativa uma lixeira de arquivo para restaurar arquivos apagados."
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "Activates the preview function on files"
+msgstr "Ativa a função de visualização em arquivos"
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_res_config_settings__module_muk_dms_preview
+msgid "Activates the preview function on files."
+msgstr "Ativa a função de visualização em arquivos."
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_category__active
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_tag__active
+msgid "Active"
+msgstr "Ativo"
+
+#. module: muk_dms
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_directory
+msgid "Add a new Directory."
+msgstr "Adicione um novo Diretório."
+
+#. module: muk_dms
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_file
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_file_migration
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_file_storage_migration
+msgid "Add a new File."
+msgstr "Adicione um novo Arquivo."
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "Adds support for messages and activities on directories and files"
+msgstr "Adiciona suporte para mensagens e atividades em diretórios e arquivos"
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_res_config_settings__module_muk_dms_mail
+msgid "Adds support for messages and activities on directories and files."
+msgstr "Adiciona suporte para mensagens e atividades em diretórios e arquivos."
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_category_search
+msgid "All"
+msgstr "Todos"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_file
+msgid "All Files"
+msgstr "Todos os Arquivos"
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_res_config_settings__module_muk_dms_attachment_rules
+msgid "Allows attachments to be automatically placed in the right directory."
+msgstr ""
+"Permite que os anexos sejam colocados automaticamente no diretório correto."
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "Allows attachments to be stored inside of Documents"
+msgstr "Permite que os anexos sejam armazenados dentro de documentos"
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_res_config_settings__module_muk_dms_attachment
+msgid "Allows attachments to be stored inside of Documents."
+msgstr "Permite que os anexos sejam armazenados dentro de documentos."
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_res_config_settings__module_muk_dms_attachment_wizard
+msgid "Allows documents to be used as attachments."
+msgstr "Permite que os documentos sejam usados como anexos."
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_res_config_settings__module_muk_dms_export
+msgid "Allows the conversion of existing files."
+msgstr "Permite a conversão de arquivos existentes."
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "Allows the creation of groups to define access rights"
+msgstr "Permite a criação de grupos para definir direitos de acesso"
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_res_config_settings__module_muk_dms_access
+msgid "Allows the creation of groups to define access rights."
+msgstr "Permite a criação de grupos para definir direitos de acesso."
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_res_config_settings__module_muk_dms_thumbnails
+msgid "Allows the creation of thumbnails for files."
+msgstr "Permite a criação de miniaturas para arquivos."
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_res_config_settings__module_muk_dms_widget
+msgid "Allows the user to use DMS documents as input for any binary field."
+msgstr ""
+"Permite que o usuário use documentos DMS como entrada para qualquer campo "
+"binário."
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_res_config_settings__module_muk_archive
+msgid "Allows to download directories as a archive file."
+msgstr "Permite baixar diretórios como um arquivo morto."
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "Allows to placed attachments in the right directory"
+msgstr "Permite colocar anexos no diretório certo"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "Allows you to create rule templates to create attachment rules"
+msgstr "Permite criar modelos de regra para criar regras de anexos"
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_res_config_settings__module_muk_dms_attachment_automation
+msgid "Allows you to create rule templates to create attachment rules."
+msgstr "Permite que você crie modelos de regra para criar regras de anexo."
+
+#. module: muk_dms
+#: model:muk_dms.tag,name:muk_dms.tag_06_demo
+msgid "Apps"
+msgstr "Aplicativos"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__active
+msgid "Archived"
+msgstr "Arquivado"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_config_settings__module_muk_dms_attachment_automation
+msgid "Attachment Rule Automation"
+msgstr "Automação de Regras de Anexos"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_config_settings__module_muk_dms_attachment_wizard
+msgid "Attachment Wizard"
+msgstr "Assistente de Anexos"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "Attachments"
+msgstr "Anexos"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_config_settings__module_muk_dms_thumbnails
+msgid "Automatic Thumbnails"
+msgstr "Miniaturas Automáticas"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_config_settings__module_muk_dms_widget
+msgid "Binary Widget Support"
+msgstr "Suporte a Widgets Binários"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_new_form
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_new_form
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_storage_new_form
+msgid "Cancel"
+msgstr "Cancelar"
+
+#. module: muk_dms
+#. openerp-web
+#: code:addons/muk_dms/static/src/xml/views.xml:46
+#: model:ir.actions.act_window,name:muk_dms.action_dms_category
+#: model:ir.ui.menu,name:muk_dms.menu_dms_category
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_category_search
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_category_tree
+#, python-format
+msgid "Categories"
+msgstr "Categorias"
+
+#. module: muk_dms
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_category
+msgid "Categories are used to categorize Documents."
+msgstr "As categorias são usadas para categorizar documentos."
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__category
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__category
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_directory
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_file
+msgid "Category"
+msgstr "Categoria"
+
+#. module: muk_dms
+#: sql_constraint:muk_dms.category:0
+msgid "Category name already exists!"
+msgstr "Nome da categoria já existe!"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__checksum
+msgid "Checksum/SHA1"
+msgstr ""
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_category__child_categories
+msgid "Child Categories"
+msgstr "Categorias Filhas"
+
+#. module: muk_dms
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_directories_all_directory
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_directories_directory
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_directories_storage
+msgid "Click to add a new directory."
+msgstr "Clique para adicionar um novo diretório."
+
+#. module: muk_dms
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_files_all_directory
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_files_directory
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_files_storage
+msgid "Click to add a new file."
+msgstr "Clique para adicionar um novo arquivo."
+
+#. module: muk_dms
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_tag
+msgid "Click to create a new tag."
+msgstr "Clique para criar uma nova marca."
+
+#. module: muk_dms
+#: selection:res.company,documents_onboarding_directory_state:0
+#: selection:res.company,documents_onboarding_file_state:0
+#: selection:res.company,documents_onboarding_state:0
+#: selection:res.company,documents_onboarding_storage_state:0
+msgid "Closed"
+msgstr "Fechado"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__color
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__color
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_directory
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_file
+msgid "Color"
+msgstr "Cor"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_tag__color
+msgid "Color Index"
+msgstr "Índice de Cores"
+
+#. module: muk_dms
+#: model:ir.model,name:muk_dms.model_res_company
+msgid "Companies"
+msgstr "Empresas"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__company
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__company
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_storage__company
+msgid "Company"
+msgstr "Empresa"
+
+#. module: muk_dms
+#: model:ir.model,name:muk_dms.model_res_config_settings
+msgid "Config Settings"
+msgstr "Ajuste as Configurações"
+
+#. module: muk_dms
+#: model:ir.ui.menu,name:muk_dms.cat_menu_muk_dms_config
+msgid "Configuration"
+msgstr "Configuração"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__content
+msgid "Content"
+msgstr "Conteúdo"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__content_binary
+msgid "Content Binary"
+msgstr "Conteúdo Binário"
+
+#. module: muk_dms
+#: model:muk_dms.tag,name:muk_dms.tag_11_demo
+msgid "Contract"
+msgstr "Contrato"
+
+#. module: muk_dms
+#: model:muk_dms.category,name:muk_dms.category_03_demo
+msgid "Contracts"
+msgstr "Contratos"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_storage__count_storage_directories
+msgid "Count Directories"
+msgstr "Contagem de Diretórios"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__count_elements
+msgid "Count Elements"
+msgstr "Contagem de Elementos"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__count_files
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_storage__count_storage_files
+msgid "Count Files"
+msgstr "Contagem de Arquivos"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__count_directories
+msgid "Count Subdirectories"
+msgstr "Contagem de Subdiretórios"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_new_form
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_new_form
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_storage_new_form
+msgid "Create"
+msgstr "Criar"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__permission_create
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__permission_create
+msgid "Create Access"
+msgstr "Criar Acesso"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.onboarding_directory_step
+msgid "Create Directory"
+msgstr "Criar Imóvel"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.onboarding_storage_step
+msgid "Create Storage"
+msgstr "Criar Armazenamento"
+
+#. module: muk_dms
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_category
+msgid "Create a new Category."
+msgstr "Crie uma nova Categoria."
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.onboarding_storage_step
+msgid "Create a new Document Storage."
+msgstr "Crie um novo Armazenamento de Documentos."
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.onboarding_directory_step
+msgid "Create a new Root Directory."
+msgstr "Crie um novo Diretório Raiz."
+
+#. module: muk_dms
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_storage
+msgid "Create a new Storage object."
+msgstr "Crie um novo objeto de Armazenamento."
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_category__create_uid
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__create_uid
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__create_uid
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_storage__create_uid
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_tag__create_uid
+msgid "Created by"
+msgstr "Criado por"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_category__create_date
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__create_date
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__create_date
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_storage__create_date
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_tag__create_date
+msgid "Created on"
+msgstr "Criado em"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_directory
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_file
+msgid "Creation Date"
+msgstr "Data de Criação"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__save_type
+msgid "Current Save Type"
+msgstr "Tipo de Salvamento Atual"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__custom_thumbnail
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__custom_thumbnail
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_mixins_thumbnail__custom_thumbnail
+msgid "Custom Thumbnail"
+msgstr "Miniatura Personalizada"
+
+#. module: muk_dms
+#: model:muk_dms.tag,name:muk_dms.tag_01_demo
+msgid "Customer"
+msgstr "Cliente"
+
+#. module: muk_dms
+#: model:muk_dms.tag,name:muk_dms.tag_08_demo
+msgid "Customer Invoice"
+msgstr "Fatura do Cliente"
+
+#. module: muk_dms
+#: code:addons/muk_dms/models/storage.py:42
+#: selection:muk_dms.storage,save_type:0
+#, python-format
+msgid "Database"
+msgstr "Banco de dados"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "Define forbidden file extensions"
+msgstr "Definir extensões de arquivo proibidas"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "Define the maximum upload size of a file in MB"
+msgstr "Definir o tamanho máximo de upload de um arquivo em MB"
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_res_config_settings__documents_forbidden_extensions
+msgid "Defines a list of forbidden file extensions. (Example: 'exe,msi')"
+msgstr ""
+"Define uma lista de extensões de arquivo proibidas. (Exemplo: 'exe,msi')"
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_res_config_settings__documents_binary_max_size
+msgid "Defines the maximum upload size in MB. Default (25MB)"
+msgstr "Define o tamanho máximo de carregamento em MB. Padrão (25MB)"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__permission_unlink
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__permission_unlink
+msgid "Delete Access"
+msgstr "Excluir Acesso"
+
+#. module: muk_dms
+#. openerp-web
+#: code:addons/muk_dms/static/src/xml/views.xml:37
+#: model:ir.actions.act_window,name:muk_dms.action_dms_directories_storage
+#: model:ir.actions.act_window,name:muk_dms.action_dms_directory
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_category__directories
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_storage__storage_directories
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_tag__directories
+#: model:ir.ui.menu,name:muk_dms.menu_dms_directory
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_file
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_form
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_tree
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_storage_form
+#, python-format
+msgid "Directories"
+msgstr "Diretórios"
+
+#. module: muk_dms
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_directories_all_directory
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_directories_directory
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_directories_storage
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_directory
+msgid ""
+"Directories can be used to structure and organize\n"
+"\t\t\tfiles directly in Odoo."
+msgstr ""
+"Os diretórios podem ser usados para estruturar e organizar\n"
+"\t\t\tarquivos diretamente no Odoo."
+
+#. module: muk_dms
+#: model:ir.model,name:muk_dms.model_muk_dms_directory
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__directory
+#: model_terms:ir.ui.view,arch_db:muk_dms.onboarding_directory_step
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_form
+msgid "Directory"
+msgstr "Diretório"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_category__display_name
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__display_name
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__display_name
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_mixins_thumbnail__display_name
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_storage__display_name
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_tag__display_name
+msgid "Display Name"
+msgstr "Nome de Exibição"
+
+#. module: muk_dms
+#: model:ir.model,name:muk_dms.model_muk_dms_category
+msgid "Document Category"
+msgstr "Categoria do Documento"
+
+#. module: muk_dms
+#: model:ir.model,name:muk_dms.model_muk_dms_tag
+msgid "Document Tag"
+msgstr "Tag do Documento"
+
+#. module: muk_dms
+#: model:ir.module.category,name:muk_dms.category_dms_security
+#: model:ir.ui.menu,name:muk_dms.main_menu_muk_dms
+msgid "Documents"
+msgstr "Documentos"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_company__documents_onboarding_directory_state
+msgid "Documents Onboarding Directory State"
+msgstr "Estado do Diretório de Integração de Documentos"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_company__documents_onboarding_file_state
+msgid "Documents Onboarding File State"
+msgstr "Estado do Arquivo de Integração de Documentos"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_company__documents_onboarding_state
+msgid "Documents Onboarding State"
+msgstr "Estado de Integração de Documentos"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_company__documents_onboarding_storage_state
+msgid "Documents Onboarding Storage State"
+msgstr "Estado de Armazenamento de Documentos de Integração"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_config_settings__module_muk_dms_attachment
+msgid "Documents Storage Location"
+msgstr "Local de Armazenamento de Documentos"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_config_settings__module_muk_dms_attachment_rules
+msgid "Documents Storage Rules"
+msgstr "Regras de Armazenamento de Documentos"
+
+#. module: muk_dms
+#: selection:res.company,documents_onboarding_directory_state:0
+#: selection:res.company,documents_onboarding_file_state:0
+#: selection:res.company,documents_onboarding_state:0
+#: selection:res.company,documents_onboarding_storage_state:0
+msgid "Done"
+msgstr "Feito"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_config_settings__module_muk_archive
+msgid "Download Directories"
+msgstr "Baixar Diretórios"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_kanban
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_kanban
+msgid "Dropdown menu"
+msgstr "Menu dropdown"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__is_lock_editor
+msgid "Editor"
+msgstr "Editor"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_form
+msgid "Elements"
+msgstr "Elementos"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "Enables a new save option to store files into a filestore"
+msgstr ""
+"Habilita uma nova opção de salvamento para armazenar arquivos em um "
+"armazenamento arquivos"
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_res_config_settings__module_muk_dms_file
+msgid "Enables a new save option to store files into a filestore."
+msgstr ""
+"Habilita uma nova opção de salvamento para armazenar arquivos em um "
+"armazenamento de registros."
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "Enables a new save option to store files into large objects"
+msgstr ""
+"Habilita uma nova opção de salvamento para armazenar arquivos em objetos "
+"grandes"
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_res_config_settings__module_muk_dms_lobject
+msgid "Enables a new save option to store files into large objects."
+msgstr ""
+"Habilita uma nova opção de salvamento para armazenar arquivos em objetos "
+"grandes."
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_res_config_settings__module_muk_dms_finder
+msgid "Enables the Document Finder."
+msgstr "Habilita o Localizador de Documentos."
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "Enables version control for files"
+msgstr "Habilita o controle de versão para arquivos"
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_res_config_settings__module_muk_dms_version
+msgid "Enables version control for files."
+msgstr "Habilita o controle de versão para arquivos."
+
+#. module: muk_dms
+#: code:addons/muk_dms/models/category.py:123
+#, python-format
+msgid "Error! You cannot create recursive categories."
+msgstr "Erro! Não é possível criar categorias recursivas."
+
+#. module: muk_dms
+#: code:addons/muk_dms/models/directory.py:321
+#, python-format
+msgid "Error! You cannot create recursive directories."
+msgstr "Erro! Não é possível criar diretórios recursivos."
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_config_settings__module_muk_dms_export
+msgid "Export Files"
+msgstr "Exportar arquivos"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__extension
+msgid "Extension"
+msgstr "Extensão"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_config_settings__documents_forbidden_extensions
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "Extensions"
+msgstr "Extensões"
+
+#. module: muk_dms
+#: model:muk_dms.category,name:muk_dms.category_05_demo
+msgid "External"
+msgstr "Externo"
+
+#. module: muk_dms
+#: model:ir.model,name:muk_dms.model_muk_dms_file
+#: model_terms:ir.ui.view,arch_db:muk_dms.onboarding_file_step
+msgid "File"
+msgstr "Arquivo"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_config_settings__module_muk_dms_preview
+msgid "File Preview"
+msgstr "Visualização de Arquivo"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "File Upload"
+msgstr "Upload de Arquivo"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__name
+msgid "Filename"
+msgstr "Nome do arquivo"
+
+#. module: muk_dms
+#: model:ir.actions.act_window,name:muk_dms.action_dms_file
+#: model:ir.actions.act_window,name:muk_dms.action_dms_file_migration
+#: model:ir.actions.act_window,name:muk_dms.action_dms_file_storage_migration
+#: model:ir.actions.act_window,name:muk_dms.action_dms_files_all_directory
+#: model:ir.actions.act_window,name:muk_dms.action_dms_files_directory
+#: model:ir.actions.act_window,name:muk_dms.action_dms_files_storage
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_category__files
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__files
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_storage__storage_files
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_tag__files
+#: model:ir.ui.menu,name:muk_dms.menu_dms_file
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_form
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_tree
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_form
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_migration_tree
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_tree
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_storage_form
+msgid "Files"
+msgstr "Arquivos"
+
+#. module: muk_dms
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_file
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_file_migration
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_file_storage_migration
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_files_all_directory
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_files_directory
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_files_storage
+msgid "Files are used to save content directly in Odoo."
+msgstr "Os arquivos são usados para salvar conteúdo diretamente no Odoo."
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_config_settings__module_muk_dms_file
+msgid "Filestore Storage"
+msgstr "Armazenamento de Filestore"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_config_settings__module_muk_dms_finder
+msgid "Finder"
+msgstr "Buscador"
+
+#. module: muk_dms
+#: model:ir.actions.act_window,name:muk_dms.action_dms_settings_general
+#: model:ir.ui.menu,name:muk_dms.menu_dms_settings_general
+msgid "General Settings"
+msgstr "Configurações Gerais"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_directory
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_file
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_file_migration
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_storage_search
+msgid "Group By"
+msgstr "Agrupar por"
+
+#. module: muk_dms
+#: model:ir.model,name:muk_dms.model_ir_http
+msgid "HTTP Routing"
+msgstr "Roteamento HTTP"
+
+#. module: muk_dms
+#: model:muk_dms.category,name:muk_dms.category_02_demo
+msgid "Human Resource"
+msgstr "Recursos Humanos"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_category__id
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__id
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__id
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_mixins_thumbnail__id
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_storage__id
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_tag__id
+msgid "ID"
+msgstr "ID"
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_muk_dms_file__active
+msgid "If a file is set to archived, it is not displayed, but still exists."
+msgstr ""
+"Se um arquivo for definido como arquivado, ele não será exibido, mas ainda "
+"existirá."
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_muk_dms_directory__company
+#: model:ir.model.fields,help:muk_dms.field_muk_dms_file__company
+#: model:ir.model.fields,help:muk_dms.field_muk_dms_storage__company
+msgid ""
+"If set, directories and files will only be available for the selected "
+"company."
+msgstr ""
+"Se definido, diretórios e arquivos só estarão disponíveis para a empresa "
+"selecionada."
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_muk_dms_directory__is_hidden
+#: model:ir.model.fields,help:muk_dms.field_muk_dms_file__is_hidden
+#: model:ir.model.fields,help:muk_dms.field_muk_dms_storage__is_hidden
+msgid "Indicates if directories and files are hidden by default."
+msgstr "Indica se os diretórios e arquivos estão ocultos por padrão."
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_muk_dms_directory__is_root_directory
+msgid ""
+"Indicates if the directory is a root directory. A root directory has a "
+"settings object,\n"
+" while a directory with a set parent inherits the settings form "
+"its parent."
+msgstr ""
+"Indica se o diretório é um diretório raiz. Um diretório raiz tem um objeto "
+"de configurações,\n"
+" enquanto um diretório com um pai definido herda as configurações "
+"formam seu pai."
+
+#. module: muk_dms
+#: model:muk_dms.category,name:muk_dms.category_01_demo
+msgid "Internal"
+msgstr "Interno"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_form
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_new_form
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_form
+msgid "Internal / Human Resource"
+msgstr "Recursos Internos/Humanos"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__is_root_directory
+msgid "Is Root Directory"
+msgstr "É o Diretório Raiz"
+
+#. module: muk_dms
+#: selection:res.company,documents_onboarding_directory_state:0
+#: selection:res.company,documents_onboarding_file_state:0
+#: selection:res.company,documents_onboarding_state:0
+#: selection:res.company,documents_onboarding_storage_state:0
+msgid "Just done"
+msgstr "Acabei de fazer"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_config_settings__module_muk_dms_lobject
+msgid "Large Objects Storage"
+msgstr "Armazenamento de Objetos Grandes"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_category____last_update
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory____last_update
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file____last_update
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_mixins_thumbnail____last_update
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_storage____last_update
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_tag____last_update
+msgid "Last Modified on"
+msgstr "Modificada pela última vez"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_category__write_uid
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__write_uid
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__write_uid
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_storage__write_uid
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_tag__write_uid
+msgid "Last Updated by"
+msgstr "Ultima atualização por"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_category__write_date
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__write_date
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__write_date
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_storage__write_date
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_tag__write_date
+msgid "Last Updated on"
+msgstr "Ultima atualização em"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_form
+msgid "Lock"
+msgstr "Bloquear"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__is_locked
+msgid "Locked"
+msgstr "Bloqueado"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__locked_by
+msgid "Locked by"
+msgstr "Bloqueado por"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_config_settings__module_muk_dms_mail
+msgid "Mail Support"
+msgstr "Suporte de Correio"
+
+#. module: muk_dms
+#: model:res.groups,name:muk_dms.group_dms_manager
+msgid "Manager"
+msgstr "Gerente"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_storage_form
+msgid "Manual File Migration"
+msgstr "Migração Manual de Arquivos"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__custom_thumbnail_medium
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__custom_thumbnail_medium
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_mixins_thumbnail__custom_thumbnail_medium
+msgid "Medium Custom Thumbnail"
+msgstr "Miniatura Personalizada Média"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__thumbnail_medium
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__thumbnail_medium
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_mixins_thumbnail__thumbnail_medium
+msgid "Medium Thumbnail"
+msgstr "Miniatura Média"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_form
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_form
+msgid "Meta Information"
+msgstr "Meta informação"
+
+#. module: muk_dms
+#: model:ir.actions.server,name:muk_dms.action_dms_attachment_migrate
+msgid "Migrate"
+msgstr "Migrar"
+
+#. module: muk_dms
+#: code:addons/muk_dms/models/file.py:221
+#, python-format
+msgid "Migrate File %s of %s [ %s ]"
+msgstr "Migrar Arquivo %s de %s [ %s]"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_storage_form
+msgid "Migrate Files"
+msgstr "Migrar Arquivos"
+
+#. module: muk_dms
+#: model:ir.ui.menu,name:muk_dms.menu_dms_file_migration
+msgid "Migration"
+msgstr "Migração"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__migration
+msgid "Migration Status"
+msgstr "Status da Migração"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_directory
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_file
+msgid "Modification Date"
+msgstr "Data de modificação"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_directory
+msgid "My Directories"
+msgstr "Meus Diretórios"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_form
+msgid "My Documents"
+msgstr "Meus Documentos"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_file
+msgid "My Files"
+msgstr "Meus Arquivos"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_category__name
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__name
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_storage__name
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_tag__name
+msgid "Name"
+msgstr "Nome"
+
+#. module: muk_dms
+#: model:ir.actions.act_window,name:muk_dms.action_dms_directory_new
+#: model:ir.actions.act_window,name:muk_dms.action_dms_file_new
+msgid "New Root Directory"
+msgstr "Novo Diretório Raiz"
+
+#. module: muk_dms
+#: model:ir.actions.act_window,name:muk_dms.action_dms_storage_new
+msgid "New Storage"
+msgstr "Novo Armazenamento"
+
+#. module: muk_dms
+#: model:muk_dms.category,name:muk_dms.category_06_demo
+msgid "News"
+msgstr "Notícias"
+
+#. module: muk_dms
+#. openerp-web
+#: code:addons/muk_dms/static/src/js/views/file/kanban/file_kanban_controller.js:92
+#, python-format
+msgid "No Directory has been selected!"
+msgstr "Nenhum diretório foi selecionado!"
+
+#. module: muk_dms
+#: selection:res.company,documents_onboarding_directory_state:0
+#: selection:res.company,documents_onboarding_file_state:0
+#: selection:res.company,documents_onboarding_state:0
+#: selection:res.company,documents_onboarding_storage_state:0
+msgid "Not done"
+msgstr "Não feito"
+
+#. module: muk_dms
+#: code:addons/muk_dms/models/storage.py:99
+#, python-format
+msgid "Only managers can execute this action."
+msgstr "Somente os gerentes podem executar essa ação."
+
+#. module: muk_dms
+#: model:ir.ui.menu,name:muk_dms.cat_menu_muk_dms_config_organizing
+msgid "Organizing"
+msgstr "Organização"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_category__parent_category
+msgid "Parent Category"
+msgstr "Categoria Pai"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__parent_directory
+msgid "Parent Directory"
+msgstr "Diretório Pai"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_category__parent_path
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__parent_path
+msgid "Parent Path"
+msgstr "Caminho Pai"
+
+#. module: muk_dms
+#: model:muk_dms.tag,name:muk_dms.tag_02_demo
+msgid "Partner"
+msgstr "Parceiro"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_tree
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_tree
+msgid "Path"
+msgstr "Caminho"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_category__parent_path_json
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__parent_path_json
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__path_json
+msgid "Path Json"
+msgstr "Caminho JSON"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_category__parent_path_names
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__parent_path_names
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__path_names
+msgid "Path Names"
+msgstr "Nomes de Caminho"
+
+#. module: muk_dms
+#: model:muk_dms.tag,name:muk_dms.tag_05_demo
+msgid "Portal"
+msgstr "Portál"
+
+#. module: muk_dms
+#: model:muk_dms.tag,name:muk_dms.tag_10_demo
+msgid "Product"
+msgstr "Produto"
+
+#. module: muk_dms
+#: model:muk_dms.tag,name:muk_dms.tag_03_demo
+msgid "Project"
+msgstr "Projeto"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__permission_read
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__permission_read
+msgid "Read Access"
+msgstr "Acesso de Leitura"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_config_settings__module_muk_dms_trash
+msgid "Restore Files"
+msgstr "Restaurar Arquivos"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_storage__root_directories
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_directory
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_storage_form
+msgid "Root Directories"
+msgstr "Diretórios Raiz"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__root_storage
+msgid "Root Storage"
+msgstr "Armazenamento Raiz"
+
+#. module: muk_dms
+#: model:muk_dms.tag,name:muk_dms.tag_04_demo
+msgid "Sales"
+msgstr "Vendas"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_storage__save_type
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_storage_search
+msgid "Save Type"
+msgstr "Salvar Tipo"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__size
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__size
+#: model:ir.model.fields,field_description:muk_dms.field_res_config_settings__documents_binary_max_size
+msgid "Size"
+msgstr "Tamanho"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__custom_thumbnail_small
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__custom_thumbnail_small
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_mixins_thumbnail__custom_thumbnail_small
+msgid "Small Custom Thumbnail"
+msgstr "Miniatura Personalizada Pequena"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__thumbnail_small
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__thumbnail_small
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_mixins_thumbnail__thumbnail_small
+msgid "Small Thumbnail"
+msgstr "Miniatura pequena"
+
+#. module: muk_dms
+#. openerp-web
+#: code:addons/muk_dms/static/src/xml/views.xml:28
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__starred
+#, python-format
+msgid "Starred"
+msgstr "Favoritos"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_directory
+msgid "Starred Directories"
+msgstr "Diretórios Favoritos"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__user_stars
+msgid "Stars"
+msgstr "Estrelas"
+
+#. module: muk_dms
+#: model:ir.model,name:muk_dms.model_muk_dms_storage
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__storage
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__storage
+#: model_terms:ir.ui.view,arch_db:muk_dms.onboarding_storage_step
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_directory
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_file
+#: model_terms:ir.ui.view,arch_db:muk_dms.search_dms_file_migration
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_storage_form
+msgid "Storage"
+msgstr "Armazenamento"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__is_hidden
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__is_hidden
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_storage__is_hidden
+msgid "Storage is Hidden"
+msgstr "O Armazenamento está Oculto"
+
+#. module: muk_dms
+#: model:ir.actions.act_window,name:muk_dms.action_dms_storage
+#: model:ir.ui.menu,name:muk_dms.menu_dms_storage
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_storage_tree
+msgid "Storages"
+msgstr "Armazenamentos"
+
+#. module: muk_dms
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_storage
+msgid "Storages are used to configure your Documents."
+msgstr "Os armazenamentos são usados para configurar seus Documentos."
+
+#. module: muk_dms
+#: model:ir.actions.act_window,name:muk_dms.action_dms_directories_all_directory
+#: model:ir.actions.act_window,name:muk_dms.action_dms_directories_directory
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__child_directories
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_form
+msgid "Subdirectories"
+msgstr "Subdiretórios"
+
+#. module: muk_dms
+#: model:ir.ui.menu,name:muk_dms.cat_menu_muk_dms_config_system
+msgid "System"
+msgstr "Sistema"
+
+#. module: muk_dms
+#: sql_constraint:muk_dms.tag:0
+msgid "Tag name already exists!"
+msgstr "Nome do Marcdor já existe!"
+
+#. module: muk_dms
+#. openerp-web
+#: code:addons/muk_dms/static/src/xml/views.xml:55
+#: model:ir.actions.act_window,name:muk_dms.action_dms_tag
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__tags
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__tags
+#: model:ir.ui.menu,name:muk_dms.menu_dms_tag
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_tag_tree
+#, python-format
+msgid "Tags"
+msgstr "Marcadores"
+
+#. module: muk_dms
+#: model_terms:ir.actions.act_window,help:muk_dms.action_dms_tag
+msgid "Tags are used to categorize Documents."
+msgstr "Os marcadores são usadas para categorizar documentos."
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_form
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_new_form
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_form
+msgid "Tags..."
+msgstr "Marcadores..."
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_form
+msgid "Technical Information"
+msgstr "Informação técnica"
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_muk_dms_category__active
+msgid "The active field allows you to hide the category without removing it."
+msgstr "O campo ativo permite que você oculte a categoria sem removê-la."
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_muk_dms_tag__active
+msgid "The active field allows you to hide the tag without removing it."
+msgstr "O campo ativo permite que você oculte a marca sem removê-la."
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.document_onboarding_directory_panel
+#: model_terms:ir.ui.view,arch_db:muk_dms.document_onboarding_file_panel
+msgid "The configuration is done!"
+msgstr "A configuração está feita!"
+
+#. module: muk_dms
+#: code:addons/muk_dms/models/file.py:420
+#, python-format
+msgid "The directory has to have the permission to create files."
+msgstr "O diretório tem que ter a permissão para criar arquivos."
+
+#. module: muk_dms
+#: code:addons/muk_dms/models/directory.py:344
+#, python-format
+msgid "The directory name is invalid."
+msgstr "O nome do diretório é inválido."
+
+#. module: muk_dms
+#: code:addons/muk_dms/models/file.py:408
+#, python-format
+msgid "The file has a forbidden file extension."
+msgstr "O arquivo tem uma extensão de arquivo proibida."
+
+#. module: muk_dms
+#: code:addons/muk_dms/models/file.py:399
+#, python-format
+msgid "The file name is invalid."
+msgstr "O nome do arquivo é inválido."
+
+#. module: muk_dms
+#: code:addons/muk_dms/models/file.py:414
+#, python-format
+msgid "The maximum upload size is %s MB)."
+msgstr "O tamanho máximo de upload é %s MB)."
+
+#. module: muk_dms
+#: code:addons/muk_dms/models/directory.py:338
+#, python-format
+msgid "The parent directory has to have the permission to create directories."
+msgstr "O diretório pai precisa ter a permissão para criar diretórios."
+
+#. module: muk_dms
+#: model:ir.model.fields,help:muk_dms.field_muk_dms_storage__save_type
+msgid ""
+"The save type is used to determine how a file is saved by the system. If you "
+"change \n"
+" this setting, you can migrate existing files manually by "
+"triggering the action."
+msgstr ""
+"O tipo de salvamento é usado para determinar como um arquivo é salvo pelo "
+"sistema. Se você alterar \n"
+" Essa configuração, você pode migrar arquivos existentes "
+"manualmente, acionando a ação."
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__thumbnail
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__thumbnail
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_mixins_thumbnail__thumbnail
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_directory_kanban
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_kanban
+msgid "Thumbnail"
+msgstr "Miniatura"
+
+#. module: muk_dms
+#: model:ir.model,name:muk_dms.model_muk_dms_mixins_thumbnail
+msgid "Thumbnail Mixin"
+msgstr "Mixin Miniatura"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__count_total_elements
+msgid "Total Elements"
+msgstr "Total de Elementos"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__count_total_files
+msgid "Total Files"
+msgstr "Total de arquivos"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__count_total_directories
+msgid "Total Subdirectories"
+msgstr "Total de Subdiretórios"
+
+#. module: muk_dms
+#: model:muk_dms.category,name:muk_dms.category_04_demo
+msgid "Traveling"
+msgstr "Viajando"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__mimetype
+msgid "Type"
+msgstr "Tipo"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.view_dms_file_form
+msgid "Unlock"
+msgstr "Desbloquear"
+
+#. module: muk_dms
+#. openerp-web
+#: code:addons/muk_dms/static/src/js/views/file/kanban/file_kanban_controller.js:92
+#, python-format
+msgid "Upload Error"
+msgstr "Erro de upload"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.onboarding_file_step
+msgid "Upload File"
+msgstr "Enviar Arquivo"
+
+#. module: muk_dms
+#. openerp-web
+#: code:addons/muk_dms/static/src/js/views/mixins/file_upload.js:63
+#, python-format
+msgid "Upload Files"
+msgstr "Enviar Arquivos"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.onboarding_file_step
+msgid "Upload your first File."
+msgstr "Carregue o seu primeiro arquivo."
+
+#. module: muk_dms
+#. openerp-web
+#: code:addons/muk_dms/static/src/js/views/mixins/file_upload.js:64
+#, python-format
+msgid "Uploading..."
+msgstr "Enviando..."
+
+#. module: muk_dms
+#: model:res.groups,name:muk_dms.group_dms_user
+msgid "User"
+msgstr "Usuário"
+
+#. module: muk_dms
+#: model:muk_dms.tag,name:muk_dms.tag_09_demo
+msgid "Vendor Bill"
+msgstr "Conta de Fornecedor"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_res_config_settings__module_muk_dms_version
+msgid "Versioning"
+msgstr "Versionamento"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "Views"
+msgstr "Visualizações"
+
+#. module: muk_dms
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_directory__permission_write
+#: model:ir.model.fields,field_description:muk_dms.field_muk_dms_file__permission_write
+msgid "Write Access"
+msgstr "Acesso de Gravação"
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.document_onboarding_directory_panel
+#: model_terms:ir.ui.view,arch_db:muk_dms.document_onboarding_file_panel
+msgid "action_close_documents_onboarding"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.res_config_settings_view_form
+msgid "exe,msi"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.document_onboarding_file_panel
+msgid "o_onboarding_blue"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.document_onboarding_directory_panel
+msgid "o_onboarding_orange"
+msgstr ""
+
+#. module: muk_dms
+#: model_terms:ir.ui.view,arch_db:muk_dms.document_onboarding_directory_panel
+#: model_terms:ir.ui.view,arch_db:muk_dms.document_onboarding_file_panel
+msgid "res.company"
+msgstr ""
diff --git a/odex-event/muk_dms/models/__init__.py b/odex-event/muk_dms/models/__init__.py
new file mode 100644
index 000000000..b1a5bfc33
--- /dev/null
+++ b/odex-event/muk_dms/models/__init__.py
@@ -0,0 +1,35 @@
+###################################################################################
+#
+# Copyright (c) 2017-2019 MuK IT GmbH.
+#
+# This file is part of MuK Documents
+# (see https://mukit.at).
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see .
+#
+###################################################################################
+
+from . import mixins_thumbnail
+
+from . import storage
+from . import directory
+from . import file
+
+from . import category
+from . import tag
+
+from . import ir_http
+from . import res_company
+from . import res_config_settings
+
diff --git a/odex-event/muk_dms/models/category.py b/odex-event/muk_dms/models/category.py
new file mode 100644
index 000000000..aa5b481e0
--- /dev/null
+++ b/odex-event/muk_dms/models/category.py
@@ -0,0 +1,151 @@
+###################################################################################
+#
+# Copyright (c) 2017-2019 MuK IT GmbH.
+#
+# This file is part of MuK Documents
+# (see https://mukit.at).
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see .
+#
+###################################################################################
+
+import logging
+
+from odoo import models, api, fields
+
+_logger = logging.getLogger(__name__)
+
+class Category(models.Model):
+
+ _name = 'muk_dms.category'
+ _description = "Document Category"
+
+ _inherit = [
+ 'muk_utils.mixins.hierarchy',
+ ]
+
+ _order = "name asc"
+
+ _parent_store = True
+ _parent_name = "parent_category"
+
+ _parent_path_sudo = False
+ _parent_path_store = True
+
+ _name_path_context = "dms_category_show_path"
+
+ #----------------------------------------------------------
+ # Database
+ #----------------------------------------------------------
+
+ name = fields.Char(
+ string='Name',
+ required=True,
+ translate=True)
+
+ active = fields.Boolean(
+ default=True,
+ help="The active field allows you to hide the category without removing it.")
+
+ parent_category = fields.Many2one(
+ comodel_name='muk_dms.category',
+ context="{'dms_category_show_path': True}",
+ string='Parent Category',
+ ondelete='cascade',
+ index=True)
+
+ child_categories = fields.One2many(
+ comodel_name='muk_dms.category',
+ inverse_name='parent_category',
+ string='Child Categories')
+
+ parent_path = fields.Char(
+ string="Parent Path",
+ index=True)
+
+ tags = fields.One2many(
+ comodel_name='muk_dms.tag',
+ inverse_name='category',
+ string='Tags')
+
+ directories = fields.One2many(
+ comodel_name='muk_dms.directory',
+ inverse_name='category',
+ string='Directories',
+ readonly=True)
+
+ files = fields.One2many(
+ comodel_name='muk_dms.file',
+ inverse_name='category',
+ string='Files',
+ readonly=True)
+
+ count_categories = fields.Integer(
+ compute='_compute_count_categories',
+ string="Count Subcategories")
+
+ count_tags = fields.Integer(
+ compute='_compute_count_tags',
+ string="Count Tags")
+
+ count_directories = fields.Integer(
+ compute='_compute_count_directories',
+ string="Count Directories")
+
+ count_files = fields.Integer(
+ compute='_compute_count_files',
+ string="Count Files")
+
+ #----------------------------------------------------------
+ # Constrains
+ #----------------------------------------------------------
+
+ _sql_constraints = [
+ ('name_uniq', 'unique (name)', "Category name already exists!"),
+ ]
+
+ #----------------------------------------------------------
+ # Read
+ #----------------------------------------------------------
+
+ @api.depends('child_categories')
+ def _compute_count_categories(self):
+ for record in self:
+ record.count_categories = len(record.child_categories)
+
+ @api.depends('tags')
+ def _compute_count_tags(self):
+ for record in self:
+ record.count_tags = len(record.tags)
+
+ @api.depends('directories')
+ def _compute_count_directories(self):
+ for record in self:
+ record.count_directories = len(record.directories)
+
+ @api.depends('files')
+ def _compute_count_files(self):
+ for record in self:
+ record.count_files = len(record.files)
+
+ #----------------------------------------------------------
+ # Create
+ #----------------------------------------------------------
+
+ @api.constrains('parent_category')
+ def _check_category_recursion(self):
+ if not self._check_recursion():
+ raise ValidationError(_('Error! You cannot create recursive categories.'))
+ return True
+
\ No newline at end of file
diff --git a/odex-event/muk_dms/models/directory.py b/odex-event/muk_dms/models/directory.py
new file mode 100644
index 000000000..534820f6d
--- /dev/null
+++ b/odex-event/muk_dms/models/directory.py
@@ -0,0 +1,466 @@
+###################################################################################
+#
+# Copyright (c) 2017-2019 MuK IT GmbH.
+#
+# This file is part of MuK Documents
+# (see https://mukit.at).
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see .
+#
+###################################################################################
+
+import os
+import json
+import base64
+import logging
+import functools
+
+from collections import defaultdict
+
+from odoo import _, models, api, fields, tools
+from odoo.modules.module import get_resource_path
+from odoo.exceptions import ValidationError, AccessError
+from odoo.osv import expression
+
+from odoo.addons.muk_utils.tools import file
+
+_logger = logging.getLogger(__name__)
+
+class Directory(models.Model):
+
+ _name = 'muk_dms.directory'
+ _description = "Directory"
+
+ _inherit = [
+ 'muk_utils.mixins.hierarchy',
+ 'muk_security.mixins.access_rights',
+ 'muk_dms.mixins.thumbnail',
+ ]
+
+ _order = "name asc"
+
+ _parent_store = True
+ _parent_name = "parent_directory"
+
+ _parent_path_sudo = False
+ _parent_path_store = False
+
+ _name_path_context = "dms_directory_show_path"
+
+ #----------------------------------------------------------
+ # Database
+ #----------------------------------------------------------
+
+ name = fields.Char(
+ string="Name",
+ required=True,
+ index=True)
+
+ is_root_directory = fields.Boolean(
+ string="Is Root Directory",
+ default=False,
+ help="""Indicates if the directory is a root directory. A root directory has a settings object,
+ while a directory with a set parent inherits the settings form its parent.""")
+
+ root_storage = fields.Many2one(
+ comodel_name='muk_dms.storage',
+ string="Root Storage",
+ ondelete='restrict')
+
+ storage = fields.Many2one(
+ compute='_compute_storage',
+ comodel_name='muk_dms.storage',
+ string="Storage",
+ ondelete='restrict',
+ auto_join=True,
+ readonly=True,
+ store=True)
+
+ parent_directory = fields.Many2one(
+ comodel_name='muk_dms.directory',
+ domain="""[('permission_create', '=', True)]""",
+ context="{'dms_directory_show_path': True}",
+ string="Parent Directory",
+ ondelete='restrict',
+ auto_join=True,
+ index=True)
+
+ child_directories = fields.One2many(
+ comodel_name='muk_dms.directory',
+ inverse_name='parent_directory',
+ string="Subdirectories",
+ auto_join=False,
+ copy=False)
+
+ is_hidden = fields.Boolean(
+ string="Storage is Hidden",
+ related="storage.is_hidden",
+ readonly=True)
+
+ company = fields.Many2one(
+ related="storage.company",
+ comodel_name='res.company',
+ string='Company',
+ readonly=True,
+ store=True,
+ index=True)
+
+ color = fields.Integer(
+ string="Color",
+ default=0)
+
+ category = fields.Many2one(
+ comodel_name='muk_dms.category',
+ context="{'dms_category_show_path': True}",
+ string="Category")
+
+ tags = fields.Many2many(
+ comodel_name='muk_dms.tag',
+ relation='muk_dms_directory_tag_rel',
+ domain="""[
+ '|', ['category', '=', False],
+ ['category', 'child_of', category]]
+ """,
+ column1='did',
+ column2='tid',
+ string='Tags')
+
+ user_stars = fields.Many2many(
+ comodel_name='res.users',
+ relation='muk_dms_directory_star_rel',
+ column1='did',
+ column2='uid',
+ string='Stars')
+
+ starred = fields.Boolean(
+ compute='_compute_starred',
+ inverse='_inverse_starred',
+ search='_search_starred',
+ string="Starred")
+
+ files = fields.One2many(
+ comodel_name='muk_dms.file',
+ inverse_name='directory',
+ string="Files",
+ auto_join=False,
+ copy=False)
+
+ count_directories = fields.Integer(
+ compute='_compute_count_directories',
+ string="Count Subdirectories")
+
+ count_files = fields.Integer(
+ compute='_compute_count_files',
+ string="Count Files")
+
+ count_elements = fields.Integer(
+ compute='_compute_count_elements',
+ string="Count Elements")
+
+ count_total_directories = fields.Integer(
+ compute='_compute_count_total_directories',
+ string="Total Subdirectories")
+
+ count_total_files = fields.Integer(
+ compute='_compute_count_total_files',
+ string="Total Files")
+
+ count_total_elements = fields.Integer(
+ compute='_compute_count_total_elements',
+ string="Total Elements")
+
+ size = fields.Integer(
+ compute='_compute_size',
+ string="Size")
+
+ #----------------------------------------------------------
+ # Functions
+ #----------------------------------------------------------
+
+
+ def toggle_starred(self):
+ updates = defaultdict(set)
+ for record in self:
+ vals = {'starred': not record.starred}
+ updates[tools.frozendict(vals)].add(record.id)
+ with self.env.norecompute():
+ for vals, ids in updates.items():
+ self.browse(ids).write(dict(vals))
+ self.recompute()
+
+ #----------------------------------------------------------
+ # Actions
+ #----------------------------------------------------------
+
+
+ def action_save_onboarding_directory_step(self):
+ self.env.user.company_id.set_onboarding_step_done(
+ 'documents_onboarding_directory_state'
+ )
+
+ #----------------------------------------------------------
+ # SearchPanel
+ #----------------------------------------------------------
+
+ @api.model
+ def _search_panel_directory(self, **kwargs):
+ search_domain = kwargs.get('search_domain', []),
+ if search_domain and len(search_domain):
+ for domain in search_domain[0]:
+ if domain[0] == 'parent_directory':
+ return domain[1], domain[2]
+ return None, None
+
+ @api.model
+ def search_panel_select_multi_range(self, field_name, **kwargs):
+ operator, directory_id = self._search_panel_directory(**kwargs)
+ if field_name == 'tags':
+ sql_query = '''
+ SELECT t.name AS name, t.id AS id, c.name AS group_name,
+ c.id AS group_id, COUNT(r.did) AS count
+ FROM muk_dms_tag t
+ JOIN muk_dms_category c ON t.category = c.id
+ LEFT JOIN muk_dms_directory_tag_rel r ON t.id = r.tid
+ {directory_where_clause}
+ GROUP BY c.name, c.id, t.name, t.id
+ ORDER BY c.name, c.id, t.name, t.id;
+ '''
+ where_clause = ''
+ if directory_id:
+ directory_ids = [directory_id]
+ if operator == 'child_of':
+ directory_ids = self.search([('id', operator, directory_id)]).ids
+ directory_where_clause = 'WHERE r.did = ANY (VALUES {ids})'
+ where_clause = '' if not directory_ids else directory_where_clause.format(
+ ids=', '.join(map(lambda id: '(%s)' % id, directory_ids))
+ )
+ self.env.cr.execute(sql_query.format(directory_where_clause=where_clause), [])
+ return self.env.cr.dictfetchall()
+ if directory_id and field_name == 'category':
+ comodel_domain = kwargs.pop('comodel_domain', [])
+ domain = [('directories', operator, directory_id)]
+ comodel_domain = expression.AND([comodel_domain, domain])
+ return super(Directory, self).search_panel_select_multi_range(
+ field_name, comodel_domain=comodel_domain, **kwargs
+ )
+ if directory_id and field_name == 'parent_directory':
+ comodel_domain = kwargs.pop('comodel_domain', [])
+ domain = [('parent_directory', operator, directory_id)]
+ comodel_domain = expression.AND([comodel_domain, domain])
+ return super(Directory, self).search_panel_select_multi_range(
+ field_name, comodel_domain=comodel_domain, **kwargs
+ )
+ return super(Directory, self).search_panel_select_multi_range(field_name, **kwargs)
+
+ #----------------------------------------------------------
+ # Search
+ #----------------------------------------------------------
+
+ @api.model
+ def _search_starred(self, operator, operand):
+ if operator == '=' and operand:
+ return [('user_stars', 'in', [self.env.uid])]
+ return [('user_stars', 'not in', [self.env.uid])]
+
+ #----------------------------------------------------------
+ # Read
+ #----------------------------------------------------------
+
+ @api.depends('root_storage', 'parent_directory')
+ def _compute_storage(self):
+ for record in self:
+ if record.is_root_directory:
+ record.storage = record.root_storage
+ else:
+ record.storage = record.parent_directory.storage
+
+ @api.depends('user_stars')
+ def _compute_starred(self):
+ for record in self:
+ record.starred = self.env.user in record.user_stars
+
+ @api.depends('child_directories')
+ def _compute_count_directories(self):
+ for record in self:
+ record.count_directories = len(record.child_directories)
+
+ @api.depends('files')
+ def _compute_count_files(self):
+ for record in self:
+ record.count_files = len(record.files)
+
+ @api.depends('child_directories', 'files')
+ def _compute_count_elements(self):
+ for record in self:
+ elements = record.count_files
+ elements += record.count_directories
+ record.count_elements = elements
+
+
+ def _compute_count_total_directories(self):
+ for record in self:
+ count = self.search_count([
+ ('id', 'child_of', record.id)
+ ])
+ count = count - 1 if count > 0 else 0
+ record.count_total_directories = count
+
+
+ def _compute_count_total_files(self):
+ model = self.env['muk_dms.file']
+ for record in self:
+ record.count_total_files = model.search_count([
+ ('directory', 'child_of', record.id)
+ ])
+
+
+ def _compute_count_total_elements(self):
+ for record in self:
+ total_elements = record.count_total_files
+ total_elements += record.count_total_directories
+ record.count_total_elements = total_elements
+
+
+ def _compute_size(self):
+ sudo_model = self.env['muk_dms.file'].sudo()
+ for record in self:
+ recs = sudo_model.search_read(
+ domain=[('directory', 'child_of', record.id)],
+ fields=['size'],
+ )
+ record.size = sum(rec.get('size', 0) for rec in recs)
+
+ #----------------------------------------------------------
+ # View
+ #----------------------------------------------------------
+
+ @api.onchange('is_root_directory')
+ def _onchange_directory_type(self):
+ if self.is_root_directory:
+ self.parent_directory = None
+ else:
+ self.root_storage = None
+
+ @api.onchange('category')
+ def _change_category(self):
+ tags = self.tags.filtered(
+ lambda rec: not rec.category or \
+ rec.category == self.category
+ )
+ self.tags = tags
+
+ #----------------------------------------------------------
+ # Constrains
+ #----------------------------------------------------------
+
+ @api.constrains('parent_directory')
+ def _check_directory_recursion(self):
+ if not self._check_recursion():
+ raise ValidationError(_('Error! You cannot create recursive directories.'))
+ return True
+
+ @api.constrains('is_root_directory', 'root_storage', 'parent_directory')
+ def _check_directory_storage(self):
+ for record in self:
+ if record.is_root_directory and not record.root_storage:
+ raise ValidationError(_("A root directory has to have a root storage."))
+ if not record.is_root_directory and not record.parent_directory:
+ raise ValidationError(_("A directory has to have a parent directory."))
+ if record.parent_directory and (record.is_root_directory or record.root_storage):
+ raise ValidationError(_("A directory can't be a root and have a parent directory."))
+
+ @api.constrains('parent_directory')
+ def _check_directory_access(self):
+ for record in self:
+ if not record.parent_directory.check_access('create', raise_exception=False):
+ raise ValidationError(_("The parent directory has to have the permission to create directories."))
+
+ @api.constrains('name')
+ def _check_name(self):
+ for record in self:
+ if not file.check_name(record.name):
+ raise ValidationError(_("The directory name is invalid."))
+ if record.is_root_directory:
+ childs = record.sudo().root_storage.root_directories.name_get()
+ else:
+ childs = record.sudo().parent_directory.child_directories.name_get()
+ if list(filter(lambda child: child[1] == record.name and child[0] != record.id, childs)):
+ raise ValidationError(_("A directory with the same name already exists."))
+
+ #----------------------------------------------------------
+ # Create, Update, Delete
+ #----------------------------------------------------------
+
+
+ def _inverse_starred(self):
+ starred_records = self.env['muk_dms.directory'].sudo()
+ not_starred_records = self.env['muk_dms.directory'].sudo()
+ for record in self:
+ if not record.starred and self.env.user in record.user_stars:
+ starred_records |= record
+ elif record.starred and self.env.user not in record.user_stars:
+ not_starred_records |= record
+ not_starred_records.write({'user_stars': [(4, self.env.uid)]})
+ starred_records.write({'user_stars': [(3, self.env.uid)]})
+
+
+ @api.returns('self', lambda value: value.id)
+ def copy(self, default=None):
+ self.ensure_one()
+ default = dict(default or [])
+ names = []
+ if 'root_storage' in default:
+ storage = self.env['muk_dms.storage'].browse(default['root_storage'])
+ names = storage.sudo().root_directories.mapped('name')
+ elif 'parent_directory' in default:
+ parent_directory = self.browse(default['parent_directory'])
+ names = parent_directory.sudo().child_directories.mapped('name')
+ elif self.is_root_directory:
+ names = self.sudo().root_storage.root_directories.mapped('name')
+ else:
+ names = self.sudo().parent_directory.child_directories.mapped('name')
+ default.update({'name': file.unique_name(self.name, names)})
+ new = super(Directory, self).copy(default)
+ for record in self.files:
+ record.copy({'directory': new.id})
+ for record in self.child_directories:
+ record.copy({'parent_directory': new.id})
+ return new
+
+
+ def write(self, vals):
+ res = super(Directory, self).write(vals)
+ if self and any(field in vals for field in ['root_storage', 'parent_directory']):
+ records = self.sudo().search([('id', 'child_of', self.ids)]) - self
+ if 'root_storage' in vals:
+ records.write({'storage': vals['root_storage']})
+ elif 'parent_directory' in vals:
+ parent = self.browse([vals['parent_directory']])
+ data = next(iter(parent.sudo().read(['storage'])), {})
+ records.write({'storage': self._convert_to_write(data).get('storage')})
+ return res
+
+
+ def unlink(self):
+ if self and self.check_access('unlink', raise_exception=True):
+ domain = [
+ '&', ('directory', 'child_of', self.ids),
+ '&', ('locked_by', '!=', self.env.uid),
+ ('locked_by', '!=', False),
+ ]
+ if self.env['muk_dms.file'].sudo().search(domain):
+ raise AccessError(_("A file is locked, the folder cannot be deleted."))
+ self.env['muk_dms.file'].sudo().search([('directory', 'child_of', self.ids)]).unlink()
+ return super(Directory, self.sudo().search([('id', 'child_of', self.ids)])).unlink()
+ return super(Directory, self).unlink()
diff --git a/odex-event/muk_dms/models/file.py b/odex-event/muk_dms/models/file.py
new file mode 100644
index 000000000..75fc11be9
--- /dev/null
+++ b/odex-event/muk_dms/models/file.py
@@ -0,0 +1,568 @@
+###################################################################################
+#
+# Copyright (c) 2017-2019 MuK IT GmbH.
+#
+# This file is part of MuK Documents
+# (see https://mukit.at).
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see .
+#
+###################################################################################
+
+import os
+import io
+import json
+import base64
+import logging
+import mimetypes
+import itertools
+import tempfile
+import hashlib
+import operator
+import functools
+
+from collections import defaultdict
+
+from odoo import _, SUPERUSER_ID
+from odoo import models, api, fields, tools
+from odoo.tools.mimetypes import guess_mimetype
+from odoo.exceptions import ValidationError
+from odoo.exceptions import AccessError
+from odoo.osv import expression
+
+from odoo.addons.muk_utils.tools import file
+from odoo.addons.muk_security.tools.security import NoSecurityUid
+
+_logger = logging.getLogger(__name__)
+
+class File(models.Model):
+
+ _name = 'muk_dms.file'
+ _description = "File"
+
+ _inherit = [
+ 'muk_security.mixins.access_rights',
+ 'muk_security.mixins.locking',
+ 'muk_dms.mixins.thumbnail',
+ ]
+
+ _order = "name asc"
+
+ #----------------------------------------------------------
+ # Database
+ #----------------------------------------------------------
+
+ name = fields.Char(
+ string="Filename",
+ required=True,
+ index=True)
+
+ active = fields.Boolean(
+ string="Archived",
+ default=True,
+ help="If a file is set to archived, it is not displayed, but still exists.")
+
+ directory = fields.Many2one(
+ comodel_name='muk_dms.directory',
+ string="Directory",
+ domain="[('permission_create', '=', True)]",
+ context="{'dms_directory_show_path': True}",
+ ondelete='restrict',
+ auto_join=True,
+ required=True,
+ index=True)
+
+ storage = fields.Many2one(
+ related="directory.storage",
+ comodel_name='muk_dms.storage',
+ string="Storage",
+ auto_join=True,
+ readonly=True,
+ store=True)
+
+ is_hidden = fields.Boolean(
+ string="Storage is Hidden",
+ related="storage.is_hidden",
+ readonly=True)
+
+ company = fields.Many2one(
+ related="storage.company",
+ comodel_name='res.company',
+ string='Company',
+ readonly=True,
+ store=True,
+ index=True)
+
+ path_names = fields.Char(
+ compute='_compute_path',
+ string="Path Names",
+ readonly=True,
+ store=False)
+
+ path_json = fields.Text(
+ compute='_compute_path',
+ string="Path Json",
+ readonly=True,
+ store=False)
+
+ color = fields.Integer(
+ string="Color",
+ default=0)
+
+ category = fields.Many2one(
+ comodel_name='muk_dms.category',
+ context="{'dms_category_show_path': True}",
+ string="Category")
+
+ tags = fields.Many2many(
+ comodel_name='muk_dms.tag',
+ relation='muk_dms_file_tag_rel',
+ column1='fid',
+ column2='tid',
+ string='Tags')
+
+ content = fields.Binary(
+ compute='_compute_content',
+ inverse='_inverse_content',
+ string='Content',
+ attachment=False,
+ prefetch=False,
+ required=True,
+ store=False)
+
+ extension = fields.Char(
+ compute='_compute_extension',
+ string='Extension',
+ readonly=True,
+ store=True)
+
+ mimetype = fields.Char(
+ compute='_compute_mimetype',
+ string='Type',
+ readonly=True,
+ store=True)
+
+ size = fields.Integer(
+ string='Size',
+ readonly=True)
+
+ checksum = fields.Char(
+ string="Checksum/SHA1",
+ readonly=True,
+ size=40,
+ index=True)
+
+ content_binary = fields.Binary(
+ string="Content Binary",
+ attachment=False,
+ prefetch=False,
+ invisible=True)
+
+ save_type = fields.Char(
+ compute='_compute_save_type',
+ string='Current Save Type',
+ invisible=True,
+ prefetch=False)
+
+ migration = fields.Char(
+ compute='_compute_migration',
+ string='Migration Status',
+ readonly=True,
+ prefetch=False)
+
+ #----------------------------------------------------------
+ # Helper
+ #----------------------------------------------------------
+
+ @api.model
+ def _get_checksum(self, binary):
+ return hashlib.sha1(binary or b'').hexdigest()
+
+ @api.model
+ def _get_content_inital_vals(self):
+ return {'content_binary': False}
+
+ @api.model
+ def _update_content_vals(self, file, vals, binary):
+ vals.update({
+ 'checksum': self._get_checksum(binary),
+ 'size': binary and len(binary) or 0,
+ })
+ return vals
+
+ @api.model
+ def _get_binary_max_size(self):
+ get_param = self.env['ir.config_parameter'].sudo().get_param
+ return int(get_param('muk_web_utils.binary_max_size', default=25))
+
+ @api.model
+ def _get_forbidden_extensions(self):
+ get_param = self.env['ir.config_parameter'].sudo().get_param
+ extensions = get_param('muk_dms.forbidden_extensions', default="")
+ return [extension.strip() for extension in extensions.split(',')]
+
+
+ def _get_thumbnail_placeholder_name(self):
+ return self.extension and "file_%s.svg" % self.extension or ""
+
+ #----------------------------------------------------------
+ # Actions
+ #----------------------------------------------------------
+
+
+ def action_migrate(self, logging=True):
+ record_count = len(self)
+ for index, file in enumerate(self):
+ if logging:
+ info = (index + 1, record_count, file.migration)
+ _logger.info(_("Migrate File %s of %s [ %s ]") % info)
+ file.with_context(migration=True).write({
+ 'content': file.with_context({}).content
+ })
+
+
+ def action_save_onboarding_file_step(self):
+ self.env.user.company_id.set_onboarding_step_done(
+ 'documents_onboarding_file_state'
+ )
+
+ #----------------------------------------------------------
+ # SearchPanel
+ #----------------------------------------------------------
+
+ @api.model
+ def _search_panel_directory(self, **kwargs):
+ search_domain = kwargs.get('search_domain', []),
+ category_domain = kwargs.get('category_domain', [])
+ if category_domain and len(category_domain):
+ return '=', category_domain[0][2]
+ if search_domain and len(search_domain):
+ for domain in search_domain[0]:
+ if domain[0] == 'directory':
+ return domain[1], domain[2]
+ return None, None
+
+ @api.model
+ def _search_panel_domain(self, field, operator, directory_id, comodel_domain=[]):
+ files_ids = self.search([('directory', operator, directory_id)]).ids
+ return expression.AND([comodel_domain, [(field, 'in', files_ids)]])
+
+ @api.model
+ def search_panel_select_range(self, field_name, **kwargs):
+ operator, directory_id = self._search_panel_directory(**kwargs)
+ if directory_id and field_name == 'directory':
+ values = self.env['muk_dms.directory'].search_read(
+ [('parent_directory', operator, directory_id)],
+ ['display_name', 'parent_directory']
+ )
+ return {
+ 'parent_field': 'parent_directory',
+ 'values': values if len(values) > 1 else [],
+ }
+ return super(File, self).search_panel_select_range(field_name, **kwargs)
+
+ @api.model
+ def search_panel_select_multi_range(self, field_name, **kwargs):
+ operator, directory_id = self._search_panel_directory(**kwargs)
+ if field_name == 'tags':
+ sql_query = '''
+ SELECT t.name AS name, t.id AS id, c.name AS group_name,
+ c.id AS group_id, COUNT(r.fid) AS count
+ FROM muk_dms_tag t
+ JOIN muk_dms_category c ON t.category = c.id
+ LEFT JOIN muk_dms_file_tag_rel r ON t.id = r.tid
+ {directory_where_clause}
+ GROUP BY c.name, c.id, t.name, t.id
+ ORDER BY c.name, c.id, t.name, t.id;
+ '''
+ where_clause = ''
+ if directory_id:
+ directory_where_clause = 'WHERE r.fid = ANY (VALUES {ids})'
+ file_ids = self.search([('directory', operator, directory_id)]).ids
+ where_clause = '' if not file_ids else directory_where_clause.format(
+ ids=', '.join(map(lambda id: '(%s)' % id, file_ids))
+ )
+ self.env.cr.execute(sql_query.format(directory_where_clause=where_clause), [])
+ return self.env.cr.dictfetchall()
+ if directory_id and field_name in ['directory', 'category']:
+ comodel_domain = kwargs.pop('comodel_domain', [])
+ directory_comodel_domain = self._search_panel_domain(
+ 'files', operator, directory_id, comodel_domain
+ )
+ return super(File, self).search_panel_select_multi_range(
+ field_name, comodel_domain=directory_comodel_domain, **kwargs
+ )
+ return super(File, self).search_panel_select_multi_range(field_name, **kwargs)
+
+ #----------------------------------------------------------
+ # Read
+ #----------------------------------------------------------
+
+ @api.depends('name', 'directory', 'directory.parent_path')
+ def _compute_path(self):
+ records_with_directory = self - self.filtered(lambda rec: not rec.directory)
+ if records_with_directory:
+ paths = [list(map(int, rec.directory.parent_path.split('/')[:-1])) for rec in records_with_directory]
+ model = self.env['muk_dms.directory'].with_context(dms_directory_show_path=False)
+ directories = model.browse(set(functools.reduce(operator.concat, paths)))
+ data = dict(directories._filter_access('read').name_get())
+ for record in self:
+ path_names = []
+ path_json = []
+ for id in reversed(list(map(int, record.directory.parent_path.split('/')[:-1]))):
+ if id not in data:
+ break
+ path_names.append(data[id])
+ path_json.append({
+ 'model': model._name,
+ 'name': data[id],
+ 'id': id,
+ })
+ path_names.reverse()
+ path_json.reverse()
+ name = record.name_get()
+ path_names.append(name[0][1])
+ path_json.append({
+ 'model': record._name,
+ 'name': name[0][1],
+ 'id': isinstance(record.id, int) and record.id or 0,
+ })
+ record.update({
+ 'path_names': '/'.join(path_names),
+ 'path_json': json.dumps(path_json),
+ })
+
+ @api.depends('name')
+ def _compute_extension(self):
+ for record in self:
+ record.extension = file.guess_extension(record.name)
+
+ @api.depends('name')
+ def _compute_mimetype(self):
+ for record in self:
+ mimetype = record.name and mimetypes.guess_type(record.name)[0]
+ if not mimetype:
+ binary = base64.b64decode(record.with_context({}).content or "")
+ mimetype = guess_mimetype(binary, default='application/octet-stream')
+ record.mimetype = mimetype
+
+ @api.depends('content_binary')
+ def _compute_content(self):
+ for record in self:
+ record.content = record.content_binary
+
+ @api.depends('content_binary')
+ def _compute_save_type(self):
+ for record in self:
+ record.save_type = "database"
+
+ @api.depends('storage', 'storage.save_type')
+ def _compute_migration(self):
+ storage_model = self.env['muk_dms.storage']
+ save_field = storage_model._fields['save_type']
+ values = save_field._description_selection(self.env)
+ selection = {value[0]: value[1] for value in values}
+ for record in self:
+ storage_type = record.storage.save_type
+ if storage_type != record.save_type:
+ storage_label = selection.get(storage_type)
+ file_label = selection.get(record.save_type)
+ record.migration = "%s > %s" % (file_label, storage_label)
+ else:
+ record.migration = selection.get(storage_type)
+
+
+ def read(self, fields=None, load='_classic_read'):
+ self.check_directory_access('read', {}, True)
+ return super(File, self).read(fields, load=load)
+
+ #----------------------------------------------------------
+ # View
+ #----------------------------------------------------------
+
+ @api.onchange('category')
+ def _change_category(self):
+ res = {'domain': {
+ 'tags': [('category', '=', False)]
+ }}
+ if self.category:
+ res.update({'domain': {
+ 'tags': ['|',
+ ('category', '=', False),
+ ('category', 'child_of', self.category.id)
+ ]
+ }})
+ tags = self.tags.filtered(
+ lambda rec: not rec.category or \
+ rec.category == self.category
+ )
+ self.tags = tags
+ return res
+
+ #----------------------------------------------------------
+ # Security
+ #----------------------------------------------------------
+
+ @api.model
+ def _get_directories_from_database(self, file_ids):
+ if not file_ids:
+ return self.env['muk_dms.directory']
+ sql_query = '''
+ SELECT directory
+ FROM muk_dms_file
+ WHERE id = ANY (VALUES {ids});
+ '''.format(
+ ids=', '.join(map(lambda id: '(%s)' % id, file_ids))
+ )
+ self.env.cr.execute(sql_query, [])
+ result = set(val[0] for val in self.env.cr.fetchall())
+ return self.env['muk_dms.directory'].browse(result)
+
+ @api.model
+ def _read_group_process_groupby(self, gb, query):
+ if self.env.user.id == SUPERUSER_ID or isinstance(self.env.uid, NoSecurityUid):
+ return super(File, self)._read_group_process_groupby(gb, query)
+ directories = self.env['muk_dms.directory'].with_context(prefetch_fields=False).search([])
+ if directories:
+ where_clause = '"{table}"."{field}" = ANY (VALUES {ids})'.format(
+ table=self._table,
+ field='directory',
+ ids=', '.join(map(lambda id: '(%s)' % id, directories.ids)),
+ )
+ query.where_clause += [where_clause]
+ else:
+ query.where_clause += ['0=1']
+ return super(File, self)._read_group_process_groupby(gb, query)
+
+ @api.model
+ def _search(self, args, offset=0, limit=None, order=None, count=False, access_rights_uid=None):
+ result = super(File, self)._search(args, offset, limit, order, False, access_rights_uid)
+ if self.env.user.id == SUPERUSER_ID or isinstance(self.env.uid, NoSecurityUid):
+ return len(result) if count else result
+ if not result:
+ return 0 if count else []
+ file_ids = set(result)
+ directories = self._get_directories_from_database(result)
+ for directory in directories - directories._filter_access('read'):
+ file_ids -= set(directory.sudo().mapped('files').ids)
+ return len(file_ids) if count else list(file_ids)
+
+
+ def _filter_access(self, operation):
+ records = super(File, self)._filter_access(operation)
+ if self.env.user.id == SUPERUSER_ID or isinstance(self.env.uid, NoSecurityUid):
+ return records
+ directories = self._get_directories_from_database(records.ids)
+ for directory in directories - directories._filter_access('read'):
+ records -= self.browse(directory.sudo().mapped('files').ids)
+ return records
+
+
+ def check_access(self, operation, raise_exception=False):
+ res = super(File, self).check_access(operation, raise_exception)
+ try:
+ return res and self.check_directory_access(operation) == None
+ except AccessError:
+ if raise_exception:
+ raise
+ return False
+
+
+ def check_directory_access(self, operation, vals={}, raise_exception=False):
+ if self.env.user.id == SUPERUSER_ID or isinstance(self.env.uid, NoSecurityUid):
+ return None
+ if 'directory' in vals and vals['directory']:
+ records = self.env['muk_dms.directory'].browse(vals['directory'])
+ else:
+ records = self._get_directories_from_database(self.ids)
+ return records.check_access(operation, raise_exception)
+
+ #----------------------------------------------------------
+ # Constrains
+ #----------------------------------------------------------
+
+ @api.constrains('name')
+ def _check_name(self):
+ for record in self:
+ if not file.check_name(record.name):
+ raise ValidationError(_("The file name is invalid."))
+ files = record.sudo().directory.files.name_get()
+ if list(filter(lambda file: file[1] == record.name and file[0] != record.id, files)):
+ raise ValidationError(_("A file with the same name already exists."))
+
+ @api.constrains('extension')
+ def _check_extension(self):
+ for record in self:
+ if record.extension and record.extension in self._get_forbidden_extensions():
+ raise ValidationError(_("The file has a forbidden file extension."))
+
+ @api.constrains('size')
+ def _check_size(self):
+ for record in self:
+ if record.size and record.size > self._get_binary_max_size() * 1024 * 1024:
+ raise ValidationError(_("The maximum upload size is %s MB).") % self._get_binary_max_size())
+
+ @api.constrains('directory')
+ def _check_directory_access(self):
+ for record in self:
+ if not record.directory.check_access('create', raise_exception=False):
+ raise ValidationError(_("The directory has to have the permission to create files."))
+
+ #----------------------------------------------------------
+ # Create, Update, Delete
+ #----------------------------------------------------------
+
+
+ def _inverse_content(self):
+ updates = defaultdict(set)
+ for record in self:
+ values = self._get_content_inital_vals()
+ binary = base64.b64decode(record.content or "")
+ values = self._update_content_vals(record, values, binary)
+ values.update({
+ 'content_binary': record.content,
+ })
+ updates[tools.frozendict(values)].add(record.id)
+ with self.env.norecompute():
+ for vals, ids in updates.items():
+ self.browse(ids).write(dict(vals))
+ self.recompute()
+
+
+ @api.returns('self', lambda value: value.id)
+ def copy(self, default=None):
+ self.ensure_one()
+ default = dict(default or [])
+ names = []
+ if 'directory' in default:
+ model = self.env['muk_dms.directory']
+ directory = model.browse(default['directory'])
+ names = directory.sudo().files.mapped('name')
+ else:
+ names = self.sudo().directory.files.mapped('name')
+ default.update({
+ 'name': file.unique_name(self.name, names, self.extension)
+ })
+ self.check_directory_access('create', default, True)
+ return super(File, self).copy(default)
+
+
+ def write(self, vals):
+ self.check_directory_access('write', vals, True)
+ return super(File, self).write(vals)
+
+
+ def unlink(self):
+ self.check_directory_access('unlink', {}, True)
+ return super(File, self).unlink()
\ No newline at end of file
diff --git a/odex-event/muk_dms/models/ir_http.py b/odex-event/muk_dms/models/ir_http.py
new file mode 100644
index 000000000..3e100b414
--- /dev/null
+++ b/odex-event/muk_dms/models/ir_http.py
@@ -0,0 +1,62 @@
+###################################################################################
+#
+# Copyright (c) 2017-2019 MuK IT GmbH.
+#
+# This file is part of MuK Documents
+# (see https://mukit.at).
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see .
+#
+###################################################################################
+
+import base64
+import logging
+import mimetypes
+
+from odoo import models
+from odoo.exceptions import AccessError
+from odoo.http import request, STATIC_CACHE
+from odoo.tools.mimetypes import guess_mimetype
+
+_logger = logging.getLogger(__name__)
+
+class IrHttp(models.AbstractModel):
+
+ _inherit = 'ir.http'
+
+ @classmethod
+ def binary_content(cls, xmlid=None, model='ir.attachment', id=None, field='datas', unique=False, filename=None,
+ filename_field='datas_fname', download=False, mimetype=None, default_mimetype='application/octet-stream',
+ access_token=None, related_id=None, access_mode=None, env=None):
+ res_status, res_headers, res_content = super(IrHttp, cls).binary_content(
+ xmlid=xmlid, model=model, id=id, field=field, unique=unique, filename=filename, mimetype=mimetype,
+ filename_field=filename_field, download=download, access_mode=access_mode, related_id=related_id,
+ default_mimetype=default_mimetype, access_token=access_token, env=env)
+ if res_status == 200:
+ env = env or request.env
+ if model == "muk_dms.file" and field != 'content':
+ obj = cls._xmlid_to_obj(env, xmlid) if xmlid else env[model].browse(int(id))
+ filename = obj[filename_field] if not filename and filename_field in obj else filename
+ mimetype = filename and mimetypes.guess_type(filename)[0]
+ if not mimetype:
+ mimetype = guess_mimetype(base64.b64decode(res_content), default=default_mimetype)
+ headers = []
+ for header in res_headers:
+ if header[0] == 'Content-Type':
+ headers.append(('Content-Type', mimetype))
+ else:
+ headers.append(header)
+ return res_status, headers, res_content
+ return res_status, res_headers, res_content
+
\ No newline at end of file
diff --git a/odex-event/muk_dms/models/mixins_thumbnail.py b/odex-event/muk_dms/models/mixins_thumbnail.py
new file mode 100644
index 000000000..8b97556c4
--- /dev/null
+++ b/odex-event/muk_dms/models/mixins_thumbnail.py
@@ -0,0 +1,158 @@
+###################################################################################
+#
+# Copyright (c) 2017-2019 MuK IT GmbH.
+#
+# This file is part of MuK Documents
+# (see https://mukit.at).
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see .
+#
+###################################################################################
+
+import os
+import json
+import base64
+import operator
+import functools
+import collections
+
+from odoo import models, fields, api, tools
+from odoo.modules.module import get_resource_path
+
+class Thumbnail(models.AbstractModel):
+
+ _name = 'muk_dms.mixins.thumbnail'
+ _description = 'Thumbnail Mixin'
+
+ #----------------------------------------------------------
+ # Database
+ #----------------------------------------------------------
+
+ custom_thumbnail = fields.Binary(
+ string="Custom Thumbnail",
+ attachment=False,
+ prefetch=False)
+
+ custom_thumbnail_medium = fields.Binary(
+ string="Medium Custom Thumbnail",
+ attachment=False,
+ prefetch=False)
+
+ custom_thumbnail_small = fields.Binary(
+ string="Small Custom Thumbnail",
+ attachment=False,
+ prefetch=False)
+
+ thumbnail = fields.Binary(
+ compute='_compute_thumbnail',
+ string="Thumbnail")
+
+ thumbnail_medium = fields.Binary(
+ compute='_compute_thumbnail_medium',
+ string="Medium Thumbnail")
+
+ thumbnail_small = fields.Binary(
+ compute='_compute_thumbnail_small',
+ string="Small Thumbnail")
+
+ #----------------------------------------------------------
+ # Helper
+ #----------------------------------------------------------
+
+ @api.model
+ def _get_thumbnail_placeholder(self, field, size, name):
+ if self._check_context_bin_size(field):
+ return self._get_thumbnail_placeholder_size(size, name)
+ else:
+ return self._get_thumbnail_placeholder_image(size, name)
+
+ @api.model
+ def _get_thumbnail_placeholder_image(self, size, name):
+ path = self._get_thumbnail_path(size, name)
+ with open(path, "rb") as image:
+ return base64.b64encode(image.read())
+
+ @api.model
+ def _get_thumbnail_placeholder_size(self, size, name):
+ return os.path.getsize(self._get_thumbnail_path(size, name))
+
+ @api.model
+ def _get_thumbnail_path(self, size, name):
+ folders = ['static', 'src', 'img', 'thumbnails']
+ path = get_resource_path('muk_dms', *folders, name)
+ if not os.path.isfile(path):
+ path = get_resource_path('muk_dms', *folders, "file_unkown.svg")
+ return path
+
+
+ def _get_thumbnail_placeholder_name(self):
+ return "folder.svg"
+
+ #----------------------------------------------------------
+ # Read
+ #----------------------------------------------------------
+
+ @api.depends('custom_thumbnail')
+ def _compute_thumbnail(self):
+ for record in self:
+ if record.custom_thumbnail:
+ record.thumbnail = record.custom_thumbnail
+ else:
+ record.thumbnail = self._get_thumbnail_placeholder(
+ 'thumbnail', 'original', record._get_thumbnail_placeholder_name()
+ )
+
+ @api.depends('custom_thumbnail_medium')
+ def _compute_thumbnail_medium(self):
+ for record in self:
+ if record.custom_thumbnail_medium:
+ record.thumbnail_medium = record.custom_thumbnail_medium
+ else:
+ record.thumbnail_medium = self._get_thumbnail_placeholder(
+ 'thumbnail_medium', 'medium', record._get_thumbnail_placeholder_name()
+ )
+
+ @api.depends('custom_thumbnail_small')
+ def _compute_thumbnail_small(self):
+ for record in self:
+ if record.custom_thumbnail_small:
+ record.thumbnail_small = record.custom_thumbnail_small
+ else:
+ record.thumbnail_small = self._get_thumbnail_placeholder(
+ 'thumbnail_small', 'small', record._get_thumbnail_placeholder_name()
+ )
+
+ #----------------------------------------------------------
+ # Create, Update, Delete
+ #----------------------------------------------------------
+
+ @api.model_create_multi
+ def create(self, vals_list):
+ for vals in vals_list:
+ tools.image_resize_images(vals,
+ big_name='custom_thumbnail',
+ medium_name='custom_thumbnail_medium',
+ small_name='custom_thumbnail_small'
+ )
+ return super(Thumbnail, self).create(vals_list)
+
+
+ def write(self, vals):
+ tools.image_resize_images(vals,
+ big_name='custom_thumbnail',
+ medium_name='custom_thumbnail_medium',
+ small_name='custom_thumbnail_small'
+ )
+ return super(Thumbnail, self).write(vals)
+
\ No newline at end of file
diff --git a/odex-event/muk_dms/models/res_company.py b/odex-event/muk_dms/models/res_company.py
new file mode 100644
index 000000000..efcfe0890
--- /dev/null
+++ b/odex-event/muk_dms/models/res_company.py
@@ -0,0 +1,123 @@
+###################################################################################
+#
+# Copyright (c) 2017-2019 MuK IT GmbH.
+#
+# This file is part of MuK Documents
+# (see https://mukit.at).
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see .
+#
+###################################################################################
+
+import logging
+
+from odoo import models, api, fields
+
+_logger = logging.getLogger(__name__)
+
+class ResCompany(models.Model):
+
+ _inherit = 'res.company'
+
+ #----------------------------------------------------------
+ # Database
+ #----------------------------------------------------------
+
+ documents_onboarding_state = fields.Selection(
+ selection=[
+ ('not_done', "Not done"),
+ ('just_done', "Just done"),
+ ('done', "Done"),
+ ('closed', "Closed")
+ ],
+ string="Documents Onboarding State",
+ default='not_done')
+
+ documents_onboarding_storage_state = fields.Selection(
+ selection=[
+ ('not_done', "Not done"),
+ ('just_done', "Just done"),
+ ('done', "Done"),
+ ('closed', "Closed")
+ ],
+ string="Documents Onboarding Storage State",
+ default='not_done')
+
+ documents_onboarding_directory_state = fields.Selection(
+ selection=[
+ ('not_done', "Not done"),
+ ('just_done', "Just done"),
+ ('done', "Done"),
+ ('closed', "Closed")
+ ],
+ string="Documents Onboarding Directory State",
+ default='not_done')
+
+ documents_onboarding_file_state = fields.Selection(
+ selection=[
+ ('not_done', "Not done"),
+ ('just_done', "Just done"),
+ ('done', "Done"),
+ ('closed', "Closed")
+ ],
+ string="Documents Onboarding File State",
+ default='not_done')
+
+ #----------------------------------------------------------
+ # Functions
+ #----------------------------------------------------------
+
+ def get_and_update_documents_onboarding_state(self):
+ return self.get_and_update_onbarding_state(
+ 'documents_onboarding_state',
+ self.get_documents_steps_states_names()
+ )
+
+ def get_documents_steps_states_names(self):
+ return [
+ 'documents_onboarding_storage_state',
+ 'documents_onboarding_directory_state',
+ 'documents_onboarding_file_state',
+ ]
+
+ #----------------------------------------------------------
+ # Actions
+ #----------------------------------------------------------
+
+ @api.model
+ def action_open_documents_onboarding_storage(self):
+ return self.env.ref('muk_dms.action_dms_storage_new').read()[0]
+
+ @api.model
+ def action_open_documents_onboarding_directory(self):
+ storage = self.env['muk_dms.storage'].search([], order="create_date desc", limit=1)
+ action = self.env.ref('muk_dms.action_dms_directory_new').read()[0]
+ action['context'] = {**self.env.context, **{
+ 'default_is_root_directory': True,
+ 'default_root_storage': storage and storage.id
+ }}
+ return action
+
+ @api.model
+ def action_open_documents_onboarding_file(self):
+ directory = self.env['muk_dms.directory'].search([], order="create_date desc", limit=1)
+ action = self.env.ref('muk_dms.action_dms_file_new').read()[0]
+ action['context'] = {**self.env.context, **{
+ 'default_directory': directory and directory.id
+ }}
+ return action
+
+ @api.model
+ def action_close_documents_onboarding(self):
+ self.env.user.company_id.documents_onboarding_state = 'closed'
diff --git a/odex-event/muk_dms/models/res_config_settings.py b/odex-event/muk_dms/models/res_config_settings.py
new file mode 100644
index 000000000..1693dd21b
--- /dev/null
+++ b/odex-event/muk_dms/models/res_config_settings.py
@@ -0,0 +1,171 @@
+###################################################################################
+#
+# Copyright (c) 2017-2019 MuK IT GmbH.
+#
+# This file is part of MuK Documents
+# (see https://mukit.at).
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see .
+#
+###################################################################################
+
+from odoo import api, fields, models
+
+class ResConfigSettings(models.TransientModel):
+
+ _inherit = 'res.config.settings'
+
+ #----------------------------------------------------------
+ # Base Addons
+ #----------------------------------------------------------
+
+ module_muk_dms_access = fields.Boolean(
+ string="Access Control",
+ help="Allows the creation of groups to define access rights.")
+
+ module_muk_dms_mail = fields.Boolean(
+ string="Mail Support",
+ help="Adds support for messages and activities on directories and files.")
+
+ module_muk_dms_version = fields.Boolean(
+ string="Versioning",
+ help="Enables version control for files.")
+
+ module_muk_dms_trash = fields.Boolean(
+ string="Restore Files",
+ help="Activates a file trash to restore deleted files.")
+
+ module_muk_dms_widget = fields.Boolean(
+ string="Binary Widget Support",
+ help="Allows the user to use documents as input for any binary field.")
+
+ module_muk_dms_archive = fields.Boolean(
+ string="Download Directories",
+ help="Allows to download directories as a archive file.")
+
+ module_muk_dms_thumbnails = fields.Boolean(
+ string="File Thumbnails",
+ help="Automatically create file thumbnails based on the content.")
+
+ module_muk_dms_index = fields.Boolean(
+ string="File Indexation",
+ help="Automatically create a file index based on the content.")
+
+ #----------------------------------------------------------
+ # Views
+ #----------------------------------------------------------
+
+ module_muk_dms_preview = fields.Boolean(
+ string="File Preview",
+ help="Activates the preview function on files.")
+
+ module_muk_dms_view = fields.Boolean(
+ string="Tree View",
+ help="Activates the documents tree view.")
+
+ module_muk_dms_finder = fields.Boolean(
+ string="Finder",
+ help="Enables the Document Finder.")
+
+ #----------------------------------------------------------
+ # Storage Addons
+ #----------------------------------------------------------
+
+ module_muk_dms_lobject = fields.Boolean(
+ string="Large Objects Storage",
+ help="Enables a new save option to store files into large objects.")
+
+ module_muk_dms_file = fields.Boolean(
+ string="Filestore Storage",
+ help="Enables a new save option to store files into a filestore.")
+
+ #----------------------------------------------------------
+ # Attachment Addons
+ #----------------------------------------------------------
+
+ module_muk_dms_attachment = fields.Boolean(
+ string="Documents Storage Location",
+ help="Allows attachments to be stored inside of Documents.")
+
+ module_muk_dms_attachment_rules = fields.Boolean(
+ string="Documents Storage Rules",
+ help="Allows attachments to be automatically placed in the right directory.")
+
+ module_muk_dms_attachment_automation = fields.Boolean(
+ string="Attachment Rule Automation",
+ help="Allows you to create rule templates to create attachment rules.")
+
+ module_muk_dms_attachment_wizard = fields.Boolean(
+ string="Attachment Wizard",
+ help="Allows documents to be used as attachments.")
+
+ #----------------------------------------------------------
+ # Integrations
+ #----------------------------------------------------------
+
+ module_muk_dms_actions = fields.Boolean(
+ string="Document Actions",
+ help="Create custom file operations.")
+
+ module_muk_dms_users = fields.Boolean(
+ string="Personal Documents",
+ help="Automatic creation of user directories.")
+
+ #----------------------------------------------------------
+ # ... Addons
+ #----------------------------------------------------------
+
+
+
+ module_muk_dms_thumbnails = fields.Boolean(
+ string="Automatic Thumbnails",
+ help="Allows the creation of thumbnails for files.")
+
+ module_muk_dms_export = fields.Boolean(
+ string="Export Files",
+ help="Allows the conversion of existing files.")
+
+ #----------------------------------------------------------
+ # Database
+ #----------------------------------------------------------
+
+ documents_binary_max_size = fields.Integer(
+ string="Size",
+ help="Defines the maximum upload size in MB. Default (25MB)")
+
+ documents_forbidden_extensions = fields.Char(
+ string="Extensions",
+ help="Defines a list of forbidden file extensions. (Example: 'exe,msi')")
+
+ #----------------------------------------------------------
+ # Functions
+ #----------------------------------------------------------
+
+
+ def set_values(self):
+ res = super(ResConfigSettings, self).set_values()
+ param = self.env['ir.config_parameter'].sudo()
+ param.set_param('muk_web_utils.binary_max_size', self.documents_binary_max_size)
+ param.set_param('muk_dms.forbidden_extensions', self.documents_forbidden_extensions)
+ return res
+
+ @api.model
+ def get_values(self):
+ res = super(ResConfigSettings, self).get_values()
+ params = self.env['ir.config_parameter'].sudo()
+ res.update(
+ documents_binary_max_size=int(params.get_param('muk_web_utils.binary_max_size', default=25)),
+ documents_forbidden_extensions=params.get_param('muk_dms.forbidden_extensions', default=""),
+ )
+ return res
diff --git a/odex-event/muk_dms/models/storage.py b/odex-event/muk_dms/models/storage.py
new file mode 100644
index 000000000..d3e9da917
--- /dev/null
+++ b/odex-event/muk_dms/models/storage.py
@@ -0,0 +1,128 @@
+###################################################################################
+#
+# Copyright (c) 2017-2019 MuK IT GmbH.
+#
+# This file is part of MuK Documents
+# (see https://mukit.at).
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see .
+#
+###################################################################################
+
+import logging
+import textwrap
+
+from odoo import _, models, api, fields
+from odoo.exceptions import AccessError
+
+_logger = logging.getLogger(__name__)
+
+class Storage(models.Model):
+
+ _name = 'muk_dms.storage'
+ _description = "Storage"
+
+ #----------------------------------------------------------
+ # Database
+ #----------------------------------------------------------
+
+ name = fields.Char(
+ string="Name",
+ required=True)
+
+ save_type = fields.Selection(
+ selection=[("database", _('Database'))],
+ string="Save Type",
+ default="database",
+ required=True,
+ help="""The save type is used to determine how a file is saved by the system. If you change
+ this setting, you can migrate existing files manually by triggering the action.""")
+
+ company = fields.Many2one(
+ comodel_name='res.company',
+ string='Company',
+ default=lambda self: self.env.user.company_id,
+ help="If set, directories and files will only be available for the selected company.")
+
+ is_hidden = fields.Boolean(
+ string="Storage is Hidden",
+ default=False,
+ help="Indicates if directories and files are hidden by default.")
+
+ root_directories = fields.One2many(
+ comodel_name='muk_dms.directory',
+ inverse_name='root_storage',
+ string="Root Directories",
+ auto_join=False,
+ readonly=False,
+ copy=False)
+
+ storage_directories = fields.One2many(
+ comodel_name='muk_dms.directory',
+ inverse_name='storage',
+ string="Directories",
+ auto_join=False,
+ readonly=True,
+ copy=False)
+
+ storage_files = fields.One2many(
+ comodel_name='muk_dms.file',
+ inverse_name='storage',
+ string="Files",
+ auto_join=False,
+ readonly=True,
+ copy=False)
+
+ count_storage_directories = fields.Integer(
+ compute='_compute_count_storage_directories',
+ string="Count Directories")
+
+ count_storage_files = fields.Integer(
+ compute='_compute_count_storage_files',
+ string="Count Files")
+
+ #----------------------------------------------------------
+ # Actions
+ #----------------------------------------------------------
+
+
+ def action_storage_migrate(self):
+ if not self.env.user.has_group('muk_dms.group_dms_manager'):
+ raise AccessError(_('Only managers can execute this action.'))
+ files = self.env['muk_dms.file'].with_context(active_test=False).sudo()
+ for record in self:
+ domain = ['&', ('content_binary', '=', False), ('storage', '=', record.id)]
+ files |= files.search(domain)
+ files.action_migrate()
+
+
+ def action_save_onboarding_storage_step(self):
+ self.env.user.company_id.set_onboarding_step_done(
+ 'documents_onboarding_storage_state'
+ )
+
+ #----------------------------------------------------------
+ # Read, View
+ #----------------------------------------------------------
+
+ @api.depends('storage_directories')
+ def _compute_count_storage_directories(self):
+ for record in self:
+ record.count_storage_directories = len(record.storage_directories)
+
+ @api.depends('storage_files')
+ def _compute_count_storage_files(self):
+ for record in self:
+ record.count_storage_files = len(record.storage_files)
+
\ No newline at end of file
diff --git a/odex-event/muk_dms/models/tag.py b/odex-event/muk_dms/models/tag.py
new file mode 100644
index 000000000..b16ffd0df
--- /dev/null
+++ b/odex-event/muk_dms/models/tag.py
@@ -0,0 +1,101 @@
+###################################################################################
+#
+# Copyright (c) 2017-2019 MuK IT GmbH.
+#
+# This file is part of MuK Documents
+# (see https://mukit.at).
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see .
+#
+###################################################################################
+
+import logging
+
+from odoo import models, api, fields
+
+_logger = logging.getLogger(__name__)
+
+class Tag(models.Model):
+
+ _name = 'muk_dms.tag'
+ _description = "Document Tag"
+
+ #----------------------------------------------------------
+ # Database
+ #----------------------------------------------------------
+
+ name = fields.Char(
+ string='Name',
+ required=True,
+ translate=True)
+
+ active = fields.Boolean(
+ default=True,
+ help="The active field allows you to hide the tag without removing it.")
+
+ category = fields.Many2one(
+ comodel_name='muk_dms.category',
+ context="{'dms_category_show_path': True}",
+ string='Category',
+ ondelete='set null')
+
+ color = fields.Integer(
+ string='Color Index',
+ default=10)
+
+ directories = fields.Many2many(
+ comodel_name='muk_dms.directory',
+ relation='muk_dms_directory_tag_rel',
+ column1='tid',
+ column2='did',
+ string='Directories',
+ readonly=True)
+
+ files = fields.Many2many(
+ comodel_name='muk_dms.file',
+ relation='muk_dms_file_tag_rel',
+ column1='tid',
+ column2='fid',
+ string='Files',
+ readonly=True)
+
+ count_directories = fields.Integer(
+ compute='_compute_count_directories',
+ string="Count Directories")
+
+ count_files = fields.Integer(
+ compute='_compute_count_files',
+ string="Count Files")
+
+ #----------------------------------------------------------
+ # Constrains
+ #----------------------------------------------------------
+
+ _sql_constraints = [
+ ('name_uniq', 'unique (name, category)', "Tag name already exists!"),
+ ]
+
+ #----------------------------------------------------------
+ # Read
+ #----------------------------------------------------------
+
+ @api.depends('directories')
+ def _compute_count_directories(self):
+ for record in self:
+ record.count_directories = len(record.directories)
+
+ @api.depends('files')
+ def _compute_count_files(self):
+ for record in self:
+ record.count_files = len(record.files)
\ No newline at end of file
diff --git a/odex-event/muk_dms/security/ir.model.access.csv b/odex-event/muk_dms/security/ir.model.access.csv
new file mode 100644
index 000000000..7866d6358
--- /dev/null
+++ b/odex-event/muk_dms/security/ir.model.access.csv
@@ -0,0 +1,10 @@
+id,name,model_id/id,group_id/id,perm_read,perm_write,perm_create,perm_unlink
+
+access_dms_tag_user,dms_tag_user,model_muk_dms_tag,group_dms_user,1,1,1,1
+access_dms_category_user,dms_category_user,model_muk_dms_category,group_dms_user,1,1,1,1
+
+access_dms_storage_user,dms_storage_user,model_muk_dms_storage,group_dms_user,1,0,0,0
+access_dms_storage_manager,dms_storage_manager,model_muk_dms_storage,group_dms_manager,1,1,1,1
+
+access_dms_directory_user,dms_directory_user,model_muk_dms_directory,group_dms_user,1,1,1,1
+access_dms_file_user,dms_file_user,model_muk_dms_file,group_dms_user,1,1,1,1
\ No newline at end of file
diff --git a/odex-event/muk_dms/security/security.xml b/odex-event/muk_dms/security/security.xml
new file mode 100644
index 000000000..1486980b6
--- /dev/null
+++ b/odex-event/muk_dms/security/security.xml
@@ -0,0 +1,65 @@
+
+
+
+
+
+
+
+ Documents
+
+
+
+ User
+
+
+
+
+ Manager
+
+
+
+
+
+
+ DMS Storage multi-company
+
+
+ ['|',('company','=',False),('company','child_of',[user.company_id.id])]
+
+
+
+ DMS Directory multi-company
+
+
+ ['|',('company','=',False),('company','child_of',[user.company_id.id])]
+
+
+
+ File multi-company
+
+
+ ['|',('company','=',False),('company','child_of',[user.company_id.id])]
+
+
+
+
diff --git a/odex-event/muk_dms/static/description/banner.png b/odex-event/muk_dms/static/description/banner.png
new file mode 100644
index 000000000..a5fba8464
Binary files /dev/null and b/odex-event/muk_dms/static/description/banner.png differ
diff --git a/odex-event/muk_dms/static/description/icon.png b/odex-event/muk_dms/static/description/icon.png
new file mode 100644
index 000000000..a561495f1
Binary files /dev/null and b/odex-event/muk_dms/static/description/icon.png differ
diff --git a/odex-event/muk_dms/static/description/icon.svg b/odex-event/muk_dms/static/description/icon.svg
new file mode 100644
index 000000000..91c822dfa
--- /dev/null
+++ b/odex-event/muk_dms/static/description/icon.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/odex-event/muk_dms/static/description/index.html b/odex-event/muk_dms/static/description/index.html
new file mode 100644
index 000000000..7701d6380
--- /dev/null
+++ b/odex-event/muk_dms/static/description/index.html
@@ -0,0 +1,176 @@
+
+
+
MuK Documents
+
Document Management System
+
MuK IT GmbH -
+ www.mukit.at
+
+
+
+
+
+
+
+
+
+
Overview
+
MuK Documents is a module to create, manage
+ and view files directly within Odoo. This module is only the basis for
+ an entire ecosystem of apps that extend and seamlessly integrate with the
+ document management system.
+
+
+
+
+
+
+
Views
+
+
The standard Odoo views, Kanban,
+ List and Form are implemented for folders and Files. The Kanban View can
+ be used to directly display the subfolders or files of a particular
+ folder.
+
+
+
+
+
+
+
+
+
+
Document Settings
+
+
+
+
+
There is the possibility to
+ create own settings for different folder structure cures. This gives
+ you the option of adapting the structure even further to your
+ requirements.
+
+
+
+
+
+
+
Documents Extension
+
+
This module is just the basis for
+ a complete ecosystem of applications that can expand and seamlessly
+ integrate into the document management system. You can download the
+ extensions in the
+ store.
+
+
\ No newline at end of file
diff --git a/odex-event/muk_dms/static/description/logo.png b/odex-event/muk_dms/static/description/logo.png
new file mode 100644
index 000000000..9427ce33e
Binary files /dev/null and b/odex-event/muk_dms/static/description/logo.png differ
diff --git a/odex-event/muk_dms/static/description/preview.png b/odex-event/muk_dms/static/description/preview.png
new file mode 100644
index 000000000..1deb1ccef
Binary files /dev/null and b/odex-event/muk_dms/static/description/preview.png differ
diff --git a/odex-event/muk_dms/static/description/screenshot.png b/odex-event/muk_dms/static/description/screenshot.png
new file mode 100644
index 000000000..67885b4ac
Binary files /dev/null and b/odex-event/muk_dms/static/description/screenshot.png differ
diff --git a/odex-event/muk_dms/static/description/screenshot_apps.png b/odex-event/muk_dms/static/description/screenshot_apps.png
new file mode 100644
index 000000000..075b168ad
Binary files /dev/null and b/odex-event/muk_dms/static/description/screenshot_apps.png differ
diff --git a/odex-event/muk_dms/static/description/screenshot_folder.png b/odex-event/muk_dms/static/description/screenshot_folder.png
new file mode 100644
index 000000000..058e3f591
Binary files /dev/null and b/odex-event/muk_dms/static/description/screenshot_folder.png differ
diff --git a/odex-event/muk_dms/static/description/screenshot_settings.png b/odex-event/muk_dms/static/description/screenshot_settings.png
new file mode 100644
index 000000000..8c5f3b4b4
Binary files /dev/null and b/odex-event/muk_dms/static/description/screenshot_settings.png differ
diff --git a/odex-event/muk_dms/static/description/service_customization.png b/odex-event/muk_dms/static/description/service_customization.png
new file mode 100644
index 000000000..3eac66488
Binary files /dev/null and b/odex-event/muk_dms/static/description/service_customization.png differ
diff --git a/odex-event/muk_dms/static/description/service_development.png b/odex-event/muk_dms/static/description/service_development.png
new file mode 100644
index 000000000..580d46046
Binary files /dev/null and b/odex-event/muk_dms/static/description/service_development.png differ
diff --git a/odex-event/muk_dms/static/description/service_implementation.png b/odex-event/muk_dms/static/description/service_implementation.png
new file mode 100644
index 000000000..d64b66bda
Binary files /dev/null and b/odex-event/muk_dms/static/description/service_implementation.png differ
diff --git a/odex-event/muk_dms/static/description/service_integration.png b/odex-event/muk_dms/static/description/service_integration.png
new file mode 100644
index 000000000..76c5e80f4
Binary files /dev/null and b/odex-event/muk_dms/static/description/service_integration.png differ
diff --git a/odex-event/muk_dms/static/description/service_support.png b/odex-event/muk_dms/static/description/service_support.png
new file mode 100644
index 000000000..4c530fafd
Binary files /dev/null and b/odex-event/muk_dms/static/description/service_support.png differ
diff --git a/odex-event/muk_dms/static/src/img/banner/documents_onboarding_directory.png b/odex-event/muk_dms/static/src/img/banner/documents_onboarding_directory.png
new file mode 100644
index 000000000..d79387705
Binary files /dev/null and b/odex-event/muk_dms/static/src/img/banner/documents_onboarding_directory.png differ
diff --git a/odex-event/muk_dms/static/src/img/banner/documents_onboarding_file.png b/odex-event/muk_dms/static/src/img/banner/documents_onboarding_file.png
new file mode 100644
index 000000000..ac830fa6b
Binary files /dev/null and b/odex-event/muk_dms/static/src/img/banner/documents_onboarding_file.png differ
diff --git a/odex-event/muk_dms/static/src/img/thumbnails/file_ai.svg b/odex-event/muk_dms/static/src/img/thumbnails/file_ai.svg
new file mode 100644
index 000000000..393473205
--- /dev/null
+++ b/odex-event/muk_dms/static/src/img/thumbnails/file_ai.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/odex-event/muk_dms/static/src/img/thumbnails/file_aj.svg b/odex-event/muk_dms/static/src/img/thumbnails/file_aj.svg
new file mode 100644
index 000000000..ea6677b51
--- /dev/null
+++ b/odex-event/muk_dms/static/src/img/thumbnails/file_aj.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/odex-event/muk_dms/static/src/img/thumbnails/file_avi.svg b/odex-event/muk_dms/static/src/img/thumbnails/file_avi.svg
new file mode 100644
index 000000000..74784ac70
--- /dev/null
+++ b/odex-event/muk_dms/static/src/img/thumbnails/file_avi.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/odex-event/muk_dms/static/src/img/thumbnails/file_c.svg b/odex-event/muk_dms/static/src/img/thumbnails/file_c.svg
new file mode 100644
index 000000000..f517ec41b
--- /dev/null
+++ b/odex-event/muk_dms/static/src/img/thumbnails/file_c.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/odex-event/muk_dms/static/src/img/thumbnails/file_cbl.svg b/odex-event/muk_dms/static/src/img/thumbnails/file_cbl.svg
new file mode 100644
index 000000000..3807ebf2f
--- /dev/null
+++ b/odex-event/muk_dms/static/src/img/thumbnails/file_cbl.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/odex-event/muk_dms/static/src/img/thumbnails/file_cc.svg b/odex-event/muk_dms/static/src/img/thumbnails/file_cc.svg
new file mode 100644
index 000000000..36e6ad3b5
--- /dev/null
+++ b/odex-event/muk_dms/static/src/img/thumbnails/file_cc.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/odex-event/muk_dms/static/src/img/thumbnails/file_coffee.svg b/odex-event/muk_dms/static/src/img/thumbnails/file_coffee.svg
new file mode 100644
index 000000000..10a84d2c3
--- /dev/null
+++ b/odex-event/muk_dms/static/src/img/thumbnails/file_coffee.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/odex-event/muk_dms/static/src/img/thumbnails/file_cs.svg b/odex-event/muk_dms/static/src/img/thumbnails/file_cs.svg
new file mode 100644
index 000000000..c1084f00f
--- /dev/null
+++ b/odex-event/muk_dms/static/src/img/thumbnails/file_cs.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/odex-event/muk_dms/static/src/img/thumbnails/file_css.svg b/odex-event/muk_dms/static/src/img/thumbnails/file_css.svg
new file mode 100644
index 000000000..0289d715b
--- /dev/null
+++ b/odex-event/muk_dms/static/src/img/thumbnails/file_css.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/odex-event/muk_dms/static/src/img/thumbnails/file_csv.svg b/odex-event/muk_dms/static/src/img/thumbnails/file_csv.svg
new file mode 100644
index 000000000..087807e2c
--- /dev/null
+++ b/odex-event/muk_dms/static/src/img/thumbnails/file_csv.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/odex-event/muk_dms/static/src/img/thumbnails/file_dbf.svg b/odex-event/muk_dms/static/src/img/thumbnails/file_dbf.svg
new file mode 100644
index 000000000..54a7ed4d6
--- /dev/null
+++ b/odex-event/muk_dms/static/src/img/thumbnails/file_dbf.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/odex-event/muk_dms/static/src/img/thumbnails/file_dll.svg b/odex-event/muk_dms/static/src/img/thumbnails/file_dll.svg
new file mode 100644
index 000000000..c31d6df2e
--- /dev/null
+++ b/odex-event/muk_dms/static/src/img/thumbnails/file_dll.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/odex-event/muk_dms/static/src/img/thumbnails/file_doc.svg b/odex-event/muk_dms/static/src/img/thumbnails/file_doc.svg
new file mode 100644
index 000000000..b4592ae91
--- /dev/null
+++ b/odex-event/muk_dms/static/src/img/thumbnails/file_doc.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/odex-event/muk_dms/static/src/img/thumbnails/file_docx.svg b/odex-event/muk_dms/static/src/img/thumbnails/file_docx.svg
new file mode 100644
index 000000000..5350ef9ee
--- /dev/null
+++ b/odex-event/muk_dms/static/src/img/thumbnails/file_docx.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/odex-event/muk_dms/static/src/img/thumbnails/file_dwg.svg b/odex-event/muk_dms/static/src/img/thumbnails/file_dwg.svg
new file mode 100644
index 000000000..c8d31f5bd
--- /dev/null
+++ b/odex-event/muk_dms/static/src/img/thumbnails/file_dwg.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/odex-event/muk_dms/static/src/img/thumbnails/file_eml.svg b/odex-event/muk_dms/static/src/img/thumbnails/file_eml.svg
new file mode 100644
index 000000000..d508814d2
--- /dev/null
+++ b/odex-event/muk_dms/static/src/img/thumbnails/file_eml.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/odex-event/muk_dms/static/src/img/thumbnails/file_eps.svg b/odex-event/muk_dms/static/src/img/thumbnails/file_eps.svg
new file mode 100644
index 000000000..bcbdf4b67
--- /dev/null
+++ b/odex-event/muk_dms/static/src/img/thumbnails/file_eps.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/odex-event/muk_dms/static/src/img/thumbnails/file_exe.svg b/odex-event/muk_dms/static/src/img/thumbnails/file_exe.svg
new file mode 100644
index 000000000..c1f6dc1d9
--- /dev/null
+++ b/odex-event/muk_dms/static/src/img/thumbnails/file_exe.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/odex-event/muk_dms/static/src/img/thumbnails/file_f.svg b/odex-event/muk_dms/static/src/img/thumbnails/file_f.svg
new file mode 100644
index 000000000..67a86d06e
--- /dev/null
+++ b/odex-event/muk_dms/static/src/img/thumbnails/file_f.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/odex-event/muk_dms/static/src/img/thumbnails/file_fla.svg b/odex-event/muk_dms/static/src/img/thumbnails/file_fla.svg
new file mode 100644
index 000000000..7d764f6fd
--- /dev/null
+++ b/odex-event/muk_dms/static/src/img/thumbnails/file_fla.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/odex-event/muk_dms/static/src/img/thumbnails/file_gif.svg b/odex-event/muk_dms/static/src/img/thumbnails/file_gif.svg
new file mode 100644
index 000000000..d862dec91
--- /dev/null
+++ b/odex-event/muk_dms/static/src/img/thumbnails/file_gif.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/odex-event/muk_dms/static/src/img/thumbnails/file_go.svg b/odex-event/muk_dms/static/src/img/thumbnails/file_go.svg
new file mode 100644
index 000000000..1f1880da8
--- /dev/null
+++ b/odex-event/muk_dms/static/src/img/thumbnails/file_go.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/odex-event/muk_dms/static/src/img/thumbnails/file_groovy.svg b/odex-event/muk_dms/static/src/img/thumbnails/file_groovy.svg
new file mode 100644
index 000000000..464c1f5af
--- /dev/null
+++ b/odex-event/muk_dms/static/src/img/thumbnails/file_groovy.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/odex-event/muk_dms/static/src/img/thumbnails/file_html.svg b/odex-event/muk_dms/static/src/img/thumbnails/file_html.svg
new file mode 100644
index 000000000..73d5c6388
--- /dev/null
+++ b/odex-event/muk_dms/static/src/img/thumbnails/file_html.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/odex-event/muk_dms/static/src/img/thumbnails/file_iso.svg b/odex-event/muk_dms/static/src/img/thumbnails/file_iso.svg
new file mode 100644
index 000000000..2994d9db6
--- /dev/null
+++ b/odex-event/muk_dms/static/src/img/thumbnails/file_iso.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/odex-event/muk_dms/static/src/img/thumbnails/file_java.svg b/odex-event/muk_dms/static/src/img/thumbnails/file_java.svg
new file mode 100644
index 000000000..5847561bc
--- /dev/null
+++ b/odex-event/muk_dms/static/src/img/thumbnails/file_java.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/odex-event/muk_dms/static/src/img/thumbnails/file_jpg.svg b/odex-event/muk_dms/static/src/img/thumbnails/file_jpg.svg
new file mode 100644
index 000000000..c18867816
--- /dev/null
+++ b/odex-event/muk_dms/static/src/img/thumbnails/file_jpg.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/odex-event/muk_dms/static/src/img/thumbnails/file_js.svg b/odex-event/muk_dms/static/src/img/thumbnails/file_js.svg
new file mode 100644
index 000000000..b799c7711
--- /dev/null
+++ b/odex-event/muk_dms/static/src/img/thumbnails/file_js.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/odex-event/muk_dms/static/src/img/thumbnails/file_json.svg b/odex-event/muk_dms/static/src/img/thumbnails/file_json.svg
new file mode 100644
index 000000000..21bcf233f
--- /dev/null
+++ b/odex-event/muk_dms/static/src/img/thumbnails/file_json.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/odex-event/muk_dms/static/src/img/thumbnails/file_less.svg b/odex-event/muk_dms/static/src/img/thumbnails/file_less.svg
new file mode 100644
index 000000000..9934ccd61
--- /dev/null
+++ b/odex-event/muk_dms/static/src/img/thumbnails/file_less.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/odex-event/muk_dms/static/src/img/thumbnails/file_md.svg b/odex-event/muk_dms/static/src/img/thumbnails/file_md.svg
new file mode 100644
index 000000000..9f11fbd1c
--- /dev/null
+++ b/odex-event/muk_dms/static/src/img/thumbnails/file_md.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/odex-event/muk_dms/static/src/img/thumbnails/file_mov.svg b/odex-event/muk_dms/static/src/img/thumbnails/file_mov.svg
new file mode 100644
index 000000000..3ab4cce1a
--- /dev/null
+++ b/odex-event/muk_dms/static/src/img/thumbnails/file_mov.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/odex-event/muk_dms/static/src/img/thumbnails/file_mp3.svg b/odex-event/muk_dms/static/src/img/thumbnails/file_mp3.svg
new file mode 100644
index 000000000..c21d4aa92
--- /dev/null
+++ b/odex-event/muk_dms/static/src/img/thumbnails/file_mp3.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/odex-event/muk_dms/static/src/img/thumbnails/file_mp4.svg b/odex-event/muk_dms/static/src/img/thumbnails/file_mp4.svg
new file mode 100644
index 000000000..0f3dcaead
--- /dev/null
+++ b/odex-event/muk_dms/static/src/img/thumbnails/file_mp4.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/odex-event/muk_dms/static/src/img/thumbnails/file_odp.svg b/odex-event/muk_dms/static/src/img/thumbnails/file_odp.svg
new file mode 100644
index 000000000..8ba4b924f
--- /dev/null
+++ b/odex-event/muk_dms/static/src/img/thumbnails/file_odp.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/odex-event/muk_dms/static/src/img/thumbnails/file_ods.svg b/odex-event/muk_dms/static/src/img/thumbnails/file_ods.svg
new file mode 100644
index 000000000..490143529
--- /dev/null
+++ b/odex-event/muk_dms/static/src/img/thumbnails/file_ods.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/odex-event/muk_dms/static/src/img/thumbnails/file_odt.svg b/odex-event/muk_dms/static/src/img/thumbnails/file_odt.svg
new file mode 100644
index 000000000..731b433b9
--- /dev/null
+++ b/odex-event/muk_dms/static/src/img/thumbnails/file_odt.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/odex-event/muk_dms/static/src/img/thumbnails/file_pdf.svg b/odex-event/muk_dms/static/src/img/thumbnails/file_pdf.svg
new file mode 100644
index 000000000..fd555e40c
--- /dev/null
+++ b/odex-event/muk_dms/static/src/img/thumbnails/file_pdf.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/odex-event/muk_dms/static/src/img/thumbnails/file_php.svg b/odex-event/muk_dms/static/src/img/thumbnails/file_php.svg
new file mode 100644
index 000000000..92f22d755
--- /dev/null
+++ b/odex-event/muk_dms/static/src/img/thumbnails/file_php.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/odex-event/muk_dms/static/src/img/thumbnails/file_png.svg b/odex-event/muk_dms/static/src/img/thumbnails/file_png.svg
new file mode 100644
index 000000000..844bcbeec
--- /dev/null
+++ b/odex-event/muk_dms/static/src/img/thumbnails/file_png.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/odex-event/muk_dms/static/src/img/thumbnails/file_ppt.svg b/odex-event/muk_dms/static/src/img/thumbnails/file_ppt.svg
new file mode 100644
index 000000000..cb0f6a2d1
--- /dev/null
+++ b/odex-event/muk_dms/static/src/img/thumbnails/file_ppt.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/odex-event/muk_dms/static/src/img/thumbnails/file_pptx.svg b/odex-event/muk_dms/static/src/img/thumbnails/file_pptx.svg
new file mode 100644
index 000000000..62c9aff03
--- /dev/null
+++ b/odex-event/muk_dms/static/src/img/thumbnails/file_pptx.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/odex-event/muk_dms/static/src/img/thumbnails/file_psd.svg b/odex-event/muk_dms/static/src/img/thumbnails/file_psd.svg
new file mode 100644
index 000000000..0f8259c8f
--- /dev/null
+++ b/odex-event/muk_dms/static/src/img/thumbnails/file_psd.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/odex-event/muk_dms/static/src/img/thumbnails/file_py.svg b/odex-event/muk_dms/static/src/img/thumbnails/file_py.svg
new file mode 100644
index 000000000..efa13b2e2
--- /dev/null
+++ b/odex-event/muk_dms/static/src/img/thumbnails/file_py.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/odex-event/muk_dms/static/src/img/thumbnails/file_rar.svg b/odex-event/muk_dms/static/src/img/thumbnails/file_rar.svg
new file mode 100644
index 000000000..8c53141ab
--- /dev/null
+++ b/odex-event/muk_dms/static/src/img/thumbnails/file_rar.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/odex-event/muk_dms/static/src/img/thumbnails/file_raw.svg b/odex-event/muk_dms/static/src/img/thumbnails/file_raw.svg
new file mode 100644
index 000000000..b25258558
--- /dev/null
+++ b/odex-event/muk_dms/static/src/img/thumbnails/file_raw.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/odex-event/muk_dms/static/src/img/thumbnails/file_rtf.svg b/odex-event/muk_dms/static/src/img/thumbnails/file_rtf.svg
new file mode 100644
index 000000000..6f1829ed1
--- /dev/null
+++ b/odex-event/muk_dms/static/src/img/thumbnails/file_rtf.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/odex-event/muk_dms/static/src/img/thumbnails/file_sass.svg b/odex-event/muk_dms/static/src/img/thumbnails/file_sass.svg
new file mode 100644
index 000000000..4aca765b2
--- /dev/null
+++ b/odex-event/muk_dms/static/src/img/thumbnails/file_sass.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/odex-event/muk_dms/static/src/img/thumbnails/file_sc.svg b/odex-event/muk_dms/static/src/img/thumbnails/file_sc.svg
new file mode 100644
index 000000000..7855254ce
--- /dev/null
+++ b/odex-event/muk_dms/static/src/img/thumbnails/file_sc.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/odex-event/muk_dms/static/src/img/thumbnails/file_sh.svg b/odex-event/muk_dms/static/src/img/thumbnails/file_sh.svg
new file mode 100644
index 000000000..59e6c6835
--- /dev/null
+++ b/odex-event/muk_dms/static/src/img/thumbnails/file_sh.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/odex-event/muk_dms/static/src/img/thumbnails/file_svg.svg b/odex-event/muk_dms/static/src/img/thumbnails/file_svg.svg
new file mode 100644
index 000000000..ad897f2d1
--- /dev/null
+++ b/odex-event/muk_dms/static/src/img/thumbnails/file_svg.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/odex-event/muk_dms/static/src/img/thumbnails/file_tar.svg b/odex-event/muk_dms/static/src/img/thumbnails/file_tar.svg
new file mode 100644
index 000000000..a09099c4d
--- /dev/null
+++ b/odex-event/muk_dms/static/src/img/thumbnails/file_tar.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/odex-event/muk_dms/static/src/img/thumbnails/file_ttf.svg b/odex-event/muk_dms/static/src/img/thumbnails/file_ttf.svg
new file mode 100644
index 000000000..908dc240b
--- /dev/null
+++ b/odex-event/muk_dms/static/src/img/thumbnails/file_ttf.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/odex-event/muk_dms/static/src/img/thumbnails/file_txt.svg b/odex-event/muk_dms/static/src/img/thumbnails/file_txt.svg
new file mode 100644
index 000000000..430fa4069
--- /dev/null
+++ b/odex-event/muk_dms/static/src/img/thumbnails/file_txt.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/odex-event/muk_dms/static/src/img/thumbnails/file_unkown.svg b/odex-event/muk_dms/static/src/img/thumbnails/file_unkown.svg
new file mode 100644
index 000000000..a615b128b
--- /dev/null
+++ b/odex-event/muk_dms/static/src/img/thumbnails/file_unkown.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/odex-event/muk_dms/static/src/img/thumbnails/file_wav.svg b/odex-event/muk_dms/static/src/img/thumbnails/file_wav.svg
new file mode 100644
index 000000000..236b7a840
--- /dev/null
+++ b/odex-event/muk_dms/static/src/img/thumbnails/file_wav.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/odex-event/muk_dms/static/src/img/thumbnails/file_xls.svg b/odex-event/muk_dms/static/src/img/thumbnails/file_xls.svg
new file mode 100644
index 000000000..d9e9ef110
--- /dev/null
+++ b/odex-event/muk_dms/static/src/img/thumbnails/file_xls.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/odex-event/muk_dms/static/src/img/thumbnails/file_xlsx.svg b/odex-event/muk_dms/static/src/img/thumbnails/file_xlsx.svg
new file mode 100644
index 000000000..3322694fc
--- /dev/null
+++ b/odex-event/muk_dms/static/src/img/thumbnails/file_xlsx.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/odex-event/muk_dms/static/src/img/thumbnails/file_xml.svg b/odex-event/muk_dms/static/src/img/thumbnails/file_xml.svg
new file mode 100644
index 000000000..116dc43cd
--- /dev/null
+++ b/odex-event/muk_dms/static/src/img/thumbnails/file_xml.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/odex-event/muk_dms/static/src/img/thumbnails/file_zip.svg b/odex-event/muk_dms/static/src/img/thumbnails/file_zip.svg
new file mode 100644
index 000000000..c99b0f98c
--- /dev/null
+++ b/odex-event/muk_dms/static/src/img/thumbnails/file_zip.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/odex-event/muk_dms/static/src/img/thumbnails/folder.svg b/odex-event/muk_dms/static/src/img/thumbnails/folder.svg
new file mode 100644
index 000000000..dfc3cf522
--- /dev/null
+++ b/odex-event/muk_dms/static/src/img/thumbnails/folder.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/odex-event/muk_dms/static/src/js/views/directory/form/directory_form_controller.js b/odex-event/muk_dms/static/src/js/views/directory/form/directory_form_controller.js
new file mode 100644
index 000000000..a838734ad
--- /dev/null
+++ b/odex-event/muk_dms/static/src/js/views/directory/form/directory_form_controller.js
@@ -0,0 +1,60 @@
+/**********************************************************************************
+*
+* Copyright (c) 2017-2019 MuK IT GmbH.
+*
+* This file is part of MuK Documents
+* (see https://mukit.at).
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program. If not, see .
+*
+**********************************************************************************/
+
+odoo.define('muk_dms.DirectoryFormController', function (require) {
+"use strict";
+
+var core = require('web.core');
+var ajax = require('web.ajax');
+var session = require('web.session');
+
+var FormController = require('web.FormController');
+
+var _t = core._t;
+var QWeb = core.qweb;
+
+var DirectoryFormController = FormController.extend({
+ createRecord: function (parentID) {
+ var record = this.model.get(this.handle, {raw: true});
+ var context = _.extend({}, record.getContext(), {
+ default_parent_directory: record.data.id,
+ });
+ return this.model.load({
+ context: context,
+ fields: record.fields,
+ fieldsInfo: record.fieldsInfo,
+ modelName: this.modelName,
+ parentID: parentID,
+ res_ids: record.res_ids,
+ type: 'record',
+ viewType: 'form',
+ }).then(function (handle) {
+ this.handle = handle;
+ this._updateEnv();
+ return this._setMode('edit');
+ }.bind(this));
+ },
+});
+
+return DirectoryFormController;
+
+});
diff --git a/odex-event/muk_dms/static/src/js/views/directory/form/directory_form_view.js b/odex-event/muk_dms/static/src/js/views/directory/form/directory_form_view.js
new file mode 100644
index 000000000..ef5af1785
--- /dev/null
+++ b/odex-event/muk_dms/static/src/js/views/directory/form/directory_form_view.js
@@ -0,0 +1,46 @@
+/**********************************************************************************
+*
+* Copyright (c) 2017-2019 MuK IT GmbH.
+*
+* This file is part of MuK Documents
+* (see https://mukit.at).
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program. If not, see .
+*
+**********************************************************************************/
+
+odoo.define('muk_dms.DirectoryFormView', function (require) {
+"use strict";
+
+var core = require('web.core');
+var registry = require('web.view_registry');
+
+var FormView = require('web.FormView');
+
+var DirectoryFormController = require('muk_dms.DirectoryFormController');
+
+var _t = core._t;
+var QWeb = core.qweb;
+
+var DirectoryFormView = FormView.extend({
+ config: _.extend({}, FormView.prototype.config, {
+ Controller: DirectoryFormController,
+ }),
+});
+
+registry.add('directory_form', DirectoryFormView);
+
+return DirectoryFormView;
+
+});
diff --git a/odex-event/muk_dms/static/src/js/views/file/form/file_form_controller.js b/odex-event/muk_dms/static/src/js/views/file/form/file_form_controller.js
new file mode 100644
index 000000000..842eb393d
--- /dev/null
+++ b/odex-event/muk_dms/static/src/js/views/file/form/file_form_controller.js
@@ -0,0 +1,60 @@
+/**********************************************************************************
+*
+* Copyright (c) 2017-2019 MuK IT GmbH.
+*
+* This file is part of MuK Documents
+* (see https://mukit.at).
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program. If not, see .
+*
+**********************************************************************************/
+
+odoo.define('muk_dms.FileFormController', function (require) {
+"use strict";
+
+var core = require('web.core');
+var ajax = require('web.ajax');
+var session = require('web.session');
+
+var FormController = require('web.FormController');
+
+var _t = core._t;
+var QWeb = core.qweb;
+
+var FileFormController = FormController.extend({
+ createRecord: function (parentID) {
+ var record = this.model.get(this.handle, {raw: true});
+ var context = _.extend({}, record.getContext(), {
+ default_directory: record.data.directory,
+ });
+ return this.model.load({
+ context: context,
+ fields: record.fields,
+ fieldsInfo: record.fieldsInfo,
+ modelName: this.modelName,
+ parentID: parentID,
+ res_ids: record.res_ids,
+ type: 'record',
+ viewType: 'form',
+ }).then(function (handle) {
+ this.handle = handle;
+ this._updateEnv();
+ return this._setMode('edit');
+ }.bind(this));
+ },
+});
+
+return FileFormController;
+
+});
diff --git a/odex-event/muk_dms/static/src/js/views/file/form/file_form_view.js b/odex-event/muk_dms/static/src/js/views/file/form/file_form_view.js
new file mode 100644
index 000000000..49b26e281
--- /dev/null
+++ b/odex-event/muk_dms/static/src/js/views/file/form/file_form_view.js
@@ -0,0 +1,46 @@
+/**********************************************************************************
+*
+* Copyright (c) 2017-2019 MuK IT GmbH.
+*
+* This file is part of MuK Documents
+* (see https://mukit.at).
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program. If not, see .
+*
+**********************************************************************************/
+
+odoo.define('muk_dms.FileFormView', function (require) {
+"use strict";
+
+var core = require('web.core');
+var registry = require('web.view_registry');
+
+var FormView = require('web.FormView');
+
+var FileFormController = require('muk_dms.FileFormController');
+
+var _t = core._t;
+var QWeb = core.qweb;
+
+var FileFormView = FormView.extend({
+ config: _.extend({}, FormView.prototype.config, {
+ Controller: FileFormController,
+ }),
+});
+
+registry.add('file_form', FileFormView);
+
+return FileFormView;
+
+});
diff --git a/odex-event/muk_dms/static/src/js/views/file/kanban/file_kanban_controller.js b/odex-event/muk_dms/static/src/js/views/file/kanban/file_kanban_controller.js
new file mode 100644
index 000000000..8423d348a
--- /dev/null
+++ b/odex-event/muk_dms/static/src/js/views/file/kanban/file_kanban_controller.js
@@ -0,0 +1,68 @@
+/**********************************************************************************
+*
+* Copyright (c) 2017-2019 MuK IT GmbH.
+*
+* This file is part of MuK Documents
+* (see https://mukit.at).
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program. If not, see .
+*
+**********************************************************************************/
+
+odoo.define('muk_dms.FileKanbanController', function (require) {
+"use strict";
+
+var core = require('web.core');
+var session = require('web.session');
+
+var utils = require('muk_web_utils.files');
+var async = require('muk_web_utils.async');
+
+var Domain = require('web.Domain');
+var KanbanController = require('web.KanbanController');
+
+var FileUpload = require('muk_dms_mixins.FileUpload');
+
+var _t = core._t;
+var QWeb = core.qweb;
+
+var FileKanbanController = KanbanController.extend(FileUpload, {
+ custom_events: _.extend({}, KanbanController.prototype.custom_events, {
+ upload_files: '_onUploadFiles',
+ }),
+ _getSelectedDirectory: function () {
+ var record = this.model.get(this.handle, {raw: true});
+ var directoryID = this._searchPanel.getSelectedDirectory();
+ var context = record.getContext();
+ if (directoryID) {
+ return directoryID;
+ } else if (context.active_model === "muk_dms.directory") {
+ return context.active_id;
+ }
+ },
+ _onUploadFiles: function(event) {
+ var directoryID = this._getSelectedDirectory();
+ if (directoryID) {
+ utils.getFileTree(event.data.items, true).then(
+ this._uploadFiles.bind(this, directoryID)
+ );
+ } else {
+ this.do_warn(_t("Upload Error"), _t("No Directory has been selected!"));
+ }
+ },
+});
+
+return FileKanbanController;
+
+});
diff --git a/odex-event/muk_dms/static/src/js/views/file/kanban/file_kanban_model.js b/odex-event/muk_dms/static/src/js/views/file/kanban/file_kanban_model.js
new file mode 100644
index 000000000..ce4fcfe35
--- /dev/null
+++ b/odex-event/muk_dms/static/src/js/views/file/kanban/file_kanban_model.js
@@ -0,0 +1,41 @@
+/**********************************************************************************
+*
+* Copyright (c) 2017-2019 MuK IT GmbH.
+*
+* This file is part of MuK Documents
+* (see https://mukit.at).
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program. If not, see .
+*
+**********************************************************************************/
+
+odoo.define('muk_dms.FileKanbanModel', function (require) {
+"use strict";
+
+var core = require('web.core');
+var session = require('web.session');
+
+var Domain = require('web.Domain');
+var KanbanModel = require('web.KanbanModel');
+
+var _t = core._t;
+var QWeb = core.qweb;
+
+var FileKanbanModel = KanbanModel.extend({
+
+});
+
+return FileKanbanModel;
+
+});
diff --git a/odex-event/muk_dms/static/src/js/views/file/kanban/file_kanban_record.js b/odex-event/muk_dms/static/src/js/views/file/kanban/file_kanban_record.js
new file mode 100644
index 000000000..db5edcad6
--- /dev/null
+++ b/odex-event/muk_dms/static/src/js/views/file/kanban/file_kanban_record.js
@@ -0,0 +1,41 @@
+/**********************************************************************************
+*
+* Copyright (c) 2017-2019 MuK IT GmbH.
+*
+* This file is part of MuK Documents
+* (see https://mukit.at).
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program. If not, see .
+*
+**********************************************************************************/
+
+odoo.define('muk_dms.FileKanbanRecord', function (require) {
+"use strict";
+
+var core = require('web.core');
+var ajax = require('web.ajax');
+var session = require('web.session');
+
+var KanbanRecord = require('web.KanbanRecord');
+
+var _t = core._t;
+var QWeb = core.qweb;
+
+var FileKanbanRecord = KanbanRecord.extend({
+
+});
+
+return FileKanbanRecord;
+
+});
diff --git a/odex-event/muk_dms/static/src/js/views/file/kanban/file_kanban_renderer.js b/odex-event/muk_dms/static/src/js/views/file/kanban/file_kanban_renderer.js
new file mode 100644
index 000000000..00a07f42c
--- /dev/null
+++ b/odex-event/muk_dms/static/src/js/views/file/kanban/file_kanban_renderer.js
@@ -0,0 +1,64 @@
+/**********************************************************************************
+*
+* Copyright (c) 2017-2019 MuK IT GmbH.
+*
+* This file is part of MuK Documents
+* (see https://mukit.at).
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program. If not, see .
+*
+**********************************************************************************/
+
+odoo.define('muk_dms.FileKanbanRenderer', function (require) {
+"use strict";
+
+var core = require('web.core');
+var config = require('web.config');
+var session = require('web.session');
+
+var dropzone = require('muk_web_utils.dropzone');
+
+var KanbanRenderer = require('web.KanbanRenderer');
+var FileKanbanRecord = require('muk_dms.FileKanbanRecord');
+
+var _t = core._t;
+var QWeb = core.qweb;
+
+var FileKanbanRenderer = KanbanRenderer.extend(dropzone.FileDropzoneMixin, {
+ config: _.extend({}, KanbanRenderer.prototype.config, {
+ KanbanRecord: FileKanbanRecord,
+ }),
+ start: function () {
+ var res = this._super.apply(this, arguments);
+ this._startDropzone(this.$el);
+ return res;
+ },
+ destroy: function () {
+ var res = this._super.apply(this, arguments);
+ this._destroyDropzone(this.$el);
+ return res;
+ },
+ _handleDrop: function(event) {
+ var dataTransfer = event.originalEvent.dataTransfer;
+ if (dataTransfer.items && dataTransfer.items.length > 0) {
+ this.trigger_up('upload_files', {
+ items: dataTransfer.items
+ });
+ }
+ },
+});
+
+return FileKanbanRenderer;
+
+});
diff --git a/odex-event/muk_dms/static/src/js/views/file/kanban/file_kanban_searchpanel.js b/odex-event/muk_dms/static/src/js/views/file/kanban/file_kanban_searchpanel.js
new file mode 100644
index 000000000..e9dcab191
--- /dev/null
+++ b/odex-event/muk_dms/static/src/js/views/file/kanban/file_kanban_searchpanel.js
@@ -0,0 +1,46 @@
+/**********************************************************************************
+*
+* Copyright (c) 2017-2019 MuK IT GmbH.
+*
+* This file is part of MuK Documents
+* (see https://mukit.at).
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program. If not, see .
+*
+**********************************************************************************/
+
+odoo.define('muk_dms.FileSearchPanel', function (require) {
+"use strict";
+
+var core = require('web.core');
+var ajax = require('web.ajax');
+var session = require('web.session');
+
+var SearchPanel = require('web.SearchPanel');
+
+var _t = core._t;
+var QWeb = core.qweb;
+
+var FileSearchPanel = SearchPanel.extend({
+ getSelectedDirectory: function () {
+ var category = _.findWhere(this.categories, {
+ fieldName: 'directory'
+ });
+ return category.activeValueId;
+ },
+});
+
+return FileSearchPanel;
+
+});
\ No newline at end of file
diff --git a/odex-event/muk_dms/static/src/js/views/file/kanban/file_kanban_view.js b/odex-event/muk_dms/static/src/js/views/file/kanban/file_kanban_view.js
new file mode 100644
index 000000000..8c316c50a
--- /dev/null
+++ b/odex-event/muk_dms/static/src/js/views/file/kanban/file_kanban_view.js
@@ -0,0 +1,52 @@
+/**********************************************************************************
+*
+* Copyright (c) 2017-2019 MuK IT GmbH.
+*
+* This file is part of MuK Documents
+* (see https://mukit.at).
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program. If not, see .
+*
+**********************************************************************************/
+
+odoo.define('muk_dms.FileKanbanView', function (require) {
+"use strict";
+
+var core = require('web.core');
+var registry = require('web.view_registry');
+
+var KanbanView = require('web.KanbanView');
+
+var FileKanbanModel = require('muk_dms.FileKanbanModel');
+var FileKanbanRenderer = require('muk_dms.FileKanbanRenderer');
+var FileKanbanController = require('muk_dms.FileKanbanController');
+var FileSearchPanel = require('muk_dms.FileSearchPanel');
+
+var _t = core._t;
+var QWeb = core.qweb;
+
+var FileKanbanView = KanbanView.extend({
+ config: _.extend({}, KanbanView.prototype.config, {
+ Renderer: FileKanbanRenderer,
+ Controller: FileKanbanController,
+ Model: FileKanbanModel,
+ SearchPanel: FileSearchPanel,
+ }),
+});
+
+registry.add('file_kanban', FileKanbanView);
+
+return FileKanbanView;
+
+});
diff --git a/odex-event/muk_dms/static/src/js/views/file/list/file_list_controller.js b/odex-event/muk_dms/static/src/js/views/file/list/file_list_controller.js
new file mode 100644
index 000000000..3371b4976
--- /dev/null
+++ b/odex-event/muk_dms/static/src/js/views/file/list/file_list_controller.js
@@ -0,0 +1,39 @@
+/**********************************************************************************
+*
+* Copyright (c) 2017-2019 MuK IT GmbH.
+*
+* This file is part of MuK Documents
+* (see https://mukit.at).
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program. If not, see .
+*
+**********************************************************************************/
+
+odoo.define('muk_dms.FileListController', function (require) {
+"use strict";
+
+var core = require('web.core');
+var ajax = require('web.ajax');
+var session = require('web.session');
+
+var ListController = require('web.ListController');
+
+var _t = core._t;
+var QWeb = core.qweb;
+
+var FileListController = ListController.extend({});
+
+return FileListController;
+
+});
diff --git a/odex-event/muk_dms/static/src/js/views/file/list/file_list_view.js b/odex-event/muk_dms/static/src/js/views/file/list/file_list_view.js
new file mode 100644
index 000000000..d2ede3387
--- /dev/null
+++ b/odex-event/muk_dms/static/src/js/views/file/list/file_list_view.js
@@ -0,0 +1,46 @@
+/**********************************************************************************
+*
+* Copyright (c) 2017-2019 MuK IT GmbH.
+*
+* This file is part of MuK Documents
+* (see https://mukit.at).
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program. If not, see .
+*
+**********************************************************************************/
+
+odoo.define('muk_dms.FileListView', function (require) {
+"use strict";
+
+var core = require('web.core');
+var registry = require('web.view_registry');
+
+var ListView = require('web.ListView');
+
+var FileListController = require('muk_dms.FileListController');
+
+var _t = core._t;
+var QWeb = core.qweb;
+
+var FileListView = ListView.extend({
+ config: _.extend({}, ListView.prototype.config, {
+ Controller: FileListController,
+ }),
+});
+
+registry.add('file_list', FileListView);
+
+return FileListView;
+
+});
diff --git a/odex-event/muk_dms/static/src/js/views/mixins/file_upload.js b/odex-event/muk_dms/static/src/js/views/mixins/file_upload.js
new file mode 100644
index 000000000..05382a8cf
--- /dev/null
+++ b/odex-event/muk_dms/static/src/js/views/mixins/file_upload.js
@@ -0,0 +1,122 @@
+/**********************************************************************************
+*
+* Copyright (c) 2017-2019 MuK IT GmbH.
+*
+* This file is part of MuK Documents
+* (see https://mukit.at).
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program. If not, see .
+*
+**********************************************************************************/
+
+odoo.define('muk_dms_mixins.FileUpload', function (require) {
+
+var core = require('web.core');
+var session = require('web.session');
+
+var utils = require('muk_web_utils.files');
+var async = require('muk_web_utils.async');
+
+var _t = core._t;
+var QWeb = core.qweb;
+
+var FileUploadMixin = {
+ _uploadFile: function(file, directory) {
+ var def = $.Deferred();
+ utils.readFile(file, function (upload) {
+ this._rpc({
+ model: 'muk_dms.file',
+ method: 'create',
+ args: [{
+ 'name': file.name,
+ 'directory': directory,
+ 'content': upload.target.result.split(',')[1],
+ }],
+ context: session.user_context
+ }).then(function (result) {
+ def.resolve(result);
+ });
+ }.bind(this));
+ return def;
+ },
+ _createUploadDirectory: function(name, parent_id) {
+ return this._rpc({
+ model: 'muk_dms.directory',
+ method: 'create',
+ args: [{
+ 'name': name,
+ 'parent_directory': parent_id,
+ }],
+ context: session.user_context,
+ });
+ },
+ _createUploadNotification: function() {
+ return this.call('notification', 'notify', {
+ title: _t('Upload Files'),
+ message: _t('Uploading...'),
+ icon: 'fa-upload',
+ sticky: true,
+ progress: {
+ text: "0%",
+ state: 0.0,
+ },
+ });
+ },
+ _updateUploadNotification: function(notification, progress) {
+ this.call('notification', 'progress', notification, {
+ text: (progress * 100).toFixed(2) + "%",
+ state: (progress * 100).toFixed(2),
+ });
+ },
+ _closeUploadNotification: function(notification) {
+ this.call('notification', 'close', notification);
+ },
+ _uploadFiles: function(directory, tree) {
+ var progress = 0;
+ var notification = this._createUploadNotification();
+ var upload = function(parent_id, item) {
+ var def = $.Deferred();
+ if(item.isFile || item.isFileItem) {
+ this._uploadFile(item, parent_id).then(function(res) {
+ this._updateUploadNotification(notification, ++progress / tree.count);
+ def.resolve(res);
+ }.bind(this));
+ } else if(item.isDirectory) {
+ this._createUploadDirectory(item.name, parent_id).then(function(id) {
+ async.syncLoop(
+ item.files,
+ upload.bind(this, id),
+ function(res) {
+ def.resolve(id);
+ }
+ );
+ }.bind(this));
+ }
+ return def;
+ };
+ var finish = function() {
+ this._closeUploadNotification(notification);
+ this.reload();
+ };
+ async.syncLoop(
+ tree.files,
+ upload.bind(this, directory),
+ finish.bind(this),
+ );
+ },
+};
+
+return FileUploadMixin;
+
+});
diff --git a/odex-event/muk_dms/static/src/scss/directory_kanban.scss b/odex-event/muk_dms/static/src/scss/directory_kanban.scss
new file mode 100644
index 000000000..9d16d1d76
--- /dev/null
+++ b/odex-event/muk_dms/static/src/scss/directory_kanban.scss
@@ -0,0 +1,103 @@
+/**********************************************************************************
+*
+* Copyright (c) 2017-2019 MuK IT GmbH.
+*
+* This file is part of MuK Documents
+* (see https://mukit.at).
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program. If not, see .
+*
+**********************************************************************************/
+
+.mk_directory_kanban_view {
+ height: 100%;
+ .o_kanban_record {
+ padding: 0;
+ max-height: $o-kanban-image-width + 1;
+ .mk_directory_kanban_actions {
+ float: left;
+ border-right: solid 1px $gray-400;
+ .mk_directory_kanban_actions_wrapper {
+ min-height: $o-kanban-image-width;
+ .btn-outline-primary {
+ display: flex;
+ border-radius: 0;
+ align-items: center;
+ justify-content: center;
+ border-color: transparent;
+ min-width: $o-kanban-image-width / 2;
+ min-height: $o-kanban-image-width / 2;
+ &.mk_directory_kanban_directories {
+ border-bottom: solid 1px $gray-400;
+ }
+ }
+ }
+ }
+ .o_kanban_image {
+ width: $o-kanban-image-width + 1;
+ border-right: solid 1px $gray-400;
+ + div {
+ padding-left: $o-kanban-image-width + $o-kanban-inside-hgutter + $o-kanban-image-width / 2;
+ @include media-breakpoint-down(sm) {
+ padding-left: $o-kanban-image-width + $o-kanban-inside-hgutter-mobile + $o-kanban-image-width / 2;
+ }
+ }
+ }
+ .o_kanban_details .o_kanban_details_wrapper {
+ padding: 4px 4px 4px 0;
+ .o_kanban_record_title {
+ font-weight: bold;
+ padding-right: 16px;
+ }
+ .o_kanban_record_body {
+ max-height: 12px;
+ .o_kanban_tags {
+ @include o-text-overflow;
+ }
+ }
+ .oe_kanban_avatar {
+ margin-left: 0px;
+ }
+ .favorite_sign_button {
+ margin-top: 1px;
+ font-size: 1.5rem;
+ line-height: 20px;
+ margin-right: 6px;
+ }
+ }
+ .o_dropdown_kanban {
+ .dropdown-menu {
+ min-width: 22rem;
+ .mk_directory_kanban_views {
+ padding-right: 8px;
+ }
+ .mk_directory_kanban_actions {
+ padding-left: 8px;
+ border-right: none;
+ }
+ .fa {
+ min-width: 12px;
+ padding-right: 2px;
+ text-align: center;
+ }
+ .oe_kanban_colorpicker {
+ max-width: none;
+ margin: 5px 5px;
+ padding: 10px 0 0 25px;
+ border-top: 1px solid gray('300');
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/odex-event/muk_dms/static/src/scss/file_kanban.scss b/odex-event/muk_dms/static/src/scss/file_kanban.scss
new file mode 100644
index 000000000..9f3b2879c
--- /dev/null
+++ b/odex-event/muk_dms/static/src/scss/file_kanban.scss
@@ -0,0 +1,77 @@
+/**********************************************************************************
+*
+* Copyright (c) 2017-2019 MuK IT GmbH.
+*
+* This file is part of MuK Documents
+* (see https://mukit.at).
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program. If not, see .
+*
+**********************************************************************************/
+
+.mk_file_kanban_view {
+ height: 100%;
+ .o_kanban_record {
+ padding: 0;
+ max-height: $o-kanban-image-width + 1;
+ .o_kanban_image {
+ width: $o-kanban-image-width + 1;
+ border-right: solid 1px $gray-400;
+ }
+ .o_kanban_details .o_kanban_details_wrapper {
+ padding: 4px 4px 4px 0;
+ .o_kanban_record_title {
+ font-weight: bold;
+ padding-right: 16px;
+ }
+ .o_kanban_record_body {
+ max-height: 12px;
+ .o_kanban_tags {
+ @include o-text-overflow;
+ }
+ }
+ .oe_kanban_avatar {
+ margin-left: 0px;
+ }
+ .mk_file_kanban_lock {
+ margin-top: 2px;
+ font-size: 1.2rem;
+ line-height: 20px;
+ margin-right: 6px;
+ }
+ }
+ .o_dropdown_kanban {
+ .dropdown-menu {
+ min-width: 22rem;
+ .mk_file_kanban_operations {
+ padding-right: 8px;
+ }
+ .mk_file_kanban_actions {
+ padding-left: 8px;
+ }
+ .fa {
+ min-width: 12px;
+ padding-right: 2px;
+ text-align: center;
+ }
+ .oe_kanban_colorpicker {
+ max-width: none;
+ margin: 5px 5px;
+ padding: 10px 0 0 25px;
+ border-top: 1px solid gray('300');
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/odex-event/muk_dms/static/src/scss/variables.scss b/odex-event/muk_dms/static/src/scss/variables.scss
new file mode 100644
index 000000000..1f9ce7294
--- /dev/null
+++ b/odex-event/muk_dms/static/src/scss/variables.scss
@@ -0,0 +1,24 @@
+/**********************************************************************************
+*
+* Copyright (c) 2017-2019 MuK IT GmbH.
+*
+* This file is part of MuK Documents
+* (see https://mukit.at).
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program. If not, see .
+*
+**********************************************************************************/
+
+$mk-file-kanban-sidebar-width: 200px;
+$mk-file-kanban-sidebar-padding: 8px;
\ No newline at end of file
diff --git a/odex-event/muk_dms/static/src/xml/views.xml b/odex-event/muk_dms/static/src/xml/views.xml
new file mode 100644
index 000000000..c518369a3
--- /dev/null
+++ b/odex-event/muk_dms/static/src/xml/views.xml
@@ -0,0 +1,121 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/odex-event/muk_security/LICENSE b/odex-event/muk_security/LICENSE
new file mode 100644
index 000000000..153d416dc
--- /dev/null
+++ b/odex-event/muk_security/LICENSE
@@ -0,0 +1,165 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+
+ This version of the GNU Lesser General Public License incorporates
+the terms and conditions of version 3 of the GNU General Public
+License, supplemented by the additional permissions listed below.
+
+ 0. Additional Definitions.
+
+ As used herein, "this License" refers to version 3 of the GNU Lesser
+General Public License, and the "GNU GPL" refers to version 3 of the GNU
+General Public License.
+
+ "The Library" refers to a covered work governed by this License,
+other than an Application or a Combined Work as defined below.
+
+ An "Application" is any work that makes use of an interface provided
+by the Library, but which is not otherwise based on the Library.
+Defining a subclass of a class defined by the Library is deemed a mode
+of using an interface provided by the Library.
+
+ A "Combined Work" is a work produced by combining or linking an
+Application with the Library. The particular version of the Library
+with which the Combined Work was made is also called the "Linked
+Version".
+
+ The "Minimal Corresponding Source" for a Combined Work means the
+Corresponding Source for the Combined Work, excluding any source code
+for portions of the Combined Work that, considered in isolation, are
+based on the Application, and not on the Linked Version.
+
+ The "Corresponding Application Code" for a Combined Work means the
+object code and/or source code for the Application, including any data
+and utility programs needed for reproducing the Combined Work from the
+Application, but excluding the System Libraries of the Combined Work.
+
+ 1. Exception to Section 3 of the GNU GPL.
+
+ You may convey a covered work under sections 3 and 4 of this License
+without being bound by section 3 of the GNU GPL.
+
+ 2. Conveying Modified Versions.
+
+ If you modify a copy of the Library, and, in your modifications, a
+facility refers to a function or data to be supplied by an Application
+that uses the facility (other than as an argument passed when the
+facility is invoked), then you may convey a copy of the modified
+version:
+
+ a) under this License, provided that you make a good faith effort to
+ ensure that, in the event an Application does not supply the
+ function or data, the facility still operates, and performs
+ whatever part of its purpose remains meaningful, or
+
+ b) under the GNU GPL, with none of the additional permissions of
+ this License applicable to that copy.
+
+ 3. Object Code Incorporating Material from Library Header Files.
+
+ The object code form of an Application may incorporate material from
+a header file that is part of the Library. You may convey such object
+code under terms of your choice, provided that, if the incorporated
+material is not limited to numerical parameters, data structure
+layouts and accessors, or small macros, inline functions and templates
+(ten or fewer lines in length), you do both of the following:
+
+ a) Give prominent notice with each copy of the object code that the
+ Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the object code with a copy of the GNU GPL and this license
+ document.
+
+ 4. Combined Works.
+
+ You may convey a Combined Work under terms of your choice that,
+taken together, effectively do not restrict modification of the
+portions of the Library contained in the Combined Work and reverse
+engineering for debugging such modifications, if you also do each of
+the following:
+
+ a) Give prominent notice with each copy of the Combined Work that
+ the Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the Combined Work with a copy of the GNU GPL and this license
+ document.
+
+ c) For a Combined Work that displays copyright notices during
+ execution, include the copyright notice for the Library among
+ these notices, as well as a reference directing the user to the
+ copies of the GNU GPL and this license document.
+
+ d) Do one of the following:
+
+ 0) Convey the Minimal Corresponding Source under the terms of this
+ License, and the Corresponding Application Code in a form
+ suitable for, and under terms that permit, the user to
+ recombine or relink the Application with a modified version of
+ the Linked Version to produce a modified Combined Work, in the
+ manner specified by section 6 of the GNU GPL for conveying
+ Corresponding Source.
+
+ 1) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (a) uses at run time
+ a copy of the Library already present on the user's computer
+ system, and (b) will operate properly with a modified version
+ of the Library that is interface-compatible with the Linked
+ Version.
+
+ e) Provide Installation Information, but only if you would otherwise
+ be required to provide such information under section 6 of the
+ GNU GPL, and only to the extent that such information is
+ necessary to install and execute a modified version of the
+ Combined Work produced by recombining or relinking the
+ Application with a modified version of the Linked Version. (If
+ you use option 4d0, the Installation Information must accompany
+ the Minimal Corresponding Source and Corresponding Application
+ Code. If you use option 4d1, you must provide the Installation
+ Information in the manner specified by section 6 of the GNU GPL
+ for conveying Corresponding Source.)
+
+ 5. Combined Libraries.
+
+ You may place library facilities that are a work based on the
+Library side by side in a single library together with other library
+facilities that are not Applications and are not covered by this
+License, and convey such a combined library under terms of your
+choice, if you do both of the following:
+
+ a) Accompany the combined library with a copy of the same work based
+ on the Library, uncombined with any other library facilities,
+ conveyed under the terms of this License.
+
+ b) Give prominent notice with the combined library that part of it
+ is a work based on the Library, and explaining where to find the
+ accompanying uncombined form of the same work.
+
+ 6. Revised Versions of the GNU Lesser General Public License.
+
+ The Free Software Foundation may publish revised and/or new versions
+of the GNU Lesser General Public License from time to time. Such new
+versions will be similar in spirit to the present version, but may
+differ in detail to address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Library as you received it specifies that a certain numbered version
+of the GNU Lesser General Public License "or any later version"
+applies to it, you have the option of following the terms and
+conditions either of that published version or of any later version
+published by the Free Software Foundation. If the Library as you
+received it does not specify a version number of the GNU Lesser
+General Public License, you may choose any version of the GNU Lesser
+General Public License ever published by the Free Software Foundation.
+
+ If the Library as you received it specifies that a proxy can decide
+whether future versions of the GNU Lesser General Public License shall
+apply, that proxy's public statement of acceptance of any version is
+permanent authorization for you to choose that version for the
+Library.
\ No newline at end of file
diff --git a/odex-event/muk_security/README.rst b/odex-event/muk_security/README.rst
new file mode 100644
index 000000000..154849927
--- /dev/null
+++ b/odex-event/muk_security/README.rst
@@ -0,0 +1,120 @@
+============
+MuK Security
+============
+
+Technical module to provide some utility and security features that can be used
+in other applications. This module has no direct effect on the running system.
+
+Installation
+============
+
+To install this module, you need to:
+
+Download the module and add it to your Odoo addons folder. Afterward, log on to
+your Odoo server and go to the Apps menu. Trigger the debug mode and update the
+list by clicking on the "Update Apps List" link. Now install the module by
+clicking on the install button.
+
+Another way to install this module is via the package management for Python
+(`PyPI `_).
+
+To install our modules using the package manager make sure
+`odoo-autodiscover `_ is installed
+correctly. Then open a console and install the module by entering the following
+command:
+
+``pip install --extra-index-url https://nexus.mukit.at/repository/odoo/simple ``
+
+The module name consists of the Odoo version and the module name, where
+underscores are replaced by a dash.
+
+**Module:**
+
+``odoo-addon-``
+
+**Example:**
+
+``sudo -H pip3 install --extra-index-url https://nexus.mukit.at/repository/odoo/simple odoo11-addon-muk-utils``
+
+Once the installation has been successfully completed, the app is already in the
+correct folder. Log on to your Odoo server and go to the Apps menu. Trigger the
+debug mode and update the list by clicking on the "Update Apps List" link. Now
+install the module by clicking on the install button.
+
+The biggest advantage of this variant is that you can now also update the app
+using the "pip" command. To do this, enter the following command in your console:
+
+``pip install --upgrade --extra-index-url https://nexus.mukit.at/repository/odoo/simple ``
+
+When the process is finished, restart your server and update the application in
+Odoo. The steps are the same as for the installation only the button has changed
+from "Install" to "Upgrade".
+
+You can also view available Apps directly in our `repository `_
+and find a more detailed installation guide on our `website `_.
+
+For modules licensed under OPL-1, you will receive access data when you purchase
+the module. If the modules were not purchased directly from
+`MuK IT `_ please contact our support (support@mukit.at)
+with a confirmation of purchase to receive the corresponding access data.
+
+Upgrade
+============
+
+To upgrade this module, you need to:
+
+Download the module and add it to your Odoo addons folder. Restart the server
+and log on to your Odoo server. Select the Apps menu and upgrade the module by
+clicking on the upgrade button.
+
+If you installed the module using the "pip" command, you can also update the
+module in the same way. Just type the following command into the console:
+
+``pip install --upgrade --extra-index-url https://nexus.mukit.at/repository/odoo/simple ``
+
+When the process is finished, restart your server and update the application in
+Odoo, just like you would normally.
+
+Configuration
+=============
+
+No additional configuration is needed to use this module.
+
+Usage
+=============
+
+This module has no direct visible effect on the system. It provide security features.
+
+Credits
+=======
+
+Contributors
+------------
+
+* Mathias Markl
+
+Images
+------------
+
+Some pictures are based on or inspired by the icon set of Font Awesome:
+
+* `Font Awesome `_
+
+Projects
+------------
+
+Parts of the module are inspired by:
+
+* `Suspend Security `_
+
+Author & Maintainer
+-------------------
+
+This module is maintained by the `MuK IT GmbH `_.
+
+MuK IT is an Austrian company specialized in customizing and extending Odoo.
+We develop custom solutions for your individual needs to help you focus on
+your strength and expertise to grow your business.
+
+If you want to get in touch please contact us via mail
+(sale@mukit.at) or visit our website (https://mukit.at).
diff --git a/odex-event/muk_security/__init__.py b/odex-event/muk_security/__init__.py
new file mode 100644
index 000000000..e71401df5
--- /dev/null
+++ b/odex-event/muk_security/__init__.py
@@ -0,0 +1,30 @@
+###################################################################################
+#
+# Copyright (c) 2017-2019 MuK IT GmbH.
+#
+# This file is part of MuK Security
+# (see https://mukit.at).
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see .
+#
+###################################################################################
+
+from . import models
+
+#----------------------------------------------------------
+# Patch System on Load
+#----------------------------------------------------------
+
+def _patch_system():
+ from . import patch
\ No newline at end of file
diff --git a/odex-event/muk_security/__manifest__.py b/odex-event/muk_security/__manifest__.py
new file mode 100644
index 000000000..8c572b8eb
--- /dev/null
+++ b/odex-event/muk_security/__manifest__.py
@@ -0,0 +1,57 @@
+###################################################################################
+#
+# Copyright (c) 2017-2019 MuK IT GmbH.
+#
+# This file is part of MuK Security
+# (see https://mukit.at).
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see .
+#
+###################################################################################
+
+{
+ "name": "MuK Security",
+ "summary": """Security Features""",
+ "version": "12.0.2.0.1",
+ "category": "Extra Tools",
+ "license": "LGPL-3",
+ "website": "http://www.mukit.at",
+ 'live_test_url': 'https://mukit.at/r/SgN',
+ "author": "MuK IT",
+ "contributors": [
+ "Mathias Markl ",
+ ],
+ "depends": [
+ "muk_utils",
+ ],
+ "data": [
+ "security/security.xml",
+ "security/ir.model.access.csv",
+ "views/access_groups.xml",
+ ],
+ "qweb": [
+ "static/src/xml/*.xml",
+ ],
+ "images": [
+ 'static/description/banner.png'
+ ],
+ "external_dependencies": {
+ "python": [],
+ "bin": [],
+ },
+ "auto_install": False,
+ "application": False,
+ "installable": True,
+ "post_load": "_patch_system",
+}
\ No newline at end of file
diff --git a/odex-event/muk_security/doc/changelog.rst b/odex-event/muk_security/doc/changelog.rst
new file mode 100644
index 000000000..a312a9f02
--- /dev/null
+++ b/odex-event/muk_security/doc/changelog.rst
@@ -0,0 +1,29 @@
+`1.5.0`
+-------
+
+- Added Group Access Mixin
+
+`1.4.0`
+-------
+
+- Added Access Mixin
+
+`1.3.0`
+-------
+
+- Added Locking Mixin
+
+`1.2.0`
+-------
+
+- Restructuring
+
+`1.1.0`
+-------
+
+- Updated dependencies
+
+`1.0.0`
+-------
+
+- Init version
diff --git a/odex-event/muk_security/doc/index.rst b/odex-event/muk_security/doc/index.rst
new file mode 100644
index 000000000..154849927
--- /dev/null
+++ b/odex-event/muk_security/doc/index.rst
@@ -0,0 +1,120 @@
+============
+MuK Security
+============
+
+Technical module to provide some utility and security features that can be used
+in other applications. This module has no direct effect on the running system.
+
+Installation
+============
+
+To install this module, you need to:
+
+Download the module and add it to your Odoo addons folder. Afterward, log on to
+your Odoo server and go to the Apps menu. Trigger the debug mode and update the
+list by clicking on the "Update Apps List" link. Now install the module by
+clicking on the install button.
+
+Another way to install this module is via the package management for Python
+(`PyPI `_).
+
+To install our modules using the package manager make sure
+`odoo-autodiscover `_ is installed
+correctly. Then open a console and install the module by entering the following
+command:
+
+``pip install --extra-index-url https://nexus.mukit.at/repository/odoo/simple ``
+
+The module name consists of the Odoo version and the module name, where
+underscores are replaced by a dash.
+
+**Module:**
+
+``odoo-addon-``
+
+**Example:**
+
+``sudo -H pip3 install --extra-index-url https://nexus.mukit.at/repository/odoo/simple odoo11-addon-muk-utils``
+
+Once the installation has been successfully completed, the app is already in the
+correct folder. Log on to your Odoo server and go to the Apps menu. Trigger the
+debug mode and update the list by clicking on the "Update Apps List" link. Now
+install the module by clicking on the install button.
+
+The biggest advantage of this variant is that you can now also update the app
+using the "pip" command. To do this, enter the following command in your console:
+
+``pip install --upgrade --extra-index-url https://nexus.mukit.at/repository/odoo/simple ``
+
+When the process is finished, restart your server and update the application in
+Odoo. The steps are the same as for the installation only the button has changed
+from "Install" to "Upgrade".
+
+You can also view available Apps directly in our `repository `_
+and find a more detailed installation guide on our `website `_.
+
+For modules licensed under OPL-1, you will receive access data when you purchase
+the module. If the modules were not purchased directly from
+`MuK IT `_ please contact our support (support@mukit.at)
+with a confirmation of purchase to receive the corresponding access data.
+
+Upgrade
+============
+
+To upgrade this module, you need to:
+
+Download the module and add it to your Odoo addons folder. Restart the server
+and log on to your Odoo server. Select the Apps menu and upgrade the module by
+clicking on the upgrade button.
+
+If you installed the module using the "pip" command, you can also update the
+module in the same way. Just type the following command into the console:
+
+``pip install --upgrade --extra-index-url https://nexus.mukit.at/repository/odoo/simple ``
+
+When the process is finished, restart your server and update the application in
+Odoo, just like you would normally.
+
+Configuration
+=============
+
+No additional configuration is needed to use this module.
+
+Usage
+=============
+
+This module has no direct visible effect on the system. It provide security features.
+
+Credits
+=======
+
+Contributors
+------------
+
+* Mathias Markl
+
+Images
+------------
+
+Some pictures are based on or inspired by the icon set of Font Awesome:
+
+* `Font Awesome `_
+
+Projects
+------------
+
+Parts of the module are inspired by:
+
+* `Suspend Security `_
+
+Author & Maintainer
+-------------------
+
+This module is maintained by the `MuK IT GmbH `_.
+
+MuK IT is an Austrian company specialized in customizing and extending Odoo.
+We develop custom solutions for your individual needs to help you focus on
+your strength and expertise to grow your business.
+
+If you want to get in touch please contact us via mail
+(sale@mukit.at) or visit our website (https://mukit.at).
diff --git a/odex-event/muk_security/i18n/ar.po b/odex-event/muk_security/i18n/ar.po
new file mode 100644
index 000000000..0731f58dd
--- /dev/null
+++ b/odex-event/muk_security/i18n/ar.po
@@ -0,0 +1,215 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * muk_security
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 12.0-20190522\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2019-07-12 23:30+0000\n"
+"PO-Revision-Date: 2019-07-12 23:30+0000\n"
+"Last-Translator: <>\n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: \n"
+
+#. module: muk_security
+#: model:ir.actions.act_window,name:muk_security.action_security_access_groups
+#: model:ir.ui.menu,name:muk_security.menu_security_access_groups
+msgid "Access Groups"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model,name:muk_security.model_muk_security_mixins_access_rights
+msgid "Access Mixin"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model,name:muk_security.model_base
+msgid "Base"
+msgstr "الأساس"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__child_groups
+msgid "Child Groups"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_groups__complete_groups
+msgid "Complete Groups"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__perm_create
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_groups__permission_create
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_rights__permission_create
+msgid "Create Access"
+msgstr "صلاحيات الإنشاء"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__create_uid
+msgid "Created by"
+msgstr "أنشئ بواسطة"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__create_date
+msgid "Created on"
+msgstr "أنشئ في"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_groups__permission_unlink
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_rights__permission_unlink
+msgid "Delete Access"
+msgstr "صلاحيات الحذف"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__display_name
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_groups__display_name
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_rights__display_name
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_locking__display_name
+msgid "Display Name"
+msgstr "اسم العرض"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_locking__is_lock_editor
+msgid "Editor"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__explicit_users
+msgid "Explicit Users"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model,name:muk_security.model_muk_security_mixins_access_groups
+msgid "Group Access Mixin"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__name
+msgid "Group Name"
+msgstr "اسم المجموعة"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__users
+msgid "Group Users"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__groups
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_groups__groups
+msgid "Groups"
+msgstr "المجموعات"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__id
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_groups__id
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_rights__id
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_locking__id
+msgid "ID"
+msgstr "المعرف"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups____last_update
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_groups____last_update
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_rights____last_update
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_locking____last_update
+msgid "Last Modified on"
+msgstr "آخر تعديل في"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__write_uid
+msgid "Last Updated by"
+msgstr "آخر تحديث بواسطة"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__write_date
+msgid "Last Updated on"
+msgstr "آخر تحديث في"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_locking__is_locked
+msgid "Locked"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_locking__locked_by
+msgid "Locked by"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model,name:muk_security.model_muk_security_mixins_locking
+msgid "Locking Mixin"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model,name:muk_security.model_ir_model_access
+msgid "Model Access"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__parent_group
+msgid "Parent Group"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__parent_path
+msgid "Parent Path"
+msgstr "المسار الأصلي"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__perm_read
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_groups__permission_read
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_rights__permission_read
+msgid "Read Access"
+msgstr "صلاحيات القراءة"
+
+#. module: muk_security
+#: model:ir.model,name:muk_security.model_muk_security_access_groups
+msgid "Record Access Groups"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model,name:muk_security.model_ir_rule
+msgid "Record Rule"
+msgstr "تسجيل القاعدة"
+
+#. module: muk_security
+#: model_terms:ir.ui.view,arch_db:muk_security.view_security_access_groups_form
+msgid "Settings"
+msgstr "الإعدادات"
+
+#. module: muk_security
+#: code:addons/muk_security/models/mixins_locking.py:77
+#, python-format
+msgid "The record (%s [%s]) is locked, by an other user."
+msgstr ""
+
+#. module: muk_security
+#: code:addons/muk_security/models/mixins_access_groups.py:197
+#, python-format
+msgid "The requested operation cannot be completed due to group security restrictions. Please contact your system administrator.\n"
+"\n"
+"(Document type: %s, Operation: %s)"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__perm_unlink
+msgid "Unlink Access"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model,name:muk_security.model_res_users
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__count_users
+msgid "Users"
+msgstr "المستخدمون"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__perm_write
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_groups__permission_write
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_rights__permission_write
+msgid "Write Access"
+msgstr "صلاحيات الكتابة"
+
diff --git a/odex-event/muk_security/i18n/de.po b/odex-event/muk_security/i18n/de.po
new file mode 100644
index 000000000..9ac5faec7
--- /dev/null
+++ b/odex-event/muk_security/i18n/de.po
@@ -0,0 +1,217 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * muk_security
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 12.0-20190522\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2019-07-12 23:31+0000\n"
+"PO-Revision-Date: 2019-07-12 23:31+0000\n"
+"Last-Translator: <>\n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: \n"
+
+#. module: muk_security
+#: model:ir.actions.act_window,name:muk_security.action_security_access_groups
+#: model:ir.ui.menu,name:muk_security.menu_security_access_groups
+msgid "Access Groups"
+msgstr "Gruppenzugriff"
+
+#. module: muk_security
+#: model:ir.model,name:muk_security.model_muk_security_mixins_access_rights
+msgid "Access Mixin"
+msgstr "Zugriff Mixin"
+
+#. module: muk_security
+#: model:ir.model,name:muk_security.model_base
+msgid "Base"
+msgstr "Basis"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__child_groups
+msgid "Child Groups"
+msgstr "Untergruppen"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_groups__complete_groups
+msgid "Complete Groups"
+msgstr "Komplette Gruppen"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__perm_create
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_groups__permission_create
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_rights__permission_create
+msgid "Create Access"
+msgstr "Objekterzeugung erlauben"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__create_uid
+msgid "Created by"
+msgstr "Erstellt von"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__create_date
+msgid "Created on"
+msgstr "Erstellt am"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_groups__permission_unlink
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_rights__permission_unlink
+msgid "Delete Access"
+msgstr "Zugang löschen"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__display_name
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_groups__display_name
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_rights__display_name
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_locking__display_name
+msgid "Display Name"
+msgstr "Anzeigename"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_locking__is_lock_editor
+msgid "Editor"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__explicit_users
+msgid "Explicit Users"
+msgstr "Explizite Benutzer"
+
+#. module: muk_security
+#: model:ir.model,name:muk_security.model_muk_security_mixins_access_groups
+msgid "Group Access Mixin"
+msgstr "Zugriffsgruppen Mixin"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__name
+msgid "Group Name"
+msgstr "Gruppenname"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__users
+msgid "Group Users"
+msgstr "Gruppenbenutzer"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__groups
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_groups__groups
+msgid "Groups"
+msgstr "Gruppen"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__id
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_groups__id
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_rights__id
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_locking__id
+msgid "ID"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups____last_update
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_groups____last_update
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_rights____last_update
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_locking____last_update
+msgid "Last Modified on"
+msgstr "Zuletzt geändert am"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__write_uid
+msgid "Last Updated by"
+msgstr "Zuletzt aktualisiert durch"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__write_date
+msgid "Last Updated on"
+msgstr "Zuletzt aktualisiert am"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_locking__is_locked
+msgid "Locked"
+msgstr "Gesperrt"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_locking__locked_by
+msgid "Locked by"
+msgstr "Gesperrt von"
+
+#. module: muk_security
+#: model:ir.model,name:muk_security.model_muk_security_mixins_locking
+msgid "Locking Mixin"
+msgstr "Sperren Mixin"
+
+#. module: muk_security
+#: model:ir.model,name:muk_security.model_ir_model_access
+msgid "Model Access"
+msgstr "Modelzugriff"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__parent_group
+msgid "Parent Group"
+msgstr "Übergeordnete Gruppe"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__parent_path
+msgid "Parent Path"
+msgstr "Übergeordneter Pfad"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__perm_read
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_groups__permission_read
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_rights__permission_read
+msgid "Read Access"
+msgstr "Leserecht"
+
+#. module: muk_security
+#: model:ir.model,name:muk_security.model_muk_security_access_groups
+msgid "Record Access Groups"
+msgstr "Zugriffsgruppeneintrag"
+
+#. module: muk_security
+#: model:ir.model,name:muk_security.model_ir_rule
+msgid "Record Rule"
+msgstr "Datensatzregel"
+
+#. module: muk_security
+#: model_terms:ir.ui.view,arch_db:muk_security.view_security_access_groups_form
+msgid "Settings"
+msgstr "Einstellungen"
+
+#. module: muk_security
+#: code:addons/muk_security/models/mixins_locking.py:77
+#, python-format
+msgid "The record (%s [%s]) is locked, by an other user."
+msgstr "Der Eintrag (%s [%s]) ist von einem anderen Benutzer gesperrt."
+
+#. module: muk_security
+#: code:addons/muk_security/models/mixins_access_groups.py:197
+#, python-format
+msgid "The requested operation cannot be completed due to group security restrictions. Please contact your system administrator.\n"
+"\n"
+"(Document type: %s, Operation: %s)"
+msgstr "Der angeforderte Vorgang kann aufgrund von Sicherheitseinschränkungen der Gruppe nicht abgeschlossen werden. Bitte verständigen Sie Ihren Systemadministrator.\n"
+"\n"
+"(Document type: %s1, Operation: %s2)"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__perm_unlink
+msgid "Unlink Access"
+msgstr "Löschen erlauben"
+
+#. module: muk_security
+#: model:ir.model,name:muk_security.model_res_users
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__count_users
+msgid "Users"
+msgstr "Benutzer"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__perm_write
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_groups__permission_write
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_rights__permission_write
+msgid "Write Access"
+msgstr "Schreibrechte"
+
diff --git a/odex-event/muk_security/i18n/es.po b/odex-event/muk_security/i18n/es.po
new file mode 100644
index 000000000..fbd418fcb
--- /dev/null
+++ b/odex-event/muk_security/i18n/es.po
@@ -0,0 +1,215 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * muk_security
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 12.0-20190522\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2019-07-12 23:31+0000\n"
+"PO-Revision-Date: 2019-07-12 23:31+0000\n"
+"Last-Translator: <>\n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: \n"
+
+#. module: muk_security
+#: model:ir.actions.act_window,name:muk_security.action_security_access_groups
+#: model:ir.ui.menu,name:muk_security.menu_security_access_groups
+msgid "Access Groups"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model,name:muk_security.model_muk_security_mixins_access_rights
+msgid "Access Mixin"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model,name:muk_security.model_base
+msgid "Base"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__child_groups
+msgid "Child Groups"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_groups__complete_groups
+msgid "Complete Groups"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__perm_create
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_groups__permission_create
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_rights__permission_create
+msgid "Create Access"
+msgstr "Acceso para crear"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__create_uid
+msgid "Created by"
+msgstr "Creado por"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__create_date
+msgid "Created on"
+msgstr "Creado el"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_groups__permission_unlink
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_rights__permission_unlink
+msgid "Delete Access"
+msgstr "Permiso para eliminar"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__display_name
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_groups__display_name
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_rights__display_name
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_locking__display_name
+msgid "Display Name"
+msgstr "Nombre mostrado"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_locking__is_lock_editor
+msgid "Editor"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__explicit_users
+msgid "Explicit Users"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model,name:muk_security.model_muk_security_mixins_access_groups
+msgid "Group Access Mixin"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__name
+msgid "Group Name"
+msgstr "Nombre del grupo"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__users
+msgid "Group Users"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__groups
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_groups__groups
+msgid "Groups"
+msgstr "Grupos"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__id
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_groups__id
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_rights__id
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_locking__id
+msgid "ID"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups____last_update
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_groups____last_update
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_rights____last_update
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_locking____last_update
+msgid "Last Modified on"
+msgstr "Última modificación en"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__write_uid
+msgid "Last Updated by"
+msgstr "Última actualización por"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__write_date
+msgid "Last Updated on"
+msgstr "Última actualización el"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_locking__is_locked
+msgid "Locked"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_locking__locked_by
+msgid "Locked by"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model,name:muk_security.model_muk_security_mixins_locking
+msgid "Locking Mixin"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model,name:muk_security.model_ir_model_access
+msgid "Model Access"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__parent_group
+msgid "Parent Group"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__parent_path
+msgid "Parent Path"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__perm_read
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_groups__permission_read
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_rights__permission_read
+msgid "Read Access"
+msgstr "Permiso para leer"
+
+#. module: muk_security
+#: model:ir.model,name:muk_security.model_muk_security_access_groups
+msgid "Record Access Groups"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model,name:muk_security.model_ir_rule
+msgid "Record Rule"
+msgstr "Regla de registro"
+
+#. module: muk_security
+#: model_terms:ir.ui.view,arch_db:muk_security.view_security_access_groups_form
+msgid "Settings"
+msgstr "Ajustes"
+
+#. module: muk_security
+#: code:addons/muk_security/models/mixins_locking.py:77
+#, python-format
+msgid "The record (%s [%s]) is locked, by an other user."
+msgstr ""
+
+#. module: muk_security
+#: code:addons/muk_security/models/mixins_access_groups.py:197
+#, python-format
+msgid "The requested operation cannot be completed due to group security restrictions. Please contact your system administrator.\n"
+"\n"
+"(Document type: %s, Operation: %s)"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__perm_unlink
+msgid "Unlink Access"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model,name:muk_security.model_res_users
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__count_users
+msgid "Users"
+msgstr "Usuarios"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__perm_write
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_groups__permission_write
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_rights__permission_write
+msgid "Write Access"
+msgstr "Permiso de escritura"
+
diff --git a/odex-event/muk_security/i18n/fr.po b/odex-event/muk_security/i18n/fr.po
new file mode 100644
index 000000000..b77b8672d
--- /dev/null
+++ b/odex-event/muk_security/i18n/fr.po
@@ -0,0 +1,215 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * muk_security
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 12.0-20190522\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2019-07-12 23:31+0000\n"
+"PO-Revision-Date: 2019-07-12 23:31+0000\n"
+"Last-Translator: <>\n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: \n"
+
+#. module: muk_security
+#: model:ir.actions.act_window,name:muk_security.action_security_access_groups
+#: model:ir.ui.menu,name:muk_security.menu_security_access_groups
+msgid "Access Groups"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model,name:muk_security.model_muk_security_mixins_access_rights
+msgid "Access Mixin"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model,name:muk_security.model_base
+msgid "Base"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__child_groups
+msgid "Child Groups"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_groups__complete_groups
+msgid "Complete Groups"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__perm_create
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_groups__permission_create
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_rights__permission_create
+msgid "Create Access"
+msgstr "Droit de création"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__create_uid
+msgid "Created by"
+msgstr "Créé par"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__create_date
+msgid "Created on"
+msgstr "Créé le"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_groups__permission_unlink
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_rights__permission_unlink
+msgid "Delete Access"
+msgstr "Droit de suppression"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__display_name
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_groups__display_name
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_rights__display_name
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_locking__display_name
+msgid "Display Name"
+msgstr "Nom affiché"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_locking__is_lock_editor
+msgid "Editor"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__explicit_users
+msgid "Explicit Users"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model,name:muk_security.model_muk_security_mixins_access_groups
+msgid "Group Access Mixin"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__name
+msgid "Group Name"
+msgstr "Nom du groupe"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__users
+msgid "Group Users"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__groups
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_groups__groups
+msgid "Groups"
+msgstr "Groupes"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__id
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_groups__id
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_rights__id
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_locking__id
+msgid "ID"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups____last_update
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_groups____last_update
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_rights____last_update
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_locking____last_update
+msgid "Last Modified on"
+msgstr "Dernière modification le"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__write_uid
+msgid "Last Updated by"
+msgstr "Dernière mise à jour par"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__write_date
+msgid "Last Updated on"
+msgstr "Dernière mise à jour le"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_locking__is_locked
+msgid "Locked"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_locking__locked_by
+msgid "Locked by"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model,name:muk_security.model_muk_security_mixins_locking
+msgid "Locking Mixin"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model,name:muk_security.model_ir_model_access
+msgid "Model Access"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__parent_group
+msgid "Parent Group"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__parent_path
+msgid "Parent Path"
+msgstr "Chemin parent"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__perm_read
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_groups__permission_read
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_rights__permission_read
+msgid "Read Access"
+msgstr "Accès en lecture"
+
+#. module: muk_security
+#: model:ir.model,name:muk_security.model_muk_security_access_groups
+msgid "Record Access Groups"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model,name:muk_security.model_ir_rule
+msgid "Record Rule"
+msgstr "Règle d'enregistrement"
+
+#. module: muk_security
+#: model_terms:ir.ui.view,arch_db:muk_security.view_security_access_groups_form
+msgid "Settings"
+msgstr "Configuration"
+
+#. module: muk_security
+#: code:addons/muk_security/models/mixins_locking.py:77
+#, python-format
+msgid "The record (%s [%s]) is locked, by an other user."
+msgstr ""
+
+#. module: muk_security
+#: code:addons/muk_security/models/mixins_access_groups.py:197
+#, python-format
+msgid "The requested operation cannot be completed due to group security restrictions. Please contact your system administrator.\n"
+"\n"
+"(Document type: %s, Operation: %s)"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__perm_unlink
+msgid "Unlink Access"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model,name:muk_security.model_res_users
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__count_users
+msgid "Users"
+msgstr "Utilisateurs"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__perm_write
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_groups__permission_write
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_rights__permission_write
+msgid "Write Access"
+msgstr "Accès en écriture"
+
diff --git a/odex-event/muk_security/i18n/hi.po b/odex-event/muk_security/i18n/hi.po
new file mode 100644
index 000000000..f393ab6ca
--- /dev/null
+++ b/odex-event/muk_security/i18n/hi.po
@@ -0,0 +1,215 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * muk_security
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 12.0-20190522\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2019-07-12 23:31+0000\n"
+"PO-Revision-Date: 2019-07-12 23:31+0000\n"
+"Last-Translator: <>\n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: \n"
+
+#. module: muk_security
+#: model:ir.actions.act_window,name:muk_security.action_security_access_groups
+#: model:ir.ui.menu,name:muk_security.menu_security_access_groups
+msgid "Access Groups"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model,name:muk_security.model_muk_security_mixins_access_rights
+msgid "Access Mixin"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model,name:muk_security.model_base
+msgid "Base"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__child_groups
+msgid "Child Groups"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_groups__complete_groups
+msgid "Complete Groups"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__perm_create
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_groups__permission_create
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_rights__permission_create
+msgid "Create Access"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__create_uid
+msgid "Created by"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__create_date
+msgid "Created on"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_groups__permission_unlink
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_rights__permission_unlink
+msgid "Delete Access"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__display_name
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_groups__display_name
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_rights__display_name
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_locking__display_name
+msgid "Display Name"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_locking__is_lock_editor
+msgid "Editor"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__explicit_users
+msgid "Explicit Users"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model,name:muk_security.model_muk_security_mixins_access_groups
+msgid "Group Access Mixin"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__name
+msgid "Group Name"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__users
+msgid "Group Users"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__groups
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_groups__groups
+msgid "Groups"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__id
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_groups__id
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_rights__id
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_locking__id
+msgid "ID"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups____last_update
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_groups____last_update
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_rights____last_update
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_locking____last_update
+msgid "Last Modified on"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__write_uid
+msgid "Last Updated by"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__write_date
+msgid "Last Updated on"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_locking__is_locked
+msgid "Locked"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_locking__locked_by
+msgid "Locked by"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model,name:muk_security.model_muk_security_mixins_locking
+msgid "Locking Mixin"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model,name:muk_security.model_ir_model_access
+msgid "Model Access"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__parent_group
+msgid "Parent Group"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__parent_path
+msgid "Parent Path"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__perm_read
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_groups__permission_read
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_rights__permission_read
+msgid "Read Access"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model,name:muk_security.model_muk_security_access_groups
+msgid "Record Access Groups"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model,name:muk_security.model_ir_rule
+msgid "Record Rule"
+msgstr ""
+
+#. module: muk_security
+#: model_terms:ir.ui.view,arch_db:muk_security.view_security_access_groups_form
+msgid "Settings"
+msgstr ""
+
+#. module: muk_security
+#: code:addons/muk_security/models/mixins_locking.py:77
+#, python-format
+msgid "The record (%s [%s]) is locked, by an other user."
+msgstr ""
+
+#. module: muk_security
+#: code:addons/muk_security/models/mixins_access_groups.py:197
+#, python-format
+msgid "The requested operation cannot be completed due to group security restrictions. Please contact your system administrator.\n"
+"\n"
+"(Document type: %s, Operation: %s)"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__perm_unlink
+msgid "Unlink Access"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model,name:muk_security.model_res_users
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__count_users
+msgid "Users"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__perm_write
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_groups__permission_write
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_rights__permission_write
+msgid "Write Access"
+msgstr ""
+
diff --git a/odex-event/muk_security/i18n/nl.po b/odex-event/muk_security/i18n/nl.po
new file mode 100644
index 000000000..a558ce659
--- /dev/null
+++ b/odex-event/muk_security/i18n/nl.po
@@ -0,0 +1,215 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * muk_security
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 12.0-20190522\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2019-07-12 23:31+0000\n"
+"PO-Revision-Date: 2019-07-12 23:31+0000\n"
+"Last-Translator: <>\n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: \n"
+
+#. module: muk_security
+#: model:ir.actions.act_window,name:muk_security.action_security_access_groups
+#: model:ir.ui.menu,name:muk_security.menu_security_access_groups
+msgid "Access Groups"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model,name:muk_security.model_muk_security_mixins_access_rights
+msgid "Access Mixin"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model,name:muk_security.model_base
+msgid "Base"
+msgstr "Basis"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__child_groups
+msgid "Child Groups"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_groups__complete_groups
+msgid "Complete Groups"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__perm_create
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_groups__permission_create
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_rights__permission_create
+msgid "Create Access"
+msgstr "Aanmaken"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__create_uid
+msgid "Created by"
+msgstr "Aangemaakt door"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__create_date
+msgid "Created on"
+msgstr "Aangemaakt op"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_groups__permission_unlink
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_rights__permission_unlink
+msgid "Delete Access"
+msgstr "Verwijderen"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__display_name
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_groups__display_name
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_rights__display_name
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_locking__display_name
+msgid "Display Name"
+msgstr "Weergavenaam"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_locking__is_lock_editor
+msgid "Editor"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__explicit_users
+msgid "Explicit Users"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model,name:muk_security.model_muk_security_mixins_access_groups
+msgid "Group Access Mixin"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__name
+msgid "Group Name"
+msgstr "Groepsnaam"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__users
+msgid "Group Users"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__groups
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_groups__groups
+msgid "Groups"
+msgstr "Groepen"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__id
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_groups__id
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_rights__id
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_locking__id
+msgid "ID"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups____last_update
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_groups____last_update
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_rights____last_update
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_locking____last_update
+msgid "Last Modified on"
+msgstr "Laatst gewijzigd op"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__write_uid
+msgid "Last Updated by"
+msgstr "Laatst bijgewerkt door"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__write_date
+msgid "Last Updated on"
+msgstr "Laatst bijgewerkt op"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_locking__is_locked
+msgid "Locked"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_locking__locked_by
+msgid "Locked by"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model,name:muk_security.model_muk_security_mixins_locking
+msgid "Locking Mixin"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model,name:muk_security.model_ir_model_access
+msgid "Model Access"
+msgstr "Model toegang"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__parent_group
+msgid "Parent Group"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__parent_path
+msgid "Parent Path"
+msgstr "Bovenliggend pad"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__perm_read
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_groups__permission_read
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_rights__permission_read
+msgid "Read Access"
+msgstr "Lezen"
+
+#. module: muk_security
+#: model:ir.model,name:muk_security.model_muk_security_access_groups
+msgid "Record Access Groups"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model,name:muk_security.model_ir_rule
+msgid "Record Rule"
+msgstr "Recordregel"
+
+#. module: muk_security
+#: model_terms:ir.ui.view,arch_db:muk_security.view_security_access_groups_form
+msgid "Settings"
+msgstr "Instellingen"
+
+#. module: muk_security
+#: code:addons/muk_security/models/mixins_locking.py:77
+#, python-format
+msgid "The record (%s [%s]) is locked, by an other user."
+msgstr ""
+
+#. module: muk_security
+#: code:addons/muk_security/models/mixins_access_groups.py:197
+#, python-format
+msgid "The requested operation cannot be completed due to group security restrictions. Please contact your system administrator.\n"
+"\n"
+"(Document type: %s, Operation: %s)"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__perm_unlink
+msgid "Unlink Access"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model,name:muk_security.model_res_users
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__count_users
+msgid "Users"
+msgstr "Gebruikers"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__perm_write
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_groups__permission_write
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_rights__permission_write
+msgid "Write Access"
+msgstr "Schrijven"
+
diff --git a/odex-event/muk_security/i18n/pt.po b/odex-event/muk_security/i18n/pt.po
new file mode 100644
index 000000000..85e868cca
--- /dev/null
+++ b/odex-event/muk_security/i18n/pt.po
@@ -0,0 +1,215 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * muk_security
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 12.0-20190522\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2019-07-12 23:32+0000\n"
+"PO-Revision-Date: 2019-07-12 23:32+0000\n"
+"Last-Translator: <>\n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: \n"
+
+#. module: muk_security
+#: model:ir.actions.act_window,name:muk_security.action_security_access_groups
+#: model:ir.ui.menu,name:muk_security.menu_security_access_groups
+msgid "Access Groups"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model,name:muk_security.model_muk_security_mixins_access_rights
+msgid "Access Mixin"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model,name:muk_security.model_base
+msgid "Base"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__child_groups
+msgid "Child Groups"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_groups__complete_groups
+msgid "Complete Groups"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__perm_create
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_groups__permission_create
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_rights__permission_create
+msgid "Create Access"
+msgstr "Criar Acesso"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__create_uid
+msgid "Created by"
+msgstr "Criado por"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__create_date
+msgid "Created on"
+msgstr "Criada em"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_groups__permission_unlink
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_rights__permission_unlink
+msgid "Delete Access"
+msgstr "Eliminar acesso"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__display_name
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_groups__display_name
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_rights__display_name
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_locking__display_name
+msgid "Display Name"
+msgstr "Nome a Exibir"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_locking__is_lock_editor
+msgid "Editor"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__explicit_users
+msgid "Explicit Users"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model,name:muk_security.model_muk_security_mixins_access_groups
+msgid "Group Access Mixin"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__name
+msgid "Group Name"
+msgstr "Nome do Grupo"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__users
+msgid "Group Users"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__groups
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_groups__groups
+msgid "Groups"
+msgstr "Grupos"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__id
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_groups__id
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_rights__id
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_locking__id
+msgid "ID"
+msgstr "Id."
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups____last_update
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_groups____last_update
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_rights____last_update
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_locking____last_update
+msgid "Last Modified on"
+msgstr "Última Modificação em"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__write_uid
+msgid "Last Updated by"
+msgstr "Última Atualização por"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__write_date
+msgid "Last Updated on"
+msgstr "Última Atualização em"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_locking__is_locked
+msgid "Locked"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_locking__locked_by
+msgid "Locked by"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model,name:muk_security.model_muk_security_mixins_locking
+msgid "Locking Mixin"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model,name:muk_security.model_ir_model_access
+msgid "Model Access"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__parent_group
+msgid "Parent Group"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__parent_path
+msgid "Parent Path"
+msgstr "Caminho ascendente "
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__perm_read
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_groups__permission_read
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_rights__permission_read
+msgid "Read Access"
+msgstr "Permissão de Leitura"
+
+#. module: muk_security
+#: model:ir.model,name:muk_security.model_muk_security_access_groups
+msgid "Record Access Groups"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model,name:muk_security.model_ir_rule
+msgid "Record Rule"
+msgstr "Regra do Registo"
+
+#. module: muk_security
+#: model_terms:ir.ui.view,arch_db:muk_security.view_security_access_groups_form
+msgid "Settings"
+msgstr "Configurações"
+
+#. module: muk_security
+#: code:addons/muk_security/models/mixins_locking.py:77
+#, python-format
+msgid "The record (%s [%s]) is locked, by an other user."
+msgstr ""
+
+#. module: muk_security
+#: code:addons/muk_security/models/mixins_access_groups.py:197
+#, python-format
+msgid "The requested operation cannot be completed due to group security restrictions. Please contact your system administrator.\n"
+"\n"
+"(Document type: %s, Operation: %s)"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__perm_unlink
+msgid "Unlink Access"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model,name:muk_security.model_res_users
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__count_users
+msgid "Users"
+msgstr "Utilizadores"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__perm_write
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_groups__permission_write
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_rights__permission_write
+msgid "Write Access"
+msgstr "Permissões de Escrita"
+
diff --git a/odex-event/muk_security/i18n/ru.po b/odex-event/muk_security/i18n/ru.po
new file mode 100644
index 000000000..48dc8ed54
--- /dev/null
+++ b/odex-event/muk_security/i18n/ru.po
@@ -0,0 +1,215 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * muk_security
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 12.0-20190522\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2019-07-12 23:32+0000\n"
+"PO-Revision-Date: 2019-07-12 23:32+0000\n"
+"Last-Translator: <>\n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: \n"
+
+#. module: muk_security
+#: model:ir.actions.act_window,name:muk_security.action_security_access_groups
+#: model:ir.ui.menu,name:muk_security.menu_security_access_groups
+msgid "Access Groups"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model,name:muk_security.model_muk_security_mixins_access_rights
+msgid "Access Mixin"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model,name:muk_security.model_base
+msgid "Base"
+msgstr "Базовый"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__child_groups
+msgid "Child Groups"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_groups__complete_groups
+msgid "Complete Groups"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__perm_create
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_groups__permission_create
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_rights__permission_create
+msgid "Create Access"
+msgstr "Доступ на создание"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__create_uid
+msgid "Created by"
+msgstr "Создано"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__create_date
+msgid "Created on"
+msgstr "Создан"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_groups__permission_unlink
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_rights__permission_unlink
+msgid "Delete Access"
+msgstr "Доступ на удаление"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__display_name
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_groups__display_name
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_rights__display_name
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_locking__display_name
+msgid "Display Name"
+msgstr "Отображаемое Имя"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_locking__is_lock_editor
+msgid "Editor"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__explicit_users
+msgid "Explicit Users"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model,name:muk_security.model_muk_security_mixins_access_groups
+msgid "Group Access Mixin"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__name
+msgid "Group Name"
+msgstr "Наименование Группы"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__users
+msgid "Group Users"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__groups
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_groups__groups
+msgid "Groups"
+msgstr "Группы"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__id
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_groups__id
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_rights__id
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_locking__id
+msgid "ID"
+msgstr "Номер"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups____last_update
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_groups____last_update
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_rights____last_update
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_locking____last_update
+msgid "Last Modified on"
+msgstr "Последнее изменение"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__write_uid
+msgid "Last Updated by"
+msgstr "Последний раз обновил"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__write_date
+msgid "Last Updated on"
+msgstr "Последнее обновление"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_locking__is_locked
+msgid "Locked"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_locking__locked_by
+msgid "Locked by"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model,name:muk_security.model_muk_security_mixins_locking
+msgid "Locking Mixin"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model,name:muk_security.model_ir_model_access
+msgid "Model Access"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__parent_group
+msgid "Parent Group"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__parent_path
+msgid "Parent Path"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__perm_read
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_groups__permission_read
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_rights__permission_read
+msgid "Read Access"
+msgstr "Доступ на чтение"
+
+#. module: muk_security
+#: model:ir.model,name:muk_security.model_muk_security_access_groups
+msgid "Record Access Groups"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model,name:muk_security.model_ir_rule
+msgid "Record Rule"
+msgstr "Ограничение доступа"
+
+#. module: muk_security
+#: model_terms:ir.ui.view,arch_db:muk_security.view_security_access_groups_form
+msgid "Settings"
+msgstr "Настройки"
+
+#. module: muk_security
+#: code:addons/muk_security/models/mixins_locking.py:77
+#, python-format
+msgid "The record (%s [%s]) is locked, by an other user."
+msgstr ""
+
+#. module: muk_security
+#: code:addons/muk_security/models/mixins_access_groups.py:197
+#, python-format
+msgid "The requested operation cannot be completed due to group security restrictions. Please contact your system administrator.\n"
+"\n"
+"(Document type: %s, Operation: %s)"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__perm_unlink
+msgid "Unlink Access"
+msgstr ""
+
+#. module: muk_security
+#: model:ir.model,name:muk_security.model_res_users
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__count_users
+msgid "Users"
+msgstr "Пользователи"
+
+#. module: muk_security
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_access_groups__perm_write
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_groups__permission_write
+#: model:ir.model.fields,field_description:muk_security.field_muk_security_mixins_access_rights__permission_write
+msgid "Write Access"
+msgstr "Доступ на запись"
+
diff --git a/odex-event/muk_security/models/__init__.py b/odex-event/muk_security/models/__init__.py
new file mode 100644
index 000000000..a24c17fac
--- /dev/null
+++ b/odex-event/muk_security/models/__init__.py
@@ -0,0 +1,30 @@
+###################################################################################
+#
+# Copyright (c) 2017-2019 MuK IT GmbH.
+#
+# This file is part of MuK Security
+# (see https://mukit.at).
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see .
+#
+###################################################################################
+
+from . import base
+from . import mixins_locking
+from . import mixins_access_rights
+from . import mixins_access_groups
+from . import access_groups
+from . import ir_model_access
+from . import res_users
+from . import ir_rule
diff --git a/odex-event/muk_security/models/access_groups.py b/odex-event/muk_security/models/access_groups.py
new file mode 100644
index 000000000..5ec1c05ec
--- /dev/null
+++ b/odex-event/muk_security/models/access_groups.py
@@ -0,0 +1,46 @@
+###################################################################################
+#
+# Copyright (c) 2017-2019 MuK IT GmbH.
+#
+# This file is part of MuK Security
+# (see https://mukit.at).
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see .
+#
+###################################################################################
+
+from odoo import models, fields, api
+
+class AccessGroups(models.Model):
+
+ _name = 'muk_security.access_groups'
+ _description = "Record Access Groups"
+ _inherit = 'muk_utils.mixins.groups'
+
+ #----------------------------------------------------------
+ # Database
+ #----------------------------------------------------------
+
+ perm_read = fields.Boolean(
+ string='Read Access')
+
+ perm_create = fields.Boolean(
+ string='Create Access')
+
+ perm_write = fields.Boolean(
+ string='Write Access')
+
+ perm_unlink = fields.Boolean(
+ string='Unlink Access')
+
\ No newline at end of file
diff --git a/odex-event/muk_security/models/base.py b/odex-event/muk_security/models/base.py
new file mode 100644
index 000000000..f89ddef8a
--- /dev/null
+++ b/odex-event/muk_security/models/base.py
@@ -0,0 +1,68 @@
+###################################################################################
+#
+# Copyright (c) 2017-2019 MuK IT GmbH.
+#
+# This file is part of MuK Security
+# (see https://mukit.at).
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see .
+#
+###################################################################################
+
+import logging
+
+from odoo import api, models, fields
+
+from odoo.addons.muk_security.tools.security import NoSecurityUid
+
+_logger = logging.getLogger(__name__)
+
+class Base(models.AbstractModel):
+
+ _inherit = 'base'
+
+ #----------------------------------------------------------
+ # Helper
+ #----------------------------------------------------------
+
+ def _filter_access_rules(self, operation):
+ if isinstance(self.env.uid, NoSecurityUid):
+ return self
+ return super(Base, self)._filter_access_rules(operation)
+
+ @api.model
+ def _apply_ir_rules(self, query, mode='read'):
+ if isinstance(self.env.uid, NoSecurityUid):
+ return None
+ return super(Base, self)._apply_ir_rules(query, mode=mode)
+
+ #----------------------------------------------------------
+ # Function
+ #----------------------------------------------------------
+
+ @api.model
+ def suspend_security(self, user=None):
+ return self.sudo(user=NoSecurityUid(user or self.env.uid))
+
+
+ def check_access_rule(self, operation):
+ if isinstance(self.env.uid, NoSecurityUid):
+ return None
+ return super(Base, self).check_access_rule(operation)
+
+ @api.model
+ def check_field_access_rights(self, operation, fields):
+ if isinstance(self.env.uid, NoSecurityUid):
+ return fields or list(self._fields)
+ return super(Base, self).check_field_access_rights(operation, fields)
\ No newline at end of file
diff --git a/odex-event/muk_security/models/ir_model_access.py b/odex-event/muk_security/models/ir_model_access.py
new file mode 100644
index 000000000..9d73e71b0
--- /dev/null
+++ b/odex-event/muk_security/models/ir_model_access.py
@@ -0,0 +1,42 @@
+###################################################################################
+#
+# Copyright (c) 2017-2019 MuK IT GmbH.
+#
+# This file is part of MuK Security
+# (see https://mukit.at).
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see .
+#
+###################################################################################
+
+import logging
+
+from odoo import api, fields, models
+from odoo import tools, _
+from odoo.exceptions import ValidationError
+
+from odoo.addons.muk_security.tools.security import NoSecurityUid
+
+_logger = logging.getLogger(__name__)
+
+class IrModelAccess(models.Model):
+
+ _inherit = 'ir.model.access'
+
+ @api.model
+ @tools.ormcache_context('self._uid', 'model', 'mode', 'raise_exception', keys=('lang',))
+ def check(self, model, mode='read', raise_exception=True):
+ if isinstance(self.env.uid, NoSecurityUid):
+ return True
+ return super(IrModelAccess, self).check(model, mode=mode, raise_exception=raise_exception)
\ No newline at end of file
diff --git a/odex-event/muk_security/models/ir_rule.py b/odex-event/muk_security/models/ir_rule.py
new file mode 100644
index 000000000..93b513610
--- /dev/null
+++ b/odex-event/muk_security/models/ir_rule.py
@@ -0,0 +1,42 @@
+###################################################################################
+#
+# Copyright (c) 2017-2019 MuK IT GmbH.
+#
+# This file is part of MuK Security
+# (see https://mukit.at).
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see .
+#
+###################################################################################
+
+import logging
+
+from odoo import api, fields, models
+from odoo import tools, _
+from odoo.exceptions import ValidationError
+
+from odoo.addons.muk_security.tools.security import NoSecurityUid
+
+_logger = logging.getLogger(__name__)
+
+class IrRule(models.Model):
+
+ _inherit = 'ir.rule'
+
+ @api.model
+ @tools.ormcache('self._uid', 'model_name', 'mode')
+ def _compute_domain(self, model_name, mode="read"):
+ if isinstance(self.env.uid, NoSecurityUid):
+ return None
+ return super(IrRule, self)._compute_domain(model_name, mode=mode)
\ No newline at end of file
diff --git a/odex-event/muk_security/models/mixins_access_groups.py b/odex-event/muk_security/models/mixins_access_groups.py
new file mode 100644
index 000000000..95f0deb01
--- /dev/null
+++ b/odex-event/muk_security/models/mixins_access_groups.py
@@ -0,0 +1,245 @@
+###################################################################################
+#
+# Copyright (c) 2017-2019 MuK IT GmbH.
+#
+# This file is part of MuK Security
+# (see https://mukit.at).
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see .
+#
+###################################################################################
+
+import logging
+
+from collections import defaultdict
+
+from odoo import _, models, api, fields, SUPERUSER_ID
+from odoo.exceptions import AccessError
+from odoo.osv import expression
+
+from odoo.addons.muk_security.tools.security import NoSecurityUid
+
+_logger = logging.getLogger(__name__)
+
+class AccessGroupsModel(models.AbstractModel):
+
+ _name = 'muk_security.mixins.access_groups'
+ _description = "Group Access Mixin"
+ _inherit = 'muk_security.mixins.access_rights'
+
+ # If set the group fields are restricted by the access group
+ _access_groups_fields = None
+
+ # If set the group fields are recomputed as super administrator
+ _access_groups_sudo = False
+
+ # Set it to True to enforced security even if no group has been set
+ _access_groups_strict = False
+
+ # Set it to True to let the non strict mode check for existing groups per mode
+ _access_groups_mode = False
+
+ #----------------------------------------------------------
+ # Datebase
+ #----------------------------------------------------------
+
+ @api.model
+ def _add_magic_fields(self):
+ super(AccessGroupsModel, self)._add_magic_fields()
+ def add(name, field):
+ if name not in self._fields:
+ self._add_field(name, field)
+ add('groups', fields.Many2many(
+ _module=self._module,
+ comodel_name='muk_security.access_groups',
+ relation='%s_groups_rel' % (self._table),
+ column1='aid',
+ column2='gid',
+ string="Groups",
+ automatic=True,
+ groups=self._access_groups_fields))
+ add('complete_groups', fields.Many2many(
+ _module=self._module,
+ comodel_name='muk_security.access_groups',
+ relation='%s_complete_groups_rel' % (self._table),
+ column1='aid',
+ column2='gid',
+ string="Complete Groups",
+ compute='_compute_groups',
+ readonly=True,
+ store=True,
+ automatic=True,
+ compute_sudo=self._access_groups_sudo,
+ groups=self._access_groups_fields))
+
+ #----------------------------------------------------------
+ # Helper
+ #----------------------------------------------------------
+
+
+ def _filter_access(self, operation):
+ records = super(AccessGroupsModel, self)._filter_access(operation)
+ return records.filter_access_groups(operation)
+
+ @api.model
+ def _apply_access_groups(self, query, mode='read'):
+ if self.env.user.id == SUPERUSER_ID or isinstance(self.env.uid, NoSecurityUid):
+ return None
+ where_clause = '''
+ "{table}".id IN (
+ SELECT r.aid
+ FROM {table}_complete_groups_rel r
+ JOIN muk_security_access_groups g ON r.gid = g.id
+ JOIN muk_security_access_groups_users_rel u ON r.gid = u.gid
+ WHERE u.uid = %s AND g.perm_{mode} = true
+ )
+ '''.format(table=self._table, mode=mode)
+ if not self._access_groups_strict:
+ exists_clause = '''
+ NOT EXISTS (
+ SELECT 1
+ FROM {table}_complete_groups_rel r
+ JOIN muk_security_access_groups g ON r.gid = g.id
+ WHERE r.aid = "{table}".id {groups_mode}
+ )
+ '''
+ groups_mode = self._access_groups_mode and 'AND g.perm_{mode} = true'.format(mode=mode)
+ exists_clause = exists_clause.format(table=self._table, groups_mode=groups_mode or "")
+ where_clause = '({groups_clause} OR {exists_clause})'.format(
+ groups_clause=where_clause,
+ exists_clause=exists_clause,
+ )
+ query.where_clause += [where_clause]
+ query.where_clause_params += [self.env.user.id]
+
+ @api.model
+ def _apply_ir_rules(self, query, mode='read'):
+ super(AccessGroupsModel, self)._apply_ir_rules(query, mode=mode)
+ self._apply_access_groups(query, mode=mode)
+
+
+ def _get_ids_without_access_groups(self, operation):
+ sql_query = '''
+ SELECT id
+ FROM {table} a
+ WHERE NOT EXISTS (
+ SELECT 1
+ FROM {table}_complete_groups_rel r
+ JOIN muk_security_access_groups g ON r.gid = g.id
+ WHERE r.aid = a.id {subset} {groups_mode}
+ );
+ '''
+ subset = self.ids and 'AND r.aid = ANY (VALUES {ids})'.format(
+ ids=', '.join(map(lambda id: '(%s)' % id, self.ids))
+ )
+ groups_mode = self._access_groups_mode and 'AND g.perm_{operation} = true'.format(
+ operation=operation
+ )
+ sql_query = sql_query.format(
+ table=self._table,
+ subset=subset or "",
+ groups_mode=groups_mode or "",
+ )
+ self.env.cr.execute(sql_query)
+ return list(map(lambda val: val[0], self.env.cr.fetchall()))
+
+ #----------------------------------------------------------
+ # Function
+ #----------------------------------------------------------
+
+
+ def check_access(self, operation, raise_exception=False):
+ res = super(AccessGroupsModel, self).check_access(operation, raise_exception)
+ try:
+ return res and self.check_access_groups(operation) == None
+ except AccessError:
+ if raise_exception:
+ raise
+ return False
+
+ #----------------------------------------------------------
+ # Security
+ #----------------------------------------------------------
+
+
+ def check_access_groups(self, operation):
+ if self.env.user.id == SUPERUSER_ID or isinstance(self.env.uid, NoSecurityUid):
+ return None
+ group_ids = set(self.ids) - set(self._get_ids_without_access_groups(operation))
+ if group_ids:
+ sql_query = '''
+ SELECT r.aid, perm_{operation}
+ FROM {table}_complete_groups_rel r
+ JOIN muk_security_access_groups g ON r.gid = g.id
+ JOIN muk_security_access_groups_users_rel u ON r.gid = u.gid
+ WHERE r.aid = ANY (VALUES {ids}) AND u.uid = %s;
+ '''.format(
+ operation=operation,
+ table=self._table,
+ ids=', '.join(map(lambda id: '(%s)' % id, group_ids)),
+ )
+ self.env.cr.execute(sql_query, [self.env.user.id])
+ result = defaultdict(list)
+ for key, val in self.env.cr.fetchall():
+ result[key].append(val)
+ if len(result.keys()) < len(group_ids) or not all(list(map(lambda val: any(val), result.values()))):
+ raise AccessError(_(
+ 'The requested operation cannot be completed due to group security restrictions. '
+ 'Please contact your system administrator.\n\n(Document type: %s, Operation: %s)'
+ ) % (self._description, operation))
+
+
+ def filter_access_groups(self, operation):
+ if self.env.user.id == SUPERUSER_ID or isinstance(self.env.uid, NoSecurityUid):
+ return self
+ ids_with_access = self._get_ids_without_access_groups(operation)
+ group_ids = set(self.ids) - set(ids_with_access)
+ if group_ids:
+ sql_query = '''
+ SELECT r.aid
+ FROM {table}_complete_groups_rel r
+ JOIN muk_security_access_groups g ON r.gid = g.id
+ JOIN muk_security_access_groups_users_rel u ON r.gid = u.gid
+ WHERE r.aid = ANY (VALUES {ids}) AND u.uid = %s AND g.perm_{operation} = true;
+ '''.format(
+ table=self._table,
+ ids=', '.join(map(lambda id: '(%s)' % id, group_ids)),
+ operation=operation,
+ )
+ self.env.cr.execute(sql_query, [self.env.user.id])
+ ids_with_access += list(map(lambda val: val[0], self.env.cr.fetchall()))
+ return self & self.browse(ids_with_access)
+
+ #----------------------------------------------------------
+ # Create, Update, Delete
+ #----------------------------------------------------------
+
+
+ def _write(self, vals):
+ self.check_access_groups('write')
+ return super(AccessGroupsModel, self)._write(vals)
+
+
+ def unlink(self):
+ self.check_access_groups('unlink')
+ return super(AccessGroupsModel, self).unlink()
+
+ #----------------------------------------------------------
+ # Groups
+ #----------------------------------------------------------
+
+ @api.depends('groups')
+ def _compute_groups(self):
+ for record in self:
+ record.complete_groups = record.groups
\ No newline at end of file
diff --git a/odex-event/muk_security/models/mixins_access_rights.py b/odex-event/muk_security/models/mixins_access_rights.py
new file mode 100644
index 000000000..e5f296fa3
--- /dev/null
+++ b/odex-event/muk_security/models/mixins_access_rights.py
@@ -0,0 +1,122 @@
+###################################################################################
+#
+# Copyright (c) 2017-2019 MuK IT GmbH.
+#
+# This file is part of MuK Security
+# (see https://mukit.at).
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see .
+#
+###################################################################################
+
+import logging
+
+from odoo import _
+from odoo import models, api, fields
+from odoo.exceptions import AccessError
+
+_logger = logging.getLogger(__name__)
+
+class AccessModel(models.AbstractModel):
+
+ _name = 'muk_security.mixins.access_rights'
+ _description = 'Access Mixin'
+
+ #----------------------------------------------------------
+ # Database
+ #----------------------------------------------------------
+
+ permission_read = fields.Boolean(
+ compute='_compute_permissions_read',
+ search='_search_permission_read',
+ string="Read Access")
+
+ permission_create = fields.Boolean(
+ compute='_compute_permissions_create',
+ search='_search_permission_create',
+ string="Create Access")
+
+ permission_write = fields.Boolean(
+ compute='_compute_permissions_write',
+ search='_search_permission_write',
+ string="Write Access")
+
+ permission_unlink = fields.Boolean(
+ compute='_compute_permissions_unlink',
+ search='_search_permission_unlink',
+ string="Delete Access")
+
+ #----------------------------------------------------------
+ # Search
+ #----------------------------------------------------------
+
+ @api.model
+ def _search_permission_read(self, operator, operand):
+ if operator == '=' and operand:
+ return [('id', 'in', self.search([])._filter_access_ids('read'))]
+ return [('id', 'not in', self.search([])._filter_access_ids('read'))]
+
+ @api.model
+ def _search_permission_create(self, operator, operand):
+ if operator == '=' and operand:
+ return [('id', 'in', self.search([])._filter_access_ids('create'))]
+ return [('id', 'not in', self.search([])._filter_access_ids('create'))]
+
+ @api.model
+ def _search_permission_write(self, operator, operand):
+ if operator == '=' and operand:
+ return [('id', 'in', self.search([])._filter_access_ids('write'))]
+ return [('id', 'not in', self.search([])._filter_access_ids('write'))]
+
+ @api.model
+ def _search_permission_unlink(self, operator, operand):
+ if operator == '=' and operand:
+ return [('id', 'in', self.search([])._filter_access_ids('unlink'))]
+ return [('id', 'not in', self.search([])._filter_access_ids('unlink'))]
+
+ #----------------------------------------------------------
+ # Read, View
+ #----------------------------------------------------------
+
+
+ def _compute_permissions_read(self):
+ records = self._filter_access('read')
+ for record in records:
+ record.update({'permission_read': True})
+ for record in self - records:
+ record.update({'permission_read': False})
+
+
+ def _compute_permissions_create(self):
+ records = self._filter_access('create')
+ for record in records:
+ record.update({'permission_create': True})
+ for record in self - records:
+ record.update({'permission_create': False})
+
+
+ def _compute_permissions_write(self):
+ records = self._filter_access('write')
+ for record in records:
+ record.update({'permission_write': True})
+ for record in self - records:
+ record.update({'permission_write': False})
+
+
+ def _compute_permissions_unlink(self):
+ records = self._filter_access('unlink')
+ for record in records:
+ record.update({'permission_unlink': True})
+ for record in self - records:
+ record.update({'permission_unlink': False})
\ No newline at end of file
diff --git a/odex-event/muk_security/models/mixins_locking.py b/odex-event/muk_security/models/mixins_locking.py
new file mode 100644
index 000000000..1ea8746ba
--- /dev/null
+++ b/odex-event/muk_security/models/mixins_locking.py
@@ -0,0 +1,106 @@
+###################################################################################
+#
+# Copyright (c) 2017-2019 MuK IT GmbH.
+#
+# This file is part of MuK Security
+# (see https://mukit.at).
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see .
+#
+###################################################################################
+
+import os
+import hashlib
+import logging
+import itertools
+
+from odoo import _, SUPERUSER_ID
+from odoo import models, api, fields
+from odoo.exceptions import AccessError
+
+from odoo.addons.muk_security.tools.security import NoSecurityUid
+
+_logger = logging.getLogger(__name__)
+
+class LockingModel(models.AbstractModel):
+
+ _name = 'muk_security.mixins.locking'
+ _description = 'Locking Mixin'
+
+ #----------------------------------------------------------
+ # Database
+ #----------------------------------------------------------
+
+ locked_by = fields.Many2one(
+ comodel_name='res.users',
+ string="Locked by")
+
+ is_locked = fields.Boolean(
+ compute='_compute_locked',
+ string="Locked")
+
+ is_lock_editor = fields.Boolean(
+ compute='_compute_locked',
+ string="Editor")
+
+ #----------------------------------------------------------
+ # Locking
+ #----------------------------------------------------------
+
+
+ def lock(self):
+ self.write({'locked_by': self.env.uid})
+
+
+ def unlock(self):
+ self.write({'locked_by': None})
+
+ @api.model
+ def _check_lock_editor(self, lock_uid):
+ return lock_uid in (self.env.uid, SUPERUSER_ID) or isinstance(self.env.uid, NoSecurityUid)
+
+
+ def check_lock(self):
+ for record in self:
+ if record.locked_by.exists() and not self._check_lock_editor(record.locked_by.id):
+ message = _("The record (%s [%s]) is locked, by an other user.")
+ raise AccessError(message % (record._description, record.id))
+
+ #----------------------------------------------------------
+ # Read, View
+ #----------------------------------------------------------
+
+ @api.depends('locked_by')
+ def _compute_locked(self):
+ for record in self:
+ if record.locked_by.exists():
+ record.update({'is_locked': True, 'is_lock_editor': record.locked_by.id == record.env.uid})
+ else:
+ record.update({'is_locked': False, 'is_lock_editor': False})
+
+ #----------------------------------------------------------
+ # Create, Update, Delete
+ #----------------------------------------------------------
+
+
+ def _write(self, vals):
+ self.check_lock()
+ return super(LockingModel, self)._write(vals)
+
+
+
+ def unlink(self):
+ self.check_lock()
+ return super(LockingModel, self).unlink()
+
diff --git a/odex-event/muk_security/models/res_users.py b/odex-event/muk_security/models/res_users.py
new file mode 100644
index 000000000..df21a742a
--- /dev/null
+++ b/odex-event/muk_security/models/res_users.py
@@ -0,0 +1,49 @@
+###################################################################################
+#
+# Copyright (c) 2017-2019 MuK IT GmbH.
+#
+# This file is part of MuK Security
+# (see https://mukit.at).
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see .
+#
+###################################################################################
+
+import logging
+
+from odoo import api, fields, models
+from odoo import tools, _
+from odoo.exceptions import ValidationError
+
+from odoo.addons.muk_security.tools.security import NoSecurityUid
+from odoo.addons.muk_security.tools.security import convert_security_uid
+
+
+_logger = logging.getLogger(__name__)
+
+class AccessUser(models.Model):
+
+ _inherit = 'res.users'
+
+ #----------------------------------------------------------
+ # Functions
+ #----------------------------------------------------------
+
+ def browse(self, arg=None, *args, **kwargs):
+ return super(AccessUser, self).browse(convert_security_uid(arg), *args, **kwargs)
+
+ @classmethod
+ def _browse(cls, ids, *args, **kwargs):
+ access_ids = [convert_security_uid(id) for id in ids]
+ return super(AccessUser, cls)._browse(access_ids, *args, **kwargs)
\ No newline at end of file
diff --git a/odex-event/muk_security/patch/__init__.py b/odex-event/muk_security/patch/__init__.py
new file mode 100644
index 000000000..e4c0f8c38
--- /dev/null
+++ b/odex-event/muk_security/patch/__init__.py
@@ -0,0 +1,23 @@
+###################################################################################
+#
+# Copyright (c) 2017-2019 MuK IT GmbH.
+#
+# This file is part of MuK Security
+# (see https://mukit.at).
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see .
+#
+###################################################################################
+
+from . import api
\ No newline at end of file
diff --git a/odex-event/muk_security/patch/api.py b/odex-event/muk_security/patch/api.py
new file mode 100644
index 000000000..c19f9d400
--- /dev/null
+++ b/odex-event/muk_security/patch/api.py
@@ -0,0 +1,39 @@
+###################################################################################
+#
+# Copyright (c) 2017-2019 MuK IT GmbH.
+#
+# This file is part of MuK Security
+# (see https://mukit.at).
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see .
+#
+###################################################################################
+
+import logging
+
+from odoo import models, api, SUPERUSER_ID
+
+from odoo.addons.muk_utils.tools import patch
+from odoo.addons.muk_security.tools import security
+
+_logger = logging.getLogger(__name__)
+
+@api.model
+@patch.monkey_patch(api.Environment)
+def __call__(self, cr=None, user=None, context=None):
+ env = __call__.super(self, cr, user, context)
+ if user and isinstance(user, security.NoSecurityUid):
+ env.uid = user
+ return env
+ return env
\ No newline at end of file
diff --git a/odex-event/muk_security/security/ir.model.access.csv b/odex-event/muk_security/security/ir.model.access.csv
new file mode 100644
index 000000000..67bb483c9
--- /dev/null
+++ b/odex-event/muk_security/security/ir.model.access.csv
@@ -0,0 +1,3 @@
+id,name,model_id/id,group_id/id,perm_read,perm_write,perm_create,perm_unlink
+
+access_security_access_groups_user,access_security_access_groups_user,model_muk_security_access_groups,base.group_user,1,1,1,1
\ No newline at end of file
diff --git a/odex-event/muk_security/security/security.xml b/odex-event/muk_security/security/security.xml
new file mode 100644
index 000000000..f53f9589e
--- /dev/null
+++ b/odex-event/muk_security/security/security.xml
@@ -0,0 +1,50 @@
+
+
+
+
+
+
+
+ User can only edit and delete their own groups.
+
+
+
+
+
+
+ [('create_uid','=',user.id)]
+
+
+
+ Admins can edit and delete all groups.
+
+
+
+
+
+
+ [(1 ,'=', 1)]
+
+
+
+
diff --git a/odex-event/muk_security/static/description/banner.png b/odex-event/muk_security/static/description/banner.png
new file mode 100644
index 000000000..a73ca8323
Binary files /dev/null and b/odex-event/muk_security/static/description/banner.png differ
diff --git a/odex-event/muk_security/static/description/icon.png b/odex-event/muk_security/static/description/icon.png
new file mode 100644
index 000000000..9789ede35
Binary files /dev/null and b/odex-event/muk_security/static/description/icon.png differ
diff --git a/odex-event/muk_security/static/description/icon.svg b/odex-event/muk_security/static/description/icon.svg
new file mode 100644
index 000000000..c1e91a8c7
--- /dev/null
+++ b/odex-event/muk_security/static/description/icon.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/odex-event/muk_security/static/description/index.html b/odex-event/muk_security/static/description/index.html
new file mode 100644
index 000000000..e38a4cbde
--- /dev/null
+++ b/odex-event/muk_security/static/description/index.html
@@ -0,0 +1,123 @@
+
+
+
MuK Security
+
Utility Features
+
MuK IT GmbH -
+ www.mukit.at
+
+
+
+
+
+
+
Overview
+
Technical module to provide some utility and
+ security features. The module is mainly used as a dependency by
+ other modules and has no direct visible effect on the system.
+
+
\ No newline at end of file
diff --git a/odex-event/muk_security/static/description/logo.png b/odex-event/muk_security/static/description/logo.png
new file mode 100644
index 000000000..9427ce33e
Binary files /dev/null and b/odex-event/muk_security/static/description/logo.png differ
diff --git a/odex-event/muk_security/static/description/preview.png b/odex-event/muk_security/static/description/preview.png
new file mode 100644
index 000000000..1deb1ccef
Binary files /dev/null and b/odex-event/muk_security/static/description/preview.png differ
diff --git a/odex-event/muk_security/static/description/service_customization.png b/odex-event/muk_security/static/description/service_customization.png
new file mode 100644
index 000000000..3eac66488
Binary files /dev/null and b/odex-event/muk_security/static/description/service_customization.png differ
diff --git a/odex-event/muk_security/static/description/service_development.png b/odex-event/muk_security/static/description/service_development.png
new file mode 100644
index 000000000..580d46046
Binary files /dev/null and b/odex-event/muk_security/static/description/service_development.png differ
diff --git a/odex-event/muk_security/static/description/service_implementation.png b/odex-event/muk_security/static/description/service_implementation.png
new file mode 100644
index 000000000..d64b66bda
Binary files /dev/null and b/odex-event/muk_security/static/description/service_implementation.png differ
diff --git a/odex-event/muk_security/static/description/service_integration.png b/odex-event/muk_security/static/description/service_integration.png
new file mode 100644
index 000000000..76c5e80f4
Binary files /dev/null and b/odex-event/muk_security/static/description/service_integration.png differ
diff --git a/odex-event/muk_security/static/description/service_support.png b/odex-event/muk_security/static/description/service_support.png
new file mode 100644
index 000000000..4c530fafd
Binary files /dev/null and b/odex-event/muk_security/static/description/service_support.png differ
diff --git a/odex-event/muk_security/tests/__init__.py b/odex-event/muk_security/tests/__init__.py
new file mode 100644
index 000000000..cc576ff31
--- /dev/null
+++ b/odex-event/muk_security/tests/__init__.py
@@ -0,0 +1,24 @@
+###################################################################################
+#
+# Copyright (c) 2017-2019 MuK IT GmbH.
+#
+# This file is part of MuK Security
+# (see https://mukit.at).
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see .
+#
+###################################################################################
+
+from . import test_access_groups
+from . import test_suspend_security
\ No newline at end of file
diff --git a/odex-event/muk_security/tests/test_access_groups.py b/odex-event/muk_security/tests/test_access_groups.py
new file mode 100644
index 000000000..fbf9c43ae
--- /dev/null
+++ b/odex-event/muk_security/tests/test_access_groups.py
@@ -0,0 +1,86 @@
+###################################################################################
+#
+# Copyright (c) 2017-2019 MuK IT GmbH.
+#
+# This file is part of MuK Security
+# (see https://mukit.at).
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see .
+#
+###################################################################################
+
+import os
+import base64
+import logging
+
+from odoo import exceptions
+from odoo.tests import common
+
+_path = os.path.dirname(os.path.dirname(__file__))
+_logger = logging.getLogger(__name__)
+
+class AccessGroupsTestCase(common.TransactionCase):
+
+ def setUp(self):
+ super(AccessGroupsTestCase, self).setUp()
+ self.user_id = self.ref('base.user_demo')
+ self.group_id = self.ref('base.group_system')
+ self.groups = self.env['muk_security.access_groups']
+ self.group01 = self.groups.create({
+ 'name': 'Group 01',
+ 'explicit_users': [(6, 0, [self.user_id])]})
+ self.group02 = self.groups.create({
+ 'name': 'Group 02',
+ 'groups': [(6, 0, [self.group_id])]})
+ self.user = self.env['res.users'].browse(self.user_id)
+ self.group = self.env['res.groups'].browse(self.group_id)
+
+ def tearDown(self):
+ super(AccessGroupsTestCase, self).tearDown()
+
+ def test_access_groups_users(self):
+ count = len(self.group02.users)
+ self.group02.write({'explicit_users': [(6, 0, [self.user_id])]})
+ self.assertTrue(len(self.group02.users) > count)
+
+ def test_access_groups_groups(self):
+ count = len(self.group01.users)
+ self.group01.write({'groups': [(6, 0, [self.group_id])]})
+ self.assertTrue(len(self.group01.users) > count)
+
+ def test_access_groups_groups_group(self):
+ count = len(self.group02.users)
+ self.group.write({'users': [(4, self.user_id)]})
+ self.assertTrue(len(self.group02.users) > count)
+
+ def test_access_groups_groups_user(self):
+ count = len(self.group02.users)
+ self.user.write({'groups_id':[(4, self.group_id)]})
+ self.assertTrue(len(self.group02.users) > count)
+
+ def test_access_groups_parent(self):
+ count = len(self.group02.users)
+ self.group02.write({'parent_group': self.group01.id})
+ self.assertTrue(len(self.group02.users) > count)
+
+ def test_access_groups_parent_multi(self):
+ group01 = self.groups.create({'name': 'MGroup 01'})
+ group02 = self.groups.create({'name': 'MGroup 02', 'parent_group': group01.id})
+ group03 = self.groups.create({'name': 'MGroup 03', 'parent_group': group02.id})
+ init_count = len(group03.users)
+ group02.write({'explicit_users': [(6, 0, [self.user_id])]})
+ self.assertTrue(len(group03.users) > init_count)
+ updated_count = len(group03.users)
+ group01.write({'groups': [(6, 0, [self.group_id])]})
+ self.assertTrue(len(group03.users) > updated_count)
\ No newline at end of file
diff --git a/odex-event/muk_security/tests/test_suspend_security.py b/odex-event/muk_security/tests/test_suspend_security.py
new file mode 100644
index 000000000..1be02c304
--- /dev/null
+++ b/odex-event/muk_security/tests/test_suspend_security.py
@@ -0,0 +1,72 @@
+###################################################################################
+#
+# Copyright (c) 2017-2019 MuK IT GmbH.
+#
+# This file is part of MuK Security
+# (see https://mukit.at).
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see .
+#
+###################################################################################
+
+import os
+import base64
+import logging
+
+from odoo import exceptions
+from odoo.tests import common
+
+_path = os.path.dirname(os.path.dirname(__file__))
+_logger = logging.getLogger(__name__)
+
+class SuspendSecurityTestCase(common.TransactionCase):
+
+ def setUp(self):
+ super(SuspendSecurityTestCase, self).setUp()
+
+ def tearDown(self):
+ super(SuspendSecurityTestCase, self).tearDown()
+
+ def test_suspend_security(self):
+ user_id = self.env.ref('base.user_demo').id
+ tester = self.env.ref('base.user_root').sudo(user_id)
+ with self.assertRaises(exceptions.AccessError):
+ tester.write({'login': 'test'})
+ tester.suspend_security().write({'login': 'test'})
+ self.assertEqual(tester.login, 'test')
+ self.assertEqual(tester.write_uid.id, user_id)
+
+ def test_normalize(self):
+ self.env['res.users'].browse(self.env['res.users'].suspend_security().env.uid)
+
+ def test_search_one2many(self):
+ user = self.env.ref('base.user_demo')
+ model = self.env['res.partner'].sudo(user.id)
+ self.assertTrue(model.env.user.id == user.id)
+ normal_domain = [('user_ids.id', '=', model.env.uid)]
+ suspend_domain = [('user_ids.id', '=', model.suspend_security().env.uid)]
+ normal_partner = model.search(normal_domain, limit=1)
+ suspend_partner = model.search(suspend_domain, limit=1)
+ self.assertEqual(normal_partner, suspend_partner)
+ normal_domain = [('user_ids', '=', model.env.uid)]
+ suspend_domain = [('user_ids', '=', model.suspend_security().env.uid)]
+ normal_partner = model.search(normal_domain, limit=1)
+ suspend_partner = model.search(suspend_domain, limit=1)
+ self.assertEqual(normal_partner, suspend_partner)
+ normal_domain = [('user_ids.id', 'in', [model.env.uid])]
+ suspend_domain = [('user_ids.id', 'in', [model.suspend_security().env.uid])]
+ normal_partner = model.search(normal_domain, limit=1)
+ suspend_partner = model.search(suspend_domain, limit=1)
+ self.assertEqual(normal_partner, suspend_partner)
+
\ No newline at end of file
diff --git a/odex-event/muk_security/tools/__init__.py b/odex-event/muk_security/tools/__init__.py
new file mode 100644
index 000000000..433767f6a
--- /dev/null
+++ b/odex-event/muk_security/tools/__init__.py
@@ -0,0 +1,23 @@
+###################################################################################
+#
+# Copyright (c) 2017-2019 MuK IT GmbH.
+#
+# This file is part of MuK Security
+# (see https://mukit.at).
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see .
+#
+###################################################################################
+
+from . import security
\ No newline at end of file
diff --git a/odex-event/muk_security/tools/security.py b/odex-event/muk_security/tools/security.py
new file mode 100644
index 000000000..927a7dfa8
--- /dev/null
+++ b/odex-event/muk_security/tools/security.py
@@ -0,0 +1,47 @@
+###################################################################################
+#
+# Copyright (c) 2017-2019 MuK IT GmbH.
+#
+# This file is part of MuK Security
+# (see https://mukit.at).
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see .
+#
+###################################################################################
+
+#----------------------------------------------------------
+# Helper
+#----------------------------------------------------------
+
+def convert_security_uid(id):
+ if isinstance(id, NoSecurityUid):
+ return super(NoSecurityUid, id).__int__()
+ return id
+
+#----------------------------------------------------------
+# Model
+#----------------------------------------------------------
+
+class NoSecurityUid(int):
+
+ def __int__(self):
+ return self
+
+ def __eq__(self, other):
+ if isinstance(other, int):
+ return False
+ return super(NoSecurityUid, self).__int__() == other
+
+ def __hash__(self):
+ return super(NoSecurityUid, self).__hash__()
\ No newline at end of file
diff --git a/odex-event/muk_security/views/access_groups.xml b/odex-event/muk_security/views/access_groups.xml
new file mode 100644
index 000000000..1f9f325f6
--- /dev/null
+++ b/odex-event/muk_security/views/access_groups.xml
@@ -0,0 +1,78 @@
+
+
+
+
+
+
+
+ muk_security_access_groups.tree
+ muk_security.access_groups
+ primary
+
+
+
+
+
+
+
+
+
+
+
+
+ muk_security_access_groups.form
+ muk_security.access_groups
+ primary
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Access Groups
+ muk_security.access_groups
+ tree,form
+
+
+
+
+
\ No newline at end of file
diff --git a/odex-event/muk_utils/LICENSE b/odex-event/muk_utils/LICENSE
new file mode 100644
index 000000000..153d416dc
--- /dev/null
+++ b/odex-event/muk_utils/LICENSE
@@ -0,0 +1,165 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+
+ This version of the GNU Lesser General Public License incorporates
+the terms and conditions of version 3 of the GNU General Public
+License, supplemented by the additional permissions listed below.
+
+ 0. Additional Definitions.
+
+ As used herein, "this License" refers to version 3 of the GNU Lesser
+General Public License, and the "GNU GPL" refers to version 3 of the GNU
+General Public License.
+
+ "The Library" refers to a covered work governed by this License,
+other than an Application or a Combined Work as defined below.
+
+ An "Application" is any work that makes use of an interface provided
+by the Library, but which is not otherwise based on the Library.
+Defining a subclass of a class defined by the Library is deemed a mode
+of using an interface provided by the Library.
+
+ A "Combined Work" is a work produced by combining or linking an
+Application with the Library. The particular version of the Library
+with which the Combined Work was made is also called the "Linked
+Version".
+
+ The "Minimal Corresponding Source" for a Combined Work means the
+Corresponding Source for the Combined Work, excluding any source code
+for portions of the Combined Work that, considered in isolation, are
+based on the Application, and not on the Linked Version.
+
+ The "Corresponding Application Code" for a Combined Work means the
+object code and/or source code for the Application, including any data
+and utility programs needed for reproducing the Combined Work from the
+Application, but excluding the System Libraries of the Combined Work.
+
+ 1. Exception to Section 3 of the GNU GPL.
+
+ You may convey a covered work under sections 3 and 4 of this License
+without being bound by section 3 of the GNU GPL.
+
+ 2. Conveying Modified Versions.
+
+ If you modify a copy of the Library, and, in your modifications, a
+facility refers to a function or data to be supplied by an Application
+that uses the facility (other than as an argument passed when the
+facility is invoked), then you may convey a copy of the modified
+version:
+
+ a) under this License, provided that you make a good faith effort to
+ ensure that, in the event an Application does not supply the
+ function or data, the facility still operates, and performs
+ whatever part of its purpose remains meaningful, or
+
+ b) under the GNU GPL, with none of the additional permissions of
+ this License applicable to that copy.
+
+ 3. Object Code Incorporating Material from Library Header Files.
+
+ The object code form of an Application may incorporate material from
+a header file that is part of the Library. You may convey such object
+code under terms of your choice, provided that, if the incorporated
+material is not limited to numerical parameters, data structure
+layouts and accessors, or small macros, inline functions and templates
+(ten or fewer lines in length), you do both of the following:
+
+ a) Give prominent notice with each copy of the object code that the
+ Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the object code with a copy of the GNU GPL and this license
+ document.
+
+ 4. Combined Works.
+
+ You may convey a Combined Work under terms of your choice that,
+taken together, effectively do not restrict modification of the
+portions of the Library contained in the Combined Work and reverse
+engineering for debugging such modifications, if you also do each of
+the following:
+
+ a) Give prominent notice with each copy of the Combined Work that
+ the Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the Combined Work with a copy of the GNU GPL and this license
+ document.
+
+ c) For a Combined Work that displays copyright notices during
+ execution, include the copyright notice for the Library among
+ these notices, as well as a reference directing the user to the
+ copies of the GNU GPL and this license document.
+
+ d) Do one of the following:
+
+ 0) Convey the Minimal Corresponding Source under the terms of this
+ License, and the Corresponding Application Code in a form
+ suitable for, and under terms that permit, the user to
+ recombine or relink the Application with a modified version of
+ the Linked Version to produce a modified Combined Work, in the
+ manner specified by section 6 of the GNU GPL for conveying
+ Corresponding Source.
+
+ 1) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (a) uses at run time
+ a copy of the Library already present on the user's computer
+ system, and (b) will operate properly with a modified version
+ of the Library that is interface-compatible with the Linked
+ Version.
+
+ e) Provide Installation Information, but only if you would otherwise
+ be required to provide such information under section 6 of the
+ GNU GPL, and only to the extent that such information is
+ necessary to install and execute a modified version of the
+ Combined Work produced by recombining or relinking the
+ Application with a modified version of the Linked Version. (If
+ you use option 4d0, the Installation Information must accompany
+ the Minimal Corresponding Source and Corresponding Application
+ Code. If you use option 4d1, you must provide the Installation
+ Information in the manner specified by section 6 of the GNU GPL
+ for conveying Corresponding Source.)
+
+ 5. Combined Libraries.
+
+ You may place library facilities that are a work based on the
+Library side by side in a single library together with other library
+facilities that are not Applications and are not covered by this
+License, and convey such a combined library under terms of your
+choice, if you do both of the following:
+
+ a) Accompany the combined library with a copy of the same work based
+ on the Library, uncombined with any other library facilities,
+ conveyed under the terms of this License.
+
+ b) Give prominent notice with the combined library that part of it
+ is a work based on the Library, and explaining where to find the
+ accompanying uncombined form of the same work.
+
+ 6. Revised Versions of the GNU Lesser General Public License.
+
+ The Free Software Foundation may publish revised and/or new versions
+of the GNU Lesser General Public License from time to time. Such new
+versions will be similar in spirit to the present version, but may
+differ in detail to address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Library as you received it specifies that a certain numbered version
+of the GNU Lesser General Public License "or any later version"
+applies to it, you have the option of following the terms and
+conditions either of that published version or of any later version
+published by the Free Software Foundation. If the Library as you
+received it does not specify a version number of the GNU Lesser
+General Public License, you may choose any version of the GNU Lesser
+General Public License ever published by the Free Software Foundation.
+
+ If the Library as you received it specifies that a proxy can decide
+whether future versions of the GNU Lesser General Public License shall
+apply, that proxy's public statement of acceptance of any version is
+permanent authorization for you to choose that version for the
+Library.
\ No newline at end of file
diff --git a/odex-event/muk_utils/README.rst b/odex-event/muk_utils/README.rst
new file mode 100644
index 000000000..9cde5dde1
--- /dev/null
+++ b/odex-event/muk_utils/README.rst
@@ -0,0 +1,113 @@
+=========
+MuK Utils
+=========
+
+Technical module to provide some utility features and libraries that can be used
+in other applications. This module has no direct effect on the running system.
+
+Installation
+============
+
+To install this module, you need to:
+
+Download the module and add it to your Odoo addons folder. Afterward, log on to
+your Odoo server and go to the Apps menu. Trigger the debug mode and update the
+list by clicking on the "Update Apps List" link. Now install the module by
+clicking on the install button.
+
+Another way to install this module is via the package management for Python
+(`PyPI `_).
+
+To install our modules using the package manager make sure
+`odoo-autodiscover `_ is installed
+correctly. Then open a console and install the module by entering the following
+command:
+
+``pip install --extra-index-url https://nexus.mukit.at/repository/odoo/simple ``
+
+The module name consists of the Odoo version and the module name, where
+underscores are replaced by a dash.
+
+**Module:**
+
+``odoo-addon-``
+
+**Example:**
+
+``sudo -H pip3 install --extra-index-url https://nexus.mukit.at/repository/odoo/simple odoo11-addon-muk-utils``
+
+Once the installation has been successfully completed, the app is already in the
+correct folder. Log on to your Odoo server and go to the Apps menu. Trigger the
+debug mode and update the list by clicking on the "Update Apps List" link. Now
+install the module by clicking on the install button.
+
+The biggest advantage of this variant is that you can now also update the app
+using the "pip" command. To do this, enter the following command in your console:
+
+``pip install --upgrade --extra-index-url https://nexus.mukit.at/repository/odoo/simple ``
+
+When the process is finished, restart your server and update the application in
+Odoo. The steps are the same as for the installation only the button has changed
+from "Install" to "Upgrade".
+
+You can also view available Apps directly in our `repository `_
+and find a more detailed installation guide on our `website `_.
+
+For modules licensed under OPL-1, you will receive access data when you purchase
+the module. If the modules were not purchased directly from
+`MuK IT `_ please contact our support (support@mukit.at)
+with a confirmation of purchase to receive the corresponding access data.
+
+Upgrade
+============
+
+To upgrade this module, you need to:
+
+Download the module and add it to your Odoo addons folder. Restart the server
+and log on to your Odoo server. Select the Apps menu and upgrade the module by
+clicking on the upgrade button.
+
+If you installed the module using the "pip" command, you can also update the
+module in the same way. Just type the following command into the console:
+
+``pip install --upgrade --extra-index-url https://nexus.mukit.at/repository/odoo/simple ``
+
+When the process is finished, restart your server and update the application in
+Odoo, just like you would normally.
+
+Configuration
+=============
+
+No additional configuration is needed to use this module.
+
+Usage
+=============
+
+This module has no direct visible effect on the system. It provide utility features.
+
+Credits
+=======
+
+Contributors
+------------
+
+* Mathias Markl
+
+Images
+------------
+
+Some pictures are based on or inspired by the icon set of Font Awesome:
+
+* `Font Awesome `_
+
+Author & Maintainer
+-------------------
+
+This module is maintained by the `MuK IT GmbH `_.
+
+MuK IT is an Austrian company specialized in customizing and extending Odoo.
+We develop custom solutions for your individual needs to help you focus on
+your strength and expertise to grow your business.
+
+If you want to get in touch please contact us via mail
+(sale@mukit.at) or visit our website (https://mukit.at).
diff --git a/odex-event/muk_utils/__init__.py b/odex-event/muk_utils/__init__.py
new file mode 100644
index 000000000..1124bf231
--- /dev/null
+++ b/odex-event/muk_utils/__init__.py
@@ -0,0 +1,24 @@
+###################################################################################
+#
+# Copyright (c) 2017-2019 MuK IT GmbH.
+#
+# This file is part of MuK Utils
+# (see https://mukit.at).
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see .
+#
+###################################################################################
+
+from . import models
+from . import tools
\ No newline at end of file
diff --git a/odex-event/muk_utils/__manifest__.py b/odex-event/muk_utils/__manifest__.py
new file mode 100644
index 000000000..15caa1450
--- /dev/null
+++ b/odex-event/muk_utils/__manifest__.py
@@ -0,0 +1,57 @@
+###################################################################################
+#
+# Copyright (c) 2017-2019 MuK IT GmbH.
+#
+# This file is part of MuK Utils
+# (see https://mukit.at).
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see .
+#
+###################################################################################
+{
+ "name": "MuK Utils",
+ "summary": """Utility Features""",
+ "version": '12.0.2.0.7',
+ "category": 'Extra Tools',
+ "license": "LGPL-3",
+ "author": "MuK IT",
+ "website": "https://www.mukit.at",
+ 'live_test_url': 'https://mukit.at/r/SgN',
+ "contributors": [
+ "Mathias Markl ",
+ ],
+ "depends": [
+ "base_setup",
+ ],
+ "data": [
+ "actions/ir_attachment.xml",
+ "views/ir_attachment.xml",
+ "views/mixins_groups.xml",
+ "views/res_config_settings.xml",
+ ],
+ "qweb": [
+ "static/src/xml/*.xml",
+ ],
+ "images": [
+ 'static/description/banner.png'
+ ],
+ "external_dependencies": {
+ "python": [],
+ "bin": [],
+ },
+ "sequence": 3,
+ "application": False,
+ "installable": True,
+ "auto_install": False,
+}
diff --git a/odex-event/muk_utils/actions/ir_attachment.xml b/odex-event/muk_utils/actions/ir_attachment.xml
new file mode 100644
index 000000000..a0515050f
--- /dev/null
+++ b/odex-event/muk_utils/actions/ir_attachment.xml
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+ Migrate
+
+
+ code
+ records.action_migrate()
+
+
+
\ No newline at end of file
diff --git a/odex-event/muk_utils/doc/changelog.rst b/odex-event/muk_utils/doc/changelog.rst
new file mode 100644
index 000000000..fcc96352f
--- /dev/null
+++ b/odex-event/muk_utils/doc/changelog.rst
@@ -0,0 +1,34 @@
+`1.6.0`
+-------
+
+- Override Attachment to make it more extendable
+
+`1.5.0`
+-------
+
+- Storage Migration Action
+
+`1.4.0`
+-------
+
+- Added Hierarchy Mixin
+
+`1.3.0`
+-------
+
+- Added SCSS Editor
+
+`1.2.0`
+-------
+
+- Added Group Mixin
+
+`1.1.0`
+-------
+
+- Added Storage Settings
+
+`1.0.0`
+-------
+
+- Init Version
diff --git a/odex-event/muk_utils/doc/index.rst b/odex-event/muk_utils/doc/index.rst
new file mode 100644
index 000000000..9cde5dde1
--- /dev/null
+++ b/odex-event/muk_utils/doc/index.rst
@@ -0,0 +1,113 @@
+=========
+MuK Utils
+=========
+
+Technical module to provide some utility features and libraries that can be used
+in other applications. This module has no direct effect on the running system.
+
+Installation
+============
+
+To install this module, you need to:
+
+Download the module and add it to your Odoo addons folder. Afterward, log on to
+your Odoo server and go to the Apps menu. Trigger the debug mode and update the
+list by clicking on the "Update Apps List" link. Now install the module by
+clicking on the install button.
+
+Another way to install this module is via the package management for Python
+(`PyPI `_).
+
+To install our modules using the package manager make sure
+`odoo-autodiscover `_ is installed
+correctly. Then open a console and install the module by entering the following
+command:
+
+``pip install --extra-index-url https://nexus.mukit.at/repository/odoo/simple ``
+
+The module name consists of the Odoo version and the module name, where
+underscores are replaced by a dash.
+
+**Module:**
+
+``odoo-addon-``
+
+**Example:**
+
+``sudo -H pip3 install --extra-index-url https://nexus.mukit.at/repository/odoo/simple odoo11-addon-muk-utils``
+
+Once the installation has been successfully completed, the app is already in the
+correct folder. Log on to your Odoo server and go to the Apps menu. Trigger the
+debug mode and update the list by clicking on the "Update Apps List" link. Now
+install the module by clicking on the install button.
+
+The biggest advantage of this variant is that you can now also update the app
+using the "pip" command. To do this, enter the following command in your console:
+
+``pip install --upgrade --extra-index-url https://nexus.mukit.at/repository/odoo/simple ``
+
+When the process is finished, restart your server and update the application in
+Odoo. The steps are the same as for the installation only the button has changed
+from "Install" to "Upgrade".
+
+You can also view available Apps directly in our `repository `_
+and find a more detailed installation guide on our `website `_.
+
+For modules licensed under OPL-1, you will receive access data when you purchase
+the module. If the modules were not purchased directly from
+`MuK IT `_ please contact our support (support@mukit.at)
+with a confirmation of purchase to receive the corresponding access data.
+
+Upgrade
+============
+
+To upgrade this module, you need to:
+
+Download the module and add it to your Odoo addons folder. Restart the server
+and log on to your Odoo server. Select the Apps menu and upgrade the module by
+clicking on the upgrade button.
+
+If you installed the module using the "pip" command, you can also update the
+module in the same way. Just type the following command into the console:
+
+``pip install --upgrade --extra-index-url https://nexus.mukit.at/repository/odoo/simple ``
+
+When the process is finished, restart your server and update the application in
+Odoo, just like you would normally.
+
+Configuration
+=============
+
+No additional configuration is needed to use this module.
+
+Usage
+=============
+
+This module has no direct visible effect on the system. It provide utility features.
+
+Credits
+=======
+
+Contributors
+------------
+
+* Mathias Markl
+
+Images
+------------
+
+Some pictures are based on or inspired by the icon set of Font Awesome:
+
+* `Font Awesome `_
+
+Author & Maintainer
+-------------------
+
+This module is maintained by the `MuK IT GmbH `_.
+
+MuK IT is an Austrian company specialized in customizing and extending Odoo.
+We develop custom solutions for your individual needs to help you focus on
+your strength and expertise to grow your business.
+
+If you want to get in touch please contact us via mail
+(sale@mukit.at) or visit our website (https://mukit.at).
diff --git a/odex-event/muk_utils/i18n/ar.po b/odex-event/muk_utils/i18n/ar.po
new file mode 100644
index 000000000..ba1adcdf7
--- /dev/null
+++ b/odex-event/muk_utils/i18n/ar.po
@@ -0,0 +1,211 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * muk_utils
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 12.0-20190522\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2019-07-13 09:39+0000\n"
+"PO-Revision-Date: 2019-07-13 09:39+0000\n"
+"Last-Translator: <>\n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: \n"
+
+#. module: muk_utils
+#: model_terms:ir.ui.view,arch_db:muk_utils.res_config_settings_view_form
+msgid "Save this page before triggering the migration."
+msgstr ""
+
+#. module: muk_utils
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_attachment_search
+msgid "All Data"
+msgstr ""
+
+#. module: muk_utils
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_attachment_search
+msgid "Attached Document Field"
+msgstr ""
+
+#. module: muk_utils
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_attachment_search
+msgid "Attached Document Model"
+msgstr ""
+
+#. module: muk_utils
+#: model:ir.model,name:muk_utils.model_ir_attachment
+msgid "Attachment"
+msgstr "مرفق"
+
+#. module: muk_utils
+#: model_terms:ir.ui.view,arch_db:muk_utils.res_config_settings_view_form
+msgid "Attachment storage location"
+msgstr ""
+
+#. module: muk_utils
+#: model:ir.model.fields,help:muk_utils.field_res_config_settings__attachment_location
+msgid "Attachment storage location."
+msgstr ""
+
+#. module: muk_utils
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_attachment_search
+msgid "Attachments"
+msgstr "المُرفقات"
+
+#. module: muk_utils
+#: model:ir.model,name:muk_utils.model_base
+msgid "Base"
+msgstr "الأساس"
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_groups__child_groups
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_mixins_groups_form
+msgid "Child Groups"
+msgstr ""
+
+#. module: muk_utils
+#: model:ir.model,name:muk_utils.model_res_config_settings
+msgid "Config Settings"
+msgstr "ضبط الإعدادات"
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_groups__display_name
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_hierarchy__display_name
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_scss_editor__display_name
+msgid "Display Name"
+msgstr "اسم العرض"
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_groups__explicit_users
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_mixins_groups_form
+msgid "Explicit Users"
+msgstr ""
+
+#. module: muk_utils
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_attachment_search
+msgid "Field Data"
+msgstr ""
+
+#. module: muk_utils
+#: model_terms:ir.ui.view,arch_db:muk_utils.res_config_settings_view_form
+msgid "Force Storage Migration"
+msgstr ""
+
+#. module: muk_utils
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_mixins_groups_form
+msgid "Group"
+msgstr "المجموعة"
+
+#. module: muk_utils
+#: model:ir.model,name:muk_utils.model_muk_utils_mixins_groups
+msgid "Group Mixin"
+msgstr ""
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_groups__name
+msgid "Group Name"
+msgstr "اسم المجموعة"
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_groups__users
+msgid "Group Users"
+msgstr ""
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_groups__groups
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_mixins_groups_form
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_mixins_groups_tree
+msgid "Groups"
+msgstr "المجموعات"
+
+#. module: muk_utils
+#: model:ir.model,name:muk_utils.model_muk_utils_mixins_hierarchy
+msgid "Hierarchy Mixin"
+msgstr ""
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_groups__id
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_hierarchy__id
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_scss_editor__id
+msgid "ID"
+msgstr "المعرف"
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_groups____last_update
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_hierarchy____last_update
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_scss_editor____last_update
+msgid "Last Modified on"
+msgstr "آخر تعديل في"
+
+#. module: muk_utils
+#: model:ir.actions.server,name:muk_utils.action_attachment_migrate
+msgid "Migrate"
+msgstr ""
+
+#. module: muk_utils
+#: code:addons/muk_utils/models/ir_attachment.py:87
+#, python-format
+msgid "Only administrators can execute this action."
+msgstr ""
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_groups__parent_group
+msgid "Parent Group"
+msgstr ""
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_groups__parent_path
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_hierarchy__parent_path
+msgid "Parent Path"
+msgstr "المسار الأصلي"
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_hierarchy__parent_path_json
+msgid "Path Json"
+msgstr ""
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_hierarchy__parent_path_names
+msgid "Path Names"
+msgstr ""
+
+#. module: muk_utils
+#: model:ir.model,name:muk_utils.model_muk_utils_scss_editor
+msgid "Scss Editor"
+msgstr ""
+
+#. module: muk_utils
+#: model_terms:ir.ui.view,arch_db:muk_utils.res_config_settings_view_form
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_attachment_form
+msgid "Storage"
+msgstr ""
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_res_config_settings__attachment_location
+msgid "Storage Location"
+msgstr ""
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_res_config_settings__attachment_location_changed
+msgid "Storage Location Changed"
+msgstr ""
+
+#. module: muk_utils
+#: model:ir.model,name:muk_utils.model_ir_config_parameter
+msgid "System Parameter"
+msgstr "باراميتر النظام"
+
+#. module: muk_utils
+#: sql_constraint:muk_utils.mixins.groups:0
+msgid "The name of the group must be unique!"
+msgstr ""
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_groups__count_users
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_mixins_groups_form
+msgid "Users"
+msgstr "المستخدمون"
+
diff --git a/odex-event/muk_utils/i18n/de.po b/odex-event/muk_utils/i18n/de.po
new file mode 100644
index 000000000..09af85047
--- /dev/null
+++ b/odex-event/muk_utils/i18n/de.po
@@ -0,0 +1,211 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * muk_utils
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 12.0-20190522\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2019-07-13 09:39+0000\n"
+"PO-Revision-Date: 2019-07-13 09:39+0000\n"
+"Last-Translator: <>\n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: \n"
+
+#. module: muk_utils
+#: model_terms:ir.ui.view,arch_db:muk_utils.res_config_settings_view_form
+msgid "Save this page before triggering the migration."
+msgstr "SpeichernSie diese Seite, bevor Sie die Migration auslösen."
+
+#. module: muk_utils
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_attachment_search
+msgid "All Data"
+msgstr "Alle Daten"
+
+#. module: muk_utils
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_attachment_search
+msgid "Attached Document Field"
+msgstr "Dokumenten Feld"
+
+#. module: muk_utils
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_attachment_search
+msgid "Attached Document Model"
+msgstr "Dokumenten Model"
+
+#. module: muk_utils
+#: model:ir.model,name:muk_utils.model_ir_attachment
+msgid "Attachment"
+msgstr "Dateianhang"
+
+#. module: muk_utils
+#: model_terms:ir.ui.view,arch_db:muk_utils.res_config_settings_view_form
+msgid "Attachment storage location"
+msgstr "Speicherort des Attachments"
+
+#. module: muk_utils
+#: model:ir.model.fields,help:muk_utils.field_res_config_settings__attachment_location
+msgid "Attachment storage location."
+msgstr "Speicherort des Attachments."
+
+#. module: muk_utils
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_attachment_search
+msgid "Attachments"
+msgstr "Dateianhänge"
+
+#. module: muk_utils
+#: model:ir.model,name:muk_utils.model_base
+msgid "Base"
+msgstr "Basis"
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_groups__child_groups
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_mixins_groups_form
+msgid "Child Groups"
+msgstr "Untergruppen"
+
+#. module: muk_utils
+#: model:ir.model,name:muk_utils.model_res_config_settings
+msgid "Config Settings"
+msgstr "Konfiguration "
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_groups__display_name
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_hierarchy__display_name
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_scss_editor__display_name
+msgid "Display Name"
+msgstr "Anzeigename"
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_groups__explicit_users
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_mixins_groups_form
+msgid "Explicit Users"
+msgstr "Explizite Benutzer"
+
+#. module: muk_utils
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_attachment_search
+msgid "Field Data"
+msgstr "Felddaten"
+
+#. module: muk_utils
+#: model_terms:ir.ui.view,arch_db:muk_utils.res_config_settings_view_form
+msgid "Force Storage Migration"
+msgstr "Speichermigration erzwingen"
+
+#. module: muk_utils
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_mixins_groups_form
+msgid "Group"
+msgstr "Gruppe"
+
+#. module: muk_utils
+#: model:ir.model,name:muk_utils.model_muk_utils_mixins_groups
+msgid "Group Mixin"
+msgstr "Gruppen Mixin"
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_groups__name
+msgid "Group Name"
+msgstr "Gruppenname"
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_groups__users
+msgid "Group Users"
+msgstr "Gruppenbenutzer"
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_groups__groups
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_mixins_groups_form
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_mixins_groups_tree
+msgid "Groups"
+msgstr "Gruppen"
+
+#. module: muk_utils
+#: model:ir.model,name:muk_utils.model_muk_utils_mixins_hierarchy
+msgid "Hierarchy Mixin"
+msgstr "Hierarchie Mixin"
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_groups__id
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_hierarchy__id
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_scss_editor__id
+msgid "ID"
+msgstr ""
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_groups____last_update
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_hierarchy____last_update
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_scss_editor____last_update
+msgid "Last Modified on"
+msgstr "Zuletzt geändert am"
+
+#. module: muk_utils
+#: model:ir.actions.server,name:muk_utils.action_attachment_migrate
+msgid "Migrate"
+msgstr "Migrieren"
+
+#. module: muk_utils
+#: code:addons/muk_utils/models/ir_attachment.py:87
+#, python-format
+msgid "Only administrators can execute this action."
+msgstr ""
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_groups__parent_group
+msgid "Parent Group"
+msgstr "Übergeordnete Gruppe"
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_groups__parent_path
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_hierarchy__parent_path
+msgid "Parent Path"
+msgstr "Übergeordneter Pfad"
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_hierarchy__parent_path_json
+msgid "Path Json"
+msgstr "Json Pfad"
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_hierarchy__parent_path_names
+msgid "Path Names"
+msgstr "Pfadnamen"
+
+#. module: muk_utils
+#: model:ir.model,name:muk_utils.model_muk_utils_scss_editor
+msgid "Scss Editor"
+msgstr ""
+
+#. module: muk_utils
+#: model_terms:ir.ui.view,arch_db:muk_utils.res_config_settings_view_form
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_attachment_form
+msgid "Storage"
+msgstr "Speicher"
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_res_config_settings__attachment_location
+msgid "Storage Location"
+msgstr "Speicherort"
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_res_config_settings__attachment_location_changed
+msgid "Storage Location Changed"
+msgstr "Speicherort geändert"
+
+#. module: muk_utils
+#: model:ir.model,name:muk_utils.model_ir_config_parameter
+msgid "System Parameter"
+msgstr "Systemparameter"
+
+#. module: muk_utils
+#: sql_constraint:muk_utils.mixins.groups:0
+msgid "The name of the group must be unique!"
+msgstr "Der Name der Gruppe muss einzigartig sein!"
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_groups__count_users
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_mixins_groups_form
+msgid "Users"
+msgstr "Benutzer"
+
diff --git a/odex-event/muk_utils/i18n/es.po b/odex-event/muk_utils/i18n/es.po
new file mode 100644
index 000000000..a79540b47
--- /dev/null
+++ b/odex-event/muk_utils/i18n/es.po
@@ -0,0 +1,211 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * muk_utils
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 12.0-20190522\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2019-07-13 09:39+0000\n"
+"PO-Revision-Date: 2019-07-13 09:39+0000\n"
+"Last-Translator: <>\n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: \n"
+
+#. module: muk_utils
+#: model_terms:ir.ui.view,arch_db:muk_utils.res_config_settings_view_form
+msgid "Save this page before triggering the migration."
+msgstr "Save esta página antes de iniciar la migración."
+
+#. module: muk_utils
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_attachment_search
+msgid "All Data"
+msgstr "Todos los datos"
+
+#. module: muk_utils
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_attachment_search
+msgid "Attached Document Field"
+msgstr "Campo de documento adjunto"
+
+#. module: muk_utils
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_attachment_search
+msgid "Attached Document Model"
+msgstr "Modelo de documento adjunto"
+
+#. module: muk_utils
+#: model:ir.model,name:muk_utils.model_ir_attachment
+msgid "Attachment"
+msgstr "Adjunto"
+
+#. module: muk_utils
+#: model_terms:ir.ui.view,arch_db:muk_utils.res_config_settings_view_form
+msgid "Attachment storage location"
+msgstr "Almacén de anexos"
+
+#. module: muk_utils
+#: model:ir.model.fields,help:muk_utils.field_res_config_settings__attachment_location
+msgid "Attachment storage location."
+msgstr "Almacén de archivos adjuntos."
+
+#. module: muk_utils
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_attachment_search
+msgid "Attachments"
+msgstr "Adjuntos"
+
+#. module: muk_utils
+#: model:ir.model,name:muk_utils.model_base
+msgid "Base"
+msgstr ""
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_groups__child_groups
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_mixins_groups_form
+msgid "Child Groups"
+msgstr "Grupos de niños"
+
+#. module: muk_utils
+#: model:ir.model,name:muk_utils.model_res_config_settings
+msgid "Config Settings"
+msgstr "Opciones de Configuración"
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_groups__display_name
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_hierarchy__display_name
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_scss_editor__display_name
+msgid "Display Name"
+msgstr "Nombre mostrado"
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_groups__explicit_users
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_mixins_groups_form
+msgid "Explicit Users"
+msgstr "Usuarios Explícitos"
+
+#. module: muk_utils
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_attachment_search
+msgid "Field Data"
+msgstr "Datos de campo"
+
+#. module: muk_utils
+#: model_terms:ir.ui.view,arch_db:muk_utils.res_config_settings_view_form
+msgid "Force Storage Migration"
+msgstr "Migración de almacenamiento forzado"
+
+#. module: muk_utils
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_mixins_groups_form
+msgid "Group"
+msgstr "Grupo"
+
+#. module: muk_utils
+#: model:ir.model,name:muk_utils.model_muk_utils_mixins_groups
+msgid "Group Mixin"
+msgstr "Mezcla de Grupo"
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_groups__name
+msgid "Group Name"
+msgstr "Nombre del grupo"
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_groups__users
+msgid "Group Users"
+msgstr "Usuarios del grupo"
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_groups__groups
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_mixins_groups_form
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_mixins_groups_tree
+msgid "Groups"
+msgstr "Grupos"
+
+#. module: muk_utils
+#: model:ir.model,name:muk_utils.model_muk_utils_mixins_hierarchy
+msgid "Hierarchy Mixin"
+msgstr "Mezcla de jerarquías"
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_groups__id
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_hierarchy__id
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_scss_editor__id
+msgid "ID"
+msgstr ""
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_groups____last_update
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_hierarchy____last_update
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_scss_editor____last_update
+msgid "Last Modified on"
+msgstr "Última modificación en"
+
+#. module: muk_utils
+#: model:ir.actions.server,name:muk_utils.action_attachment_migrate
+msgid "Migrate"
+msgstr "Migrar"
+
+#. module: muk_utils
+#: code:addons/muk_utils/models/ir_attachment.py:87
+#, python-format
+msgid "Only administrators can execute this action."
+msgstr ""
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_groups__parent_group
+msgid "Parent Group"
+msgstr "Grupo de padres"
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_groups__parent_path
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_hierarchy__parent_path
+msgid "Parent Path"
+msgstr "Trayectoria de los padres"
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_hierarchy__parent_path_json
+msgid "Path Json"
+msgstr "Camino Json"
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_hierarchy__parent_path_names
+msgid "Path Names"
+msgstr "Nombres de senderos"
+
+#. module: muk_utils
+#: model:ir.model,name:muk_utils.model_muk_utils_scss_editor
+msgid "Scss Editor"
+msgstr "Editor de Scss"
+
+#. module: muk_utils
+#: model_terms:ir.ui.view,arch_db:muk_utils.res_config_settings_view_form
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_attachment_form
+msgid "Storage"
+msgstr "Almacenamiento"
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_res_config_settings__attachment_location
+msgid "Storage Location"
+msgstr "Almacén"
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_res_config_settings__attachment_location_changed
+msgid "Storage Location Changed"
+msgstr "Almacén modificado"
+
+#. module: muk_utils
+#: model:ir.model,name:muk_utils.model_ir_config_parameter
+msgid "System Parameter"
+msgstr "Parámetros del sistema"
+
+#. module: muk_utils
+#: sql_constraint:muk_utils.mixins.groups:0
+msgid "The name of the group must be unique!"
+msgstr "El nombre del grupo debe ser único!"
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_groups__count_users
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_mixins_groups_form
+msgid "Users"
+msgstr "Usuarios"
+
diff --git a/odex-event/muk_utils/i18n/fr.po b/odex-event/muk_utils/i18n/fr.po
new file mode 100644
index 000000000..c13768c4a
--- /dev/null
+++ b/odex-event/muk_utils/i18n/fr.po
@@ -0,0 +1,211 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * muk_utils
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 12.0-20190522\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2019-07-13 09:40+0000\n"
+"PO-Revision-Date: 2019-07-13 09:40+0000\n"
+"Last-Translator: <>\n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: \n"
+
+#. module: muk_utils
+#: model_terms:ir.ui.view,arch_db:muk_utils.res_config_settings_view_form
+msgid "Save this page before triggering the migration."
+msgstr "Save cette page avant de déclencher la migration."
+
+#. module: muk_utils
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_attachment_search
+msgid "All Data"
+msgstr "Toutes les données"
+
+#. module: muk_utils
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_attachment_search
+msgid "Attached Document Field"
+msgstr "Champ du document joint"
+
+#. module: muk_utils
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_attachment_search
+msgid "Attached Document Model"
+msgstr "Modèle de document joint"
+
+#. module: muk_utils
+#: model:ir.model,name:muk_utils.model_ir_attachment
+msgid "Attachment"
+msgstr "Pièce jointe"
+
+#. module: muk_utils
+#: model_terms:ir.ui.view,arch_db:muk_utils.res_config_settings_view_form
+msgid "Attachment storage location"
+msgstr "Pièce jointe"
+
+#. module: muk_utils
+#: model:ir.model.fields,help:muk_utils.field_res_config_settings__attachment_location
+msgid "Attachment storage location."
+msgstr "Emplacement de stockage des pièces jointes"
+
+#. module: muk_utils
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_attachment_search
+msgid "Attachments"
+msgstr "Pièces jointes"
+
+#. module: muk_utils
+#: model:ir.model,name:muk_utils.model_base
+msgid "Base"
+msgstr ""
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_groups__child_groups
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_mixins_groups_form
+msgid "Child Groups"
+msgstr "Base"
+
+#. module: muk_utils
+#: model:ir.model,name:muk_utils.model_res_config_settings
+msgid "Config Settings"
+msgstr "Paramètres de config"
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_groups__display_name
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_hierarchy__display_name
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_scss_editor__display_name
+msgid "Display Name"
+msgstr "Nom affiché"
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_groups__explicit_users
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_mixins_groups_form
+msgid "Explicit Users"
+msgstr "Nom d'affichage"
+
+#. module: muk_utils
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_attachment_search
+msgid "Field Data"
+msgstr "Utilisateurs explicites"
+
+#. module: muk_utils
+#: model_terms:ir.ui.view,arch_db:muk_utils.res_config_settings_view_form
+msgid "Force Storage Migration"
+msgstr "Données de terrain"
+
+#. module: muk_utils
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_mixins_groups_form
+msgid "Group"
+msgstr "Groupe"
+
+#. module: muk_utils
+#: model:ir.model,name:muk_utils.model_muk_utils_mixins_groups
+msgid "Group Mixin"
+msgstr "Groupe"
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_groups__name
+msgid "Group Name"
+msgstr "Nom du groupe"
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_groups__users
+msgid "Group Users"
+msgstr "Nom du groupe"
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_groups__groups
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_mixins_groups_form
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_mixins_groups_tree
+msgid "Groups"
+msgstr "Groupes"
+
+#. module: muk_utils
+#: model:ir.model,name:muk_utils.model_muk_utils_mixins_hierarchy
+msgid "Hierarchy Mixin"
+msgstr "Groupes"
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_groups__id
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_hierarchy__id
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_scss_editor__id
+msgid "ID"
+msgstr ""
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_groups____last_update
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_hierarchy____last_update
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_scss_editor____last_update
+msgid "Last Modified on"
+msgstr "Dernière modification le"
+
+#. module: muk_utils
+#: model:ir.actions.server,name:muk_utils.action_attachment_migrate
+msgid "Migrate"
+msgstr "Dernière modification le"
+
+#. module: muk_utils
+#: code:addons/muk_utils/models/ir_attachment.py:87
+#, python-format
+msgid "Only administrators can execute this action."
+msgstr ""
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_groups__parent_group
+msgid "Parent Group"
+msgstr "Seuls les administrateurs peuvent exécuter cette action."
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_groups__parent_path
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_hierarchy__parent_path
+msgid "Parent Path"
+msgstr "Chemin parent"
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_hierarchy__parent_path_json
+msgid "Path Json"
+msgstr "Cheminement des parents"
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_hierarchy__parent_path_names
+msgid "Path Names"
+msgstr "Sentier Json"
+
+#. module: muk_utils
+#: model:ir.model,name:muk_utils.model_muk_utils_scss_editor
+msgid "Scss Editor"
+msgstr "Noms des chemins"
+
+#. module: muk_utils
+#: model_terms:ir.ui.view,arch_db:muk_utils.res_config_settings_view_form
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_attachment_form
+msgid "Storage"
+msgstr "Editeur Scss"
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_res_config_settings__attachment_location
+msgid "Storage Location"
+msgstr "Stockage"
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_res_config_settings__attachment_location_changed
+msgid "Storage Location Changed"
+msgstr "Emplacement de stockage"
+
+#. module: muk_utils
+#: model:ir.model,name:muk_utils.model_ir_config_parameter
+msgid "System Parameter"
+msgstr "Paramètres du système"
+
+#. module: muk_utils
+#: sql_constraint:muk_utils.mixins.groups:0
+msgid "The name of the group must be unique!"
+msgstr "Changement de magasin"
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_groups__count_users
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_mixins_groups_form
+msgid "Users"
+msgstr "Utilisateurs"
+
diff --git a/odex-event/muk_utils/i18n/hi.po b/odex-event/muk_utils/i18n/hi.po
new file mode 100644
index 000000000..2f56a2073
--- /dev/null
+++ b/odex-event/muk_utils/i18n/hi.po
@@ -0,0 +1,211 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * muk_utils
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 12.0-20190522\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2019-07-13 09:40+0000\n"
+"PO-Revision-Date: 2019-07-13 09:40+0000\n"
+"Last-Translator: <>\n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: \n"
+
+#. module: muk_utils
+#: model_terms:ir.ui.view,arch_db:muk_utils.res_config_settings_view_form
+msgid "Save this page before triggering the migration."
+msgstr ""
+
+#. module: muk_utils
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_attachment_search
+msgid "All Data"
+msgstr ""
+
+#. module: muk_utils
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_attachment_search
+msgid "Attached Document Field"
+msgstr ""
+
+#. module: muk_utils
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_attachment_search
+msgid "Attached Document Model"
+msgstr ""
+
+#. module: muk_utils
+#: model:ir.model,name:muk_utils.model_ir_attachment
+msgid "Attachment"
+msgstr ""
+
+#. module: muk_utils
+#: model_terms:ir.ui.view,arch_db:muk_utils.res_config_settings_view_form
+msgid "Attachment storage location"
+msgstr ""
+
+#. module: muk_utils
+#: model:ir.model.fields,help:muk_utils.field_res_config_settings__attachment_location
+msgid "Attachment storage location."
+msgstr ""
+
+#. module: muk_utils
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_attachment_search
+msgid "Attachments"
+msgstr ""
+
+#. module: muk_utils
+#: model:ir.model,name:muk_utils.model_base
+msgid "Base"
+msgstr ""
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_groups__child_groups
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_mixins_groups_form
+msgid "Child Groups"
+msgstr ""
+
+#. module: muk_utils
+#: model:ir.model,name:muk_utils.model_res_config_settings
+msgid "Config Settings"
+msgstr ""
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_groups__display_name
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_hierarchy__display_name
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_scss_editor__display_name
+msgid "Display Name"
+msgstr ""
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_groups__explicit_users
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_mixins_groups_form
+msgid "Explicit Users"
+msgstr ""
+
+#. module: muk_utils
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_attachment_search
+msgid "Field Data"
+msgstr ""
+
+#. module: muk_utils
+#: model_terms:ir.ui.view,arch_db:muk_utils.res_config_settings_view_form
+msgid "Force Storage Migration"
+msgstr ""
+
+#. module: muk_utils
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_mixins_groups_form
+msgid "Group"
+msgstr ""
+
+#. module: muk_utils
+#: model:ir.model,name:muk_utils.model_muk_utils_mixins_groups
+msgid "Group Mixin"
+msgstr ""
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_groups__name
+msgid "Group Name"
+msgstr ""
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_groups__users
+msgid "Group Users"
+msgstr ""
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_groups__groups
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_mixins_groups_form
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_mixins_groups_tree
+msgid "Groups"
+msgstr ""
+
+#. module: muk_utils
+#: model:ir.model,name:muk_utils.model_muk_utils_mixins_hierarchy
+msgid "Hierarchy Mixin"
+msgstr ""
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_groups__id
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_hierarchy__id
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_scss_editor__id
+msgid "ID"
+msgstr ""
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_groups____last_update
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_hierarchy____last_update
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_scss_editor____last_update
+msgid "Last Modified on"
+msgstr ""
+
+#. module: muk_utils
+#: model:ir.actions.server,name:muk_utils.action_attachment_migrate
+msgid "Migrate"
+msgstr ""
+
+#. module: muk_utils
+#: code:addons/muk_utils/models/ir_attachment.py:87
+#, python-format
+msgid "Only administrators can execute this action."
+msgstr ""
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_groups__parent_group
+msgid "Parent Group"
+msgstr ""
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_groups__parent_path
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_hierarchy__parent_path
+msgid "Parent Path"
+msgstr ""
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_hierarchy__parent_path_json
+msgid "Path Json"
+msgstr ""
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_hierarchy__parent_path_names
+msgid "Path Names"
+msgstr ""
+
+#. module: muk_utils
+#: model:ir.model,name:muk_utils.model_muk_utils_scss_editor
+msgid "Scss Editor"
+msgstr ""
+
+#. module: muk_utils
+#: model_terms:ir.ui.view,arch_db:muk_utils.res_config_settings_view_form
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_attachment_form
+msgid "Storage"
+msgstr ""
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_res_config_settings__attachment_location
+msgid "Storage Location"
+msgstr ""
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_res_config_settings__attachment_location_changed
+msgid "Storage Location Changed"
+msgstr ""
+
+#. module: muk_utils
+#: model:ir.model,name:muk_utils.model_ir_config_parameter
+msgid "System Parameter"
+msgstr ""
+
+#. module: muk_utils
+#: sql_constraint:muk_utils.mixins.groups:0
+msgid "The name of the group must be unique!"
+msgstr ""
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_groups__count_users
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_mixins_groups_form
+msgid "Users"
+msgstr ""
+
diff --git a/odex-event/muk_utils/i18n/nl.po b/odex-event/muk_utils/i18n/nl.po
new file mode 100644
index 000000000..f6362cdbb
--- /dev/null
+++ b/odex-event/muk_utils/i18n/nl.po
@@ -0,0 +1,211 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * muk_utils
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 12.0-20190522\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2019-07-13 09:40+0000\n"
+"PO-Revision-Date: 2019-07-13 09:40+0000\n"
+"Last-Translator: <>\n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: \n"
+
+#. module: muk_utils
+#: model_terms:ir.ui.view,arch_db:muk_utils.res_config_settings_view_form
+msgid "Save this page before triggering the migration."
+msgstr "Save deze pagina vooraleer de migratie te starten."
+
+#. module: muk_utils
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_attachment_search
+msgid "All Data"
+msgstr "Alle gegevens"
+
+#. module: muk_utils
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_attachment_search
+msgid "Attached Document Field"
+msgstr "Bijgevoegd documentveld"
+
+#. module: muk_utils
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_attachment_search
+msgid "Attached Document Model"
+msgstr "Bijgevoegd documentmodel"
+
+#. module: muk_utils
+#: model:ir.model,name:muk_utils.model_ir_attachment
+msgid "Attachment"
+msgstr "Bijlage"
+
+#. module: muk_utils
+#: model_terms:ir.ui.view,arch_db:muk_utils.res_config_settings_view_form
+msgid "Attachment storage location"
+msgstr "Opslaglocatie voor hulpstukken"
+
+#. module: muk_utils
+#: model:ir.model.fields,help:muk_utils.field_res_config_settings__attachment_location
+msgid "Attachment storage location."
+msgstr "Opslagplaats voor bevestigingsmateriaal."
+
+#. module: muk_utils
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_attachment_search
+msgid "Attachments"
+msgstr "Bijlagen"
+
+#. module: muk_utils
+#: model:ir.model,name:muk_utils.model_base
+msgid "Base"
+msgstr "Basis"
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_groups__child_groups
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_mixins_groups_form
+msgid "Child Groups"
+msgstr "Kind groepen"
+
+#. module: muk_utils
+#: model:ir.model,name:muk_utils.model_res_config_settings
+msgid "Config Settings"
+msgstr "Configuratie instellingen"
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_groups__display_name
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_hierarchy__display_name
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_scss_editor__display_name
+msgid "Display Name"
+msgstr "Weergavenaam"
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_groups__explicit_users
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_mixins_groups_form
+msgid "Explicit Users"
+msgstr "Expliciete gebruikers"
+
+#. module: muk_utils
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_attachment_search
+msgid "Field Data"
+msgstr "Veldgegevens"
+
+#. module: muk_utils
+#: model_terms:ir.ui.view,arch_db:muk_utils.res_config_settings_view_form
+msgid "Force Storage Migration"
+msgstr "Krachtenopslag migratie"
+
+#. module: muk_utils
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_mixins_groups_form
+msgid "Group"
+msgstr "Groep"
+
+#. module: muk_utils
+#: model:ir.model,name:muk_utils.model_muk_utils_mixins_groups
+msgid "Group Mixin"
+msgstr "Groepsmixer"
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_groups__name
+msgid "Group Name"
+msgstr "Groepsnaam"
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_groups__users
+msgid "Group Users"
+msgstr "Groep gebruikers"
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_groups__groups
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_mixins_groups_form
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_mixins_groups_tree
+msgid "Groups"
+msgstr "Groepen"
+
+#. module: muk_utils
+#: model:ir.model,name:muk_utils.model_muk_utils_mixins_hierarchy
+msgid "Hierarchy Mixin"
+msgstr "Hiërarchie Mixin"
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_groups__id
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_hierarchy__id
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_scss_editor__id
+msgid "ID"
+msgstr ""
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_groups____last_update
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_hierarchy____last_update
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_scss_editor____last_update
+msgid "Last Modified on"
+msgstr "Laatst gewijzigd op"
+
+#. module: muk_utils
+#: model:ir.actions.server,name:muk_utils.action_attachment_migrate
+msgid "Migrate"
+msgstr "Migreren"
+
+#. module: muk_utils
+#: code:addons/muk_utils/models/ir_attachment.py:87
+#, python-format
+msgid "Only administrators can execute this action."
+msgstr ""
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_groups__parent_group
+msgid "Parent Group"
+msgstr "Moedergroep"
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_groups__parent_path
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_hierarchy__parent_path
+msgid "Parent Path"
+msgstr "Bovenliggend pad"
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_hierarchy__parent_path_json
+msgid "Path Json"
+msgstr "Pad Json"
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_hierarchy__parent_path_names
+msgid "Path Names"
+msgstr "Padnamen"
+
+#. module: muk_utils
+#: model:ir.model,name:muk_utils.model_muk_utils_scss_editor
+msgid "Scss Editor"
+msgstr "Scss-editor"
+
+#. module: muk_utils
+#: model_terms:ir.ui.view,arch_db:muk_utils.res_config_settings_view_form
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_attachment_form
+msgid "Storage"
+msgstr "Opslag"
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_res_config_settings__attachment_location
+msgid "Storage Location"
+msgstr "Opslaglocatie"
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_res_config_settings__attachment_location_changed
+msgid "Storage Location Changed"
+msgstr "Opslaglocatie veranderd"
+
+#. module: muk_utils
+#: model:ir.model,name:muk_utils.model_ir_config_parameter
+msgid "System Parameter"
+msgstr "Systeem parameter"
+
+#. module: muk_utils
+#: sql_constraint:muk_utils.mixins.groups:0
+msgid "The name of the group must be unique!"
+msgstr "De naam van de groep moet uniek zijn!"
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_groups__count_users
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_mixins_groups_form
+msgid "Users"
+msgstr "Gebruikers"
+
diff --git a/odex-event/muk_utils/i18n/pt.po b/odex-event/muk_utils/i18n/pt.po
new file mode 100644
index 000000000..d863b5e6c
--- /dev/null
+++ b/odex-event/muk_utils/i18n/pt.po
@@ -0,0 +1,211 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * muk_utils
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 12.0-20190522\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2019-07-13 09:40+0000\n"
+"PO-Revision-Date: 2019-07-13 09:40+0000\n"
+"Last-Translator: <>\n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: \n"
+
+#. module: muk_utils
+#: model_terms:ir.ui.view,arch_db:muk_utils.res_config_settings_view_form
+msgid "Save this page before triggering the migration."
+msgstr ""
+
+#. module: muk_utils
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_attachment_search
+msgid "All Data"
+msgstr ""
+
+#. module: muk_utils
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_attachment_search
+msgid "Attached Document Field"
+msgstr ""
+
+#. module: muk_utils
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_attachment_search
+msgid "Attached Document Model"
+msgstr ""
+
+#. module: muk_utils
+#: model:ir.model,name:muk_utils.model_ir_attachment
+msgid "Attachment"
+msgstr "Anexo"
+
+#. module: muk_utils
+#: model_terms:ir.ui.view,arch_db:muk_utils.res_config_settings_view_form
+msgid "Attachment storage location"
+msgstr ""
+
+#. module: muk_utils
+#: model:ir.model.fields,help:muk_utils.field_res_config_settings__attachment_location
+msgid "Attachment storage location."
+msgstr ""
+
+#. module: muk_utils
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_attachment_search
+msgid "Attachments"
+msgstr "Anexos"
+
+#. module: muk_utils
+#: model:ir.model,name:muk_utils.model_base
+msgid "Base"
+msgstr ""
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_groups__child_groups
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_mixins_groups_form
+msgid "Child Groups"
+msgstr ""
+
+#. module: muk_utils
+#: model:ir.model,name:muk_utils.model_res_config_settings
+msgid "Config Settings"
+msgstr "config configurações"
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_groups__display_name
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_hierarchy__display_name
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_scss_editor__display_name
+msgid "Display Name"
+msgstr "Nome a Exibir"
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_groups__explicit_users
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_mixins_groups_form
+msgid "Explicit Users"
+msgstr ""
+
+#. module: muk_utils
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_attachment_search
+msgid "Field Data"
+msgstr ""
+
+#. module: muk_utils
+#: model_terms:ir.ui.view,arch_db:muk_utils.res_config_settings_view_form
+msgid "Force Storage Migration"
+msgstr ""
+
+#. module: muk_utils
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_mixins_groups_form
+msgid "Group"
+msgstr "Grupo"
+
+#. module: muk_utils
+#: model:ir.model,name:muk_utils.model_muk_utils_mixins_groups
+msgid "Group Mixin"
+msgstr ""
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_groups__name
+msgid "Group Name"
+msgstr "Nome do Grupo"
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_groups__users
+msgid "Group Users"
+msgstr ""
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_groups__groups
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_mixins_groups_form
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_mixins_groups_tree
+msgid "Groups"
+msgstr "Grupos"
+
+#. module: muk_utils
+#: model:ir.model,name:muk_utils.model_muk_utils_mixins_hierarchy
+msgid "Hierarchy Mixin"
+msgstr ""
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_groups__id
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_hierarchy__id
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_scss_editor__id
+msgid "ID"
+msgstr "Id."
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_groups____last_update
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_hierarchy____last_update
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_scss_editor____last_update
+msgid "Last Modified on"
+msgstr "Última Modificação em"
+
+#. module: muk_utils
+#: model:ir.actions.server,name:muk_utils.action_attachment_migrate
+msgid "Migrate"
+msgstr ""
+
+#. module: muk_utils
+#: code:addons/muk_utils/models/ir_attachment.py:87
+#, python-format
+msgid "Only administrators can execute this action."
+msgstr ""
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_groups__parent_group
+msgid "Parent Group"
+msgstr ""
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_groups__parent_path
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_hierarchy__parent_path
+msgid "Parent Path"
+msgstr "Caminho ascendente "
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_hierarchy__parent_path_json
+msgid "Path Json"
+msgstr ""
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_hierarchy__parent_path_names
+msgid "Path Names"
+msgstr ""
+
+#. module: muk_utils
+#: model:ir.model,name:muk_utils.model_muk_utils_scss_editor
+msgid "Scss Editor"
+msgstr ""
+
+#. module: muk_utils
+#: model_terms:ir.ui.view,arch_db:muk_utils.res_config_settings_view_form
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_attachment_form
+msgid "Storage"
+msgstr ""
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_res_config_settings__attachment_location
+msgid "Storage Location"
+msgstr ""
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_res_config_settings__attachment_location_changed
+msgid "Storage Location Changed"
+msgstr ""
+
+#. module: muk_utils
+#: model:ir.model,name:muk_utils.model_ir_config_parameter
+msgid "System Parameter"
+msgstr ""
+
+#. module: muk_utils
+#: sql_constraint:muk_utils.mixins.groups:0
+msgid "The name of the group must be unique!"
+msgstr ""
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_groups__count_users
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_mixins_groups_form
+msgid "Users"
+msgstr "Utilizadores"
+
diff --git a/odex-event/muk_utils/i18n/ru.po b/odex-event/muk_utils/i18n/ru.po
new file mode 100644
index 000000000..24fee8599
--- /dev/null
+++ b/odex-event/muk_utils/i18n/ru.po
@@ -0,0 +1,211 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * muk_utils
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 12.0-20190522\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2019-07-13 09:40+0000\n"
+"PO-Revision-Date: 2019-07-13 09:40+0000\n"
+"Last-Translator: <>\n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: \n"
+
+#. module: muk_utils
+#: model_terms:ir.ui.view,arch_db:muk_utils.res_config_settings_view_form
+msgid "Save this page before triggering the migration."
+msgstr ""
+
+#. module: muk_utils
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_attachment_search
+msgid "All Data"
+msgstr ""
+
+#. module: muk_utils
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_attachment_search
+msgid "Attached Document Field"
+msgstr ""
+
+#. module: muk_utils
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_attachment_search
+msgid "Attached Document Model"
+msgstr ""
+
+#. module: muk_utils
+#: model:ir.model,name:muk_utils.model_ir_attachment
+msgid "Attachment"
+msgstr "Приложение"
+
+#. module: muk_utils
+#: model_terms:ir.ui.view,arch_db:muk_utils.res_config_settings_view_form
+msgid "Attachment storage location"
+msgstr ""
+
+#. module: muk_utils
+#: model:ir.model.fields,help:muk_utils.field_res_config_settings__attachment_location
+msgid "Attachment storage location."
+msgstr ""
+
+#. module: muk_utils
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_attachment_search
+msgid "Attachments"
+msgstr "Вложения"
+
+#. module: muk_utils
+#: model:ir.model,name:muk_utils.model_base
+msgid "Base"
+msgstr "Базовый"
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_groups__child_groups
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_mixins_groups_form
+msgid "Child Groups"
+msgstr ""
+
+#. module: muk_utils
+#: model:ir.model,name:muk_utils.model_res_config_settings
+msgid "Config Settings"
+msgstr "Настройки конфигурации"
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_groups__display_name
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_hierarchy__display_name
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_scss_editor__display_name
+msgid "Display Name"
+msgstr "Отображаемое Имя"
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_groups__explicit_users
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_mixins_groups_form
+msgid "Explicit Users"
+msgstr ""
+
+#. module: muk_utils
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_attachment_search
+msgid "Field Data"
+msgstr ""
+
+#. module: muk_utils
+#: model_terms:ir.ui.view,arch_db:muk_utils.res_config_settings_view_form
+msgid "Force Storage Migration"
+msgstr ""
+
+#. module: muk_utils
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_mixins_groups_form
+msgid "Group"
+msgstr "Группа"
+
+#. module: muk_utils
+#: model:ir.model,name:muk_utils.model_muk_utils_mixins_groups
+msgid "Group Mixin"
+msgstr ""
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_groups__name
+msgid "Group Name"
+msgstr "Наименование Группы"
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_groups__users
+msgid "Group Users"
+msgstr ""
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_groups__groups
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_mixins_groups_form
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_mixins_groups_tree
+msgid "Groups"
+msgstr "Группы"
+
+#. module: muk_utils
+#: model:ir.model,name:muk_utils.model_muk_utils_mixins_hierarchy
+msgid "Hierarchy Mixin"
+msgstr ""
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_groups__id
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_hierarchy__id
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_scss_editor__id
+msgid "ID"
+msgstr "Номер"
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_groups____last_update
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_hierarchy____last_update
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_scss_editor____last_update
+msgid "Last Modified on"
+msgstr "Последнее изменение"
+
+#. module: muk_utils
+#: model:ir.actions.server,name:muk_utils.action_attachment_migrate
+msgid "Migrate"
+msgstr ""
+
+#. module: muk_utils
+#: code:addons/muk_utils/models/ir_attachment.py:87
+#, python-format
+msgid "Only administrators can execute this action."
+msgstr ""
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_groups__parent_group
+msgid "Parent Group"
+msgstr ""
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_groups__parent_path
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_hierarchy__parent_path
+msgid "Parent Path"
+msgstr ""
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_hierarchy__parent_path_json
+msgid "Path Json"
+msgstr ""
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_hierarchy__parent_path_names
+msgid "Path Names"
+msgstr ""
+
+#. module: muk_utils
+#: model:ir.model,name:muk_utils.model_muk_utils_scss_editor
+msgid "Scss Editor"
+msgstr ""
+
+#. module: muk_utils
+#: model_terms:ir.ui.view,arch_db:muk_utils.res_config_settings_view_form
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_attachment_form
+msgid "Storage"
+msgstr ""
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_res_config_settings__attachment_location
+msgid "Storage Location"
+msgstr ""
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_res_config_settings__attachment_location_changed
+msgid "Storage Location Changed"
+msgstr ""
+
+#. module: muk_utils
+#: model:ir.model,name:muk_utils.model_ir_config_parameter
+msgid "System Parameter"
+msgstr ""
+
+#. module: muk_utils
+#: sql_constraint:muk_utils.mixins.groups:0
+msgid "The name of the group must be unique!"
+msgstr ""
+
+#. module: muk_utils
+#: model:ir.model.fields,field_description:muk_utils.field_muk_utils_mixins_groups__count_users
+#: model_terms:ir.ui.view,arch_db:muk_utils.view_mixins_groups_form
+msgid "Users"
+msgstr "Пользователи"
+
diff --git a/odex-event/muk_utils/models/__init__.py b/odex-event/muk_utils/models/__init__.py
new file mode 100644
index 000000000..424dbbe03
--- /dev/null
+++ b/odex-event/muk_utils/models/__init__.py
@@ -0,0 +1,30 @@
+###################################################################################
+#
+# Copyright (c) 2017-2019 MuK IT GmbH.
+#
+# This file is part of MuK Utils
+# (see https://mukit.at).
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see .
+#
+###################################################################################
+
+from . import base
+from . import mixins_groups
+from . import mixins_hierarchy
+from . import scss_editor
+from . import ir_attachment
+from . import ir_config_parameter
+from . import res_config_settings
+
diff --git a/odex-event/muk_utils/models/base.py b/odex-event/muk_utils/models/base.py
new file mode 100644
index 000000000..167979700
--- /dev/null
+++ b/odex-event/muk_utils/models/base.py
@@ -0,0 +1,189 @@
+###################################################################################
+#
+# Copyright (c) 2017-2019 MuK IT GmbH.
+#
+# This file is part of MuK Utils
+# (see https://mukit.at).
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see .
+#
+###################################################################################
+
+import logging
+
+from odoo import api, models, fields
+from odoo.osv import expression
+
+from odoo.addons.muk_utils.tools import utils
+
+_logger = logging.getLogger(__name__)
+
+class Base(models.AbstractModel):
+
+ _inherit = 'base'
+
+ #----------------------------------------------------------
+ # Helper Methods
+ #----------------------------------------------------------
+
+ @api.model
+ def _check_parent_field(self):
+ if self._parent_name not in self._fields:
+ raise TypeError("The parent (%s) field does not exist." % self._parent_name)
+
+ @api.model
+ def _build_search_childs_domain(self, parent_id, domain=[]):
+ self._check_parent_field()
+ parent_domain = [[self._parent_name, '=', parent_id]]
+ return expression.AND([parent_domain, domain]) if domain else parent_domain
+
+ @api.model
+ def _check_context_bin_size(self, field):
+ return any(
+ key in self.env.context and self.env.context[key]
+ for key in ['bin_size', 'bin_size_%s' % (field)]
+ )
+
+ #----------------------------------------------------------
+ # Security
+ #----------------------------------------------------------
+
+
+ def _filter_access(self, operation):
+ if self.check_access_rights(operation, False):
+ return self._filter_access_rules(operation)
+ return self.env[self._name]
+
+
+ def _filter_access_ids(self, operation):
+ return self._filter_access(operation).ids
+
+
+ def check_access(self, operation, raise_exception=False):
+ try:
+ access_right = self.check_access_rights(operation, raise_exception)
+ access_rule = self.check_access_rule(operation) is None
+ return access_right and access_rule
+ except AccessError:
+ if raise_exception:
+ raise
+ return False
+
+ #----------------------------------------------------------
+ # Hierarchy Methods
+ #----------------------------------------------------------
+
+ @api.model
+ def search_parents(self, domain=[], offset=0, limit=None, order=None, count=False):
+ """ This method finds the top level elements of the hierarchy for a given search query.
+
+ :param domain: a search domain (default: empty list)
+ :param order: a string to define the sort order of the query (default: none)
+ :returns: the top level elements for the given search query
+ """
+ res = self._search_parents(domain=domain, offset=offset, limit=limit, order=order, count=count)
+ return res if count else self.browse(res)
+
+ @api.model
+ def search_read_parents(self, domain=[], fields=None, offset=0, limit=None, order=None):
+ """ This method finds the top level elements of the hierarchy for a given search query.
+
+ :param domain: a search domain (default: empty list)
+ :param fields: a list of fields to read (default: all fields of the model)
+ :param order: a string to define the sort order of the query (default: none)
+ :returns: the top level elements for the given search query
+ """
+ records = self.search_parents(domain=domain, offset=offset, limit=limit, order=order)
+ if not records:
+ return []
+ if fields and fields == ['id']:
+ return [{'id': record.id} for record in records]
+ result = records.read(fields)
+ if len(result) <= 1:
+ return result
+ index = {vals['id']: vals for vals in result}
+ return [index[record.id] for record in records if record.id in index]
+
+ @api.model
+ def _search_parents(self, domain=[], offset=0, limit=None, order=None, count=False):
+ self._check_parent_field()
+ self.check_access_rights('read')
+ if expression.is_false(self, domain):
+ return []
+ query = self._where_calc(domain)
+ self._apply_ir_rules(query, 'read')
+ from_clause, where_clause, where_clause_arguments = query.get_sql()
+ parent_where = where_clause and (" WHERE %s" % where_clause) or ''
+ parent_query = 'SELECT "%s".id FROM ' % self._table + from_clause + parent_where
+ no_parent_clause ='"{table}"."{field}" IS NULL'.format(
+ table=self._table,
+ field=self._parent_name
+ )
+ no_access_clause ='"{table}"."{field}" NOT IN ({query})'.format(
+ table=self._table,
+ field=self._parent_name,
+ query=parent_query
+ )
+ parent_clause = '({0} OR {1})'.format(
+ no_parent_clause,
+ no_access_clause
+ )
+ order_by = self._generate_order_by(order, query)
+ from_clause, where_clause, where_clause_params = query.get_sql()
+ where_str = (
+ where_clause and
+ (" WHERE %s AND %s" % (where_clause, parent_clause)) or
+ (" WHERE %s" % parent_clause)
+ )
+ if count:
+ query_str = 'SELECT count(1) FROM ' + from_clause + where_str
+ self._cr.execute(query_str, where_clause_params)
+ return self._cr.fetchone()[0]
+ limit_str = limit and ' limit %d' % limit or ''
+ offset_str = offset and ' offset %d' % offset or ''
+ query_str = 'SELECT "%s".id FROM ' % self._table + from_clause + where_str + order_by + limit_str + offset_str
+ complete_where_clause_params = where_clause_params + where_clause_arguments
+ self._cr.execute(query_str, complete_where_clause_params)
+ return utils.uniquify_list([x[0] for x in self._cr.fetchall()])
+
+ @api.model
+ def search_childs(self, parent_id, domain=[], offset=0, limit=None, order=None, count=False):
+ """ This method finds the direct child elements of the parent record for a given search query.
+
+ :param parent_id: the integer representing the ID of the parent record
+ :param domain: a search domain (default: empty list)
+ :param offset: the number of results to ignore (default: none)
+ :param limit: maximum number of records to return (default: all)
+ :param order: a string to define the sort order of the query (default: none)
+ :param count: counts and returns the number of matching records (default: False)
+ :returns: the top level elements for the given search query
+ """
+ domain = self._build_search_childs_domain(parent_id, domain=domain)
+ return self.search(domain, offset=offset, limit=limit, order=order, count=count)
+
+ @api.model
+ def search_read_childs(self, parent_id, domain=[], fields=None, offset=0, limit=None, order=None):
+ """ This method finds the direct child elements of the parent record for a given search query.
+
+ :param parent_id: the integer representing the ID of the parent record
+ :param domain: a search domain (default: empty list)
+ :param fields: a list of fields to read (default: all fields of the model)
+ :param offset: the number of results to ignore (default: none)
+ :param limit: maximum number of records to return (default: all)
+ :param order: a string to define the sort order of the query (default: none)
+ :returns: the top level elements for the given search query
+ """
+ domain = self._build_search_childs_domain(parent_id, domain=domain)
+ return self.search_read(domain=domain, fields=fields, offset=offset, limit=limit, order=order)
+
\ No newline at end of file
diff --git a/odex-event/muk_utils/models/ir_attachment.py b/odex-event/muk_utils/models/ir_attachment.py
new file mode 100644
index 000000000..c9a6ccdd5
--- /dev/null
+++ b/odex-event/muk_utils/models/ir_attachment.py
@@ -0,0 +1,155 @@
+###################################################################################
+#
+# Copyright (c) 2017-2019 MuK IT GmbH.
+#
+# This file is part of MuK Utils
+# (see https://mukit.at).
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see .
+#
+###################################################################################
+
+import math
+import base64
+import logging
+import mimetypes
+
+from odoo import registry, api, models, _
+from odoo.tools.mimetypes import guess_mimetype
+from odoo.tools.misc import split_every
+from odoo.exceptions import AccessError
+
+_logger = logging.getLogger(__name__)
+
+class IrAttachment(models.Model):
+
+ _inherit = 'ir.attachment'
+
+ #----------------------------------------------------------
+ # Helper
+ #----------------------------------------------------------
+
+ @api.model
+ def _get_datas_inital_vals(self):
+ return {
+ 'store_fname': False,
+ 'db_datas': False,
+ }
+
+ @api.model
+ def _update_datas_vals(self, vals, attach, bin_data):
+ vals.update({
+ 'file_size': len(bin_data),
+ 'checksum': self._compute_checksum(bin_data),
+ 'index_content': self._index(bin_data, attach.store_fname, attach.mimetype),
+ })
+ return vals
+
+ @api.model
+ def _get_datas_clean_vals(self, attach):
+ vals = {}
+ if attach.store_fname:
+ vals['store_fname'] = attach.store_fname
+ return vals
+
+ @api.model
+ def _clean_datas_after_write(self, vals):
+ if 'store_fname' in vals:
+ self._file_delete(vals['store_fname'])
+
+ #----------------------------------------------------------
+ # Actions
+ #----------------------------------------------------------
+
+
+ def action_migrate(self):
+ self.migrate()
+
+ #----------------------------------------------------------
+ # Functions
+ #----------------------------------------------------------
+
+ @api.model
+ def storage_locations(self):
+ return ['db', 'file']
+
+ @api.model
+ def force_storage(self):
+ if not self._storage() in self.storage_locations():
+ return super(IrAttachment, self).force_storage()
+ if not self.env.user._is_admin():
+ raise AccessError(_('Only administrators can execute this action.'))
+ storage_domain = {
+ 'db': ('db_datas', '=', False),
+ 'file': ('store_fname', '=', False),
+ }
+ record_domain = [
+ '&', ('type', '=', 'binary'),
+ '&', storage_domain[self._storage()],
+ '|', ('res_field', '=', False), ('res_field', '!=', False)
+ ]
+ self.search(record_domain).migrate(batch_size=100)
+ return True
+
+
+ def migrate(self, batch_size=None):
+ commit_on_batch = bool(batch_size)
+ batch_size = batch_size or len(self) or 1
+ storage_location = self._storage().upper()
+ batches = math.ceil(len(self) / batch_size)
+ for index, attachment in enumerate(self, start=1):
+ current_batch = math.ceil(index / batch_size)
+ counter = len(self) - (batches - 1) * batch_size
+ counter = counter if current_batch == batches else batch_size
+ _logger.info("Migrate Attachment %s of %s to %s [Batch %s of %s]",
+ index % batch_size or batch_size, counter,
+ storage_location, current_batch, batches
+ )
+ attachment.with_context(migration=True).write({
+ 'datas': attachment.datas
+ })
+ if commit_on_batch and not index % batch_size:
+ self.env.cr.commit()
+
+ #----------------------------------------------------------
+ # Read
+ #----------------------------------------------------------
+
+
+ def _compute_mimetype(self, values):
+ if self.env.context.get('migration') and len(self) == 1:
+ return self.mimetype or 'application/octet-stream'
+ else:
+ return super(IrAttachment, self)._compute_mimetype(values)
+
+ #----------------------------------------------------------
+ # Create, Write, Delete
+ #----------------------------------------------------------
+
+
+ # def _inverse_datas(self):
+ # location = self._storage()
+ # for attach in self:
+ # value = attach.datas
+ # bin_data = base64.b64decode(value) if value else b''
+ # vals = self._get_datas_inital_vals()
+ # vals = self._update_datas_vals(vals, attach, bin_data)
+ # if value and location != 'db':
+ # vals['datas'] = self._file_write(value, vals['checksum'])
+ # else:
+ # vals['db_datas'] = value
+ # clean_vals = self._get_datas_clean_vals(attach)
+ # models.Model.write(attach.sudo(), vals)
+ # self._clean_datas_after_write(clean_vals)
+
\ No newline at end of file
diff --git a/odex-event/muk_utils/models/ir_config_parameter.py b/odex-event/muk_utils/models/ir_config_parameter.py
new file mode 100644
index 000000000..918feb4d5
--- /dev/null
+++ b/odex-event/muk_utils/models/ir_config_parameter.py
@@ -0,0 +1,32 @@
+###################################################################################
+#
+# Copyright (c) 2017-2019 MuK IT GmbH.
+#
+# This file is part of MuK Utils
+# (see https://mukit.at).
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see .
+#
+###################################################################################
+
+from odoo import models, api
+
+class IrConfigParameter(models.Model):
+
+ _inherit = 'ir.config_parameter'
+
+ @api.model
+ def set_params(self, params):
+ for key, value in params.items():
+ self.set_param(key, value)
\ No newline at end of file
diff --git a/odex-event/muk_utils/models/mixins_groups.py b/odex-event/muk_utils/models/mixins_groups.py
new file mode 100644
index 000000000..202db0cd9
--- /dev/null
+++ b/odex-event/muk_utils/models/mixins_groups.py
@@ -0,0 +1,126 @@
+###################################################################################
+#
+# Copyright (c) 2017-2019 MuK IT GmbH.
+#
+# This file is part of MuK Utils
+# (see https://mukit.at).
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see .
+#
+###################################################################################
+
+from odoo import models, fields, api
+
+class Groups(models.AbstractModel):
+
+ _name = 'muk_utils.mixins.groups'
+ _description = 'Group Mixin'
+
+ _parent_store = True
+ _parent_name = "parent_group"
+
+ #----------------------------------------------------------
+ # Database
+ #----------------------------------------------------------
+
+ name = fields.Char(
+ string="Group Name",
+ required=True,
+ translate=True)
+
+ parent_path = fields.Char(
+ string="Parent Path",
+ index=True)
+
+ count_users = fields.Integer(
+ compute='_compute_users',
+ string="Users",
+ store=True)
+
+ @api.model
+ def _add_magic_fields(self):
+ super(Groups, self)._add_magic_fields()
+ def add(name, field):
+ if name not in self._fields:
+ self._add_field(name, field)
+ add('parent_group', fields.Many2one(
+ _module=self._module,
+ comodel_name=self._name,
+ string='Parent Group',
+ ondelete='cascade',
+ auto_join=True,
+ index=True,
+ automatic=True))
+ add('child_groups', fields.One2many(
+ _module=self._module,
+ comodel_name=self._name,
+ inverse_name='parent_group',
+ string='Child Groups',
+ automatic=True))
+ add('groups', fields.Many2many(
+ _module=self._module,
+ comodel_name='res.groups',
+ relation='%s_groups_rel' % (self._table),
+ column1='gid',
+ column2='rid',
+ string='Groups',
+ automatic=True))
+ add('explicit_users', fields.Many2many(
+ _module=self._module,
+ comodel_name='res.users',
+ relation='%s_explicit_users_rel' % (self._table),
+ column1='gid',
+ column2='uid',
+ string='Explicit Users',
+ automatic=True))
+ add('users', fields.Many2many(
+ _module=self._module,
+ comodel_name='res.users',
+ relation='%s_users_rel' % (self._table),
+ column1='gid',
+ column2='uid',
+ string='Group Users',
+ compute='_compute_users',
+ store=True,
+ automatic=True))
+
+ _sql_constraints = [
+ ('name_uniq', 'unique (name)', 'The name of the group must be unique!')
+ ]
+
+ #----------------------------------------------------------
+ # Functions
+ #----------------------------------------------------------
+
+ @api.model
+ def default_get(self, fields_list):
+ res = super(Groups, self).default_get(fields_list)
+ if not self.env.context.get('groups_no_autojoin'):
+ if 'explicit_users' in res and res['explicit_users']:
+ res['explicit_users'] = res['explicit_users'] + [self.env.uid]
+ else:
+ res['explicit_users'] = [self.env.uid]
+ return res
+
+ #----------------------------------------------------------
+ # Read, View
+ #----------------------------------------------------------
+
+ @api.depends('parent_group', 'parent_group.users', 'groups', 'groups.users', 'explicit_users')
+ def _compute_users(self):
+ for record in self:
+ users = record.mapped('groups.users')
+ users |= record.mapped('explicit_users')
+ users |= record.mapped('parent_group.users')
+ record.update({'users': users, 'count_users': len(users)})
\ No newline at end of file
diff --git a/odex-event/muk_utils/models/mixins_hierarchy.py b/odex-event/muk_utils/models/mixins_hierarchy.py
new file mode 100644
index 000000000..597025cb2
--- /dev/null
+++ b/odex-event/muk_utils/models/mixins_hierarchy.py
@@ -0,0 +1,176 @@
+###################################################################################
+#
+# Copyright (c) 2017-2019 MuK IT GmbH.
+#
+# This file is part of MuK Utils
+# (see https://mukit.at).
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see .
+#
+###################################################################################
+
+import json
+import operator
+import functools
+import collections
+
+from odoo import models, fields, api
+from odoo.osv import expression
+
+class Hierarchy(models.AbstractModel):
+
+ _name = 'muk_utils.mixins.hierarchy'
+ _description = 'Hierarchy Mixin'
+
+ _parent_store = True
+ _parent_path_sudo = False
+ _parent_path_store = False
+
+ _name_path_context = "show_path"
+
+ #----------------------------------------------------------
+ # Database
+ #----------------------------------------------------------
+
+ parent_path = fields.Char(
+ string="Parent Path",
+ index=True)
+
+ @api.model
+ def _add_magic_fields(self):
+ super(Hierarchy, self)._add_magic_fields()
+ def add(name, field):
+ if name not in self._fields:
+ self._add_field(name, field)
+ path_names_search = None
+ if not self._parent_path_store:
+ path_names_search = '_search_parent_path_names'
+ add('parent_path_names', fields.Char(
+ _module=self._module,
+ compute='_compute_parent_paths',
+ compute_sudo=self._parent_path_sudo,
+ store=self._parent_path_store,
+ search=path_names_search,
+ string="Path Names",
+ readonly=True,
+ automatic=True))
+ add('parent_path_json', fields.Text(
+ _module=self._module,
+ compute='_compute_parent_paths',
+ compute_sudo=self._parent_path_sudo,
+ store=self._parent_path_store,
+ string="Path Json",
+ readonly=True,
+ automatic=True))
+
+ #----------------------------------------------------------
+ # Helper
+ #----------------------------------------------------------
+
+ def _get_depends_parent_paths(self):
+ depends = ['parent_path']
+ if self._rec_name:
+ depends += [self._rec_name]
+ elif 'name' in self._fields:
+ depends += ['name']
+ elif 'x_name' in self._fields:
+ depends += ['x_name']
+ return depends
+
+ #----------------------------------------------------------
+ # Search
+ #----------------------------------------------------------
+
+ @api.model
+ def _search_parent_path_names(self, operator, operand):
+ domain = []
+ for value in operand.split('/'):
+ args = [(self._rec_name_fallback(), operator, value)]
+ domain = expression.OR([args, domain]) if domain else args
+ return domain if domain else [(self._rec_name_fallback(), operator, "")]
+
+ #----------------------------------------------------------
+ # Read, View
+ #----------------------------------------------------------
+
+ @api.depends(lambda self: self._get_depends_parent_paths())
+ def _compute_parent_paths(self):
+ records = self.filtered(lambda record: record.parent_path)
+ paths = [list(map(int, rec.parent_path.split('/')[:-1])) for rec in records]
+ ids = paths and set(functools.reduce(operator.concat, paths)) or []
+ model_without_path = self.with_context(**{self._name_path_context: False})
+ filtered_records = model_without_path.browse(ids)._filter_access('read')
+ data = dict(filtered_records.name_get())
+ for record in records:
+ path_names = [""]
+ path_json = []
+ for id in reversed(list(map(int, record.parent_path.split('/')[:-1]))):
+ if id not in data:
+ break
+ path_names.append(data[id])
+ path_json.append({
+ 'model': record._name,
+ 'name': data[id],
+ 'id': id,
+ })
+ path_names.reverse()
+ path_json.reverse()
+ record.update({
+ 'parent_path_names': '/'.join(path_names),
+ 'parent_path_json': json.dumps(path_json),
+ })
+
+ @api.model
+ def _name_search(self, name='', args=None, operator='ilike', limit=100, name_get_uid=None):
+ domain = list(args or [])
+ if not (name == '' and operator == 'ilike') :
+ if '/' in name:
+ domain += [('parent_path_names', operator, name)]
+ else:
+ domain += [(self._rec_name, operator, name)]
+ records = self.browse(self._search(domain, limit=limit, access_rights_uid=name_get_uid))
+ return models.lazy_name_get(records.sudo(name_get_uid or self.env.uid))
+
+
+ def name_get(self):
+ if self.env.context.get(self._name_path_context):
+ res = []
+ for record in self:
+ names = record.parent_path_names
+ if not names:
+ res.append(super(Hierarchy, record).name_get()[0])
+ elif not len(names) > 50:
+ res.append((record.id, names))
+ else:
+ res.append((record.id, ".." + names[-48:]))
+ return res
+ return super(Hierarchy, self).name_get()
+
+ #----------------------------------------------------------
+ # Create, Update, Delete
+ #----------------------------------------------------------
+
+
+ def write(self, vals):
+ if self._parent_path_store and self._rec_name_fallback() in vals:
+ with self.env.norecompute():
+ res = super(Hierarchy, self).write(vals)
+ domain = [('id', 'child_of', self.ids)]
+ records = self.sudo().search(domain)
+ records.modified(['parent_path'])
+ if self.env.recompute and self.env.context.get('recompute', True):
+ records.recompute()
+ return res
+ return super(Hierarchy, self).write(vals)
+
\ No newline at end of file
diff --git a/odex-event/muk_utils/models/res_config_settings.py b/odex-event/muk_utils/models/res_config_settings.py
new file mode 100644
index 000000000..e9f84dd8c
--- /dev/null
+++ b/odex-event/muk_utils/models/res_config_settings.py
@@ -0,0 +1,82 @@
+###################################################################################
+#
+# Copyright (c) 2017-2019 MuK IT GmbH.
+#
+# This file is part of MuK Utils
+# (see https://mukit.at).
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see .
+#
+###################################################################################
+
+from odoo import api, fields, models
+
+class ResConfigSettings(models.TransientModel):
+
+ _inherit = 'res.config.settings'
+
+ #----------------------------------------------------------
+ # Selections
+ #----------------------------------------------------------
+
+ def _attachment_location_selection(self):
+ locations = self.env['ir.attachment'].storage_locations()
+ return list(map(lambda location: (location, location.upper()), locations))
+
+ #----------------------------------------------------------
+ # Database
+ #----------------------------------------------------------
+
+ attachment_location = fields.Selection(
+ selection=lambda self: self._attachment_location_selection(),
+ string='Storage Location',
+ required=True,
+ default='file',
+ help="Attachment storage location.")
+
+ attachment_location_changed = fields.Boolean(
+ compute='_compute_attachment_location_changed',
+ string='Storage Location Changed')
+
+ #----------------------------------------------------------
+ # Functions
+ #----------------------------------------------------------
+
+
+ def set_values(self):
+ res = super(ResConfigSettings, self).set_values()
+ param = self.env['ir.config_parameter'].sudo()
+ param.set_param('ir_attachment.location', self.attachment_location)
+ return res
+
+ @api.model
+ def get_values(self):
+ res = super(ResConfigSettings, self).get_values()
+ params = self.env['ir.config_parameter'].sudo()
+ res.update(attachment_location=params.get_param('ir_attachment.location', 'file'))
+ return res
+
+ def attachment_force_storage(self):
+ self.env['ir.attachment'].force_storage()
+
+ #----------------------------------------------------------
+ # Read
+ #----------------------------------------------------------
+
+ @api.depends('attachment_location')
+ def _compute_attachment_location_changed(self):
+ params = self.env['ir.config_parameter'].sudo()
+ location = params.get_param('ir_attachment.location', 'file')
+ for record in self:
+ record.attachment_location_changed = location != self.attachment_location
diff --git a/odex-event/muk_utils/models/scss_editor.py b/odex-event/muk_utils/models/scss_editor.py
new file mode 100644
index 000000000..ddc18ab4e
--- /dev/null
+++ b/odex-event/muk_utils/models/scss_editor.py
@@ -0,0 +1,145 @@
+###################################################################################
+#
+# Copyright (c) 2017-2019 MuK IT GmbH.
+#
+# This file is part of MuK Utils
+# (see https://mukit.at).
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see .
+#
+###################################################################################
+
+import re
+import uuid
+import base64
+
+from odoo import models, fields, api
+from odoo.modules import module
+
+class ScssEditor(models.AbstractModel):
+
+ _name = 'muk_utils.scss_editor'
+ _description = 'Scss Editor'
+
+ #----------------------------------------------------------
+ # Helper
+ #----------------------------------------------------------
+
+ def _build_custom_url(self, url_parts, xmlid):
+ return "%s.custom.%s.%s" % (url_parts[0], xmlid, url_parts[1])
+
+ def _get_custom_url(self, url, xmlid):
+ return self._build_custom_url(url.rsplit(".", 1), xmlid)
+
+ def _get_custom_attachment(self, url):
+ return self.env["ir.attachment"].with_context(
+ bin_size=False, bin_size_datas=False
+ ).search([("url", '=', url)], limit=1)
+
+ def _get_custom_view(self, url):
+ return self.env["ir.ui.view"].search([("name", '=', url)])
+
+ def _get_variable(self, content, variable):
+ regex = r'{0}\:?\s(.*?);'.format(variable)
+ value = re.search(regex, content)
+ return value and value.group(1)
+
+ def _get_variables(self, content, variables):
+ return {var: self._get_variable(content, var) for var in variables}
+
+ def _replace_variables(self, content, variables):
+ for variable in variables:
+ variable_content = '{0}: {1};'.format(
+ variable['name'],
+ variable['value']
+ )
+ regex = r'{0}\:?\s(.*?);'.format(variable['name'])
+ content = re.sub(regex, variable_content, content)
+ return content
+
+ #----------------------------------------------------------
+ # Read
+ #----------------------------------------------------------
+
+ def get_content(self, url, xmlid):
+ custom_url = self._get_custom_url(url, xmlid)
+ custom_attachment = self._get_custom_attachment(custom_url)
+ if custom_attachment.exists():
+ return base64.b64decode(custom_attachment.datas).decode('utf-8')
+ else:
+ match = re.compile("^/(\w+)/(.+?)(\.custom\.(.+))?\.(\w+)$").match(url)
+ module_path = module.get_module_path(match.group(1))
+ resource_path = "%s.%s" % (match.group(2), match.group(5))
+ module_resource_path = module.get_resource_path(module_path, resource_path)
+ with open(module_resource_path, "rb") as file:
+ return file.read().decode('utf-8')
+
+ def get_values(self, url, xmlid, variables):
+ return self._get_variables(self.get_content(url, xmlid), variables)
+
+ #----------------------------------------------------------
+ # Write
+ #----------------------------------------------------------
+
+ def replace_content(self, url, xmlid, content):
+ custom_url = self._get_custom_url(url, xmlid)
+ custom_view = self._get_custom_view(custom_url)
+ custom_attachment = self._get_custom_attachment(custom_url)
+ datas = base64.b64encode((content or "\n").encode("utf-8"))
+ if custom_attachment.exists():
+ custom_attachment.write({"datas": datas})
+ else:
+ self.env["ir.attachment"].create({
+ 'name': custom_url,
+ 'type': "binary",
+ 'mimetype': "text/scss",
+ 'datas': datas,
+ 'datas_fname': url.split("/")[-1],
+ 'url': custom_url,
+ })
+ if not custom_view.exists():
+ view_to_xpath = self.env["ir.ui.view"].get_related_views(
+ xmlid, bundles=True
+ ).filtered(lambda v: v.arch.find(url) >= 0)
+ self.env["ir.ui.view"].create({
+ 'name': custom_url,
+ 'key': 'web_editor.scss_%s' % str(uuid.uuid4())[:6],
+ 'mode': "extension",
+ 'priority': view_to_xpath.priority,
+ 'inherit_id': view_to_xpath.id,
+ 'arch': """
+
+
+ %(new_url)s
+
+
+ """ % {
+ 'inherit_xml_id': view_to_xpath.xml_id,
+ 'name': custom_url,
+ 'url_to_replace': url,
+ 'new_url': custom_url,
+ }
+ })
+ self.env["ir.qweb"].clear_caches()
+
+ def replace_values(self, url, xmlid, variables):
+ content = self._replace_variables(
+ self.get_content(url, xmlid), variables
+ )
+ self.replace_content(url, xmlid, content)
+
+ def reset_values(self, url, xmlid):
+ custom_url = self._get_custom_url(url, xmlid)
+ self._get_custom_attachment(custom_url).unlink()
+ self._get_custom_view(custom_url).unlink()
diff --git a/odex-event/muk_utils/static/description/banner.png b/odex-event/muk_utils/static/description/banner.png
new file mode 100644
index 000000000..cf5692b6a
Binary files /dev/null and b/odex-event/muk_utils/static/description/banner.png differ
diff --git a/odex-event/muk_utils/static/description/icon.png b/odex-event/muk_utils/static/description/icon.png
new file mode 100644
index 000000000..1b124a971
Binary files /dev/null and b/odex-event/muk_utils/static/description/icon.png differ
diff --git a/odex-event/muk_utils/static/description/icon.svg b/odex-event/muk_utils/static/description/icon.svg
new file mode 100644
index 000000000..c06d89de4
--- /dev/null
+++ b/odex-event/muk_utils/static/description/icon.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/odex-event/muk_utils/static/description/index.html b/odex-event/muk_utils/static/description/index.html
new file mode 100644
index 000000000..6cbfb04b0
--- /dev/null
+++ b/odex-event/muk_utils/static/description/index.html
@@ -0,0 +1,124 @@
+
+
+
MuK Utils
+
Utility Features
+
MuK IT GmbH -
+ www.mukit.at
+
+
+
+
+
+
+
Overview
+
Technical module to provide some utility
+ features. The module is mainly used as a dependency by other modules
+ and to provide a collection of common libraries. It has no direct
+ visible effect on the system.
+
+
\ No newline at end of file
diff --git a/odex-event/muk_utils/static/description/logo.png b/odex-event/muk_utils/static/description/logo.png
new file mode 100644
index 000000000..9427ce33e
Binary files /dev/null and b/odex-event/muk_utils/static/description/logo.png differ
diff --git a/odex-event/muk_utils/static/description/preview.png b/odex-event/muk_utils/static/description/preview.png
new file mode 100644
index 000000000..1deb1ccef
Binary files /dev/null and b/odex-event/muk_utils/static/description/preview.png differ
diff --git a/odex-event/muk_utils/static/description/service_customization.png b/odex-event/muk_utils/static/description/service_customization.png
new file mode 100644
index 000000000..3eac66488
Binary files /dev/null and b/odex-event/muk_utils/static/description/service_customization.png differ
diff --git a/odex-event/muk_utils/static/description/service_development.png b/odex-event/muk_utils/static/description/service_development.png
new file mode 100644
index 000000000..580d46046
Binary files /dev/null and b/odex-event/muk_utils/static/description/service_development.png differ
diff --git a/odex-event/muk_utils/static/description/service_implementation.png b/odex-event/muk_utils/static/description/service_implementation.png
new file mode 100644
index 000000000..d64b66bda
Binary files /dev/null and b/odex-event/muk_utils/static/description/service_implementation.png differ
diff --git a/odex-event/muk_utils/static/description/service_integration.png b/odex-event/muk_utils/static/description/service_integration.png
new file mode 100644
index 000000000..76c5e80f4
Binary files /dev/null and b/odex-event/muk_utils/static/description/service_integration.png differ
diff --git a/odex-event/muk_utils/static/description/service_support.png b/odex-event/muk_utils/static/description/service_support.png
new file mode 100644
index 000000000..4c530fafd
Binary files /dev/null and b/odex-event/muk_utils/static/description/service_support.png differ
diff --git a/odex-event/muk_utils/tests/__init__.py b/odex-event/muk_utils/tests/__init__.py
new file mode 100644
index 000000000..2fb4f4b18
--- /dev/null
+++ b/odex-event/muk_utils/tests/__init__.py
@@ -0,0 +1,25 @@
+###################################################################################
+#
+# Copyright (c) 2017-2019 MuK IT GmbH.
+#
+# This file is part of MuK Utils
+# (see https://mukit.at).
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see .
+#
+###################################################################################
+
+from . import common
+from . import test_search_parents
+from . import test_attachment_migration
\ No newline at end of file
diff --git a/odex-event/muk_utils/tests/common.py b/odex-event/muk_utils/tests/common.py
new file mode 100644
index 000000000..f78b2547f
--- /dev/null
+++ b/odex-event/muk_utils/tests/common.py
@@ -0,0 +1,156 @@
+###################################################################################
+#
+# Copyright (c) 2017-2019 MuK IT GmbH.
+#
+# This file is part of MuK Utils
+# (see https://mukit.at).
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see .
+#
+###################################################################################
+
+import os
+import time
+import hmac
+import hashlib
+import logging
+import functools
+import threading
+import traceback
+
+from odoo.tests import common, HOST, PORT
+
+_path = os.path.dirname(os.path.dirname(__file__))
+_logger = logging.getLogger(__name__)
+
+#----------------------------------------------------------
+# Decorators
+#----------------------------------------------------------
+
+def multi_users(users=[['base.user_root', True], ['base.user_admin', True]], reset=True, raise_exception=True):
+ def decorator(func):
+ @functools.wraps(func)
+ def wrapper(self, *args, **kwargs):
+ user_list = users(self) if callable(users) else users
+ test_results = []
+ for user in user_list:
+ self.cr.execute('SAVEPOINT test_multi_users')
+ try:
+ if not isinstance(user[0], int):
+ self.uid = self.ref(user[0])
+ else:
+ self.uid = user[0]
+ func(self, *args, **kwargs)
+ except Exception as error:
+ test_results.append({
+ 'user': user[0],
+ 'expect': user[1],
+ 'result': False,
+ 'error': error,
+ })
+ else:
+ test_results.append({
+ 'user': user[0],
+ 'expect': user[1],
+ 'result': True,
+ 'error': None,
+ })
+ if reset:
+ self.env.cache.invalidate()
+ self.registry.clear_caches()
+ self.registry.reset_changes()
+ self.cr.execute('ROLLBACK TO SAVEPOINT test_multi_users')
+ else:
+ self._cr.execute('RELEASE SAVEPOINT test_multi_users')
+ test_fails = []
+ for result in test_results:
+ if result['expect'] != result['result']:
+ message = "Test (%s) with user (%s) failed!"
+ _logger.info(message % (func.__name__, result['user']))
+ if result['error']:
+ _logger.error(result['error'], exc_info=True)
+ test_fails.append(result)
+ if test_fails:
+ message = "%s out of %s tests failed" % (len(test_fails), len(test_results))
+ if raise_exception:
+ raise test_fails[0]['error']
+ else:
+ _logger.info(message)
+ return test_results
+ return wrapper
+ return decorator
+
+def track_function(max_query_count=None, max_query_time=None, max_time=None, return_tracking=False):
+ def decorator(func):
+ @functools.wraps(func)
+ def wrapper(*args, **kwargs):
+ tracking_parameters = [func.__name__]
+ threading.current_thread().query_time = 0
+ threading.current_thread().query_count = 0
+ threading.current_thread().perf_t0 = time.time()
+ result = func(*args, **kwargs)
+ message = "%s" % func.__name__
+ if args and hasattr(args[0], "uid"):
+ message = " (%s)" % args[0].uid
+ if hasattr(threading.current_thread(), "query_count"):
+ query_count = threading.current_thread().query_count
+ query_time = threading.current_thread().query_time
+ perf_t0 = threading.current_thread().perf_t0
+ remaining_time = time.time() - perf_t0 - query_time
+ time_taken = query_time + remaining_time
+ message += " - %s Q %.3fs QT %.3fs OT %.3fs TT" % (
+ query_count, query_time, remaining_time, time_taken
+ )
+ tracking_parameters += [
+ query_count, query_time, remaining_time, time_taken
+ ]
+ if max_query_count and query_count > max_query_count:
+ raise AssertionError("More than %s queries" % max_query_count)
+ if max_query_time and query_time > max_query_time:
+ raise AssertionError("Queries took longer than %.3fs" % max_query_time)
+ if max_time and time_taken > max_time:
+ raise AssertionError("Function took longer than %.3fs" % max_time)
+ if not return_tracking:
+ _logger.info(message)
+ if return_tracking:
+ return result, tracking_parameters
+ return result
+ return wrapper
+ return decorator
+
+#----------------------------------------------------------
+# Test Cases
+#----------------------------------------------------------
+
+class HttpCase(common.HttpCase):
+
+ def csrf_token(self, time_limit=3600):
+ token = self.session.sid
+ max_ts = '' if not time_limit else int(time.time() + time_limit)
+ msg = '%s%s' % (token, max_ts)
+ secret = self.env['ir.config_parameter'].sudo().get_param('database.secret')
+ assert secret, "CSRF protection requires a configured database secret"
+ hm = hmac.new(secret.encode('ascii'), msg.encode('utf-8'), hashlib.sha1).hexdigest()
+ return '%so%s' % (hm, max_ts)
+
+ def url_open(self, url, data=None, timeout=10, csrf=False):
+ if url.startswith('/'):
+ url = "http://%s:%s%s" % (HOST, PORT, url)
+ if data:
+ if csrf:
+ data.update({'csrf_token': self.csrf_token()})
+ return self.opener.post(url, data=data, timeout=timeout)
+ return self.opener.get(url, timeout=timeout)
+
+
\ No newline at end of file
diff --git a/odex-event/muk_utils/tests/test_attachment_migration.py b/odex-event/muk_utils/tests/test_attachment_migration.py
new file mode 100644
index 000000000..3f0ad85bf
--- /dev/null
+++ b/odex-event/muk_utils/tests/test_attachment_migration.py
@@ -0,0 +1,51 @@
+###################################################################################
+#
+# Copyright (c) 2017-2019 MuK IT GmbH.
+#
+# This file is part of MuK Utils
+# (see https://mukit.at).
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see .
+#
+###################################################################################
+
+import os
+import base64
+import logging
+
+from odoo import exceptions
+from odoo.tests import common
+
+_path = os.path.dirname(os.path.dirname(__file__))
+_logger = logging.getLogger(__name__)
+
+class MigrationTestCase(common.TransactionCase):
+
+ def setUp(self):
+ super(MigrationTestCase, self).setUp()
+ self.model = self.env['ir.attachment']
+ self.params = self.env['ir.config_parameter'].sudo()
+ self.location = self.params.get_param('ir_attachment.location')
+ if self.location == 'file':
+ self.params.set_param('ir_attachment.location', 'db')
+ else:
+ self.params.set_param('ir_attachment.location', 'file')
+
+ def tearDown(self):
+ self.params.set_param('ir_attachment.location', self.location)
+ super(MigrationTestCase, self).tearDown()
+
+ def test_migration(self):
+ self.model.search([], limit=25).migrate(batch_size=5)
+
\ No newline at end of file
diff --git a/odex-event/muk_utils/tests/test_search_parents.py b/odex-event/muk_utils/tests/test_search_parents.py
new file mode 100644
index 000000000..0f2ffcabb
--- /dev/null
+++ b/odex-event/muk_utils/tests/test_search_parents.py
@@ -0,0 +1,65 @@
+###################################################################################
+#
+# Copyright (c) 2017-2019 MuK IT GmbH.
+#
+# This file is part of MuK Utils
+# (see https://mukit.at).
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see .
+#
+###################################################################################
+
+import os
+import base64
+import logging
+
+from odoo import exceptions
+from odoo.tests import common
+
+_path = os.path.dirname(os.path.dirname(__file__))
+_logger = logging.getLogger(__name__)
+
+class SearchParentTestCase(common.TransactionCase):
+
+ def setUp(self):
+ super(SearchParentTestCase, self).setUp()
+ self.model = self.env['res.partner.category']
+
+ def tearDown(self):
+ super(SearchParentTestCase, self).tearDown()
+
+ def _evaluate_parent_result(self, parents, records):
+ for parent in parents:
+ self.assertTrue(
+ not parent.parent_id or
+ parent.parent_id.id not in records.ids
+ )
+
+ def test_search_parents(self):
+ records = self.model.search([])
+ parents = self.model.search_parents([])
+ self._evaluate_parent_result(parents, records)
+
+ def test_search_parents_domain(self):
+ records = self.model.search([('id', '!=', 1)])
+ parents = self.model.search_parents([('id', '!=', 1)])
+ self._evaluate_parent_result(parents, records)
+
+ def test_search_read_parents(self):
+ parents = self.model.search_parents([])
+ read_names = parents.read(['name'])
+ search_names = self.model.search_read_parents([], ['name'])
+ self.assertTrue(read_names == search_names)
+
+
\ No newline at end of file
diff --git a/odex-event/muk_utils/tools/__init__.py b/odex-event/muk_utils/tools/__init__.py
new file mode 100644
index 000000000..6631a99c1
--- /dev/null
+++ b/odex-event/muk_utils/tools/__init__.py
@@ -0,0 +1,30 @@
+###################################################################################
+#
+# Copyright (c) 2017-2019 MuK IT GmbH.
+#
+# This file is part of MuK Utils
+# (see https://mukit.at).
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see .
+#
+###################################################################################
+
+from . import rst
+from . import file
+from . import json
+from . import cache
+from . import types
+from . import http
+from . import patch
+from . import security
\ No newline at end of file
diff --git a/odex-event/muk_utils/tools/cache.py b/odex-event/muk_utils/tools/cache.py
new file mode 100644
index 000000000..0961c697b
--- /dev/null
+++ b/odex-event/muk_utils/tools/cache.py
@@ -0,0 +1,63 @@
+###################################################################################
+#
+# Copyright (c) 2017-2019 MuK IT GmbH.
+#
+# This file is part of MuK Utils
+# (see https://mukit.at).
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see .
+#
+###################################################################################
+
+import time
+import logging
+import datetime
+import functools
+
+_logger = logging.getLogger(__name__)
+
+
+#----------------------------------------------------------
+# Properties
+#----------------------------------------------------------
+
+class cached_property(object):
+
+ def __init__(self, timeout=None):
+ self.timeout = timeout
+
+ def __call__(self, func):
+ return functools.update_wrapper(self, func)
+
+ def __get__(self, obj, cls):
+ if obj is None:
+ return self
+ try:
+ value, last_updated = obj.__dict__[self.__name__]
+ except KeyError:
+ pass
+ else:
+ if self.timeout is None:
+ return value
+ elif self.timeout >= time.time() - last_updated:
+ return value
+ value = self.__wrapped__(obj)
+ obj.__dict__[self.__name__] = (value, time.time())
+ return value
+
+ def __delete__(self, obj):
+ obj.__dict__.pop(self.__name__, None)
+
+ def __set__(self, obj, value):
+ obj.__dict__[self.__name__] = (value, time())
\ No newline at end of file
diff --git a/odex-event/muk_utils/tools/file.py b/odex-event/muk_utils/tools/file.py
new file mode 100644
index 000000000..ceeb5297a
--- /dev/null
+++ b/odex-event/muk_utils/tools/file.py
@@ -0,0 +1,119 @@
+###################################################################################
+#
+# Copyright (c) 2017-2019 MuK IT GmbH.
+#
+# This file is part of MuK Utils
+# (see https://mukit.at).
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see .
+#
+###################################################################################
+
+import os
+import re
+import io
+import sys
+import base64
+import shutil
+import urllib
+import logging
+import hashlib
+import binascii
+import tempfile
+import mimetypes
+import unicodedata
+
+from odoo.tools import human_size
+from odoo.tools.mimetypes import guess_mimetype
+
+_logger = logging.getLogger(__name__)
+
+#----------------------------------------------------------
+# File Helper
+#----------------------------------------------------------
+
+def slugify(value, lower=True):
+ value = unicodedata.normalize('NFKD', value)
+ value = value.encode('ascii', 'ignore').decode('ascii')
+ value = value.lower() if lower else value
+ value = re.sub('[^\w\s-]', '', value)
+ value = re.sub('[-\s]+', '-', value)
+ return value.strip()
+
+def check_name(name):
+ tmp_dir = tempfile.mkdtemp()
+ try:
+ open(os.path.join(tmp_dir, name), 'a').close()
+ except IOError:
+ return False
+ finally:
+ shutil.rmtree(tmp_dir)
+ return True
+
+def compute_name(name, suffix, escape_suffix):
+ if escape_suffix:
+ name, extension = os.path.splitext(name)
+ return "%s(%s)%s" % (name, suffix, extension)
+ else:
+ return "%s(%s)" % (name, suffix)
+
+def unique_name(name, names, escape_suffix=False):
+ if not name in names:
+ return name
+ else:
+ suffix = 1
+ name = compute_name(name, suffix, escape_suffix)
+ while name in names:
+ suffix += 1
+ name = compute_name(name, suffix, escape_suffix)
+ return name
+
+def unique_files(files):
+ ufiles = []
+ unames = []
+ for file in files:
+ uname = unique_name(file[0], unames, escape_suffix=True)
+ ufiles.append((uname, file[1]))
+ unames.append(uname)
+ return ufiles
+
+def guess_extension(filename=None, mimetype=None, binary=None):
+ extension = filename and os.path.splitext(filename)[1][1:].strip().lower()
+ if not extension and mimetype:
+ extension = mimetypes.guess_extension(mimetype)[1:].strip().lower()
+ if not extension and binary:
+ mimetype = guess_mimetype(binary, default="")
+ extension = mimetypes.guess_extension(mimetype)[1:].strip().lower()
+ return extension
+
+#----------------------------------------------------------
+# System Helper
+#----------------------------------------------------------
+
+def ensure_path_directories(path):
+ directory_path = os.path.dirname(path)
+ if not os.path.exists(directory_path):
+ os.makedirs(directory_path)
+
+def remove_empty_directories(path):
+ if not os.path.isdir(path):
+ return
+ entries = os.listdir(path)
+ if len(entries) > 0:
+ for entry in entries:
+ subpath = os.path.join(path, entry)
+ if os.path.isdir(subpath):
+ self._remove_empty_directories(subpath)
+ else:
+ os.rmdir(path)
\ No newline at end of file
diff --git a/odex-event/muk_utils/tools/http.py b/odex-event/muk_utils/tools/http.py
new file mode 100644
index 000000000..b12e6cb51
--- /dev/null
+++ b/odex-event/muk_utils/tools/http.py
@@ -0,0 +1,59 @@
+###################################################################################
+#
+# Copyright (c) 2017-2019 MuK IT GmbH.
+#
+# This file is part of MuK Utils
+# (see https://mukit.at).
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see .
+#
+###################################################################################
+
+import urllib
+import base64
+import logging
+
+from werkzeug.datastructures import CombinedMultiDict
+
+_logger = logging.getLogger(__name__)
+
+#----------------------------------------------------------
+# Header Helper
+#----------------------------------------------------------
+
+def decode_http_basic_authentication_value(value):
+ try:
+ username, password = base64.b64decode(value).decode().split(':', 1)
+ return urllib.parse.unquote(username), urllib.parse.unquote(password)
+ except:
+ return None, None
+
+def decode_http_basic_authentication(encoded_header):
+ header_values = encoded_header.strip().split(' ')
+ if len(header_values) == 1:
+ return decode_http_basic_authentication_value(header_values[0])
+ if len(header_values) == 2 and header_values[0].strip().lower() == 'basic':
+ return decode_http_basic_authentication_value(header_values[1])
+ return None, None
+
+#----------------------------------------------------------
+# Werkzeug Helper
+#----------------------------------------------------------
+
+def request_params(httprequest):
+ return CombinedMultiDict([
+ httprequest.args,
+ httprequest.form,
+ httprequest.files
+ ])
\ No newline at end of file
diff --git a/odex-event/muk_utils/tools/json.py b/odex-event/muk_utils/tools/json.py
new file mode 100644
index 000000000..183a3e171
--- /dev/null
+++ b/odex-event/muk_utils/tools/json.py
@@ -0,0 +1,52 @@
+###################################################################################
+#
+# Copyright (c) 2017-2019 MuK IT GmbH.
+#
+# This file is part of MuK Utils
+# (see https://mukit.at).
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see .
+#
+###################################################################################
+
+import json
+import logging
+import datetime
+
+from odoo import models, tools
+
+_logger = logging.getLogger(__name__)
+
+#----------------------------------------------------------
+# JSON Encoder
+#----------------------------------------------------------
+
+class ResponseEncoder(json.JSONEncoder):
+
+ def default(self, obj):
+ if isinstance(obj, datetime.datetime):
+ return obj.strftime(tools.DEFAULT_SERVER_DATETIME_FORMAT)
+ if isinstance(obj, datetime.date):
+ return obj.strftime(tools.DEFAULT_SERVER_DATE_FORMAT)
+ if isinstance(obj, (bytes, bytearray)):
+ return obj.decode()
+ return json.JSONEncoder.default(self, obj)
+
+class RecordEncoder(ResponseEncoder):
+
+ def default(self, obj):
+ if isinstance(obj, models.BaseModel):
+ return obj.name_get()
+ return ResponseEncoder.default(self, obj)
+
\ No newline at end of file
diff --git a/odex-event/muk_utils/tools/patch.py b/odex-event/muk_utils/tools/patch.py
new file mode 100644
index 000000000..c1a66d05c
--- /dev/null
+++ b/odex-event/muk_utils/tools/patch.py
@@ -0,0 +1,39 @@
+###################################################################################
+#
+# Copyright (c) 2017-2019 MuK IT GmbH.
+#
+# This file is part of MuK Utils
+# (see https://mukit.at).
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see .
+#
+###################################################################################
+
+import logging
+
+from odoo import api
+
+_logger = logging.getLogger(__name__)
+
+#----------------------------------------------------------
+# Patch Helper
+#----------------------------------------------------------
+
+def monkey_patch(cls):
+ def decorate(func):
+ name = func.__name__
+ func.super = getattr(cls, name, None)
+ setattr(cls, name, func)
+ return func
+ return decorate
diff --git a/odex-event/muk_utils/tools/rst.py b/odex-event/muk_utils/tools/rst.py
new file mode 100644
index 000000000..8bdf2cc7f
--- /dev/null
+++ b/odex-event/muk_utils/tools/rst.py
@@ -0,0 +1,55 @@
+###################################################################################
+#
+# Copyright (c) 2017-2019 MuK IT GmbH.
+#
+# This file is part of MuK Utils
+# (see https://mukit.at).
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see .
+#
+###################################################################################
+
+import logging
+
+from docutils import nodes
+from docutils.core import publish_string
+from docutils.transforms import Transform, writer_aux
+from docutils.writers.html4css1 import Writer
+
+from odoo import tools
+
+_logger = logging.getLogger(__name__)
+
+class ReStructuredTextFilterMessages(Transform):
+ default_priority = 870
+ def apply(self):
+ for node in self.document.traverse(nodes.system_message):
+ node.parent.remove(node)
+
+class ReStructuredTextWriter(Writer):
+ def get_transforms(self):
+ return [ReStructuredTextFilterMessages, writer_aux.Admonitions]
+
+def rst2html(content):
+ overrides = {
+ 'embed_stylesheet': False,
+ 'doctitle_xform': False,
+ 'output_encoding': 'unicode',
+ 'xml_declaration': False,
+ }
+ output = publish_string(content,
+ settings_overrides=overrides,
+ writer=ReStructuredTextWriter()
+ )
+ return tools.html_sanitize(output)
diff --git a/odex-event/muk_utils/tools/security.py b/odex-event/muk_utils/tools/security.py
new file mode 100644
index 000000000..ef008a532
--- /dev/null
+++ b/odex-event/muk_utils/tools/security.py
@@ -0,0 +1,37 @@
+###################################################################################
+#
+# Copyright (c) 2017-2019 MuK IT GmbH.
+#
+# This file is part of MuK Utils
+# (see https://mukit.at).
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see .
+#
+###################################################################################
+
+import string
+import random
+import logging
+
+_logger = logging.getLogger(__name__)
+
+UNICODE_ASCII_CHARACTERS = string.ascii_letters + string.digits
+
+#----------------------------------------------------------
+# Generator
+#----------------------------------------------------------
+
+def generate_token(length=30, chars=UNICODE_ASCII_CHARACTERS):
+ generator = random.SystemRandom()
+ return "".join(generator.choice(chars) for index in range(length))
\ No newline at end of file
diff --git a/odex-event/muk_utils/tools/types.py b/odex-event/muk_utils/tools/types.py
new file mode 100644
index 000000000..11ef779cd
--- /dev/null
+++ b/odex-event/muk_utils/tools/types.py
@@ -0,0 +1,40 @@
+###################################################################################
+#
+# Copyright (c) 2017-2019 MuK IT GmbH.
+#
+# This file is part of MuK Utils
+# (see https://mukit.at).
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see .
+#
+###################################################################################
+
+import logging
+
+_logger = logging.getLogger(__name__)
+
+#----------------------------------------------------------
+# Meta Classes
+#----------------------------------------------------------
+
+class Singleton(type):
+
+ _instances = {}
+
+ def __call__(cls, *args, **kwargs):
+ if cls not in cls._instances:
+ cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
+ return cls._instances[cls]
+
+
\ No newline at end of file
diff --git a/odex-event/muk_utils/tools/utils.py b/odex-event/muk_utils/tools/utils.py
new file mode 100644
index 000000000..84e3b4c40
--- /dev/null
+++ b/odex-event/muk_utils/tools/utils.py
@@ -0,0 +1,48 @@
+###################################################################################
+#
+# Copyright (c) 2017-2019 MuK IT GmbH.
+#
+# This file is part of MuK Utils
+# (see https://mukit.at).
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see .
+#
+###################################################################################
+
+import logging
+
+_logger = logging.getLogger(__name__)
+
+#----------------------------------------------------------
+# List Methods
+#----------------------------------------------------------
+
+def uniquify_list(seq):
+ seen = set()
+ return [
+ val for val in seq if val not in seen and not seen.add(val)
+ ]
+
+#----------------------------------------------------------
+# Safe Execute
+#----------------------------------------------------------
+
+def safe_execute_exception(default, exception, function, *args, **kwargs):
+ try:
+ return function(*args, **kwargs)
+ except exception:
+ return default
+
+def safe_execute(default, function, *args, **kwargs):
+ return safe_execute_exception(default, Exception, function, *args, **kwargs)
\ No newline at end of file
diff --git a/odex-event/muk_utils/views/ir_attachment.xml b/odex-event/muk_utils/views/ir_attachment.xml
new file mode 100644
index 000000000..eda9bc0e6
--- /dev/null
+++ b/odex-event/muk_utils/views/ir_attachment.xml
@@ -0,0 +1,72 @@
+
+
+
+
+
+
+
+ ir_attachment.search
+ ir.attachment
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ir_attachment.tree
+ ir.attachment
+
+
+
+
+
+
+
+
+
+ ir_attachment.form
+ ir.attachment
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/odex-event/muk_utils/views/mixins_groups.xml b/odex-event/muk_utils/views/mixins_groups.xml
new file mode 100644
index 000000000..0f9bdccd8
--- /dev/null
+++ b/odex-event/muk_utils/views/mixins_groups.xml
@@ -0,0 +1,101 @@
+
+
+
+
+
+
+
+ muk_utils_mixins_groups.tree
+ muk_utils.mixins.groups
+
+
+
+
+
+
+
+
+
+ muk_utils_mixins_groups.form
+ muk_utils.mixins.groups
+
+
+
+
+
+
\ No newline at end of file
diff --git a/odex-event/muk_utils/views/res_config_settings.xml b/odex-event/muk_utils/views/res_config_settings.xml
new file mode 100644
index 000000000..7f8a0ff1d
--- /dev/null
+++ b/odex-event/muk_utils/views/res_config_settings.xml
@@ -0,0 +1,61 @@
+
+
+
+
+
+
+
+ res.config.settings.view.form
+ res.config.settings
+
+
+
+
Storage
+
+
+
+
+
+
+ Attachment storage location
+
+
+
+
+
+
+ Save this page before triggering the migration.
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/odex-event/muk_web_searchpanel/LICENSE b/odex-event/muk_web_searchpanel/LICENSE
new file mode 100644
index 000000000..153d416dc
--- /dev/null
+++ b/odex-event/muk_web_searchpanel/LICENSE
@@ -0,0 +1,165 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+
+ This version of the GNU Lesser General Public License incorporates
+the terms and conditions of version 3 of the GNU General Public
+License, supplemented by the additional permissions listed below.
+
+ 0. Additional Definitions.
+
+ As used herein, "this License" refers to version 3 of the GNU Lesser
+General Public License, and the "GNU GPL" refers to version 3 of the GNU
+General Public License.
+
+ "The Library" refers to a covered work governed by this License,
+other than an Application or a Combined Work as defined below.
+
+ An "Application" is any work that makes use of an interface provided
+by the Library, but which is not otherwise based on the Library.
+Defining a subclass of a class defined by the Library is deemed a mode
+of using an interface provided by the Library.
+
+ A "Combined Work" is a work produced by combining or linking an
+Application with the Library. The particular version of the Library
+with which the Combined Work was made is also called the "Linked
+Version".
+
+ The "Minimal Corresponding Source" for a Combined Work means the
+Corresponding Source for the Combined Work, excluding any source code
+for portions of the Combined Work that, considered in isolation, are
+based on the Application, and not on the Linked Version.
+
+ The "Corresponding Application Code" for a Combined Work means the
+object code and/or source code for the Application, including any data
+and utility programs needed for reproducing the Combined Work from the
+Application, but excluding the System Libraries of the Combined Work.
+
+ 1. Exception to Section 3 of the GNU GPL.
+
+ You may convey a covered work under sections 3 and 4 of this License
+without being bound by section 3 of the GNU GPL.
+
+ 2. Conveying Modified Versions.
+
+ If you modify a copy of the Library, and, in your modifications, a
+facility refers to a function or data to be supplied by an Application
+that uses the facility (other than as an argument passed when the
+facility is invoked), then you may convey a copy of the modified
+version:
+
+ a) under this License, provided that you make a good faith effort to
+ ensure that, in the event an Application does not supply the
+ function or data, the facility still operates, and performs
+ whatever part of its purpose remains meaningful, or
+
+ b) under the GNU GPL, with none of the additional permissions of
+ this License applicable to that copy.
+
+ 3. Object Code Incorporating Material from Library Header Files.
+
+ The object code form of an Application may incorporate material from
+a header file that is part of the Library. You may convey such object
+code under terms of your choice, provided that, if the incorporated
+material is not limited to numerical parameters, data structure
+layouts and accessors, or small macros, inline functions and templates
+(ten or fewer lines in length), you do both of the following:
+
+ a) Give prominent notice with each copy of the object code that the
+ Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the object code with a copy of the GNU GPL and this license
+ document.
+
+ 4. Combined Works.
+
+ You may convey a Combined Work under terms of your choice that,
+taken together, effectively do not restrict modification of the
+portions of the Library contained in the Combined Work and reverse
+engineering for debugging such modifications, if you also do each of
+the following:
+
+ a) Give prominent notice with each copy of the Combined Work that
+ the Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the Combined Work with a copy of the GNU GPL and this license
+ document.
+
+ c) For a Combined Work that displays copyright notices during
+ execution, include the copyright notice for the Library among
+ these notices, as well as a reference directing the user to the
+ copies of the GNU GPL and this license document.
+
+ d) Do one of the following:
+
+ 0) Convey the Minimal Corresponding Source under the terms of this
+ License, and the Corresponding Application Code in a form
+ suitable for, and under terms that permit, the user to
+ recombine or relink the Application with a modified version of
+ the Linked Version to produce a modified Combined Work, in the
+ manner specified by section 6 of the GNU GPL for conveying
+ Corresponding Source.
+
+ 1) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (a) uses at run time
+ a copy of the Library already present on the user's computer
+ system, and (b) will operate properly with a modified version
+ of the Library that is interface-compatible with the Linked
+ Version.
+
+ e) Provide Installation Information, but only if you would otherwise
+ be required to provide such information under section 6 of the
+ GNU GPL, and only to the extent that such information is
+ necessary to install and execute a modified version of the
+ Combined Work produced by recombining or relinking the
+ Application with a modified version of the Linked Version. (If
+ you use option 4d0, the Installation Information must accompany
+ the Minimal Corresponding Source and Corresponding Application
+ Code. If you use option 4d1, you must provide the Installation
+ Information in the manner specified by section 6 of the GNU GPL
+ for conveying Corresponding Source.)
+
+ 5. Combined Libraries.
+
+ You may place library facilities that are a work based on the
+Library side by side in a single library together with other library
+facilities that are not Applications and are not covered by this
+License, and convey such a combined library under terms of your
+choice, if you do both of the following:
+
+ a) Accompany the combined library with a copy of the same work based
+ on the Library, uncombined with any other library facilities,
+ conveyed under the terms of this License.
+
+ b) Give prominent notice with the combined library that part of it
+ is a work based on the Library, and explaining where to find the
+ accompanying uncombined form of the same work.
+
+ 6. Revised Versions of the GNU Lesser General Public License.
+
+ The Free Software Foundation may publish revised and/or new versions
+of the GNU Lesser General Public License from time to time. Such new
+versions will be similar in spirit to the present version, but may
+differ in detail to address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Library as you received it specifies that a certain numbered version
+of the GNU Lesser General Public License "or any later version"
+applies to it, you have the option of following the terms and
+conditions either of that published version or of any later version
+published by the Free Software Foundation. If the Library as you
+received it does not specify a version number of the GNU Lesser
+General Public License, you may choose any version of the GNU Lesser
+General Public License ever published by the Free Software Foundation.
+
+ If the Library as you received it specifies that a proxy can decide
+whether future versions of the GNU Lesser General Public License shall
+apply, that proxy's public statement of acceptance of any version is
+permanent authorization for you to choose that version for the
+Library.
\ No newline at end of file
diff --git a/odex-event/muk_web_searchpanel/README.rst b/odex-event/muk_web_searchpanel/README.rst
new file mode 100644
index 000000000..a54d3c4ef
--- /dev/null
+++ b/odex-event/muk_web_searchpanel/README.rst
@@ -0,0 +1,160 @@
+================
+MuK Search Panel
+================
+
+With Odoo version 13 a new feature is added which allows kanban views to be
+extended by a search panel. This can be defined via XML and is then automatically
+added to the view. With this module the function is ported back to version 12.
+
+Installation
+============
+
+To install this module, you need to:
+
+Download the module and add it to your Odoo addons folder. Afterward, log on to
+your Odoo server and go to the Apps menu. Trigger the debug mode and update the
+list by clicking on the "Update Apps List" link. Now install the module by
+clicking on the install button.
+
+Another way to install this module is via the package management for Python
+(`PyPI `_).
+
+To install our modules using the package manager make sure
+`odoo-autodiscover `_ is installed
+correctly. Then open a console and install the module by entering the following
+command:
+
+``pip install --extra-index-url https://nexus.mukit.at/repository/odoo/simple ``
+
+The module name consists of the Odoo version and the module name, where
+underscores are replaced by a dash.
+
+**Module:**
+
+``odoo-addon-``
+
+**Example:**
+
+``sudo -H pip3 install --extra-index-url https://nexus.mukit.at/repository/odoo/simple odoo11-addon-muk-utils``
+
+Once the installation has been successfully completed, the app is already in the
+correct folder. Log on to your Odoo server and go to the Apps menu. Trigger the
+debug mode and update the list by clicking on the "Update Apps List" link. Now
+install the module by clicking on the install button.
+
+The biggest advantage of this variant is that you can now also update the app
+using the "pip" command. To do this, enter the following command in your console:
+
+``pip install --upgrade --extra-index-url https://nexus.mukit.at/repository/odoo/simple ``
+
+When the process is finished, restart your server and update the application in
+Odoo. The steps are the same as for the installation only the button has changed
+from "Install" to "Upgrade".
+
+You can also view available Apps directly in our `repository `_
+and find a more detailed installation guide on our `website `_.
+
+For modules licensed under OPL-1, you will receive access data when you purchase
+the module. If the modules were not purchased directly from
+`MuK IT `_ please contact our support (support@mukit.at)
+with a confirmation of purchase to receive the corresponding access data.
+
+Upgrade
+============
+
+To upgrade this module, you need to:
+
+Download the module and add it to your Odoo addons folder. Restart the server
+and log on to your Odoo server. Select the Apps menu and upgrade the module by
+clicking on the upgrade button.
+
+If you installed the module using the "pip" command, you can also update the
+module in the same way. Just type the following command into the console:
+
+``pip install --upgrade --extra-index-url https://nexus.mukit.at/repository/odoo/simple ``
+
+When the process is finished, restart your server and update the application in
+Odoo, just like you would normally.
+
+Configuration
+=============
+
+No additional configuration is needed to use this module.
+
+Usage
+=============
+
+This tool allows to quickly filter data on the basis of given fields. The fields
+are specified as direct children of the ``searchpanel`` with tag name ``field``,
+and the following attributes:
+
+* ``name`` (mandatory) the name of the field to filter on
+* ``select`` determines the behavior and display.
+* ``groups``: restricts to specific users
+* ``string``: determines the label to display
+* ``icon``: specifies which icon is used
+* ``color``: determines the icon color
+
+Possible values for the ``select`` attribute are
+
+* ``one`` (default) at most one value can be selected. Supported field types are many2one and selection.
+* ``multi`` several values can be selected (checkboxes). Supported field types are many2one, many2many and selection.
+
+Additional optional attributes are available in the ``multi`` case:
+
+* ``domain``: determines conditions that the comodel records have to satisfy.
+
+A domain might be used to express a dependency on another field (with select="one")
+of the search panel. Consider
+
+.. code-block:: xml
+
+
+
+
+
+
+In the above example, the range of values for manager_id (manager names) available at screen
+will depend on the value currently selected for the field ``department_id``.
+
+* ``groupby``: field name of the comodel (only available for many2one and many2many fields). Values will be grouped by that field.
+
+* ``disable_counters``: default is false. If set to true the counters won't be computed.
+
+This feature has been implemented in case performances would be too bad.
+
+Another way to solve performance issues is to properly override the ``search_panel_select_multi_range`` method.
+
+Credits
+=======
+
+Contributors
+------------
+
+* Mathias Markl
+
+Images
+------------
+
+Some pictures are based on or inspired by the icon set of Font Awesome:
+
+* `Font Awesome `_
+
+Projects
+------------
+
+Parts of the module are based on or inspired by:
+
+* `Odoo `_
+
+Author & Maintainer
+-------------------
+
+This module is maintained by the `MuK IT GmbH `_.
+
+MuK IT is an Austrian company specialized in customizing and extending Odoo.
+We develop custom solutions for your individual needs to help you focus on
+your strength and expertise to grow your business.
+
+If you want to get in touch please contact us via mail
+(sale@mukit.at) or visit our website (https://mukit.at).
diff --git a/odex-event/muk_web_searchpanel/__init__.py b/odex-event/muk_web_searchpanel/__init__.py
new file mode 100644
index 000000000..c4c92ba30
--- /dev/null
+++ b/odex-event/muk_web_searchpanel/__init__.py
@@ -0,0 +1,23 @@
+###################################################################################
+#
+# Copyright (c) 2017-2019 MuK IT GmbH.
+#
+# This file is part of MuK Search Panel
+# (see https://mukit.at).
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see .
+#
+###################################################################################
+
+from . import models
\ No newline at end of file
diff --git a/odex-event/muk_web_searchpanel/__manifest__.py b/odex-event/muk_web_searchpanel/__manifest__.py
new file mode 100644
index 000000000..21fbf5a72
--- /dev/null
+++ b/odex-event/muk_web_searchpanel/__manifest__.py
@@ -0,0 +1,54 @@
+###################################################################################
+#
+# Copyright (c) 2017-2019 MuK IT GmbH.
+#
+# This file is part of MuK Search Panel
+# (see https://mukit.at).
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see .
+#
+###################################################################################
+
+{
+ 'name': 'MuK Search Panel',
+ 'summary': 'Kanban Search Panel',
+ 'version': '12.0.2.0.1',
+ 'category': 'Extra Tools',
+ 'license': 'LGPL-3',
+ 'author': 'MuK IT',
+ 'website': 'https://www.mukit.at',
+ 'live_test_url': 'https://mukit.at/r/SgN',
+ 'contributors': [
+ 'Mathias Markl ',
+ ],
+ 'depends': [
+ 'muk_web_utils',
+ ],
+ 'data': [
+ "template/assets.xml",
+ ],
+ 'qweb': [
+ 'static/src/xml/*.xml',
+ ],
+ 'images': [
+ 'static/description/banner.png'
+ ],
+ 'external_dependencies': {
+ 'python': [],
+ 'bin': [],
+ },
+ 'application': False,
+ 'installable': True,
+ 'auto_install': False,
+}
\ No newline at end of file
diff --git a/odex-event/muk_web_searchpanel/doc/changelog.rst b/odex-event/muk_web_searchpanel/doc/changelog.rst
new file mode 100644
index 000000000..4c6a0d20e
--- /dev/null
+++ b/odex-event/muk_web_searchpanel/doc/changelog.rst
@@ -0,0 +1,15 @@
+`1.2.0`
+-------
+
+- Mobile Support
+
+`1.1.0`
+-------
+
+- Lazy Loading on long requests
+
+`1.0.0`
+-------
+
+- Init version
+
diff --git a/odex-event/muk_web_searchpanel/doc/index.rst b/odex-event/muk_web_searchpanel/doc/index.rst
new file mode 100644
index 000000000..a54d3c4ef
--- /dev/null
+++ b/odex-event/muk_web_searchpanel/doc/index.rst
@@ -0,0 +1,160 @@
+================
+MuK Search Panel
+================
+
+With Odoo version 13 a new feature is added which allows kanban views to be
+extended by a search panel. This can be defined via XML and is then automatically
+added to the view. With this module the function is ported back to version 12.
+
+Installation
+============
+
+To install this module, you need to:
+
+Download the module and add it to your Odoo addons folder. Afterward, log on to
+your Odoo server and go to the Apps menu. Trigger the debug mode and update the
+list by clicking on the "Update Apps List" link. Now install the module by
+clicking on the install button.
+
+Another way to install this module is via the package management for Python
+(`PyPI `_).
+
+To install our modules using the package manager make sure
+`odoo-autodiscover `_ is installed
+correctly. Then open a console and install the module by entering the following
+command:
+
+``pip install --extra-index-url https://nexus.mukit.at/repository/odoo/simple ``
+
+The module name consists of the Odoo version and the module name, where
+underscores are replaced by a dash.
+
+**Module:**
+
+``odoo-addon-``
+
+**Example:**
+
+``sudo -H pip3 install --extra-index-url https://nexus.mukit.at/repository/odoo/simple odoo11-addon-muk-utils``
+
+Once the installation has been successfully completed, the app is already in the
+correct folder. Log on to your Odoo server and go to the Apps menu. Trigger the
+debug mode and update the list by clicking on the "Update Apps List" link. Now
+install the module by clicking on the install button.
+
+The biggest advantage of this variant is that you can now also update the app
+using the "pip" command. To do this, enter the following command in your console:
+
+``pip install --upgrade --extra-index-url https://nexus.mukit.at/repository/odoo/simple ``
+
+When the process is finished, restart your server and update the application in
+Odoo. The steps are the same as for the installation only the button has changed
+from "Install" to "Upgrade".
+
+You can also view available Apps directly in our `repository `_
+and find a more detailed installation guide on our `website `_.
+
+For modules licensed under OPL-1, you will receive access data when you purchase
+the module. If the modules were not purchased directly from
+`MuK IT `_ please contact our support (support@mukit.at)
+with a confirmation of purchase to receive the corresponding access data.
+
+Upgrade
+============
+
+To upgrade this module, you need to:
+
+Download the module and add it to your Odoo addons folder. Restart the server
+and log on to your Odoo server. Select the Apps menu and upgrade the module by
+clicking on the upgrade button.
+
+If you installed the module using the "pip" command, you can also update the
+module in the same way. Just type the following command into the console:
+
+``pip install --upgrade --extra-index-url https://nexus.mukit.at/repository/odoo/simple ``
+
+When the process is finished, restart your server and update the application in
+Odoo, just like you would normally.
+
+Configuration
+=============
+
+No additional configuration is needed to use this module.
+
+Usage
+=============
+
+This tool allows to quickly filter data on the basis of given fields. The fields
+are specified as direct children of the ``searchpanel`` with tag name ``field``,
+and the following attributes:
+
+* ``name`` (mandatory) the name of the field to filter on
+* ``select`` determines the behavior and display.
+* ``groups``: restricts to specific users
+* ``string``: determines the label to display
+* ``icon``: specifies which icon is used
+* ``color``: determines the icon color
+
+Possible values for the ``select`` attribute are
+
+* ``one`` (default) at most one value can be selected. Supported field types are many2one and selection.
+* ``multi`` several values can be selected (checkboxes). Supported field types are many2one, many2many and selection.
+
+Additional optional attributes are available in the ``multi`` case:
+
+* ``domain``: determines conditions that the comodel records have to satisfy.
+
+A domain might be used to express a dependency on another field (with select="one")
+of the search panel. Consider
+
+.. code-block:: xml
+
+
+
+
+
+
+In the above example, the range of values for manager_id (manager names) available at screen
+will depend on the value currently selected for the field ``department_id``.
+
+* ``groupby``: field name of the comodel (only available for many2one and many2many fields). Values will be grouped by that field.
+
+* ``disable_counters``: default is false. If set to true the counters won't be computed.
+
+This feature has been implemented in case performances would be too bad.
+
+Another way to solve performance issues is to properly override the ``search_panel_select_multi_range`` method.
+
+Credits
+=======
+
+Contributors
+------------
+
+* Mathias Markl
+
+Images
+------------
+
+Some pictures are based on or inspired by the icon set of Font Awesome:
+
+* `Font Awesome `_
+
+Projects
+------------
+
+Parts of the module are based on or inspired by:
+
+* `Odoo `_
+
+Author & Maintainer
+-------------------
+
+This module is maintained by the `MuK IT GmbH `_.
+
+MuK IT is an Austrian company specialized in customizing and extending Odoo.
+We develop custom solutions for your individual needs to help you focus on
+your strength and expertise to grow your business.
+
+If you want to get in touch please contact us via mail
+(sale@mukit.at) or visit our website (https://mukit.at).
diff --git a/odex-event/muk_web_searchpanel/models/__init__.py b/odex-event/muk_web_searchpanel/models/__init__.py
new file mode 100644
index 000000000..2f434a23a
--- /dev/null
+++ b/odex-event/muk_web_searchpanel/models/__init__.py
@@ -0,0 +1,24 @@
+###################################################################################
+#
+# Copyright (c) 2017-2019 MuK IT GmbH.
+#
+# This file is part of MuK Search Panel
+# (see https://mukit.at).
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see .
+#
+###################################################################################
+
+from . import base
+
diff --git a/odex-event/muk_web_searchpanel/models/base.py b/odex-event/muk_web_searchpanel/models/base.py
new file mode 100644
index 000000000..f87653170
--- /dev/null
+++ b/odex-event/muk_web_searchpanel/models/base.py
@@ -0,0 +1,196 @@
+###################################################################################
+#
+# Copyright (c) 2017-2019 MuK IT GmbH.
+#
+# This file is part of MuK Search Panel
+# (see https://mukit.at).
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see .
+#
+###################################################################################
+
+import logging
+
+from odoo import _, api, fields, models
+from odoo.exceptions import UserError
+from odoo.osv import expression
+from odoo.tools import lazy
+
+_logger = logging.getLogger(__name__)
+
+class Base(models.AbstractModel):
+
+ _inherit = 'base'
+
+ #----------------------------------------------------------
+ # Functions
+ #----------------------------------------------------------
+
+ @api.model
+ def search_panel_select_range(self, field_name, **kwargs):
+ """
+ Return possible values of the field field_name (case select="one")
+ and the parent field (if any) used to hierarchize them.
+
+ :param field_name: the name of a many2one category field
+ :return: {
+ 'parent_field': parent field on the comodel of field, or False
+ 'values': array of dictionaries containing some info on the records
+ available on the comodel of the field 'field_name'.
+ The display name (and possibly parent_field) are fetched.
+ }
+ """
+ field = self._fields[field_name]
+ supported_types = ['many2one']
+ if field.type not in supported_types:
+ raise UserError(_('Only types %(supported_types)s are supported for category (found type %(field_type)s)') % ({
+ 'supported_types': supported_types, 'field_type': field.type}))
+
+ Comodel = self.env[field.comodel_name]
+ fields = ['display_name']
+ parent_name = Comodel._parent_name if Comodel._parent_name in Comodel._fields else False
+ if parent_name:
+ fields.append(parent_name)
+
+ model_domain = expression.AND([
+ kwargs.get('search_domain', []),
+ kwargs.get('category_domain', []),
+ kwargs.get('filter_domain', []),
+ ])
+
+ return {
+ 'parent_field': parent_name,
+ 'values': Comodel.with_context(hierarchical_naming=False).search_read(model_domain, fields),
+ }
+
+ @api.model
+ def search_panel_select_multi_range(self, field_name, **kwargs):
+ """
+ Return possible values of the field field_name (case select="multi"),
+ possibly with counters and groups.
+
+ :param field_name: the name of a filter field;
+ possible types are many2one, many2many, selection.
+ :param search_domain: base domain of search
+ :param category_domain: domain generated by categories
+ :param filter_domain: domain generated by filters
+ :param comodel_domain: domain of field values (if relational)
+ :param group_by: extra field to read on comodel, to group comodel records
+ :param disable_counters: whether to count records by value
+ :return: a list of possible values, each being a dict with keys
+ 'id' (value),
+ 'name' (value label),
+ 'count' (how many records with that value),
+ 'group_id' (value of group),
+ 'group_name' (label of group).
+ """
+ field = self._fields[field_name]
+ supported_types = ['many2one', 'many2many', 'selection']
+ if field.type not in supported_types:
+ raise UserError(_('Only types %(supported_types)s are supported for filter (found type %(field_type)s)') % ({
+ 'supported_types': supported_types, 'field_type': field.type}))
+
+ Comodel = self.env.get(field.comodel_name)
+
+ model_domain = expression.AND([
+ kwargs.get('search_domain', []),
+ kwargs.get('category_domain', []),
+ kwargs.get('filter_domain', []),
+ [(field_name, '!=', False)],
+ ])
+ comodel_domain = kwargs.get('comodel_domain', [])
+ disable_counters = kwargs.get('disable_counters', False)
+
+ group_by = kwargs.get('group_by', False)
+ if group_by:
+ # determine the labeling of values returned by the group_by field
+ group_by_field = Comodel._fields[group_by]
+
+ if group_by_field.type == 'many2one':
+ def group_id_name(value):
+ return value or (False, _("Not Set"))
+
+ elif group_by_field.type == 'selection':
+ desc = Comodel.fields_get([group_by])[group_by]
+ group_by_selection = dict(desc['selection'])
+ group_by_selection[False] = _("Not Set")
+
+ def group_id_name(value):
+ return value, group_by_selection[value]
+
+ else:
+ def group_id_name(value):
+ return (value, value) if value else (False, _("Not Set"))
+
+ # get filter_values
+ filter_values = []
+
+ if field.type == 'many2one':
+ counters = {}
+ if not disable_counters:
+ groups = self.read_group(model_domain, [field_name], [field_name])
+ counters = {
+ group[field_name][0]: group[field_name + '_count']
+ for group in groups
+ }
+ # retrieve all possible values, and return them with their label and counter
+ field_names = ['display_name', group_by] if group_by else ['display_name']
+ records = Comodel.search_read(comodel_domain, field_names)
+ for record in records:
+ record_id = record['id']
+ values = {
+ 'id': record_id,
+ 'name': record['display_name'],
+ 'count': counters.get(record_id, 0),
+ }
+ if group_by:
+ values['group_id'], values['group_name'] = group_id_name(record[group_by])
+ filter_values.append(values)
+
+ elif field.type == 'many2many':
+ # retrieve all possible values, and return them with their label and counter
+ field_names = ['display_name', group_by] if group_by else ['display_name']
+ records = Comodel.search_read(comodel_domain, field_names)
+ for record in records:
+ record_id = record['id']
+ values = {
+ 'id': record_id,
+ 'name': record['display_name'],
+ 'count': 0,
+ }
+ if not disable_counters:
+ count_domain = expression.AND([model_domain, [(field_name, 'in', record_id)]])
+ values['count'] = self.search_count(count_domain)
+ if group_by:
+ values['group_id'], values['group_name'] = group_id_name(record[group_by])
+ filter_values.append(values)
+
+ elif field.type == 'selection':
+ counters = {}
+ if not disable_counters:
+ groups = self.read_group(model_domain, [field_name], [field_name])
+ counters = {
+ group[field_name]: group[field_name + '_count']
+ for group in groups
+ }
+ # retrieve all possible values, and return them with their label and counter
+ selection = self.fields_get([field_name])[field_name]
+ for value, label in selection:
+ filter_values.append({
+ 'id': value,
+ 'name': label,
+ 'count': counters.get(value, 0),
+ })
+
+ return filter_values
diff --git a/odex-event/muk_web_searchpanel/static/description/banner.png b/odex-event/muk_web_searchpanel/static/description/banner.png
new file mode 100644
index 000000000..4718e7585
Binary files /dev/null and b/odex-event/muk_web_searchpanel/static/description/banner.png differ
diff --git a/odex-event/muk_web_searchpanel/static/description/icon.png b/odex-event/muk_web_searchpanel/static/description/icon.png
new file mode 100644
index 000000000..80205d335
Binary files /dev/null and b/odex-event/muk_web_searchpanel/static/description/icon.png differ
diff --git a/odex-event/muk_web_searchpanel/static/description/icon.svg b/odex-event/muk_web_searchpanel/static/description/icon.svg
new file mode 100644
index 000000000..e9106763e
--- /dev/null
+++ b/odex-event/muk_web_searchpanel/static/description/icon.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/odex-event/muk_web_searchpanel/static/description/index.html b/odex-event/muk_web_searchpanel/static/description/index.html
new file mode 100644
index 000000000..45b4ee928
--- /dev/null
+++ b/odex-event/muk_web_searchpanel/static/description/index.html
@@ -0,0 +1,124 @@
+
+
+
MuK Search Panel
+
Kanban Search Panel
+
MuK IT GmbH -
+ www.mukit.at
+
+
+
+
+
+
+
Overview
+
With Odoo version 13 a new feature is added
+ which allows kanban views to be extended by a search panel. This can
+ be defined via XML and is then automatically added to the view. With
+ this module the function is ported back to version 12.
+
+
\ No newline at end of file
diff --git a/odex-event/muk_web_searchpanel/static/description/logo.png b/odex-event/muk_web_searchpanel/static/description/logo.png
new file mode 100644
index 000000000..9427ce33e
Binary files /dev/null and b/odex-event/muk_web_searchpanel/static/description/logo.png differ
diff --git a/odex-event/muk_web_searchpanel/static/description/preview.png b/odex-event/muk_web_searchpanel/static/description/preview.png
new file mode 100644
index 000000000..1deb1ccef
Binary files /dev/null and b/odex-event/muk_web_searchpanel/static/description/preview.png differ
diff --git a/odex-event/muk_web_searchpanel/static/description/service_customization.png b/odex-event/muk_web_searchpanel/static/description/service_customization.png
new file mode 100644
index 000000000..3eac66488
Binary files /dev/null and b/odex-event/muk_web_searchpanel/static/description/service_customization.png differ
diff --git a/odex-event/muk_web_searchpanel/static/description/service_development.png b/odex-event/muk_web_searchpanel/static/description/service_development.png
new file mode 100644
index 000000000..580d46046
Binary files /dev/null and b/odex-event/muk_web_searchpanel/static/description/service_development.png differ
diff --git a/odex-event/muk_web_searchpanel/static/description/service_implementation.png b/odex-event/muk_web_searchpanel/static/description/service_implementation.png
new file mode 100644
index 000000000..d64b66bda
Binary files /dev/null and b/odex-event/muk_web_searchpanel/static/description/service_implementation.png differ
diff --git a/odex-event/muk_web_searchpanel/static/description/service_integration.png b/odex-event/muk_web_searchpanel/static/description/service_integration.png
new file mode 100644
index 000000000..76c5e80f4
Binary files /dev/null and b/odex-event/muk_web_searchpanel/static/description/service_integration.png differ
diff --git a/odex-event/muk_web_searchpanel/static/description/service_support.png b/odex-event/muk_web_searchpanel/static/description/service_support.png
new file mode 100644
index 000000000..4c530fafd
Binary files /dev/null and b/odex-event/muk_web_searchpanel/static/description/service_support.png differ
diff --git a/odex-event/muk_web_searchpanel/static/src/js/kanban_controller.js b/odex-event/muk_web_searchpanel/static/src/js/kanban_controller.js
new file mode 100644
index 000000000..c4e9a36a7
--- /dev/null
+++ b/odex-event/muk_web_searchpanel/static/src/js/kanban_controller.js
@@ -0,0 +1,80 @@
+/**********************************************************************************
+*
+* Copyright (c) 2017-2019 MuK IT GmbH.
+*
+* This file is part of MuK Search Panel
+* (see https://mukit.at).
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program. If not, see .
+*
+**********************************************************************************/
+
+odoo.define('muk_web_searchpanel.KanbanController', function (require) {
+"use strict";
+
+var core = require('web.core');
+var session = require('web.session');
+var view_dialogs = require('web.view_dialogs');
+var viewUtils = require('web.viewUtils');
+
+var Domain = require('web.Domain');
+var Context = require('web.Context');
+var KanbanController = require('web.KanbanController');
+
+var _t = core._t;
+var QWeb = core.qweb;
+
+KanbanController.include({
+ custom_events: _.extend({}, KanbanController.prototype.custom_events, {
+ search_panel_domain_updated: '_onSearchPanelDomainUpdated',
+ }),
+ init: function (parent, model, renderer, params) {
+ this._super.apply(this, arguments);
+ this._searchPanel = params.searchPanel;
+ this.controlPanelDomain = params.controlPanelDomain || [];
+ this.searchPanelDomain = this._searchPanel ? this._searchPanel.getDomain() : [];
+ },
+ start: function () {
+ if (this._searchPanel) {
+ this.$el.addClass('o_kanban_with_searchpanel');
+ this.$el.prepend(this._searchPanel.$el);
+ }
+ return this._super.apply(this, arguments);
+ },
+ update: function (params) {
+ if (!this._searchPanel) {
+ return this._super.apply(this, arguments);
+ }
+ var self = this;
+ if (params.domain) {
+ this.controlPanelDomain = params.domain;
+ }
+ params.noRender = true;
+ params.domain = this.controlPanelDomain.concat(this.searchPanelDomain);
+ var superProm = this._super.apply(this, arguments);
+ var searchPanelProm = this._updateSearchPanel();
+ return $.when(superProm, searchPanelProm).then(function () {
+ return self.renderer.render();
+ });
+ },
+ _updateSearchPanel: function () {
+ return this._searchPanel.update({searchDomain: this.controlPanelDomain});
+ },
+ _onSearchPanelDomainUpdated: function (ev) {
+ this.searchPanelDomain = ev.data.domain;
+ this.reload({offset: 0});
+ },
+});
+
+});
diff --git a/odex-event/muk_web_searchpanel/static/src/js/kanban_renderer.js b/odex-event/muk_web_searchpanel/static/src/js/kanban_renderer.js
new file mode 100644
index 000000000..6e13cc6f1
--- /dev/null
+++ b/odex-event/muk_web_searchpanel/static/src/js/kanban_renderer.js
@@ -0,0 +1,41 @@
+/**********************************************************************************
+*
+* Copyright (c) 2017-2019 MuK IT GmbH.
+*
+* This file is part of MuK Search Panel
+* (see https://mukit.at).
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program. If not, see .
+*
+**********************************************************************************/
+
+odoo.define('muk_web_searchpanel.KanbanRenderer', function (require) {
+"use strict";
+
+var core = require('web.core');
+var config = require('web.config');
+var session = require('web.session');
+
+var KanbanRenderer = require('web.KanbanRenderer');
+
+var _t = core._t;
+var QWeb = core.qweb;
+
+KanbanRenderer.include({
+ render: function () {
+ return this._render();
+ },
+});
+
+});
diff --git a/odex-event/muk_web_searchpanel/static/src/js/kanban_searchpanel.js b/odex-event/muk_web_searchpanel/static/src/js/kanban_searchpanel.js
new file mode 100644
index 000000000..95b1f78a7
--- /dev/null
+++ b/odex-event/muk_web_searchpanel/static/src/js/kanban_searchpanel.js
@@ -0,0 +1,650 @@
+/**********************************************************************************
+*
+* Copyright (c) 2017-2019 MuK IT GmbH.
+*
+* This file is part of MuK Search Panel
+* (see https://mukit.at).
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program. If not, see .
+*
+**********************************************************************************/
+
+odoo.define('web.SearchPanel', function (require) {
+"use strict";
+
+var core = require('web.core');
+var config = require('web.config');
+var Domain = require('web.Domain');
+var Widget = require('web.Widget');
+
+var qweb = core.qweb;
+
+var SearchPanel = Widget.extend({
+ className: 'o_search_panel',
+ events: {
+ 'click .o_search_panel_category_value header': '_onCategoryValueClicked',
+ 'click .o_search_panel_category_value .o_toggle_fold': '_onToggleFoldCategory',
+ 'click .o_search_panel_filter_group .o_toggle_fold': '_onToggleFoldFilterGroup',
+ 'change .o_search_panel_filter_value > div > input': '_onFilterValueChanged',
+ 'change .o_search_panel_filter_group > div > input': '_onFilterGroupChanged',
+ },
+
+ /**
+ * @override
+ * @param {Object} params
+ * @param {Object} [params.defaultCategoryValues={}] the category value to
+ * activate by default, for each category
+ * @param {Object} params.fields
+ * @param {string} params.model
+ * @param {Object} params.sections
+ * @param {Array[]} params.searchDomain domain coming from controlPanel
+ */
+ init: function (parent, params) {
+ this._super.apply(this, arguments);
+
+ this.categories = _.pick(params.sections, function (section) {
+ return section.type === 'category';
+ });
+ this.filters = _.pick(params.sections, function (section) {
+ return section.type === 'filter';
+ });
+
+ this.defaultCategoryValues = params.defaultCategoryValues || {};
+ this.fields = params.fields;
+ this.model = params.model;
+ this.searchDomain = params.searchDomain;
+
+ this.loadProm = $.Deferred();
+ this.loadPromLazy = true;
+ },
+ willStart: function () {
+ var self = this;
+ var loading = $.Deferred();
+ var loadPromTimer = setTimeout(function () {
+ if(loading.state() !== 'resolved') {
+ loading.resolve();
+ }
+ }, this.loadPromMaxTime || 1000);
+ this._fetchCategories().then(function () {
+ self._fetchFilters().then(function () {
+ if(loading.state() !== 'resolved') {
+ clearTimeout(loadPromTimer);
+ self.loadPromLazy = false;
+ loading.resolve();
+ }
+ self.loadProm.resolve();
+ });
+ });
+ return $.when(loading, this._super.apply(this, arguments));
+ },
+ start: function () {
+ var self = this;
+ if(this.loadProm.state() !== 'resolved') {
+ this.$el.html($("", {
+ 'class': "o_search_panel_loading",
+ 'html': ""
+ }));
+ }
+ this.loadProm.then(function() {
+ self._render();
+ });
+ return this._super.apply(this, arguments);
+ },
+
+ //--------------------------------------------------------------------------
+ // Public
+ //--------------------------------------------------------------------------
+
+ /**
+ * @returns {Array[]} the current searchPanel domain based on active
+ * categories and checked filters
+ */
+ getDomain: function () {
+ return this._getCategoryDomain().concat(this._getFilterDomain());
+ },
+ /**
+ * Reload the filters and re-render. Note that we only reload the filters if
+ * the controlPanel domain or searchPanel domain has changed.
+ *
+ * @param {Object} params
+ * @param {Array[]} params.searchDomain domain coming from controlPanel
+ * @returns {$.Promise}
+ */
+ update: function (params) {
+ if(this.loadProm.state() === 'resolved') {
+ var newSearchDomainStr = JSON.stringify(params.searchDomain);
+ var currentSearchDomainStr = JSON.stringify(this.searchDomain);
+ if (this.needReload || (currentSearchDomainStr !== newSearchDomainStr)) {
+ this.needReload = false;
+ this.searchDomain = params.searchDomain;
+ this._fetchFilters().then(this._render.bind(this));
+ } else {
+ this._render();
+ }
+ }
+ return $.when();
+ },
+
+ //--------------------------------------------------------------------------
+ // Private
+ //--------------------------------------------------------------------------
+
+ /**
+ * @private
+ * @param {string} categoryId
+ * @param {Object[]} values
+ */
+ _createCategoryTree: function (categoryId, values) {
+ var category = this.categories[categoryId];
+ var parentField = category.parentField;
+
+ category.values = {};
+ values.forEach(function (value) {
+ category.values[value.id] = _.extend({}, value, {
+ childrenIds: [],
+ folded: true,
+ parentId: value[parentField] && value[parentField][0] || false,
+ });
+ });
+ Object.keys(category.values).forEach(function (valueId) {
+ var value = category.values[valueId];
+ if (value.parentId && category.values[value.parentId]) {
+ category.values[value.parentId].childrenIds.push(value.id);
+ } else {
+ value.parentId = false;
+ value[parentField] = false;
+ }
+ });
+ category.rootIds = Object.keys(category.values).filter(function (valueId) {
+ var value = category.values[valueId];
+ return value.parentId === false;
+ });
+ category.activeValueId = false;
+
+ if(!this.loadPromLazy) {
+ // set active value
+ var validValues = _.pluck(category.values, 'id').concat([false]);
+ // set active value from context
+ var value = this.defaultCategoryValues[category.fieldName];
+ // if not set in context, or set to an unknown value, set active value
+ // from localStorage
+ if (!_.contains(validValues, value)) {
+ var storageKey = this._getLocalStorageKey(category);
+ value = this.call('local_storage', 'getItem', storageKey);
+ }
+
+ // if not set in localStorage either, select 'All'
+ category.activeValueId = _.contains(validValues, value) ? value : false;
+
+ // unfold ancestor values of active value to make it is visible
+ if (category.activeValueId) {
+ var parentValueIds = this._getAncestorValueIds(category, category.activeValueId);
+ parentValueIds.forEach(function (parentValue) {
+ category.values[parentValue].folded = false;
+ });
+ }
+ }
+ },
+ /**
+ * @private
+ * @param {string} filterId
+ * @param {Object[]} values
+ */
+ _createFilterTree: function (filterId, values) {
+ var filter = this.filters[filterId];
+
+ // restore checked property
+ values.forEach(function (value) {
+ var oldValue = filter.values && filter.values[value.id];
+ value.checked = oldValue && oldValue.checked || false;
+ });
+
+ filter.values = {};
+ var groupIds = [];
+ if (filter.groupBy) {
+ var groups = {};
+ values.forEach(function (value) {
+ var groupId = value.group_id;
+ if (!groups[groupId]) {
+ if (groupId) {
+ groupIds.push(groupId);
+ }
+ groups[groupId] = {
+ folded: false,
+ id: groupId,
+ name: value.group_name,
+ values: {},
+ tooltip: value.group_tooltip,
+ sequence: value.group_sequence,
+ sortedValueIds: [],
+ };
+ // restore former checked and folded state
+ var oldGroup = filter.groups && filter.groups[groupId];
+ groups[groupId].state = oldGroup && oldGroup.state || false;
+ groups[groupId].folded = oldGroup && oldGroup.folded || false;
+ }
+ groups[groupId].values[value.id] = value;
+ groups[groupId].sortedValueIds.push(value.id);
+ });
+ filter.groups = groups;
+ filter.sortedGroupIds = _.sortBy(groupIds, function (groupId) {
+ return groups[groupId].sequence || groups[groupId].name;
+ });
+ Object.keys(filter.groups).forEach(function (groupId) {
+ filter.values = _.extend(filter.values, filter.groups[groupId].values);
+ });
+ } else {
+ values.forEach(function (value) {
+ filter.values[value.id] = value;
+ });
+ filter.sortedValueIds = values.map(function (value) {
+ return value.id;
+ });
+ }
+ },
+ /**
+ * Fetch values for each category. This is done only once, at startup.
+ *
+ * @private
+ * @returns {$.Promise} resolved when all categories have been fetched
+ */
+ _fetchCategories: function () {
+ var self = this;
+ var defs = Object.keys(this.categories).map(function (categoryId) {
+ var category = self.categories[categoryId];
+ var field = self.fields[category.fieldName];
+ var def;
+ if (field.type === 'selection') {
+ var values = field.selection.map(function (value) {
+ return {id: value[0], display_name: value[1]};
+ });
+ def = $.when(values);
+ } else {
+ var categoryDomain = self._getCategoryDomain();
+ var filterDomain = self._getFilterDomain();
+ def = self._rpc({
+ method: 'search_panel_select_range',
+ model: self.model,
+ args: [category.fieldName],
+ kwargs: {
+ category_domain: categoryDomain,
+ filter_domain: filterDomain,
+ search_domain: self.searchDomain,
+ },
+ }, {
+ shadow: true,
+ }).then(function (result) {
+ category.parentField = result.parent_field;
+ return result.values;
+ });
+ }
+ return def.then(function (values) {
+ self._createCategoryTree(categoryId, values);
+ });
+ });
+ return $.when.apply($, defs);
+ },
+ /**
+ * Fetch values for each filter. This is done at startup, and at each reload
+ * (when the controlPanel or searchPanel domain changes).
+ *
+ * @private
+ * @returns {$.Promise} resolved when all filters have been fetched
+ */
+ _fetchFilters: function () {
+ var self = this;
+ var evalContext = {};
+ Object.keys(this.categories).forEach(function (categoryId) {
+ var category = self.categories[categoryId];
+ evalContext[category.fieldName] = category.activeValueId;
+ });
+ var categoryDomain = this._getCategoryDomain();
+ var filterDomain = this._getFilterDomain();
+ var defs = Object.keys(this.filters).map(function (filterId) {
+ var filter = self.filters[filterId];
+ return self._rpc({
+ method: 'search_panel_select_multi_range',
+ model: self.model,
+ args: [filter.fieldName],
+ kwargs: {
+ category_domain: categoryDomain,
+ comodel_domain: Domain.prototype.stringToArray(filter.domain, evalContext),
+ disable_counters: filter.disableCounters,
+ filter_domain: filterDomain,
+ group_by: filter.groupBy || false,
+ search_domain: self.searchDomain,
+ },
+ }, {
+ shadow: true,
+ }).then(function (values) {
+ self._createFilterTree(filterId, values);
+ });
+ });
+ return $.when.apply($, defs);
+ },
+ /**
+ * Compute and return the domain based on the current active categories.
+ *
+ * @private
+ * @returns {Array[]}
+ */
+ _getCategoryDomain: function () {
+ var self = this;
+ function categoryToDomain(domain, categoryId) {
+ var category = self.categories[categoryId];
+ if (category.activeValueId) {
+ domain.push([category.fieldName, '=', category.activeValueId]);
+ } else if(self.loadPromLazy && self.loadProm.state() !== 'resolved') {
+ var value = self.defaultCategoryValues[category.fieldName];
+ if (value) {
+ domain.push([category.fieldName, '=', value]);
+ }
+ }
+ return domain;
+ }
+ return Object.keys(this.categories).reduce(categoryToDomain, []);
+ },
+ /**
+ * Compute and return the domain based on the current checked filters.
+ * The values of a single filter are combined using a simple rule: checked values within
+ * a same group are combined with an 'OR' (this is expressed as single condition using a list)
+ * and groups are combined with an 'AND' (expressed by concatenation of conditions).
+ * If a filter has no groups, its checked values are implicitely considered as forming
+ * a group (and grouped using an 'OR').
+ *
+ * @private
+ * @returns {Array[]}
+ */
+ _getFilterDomain: function () {
+ var self = this;
+ function getCheckedValueIds(values) {
+ return Object.keys(values).reduce(function (checkedValues, valueId) {
+ if (values[valueId].checked) {
+ checkedValues.push(values[valueId].id);
+ }
+ return checkedValues;
+ }, []);
+ }
+ function filterToDomain(domain, filterId) {
+ var filter = self.filters[filterId];
+ if (filter.groups) {
+ Object.keys(filter.groups).forEach(function (groupId) {
+ var group = filter.groups[groupId];
+ var checkedValues = getCheckedValueIds(group.values);
+ if (checkedValues.length) {
+ domain.push([filter.fieldName, 'in', checkedValues]);
+ }
+ });
+ } else if (filter.values) {
+ var checkedValues = getCheckedValueIds(filter.values);
+ if (checkedValues.length) {
+ domain.push([filter.fieldName, 'in', checkedValues]);
+ }
+ }
+ return domain;
+ }
+ return Object.keys(this.filters).reduce(filterToDomain, []);
+ },
+ /**
+ * The active id of each category is stored in the localStorage, s.t. it
+ * can be restored afterwards (when the action is reloaded, for instance).
+ * This function returns the key in the sessionStorage for a given category.
+ *
+ * @param {Object} category
+ * @returns {string}
+ */
+ _getLocalStorageKey: function (category) {
+ return 'searchpanel_' + this.model + '_' + category.fieldName;
+ },
+ /**
+ * @private
+ * @param {Object} category
+ * @param {integer} categoryValueId
+ * @returns {integer[]} list of ids of the ancestors of the given value in
+ * the given category
+ */
+ _getAncestorValueIds: function (category, categoryValueId) {
+ var categoryValue = category.values[categoryValueId];
+ var parentId = categoryValue.parentId;
+ if (parentId) {
+ return [parentId].concat(this._getAncestorValueIds(category, parentId));
+ }
+ return [];
+ },
+ /**
+ * @private
+ */
+ _render: function () {
+ var self = this;
+ this.$el.empty();
+
+ // sort categories and filters according to their index
+ var categories = Object.keys(this.categories).map(function (categoryId) {
+ return self.categories[categoryId];
+ });
+ var filters = Object.keys(this.filters).map(function (filterId) {
+ return self.filters[filterId];
+ });
+ var sections = categories.concat(filters).sort(function (s1, s2) {
+ return s1.index - s2.index;
+ });
+
+ sections.forEach(function (section) {
+ if (Object.keys(section.values).length) {
+ if (section.type === 'category') {
+ self.$el.append(self._renderCategory(section));
+ } else {
+ self.$el.append(self._renderFilter(section));
+ }
+ }
+ });
+ },
+ /**
+ * @private
+ * @param {Object} category
+ * @returns {string}
+ */
+ _renderCategory: function (category) {
+ return qweb.render('SearchPanel.Category', {category: category});
+ },
+ /**
+ * @private
+ * @param {Object} filter
+ * @returns {jQuery}
+ */
+ _renderFilter: function (filter) {
+ var $filter = $(qweb.render('SearchPanel.Filter', {filter: filter}));
+
+ // set group inputs in indeterminate state when necessary
+ Object.keys(filter.groups || {}).forEach(function (groupId) {
+ var state = filter.groups[groupId].state;
+ // group 'false' is not displayed
+ if (groupId !== 'false' && state === 'indeterminate') {
+ $filter
+ .find('.o_search_panel_filter_group[data-group-id=' + groupId + '] input')
+ .get(0)
+ .indeterminate = true;
+ }
+ });
+
+ return $filter;
+ },
+ /**
+ * Compute the current searchPanel domain based on categories and filters,
+ * and notify environment of the domain change.
+ *
+ * Note that this assumes that the environment will update the searchPanel.
+ * This is done as such to ensure the coordination between the reloading of
+ * the searchPanel and the reloading of the data.
+ *
+ * @private
+ */
+ _notifyDomainUpdated: function () {
+ this.needReload = true;
+ this.trigger_up('search_panel_domain_updated', {
+ domain: this.getDomain(),
+ });
+ },
+
+ //--------------------------------------------------------------------------
+ // Handlers
+ //--------------------------------------------------------------------------
+
+ /**
+ * @private
+ * @param {MouseEvent} ev
+ */
+ _onCategoryValueClicked: function (ev) {
+ ev.stopPropagation();
+ var $item = $(ev.currentTarget).closest('.o_search_panel_category_value');
+ var category = this.categories[$item.data('categoryId')];
+ var valueId = $item.data('id') || false;
+ category.activeValueId = valueId;
+ var storageKey = this._getLocalStorageKey(category);
+ this.call('local_storage', 'setItem', storageKey, valueId);
+ this._notifyDomainUpdated();
+ },
+ /**
+ * @private
+ * @param {MouseEvent} ev
+ */
+ _onFilterGroupChanged: function (ev) {
+ ev.stopPropagation();
+ var $item = $(ev.target).closest('.o_search_panel_filter_group');
+ var filter = this.filters[$item.data('filterId')];
+ var groupId = $item.data('groupId');
+ var group = filter.groups[groupId];
+ group.state = group.state === 'checked' ? 'unchecked' : 'checked';
+ Object.keys(group.values).forEach(function (valueId) {
+ group.values[valueId].checked = group.state === 'checked';
+ });
+ this._notifyDomainUpdated();
+ },
+ /**
+ * @private
+ * @param {MouseEvent} ev
+ */
+ _onFilterValueChanged: function (ev) {
+ ev.stopPropagation();
+ var $item = $(ev.target).closest('.o_search_panel_filter_value');
+ var valueId = $item.data('valueId');
+ var filter = this.filters[$item.data('filterId')];
+ var value = filter.values[valueId];
+ value.checked = !value.checked;
+ var group = filter.groups && filter.groups[value.group_id];
+ if (group) {
+ var valuePartition = _.partition(Object.keys(group.values), function (valueId) {
+ return group.values[valueId].checked;
+ });
+ if (valuePartition[0].length && valuePartition[1].length) {
+ group.state = 'indeterminate';
+ } else if (valuePartition[0].length) {
+ group.state = 'checked';
+ } else {
+ group.state = 'unchecked';
+ }
+ }
+ this._notifyDomainUpdated();
+ },
+ /**
+ * @private
+ * @param {MouseEvent} ev
+ */
+ _onToggleFoldCategory: function (ev) {
+ ev.preventDefault();
+ ev.stopPropagation();
+ var $item = $(ev.currentTarget).closest('.o_search_panel_category_value');
+ var category = this.categories[$item.data('categoryId')];
+ var valueId = $item.data('id');
+ category.values[valueId].folded = !category.values[valueId].folded;
+ this._render();
+ },
+ /**
+ * @private
+ * @param {MouseEvent} ev
+ */
+ _onToggleFoldFilterGroup: function (ev) {
+ ev.preventDefault();
+ ev.stopPropagation();
+ var $item = $(ev.currentTarget).closest('.o_search_panel_filter_group');
+ var filter = this.filters[$item.data('filterId')];
+ var groupId = $item.data('groupId');
+ filter.groups[groupId].folded = !filter.groups[groupId].folded;
+ this._render();
+ },
+});
+
+if (config.device.isMobile) {
+ SearchPanel.include({
+ tagName: 'details',
+
+ _getCategorySelection: function () {
+ var self = this;
+ return Object.keys(this.categories).reduce(function (selection, categoryId) {
+ var category = self.categories[categoryId];
+ console.log('category', category);
+ if (category.activeValueId) {
+ var ancestorIds = [category.activeValueId].concat(self._getAncestorValueIds(category, category.activeValueId));
+ var breadcrumb = ancestorIds.map(function (valueId) {
+ return category.values[valueId].display_name;
+ });
+ selection.push({ breadcrumb: breadcrumb, icon: category.icon, color: category.color});
+ }
+ console.log('selection', selection);
+ return selection;
+ }, []);
+ },
+
+ _getFilterSelection: function () {
+ var self = this;
+ return Object.keys(this.filters).reduce(function (selection, filterId) {
+ var filter = self.filters[filterId];
+ console.log('filter', filter);
+ if (filter.groups) {
+ Object.keys(filter.groups).forEach(function (groupId) {
+ var group = filter.groups[groupId];
+ Object.keys(group.values).forEach(function (valueId) {
+ var value = group.values[valueId];
+ if (value.checked) {
+ selection.push({name: value.name, icon: filter.icon, color: filter.color});
+ }
+ });
+ });
+ } else if (filter.values) {
+ Object.keys(filter.values).forEach(function (valueId) {
+ var value = filter.values[valueId];
+ if (value.checked) {
+ selection.push({name: value.name, icon: filter.icon, color: filter.color});
+ }
+ });
+ }
+ console.log('selection', selection);
+ return selection;
+ }, []);
+ },
+
+ _render: function () {
+ this._super.apply(this, arguments);
+ this.$el.prepend(qweb.render('SearchPanel.MobileSummary', {
+ categories: this._getCategorySelection(),
+ filterValues: this._getFilterSelection(),
+ separator: ' / ',
+ }));
+ },
+ });
+}
+
+return SearchPanel;
+
+});
\ No newline at end of file
diff --git a/odex-event/muk_web_searchpanel/static/src/js/kanban_view.js b/odex-event/muk_web_searchpanel/static/src/js/kanban_view.js
new file mode 100644
index 000000000..17705c612
--- /dev/null
+++ b/odex-event/muk_web_searchpanel/static/src/js/kanban_view.js
@@ -0,0 +1,133 @@
+/**********************************************************************************
+*
+* Copyright (c) 2017-2019 MuK IT GmbH.
+*
+* This file is part of MuK Search Panel
+* (see https://mukit.at).
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program. If not, see .
+*
+**********************************************************************************/
+
+odoo.define('muk_web_searchpanel.KanbanView', function (require) {
+"use strict";
+
+var core = require('web.core');
+var config = require('web.config');
+var pyUtils = require('web.py_utils');
+var utils = require('web.utils');
+
+var KanbanView = require('web.KanbanView');
+var SearchPanel = require('web.SearchPanel');
+
+var _t = core._t;
+var QWeb = core.qweb;
+
+KanbanView.include({
+ config: _.extend({}, KanbanView.prototype.config, {
+ SearchPanel: SearchPanel,
+ }),
+ init: function (viewInfo, params) {
+ this.searchPanelSections = Object.create(null);
+ this._super.apply(this, arguments);
+ this.hasSearchPanel = !_.isEmpty(this.searchPanelSections);
+
+ },
+ getController: function (parent) {
+ var self = this;
+ var def = undefined;
+ if (this.hasSearchPanel) {
+ def = this._createSearchPanel(parent);
+ }
+ var _super = this._super.bind(this);
+ return $.when(def).then(function (searchPanel) {
+ return _super(parent).done(function (controller) {
+ if (self.hasSearchPanel) {
+ self.controllerParams.searchPanel.setParent(controller);
+ }
+ return controller
+ });
+ });
+ },
+ _createSearchPanel: function (parent) {
+ var self = this;
+ var defaultCategoryValues = {};
+ Object.keys(this.loadParams.context).forEach(function (key) {
+ var match = /^searchpanel_default_(.*)$/.exec(key);
+ if (match) {
+ defaultCategoryValues[match[1]] = self.loadParams.context[key];
+ }
+ });
+ var controlPanelDomain = this.loadParams.domain;
+ var searchPanel = new this.config.SearchPanel(parent, {
+ defaultCategoryValues: defaultCategoryValues,
+ fields: this.fields,
+ model: this.loadParams.modelName,
+ searchDomain: controlPanelDomain,
+ sections: this.searchPanelSections,
+ });
+ this.controllerParams.searchPanel = searchPanel;
+ this.controllerParams.controlPanelDomain = controlPanelDomain;
+ return searchPanel.appendTo(document.createDocumentFragment()).then(function () {
+ var searchPanelDomain = searchPanel.getDomain();
+ self.loadParams.domain = controlPanelDomain.concat(searchPanelDomain);
+ });
+ },
+ _processNode: function (node, fv) {
+ if (node.tag === 'searchpanel') {
+// if (!config.device.isMobile) {
+// this._processSearchPanelNode(node, fv);
+// }
+ this._processSearchPanelNode(node, fv);
+ return false;
+ }
+ return this._super.apply(this, arguments);
+ },
+ _processSearchPanelNode: function (node, fv) {
+ var self = this;
+ node.children.forEach(function (childNode, index) {
+ if (childNode.tag !== 'field') {
+ return;
+ }
+ if (childNode.attrs.invisible === "1") {
+ return;
+ }
+ var fieldName = childNode.attrs.name;
+ var type = childNode.attrs.select === 'multi' ? 'filter' : 'category';
+
+ var sectionId = _.uniqueId('section_');
+ var section = {
+ color: childNode.attrs.color,
+ description: childNode.attrs.string || fv.fields[fieldName].string,
+ fieldName: fieldName,
+ icon: childNode.attrs.icon,
+ id: sectionId,
+ index: index,
+ type: type,
+ };
+ if (section.type === 'category') {
+ section.icon = section.icon || 'fa-folder';
+ } else if (section.type === 'filter') {
+ section.disableCounters = !!pyUtils.py_eval(childNode.attrs.disable_counters || '0');
+ section.domain = childNode.attrs.domain || '[]';
+ section.groupBy = childNode.attrs.groupby;
+ section.icon = section.icon || 'fa-filter';
+ }
+ self.searchPanelSections[sectionId] = section;
+ });
+ },
+});
+
+
+});
diff --git a/odex-event/muk_web_searchpanel/static/src/scss/kanban_view.scss b/odex-event/muk_web_searchpanel/static/src/scss/kanban_view.scss
new file mode 100644
index 000000000..6c2495a90
--- /dev/null
+++ b/odex-event/muk_web_searchpanel/static/src/scss/kanban_view.scss
@@ -0,0 +1,173 @@
+/**********************************************************************************
+*
+* Copyright (c) 2017-2019 MuK IT GmbH.
+*
+* This file is part of MuK Search Panel
+* (see https://mukit.at).
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program. If not, see .
+*
+**********************************************************************************/
+
+.o_kanban_with_searchpanel {
+ display: flex;
+ flex-flow: row wrap;
+ align-items: flex-start;
+
+ .o_onboarding_container {
+ flex: 1 1 100%;
+ }
+ .o_kanban_view {
+ flex: 1 1 calc(100% - #{$o-searchpanel-w});
+ overflow: auto;
+ max-height: 100%;
+ }
+ .o_search_panel {
+ flex: 0 0 $o-searchpanel-w;
+ overflow: auto;
+ height: 100%;
+ padding: $o-searchpanel-p-small $o-searchpanel-p-small $o-searchpanel-p*2 $o-searchpanel-p;
+ border-right: 1px solid $gray-300;
+ background-color: white;
+ position: relative;
+
+ .o_search_panel_loading {
+ position: absolute;
+ margin-top: -30px;
+ margin-left: -30px;
+ margin-bottom: 0;
+ margin-right: 0;
+ font-size: 60px;
+ height: 60px;
+ width: 60px;
+ left: 50%;
+ top: 50%;
+ }
+
+ .o_search_panel_category .o_search_panel_section_icon {
+ color: $o-searchpanel-category-default-color;
+ }
+ .o_search_panel_filter .o_search_panel_section_icon {
+ color: $o-searchpanel-filter-default-color;
+ }
+
+ .o_search_panel_label {
+ cursor: pointer;
+ user-select: none;
+
+ .o_toggle_fold {
+ padding: 3px;
+ }
+ }
+ .o_search_panel_section_header {
+ padding: $o-searchpanel-p-small 0;
+ }
+ .list-group-item {
+ padding: 0 0 $o-searchpanel-p-small 0;
+
+ .list-group-item {
+ padding: 0 0 0 $custom-control-gutter;
+ margin-bottom: $o-searchpanel-p-tiny*0.5;
+ &:first-child {
+ margin-top: $o-searchpanel-p-tiny*0.5;
+ }
+ }
+ span.o_search_panel_label_title {
+ color: $headings-color;
+ @include o-text-overflow(inline-block, calc(100% - 22px));
+ }
+ header.active {
+ background-color: $list-group-action-active-bg;
+ }
+ }
+ .o_search_panel_category_value {
+ header {
+ margin-left: -$o-searchpanel-p-tiny;
+ padding-left: $o-searchpanel-p-tiny;
+ }
+ .o_search_panel_category_value {
+ position: relative;
+ padding-left: $o-searchpanel-p;
+ padding-bottom: $o-searchpanel-p-tiny;
+ margin-bottom: 0;
+
+ &:before, &:after {
+ @include o-position-absolute(0, $left: $o-searchpanel-p-tiny)
+ @include size(1px, 100%);
+ background: $gray-500;
+ content: '';
+ }
+ &:after {
+ top: 10px;
+ @include size(8px, 1px);
+ }
+ &:last-child {
+ &:before {
+ height: 11px;
+ }
+ &:after {
+ top: 11px;
+ }
+ }
+ }
+ }
+ }
+}
+
+@include media-breakpoint-down(sm) {
+ .o_kanban_with_searchpanel {
+ flex-direction: column;
+
+ .o_onboarding_container {
+ display: none;
+ }
+
+ details.o_search_panel {
+ flex-basis: auto;
+ height: auto;
+ width: 100%;
+ padding: 0;
+
+ > summary {
+ padding: $o-searchpanel-p-small;
+ // Hide the caret. For details see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/summary
+ list-style-type: none;
+ &::-webkit-details-marker {
+ display: none
+ }
+
+ .badge {
+ font-size: 100%;
+ background-color: white;
+ }
+ }
+
+ > .o_search_panel_section {
+ margin: 0 $o-searchpanel-p-small 0 $o-searchpanel-p;
+ }
+
+ &[open] {
+ z-index: $zindex-dropdown;
+
+ > summary {
+ background-color: $list-group-action-active-bg;
+ }
+
+ .fa-chevron-left:before {
+ content: "\f078";
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/odex-event/muk_web_searchpanel/static/src/scss/variables.scss b/odex-event/muk_web_searchpanel/static/src/scss/variables.scss
new file mode 100644
index 000000000..c4d2259a6
--- /dev/null
+++ b/odex-event/muk_web_searchpanel/static/src/scss/variables.scss
@@ -0,0 +1,30 @@
+/**********************************************************************************
+*
+* Copyright (c) 2017-2019 MuK IT GmbH.
+*
+* This file is part of MuK Search Panel
+* (see https://mukit.at).
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program. If not, see .
+*
+**********************************************************************************/
+
+$o-searchpanel-w: 220px;
+
+$o-searchpanel-p: $o-horizontal-padding;
+$o-searchpanel-p-small: $o-horizontal-padding*0.5;
+$o-searchpanel-p-tiny: $o-searchpanel-p-small*0.5;
+
+$o-searchpanel-category-default-color: $o-brand-primary;
+$o-searchpanel-filter-default-color: $o-brand-odoo;
\ No newline at end of file
diff --git a/odex-event/muk_web_searchpanel/static/src/xml/kanban.xml b/odex-event/muk_web_searchpanel/static/src/xml/kanban.xml
new file mode 100644
index 000000000..6dd8110ce
--- /dev/null
+++ b/odex-event/muk_web_searchpanel/static/src/xml/kanban.xml
@@ -0,0 +1,149 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Filters...
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/odex-event/muk_web_searchpanel/template/assets.xml b/odex-event/muk_web_searchpanel/template/assets.xml
new file mode 100644
index 000000000..255e47971
--- /dev/null
+++ b/odex-event/muk_web_searchpanel/template/assets.xml
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/odex-event/muk_web_utils/LICENSE b/odex-event/muk_web_utils/LICENSE
new file mode 100644
index 000000000..153d416dc
--- /dev/null
+++ b/odex-event/muk_web_utils/LICENSE
@@ -0,0 +1,165 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+
+ This version of the GNU Lesser General Public License incorporates
+the terms and conditions of version 3 of the GNU General Public
+License, supplemented by the additional permissions listed below.
+
+ 0. Additional Definitions.
+
+ As used herein, "this License" refers to version 3 of the GNU Lesser
+General Public License, and the "GNU GPL" refers to version 3 of the GNU
+General Public License.
+
+ "The Library" refers to a covered work governed by this License,
+other than an Application or a Combined Work as defined below.
+
+ An "Application" is any work that makes use of an interface provided
+by the Library, but which is not otherwise based on the Library.
+Defining a subclass of a class defined by the Library is deemed a mode
+of using an interface provided by the Library.
+
+ A "Combined Work" is a work produced by combining or linking an
+Application with the Library. The particular version of the Library
+with which the Combined Work was made is also called the "Linked
+Version".
+
+ The "Minimal Corresponding Source" for a Combined Work means the
+Corresponding Source for the Combined Work, excluding any source code
+for portions of the Combined Work that, considered in isolation, are
+based on the Application, and not on the Linked Version.
+
+ The "Corresponding Application Code" for a Combined Work means the
+object code and/or source code for the Application, including any data
+and utility programs needed for reproducing the Combined Work from the
+Application, but excluding the System Libraries of the Combined Work.
+
+ 1. Exception to Section 3 of the GNU GPL.
+
+ You may convey a covered work under sections 3 and 4 of this License
+without being bound by section 3 of the GNU GPL.
+
+ 2. Conveying Modified Versions.
+
+ If you modify a copy of the Library, and, in your modifications, a
+facility refers to a function or data to be supplied by an Application
+that uses the facility (other than as an argument passed when the
+facility is invoked), then you may convey a copy of the modified
+version:
+
+ a) under this License, provided that you make a good faith effort to
+ ensure that, in the event an Application does not supply the
+ function or data, the facility still operates, and performs
+ whatever part of its purpose remains meaningful, or
+
+ b) under the GNU GPL, with none of the additional permissions of
+ this License applicable to that copy.
+
+ 3. Object Code Incorporating Material from Library Header Files.
+
+ The object code form of an Application may incorporate material from
+a header file that is part of the Library. You may convey such object
+code under terms of your choice, provided that, if the incorporated
+material is not limited to numerical parameters, data structure
+layouts and accessors, or small macros, inline functions and templates
+(ten or fewer lines in length), you do both of the following:
+
+ a) Give prominent notice with each copy of the object code that the
+ Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the object code with a copy of the GNU GPL and this license
+ document.
+
+ 4. Combined Works.
+
+ You may convey a Combined Work under terms of your choice that,
+taken together, effectively do not restrict modification of the
+portions of the Library contained in the Combined Work and reverse
+engineering for debugging such modifications, if you also do each of
+the following:
+
+ a) Give prominent notice with each copy of the Combined Work that
+ the Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the Combined Work with a copy of the GNU GPL and this license
+ document.
+
+ c) For a Combined Work that displays copyright notices during
+ execution, include the copyright notice for the Library among
+ these notices, as well as a reference directing the user to the
+ copies of the GNU GPL and this license document.
+
+ d) Do one of the following:
+
+ 0) Convey the Minimal Corresponding Source under the terms of this
+ License, and the Corresponding Application Code in a form
+ suitable for, and under terms that permit, the user to
+ recombine or relink the Application with a modified version of
+ the Linked Version to produce a modified Combined Work, in the
+ manner specified by section 6 of the GNU GPL for conveying
+ Corresponding Source.
+
+ 1) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (a) uses at run time
+ a copy of the Library already present on the user's computer
+ system, and (b) will operate properly with a modified version
+ of the Library that is interface-compatible with the Linked
+ Version.
+
+ e) Provide Installation Information, but only if you would otherwise
+ be required to provide such information under section 6 of the
+ GNU GPL, and only to the extent that such information is
+ necessary to install and execute a modified version of the
+ Combined Work produced by recombining or relinking the
+ Application with a modified version of the Linked Version. (If
+ you use option 4d0, the Installation Information must accompany
+ the Minimal Corresponding Source and Corresponding Application
+ Code. If you use option 4d1, you must provide the Installation
+ Information in the manner specified by section 6 of the GNU GPL
+ for conveying Corresponding Source.)
+
+ 5. Combined Libraries.
+
+ You may place library facilities that are a work based on the
+Library side by side in a single library together with other library
+facilities that are not Applications and are not covered by this
+License, and convey such a combined library under terms of your
+choice, if you do both of the following:
+
+ a) Accompany the combined library with a copy of the same work based
+ on the Library, uncombined with any other library facilities,
+ conveyed under the terms of this License.
+
+ b) Give prominent notice with the combined library that part of it
+ is a work based on the Library, and explaining where to find the
+ accompanying uncombined form of the same work.
+
+ 6. Revised Versions of the GNU Lesser General Public License.
+
+ The Free Software Foundation may publish revised and/or new versions
+of the GNU Lesser General Public License from time to time. Such new
+versions will be similar in spirit to the present version, but may
+differ in detail to address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Library as you received it specifies that a certain numbered version
+of the GNU Lesser General Public License "or any later version"
+applies to it, you have the option of following the terms and
+conditions either of that published version or of any later version
+published by the Free Software Foundation. If the Library as you
+received it does not specify a version number of the GNU Lesser
+General Public License, you may choose any version of the GNU Lesser
+General Public License ever published by the Free Software Foundation.
+
+ If the Library as you received it specifies that a proxy can decide
+whether future versions of the GNU Lesser General Public License shall
+apply, that proxy's public statement of acceptance of any version is
+permanent authorization for you to choose that version for the
+Library.
\ No newline at end of file
diff --git a/odex-event/muk_web_utils/README.rst b/odex-event/muk_web_utils/README.rst
new file mode 100644
index 000000000..1d9ac5771
--- /dev/null
+++ b/odex-event/muk_web_utils/README.rst
@@ -0,0 +1,113 @@
+=============
+MuK Web Utils
+=============
+
+Technical module to provide some utility features and libraries that can be used
+in other applications. This module has no direct effect on the running system.
+
+Installation
+============
+
+To install this module, you need to:
+
+Download the module and add it to your Odoo addons folder. Afterward, log on to
+your Odoo server and go to the Apps menu. Trigger the debug mode and update the
+list by clicking on the "Update Apps List" link. Now install the module by
+clicking on the install button.
+
+Another way to install this module is via the package management for Python
+(`PyPI `_).
+
+To install our modules using the package manager make sure
+`odoo-autodiscover `_ is installed
+correctly. Then open a console and install the module by entering the following
+command:
+
+``pip install --extra-index-url https://nexus.mukit.at/repository/odoo/simple ``
+
+The module name consists of the Odoo version and the module name, where
+underscores are replaced by a dash.
+
+**Module:**
+
+``odoo-addon-``
+
+**Example:**
+
+``sudo -H pip3 install --extra-index-url https://nexus.mukit.at/repository/odoo/simple odoo11-addon-muk-utils``
+
+Once the installation has been successfully completed, the app is already in the
+correct folder. Log on to your Odoo server and go to the Apps menu. Trigger the
+debug mode and update the list by clicking on the "Update Apps List" link. Now
+install the module by clicking on the install button.
+
+The biggest advantage of this variant is that you can now also update the app
+using the "pip" command. To do this, enter the following command in your console:
+
+``pip install --upgrade --extra-index-url https://nexus.mukit.at/repository/odoo/simple ``
+
+When the process is finished, restart your server and update the application in
+Odoo. The steps are the same as for the installation only the button has changed
+from "Install" to "Upgrade".
+
+You can also view available Apps directly in our `repository `_
+and find a more detailed installation guide on our `website `_.
+
+For modules licensed under OPL-1, you will receive access data when you purchase
+the module. If the modules were not purchased directly from
+`MuK IT `_ please contact our support (support@mukit.at)
+with a confirmation of purchase to receive the corresponding access data.
+
+Upgrade
+============
+
+To upgrade this module, you need to:
+
+Download the module and add it to your Odoo addons folder. Restart the server
+and log on to your Odoo server. Select the Apps menu and upgrade the module by
+clicking on the upgrade button.
+
+If you installed the module using the "pip" command, you can also update the
+module in the same way. Just type the following command into the console:
+
+``pip install --upgrade --extra-index-url https://nexus.mukit.at/repository/odoo/simple ``
+
+When the process is finished, restart your server and update the application in
+Odoo, just like you would normally.
+
+Configuration
+=============
+
+No additional configuration is needed to use this module.
+
+Usage
+=============
+
+This module has no direct visible effect on the system. It provide utility features.
+
+Credits
+=======
+
+Contributors
+------------
+
+* Mathias Markl
+
+Images
+------------
+
+Some pictures are based on or inspired by the icon set of Font Awesome:
+
+* `Font Awesome `_
+
+Author & Maintainer
+-------------------
+
+This module is maintained by the `MuK IT GmbH `_.
+
+MuK IT is an Austrian company specialized in customizing and extending Odoo.
+We develop custom solutions for your individual needs to help you focus on
+your strength and expertise to grow your business.
+
+If you want to get in touch please contact us via mail
+(sale@mukit.at) or visit our website (https://mukit.at).
diff --git a/odex-event/muk_web_utils/__init__.py b/odex-event/muk_web_utils/__init__.py
new file mode 100644
index 000000000..bbab24ae8
--- /dev/null
+++ b/odex-event/muk_web_utils/__init__.py
@@ -0,0 +1,24 @@
+###################################################################################
+#
+# Copyright (c) 2017-2019 MuK IT GmbH.
+#
+# This file is part of MuK Web Utils
+# (see https://mukit.at).
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see .
+#
+###################################################################################
+
+from . import models
+from . import controllers
\ No newline at end of file
diff --git a/odex-event/muk_web_utils/__manifest__.py b/odex-event/muk_web_utils/__manifest__.py
new file mode 100644
index 000000000..54149357e
--- /dev/null
+++ b/odex-event/muk_web_utils/__manifest__.py
@@ -0,0 +1,57 @@
+###################################################################################
+#
+# Copyright (c) 2017-2019 MuK IT GmbH.
+#
+# This file is part of MuK Web Utils
+# (see https://mukit.at).
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see .
+#
+###################################################################################
+
+{
+ "name": "MuK Web Utils",
+ "summary": """Utility Features""",
+ "version": "12.0.3.0.5",
+ "category": "Extra Tools",
+ "license": "LGPL-3",
+ "author": "MuK IT",
+ "website": "http://www.mukit.at",
+ 'live_test_url': 'https://mukit.at/r/SgN',
+ "contributors": [
+ "Mathias Markl ",
+ ],
+ "depends": [
+ "web_editor",
+ "muk_autovacuum",
+ ],
+ "data": [
+ "template/assets.xml",
+ "views/res_config_settings_view.xml",
+ "data/autovacuum.xml",
+ ],
+ "qweb": [
+ "static/src/xml/*.xml",
+ ],
+ "images": [
+ 'static/description/banner.png'
+ ],
+ "external_dependencies": {
+ "python": [],
+ "bin": [],
+ },
+ "application": False,
+ "installable": True,
+ 'auto_install': False,
+}
diff --git a/odex-event/muk_web_utils/controllers/__init__.py b/odex-event/muk_web_utils/controllers/__init__.py
new file mode 100644
index 000000000..5caf3fa18
--- /dev/null
+++ b/odex-event/muk_web_utils/controllers/__init__.py
@@ -0,0 +1,24 @@
+###################################################################################
+#
+# Copyright (c) 2017-2019 MuK IT GmbH.
+#
+# This file is part of MuK Web Utils
+# (see https://mukit.at).
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see .
+#
+###################################################################################
+
+from . import backend
+from . import attachment
diff --git a/odex-event/muk_web_utils/controllers/attachment.py b/odex-event/muk_web_utils/controllers/attachment.py
new file mode 100644
index 000000000..e951353da
--- /dev/null
+++ b/odex-event/muk_web_utils/controllers/attachment.py
@@ -0,0 +1,56 @@
+###################################################################################
+#
+# Copyright (c) 2017-2019 MuK IT GmbH.
+#
+# This file is part of MuK Web Utils
+# (see https://mukit.at).
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see .
+#
+###################################################################################
+
+import json
+import base64
+import logging
+
+from odoo import http
+from odoo.http import request
+from odoo.tools.misc import str2bool
+
+_logger = logging.getLogger(__name__)
+
+class AttachmentController(http.Controller):
+
+ @http.route('/utils/attachment/add', type='http', auth="user", methods=['POST'])
+ def add_attachment(self, ufile, temporary=False, **kw):
+ tmp = temporary and str2bool(temporary) or False
+ name = "Access Attachment: %s" % ufile.filename
+ attachment = request.env['ir.attachment'].create({
+ 'name': tmp and "%s (Temporary)" % name or name,
+ 'datas': base64.b64encode(ufile.read()),
+ 'datas_fname': ufile.filename,
+ 'type': 'binary',
+ 'public': False,
+ 'temporary': tmp,
+ })
+ attachment.generate_access_token()
+ if ufile.mimetype and ufile.mimetype != 'application/octet-stream':
+ attachment.sudo().write({
+ 'mimetype': ufile.mimetype,
+ })
+ base_url = request.env['ir.config_parameter'].sudo().get_param('web.base.url')
+ result = attachment.read(['name', 'datas_fname', 'mimetype', 'checksum', 'access_token'])[0]
+ result['url'] = '%s/web/content/%s?access_token=%s' % (base_url, attachment.id, attachment.access_token)
+ return json.dumps(result)
+
\ No newline at end of file
diff --git a/odex-event/muk_web_utils/controllers/backend.py b/odex-event/muk_web_utils/controllers/backend.py
new file mode 100644
index 000000000..80a9fec70
--- /dev/null
+++ b/odex-event/muk_web_utils/controllers/backend.py
@@ -0,0 +1,37 @@
+###################################################################################
+#
+# Copyright (c) 2017-2019 MuK IT GmbH.
+#
+# This file is part of MuK Web Utils
+# (see https://mukit.at).
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see .
+#
+###################################################################################
+
+import logging
+
+from odoo import http
+from odoo.http import request
+
+_logger = logging.getLogger(__name__)
+
+class BackendController(http.Controller):
+
+ @http.route('/config/muk_web_utils.binary_max_size', type='json', auth="user")
+ def max_upload_size(self, **kw):
+ params = request.env['ir.config_parameter'].sudo()
+ return {
+ 'max_upload_size': int(params.get_param('muk_web_utils.binary_max_size', default=25))
+ }
\ No newline at end of file
diff --git a/odex-event/muk_web_utils/data/autovacuum.xml b/odex-event/muk_web_utils/data/autovacuum.xml
new file mode 100644
index 000000000..c3c3f2289
--- /dev/null
+++ b/odex-event/muk_web_utils/data/autovacuum.xml
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+ Delete temporary Attachments
+
+
+ domain
+ [('temporary','=',True), ('create_date', '<=', (datetime.datetime.utcnow() - datetime.timedelta(hours=24)).strftime('%Y-%m-%d %H:%M:%S'))]
+
+
+
+
\ No newline at end of file
diff --git a/odex-event/muk_web_utils/doc/changelog.rst b/odex-event/muk_web_utils/doc/changelog.rst
new file mode 100644
index 000000000..faf2ed65a
--- /dev/null
+++ b/odex-event/muk_web_utils/doc/changelog.rst
@@ -0,0 +1,54 @@
+`2.9.0`
+-------
+
+- Temporary attachments
+
+`2.8.0`
+-------
+
+- Added path field widgets
+
+`2.7.0`
+-------
+
+- Added color index field widget
+
+`2.6.0`
+-------
+
+- Moved editor features to separate module
+
+`2.5.0`
+-------
+
+- Added color field widget
+
+`2.4.0`
+-------
+
+- Added widget to share binary fields
+
+`2.3.0`
+-------
+
+- Added custom colors to snippet options
+
+`2.2.0`
+-------
+
+- Added widget to share text fields
+
+`2.1.0`
+-------
+
+- Automatic labels on settings
+
+`2.0.0`
+-------
+
+- Migrated to Python 3
+
+`1.0.0`
+-------
+
+- Init version
diff --git a/odex-event/muk_web_utils/doc/index.rst b/odex-event/muk_web_utils/doc/index.rst
new file mode 100644
index 000000000..1d9ac5771
--- /dev/null
+++ b/odex-event/muk_web_utils/doc/index.rst
@@ -0,0 +1,113 @@
+=============
+MuK Web Utils
+=============
+
+Technical module to provide some utility features and libraries that can be used
+in other applications. This module has no direct effect on the running system.
+
+Installation
+============
+
+To install this module, you need to:
+
+Download the module and add it to your Odoo addons folder. Afterward, log on to
+your Odoo server and go to the Apps menu. Trigger the debug mode and update the
+list by clicking on the "Update Apps List" link. Now install the module by
+clicking on the install button.
+
+Another way to install this module is via the package management for Python
+(`PyPI `_).
+
+To install our modules using the package manager make sure
+`odoo-autodiscover `_ is installed
+correctly. Then open a console and install the module by entering the following
+command:
+
+``pip install --extra-index-url https://nexus.mukit.at/repository/odoo/simple ``
+
+The module name consists of the Odoo version and the module name, where
+underscores are replaced by a dash.
+
+**Module:**
+
+``odoo-addon-``
+
+**Example:**
+
+``sudo -H pip3 install --extra-index-url https://nexus.mukit.at/repository/odoo/simple odoo11-addon-muk-utils``
+
+Once the installation has been successfully completed, the app is already in the
+correct folder. Log on to your Odoo server and go to the Apps menu. Trigger the
+debug mode and update the list by clicking on the "Update Apps List" link. Now
+install the module by clicking on the install button.
+
+The biggest advantage of this variant is that you can now also update the app
+using the "pip" command. To do this, enter the following command in your console:
+
+``pip install --upgrade --extra-index-url https://nexus.mukit.at/repository/odoo/simple ``
+
+When the process is finished, restart your server and update the application in
+Odoo. The steps are the same as for the installation only the button has changed
+from "Install" to "Upgrade".
+
+You can also view available Apps directly in our `repository `_
+and find a more detailed installation guide on our `website `_.
+
+For modules licensed under OPL-1, you will receive access data when you purchase
+the module. If the modules were not purchased directly from
+`MuK IT `_ please contact our support (support@mukit.at)
+with a confirmation of purchase to receive the corresponding access data.
+
+Upgrade
+============
+
+To upgrade this module, you need to:
+
+Download the module and add it to your Odoo addons folder. Restart the server
+and log on to your Odoo server. Select the Apps menu and upgrade the module by
+clicking on the upgrade button.
+
+If you installed the module using the "pip" command, you can also update the
+module in the same way. Just type the following command into the console:
+
+``pip install --upgrade --extra-index-url https://nexus.mukit.at/repository/odoo/simple ``
+
+When the process is finished, restart your server and update the application in
+Odoo, just like you would normally.
+
+Configuration
+=============
+
+No additional configuration is needed to use this module.
+
+Usage
+=============
+
+This module has no direct visible effect on the system. It provide utility features.
+
+Credits
+=======
+
+Contributors
+------------
+
+* Mathias Markl
+
+Images
+------------
+
+Some pictures are based on or inspired by the icon set of Font Awesome:
+
+* `Font Awesome `_
+
+Author & Maintainer
+-------------------
+
+This module is maintained by the `MuK IT GmbH `_.
+
+MuK IT is an Austrian company specialized in customizing and extending Odoo.
+We develop custom solutions for your individual needs to help you focus on
+your strength and expertise to grow your business.
+
+If you want to get in touch please contact us via mail
+(sale@mukit.at) or visit our website (https://mukit.at).
diff --git a/odex-event/muk_web_utils/i18n/de.po b/odex-event/muk_web_utils/i18n/de.po
new file mode 100644
index 000000000..9b8953280
--- /dev/null
+++ b/odex-event/muk_web_utils/i18n/de.po
@@ -0,0 +1,340 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * muk_web_utils
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 12.0-20190128\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2019-02-27 09:28+0000\n"
+"PO-Revision-Date: 2019-06-27 08:23+0000\n"
+"Last-Translator: MuK IT \n"
+"Language-Team: German \n"
+"Language: de\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+"X-Generator: Weblate 3.7\n"
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/js/fields/color.js:113
+#, python-format
+msgid "'%s' is not a correct color index (0-12)"
+msgstr "%s' ist kein korrekter Farbindex (0-12)."
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/js/fields/color.js:68
+#, python-format
+msgid "'%s' is not a correct color value"
+msgstr "%s' ist kein korrekter Farbwert."
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/js/fields/share.js:175
+#, python-format
+msgid "<%= name %> shared a file!"
+msgstr "<%= name %> teilte eine Datei!"
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/js/fields/share.js:115
+#: code:addons/muk_web_utils/static/src/js/fields/share.js:144
+#, python-format
+msgid "<%= name %> shared a message!"
+msgstr "<%= name %> teilte eine Nachricht!"
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/js/fields/share.js:116
+#: code:addons/muk_web_utils/static/src/js/fields/share.js:145
+#: code:addons/muk_web_utils/static/src/js/fields/share.js:176
+#, python-format
+msgid "<%= value %>"
+msgstr "<%= Wert %>"
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/js/core/dialog.js:51
+#: code:addons/muk_web_utils/static/src/js/fields/module.js:50
+#, python-format
+msgid "Cancel"
+msgstr "Abbrechen"
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/module.xml:30
+#, python-format
+msgid "Click on the download button to be redirected to the store and download the corresponding module."
+msgstr ""
+"Klicken Sie auf den Download-Button, um in den Shop weitergeleitet zu werden "
+"und das entsprechende Modul herunterzuladen."
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/color.xml:46
+#, python-format
+msgid "Color 0"
+msgstr "Farbe 0"
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/color.xml:47
+#, python-format
+msgid "Color 1"
+msgstr "Farbe 1"
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/color.xml:56
+#, python-format
+msgid "Color 10"
+msgstr "Farbe 10"
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/color.xml:57
+#, python-format
+msgid "Color 11"
+msgstr "Farbe 11"
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/color.xml:48
+#, python-format
+msgid "Color 2"
+msgstr "Farbe 2"
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/color.xml:49
+#, python-format
+msgid "Color 3"
+msgstr "Farbe 3"
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/color.xml:50
+#, python-format
+msgid "Color 4"
+msgstr "Farbe 4"
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/color.xml:51
+#, python-format
+msgid "Color 5"
+msgstr "Farbe 5"
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/color.xml:52
+#, python-format
+msgid "Color 6"
+msgstr "Farbe 6"
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/color.xml:53
+#, python-format
+msgid "Color 7"
+msgstr "Farbe 7"
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/color.xml:54
+#, python-format
+msgid "Color 8"
+msgstr "Farbe 8"
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/color.xml:55
+#, python-format
+msgid "Color 9"
+msgstr "Farbe 9"
+
+#. module: muk_web_utils
+#: model:ir.model,name:muk_web_utils.model_res_config_settings
+msgid "Config Settings"
+msgstr "Konfiguration "
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/js/fields/module.js:45
+#: code:addons/muk_web_utils/static/src/xml/share.xml:97
+#, python-format
+msgid "Download"
+msgstr "Herunterladen"
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/js/core/dropzone.js:108
+#, python-format
+msgid "Drop files here to upload!"
+msgstr "Lassen Sie Dateien hier zum Hochladen fallen!"
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/share.xml:45
+#, python-format
+msgid "External"
+msgstr "Extern"
+
+#. module: muk_web_utils
+#: model:ir.model.fields,field_description:muk_web_utils.field_res_config_settings__binary_max_size
+msgid "File Size Limit"
+msgstr "Dateigrößenbegrenzung"
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/share.xml:35
+#, python-format
+msgid "Internal"
+msgstr "Intern"
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/js/fields/copy.js:107
+#, python-format
+msgid "Link Copied!"
+msgstr "Link kopiert!"
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/share.xml:48
+#, python-format
+msgid "Mail"
+msgstr "Mail"
+
+#. module: muk_web_utils
+#: model_terms:ir.ui.view,arch_db:muk_web_utils.res_config_settings_view_form
+msgid "Maximum allowed file size in MB"
+msgstr "Maximal zulässige Dateigröße in MB"
+
+#. module: muk_web_utils
+#: model:ir.model.fields,help:muk_web_utils.field_res_config_settings__binary_max_size
+msgid "Maximum allowed file size in megabytes. Note that this setting only adjusts\n"
+" the binary widgets accordingly. The maximum file size on your server can probably\n"
+" be restricted in several places. Note that a large file size limit and therefore\n"
+" large files in your system can significantly limit performance."
+msgstr ""
+"Maximal zulässige Dateigröße in Megabyte. Beachten Sie, dass diese "
+"Einstellung nur angepasst wird._x000D_\n"
+" die binären Widgets entsprechend. Die maximale Dateigröße auf "
+"Ihrem Server kann wahrscheinlich_x000D_\n"
+" an mehreren Stellen eingeschränkt sein. Beachten Sie, dass eine "
+"große Dateigröße und damit eine große Dateigröße begrenzt ist._x000D_\n"
+" können große Dateien in Ihrem System die Leistung erheblich "
+"einschränken."
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/share.xml:38
+#, python-format
+msgid "Message"
+msgstr "Nachricht"
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/js/fields/module.js:59
+#: code:addons/muk_web_utils/static/src/xml/module.xml:26
+#, python-format
+msgid "Missing Module"
+msgstr "Fehlende Module"
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/share.xml:42
+#, python-format
+msgid "Note"
+msgstr "Hinweis"
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/share.xml:83
+#, python-format
+msgid "Open"
+msgstr "Offen"
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/js/core/dialog.js:45
+#, python-format
+msgid "Save"
+msgstr "Speichern"
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/share.xml:52
+#, python-format
+msgid "Send"
+msgstr "Senden"
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/share.xml:27
+#, python-format
+msgid "Share"
+msgstr "Teilen"
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/js/fields/module.js:74
+#, python-format
+msgid "Store"
+msgstr "Laden"
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/js/fields/copy.js:35
+#, python-format
+msgid "The field '%s' must be a binary field with an set attachment flag for the share widget to work."
+msgstr ""
+"Das Feld'%s' muss ein Binärfeld mit einem gesetzten Attachment-Flag sein, "
+"damit das Share-Widget funktioniert."
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/module.xml:29
+#, python-format
+msgid "The module could not be found on the server."
+msgstr "Das Modul konnte auf dem Server nicht gefunden werden."
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/js/core/async.js:46
+#, python-format
+msgid "Upload"
+msgstr "Hochladen"
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/js/core/async.js:47
+#, python-format
+msgid "Uploading..."
+msgstr "Hochladen....."
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/share.xml:95
+#, python-format
+msgid "shared a file with you!"
+msgstr "hat eine Datei mit dir geteilt!"
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/share.xml:81
+#, python-format
+msgid "shared a link with you!"
+msgstr "einen Link mit dir geteilt!"
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/share.xml:87
+#, python-format
+msgid "shared a message with you!"
+msgstr "hat eine Nachricht mit dir geteilt!"
diff --git a/odex-event/muk_web_utils/i18n/es.po b/odex-event/muk_web_utils/i18n/es.po
new file mode 100644
index 000000000..72ab6d390
--- /dev/null
+++ b/odex-event/muk_web_utils/i18n/es.po
@@ -0,0 +1,326 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * muk_web_utils
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 12.0-20190128\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2019-02-27 09:28+0000\n"
+"PO-Revision-Date: 2019-02-27 09:28+0000\n"
+"Last-Translator: <>\n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: \n"
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/js/fields/color.js:113
+#, python-format
+msgid "'%s' is not a correct color index (0-12)"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/js/fields/color.js:68
+#, python-format
+msgid "'%s' is not a correct color value"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/js/fields/share.js:175
+#, python-format
+msgid "<%= name %> shared a file!"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/js/fields/share.js:115
+#: code:addons/muk_web_utils/static/src/js/fields/share.js:144
+#, python-format
+msgid "<%= name %> shared a message!"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/js/fields/share.js:116
+#: code:addons/muk_web_utils/static/src/js/fields/share.js:145
+#: code:addons/muk_web_utils/static/src/js/fields/share.js:176
+#, python-format
+msgid "<%= value %>"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/js/core/dialog.js:51
+#: code:addons/muk_web_utils/static/src/js/fields/module.js:50
+#, python-format
+msgid "Cancel"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/module.xml:30
+#, python-format
+msgid "Click on the download button to be redirected to the store and download the corresponding module."
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/color.xml:46
+#, python-format
+msgid "Color 0"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/color.xml:47
+#, python-format
+msgid "Color 1"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/color.xml:56
+#, python-format
+msgid "Color 10"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/color.xml:57
+#, python-format
+msgid "Color 11"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/color.xml:48
+#, python-format
+msgid "Color 2"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/color.xml:49
+#, python-format
+msgid "Color 3"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/color.xml:50
+#, python-format
+msgid "Color 4"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/color.xml:51
+#, python-format
+msgid "Color 5"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/color.xml:52
+#, python-format
+msgid "Color 6"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/color.xml:53
+#, python-format
+msgid "Color 7"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/color.xml:54
+#, python-format
+msgid "Color 8"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/color.xml:55
+#, python-format
+msgid "Color 9"
+msgstr ""
+
+#. module: muk_web_utils
+#: model:ir.model,name:muk_web_utils.model_res_config_settings
+msgid "Config Settings"
+msgstr "Opciones de Configuración"
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/js/fields/module.js:45
+#: code:addons/muk_web_utils/static/src/xml/share.xml:97
+#, python-format
+msgid "Download"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/js/core/dropzone.js:108
+#, python-format
+msgid "Drop files here to upload!"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/share.xml:45
+#, python-format
+msgid "External"
+msgstr ""
+
+#. module: muk_web_utils
+#: model:ir.model.fields,field_description:muk_web_utils.field_res_config_settings__binary_max_size
+msgid "File Size Limit"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/share.xml:35
+#, python-format
+msgid "Internal"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/js/fields/copy.js:107
+#, python-format
+msgid "Link Copied!"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/share.xml:48
+#, python-format
+msgid "Mail"
+msgstr ""
+
+#. module: muk_web_utils
+#: model_terms:ir.ui.view,arch_db:muk_web_utils.res_config_settings_view_form
+msgid "Maximum allowed file size in MB"
+msgstr ""
+
+#. module: muk_web_utils
+#: model:ir.model.fields,help:muk_web_utils.field_res_config_settings__binary_max_size
+msgid "Maximum allowed file size in megabytes. Note that this setting only adjusts\n"
+" the binary widgets accordingly. The maximum file size on your server can probably\n"
+" be restricted in several places. Note that a large file size limit and therefore\n"
+" large files in your system can significantly limit performance."
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/share.xml:38
+#, python-format
+msgid "Message"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/js/fields/module.js:59
+#: code:addons/muk_web_utils/static/src/xml/module.xml:26
+#, python-format
+msgid "Missing Module"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/share.xml:42
+#, python-format
+msgid "Note"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/share.xml:83
+#, python-format
+msgid "Open"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/js/core/dialog.js:45
+#, python-format
+msgid "Save"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/share.xml:52
+#, python-format
+msgid "Send"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/share.xml:27
+#, python-format
+msgid "Share"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/js/fields/module.js:74
+#, python-format
+msgid "Store"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/js/fields/copy.js:35
+#, python-format
+msgid "The field '%s' must be a binary field with an set attachment flag for the share widget to work."
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/module.xml:29
+#, python-format
+msgid "The module could not be found on the server."
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/js/core/async.js:46
+#, python-format
+msgid "Upload"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/js/core/async.js:47
+#, python-format
+msgid "Uploading..."
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/share.xml:95
+#, python-format
+msgid "shared a file with you!"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/share.xml:81
+#, python-format
+msgid "shared a link with you!"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/share.xml:87
+#, python-format
+msgid "shared a message with you!"
+msgstr ""
+
diff --git a/odex-event/muk_web_utils/i18n/fr.po b/odex-event/muk_web_utils/i18n/fr.po
new file mode 100644
index 000000000..d00b7e5a6
--- /dev/null
+++ b/odex-event/muk_web_utils/i18n/fr.po
@@ -0,0 +1,326 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * muk_web_utils
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 12.0-20190128\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2019-02-27 09:28+0000\n"
+"PO-Revision-Date: 2019-02-27 09:28+0000\n"
+"Last-Translator: <>\n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: \n"
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/js/fields/color.js:113
+#, python-format
+msgid "'%s' is not a correct color index (0-12)"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/js/fields/color.js:68
+#, python-format
+msgid "'%s' is not a correct color value"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/js/fields/share.js:175
+#, python-format
+msgid "<%= name %> shared a file!"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/js/fields/share.js:115
+#: code:addons/muk_web_utils/static/src/js/fields/share.js:144
+#, python-format
+msgid "<%= name %> shared a message!"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/js/fields/share.js:116
+#: code:addons/muk_web_utils/static/src/js/fields/share.js:145
+#: code:addons/muk_web_utils/static/src/js/fields/share.js:176
+#, python-format
+msgid "<%= value %>"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/js/core/dialog.js:51
+#: code:addons/muk_web_utils/static/src/js/fields/module.js:50
+#, python-format
+msgid "Cancel"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/module.xml:30
+#, python-format
+msgid "Click on the download button to be redirected to the store and download the corresponding module."
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/color.xml:46
+#, python-format
+msgid "Color 0"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/color.xml:47
+#, python-format
+msgid "Color 1"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/color.xml:56
+#, python-format
+msgid "Color 10"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/color.xml:57
+#, python-format
+msgid "Color 11"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/color.xml:48
+#, python-format
+msgid "Color 2"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/color.xml:49
+#, python-format
+msgid "Color 3"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/color.xml:50
+#, python-format
+msgid "Color 4"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/color.xml:51
+#, python-format
+msgid "Color 5"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/color.xml:52
+#, python-format
+msgid "Color 6"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/color.xml:53
+#, python-format
+msgid "Color 7"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/color.xml:54
+#, python-format
+msgid "Color 8"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/color.xml:55
+#, python-format
+msgid "Color 9"
+msgstr ""
+
+#. module: muk_web_utils
+#: model:ir.model,name:muk_web_utils.model_res_config_settings
+msgid "Config Settings"
+msgstr "Paramètres de config"
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/js/fields/module.js:45
+#: code:addons/muk_web_utils/static/src/xml/share.xml:97
+#, python-format
+msgid "Download"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/js/core/dropzone.js:108
+#, python-format
+msgid "Drop files here to upload!"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/share.xml:45
+#, python-format
+msgid "External"
+msgstr ""
+
+#. module: muk_web_utils
+#: model:ir.model.fields,field_description:muk_web_utils.field_res_config_settings__binary_max_size
+msgid "File Size Limit"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/share.xml:35
+#, python-format
+msgid "Internal"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/js/fields/copy.js:107
+#, python-format
+msgid "Link Copied!"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/share.xml:48
+#, python-format
+msgid "Mail"
+msgstr ""
+
+#. module: muk_web_utils
+#: model_terms:ir.ui.view,arch_db:muk_web_utils.res_config_settings_view_form
+msgid "Maximum allowed file size in MB"
+msgstr ""
+
+#. module: muk_web_utils
+#: model:ir.model.fields,help:muk_web_utils.field_res_config_settings__binary_max_size
+msgid "Maximum allowed file size in megabytes. Note that this setting only adjusts\n"
+" the binary widgets accordingly. The maximum file size on your server can probably\n"
+" be restricted in several places. Note that a large file size limit and therefore\n"
+" large files in your system can significantly limit performance."
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/share.xml:38
+#, python-format
+msgid "Message"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/js/fields/module.js:59
+#: code:addons/muk_web_utils/static/src/xml/module.xml:26
+#, python-format
+msgid "Missing Module"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/share.xml:42
+#, python-format
+msgid "Note"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/share.xml:83
+#, python-format
+msgid "Open"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/js/core/dialog.js:45
+#, python-format
+msgid "Save"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/share.xml:52
+#, python-format
+msgid "Send"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/share.xml:27
+#, python-format
+msgid "Share"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/js/fields/module.js:74
+#, python-format
+msgid "Store"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/js/fields/copy.js:35
+#, python-format
+msgid "The field '%s' must be a binary field with an set attachment flag for the share widget to work."
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/module.xml:29
+#, python-format
+msgid "The module could not be found on the server."
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/js/core/async.js:46
+#, python-format
+msgid "Upload"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/js/core/async.js:47
+#, python-format
+msgid "Uploading..."
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/share.xml:95
+#, python-format
+msgid "shared a file with you!"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/share.xml:81
+#, python-format
+msgid "shared a link with you!"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/share.xml:87
+#, python-format
+msgid "shared a message with you!"
+msgstr ""
+
diff --git a/odex-event/muk_web_utils/i18n/nl.po b/odex-event/muk_web_utils/i18n/nl.po
new file mode 100644
index 000000000..032b13baa
--- /dev/null
+++ b/odex-event/muk_web_utils/i18n/nl.po
@@ -0,0 +1,326 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * muk_web_utils
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 12.0-20190128\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2019-02-27 09:28+0000\n"
+"PO-Revision-Date: 2019-02-27 09:28+0000\n"
+"Last-Translator: <>\n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: \n"
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/js/fields/color.js:113
+#, python-format
+msgid "'%s' is not a correct color index (0-12)"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/js/fields/color.js:68
+#, python-format
+msgid "'%s' is not a correct color value"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/js/fields/share.js:175
+#, python-format
+msgid "<%= name %> shared a file!"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/js/fields/share.js:115
+#: code:addons/muk_web_utils/static/src/js/fields/share.js:144
+#, python-format
+msgid "<%= name %> shared a message!"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/js/fields/share.js:116
+#: code:addons/muk_web_utils/static/src/js/fields/share.js:145
+#: code:addons/muk_web_utils/static/src/js/fields/share.js:176
+#, python-format
+msgid "<%= value %>"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/js/core/dialog.js:51
+#: code:addons/muk_web_utils/static/src/js/fields/module.js:50
+#, python-format
+msgid "Cancel"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/module.xml:30
+#, python-format
+msgid "Click on the download button to be redirected to the store and download the corresponding module."
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/color.xml:46
+#, python-format
+msgid "Color 0"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/color.xml:47
+#, python-format
+msgid "Color 1"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/color.xml:56
+#, python-format
+msgid "Color 10"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/color.xml:57
+#, python-format
+msgid "Color 11"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/color.xml:48
+#, python-format
+msgid "Color 2"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/color.xml:49
+#, python-format
+msgid "Color 3"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/color.xml:50
+#, python-format
+msgid "Color 4"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/color.xml:51
+#, python-format
+msgid "Color 5"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/color.xml:52
+#, python-format
+msgid "Color 6"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/color.xml:53
+#, python-format
+msgid "Color 7"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/color.xml:54
+#, python-format
+msgid "Color 8"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/color.xml:55
+#, python-format
+msgid "Color 9"
+msgstr ""
+
+#. module: muk_web_utils
+#: model:ir.model,name:muk_web_utils.model_res_config_settings
+msgid "Config Settings"
+msgstr "Configuratie instellingen"
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/js/fields/module.js:45
+#: code:addons/muk_web_utils/static/src/xml/share.xml:97
+#, python-format
+msgid "Download"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/js/core/dropzone.js:108
+#, python-format
+msgid "Drop files here to upload!"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/share.xml:45
+#, python-format
+msgid "External"
+msgstr ""
+
+#. module: muk_web_utils
+#: model:ir.model.fields,field_description:muk_web_utils.field_res_config_settings__binary_max_size
+msgid "File Size Limit"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/share.xml:35
+#, python-format
+msgid "Internal"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/js/fields/copy.js:107
+#, python-format
+msgid "Link Copied!"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/share.xml:48
+#, python-format
+msgid "Mail"
+msgstr ""
+
+#. module: muk_web_utils
+#: model_terms:ir.ui.view,arch_db:muk_web_utils.res_config_settings_view_form
+msgid "Maximum allowed file size in MB"
+msgstr ""
+
+#. module: muk_web_utils
+#: model:ir.model.fields,help:muk_web_utils.field_res_config_settings__binary_max_size
+msgid "Maximum allowed file size in megabytes. Note that this setting only adjusts\n"
+" the binary widgets accordingly. The maximum file size on your server can probably\n"
+" be restricted in several places. Note that a large file size limit and therefore\n"
+" large files in your system can significantly limit performance."
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/share.xml:38
+#, python-format
+msgid "Message"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/js/fields/module.js:59
+#: code:addons/muk_web_utils/static/src/xml/module.xml:26
+#, python-format
+msgid "Missing Module"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/share.xml:42
+#, python-format
+msgid "Note"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/share.xml:83
+#, python-format
+msgid "Open"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/js/core/dialog.js:45
+#, python-format
+msgid "Save"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/share.xml:52
+#, python-format
+msgid "Send"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/share.xml:27
+#, python-format
+msgid "Share"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/js/fields/module.js:74
+#, python-format
+msgid "Store"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/js/fields/copy.js:35
+#, python-format
+msgid "The field '%s' must be a binary field with an set attachment flag for the share widget to work."
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/module.xml:29
+#, python-format
+msgid "The module could not be found on the server."
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/js/core/async.js:46
+#, python-format
+msgid "Upload"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/js/core/async.js:47
+#, python-format
+msgid "Uploading..."
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/share.xml:95
+#, python-format
+msgid "shared a file with you!"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/share.xml:81
+#, python-format
+msgid "shared a link with you!"
+msgstr ""
+
+#. module: muk_web_utils
+#. openerp-web
+#: code:addons/muk_web_utils/static/src/xml/share.xml:87
+#, python-format
+msgid "shared a message with you!"
+msgstr ""
+
diff --git a/odex-event/muk_web_utils/models/__init__.py b/odex-event/muk_web_utils/models/__init__.py
new file mode 100644
index 000000000..b692fb19f
--- /dev/null
+++ b/odex-event/muk_web_utils/models/__init__.py
@@ -0,0 +1,25 @@
+###################################################################################
+#
+# Copyright (c) 2017-2019 MuK IT GmbH.
+#
+# This file is part of MuK Web Utils
+# (see https://mukit.at).
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see .
+#
+###################################################################################
+
+from . import ir_attachment
+from . import res_config_settings
+
diff --git a/odex-event/muk_web_utils/models/ir_attachment.py b/odex-event/muk_web_utils/models/ir_attachment.py
new file mode 100644
index 000000000..bb5d745da
--- /dev/null
+++ b/odex-event/muk_web_utils/models/ir_attachment.py
@@ -0,0 +1,46 @@
+###################################################################################
+#
+# Copyright (c) 2017-2019 MuK IT GmbH.
+#
+# This file is part of MuK Web Utils
+# (see https://mukit.at).
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see .
+#
+###################################################################################
+
+import base64
+import logging
+import mimetypes
+
+from odoo import api, models, fields, _
+from odoo.exceptions import AccessError
+from odoo.tools.mimetypes import guess_mimetype
+
+_logger = logging.getLogger(__name__)
+
+class IrAttachment(models.Model):
+
+ _inherit = 'ir.attachment'
+
+ #----------------------------------------------------------
+ # Database
+ #----------------------------------------------------------
+
+ temporary = fields.Boolean(
+ string="Temporary",
+ default=False,
+ help="Attachments will be deleted by Autovacuum.",
+ )
+
\ No newline at end of file
diff --git a/odex-event/muk_web_utils/models/res_config_settings.py b/odex-event/muk_web_utils/models/res_config_settings.py
new file mode 100644
index 000000000..6e6827738
--- /dev/null
+++ b/odex-event/muk_web_utils/models/res_config_settings.py
@@ -0,0 +1,80 @@
+###################################################################################
+#
+# Copyright (c) 2017-2019 MuK IT GmbH.
+#
+# This file is part of MuK Web Utils
+# (see https://mukit.at).
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see .
+#
+###################################################################################
+
+import re
+import json
+import logging
+
+from lxml import etree
+
+from odoo import api, fields, models
+
+_logger = logging.getLogger(__name__)
+
+class ResConfigSettings(models.TransientModel):
+
+ _inherit = 'res.config.settings'
+
+ #----------------------------------------------------------
+ # Database
+ #----------------------------------------------------------
+
+ binary_max_size = fields.Integer(
+ string='File Size Limit',
+ required=True,
+ default=25,
+ help="""Maximum allowed file size in megabytes. Note that this setting only adjusts
+ the binary widgets accordingly. The maximum file size on your server can probably
+ be restricted in several places. Note that a large file size limit and therefore
+ large files in your system can significantly limit performance.""")
+
+ #----------------------------------------------------------
+ # Functions
+ #----------------------------------------------------------
+
+
+ def set_values(self):
+ res = super(ResConfigSettings, self).set_values()
+ param = self.env['ir.config_parameter'].sudo()
+ param.set_param('muk_web_utils.binary_max_size', self.binary_max_size)
+ return res
+
+ @api.model
+ def get_values(self):
+ res = super(ResConfigSettings, self).get_values()
+ params = self.env['ir.config_parameter'].sudo()
+ res.update(binary_max_size=int(params.get_param('muk_web_utils.binary_max_size', 25)))
+ return res
+
+ @api.model
+ def fields_view_get(self, view_id=None, view_type='form', toolbar=False, submenu=False):
+ ret_val = super(ResConfigSettings, self).fields_view_get(
+ view_id=view_id, view_type=view_type, toolbar=toolbar, submenu=submenu)
+ modules = self.env['ir.module.module'].sudo().search([]).mapped('name')
+ document = etree.XML(ret_val['arch'])
+ for field in ret_val['fields']:
+ if field.startswith("module_") and field[len("module_"):] not in modules:
+ for node in document.xpath("//field[@name='%s']" % field):
+ if node.get("widget") != 'upgrade_boolean':
+ node.set("widget", "module_boolean")
+ ret_val['arch'] = etree.tostring(document, encoding='unicode')
+ return ret_val
\ No newline at end of file
diff --git a/odex-event/muk_web_utils/static/description/banner.png b/odex-event/muk_web_utils/static/description/banner.png
new file mode 100644
index 000000000..98df572ac
Binary files /dev/null and b/odex-event/muk_web_utils/static/description/banner.png differ
diff --git a/odex-event/muk_web_utils/static/description/icon.png b/odex-event/muk_web_utils/static/description/icon.png
new file mode 100644
index 000000000..858ea62ff
Binary files /dev/null and b/odex-event/muk_web_utils/static/description/icon.png differ
diff --git a/odex-event/muk_web_utils/static/description/icon.svg b/odex-event/muk_web_utils/static/description/icon.svg
new file mode 100644
index 000000000..d3d63f188
--- /dev/null
+++ b/odex-event/muk_web_utils/static/description/icon.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/odex-event/muk_web_utils/static/description/index.html b/odex-event/muk_web_utils/static/description/index.html
new file mode 100644
index 000000000..2cccde3c2
--- /dev/null
+++ b/odex-event/muk_web_utils/static/description/index.html
@@ -0,0 +1,124 @@
+
+
+
MuK Web Utils
+
Utility Features
+
MuK IT GmbH -
+ www.mukit.at
+
+
+
+
+
+
+
Overview
+
Technical module to provide some utility
+ features. The module is mainly used as a dependency by other modules
+ and to provide a collection of common libraries. It has no direct
+ visible effect on the system.
', {
+ html: $(QWeb.render('muk_web_utils.MissingModuleDialog')),
+ }),
+ title: _t("Missing Module"),
+ }).open();
+ },
+ _confirmRedirect: function () {
+ if(this.nodeOptions.url) {
+ framework.redirect(this.nodeOptions.url);
+ } else {
+ var module = this.name.replace("module_", "");
+ framework.redirect("https://apps.odoo.com/apps/modules/browse?search=" + module);
+ }
+ },
+ _render: function () {
+ this._super.apply(this, arguments);
+ var $element = this.$label || this.$el;
+ $element.append(' ').append($("", {
+ 'text': _t("Store"),
+ 'class': "badge badge-primary oe_inline mk_module_label"
+ }));
+ },
+ _onInputClicked: function (event) {
+ if ($(event.currentTarget).prop("checked")) {
+ var dialog = this._openDialog();
+ dialog.on('closed', this, this._resetValue.bind(this));
+ }
+ },
+ _resetValue: function () {
+ this.$input.prop("checked", false).change();
+ },
+});
+
+registry.add('module_boolean', ModuleBoolean);
+
+return ModuleBoolean;
+
+});
\ No newline at end of file
diff --git a/odex-event/muk_web_utils/static/src/js/fields/path.js b/odex-event/muk_web_utils/static/src/js/fields/path.js
new file mode 100644
index 000000000..ffc2bc132
--- /dev/null
+++ b/odex-event/muk_web_utils/static/src/js/fields/path.js
@@ -0,0 +1,119 @@
+/**********************************************************************************
+*
+* Copyright (c) 2017-2019 MuK IT GmbH.
+*
+* This file is part of MuK Web Utils
+* (see https://mukit.at).
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program. If not, see .
+*
+**********************************************************************************/
+
+odoo.define('muk_web_utils.path', function (require) {
+"use strict";
+
+var core = require('web.core');
+var fields = require('web.basic_fields');
+var registry = require('web.field_registry');
+var colorpicker = require('web.colorpicker');
+
+var AbstractField = require('web.AbstractField');
+
+var _t = core._t;
+var QWeb = core.qweb;
+
+var FieldPathNames = fields.FieldChar.extend({
+ init: function(parent, name, record) {
+ this._super.apply(this, arguments);
+ this.max_width = this.nodeOptions.width || 500;
+ },
+ _renderReadonly: function() {
+ var show_value = this._formatValue(this.value);
+ var text_witdh = $.fn.textWidth(show_value);
+ if(text_witdh >= this.max_width) {
+ var ratio_start = (1 - (this.max_width / text_witdh)) * show_value.length;
+ show_value = ".." + show_value.substring(ratio_start, show_value.length);
+ }
+ this.$el.text(show_value);
+ },
+});
+
+var FieldPathJson = fields.FieldText.extend({
+ events: _.extend({}, fields.FieldText.prototype.events, {
+ 'click a' : '_onNodeClicked',
+ }),
+ init: function(parent, name, record) {
+ this._super.apply(this, arguments);
+ this.max_width = this.nodeOptions.width || 500;
+ this.seperator = this.nodeOptions.seperator || "/";
+ this.prefix = this.nodeOptions.prefix || false;
+ this.suffix = this.nodeOptions.suffix || false;
+ },
+ _renderReadonly: function() {
+ this.$el.empty();
+ this._renderPath();
+ },
+ _renderPath: function() {
+ var text_width_measure = "";
+ var path = JSON.parse(this.value || "[]");
+ $.each(_.clone(path).reverse(), function(index, element) {
+ text_width_measure += element.name + "/";
+ if($.fn.textWidth(text_width_measure) >= this.max_width) {
+ this.$el.prepend($('').text(".."));
+ } else {
+ if (index == 0) {
+ if(this.suffix) {
+ this.$el.prepend($('').text(this.seperator));
+ }
+ this.$el.prepend($('').text(element.name));
+ this.$el.prepend($('').text(this.seperator));
+ } else {
+ this.$el.prepend($('', {
+ 'class': 'oe_form_uri',
+ 'data-model': element.model,
+ 'data-id': element.id,
+ 'href': "javascript:void(0);",
+ 'text': element.name,
+ }));
+ if (index != path.length - 1) {
+ this.$el.prepend($('').text(this.seperator));
+ } else if (this.prefix) {
+ this.$el.prepend($('').text(this.seperator));
+ }
+ }
+ }
+ return ($.fn.textWidth(text_width_measure) < this.max_width);
+ }.bind(this));
+ },
+ _onNodeClicked : function(event) {
+ this.do_action({
+ type: 'ir.actions.act_window',
+ res_model: $(event.currentTarget).data('model'),
+ res_id: $(event.currentTarget).data('id'),
+ views: [[false, 'form']],
+ target: 'current',
+ context: {},
+ });
+ }
+});
+
+registry.add('path_names', FieldPathNames);
+registry.add('path_json', FieldPathJson);
+
+return {
+ FieldPathNames: FieldPathNames,
+ FieldPathJson: FieldPathJson,
+};
+
+});
\ No newline at end of file
diff --git a/odex-event/muk_web_utils/static/src/js/fields/share.js b/odex-event/muk_web_utils/static/src/js/fields/share.js
new file mode 100644
index 000000000..eaa0eeed8
--- /dev/null
+++ b/odex-event/muk_web_utils/static/src/js/fields/share.js
@@ -0,0 +1,227 @@
+/**********************************************************************************
+*
+* Copyright (c) 2017-2019 MuK IT GmbH.
+*
+* This file is part of MuK Web Utils
+* (see https://mukit.at).
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program. If not, see .
+*
+**********************************************************************************/
+
+odoo.define('muk_web_utils.share', function (require) {
+"use strict";
+
+var core = require('web.core');
+var session = require('web.session');
+var fields = require('web.basic_fields');
+var registry = require('web.field_registry');
+
+var utils = require('muk_web_utils.utils');
+var copy = require('muk_web_utils.copy');
+
+var _t = core._t;
+var QWeb = core.qweb;
+
+var ShareMixin = {
+ shareEvents: {
+ 'click .mk_share_dropdown_message': '_onShareMessageClick',
+ 'click .mk_share_dropdown_note': '_onShareNoteClick',
+ 'click .mk_share_dropdown_mail': '_onShareMailClick',
+ 'click .mk_share_dropdown_send': '_onShareSendClick',
+ },
+ getShareMessageValues: function(message) {
+ var values = {
+ name: session.partner_display_name,
+ record: this.recordData.display_name,
+ url: utils.isUrl(this.value) && this.value,
+ value: this.value,
+ };
+ return {
+ subject: _.template(this.shareOptions.subjectTemplate)(values),
+ body: QWeb.render(this.shareOptions.bodyTemplate, values),
+ text: _.template(this.shareOptions.textTemplate)(values),
+ url: utils.isUrl(this.value) && this.value,
+ }
+ },
+ openShareChat: function(note) {
+ var values = this.getShareMessageValues();
+ var context = {
+ default_is_log: note,
+ default_body: values.body,
+ default_subject: values.subject,
+ default_model: this.shareOptions.res_model,
+ default_res_id: this.shareOptions.res_id,
+ mail_post_autofollow: false,
+ };
+ this.do_action({
+ type: 'ir.actions.act_window',
+ res_model: 'mail.compose.message',
+ view_mode: 'form',
+ view_type: 'form',
+ views: [[false, 'form']],
+ target: 'new',
+ context: context,
+ });
+ },
+ _onShareMessageClick: function(event) {
+ event.preventDefault();
+ event.stopPropagation();
+ this.openShareChat(false);
+ },
+ _onShareNoteClick: function(event) {
+ event.preventDefault();
+ event.stopPropagation();
+ this.openShareChat(true);
+ },
+ _onShareMailClick: function(event) {
+ event.preventDefault();
+ event.stopPropagation();
+ var values = this.getShareMessageValues();
+ var subject = "subject=" + values.subject;
+ var body = "&body=" + encodeURIComponent(values.text);
+ window.location.href = "mailto:?" + subject + body;
+ },
+ _onShareSendClick: function(event) {
+ event.preventDefault();
+ event.stopPropagation();
+ var values = this.getShareMessageValues();
+ navigator.share({
+ title: values.subject,
+ text: values.text,
+ url: values.url,
+ });
+ },
+};
+
+var CharShare = fields.CharCopyClipboard.extend(ShareMixin, {
+ fieldDependencies: _.extend({}, fields.CharCopyClipboard.prototype.fieldDependencies, {
+ display_name: {type: 'char'},
+ }),
+ events: _.extend({}, fields.CharCopyClipboard.prototype.events, ShareMixin.shareEvents),
+ init: function(parent, name, record) {
+ this._super.apply(this, arguments);
+ this.navigator = window.navigator.share;
+ this.chatter = _.contains(odoo._modules, "mail");
+ this.shareOptions = _.defaults(this.nodeOptions, {
+ subjectTemplate: _t("<%= name %> shared a message!"),
+ textTemplate: _t("<%= value %>"),
+ bodyTemplate: 'muk_web_utils.ShareMessage',
+ });
+ this.shareOptions = _.extend({}, this.shareOptions, {
+ res_model: this.recordData[this.nodeOptions.res_model] || this.model,
+ res_id: this.recordData[this.nodeOptions.res_id] || this.res_id,
+ });
+ },
+ _render: function() {
+ this._super.apply(this, arguments);
+ this.$el.addClass('mk_field_share');
+ this.$el.prepend($(QWeb.render('muk_web_utils.CharShare', {
+ navigator: !!this.navigator,
+ chatter: !!this.chatter,
+ })));
+ },
+});
+
+var TextShare = fields.TextCopyClipboard.extend(ShareMixin, {
+ fieldDependencies: _.extend({}, fields.TextCopyClipboard.prototype.fieldDependencies, {
+ display_name: {type: 'char'},
+ }),
+ events: _.extend({}, fields.TextCopyClipboard.prototype.events, ShareMixin.shareEvents),
+ init: function(parent, name, record) {
+ this._super.apply(this, arguments);
+ this.navigator = window.navigator.share;
+ this.chatter = _.contains(odoo._modules, "mail");
+ this.shareOptions = _.defaults(this.nodeOptions, {
+ subjectTemplate: _t("<%= name %> shared a message!"),
+ textTemplate: _t("<%= value %>"),
+ bodyTemplate: 'muk_web_utils.ShareMessage',
+ });
+ this.shareOptions = _.extend({}, this.shareOptions, {
+ res_model: this.recordData[this.nodeOptions.res_model] || this.model,
+ res_id: this.recordData[this.nodeOptions.res_id] || this.res_id,
+ });
+ },
+ _render: function() {
+ this._super.apply(this, arguments);
+ this.$el.addClass('mk_field_share');
+ this.$el.prepend($(QWeb.render('muk_web_utils.TextShare', {
+ navigator: !!this.navigator,
+ chatter: !!this.chatter,
+ })));
+ }
+});
+
+var BinaryFileShare = copy.BinaryFileCopy.extend(ShareMixin, {
+ fieldDependencies: _.extend({}, fields.FieldBinaryFile.prototype.fieldDependencies, {
+ display_name: {type: 'char'},
+ }),
+ events: _.extend({}, copy.BinaryFileCopy.prototype.events, ShareMixin.shareEvents, {
+ 'click .mk_share_button': '_onShareDropdownClick',
+ }),
+ init: function () {
+ this._super.apply(this, arguments);
+ this.navigator = window.navigator.share;
+ this.chatter = _.contains(odoo._modules, "mail");
+ this.shareOptions = _.defaults(this.nodeOptions, {
+ subjectTemplate: _t("<%= name %> shared a file!"),
+ textTemplate: _t("<%= value %>"),
+ bodyTemplate: 'muk_web_utils.ShareBinaryMessage',
+ });
+ this.shareOptions = _.extend({}, this.shareOptions, {
+ res_model: this.recordData[this.nodeOptions.res_model] || this.model,
+ res_id: this.recordData[this.nodeOptions.res_id] || this.res_id,
+ });
+ },
+ getShareMessageValues: function() {
+ var values = {
+ name: session.partner_display_name,
+ record: this.recordData.display_name,
+ url: this.shareUrl,
+ value: this.shareUrl,
+ };
+ return {
+ subject: _.template(this.shareOptions.subjectTemplate)(values),
+ body: QWeb.render(this.shareOptions.bodyTemplate, values),
+ text: _.template(this.shareOptions.textTemplate)(values),
+ url: this.shareUrl,
+ }
+ },
+ _renderReadonly: function () {
+ this._super.apply(this, arguments);
+ this.$el.addClass('mk_field_share');
+ this.$el.append($(QWeb.render('muk_web_utils.BinaryShare', {
+ navigator: !!this.navigator,
+ chatter: !!this.chatter,
+ share: !!this.shareUrl,
+ })));
+ },
+ _onShareDropdownClick: function(event) {
+ $(event.currentTarget).dropdown("toggle");
+ event.stopPropagation();
+ },
+});
+
+registry.add('share_char', CharShare);
+registry.add('share_text', TextShare);
+registry.add('share_binary', BinaryFileShare);
+
+return {
+ ShareMixin: ShareMixin,
+ CharShare: CharShare,
+ TextShare: TextShare,
+ BinaryFileShare: BinaryFileShare,
+};
+
+});
\ No newline at end of file
diff --git a/odex-event/muk_web_utils/static/src/js/fields/utils.js b/odex-event/muk_web_utils/static/src/js/fields/utils.js
new file mode 100644
index 000000000..001acdd04
--- /dev/null
+++ b/odex-event/muk_web_utils/static/src/js/fields/utils.js
@@ -0,0 +1,54 @@
+/**********************************************************************************
+*
+* Copyright (c) 2017-2019 MuK IT GmbH.
+*
+* This file is part of MuK Web Utils
+* (see https://mukit.at).
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program. If not, see .
+*
+**********************************************************************************/
+
+odoo.define('muk_web_utils.field_utils', function(require) {
+"use strict";
+
+var core = require('web.core');
+var session = require('web.session');
+var utils = require('web.field_utils');
+
+var _t = core._t;
+var QWeb = core.qweb;
+
+function formatBinarySize(value, field, options) {
+ options = _.defaults(options || {}, {
+ si: true,
+ });
+ var thresh = options.si ? 1000 : 1024;
+ if(Math.abs(value) < thresh) {
+ return utils.format['float'](value, field, options) + ' B';
+ }
+ var units = options.si
+ ? ['KB','MB','GB','TB','PB','EB','ZB','YB']
+ : ['KiB','MiB','GiB','TiB','PiB','EiB','ZiB','YiB'];
+ var unit = -1;
+ do {
+ value /= thresh;
+ ++unit;
+ } while(Math.abs(value) >= thresh && unit < units.length - 1);
+ return utils.format['float'](value, field, options) + ' ' + units[unit];
+}
+
+utils.format.binary_size = formatBinarySize;
+
+});
diff --git a/odex-event/muk_web_utils/static/src/js/libs/jquery.js b/odex-event/muk_web_utils/static/src/js/libs/jquery.js
new file mode 100644
index 000000000..84b3314ec
--- /dev/null
+++ b/odex-event/muk_web_utils/static/src/js/libs/jquery.js
@@ -0,0 +1,104 @@
+/**********************************************************************************
+*
+* Copyright (c) 2017-2019 MuK IT GmbH.
+*
+* This file is part of MuK Web Utils
+* (see https://mukit.at).
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program. If not, see .
+*
+**********************************************************************************/
+
+$.fn.textWidth = function(text, font) {
+ if (!$.fn.textWidth.fakeEl) $.fn.textWidth.fakeEl = $('').hide().appendTo(document.body);
+ $.fn.textWidth.fakeEl.text(text || this.val() || this.text()).css('font', font || this.css('font'));
+ return $.fn.textWidth.fakeEl.width();
+};
+
+$.fn.dndHover = function(options) {
+ return this.each(function() {
+ var self = $(this);
+ var collection = $();
+ var dragenter = function(event) {
+ if (collection.size() === 0) {
+ self.trigger('dndHoverStart', [event]);
+ }
+ collection = collection.add(event.target);
+ };
+ var dragleave = function(event) {
+ setTimeout(function() {
+ collection = collection.not(event.target);
+ if (collection.size() === 0) {
+ self.trigger('dndHoverEnd', [event]);
+ }
+ }, 1);
+ };
+ var drop = function(event) {
+ setTimeout(function() {
+ collection = $();
+ self.trigger('dndHoverEnd', [event]);
+ }, 1);
+ };
+ if(options && options === 'destroy') {
+ self.off('dragenter.dnd_hover');
+ self.off('dragleave.dnd_hover');
+ self.off('drop.dnd_hover');
+ } else {
+ self.on('dragenter.dnd_hover', dragenter);
+ self.on('dragleave.dnd_hover', dragleave);
+ self.on('drop.dnd_hover', drop);
+ }
+ });
+};
+
+$.ajaxTransport("+binary", function(options, originalOptions, jqXHR) {
+ if (window.FormData && ((options.dataType && (options.dataType == 'binary')) ||
+ (options.data && ((window.ArrayBuffer && options.data instanceof ArrayBuffer) ||
+ (window.Blob && options.data instanceof Blob))))) {
+ return {
+ send: function(headers, callback){
+ var xhr = new XMLHttpRequest();
+ var url = options.url,
+ type = options.type,
+ async = options.async || true,
+ dataType = options.responseType || 'blob',
+ data = options.data || null,
+ username = options.username,
+ password = options.password;
+ xhr.addEventListener('load', function(){
+ var data = {};
+ data[options.dataType] = xhr.response;
+ callback(xhr.status, xhr.statusText, data, xhr.getAllResponseHeaders());
+ });
+ xhr.open(type, url, async, username, password);
+ for (var i in headers ) {
+ xhr.setRequestHeader(i, headers[i] );
+ }
+ if (options.xhrFields) {
+ for (var key in options.xhrFields) {
+ if (key in xhr) {
+ xhr[key] = options.xhrFields[key];
+ }
+ }
+ }
+ xhr.responseType = dataType;
+ xhr.send(data);
+ },
+ abort: function(){
+ jqXHR.abort();
+ }
+ };
+ }
+});
+
diff --git a/odex-event/muk_web_utils/static/src/js/libs/scrollbar.js b/odex-event/muk_web_utils/static/src/js/libs/scrollbar.js
new file mode 100644
index 000000000..2c889fdb7
--- /dev/null
+++ b/odex-event/muk_web_utils/static/src/js/libs/scrollbar.js
@@ -0,0 +1,27 @@
+/**********************************************************************************
+*
+* Copyright (c) 2017-2019 MuK IT GmbH.
+*
+* This file is part of MuK Web Utils
+* (see https://mukit.at).
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program. If not, see .
+*
+**********************************************************************************/
+
+$.fn.renderScrollBar = function() {
+ this.each(function() {
+ new SimpleBar(this);
+ });
+};
diff --git a/odex-event/muk_web_utils/static/src/js/libs/underscore.js b/odex-event/muk_web_utils/static/src/js/libs/underscore.js
new file mode 100644
index 000000000..a8a4aa84d
--- /dev/null
+++ b/odex-event/muk_web_utils/static/src/js/libs/underscore.js
@@ -0,0 +1,47 @@
+/**********************************************************************************
+*
+* Copyright (c) 2017-2019 MuK IT GmbH.
+*
+* This file is part of MuK Web Utils
+* (see https://mukit.at).
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program. If not, see .
+*
+**********************************************************************************/
+
+_.mixin({
+ memoizeDebounce: function(func, wait, options) {
+ wait = (typeof wait !== 'undefined') ? wait : 0;
+ options = (typeof options !== 'undefined') ? options : {};
+ var mem = _.memoize(function() {
+ return _.debounce(func, wait, options)
+ }, options.resolver);
+ return function() {
+ mem.apply(this, arguments).apply(this, arguments)
+ }
+ }
+});
+
+_.mixin({
+ memoizeThrottle: function(func, wait, options) {
+ wait = (typeof wait !== 'undefined') ? wait : 0;
+ options = (typeof options !== 'undefined') ? options : {};
+ var mem = _.memoize(function() {
+ return _.throttle(func, wait, options)
+ }, options.resolver);
+ return function() {
+ mem.apply(this, arguments).apply(this, arguments)
+ }
+ }
+});
\ No newline at end of file
diff --git a/odex-event/muk_web_utils/static/src/js/services/notification_service.js b/odex-event/muk_web_utils/static/src/js/services/notification_service.js
new file mode 100644
index 000000000..8f5787e70
--- /dev/null
+++ b/odex-event/muk_web_utils/static/src/js/services/notification_service.js
@@ -0,0 +1,37 @@
+/**********************************************************************************
+*
+* Copyright (c) 2017-2019 MuK IT GmbH.
+*
+* This file is part of MuK Web Utils
+* (see https://mukit.at).
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program. If not, see .
+*
+**********************************************************************************/
+
+odoo.define('muk_web_utils.NotificationService', function (require) {
+"use strict";
+
+var NotificationService = require('web.NotificationService');
+
+NotificationService.include({
+ progress: function (notificationId, progress) {
+ if(notificationId in this.notifications) {
+ var notification = this.notifications[notificationId];
+ notification.updateProgress(progress.state, progress.text);
+ }
+ },
+});
+
+});
diff --git a/odex-event/muk_web_utils/static/src/js/views/form/renderer.js b/odex-event/muk_web_utils/static/src/js/views/form/renderer.js
new file mode 100644
index 000000000..496211a98
--- /dev/null
+++ b/odex-event/muk_web_utils/static/src/js/views/form/renderer.js
@@ -0,0 +1,47 @@
+/**********************************************************************************
+*
+* Copyright (c) 2017-2019 MuK IT GmbH.
+*
+* This file is part of MuK Web Utils
+* (see https://mukit.at).
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program. If not, see .
+*
+**********************************************************************************/
+
+odoo.define('muk_web_utils.FormRenderer', function (require) {
+"use strict";
+
+var core = require('web.core');
+
+var FormRenderer = require('web.FormRenderer');
+
+var _t = core._t;
+var QWeb = core.qweb;
+
+FormRenderer.include({
+ _updateView: function ($newContent) {
+ this._super.apply(this, arguments);
+ _.each(this.allFieldWidgets[this.state.id], function (widget) {
+ if (widget.attrs.widget === 'module_boolean') {
+ var inputID = this.idsForLabels[widget.name];
+ var $widgets = this.$('.o_field_widget[name=' + widget.name + ']');
+ var $label = inputID ? this.$('.o_form_label[for=' + inputID + ']') : $();
+ widget.renderWithLabel($label.eq($widgets.index(widget.$el)));
+ }
+ }, this);
+ }
+});
+
+});
\ No newline at end of file
diff --git a/odex-event/muk_web_utils/static/src/js/widgets/notification.js b/odex-event/muk_web_utils/static/src/js/widgets/notification.js
new file mode 100644
index 000000000..b51b63628
--- /dev/null
+++ b/odex-event/muk_web_utils/static/src/js/widgets/notification.js
@@ -0,0 +1,46 @@
+/**********************************************************************************
+*
+* Copyright (c) 2017-2019 MuK IT GmbH.
+*
+* This file is part of MuK Web Utils
+* (see https://mukit.at).
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program. If not, see .
+*
+**********************************************************************************/
+
+odoo.define('muk_web_utils.Notification', function (require) {
+"use strict";
+
+var core = require('web.core');
+
+var Notification = require('web.Notification');
+
+var _t = core._t;
+var QWeb = core.qweb;
+
+Notification.include({
+ init: function (parent, params) {
+ this._super.apply(this, arguments);
+ this.icon = params.icon || this.icon;
+ this.progress = params.progress;
+ },
+ updateProgress: function(state, text) {
+ this.progress = {state: state, text: text};
+ this.$(".progress-bar").text(text);
+ this.$(".progress-bar").width(state + "%");
+ },
+});
+
+});
\ No newline at end of file
diff --git a/odex-event/muk_web_utils/static/src/scss/binary.scss b/odex-event/muk_web_utils/static/src/scss/binary.scss
new file mode 100644
index 000000000..d4541e2df
--- /dev/null
+++ b/odex-event/muk_web_utils/static/src/scss/binary.scss
@@ -0,0 +1,28 @@
+/**********************************************************************************
+*
+* Copyright (c) 2017-2019 MuK IT GmbH.
+*
+* This file is part of MuK Web Utils
+* (see https://mukit.at).
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program. If not, see .
+*
+**********************************************************************************/
+
+.o_list_view .o_field_widget.o_field_binary_file {
+ height: 100%;
+ button.btn {
+ padding-top: 0.25rem;
+ }
+}
diff --git a/odex-event/muk_web_utils/static/src/scss/color.scss b/odex-event/muk_web_utils/static/src/scss/color.scss
new file mode 100644
index 000000000..297f8f927
--- /dev/null
+++ b/odex-event/muk_web_utils/static/src/scss/color.scss
@@ -0,0 +1,66 @@
+/**********************************************************************************
+*
+* Copyright (c) 2017-2019 MuK IT GmbH.
+*
+* This file is part of MuK Web Utils
+* (see https://mukit.at).
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program. If not, see .
+*
+**********************************************************************************/
+
+.mk_field_color_picker {
+ .o_opacity_slider {
+ display: none ! important;
+ }
+ input#opacity {
+ display: none ! important;
+ }
+ label[for="opacity"] {
+ display: none ! important;
+ }
+}
+
+.o_field_widget.mk_field_color {
+ .mk_field_color_input {
+ width: auto;
+ display: inline-block;
+ }
+ .mk_field_color_button {
+ display: inline-block;
+ margin-bottom: 0.25rem;
+ line-height: 1.42rem;
+ }
+}
+
+span.mk_field_color_index {
+ @for $size from 1 through length($o-colors) {
+ &.mk_color_index_#{$size - 1} {
+ color: nth($o-colors, $size);
+ }
+ }
+}
+
+select.mk_field_color_index {
+ &.mk_color_index_0, .mk_color_index_0 {
+ background-color: $white ! important;
+ color: nth($o-colors, 1) ! important;
+ }
+ @for $size from 2 through length($o-colors) {
+ &.mk_color_index_#{$size - 1}, .mk_color_index_#{$size - 1} {
+ background-color: nth($o-colors, $size) ! important;
+ color: $white ! important;
+ }
+ }
+}
\ No newline at end of file
diff --git a/odex-event/muk_web_utils/static/src/scss/copy.scss b/odex-event/muk_web_utils/static/src/scss/copy.scss
new file mode 100644
index 000000000..ff675046c
--- /dev/null
+++ b/odex-event/muk_web_utils/static/src/scss/copy.scss
@@ -0,0 +1,34 @@
+/**********************************************************************************
+*
+* Copyright (c) 2017-2019 MuK IT GmbH.
+*
+* This file is part of MuK Web Utils
+* (see https://mukit.at).
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program. If not, see .
+*
+**********************************************************************************/
+
+.o_field_widget.mk_field_copy {
+ .mk_copy_binary {
+ margin-left: 0.5rem;
+ .mk_copy_button {
+ font-size: 0.8rem;
+ line-height: 0.5;
+ border-radius: 0.2rem;
+ margin-bottom: 0.12rem;
+ padding: 0.25rem 0.4rem;
+ }
+ }
+}
\ No newline at end of file
diff --git a/odex-event/muk_web_utils/static/src/scss/dropzone.scss b/odex-event/muk_web_utils/static/src/scss/dropzone.scss
new file mode 100644
index 000000000..337ffbfce
--- /dev/null
+++ b/odex-event/muk_web_utils/static/src/scss/dropzone.scss
@@ -0,0 +1,64 @@
+/**********************************************************************************
+*
+* Copyright (c) 2017-2019 MuK IT GmbH.
+*
+* This file is part of MuK Web Utils
+* (see https://mukit.at).
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program. If not, see .
+*
+**********************************************************************************/
+
+.mk_dropzone {
+ position: relative;
+ &:before {
+ display:flex;
+ z-index: 1052;
+ color: gray('700');
+ flex-direction:row;
+ align-items: center;
+ justify-content: center;
+ width: #{"calc(100% - 20px)"};
+ height: #{"calc(100% - 20px)"};
+ border: 2px dashed gray('700');
+ @include gradient-y($white, gray('100'));
+ @include o-position-absolute(10px, 0, 0, 10px);
+ }
+ &:after {
+ display:flex;
+ z-index: 1052;
+ color: gray('700');
+ flex-direction:row;
+ align-items: center;
+ justify-content: center;
+ width: #{"calc(100% - 20px)"};
+ height: #{"calc(100% - 10px)"};
+ @include o-position-absolute(0, 0, 0, 0);
+ }
+ &.mk_dropzone_file {
+ &:before {
+ font-family: FontAwesome;
+ text-decoration: inherit;
+ font-style: normal;
+ font-weight: normal;
+ font-size: 15rem;
+ content: "\f0ee";
+ }
+ &:after {
+ padding-top: 18rem;
+ font-size: 3rem;
+ content: attr(data-dropzone-text);
+ }
+ }
+}
\ No newline at end of file
diff --git a/odex-event/muk_web_utils/static/src/scss/image.scss b/odex-event/muk_web_utils/static/src/scss/image.scss
new file mode 100644
index 000000000..e78e9a386
--- /dev/null
+++ b/odex-event/muk_web_utils/static/src/scss/image.scss
@@ -0,0 +1,84 @@
+/**********************************************************************************
+*
+* Copyright (c) 2017-2019 MuK IT GmbH.
+*
+* This file is part of MuK Web Utils
+* (see https://mukit.at).
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program. If not, see .
+*
+**********************************************************************************/
+
+.o_field_widget.o_field_image {
+ @include media-breakpoint-up(sm, $o-extra-grid-breakpoints) {
+ .mk_field_image_wrapper {
+ min-height: 60px;
+ min-width: 80px;
+ }
+ }
+ .mk_form_image_controls {
+ @include o-position-absolute($left: 0, $bottom: 0);
+ width: 100%;
+ color: white;
+ background-color: $o-brand-primary;
+ opacity: 0;
+ transition: opacity ease 400ms;
+ > button.fa {
+ border: none;
+ background-color: transparent;
+ }
+ > .fa {
+ margin: 5px;
+ cursor: pointer;
+ }
+ }
+ &:hover .mk_form_image_controls {
+ opacity: 0.8;
+ }
+ @include media-breakpoint-down(xs, $o-extra-grid-breakpoints) {
+ .mk_form_image_controls{
+ position: initial;
+ opacity: 1;
+ > .fa{
+ width: 50%;
+ padding: 6px;
+ margin: 0px;
+ text-align: center;
+ background: $o-brand-secondary;
+ }
+ }
+ }
+}
+
+.o_field_widget.o_field_image.oe_avatar {
+ .mk_form_image_controls {
+ @include o-position-absolute($left: 0, $bottom: 10px);
+ }
+ img {
+ box-shadow: 0 1px 4px rgba(0, 0, 0, 0.4);
+ max-width: $o-avatar-size;
+ max-height: $o-avatar-size;
+ vertical-align: top;
+ margin-bottom: 10px;
+ border: none;
+ }
+ @include media-breakpoint-down(xs, $o-extra-grid-breakpoints) {
+ .mk_form_image_controls{
+ position: initial;
+ > .fa{
+ background: $o-brand-secondary;
+ }
+ }
+ }
+}
diff --git a/odex-event/muk_web_utils/static/src/scss/mixins.scss b/odex-event/muk_web_utils/static/src/scss/mixins.scss
new file mode 100644
index 000000000..4c6e540e2
--- /dev/null
+++ b/odex-event/muk_web_utils/static/src/scss/mixins.scss
@@ -0,0 +1,40 @@
+/**********************************************************************************
+*
+* Copyright (c) 2017-2019 MuK IT GmbH.
+*
+* This file is part of MuK Web Utils
+* (see https://mukit.at).
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program. If not, see .
+*
+**********************************************************************************/
+
+@mixin mk-flex-container ($direction: row, $wrap: nowrap, $justify: flex-start, $items: stretch, $content: stretch) {
+ display: flex;
+ flex-wrap: $wrap;
+ flex-direction: $direction;
+ justify-content: $justify;
+ align-content: $content;
+ align-items: $items;
+}
+
+@mixin mk-flex-child ($grow: 0, $shrink: 1, $basis: auto, $order: 0) {
+ display: flex;
+ flex-grow: $grow;
+ flex-shrink: $shrink;
+ flex-basis: $basis;
+ order: $order;
+}
+
+
diff --git a/odex-event/muk_web_utils/static/src/scss/module.scss b/odex-event/muk_web_utils/static/src/scss/module.scss
new file mode 100644
index 000000000..0a30d94a2
--- /dev/null
+++ b/odex-event/muk_web_utils/static/src/scss/module.scss
@@ -0,0 +1,33 @@
+/**********************************************************************************
+*
+* Copyright (c) 2017-2019 MuK IT GmbH.
+*
+* This file is part of MuK Web Utils
+* (see https://mukit.at).
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program. If not, see .
+*
+**********************************************************************************/
+
+.o_settings_container {
+ .o_setting_box {
+ .o_setting_left_pane {
+ .mk_module_label {
+ position: absolute;
+ top: 0px;
+ right: 40px;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/odex-event/muk_web_utils/static/src/scss/notification.scss b/odex-event/muk_web_utils/static/src/scss/notification.scss
new file mode 100644
index 000000000..4caf3397d
--- /dev/null
+++ b/odex-event/muk_web_utils/static/src/scss/notification.scss
@@ -0,0 +1,30 @@
+/**********************************************************************************
+*
+* Copyright (c) 2017-2019 MuK IT GmbH.
+*
+* This file is part of MuK Web Utils
+* (see https://mukit.at).
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program. If not, see .
+*
+**********************************************************************************/
+
+.o_notification {
+ .mk_notification_progress {
+ padding: 2px 10px 10px 10px;
+ .progress {
+ background-color: rgba(0, 0, 0, 0.3);
+ }
+ }
+}
diff --git a/odex-event/muk_web_utils/static/src/scss/share.scss b/odex-event/muk_web_utils/static/src/scss/share.scss
new file mode 100644
index 000000000..37fa64ecb
--- /dev/null
+++ b/odex-event/muk_web_utils/static/src/scss/share.scss
@@ -0,0 +1,54 @@
+/**********************************************************************************
+*
+* Copyright (c) 2017-2019 MuK IT GmbH.
+*
+* This file is part of MuK Web Utils
+* (see https://mukit.at).
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program. If not, see .
+*
+**********************************************************************************/
+
+.o_field_widget.mk_field_share {
+ &.o_field_copy {
+ padding-left: 90px;
+ .mk_share_dropdown {
+ @include o-position-absolute($top: 0, $left: 0);
+ .mk_share_button {
+ padding: 0 10px;
+ }
+ &.mk_share_char {
+ height: 100%;
+
+ }
+ &.mk_share_text {
+ .dropdown-menu {
+ line-height: 0.1
+ }
+ }
+ }
+ }
+ &.o_form_uri {
+ .mk_share_dropdown {
+ margin-left: 0.2rem;
+ .mk_share_button {
+ padding: 0.25rem 0.4rem;
+ font-size: 0.8rem;
+ line-height: 0.5;
+ border-radius: 0.2rem;
+ margin-bottom: 0.12rem;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/odex-event/muk_web_utils/static/src/scss/switch.scss b/odex-event/muk_web_utils/static/src/scss/switch.scss
new file mode 100644
index 000000000..7fe9d6eb0
--- /dev/null
+++ b/odex-event/muk_web_utils/static/src/scss/switch.scss
@@ -0,0 +1,158 @@
+/**********************************************************************************
+*
+* Copyright (c) 2017-2019 MuK IT GmbH.
+*
+* This file is part of MuK Web Utils
+* (see https://mukit.at).
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program. If not, see .
+*
+**********************************************************************************/
+
+.switch {
+ font-size: $font-size-base;
+ position: relative;
+
+ input {
+ position: absolute;
+ height: 1px;
+ width: 1px;
+ background: none;
+ border: 0;
+ clip: rect(0 0 0 0);
+ clip-path: inset(50%);
+ overflow: hidden;
+ padding: 0;
+
+ + label {
+ position: relative;
+ min-width: calc(#{$switch-height} * 2);
+ border-radius: $switch-border-radius;
+ height: $switch-height;
+ line-height: $switch-height;
+ display: inline-block;
+ cursor: pointer;
+ outline: none;
+ user-select: none;
+ vertical-align: middle;
+ text-indent: calc(calc(#{$switch-height} * 2) + .5rem);
+ }
+
+ + label::before,
+ + label::after {
+ content: '';
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: calc(#{$switch-height} * 2);
+ bottom: 0;
+ display: block;
+ }
+
+ + label::before {
+ right: 0;
+ background-color: $switch-bg;
+ border-radius: $switch-border-radius;
+ transition: $switch-transition;
+ }
+
+ + label::after {
+ top: $switch-thumb-padding;
+ left: $switch-thumb-padding;
+ width: calc(#{$switch-height} - calc(#{$switch-thumb-padding} * 2));
+ height: calc(#{$switch-height} - calc(#{$switch-thumb-padding} * 2));
+ border-radius: $switch-thumb-border-radius;
+ background-color: $switch-thumb-bg;
+ transition: $switch-transition;
+ }
+
+ &:checked + label::before {
+ background-color: $switch-checked-bg;
+ }
+
+ &:checked + label::after {
+ margin-left: $switch-height;
+ }
+
+ &:focus + label::before {
+ outline: none;
+ box-shadow: $switch-focus-box-shadow;
+ }
+
+ &:disabled + label {
+ color: $switch-disabled-color;
+ cursor: not-allowed;
+ }
+
+ &:disabled + label::before {
+ background-color: $switch-disabled-bg;
+ }
+ }
+
+ &.switch-sm {
+ font-size: $font-size-sm;
+
+ input {
+ + label {
+ min-width: calc(#{$switch-height-sm} * 2);
+ height: $switch-height-sm;
+ line-height: $switch-height-sm;
+ text-indent: calc(calc(#{$switch-height-sm} * 2) + .5rem);
+ }
+
+ + label::before {
+ width: calc(#{$switch-height-sm} * 2);
+ }
+
+ + label::after {
+ width: calc(#{$switch-height-sm} - calc(#{$switch-thumb-padding} * 2));
+ height: calc(#{$switch-height-sm} - calc(#{$switch-thumb-padding} * 2));
+ }
+
+ &:checked + label::after {
+ margin-left: $switch-height-sm;
+ }
+ }
+ }
+
+ &.switch-lg {
+ font-size: $font-size-lg;
+
+ input {
+ + label {
+ min-width: calc(#{$switch-height-lg} * 2);
+ height: $switch-height-lg;
+ line-height: $switch-height-lg;
+ text-indent: calc(calc(#{$switch-height-lg} * 2) + .5rem);
+ }
+
+ + label::before {
+ width: calc(#{$switch-height-lg} * 2);
+ }
+
+ + label::after {
+ width: calc(#{$switch-height-lg} - calc(#{$switch-thumb-padding} * 2));
+ height: calc(#{$switch-height-lg} - calc(#{$switch-thumb-padding} * 2));
+ }
+
+ &:checked + label::after {
+ margin-left: $switch-height-lg;
+ }
+ }
+ }
+
+ + .switch {
+ margin-left: 1rem;
+ }
+}
\ No newline at end of file
diff --git a/odex-event/muk_web_utils/static/src/scss/variables.scss b/odex-event/muk_web_utils/static/src/scss/variables.scss
new file mode 100644
index 000000000..74fa8ca27
--- /dev/null
+++ b/odex-event/muk_web_utils/static/src/scss/variables.scss
@@ -0,0 +1,39 @@
+/**********************************************************************************
+*
+* Copyright (c) 2017-2019 MuK IT GmbH.
+*
+* This file is part of MuK Web Utils
+* (see https://mukit.at).
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program. If not, see .
+*
+**********************************************************************************/
+
+//----------------------------------------------------------
+// Switch
+//----------------------------------------------------------
+
+$switch-bg: #dee2e6;
+$switch-disabled-bg: #e9ecef;
+$switch-disabled-color: #868e96;
+$switch-height: calc(#{$input-height} * .8) !default;
+$switch-height-sm: calc(#{$input-height-sm} * .8) !default;
+$switch-height-lg: calc(#{$input-height-lg} * .8) !default;
+$switch-checked-bg: map-get($theme-colors, 'primary') !default;
+$switch-thumb-bg: $white !default;
+$switch-thumb-border-radius: 50% !default;
+$switch-thumb-padding: 2px !default;
+$switch-transition: .2s all !default;
+$switch-border-radius: $switch-height;
+$switch-focus-box-shadow: 0 0 0 $input-btn-focus-width rgba(map-get($theme-colors, 'primary'), .25);
\ No newline at end of file
diff --git a/odex-event/muk_web_utils/static/src/xml/color.xml b/odex-event/muk_web_utils/static/src/xml/color.xml
new file mode 100644
index 000000000..ecbc10d72
--- /dev/null
+++ b/odex-event/muk_web_utils/static/src/xml/color.xml
@@ -0,0 +1,65 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/odex-event/muk_web_utils/static/src/xml/copy.xml b/odex-event/muk_web_utils/static/src/xml/copy.xml
new file mode 100644
index 000000000..4a21900f3
--- /dev/null
+++ b/odex-event/muk_web_utils/static/src/xml/copy.xml
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/odex-event/muk_web_utils/static/src/xml/image.xml b/odex-event/muk_web_utils/static/src/xml/image.xml
new file mode 100644
index 000000000..824c3af56
--- /dev/null
+++ b/odex-event/muk_web_utils/static/src/xml/image.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/odex-event/muk_web_utils/static/src/xml/module.xml b/odex-event/muk_web_utils/static/src/xml/module.xml
new file mode 100644
index 000000000..0709de484
--- /dev/null
+++ b/odex-event/muk_web_utils/static/src/xml/module.xml
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
The module could not be found on the server.
+
Click on the download button to be redirected to the store and download the corresponding module.
+
+
+
+
+
\ No newline at end of file
diff --git a/odex-event/muk_web_utils/static/src/xml/notification.xml b/odex-event/muk_web_utils/static/src/xml/notification.xml
new file mode 100644
index 000000000..2ed595a5a
--- /dev/null
+++ b/odex-event/muk_web_utils/static/src/xml/notification.xml
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/odex-event/muk_web_utils/static/src/xml/share.xml b/odex-event/muk_web_utils/static/src/xml/share.xml
new file mode 100644
index 000000000..64bcee4de
--- /dev/null
+++ b/odex-event/muk_web_utils/static/src/xml/share.xml
@@ -0,0 +1,106 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/odex-event/muk_web_utils/static/src/xml/switch.xml b/odex-event/muk_web_utils/static/src/xml/switch.xml
new file mode 100644
index 000000000..cb9e742a5
--- /dev/null
+++ b/odex-event/muk_web_utils/static/src/xml/switch.xml
@@ -0,0 +1,54 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/odex-event/muk_web_utils/static/tests/fields.js b/odex-event/muk_web_utils/static/tests/fields.js
new file mode 100644
index 000000000..6af0e6f30
--- /dev/null
+++ b/odex-event/muk_web_utils/static/tests/fields.js
@@ -0,0 +1,205 @@
+/**********************************************************************************
+*
+* Copyright (c) 2017-2019 MuK IT GmbH.
+*
+* This file is part of MuK Web Utils
+* (see https://mukit.at).
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program. If not, see .
+*
+**********************************************************************************/
+odoo.define('muk_web_utils.tests.fields', function (require) {
+"use strict";
+
+var basicFields = require('web.basic_fields');
+var concurrency = require('web.concurrency');
+var config = require('web.config');
+var core = require('web.core');
+var FormView = require('web.FormView');
+var KanbanView = require('web.KanbanView');
+var ListView = require('web.ListView');
+var session = require('web.session');
+var testUtils = require('web.test_utils');
+var field_registry = require('web.field_registry');
+
+var createView = testUtils.createView;
+var createAsyncView = testUtils.createAsyncView;
+var DebouncedField = basicFields.DebouncedField;
+var JournalDashboardGraph = basicFields.JournalDashboardGraph;
+var _t = core._t;
+
+QUnit.module('muk_web_utils', {}, function () {
+
+QUnit.module('fields', {
+ beforeEach: function () {
+ this.data = {
+ partner: {
+ fields: {
+ display_name: {
+ string: "Displayed name",
+ type: "char",
+ searchable: true
+ },
+ short: {
+ string: "Short",
+ type: "char",
+ searchable: true,
+ trim: true
+ },
+ long: {
+ string: "Long",
+ string: "txt",
+ type: "text",
+ },
+ document: {
+ string: "Binary",
+ type: "binary",
+ attachment: true,
+ },
+ },
+ records: [{
+ id: 1,
+ display_name: "first record",
+ short: "Short Text",
+ long: "Super looooooong Text",
+ document: 'coucou==\n',
+ }],
+ },
+ };
+ }
+}, function () {
+ QUnit.module('BinaryFileCopy');
+
+ QUnit.test('Fields is correctly rendered', function (assert) {
+ assert.expect(2);
+
+ var form = createView({
+ View: FormView,
+ model: 'partner',
+ data: this.data,
+ arch: (
+ ''
+ ),
+ res_id: 1,
+ });
+
+ assert.strictEqual(
+ form.$('a.o_field_widget[name="document"] > .mk_copy_binary > .mk_copy_button').length,
+ 1, "the copy button should be visible in readonly mode"
+ );
+
+ form.$buttons.find('.o_form_button_edit').click();
+
+ assert.strictEqual(
+ form.$('a.o_field_widget[name="document"] > .mk_copy_binary').length,
+ 0, "the copy button shouldn't be visible in edit mode"
+ );
+
+ form.destroy();
+ });
+
+ QUnit.module('CharShare');
+
+ QUnit.test('Fields is correctly rendered', function (assert) {
+ assert.expect(1);
+
+ var form = createView({
+ View: FormView,
+ model: 'partner',
+ data: this.data,
+ arch: (
+ ''
+ ),
+ res_id: 1,
+ });
+
+ assert.strictEqual(
+ form.$('span.o_field_widget[name="short"] > .mk_share_dropdown.mk_share_char').length,
+ 1, "the copy button should be visible in readonly mode"
+ );
+
+ form.destroy();
+ });
+
+ QUnit.module('TextShare');
+
+ QUnit.test('Fields is correctly rendered', function (assert) {
+ assert.expect(1);
+
+ var form = createView({
+ View: FormView,
+ model: 'partner',
+ data: this.data,
+ arch: (
+ ''
+ ),
+ res_id: 1,
+ });
+
+ assert.strictEqual(
+ form.$('span.o_field_widget[name="long"] > .mk_share_dropdown.mk_share_text').length,
+ 1, "the copy button should be visible in readonly mode"
+ );
+
+ form.destroy();
+ });
+
+ QUnit.module('BinaryFileShare');
+
+ QUnit.test('Fields is correctly rendered', function (assert) {
+ assert.expect(2);
+
+ var form = createView({
+ View: FormView,
+ model: 'partner',
+ data: this.data,
+ arch: (
+ ''
+ ),
+ res_id: 1,
+ });
+
+ assert.strictEqual(
+ form.$('a.o_field_widget[name="document"] > .mk_share_dropdown > .mk_share_button').length,
+ 1, "the share dropdown should be visible in readonly mode"
+ );
+
+ form.$buttons.find('.o_form_button_edit').click();
+
+ assert.strictEqual(
+ form.$('a.o_field_widget[name="document"] > .mk_share_dropdown > .mk_share_button').length,
+ 0, "the share dropdown shouldn't be visible in edit mode"
+ );
+
+ form.destroy();
+ });
+});
+
+});
+
+});
\ No newline at end of file
diff --git a/odex-event/muk_web_utils/template/assets.xml b/odex-event/muk_web_utils/template/assets.xml
new file mode 100644
index 000000000..1386b49d4
--- /dev/null
+++ b/odex-event/muk_web_utils/template/assets.xml
@@ -0,0 +1,79 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/odex-event/muk_web_utils/tests/__init__.py b/odex-event/muk_web_utils/tests/__init__.py
new file mode 100644
index 000000000..0c50c4c5d
--- /dev/null
+++ b/odex-event/muk_web_utils/tests/__init__.py
@@ -0,0 +1,23 @@
+###################################################################################
+#
+# Copyright (c) 2017-2019 MuK IT GmbH.
+#
+# This file is part of MuK Web Utils
+# (see https://mukit.at).
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see .
+#
+###################################################################################
+
+from . import test_js
diff --git a/odex-event/muk_web_utils/tests/test_js.py b/odex-event/muk_web_utils/tests/test_js.py
new file mode 100644
index 000000000..39266f6ef
--- /dev/null
+++ b/odex-event/muk_web_utils/tests/test_js.py
@@ -0,0 +1,41 @@
+###################################################################################
+#
+# Copyright (c) 2017-2019 MuK IT GmbH.
+#
+# This file is part of MuK Web Utils
+# (see https://mukit.at).
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see .
+#
+###################################################################################
+
+import os
+import json
+import logging
+import requests
+import unittest
+
+from odoo import _, http, tools, SUPERUSER_ID
+from odoo.tests.common import HttpCase
+
+from odoo.addons.muk_utils.tools.json import RecordEncoder
+
+_path = os.path.dirname(os.path.dirname(__file__))
+_logger = logging.getLogger(__name__)
+
+class WebSuite(HttpCase):
+
+ @unittest.skip("")
+ def test_js(self):
+ self.browser_js('/web/tests?module=muk_web_utils&failfast', "", "", login='admin', timeout=1800)
\ No newline at end of file
diff --git a/odex-event/muk_web_utils/views/res_config_settings_view.xml b/odex-event/muk_web_utils/views/res_config_settings_view.xml
new file mode 100644
index 000000000..e9ea79e46
--- /dev/null
+++ b/odex-event/muk_web_utils/views/res_config_settings_view.xml
@@ -0,0 +1,49 @@
+
+
+
+
+
+
+
+ res.config.settings.view.form
+ res.config.settings
+
+
+