diff --git a/document_choose_directory/__init__.py b/document_choose_directory/__init__.py new file mode 100644 index 00000000..fcf92314 --- /dev/null +++ b/document_choose_directory/__init__.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# This module copyright (C) 2014 Therp BV (). +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## +from . import model diff --git a/document_choose_directory/__openerp__.py b/document_choose_directory/__openerp__.py new file mode 100644 index 00000000..ef229693 --- /dev/null +++ b/document_choose_directory/__openerp__.py @@ -0,0 +1,72 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# This module copyright (C) 2014 Therp BV (). +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## +{ + "name": "Choose a document's directory during upload", + "version": "1.0", + "author": "Therp BV", + "license": "AGPL-3", + "complexity": "normal", + "description": """ +Introduction +============ + +This addons enables users to choose a directory while uploading a file. In +combination with access permissions on directories, this can be used to +restrict access on certain records' attachments or simply for a better +overview. + +Configuration +============= + +Create a static directory and choose the resource model you want to use this +directory on. Assign groups to whom this directory should be accessible. When +uploading a files, users can select one of the directories they have access to, +or no directory which is the default setting. + +Keep in mind that if a directory has a owner, it's only visible for this user, +that's probably not what you want. + """, + "category": "Knowledge", + "depends": [ + 'document', + 'web', + ], + "data": [ + "view/document_directory.xml", + ], + "js": [ + 'static/src/js/document_choose_directory.js', + ], + "css": [ + 'static/src/css/document_choose_directory.css', + ], + "qweb": [ + 'static/src/xml/document_choose_directory.xml', + ], + "test": [ + ], + "auto_install": False, + "installable": True, + "application": False, + "external_dependencies": { + 'python': [], + }, +} diff --git a/document_choose_directory/i18n/document_choose_directory.pot b/document_choose_directory/i18n/document_choose_directory.pot new file mode 100644 index 00000000..0ffa4227 --- /dev/null +++ b/document_choose_directory/i18n/document_choose_directory.pot @@ -0,0 +1,41 @@ +# Translation of OpenERP Server. +# This file contains the translation of the following modules: +# * document_choose_directory +# +msgid "" +msgstr "" +"Project-Id-Version: OpenERP Server 7.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2014-07-30 11:27+0000\n" +"PO-Revision-Date: 2014-07-30 11:27+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: document_choose_directory +#. openerp-web +#: code:addons/document_choose_directory/static/src/xml/document_choose_directory.xml:6 +#, python-format +msgid "Choose directory" +msgstr "" + +#. module: document_choose_directory +#: model:ir.model,name:document_choose_directory.model_document_directory +msgid "Directory" +msgstr "" + +#. module: document_choose_directory +#. openerp-web +#: code:addons/document_choose_directory/static/src/js/document_choose_directory.js:64 +#, python-format +msgid "No directory" +msgstr "" + +#. module: document_choose_directory +#: model:ir.model,name:document_choose_directory.model_ir_attachment +msgid "ir.attachment" +msgstr "" + diff --git a/document_choose_directory/i18n/nl.po b/document_choose_directory/i18n/nl.po new file mode 100644 index 00000000..dc0464f4 --- /dev/null +++ b/document_choose_directory/i18n/nl.po @@ -0,0 +1,35 @@ +# Translation of OpenERP Server. +# This file contains the translation of the following modules: +# * document_choose_directory +# +msgid "" +msgstr "" +"Project-Id-Version: OpenERP Server 7.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2014-07-30 11:27+0000\n" +"PO-Revision-Date: 2014-07-30 11:27+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: document_choose_directory +#. openerp-web +#: code:addons/document_choose_directory/static/src/xml/document_choose_directory.xml:6 +#, python-format +msgid "Choose directory" +msgstr "Kies map" + +#. module: document_choose_directory +#: model:ir.model,name:document_choose_directory.model_document_directory +msgid "Directory" +msgstr "Map" + +#. module: document_choose_directory +#. openerp-web +#: code:addons/document_choose_directory/static/src/js/document_choose_directory.js:64 +#, python-format +msgid "No directory" +msgstr "Geen map" diff --git a/document_choose_directory/model/__init__.py b/document_choose_directory/model/__init__.py new file mode 100644 index 00000000..a3ba9590 --- /dev/null +++ b/document_choose_directory/model/__init__.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# This module copyright (C) 2014 Therp BV (). +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## +from . import document_directory +from . import ir_attachment diff --git a/document_choose_directory/model/document_directory.py b/document_choose_directory/model/document_directory.py new file mode 100644 index 00000000..7c6faf1e --- /dev/null +++ b/document_choose_directory/model/document_directory.py @@ -0,0 +1,74 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# This module copyright (C) 2014 Therp BV (). +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## +from openerp.osv.orm import Model + + +class DocumentDirectory(Model): + _inherit = 'document.directory' + + def _get_candidates_for_resource(self, cr, uid, res_model, res_id, + context=None): + '''return directories that can be chosen for a certain record of a + certain model - called by js api, override as needed''' + result = [] + for this in self.browse( + cr, uid, + self.search( + cr, uid, + [ + ('type', '=', 'directory'), + ('ressource_type_id.model', '=', res_model), + ], + context=context), + context=context): + #TODO: add write tests + result.append(this) + return result + + def get_candidates_for_resource(self, cr, uid, res_model, res_id, + context=None): + '''return directories that can be chosen for a certain record of a + certain model - js api''' + result = [] + for this in self._get_candidates_for_resource( + cr, uid, res_model, res_id, context=context): + result.append({ + 'id': this.id, + 'name': this.name_get()[0][1], + }) + return result + + def _register_hook(self, cr): + from openerp.addons.web.http import httprequest + from openerp.addons.web.controllers.main import Binary + original = Binary.upload_attachment + @httprequest + def upload_attachment(self, req, callback, model, id, ufile, + directory_id=None): + if directory_id: + # we can't use default_parent_id because of + # the ir_attachment.create overwrite in document + req.context['parent_id'] = int(directory_id) + # fallback if the aboev is ever fixed + req.context['default_parent_id'] = int(directory_id) + return original(self, req, callback, model, id, ufile) + + Binary.upload_attachment = upload_attachment diff --git a/document_choose_directory/model/ir_attachment.py b/document_choose_directory/model/ir_attachment.py new file mode 100644 index 00000000..56ea6f76 --- /dev/null +++ b/document_choose_directory/model/ir_attachment.py @@ -0,0 +1,55 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# This module copyright (C) 2014 Therp BV (). +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## +from openerp.osv.orm import Model +from openerp.osv import fields + + +class IrAttachment(Model): + _inherit = 'ir.attachment' + + def _auto_init(self, cr, context=None): + '''drop filename_unique if it exists and prevent it from being + created''' + cr.execute('''SELECT + conname, pg_catalog.pg_get_constraintdef(oid, true) as condef + FROM pg_constraint where conname=%s''', + ('ir_attachment_filename_unique',)) + if cr.fetchone(): + cr.execute( + 'ALTER TABLE "%s" DROP CONSTRAINT "%s"' % ( + self._table, 'ir_attachment_filename_unique')) + self._sql_constraints = filter( + lambda x: x[0] != 'filename_unique', self._sql_constraints) + return super(IrAttachment, self)._auto_init(cr, context=context) + + def read(self, cr, uid, ids, fields_to_read=None, context=None, + load='_classic_read'): + '''inject the extra field we need in the web client. This saves us a + couple of extra client side calls''' + if fields_to_read == ['name', 'url', 'type', 'create_uid', + 'create_date', 'write_uid', 'write_date']: + fields_to_read = fields_to_read + ['parent_id'] + result = super(IrAttachment, self).read( + cr, uid, ids, fields_to_read=fields_to_read, context=context, + load=load) + return result + + diff --git a/document_choose_directory/static/src/css/document_choose_directory.css b/document_choose_directory/static/src/css/document_choose_directory.css new file mode 100644 index 00000000..b0ae9693 --- /dev/null +++ b/document_choose_directory/static/src/css/document_choose_directory.css @@ -0,0 +1,32 @@ +.openerp .oe_sidebar .oe_dropdown_menu .oe_sidebar_add_attachment .oe_hidden_input_file, +.oe_sidebar_add_attachment .oe_form_binary_form +{ + width: 100%; +} +.oe_sidebar_add_attachment .oe_form_binary_form select +{ + display: block; + min-width: 100%; +} +.openerp .oe_sidebar_add_attachment .oe_hidden_input_file input.oe_form_binary_file +{ + top: 2em; +} +.openerp .oe_sidebar .oe_dropdown_menu .oe_sidebar_add_attachment +{ + height: 3.5em; +} +li.oe_attachment_directory +{ + font-weight: bold; +} +.openerp .oe_dropdown_menu > li.oe_attachment_directory:hover +{ + background-color: inherit; + background-image: inherit; + box-shadow: none; +} +.openerp .oe_dropdown_menu > li.oe_attachment_directory a:hover +{ + cursor: default !important; +} diff --git a/document_choose_directory/static/src/img/icon.png b/document_choose_directory/static/src/img/icon.png new file mode 100644 index 00000000..ac14079a Binary files /dev/null and b/document_choose_directory/static/src/img/icon.png differ diff --git a/document_choose_directory/static/src/js/document_choose_directory.js b/document_choose_directory/static/src/js/document_choose_directory.js new file mode 100644 index 00000000..d5de0e68 --- /dev/null +++ b/document_choose_directory/static/src/js/document_choose_directory.js @@ -0,0 +1,84 @@ +//-*- coding: utf-8 -*- +//############################################################################ +// +// OpenERP, Open Source Management Solution +// This module copyright (C) 2014 Therp BV (). +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . +// +//############################################################################ + +openerp.document_choose_directory = function(instance) +{ + instance.web.Sidebar.include( + { + init: function() + { + this._super.apply(this, arguments); + this.directory_candidates = []; + }, + do_attachement_update: function(dataset, model_id, args) + { + var document_folder = new instance.web.Model( + 'document.directory', dataset.get_context()), + self = this, + _super = this._super; + return document_folder.call( + 'get_candidates_for_resource', [dataset.model, model_id]) + .then(function(records) + { + self.directory_candidates = records; + self.$el.on( + //suppress html's onclick event that would close the + //menu + 'click', 'select[name="directory_id"]', + function(e) {e.stopPropagation()}); + }) + .then(function() + { + _super.apply(self, [dataset, model_id, args]); + }); + }, + on_attachments_loaded: function(attachments) + { + var attachments_per_directory = []; + _.chain(attachments) + .groupBy( + function(a) { return a.parent_id[0] }) + .each( + function(group) + { + attachments_per_directory.push({ + name: _.first(group).parent_id[1] || + instance.web._t('No directory'), + classname: 'oe_attachment_directory', + }); + _(group).each(function(a) + { + attachments_per_directory.push(a); + }); + }); + + return this._super(attachments_per_directory); + }, + get_directory_items: function(items) + { + return _(items).filter( + function(i) + { + return i.classname == 'oe_attachment_directory'; + }); + }, + }); +} diff --git a/document_choose_directory/static/src/xml/document_choose_directory.xml b/document_choose_directory/static/src/xml/document_choose_directory.xml new file mode 100644 index 00000000..650a40ee --- /dev/null +++ b/document_choose_directory/static/src/xml/document_choose_directory.xml @@ -0,0 +1,19 @@ + + + + + + + + this.attr('t-if', "section.name == 'files' and !item.callback and item.classname != 'oe_attachment_directory'"); + + + this.attr('t-raw', "(widget.items[section.name].length - widget.get_directory_items(widget.items[section.name]).length) || ''"); + + + diff --git a/document_choose_directory/view/document_directory.xml b/document_choose_directory/view/document_directory.xml new file mode 100644 index 00000000..033b12c5 --- /dev/null +++ b/document_choose_directory/view/document_directory.xml @@ -0,0 +1,20 @@ + + + + + document.directory + + + + + + + {'invisible': [('type', '!=', 'ressource')]} + + + {'invisible': [('type', '!=', 'ressource')]} + + + + +