diff --git a/mass_editing/ChangeLog.txt b/mass_editing/ChangeLog.txt
new file mode 100755
index 0000000..143abf1
--- /dev/null
+++ b/mass_editing/ChangeLog.txt
@@ -0,0 +1,11 @@
+===============================================================================
+ Version Change Log (mass_editing)
+===============================================================================
+1.3 * March 11,2013 : Serpent Consulting Services
+ * Improved and optimized the code of mass_editing
+
+1.2 * Feb 14,2013 : Serpent Consulting Services
+ * Corrected code as per the review by Community
+
+1.1 * Feb 12,2013 : Serpent Consulting Services
+ * Added the module
diff --git a/mass_editing/__init__.py b/mass_editing/__init__.py
new file mode 100644
index 0000000..686e4a8
--- /dev/null
+++ b/mass_editing/__init__.py
@@ -0,0 +1,24 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# This module uses OpenERP, Open Source Management Solution Framework.
+# Copyright (C):
+# 2012-Today Serpent Consulting Services (
+#
+##############################################################################
+
+from . import models
+from . import wizard
diff --git a/mass_editing/__openerp__.py b/mass_editing/__openerp__.py
new file mode 100644
index 0000000..3be5587
--- /dev/null
+++ b/mass_editing/__openerp__.py
@@ -0,0 +1,50 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# This module uses OpenERP, Open Source Management Solution Framework.
+# Copyright (C):
+# 2012-Today Serpent Consulting Services ()
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see
+#
+##############################################################################
+{
+ "name": "Mass Editing",
+ "version": "1.3",
+ "author": "Serpent Consulting Services",
+ "contributors": [
+ "Oihane Crucelaegui ",
+ ],
+ "category": "Tools",
+ "website": "http://www.serpentcs.com",
+ "description": """
+ This module provides the functionality to add, update or remove the values
+ of more than one records on the fly at the same time.
+ You can configure mass editing for any OpenERP model.
+ The video explaining the features and how-to for OpenERP Version 6
+ is here http://t.co/wukYMx1A
+ The video explaining the features and how-to for OpenERP Version 7 is
+ here : http://www.youtube.com/watch?v=9BH0o74A748&feature=youtu.be
+ For more details/customization/feedback contact us on
+ contact@serpentcs.com.
+ """,
+ 'depends': ['base'],
+ 'data': [
+ "security/ir.model.access.csv",
+ 'views/mass_editing_view.xml',
+ ],
+ 'installable': True,
+ 'application': True,
+ 'auto_install': False,
+}
diff --git a/mass_editing/i18n/es.po b/mass_editing/i18n/es.po
new file mode 100644
index 0000000..26ef75b
--- /dev/null
+++ b/mass_editing/i18n/es.po
@@ -0,0 +1,134 @@
+# Translation of OpenERP Server.
+# This file contains the translation of the following modules:
+# * mass_editing
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: OpenERP Server 7.0-20140206-002714\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2014-03-14 17:40+0000\n"
+"PO-Revision-Date: 2014-03-24 17:44+0000\n"
+"Last-Translator: Alberto Garcia (Factor Libre) "
+"\n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Launchpad-Export-Date: 2014-05-24 06:46+0000\n"
+"X-Generator: Launchpad (build 17017)\n"
+
+#. module: mass_editing
+#: model:ir.actions.act_window,name:mass_editing.action_mass_object_form
+#: model:ir.ui.menu,name:mass_editing.menu_mass_editing
+#: model:ir.ui.menu,name:mass_editing.menu_mass_object_view
+msgid "Mass Editing"
+msgstr "Edición masiva"
+
+#. module: mass_editing
+#: view:mass.object:0
+msgid ""
+"Display a button in the sidebar of related documents to open a composition "
+"wizard"
+msgstr ""
+"Mostrar un botón en el menú contextual de los documentos relacionados para "
+"abrir un asistente de composición"
+
+#. module: mass_editing
+#: model:ir.model,name:mass_editing.model_mass_editing_wizard
+msgid "mass.editing.wizard"
+msgstr "mass.editing.wizard"
+
+#. module: mass_editing
+#: field:mass.object,name:0
+msgid "Name"
+msgstr "Nombre"
+
+#. module: mass_editing
+#: code:addons/mass_editing/mass_editing.py:96
+#, python-format
+msgid "Deletion of the action record failed."
+msgstr "Borrado del registro de la acción fallido"
+
+#. module: mass_editing
+#: view:mass.object:0
+#: field:mass.object,field_ids:0
+msgid "Fields"
+msgstr "Campos"
+
+#. module: mass_editing
+#: code:addons/mass_editing/mass_editing.py:62
+#, python-format
+msgid "Mass Editing (%s)"
+msgstr "Edición Masiva (%s)"
+
+#. module: mass_editing
+#: view:mass.object:0
+msgid "Object"
+msgstr "Objeto"
+
+#. module: mass_editing
+#: model:ir.model,name:mass_editing.model_mass_object
+msgid "mass.object"
+msgstr "mass.object"
+
+#. module: mass_editing
+#: field:mass.object,model_ids:0
+msgid "Model List"
+msgstr "Lista de modelos"
+
+#. module: mass_editing
+#: code:addons/mass_editing/mass_editing.py:57
+#: sql_constraint:mass.object:0
+#, python-format
+msgid "Name must be unique!"
+msgstr "¡El nombre debe ser único!"
+
+#. module: mass_editing
+#: field:mass.object,ref_ir_act_window:0
+msgid "Sidebar Action"
+msgstr "Acción del menú contextual"
+
+#. module: mass_editing
+#: view:mass.object:0
+msgid "Remove sidebar button"
+msgstr "Eliminar botón del menú contextual"
+
+#. module: mass_editing
+#: field:mass.object,ref_ir_value:0
+msgid "Sidebar Button"
+msgstr "Botón del menú contextual"
+
+#. module: mass_editing
+#: field:mass.object,model_id:0
+msgid "Model"
+msgstr "Modelo"
+
+#. module: mass_editing
+#: code:addons/mass_editing/mass_editing.py:96
+#, python-format
+msgid "Warning"
+msgstr "Advertencia"
+
+#. module: mass_editing
+#: help:mass.object,ref_ir_act_window:0
+msgid ""
+"Sidebar action to make this template available on records "
+" of the related document model"
+msgstr ""
+"Acción del menú contextual para hacer esta plantilla disponible en los "
+"registros del modelo de documento relacionado"
+
+#. module: mass_editing
+#: view:mass.object:0
+msgid "Add sidebar button"
+msgstr "Añadir botón al menú contextual"
+
+#. module: mass_editing
+#: view:mass.object:0
+msgid "Advanced"
+msgstr "Avanzado"
+
+#. module: mass_editing
+#: help:mass.object,ref_ir_value:0
+msgid "Sidebar button to open the sidebar action"
+msgstr "Botón del menú contextual para abrir la acción del menú contextual"
diff --git a/mass_editing/i18n/fr.po b/mass_editing/i18n/fr.po
new file mode 100644
index 0000000..3b7a3d0
--- /dev/null
+++ b/mass_editing/i18n/fr.po
@@ -0,0 +1,130 @@
+# French translation for server-env-tools
+# Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014
+# This file is distributed under the same license as the server-env-tools package.
+# FIRST AUTHOR , 2014.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: server-env-tools\n"
+"Report-Msgid-Bugs-To: FULL NAME \n"
+"POT-Creation-Date: 2014-03-14 17:40+0000\n"
+"PO-Revision-Date: 2014-03-20 17:39+0000\n"
+"Last-Translator: Davin Baragiotta \n"
+"Language-Team: French \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Launchpad-Export-Date: 2014-05-24 06:46+0000\n"
+"X-Generator: Launchpad (build 17017)\n"
+
+#. module: mass_editing
+#: model:ir.actions.act_window,name:mass_editing.action_mass_object_form
+#: model:ir.ui.menu,name:mass_editing.menu_mass_editing
+#: model:ir.ui.menu,name:mass_editing.menu_mass_object_view
+msgid "Mass Editing"
+msgstr "Édition en lot"
+
+#. module: mass_editing
+#: view:mass.object:0
+msgid ""
+"Display a button in the sidebar of related documents to open a composition "
+"wizard"
+msgstr ""
+
+#. module: mass_editing
+#: model:ir.model,name:mass_editing.model_mass_editing_wizard
+msgid "mass.editing.wizard"
+msgstr ""
+
+#. module: mass_editing
+#: field:mass.object,name:0
+msgid "Name"
+msgstr "Nom"
+
+#. module: mass_editing
+#: code:addons/mass_editing/mass_editing.py:96
+#, python-format
+msgid "Deletion of the action record failed."
+msgstr "La suppression de l'enregistrement de l'action a échoué."
+
+#. module: mass_editing
+#: view:mass.object:0
+#: field:mass.object,field_ids:0
+msgid "Fields"
+msgstr "Champs"
+
+#. module: mass_editing
+#: code:addons/mass_editing/mass_editing.py:62
+#, python-format
+msgid "Mass Editing (%s)"
+msgstr "Édition en lot (%s)"
+
+#. module: mass_editing
+#: view:mass.object:0
+msgid "Object"
+msgstr "Objet"
+
+#. module: mass_editing
+#: model:ir.model,name:mass_editing.model_mass_object
+msgid "mass.object"
+msgstr ""
+
+#. module: mass_editing
+#: field:mass.object,model_ids:0
+msgid "Model List"
+msgstr ""
+
+#. module: mass_editing
+#: code:addons/mass_editing/mass_editing.py:57
+#: sql_constraint:mass.object:0
+#, python-format
+msgid "Name must be unique!"
+msgstr ""
+
+#. module: mass_editing
+#: field:mass.object,ref_ir_act_window:0
+msgid "Sidebar Action"
+msgstr ""
+
+#. module: mass_editing
+#: view:mass.object:0
+msgid "Remove sidebar button"
+msgstr ""
+
+#. module: mass_editing
+#: field:mass.object,ref_ir_value:0
+msgid "Sidebar Button"
+msgstr ""
+
+#. module: mass_editing
+#: field:mass.object,model_id:0
+msgid "Model"
+msgstr ""
+
+#. module: mass_editing
+#: code:addons/mass_editing/mass_editing.py:96
+#, python-format
+msgid "Warning"
+msgstr ""
+
+#. module: mass_editing
+#: help:mass.object,ref_ir_act_window:0
+msgid ""
+"Sidebar action to make this template available on records "
+" of the related document model"
+msgstr ""
+
+#. module: mass_editing
+#: view:mass.object:0
+msgid "Add sidebar button"
+msgstr ""
+
+#. module: mass_editing
+#: view:mass.object:0
+msgid "Advanced"
+msgstr ""
+
+#. module: mass_editing
+#: help:mass.object,ref_ir_value:0
+msgid "Sidebar button to open the sidebar action"
+msgstr ""
diff --git a/mass_editing/i18n/fr_CA.po b/mass_editing/i18n/fr_CA.po
new file mode 100644
index 0000000..8225199
--- /dev/null
+++ b/mass_editing/i18n/fr_CA.po
@@ -0,0 +1,132 @@
+# French (Canada) translation for server-env-tools
+# Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014
+# This file is distributed under the same license as the server-env-tools package.
+# FIRST AUTHOR , 2014.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: server-env-tools\n"
+"Report-Msgid-Bugs-To: FULL NAME \n"
+"POT-Creation-Date: 2014-03-14 17:40+0000\n"
+"PO-Revision-Date: 2014-03-20 16:49+0000\n"
+"Last-Translator: Davin Baragiotta \n"
+"Language-Team: French (Canada) \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Launchpad-Export-Date: 2014-05-24 06:46+0000\n"
+"X-Generator: Launchpad (build 17017)\n"
+
+#. module: mass_editing
+#: model:ir.actions.act_window,name:mass_editing.action_mass_object_form
+#: model:ir.ui.menu,name:mass_editing.menu_mass_editing
+#: model:ir.ui.menu,name:mass_editing.menu_mass_object_view
+msgid "Mass Editing"
+msgstr "Édition en lot"
+
+#. module: mass_editing
+#: view:mass.object:0
+msgid ""
+"Display a button in the sidebar of related documents to open a composition "
+"wizard"
+msgstr ""
+"Afficher un bouton dans le menu latéral des documents associés pour ouvrir "
+"un assistant de rédaction"
+
+#. module: mass_editing
+#: model:ir.model,name:mass_editing.model_mass_editing_wizard
+msgid "mass.editing.wizard"
+msgstr ""
+
+#. module: mass_editing
+#: field:mass.object,name:0
+msgid "Name"
+msgstr "Nom"
+
+#. module: mass_editing
+#: code:addons/mass_editing/mass_editing.py:96
+#, python-format
+msgid "Deletion of the action record failed."
+msgstr "Échec de la suppression de l'enregistrement de l'action"
+
+#. module: mass_editing
+#: view:mass.object:0
+#: field:mass.object,field_ids:0
+msgid "Fields"
+msgstr "Champs"
+
+#. module: mass_editing
+#: code:addons/mass_editing/mass_editing.py:62
+#, python-format
+msgid "Mass Editing (%s)"
+msgstr "Édition en lot (%s)"
+
+#. module: mass_editing
+#: view:mass.object:0
+msgid "Object"
+msgstr "Objet"
+
+#. module: mass_editing
+#: model:ir.model,name:mass_editing.model_mass_object
+msgid "mass.object"
+msgstr ""
+
+#. module: mass_editing
+#: field:mass.object,model_ids:0
+msgid "Model List"
+msgstr ""
+
+#. module: mass_editing
+#: code:addons/mass_editing/mass_editing.py:57
+#: sql_constraint:mass.object:0
+#, python-format
+msgid "Name must be unique!"
+msgstr "Le nom doit être unique!"
+
+#. module: mass_editing
+#: field:mass.object,ref_ir_act_window:0
+msgid "Sidebar Action"
+msgstr "Action du menu latéral"
+
+#. module: mass_editing
+#: view:mass.object:0
+msgid "Remove sidebar button"
+msgstr "Enlever le bouton du menu latéral"
+
+#. module: mass_editing
+#: field:mass.object,ref_ir_value:0
+msgid "Sidebar Button"
+msgstr "Bouton du menu latéral"
+
+#. module: mass_editing
+#: field:mass.object,model_id:0
+msgid "Model"
+msgstr "Modèle"
+
+#. module: mass_editing
+#: code:addons/mass_editing/mass_editing.py:96
+#, python-format
+msgid "Warning"
+msgstr "Avertissement"
+
+#. module: mass_editing
+#: help:mass.object,ref_ir_act_window:0
+msgid ""
+"Sidebar action to make this template available on records "
+" of the related document model"
+msgstr ""
+
+#. module: mass_editing
+#: view:mass.object:0
+msgid "Add sidebar button"
+msgstr "Ajouter le bouton du menu latéral"
+
+#. module: mass_editing
+#: view:mass.object:0
+msgid "Advanced"
+msgstr "Avancé"
+
+#. module: mass_editing
+#: help:mass.object,ref_ir_value:0
+msgid "Sidebar button to open the sidebar action"
+msgstr ""
diff --git a/mass_editing/i18n/mass_editing.pot b/mass_editing/i18n/mass_editing.pot
new file mode 100644
index 0000000..3085b14
--- /dev/null
+++ b/mass_editing/i18n/mass_editing.pot
@@ -0,0 +1,129 @@
+# Translation of OpenERP Server.
+# This file contains the translation of the following modules:
+# * mass_editing
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: OpenERP Server 7.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2014-03-14 17:40+0000\n"
+"PO-Revision-Date: 2014-03-14 17: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: mass_editing
+#: model:ir.actions.act_window,name:mass_editing.action_mass_object_form
+#: model:ir.ui.menu,name:mass_editing.menu_mass_editing
+#: model:ir.ui.menu,name:mass_editing.menu_mass_object_view
+msgid "Mass Editing"
+msgstr ""
+
+#. module: mass_editing
+#: view:mass.object:0
+msgid "Display a button in the sidebar of related documents to open a composition wizard"
+msgstr ""
+
+#. module: mass_editing
+#: model:_description:0
+#: model:ir.model,name:mass_editing.model_mass_editing_wizard
+msgid "mass.editing.wizard"
+msgstr ""
+
+#. module: mass_editing
+#: field:mass.object,name:0
+msgid "Name"
+msgstr ""
+
+#. module: mass_editing
+#: code:addons/mass_editing/mass_editing.py:114
+#, python-format
+msgid "Deletion of the action record failed."
+msgstr ""
+
+#. module: mass_editing
+#: model:_description:0
+#: model:ir.model,name:mass_editing.model_ir_model_fields
+#: view:mass.object:0
+#: field:mass.object,field_ids:0
+msgid "Fields"
+msgstr ""
+
+#. module: mass_editing
+#: code:addons/mass_editing/mass_editing.py:80
+#, python-format
+msgid "Mass Editing (%s)"
+msgstr ""
+
+#. module: mass_editing
+#: view:mass.object:0
+msgid "Object"
+msgstr ""
+
+#. module: mass_editing
+#: model:_description:0
+#: model:ir.model,name:mass_editing.model_mass_object
+msgid "mass.object"
+msgstr ""
+
+#. module: mass_editing
+#: field:mass.object,model_ids:0
+msgid "Model List"
+msgstr ""
+
+#. module: mass_editing
+#: code:addons/mass_editing/mass_editing.py:57
+#: sql_constraint:mass.object:0
+#, python-format
+msgid "Name must be unique!"
+msgstr ""
+
+#. module: mass_editing
+#: field:mass.object,ref_ir_act_window:0
+msgid "Sidebar Action"
+msgstr ""
+
+#. module: mass_editing
+#: view:mass.object:0
+msgid "Remove sidebar button"
+msgstr ""
+
+#. module: mass_editing
+#: field:mass.object,ref_ir_value:0
+msgid "Sidebar Button"
+msgstr ""
+
+#. module: mass_editing
+#: field:mass.object,model_id:0
+msgid "Model"
+msgstr ""
+
+#. module: mass_editing
+#: code:addons/mass_editing/mass_editing.py:114
+#, python-format
+msgid "Warning"
+msgstr ""
+
+#. module: mass_editing
+#: help:mass.object,ref_ir_act_window:0
+msgid "Sidebar action to make this template available on records of the related document model"
+msgstr ""
+
+#. module: mass_editing
+#: view:mass.object:0
+msgid "Add sidebar button"
+msgstr ""
+
+#. module: mass_editing
+#: view:mass.object:0
+msgid "Advanced"
+msgstr ""
+
+#. module: mass_editing
+#: help:mass.object,ref_ir_value:0
+msgid "Sidebar button to open the sidebar action"
+msgstr ""
+
diff --git a/mass_editing/models/__init__.py b/mass_editing/models/__init__.py
new file mode 100644
index 0000000..64fd501
--- /dev/null
+++ b/mass_editing/models/__init__.py
@@ -0,0 +1,24 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# This module uses OpenERP, Open Source Management Solution Framework.
+# Copyright (C):
+# 2012-Today Serpent Consulting Services ()
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see
+#
+##############################################################################
+
+from . import ir_model_fields
+from . import mass_object
diff --git a/mass_editing/models/ir_model_fields.py b/mass_editing/models/ir_model_fields.py
new file mode 100644
index 0000000..7257910
--- /dev/null
+++ b/mass_editing/models/ir_model_fields.py
@@ -0,0 +1,42 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# This module uses OpenERP, Open Source Management Solution Framework.
+# Copyright (C):
+# 2012-Today Serpent Consulting Services ()
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see
+#
+##############################################################################
+
+from openerp.osv import orm
+
+
+class IrModelFields(orm.Model):
+ _inherit = 'ir.model.fields'
+
+ def search(
+ self, cr, uid, args, offset=0, limit=0, order=None, context=None,
+ count=False):
+ model_domain = []
+ for domain in args:
+ if domain[0] == 'model_id' and domain[2]\
+ and type(domain[2]) != list:
+ model_domain += [(
+ 'model_id', 'in', map(int, domain[2][1:-1].split(',')))]
+ else:
+ model_domain.append(domain)
+ return super(IrModelFields, self).search(
+ cr, uid, model_domain, offset=offset, limit=limit, order=order,
+ context=context, count=count)
diff --git a/mass_editing/models/mass_object.py b/mass_editing/models/mass_object.py
new file mode 100644
index 0000000..8e7737d
--- /dev/null
+++ b/mass_editing/models/mass_object.py
@@ -0,0 +1,129 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# This module uses OpenERP, Open Source Management Solution Framework.
+# Copyright (C):
+# 2012-Today Serpent Consulting Services ()
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see
+#
+##############################################################################
+
+from openerp import SUPERUSER_ID
+from openerp.osv import orm, fields
+from openerp.tools.translate import _
+
+
+class MassObject(orm.Model):
+ _name = "mass.object"
+
+ _columns = {
+ 'name': fields.char("Name", size=64, required=True, select=1),
+ 'model_id': fields.many2one(
+ 'ir.model', 'Model', required=True, select=1),
+ 'field_ids': fields.many2many(
+ 'ir.model.fields', 'mass_field_rel', 'mass_id', 'field_id',
+ 'Fields'),
+ 'ref_ir_act_window': fields.many2one(
+ 'ir.actions.act_window', 'Sidebar Action', readonly=True,
+ help="Sidebar action to make this template available on records \
+ of the related document model"),
+ 'ref_ir_value': fields.many2one(
+ 'ir.values', 'Sidebar Button', readonly=True,
+ help="Sidebar button to open the sidebar action"),
+ 'model_ids': fields.many2many('ir.model', string='Model List')
+ }
+
+ _sql_constraints = [
+ ('name_uniq', 'unique (name)', _('Name must be unique!')),
+ ]
+
+ def onchange_model(self, cr, uid, ids, model_id, context=None):
+ if context is None:
+ context = {}
+ if not model_id:
+ return {'value': {'model_ids': [(6, 0, [])]}}
+ model_ids = [model_id]
+ model_obj = self.pool['ir.model']
+ active_model_obj = self.pool.get(model_obj.browse(
+ cr, uid, model_id).model)
+ if active_model_obj._inherits:
+ for key, val in active_model_obj._inherits.items():
+ found_model_ids = model_obj.search(
+ cr, uid, [('model', '=', key)], context=context)
+ model_ids += found_model_ids
+ return {'value': {'model_ids': [(6, 0, model_ids)]}}
+
+ def create_action(self, cr, uid, ids, context=None):
+ vals = {}
+ action_obj = self.pool['ir.actions.act_window']
+ ir_values_obj = self.pool['ir.values']
+ for data in self.browse(cr, uid, ids, context=context):
+ src_obj = data.model_id.model
+ button_name = _('Mass Editing (%s)') % data.name
+ vals['ref_ir_act_window'] = action_obj.create(cr, SUPERUSER_ID, {
+ 'name': button_name,
+ 'type': 'ir.actions.act_window',
+ 'res_model': 'mass.editing.wizard',
+ 'src_model': src_obj,
+ 'view_type': 'form',
+ 'context': "{'mass_editing_object' : %d}" % (data.id),
+ 'view_mode': 'form,tree',
+ 'target': 'new',
+ 'auto_refresh': 1,
+ }, context)
+ vals['ref_ir_value'] = ir_values_obj.create(cr, SUPERUSER_ID, {
+ 'name': button_name,
+ 'model': src_obj,
+ 'key2': 'client_action_multi',
+ 'value': (
+ "ir.actions.act_window,"
+ + str(vals['ref_ir_act_window'])),
+ 'object': True,
+ }, context)
+ self.write(cr, uid, ids, {
+ 'ref_ir_act_window': vals.get('ref_ir_act_window', False),
+ 'ref_ir_value': vals.get('ref_ir_value', False),
+ }, context)
+ return True
+
+ def unlink_action(self, cr, uid, ids, context=None):
+ for template in self.browse(cr, uid, ids, context=context):
+ try:
+ if template.ref_ir_act_window:
+ act_window_obj = self.pool['ir.actions.act_window']
+ act_window_obj.unlink(
+ cr, SUPERUSER_ID, [template.ref_ir_act_window.id],
+ context=context)
+ if template.ref_ir_value:
+ ir_values_obj = self.pool['ir.values']
+ ir_values_obj.unlink(
+ cr, SUPERUSER_ID, template.ref_ir_value.id,
+ context=context)
+ except:
+ raise orm.except_orm(
+ _("Warning"),
+ _("Deletion of the action record failed."))
+ return True
+
+ def unlink(self, cr, uid, ids, context=None):
+ self.unlink_action(cr, uid, ids, context=context)
+ return super(MassObject, self).unlink(cr, uid, ids, context=context)
+
+ def copy(self, cr, uid, record_id, default=None, context=None):
+ if default is None:
+ default = {}
+ default.update({'name': '', 'field_ids': []})
+ return super(MassObject, self).copy(
+ cr, uid, record_id, default, context=context)
diff --git a/mass_editing/security/ir.model.access.csv b/mass_editing/security/ir.model.access.csv
new file mode 100755
index 0000000..80ee747
--- /dev/null
+++ b/mass_editing/security/ir.model.access.csv
@@ -0,0 +1,2 @@
+"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink"
+"access_mass_editing_normal_user","mass.editing.normal.user","model_mass_object","base.group_user",1,0,0,0
diff --git a/mass_editing/views/mass_editing_view.xml b/mass_editing/views/mass_editing_view.xml
new file mode 100644
index 0000000..1ab945f
--- /dev/null
+++ b/mass_editing/views/mass_editing_view.xml
@@ -0,0 +1,98 @@
+
+
+
+
+
+ mass.object.form
+ mass.object
+
+
+
+
+
+
+ mass.object.tree
+ mass.object
+
+
+
+
+
+
+
+
+
+ Mass Editing
+ mass.object
+ form
+ tree,form
+
+
+
+
+
+ tree
+
+
+
+
+
+ form
+
+
+
+
+
+
+
+
+
+
diff --git a/mass_editing/wizard/__init__.py b/mass_editing/wizard/__init__.py
new file mode 100644
index 0000000..4f383dd
--- /dev/null
+++ b/mass_editing/wizard/__init__.py
@@ -0,0 +1,23 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# This module uses OpenERP, Open Source Management Solution Framework.
+# Copyright (C):
+# 2012-Today Serpent Consulting Services (
+#
+##############################################################################
+
+from . import mass_editing_wizard
diff --git a/mass_editing/wizard/mass_editing_wizard.py b/mass_editing/wizard/mass_editing_wizard.py
new file mode 100644
index 0000000..4af12c3
--- /dev/null
+++ b/mass_editing/wizard/mass_editing_wizard.py
@@ -0,0 +1,213 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# This module uses OpenERP, Open Source Management Solution Framework.
+# Copyright (C):
+# 2012-Today Serpent Consulting Services ()
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see
+#
+##############################################################################
+
+from openerp.osv import orm
+import openerp.tools as tools
+from lxml import etree
+
+
+class MassEditingWizard(orm.TransientModel):
+ _name = 'mass.editing.wizard'
+
+ def fields_view_get(
+ self, cr, uid, view_id=None, view_type='form', context=None,
+ toolbar=False, submenu=False):
+ result = super(MassEditingWizard, self).fields_view_get(
+ cr, uid, view_id, view_type, context, toolbar, submenu)
+ if context.get('mass_editing_object'):
+ mass_object = self.pool['mass.object']
+ editing_data = mass_object.browse(
+ cr, uid, context.get('mass_editing_object'), context)
+ all_fields = {}
+ xml_form = etree.Element('form', {
+ 'string': tools.ustr(editing_data.name), 'version': '7.0'})
+ xml_group = etree.SubElement(xml_form, 'group', {'colspan': '4'})
+ etree.SubElement(xml_group, 'label', {
+ 'string': '', 'colspan': '2'})
+ xml_group = etree.SubElement(xml_form, 'group', {'colspan': '4',
+ 'col': '4'})
+ model_obj = self.pool[context.get('active_model')]
+ field_info = model_obj.fields_get(cr, uid, [], context)
+ for field in editing_data.field_ids:
+ if field.ttype == "many2many":
+ all_fields[field.name] = field_info[field.name]
+ all_fields["selection__" + field.name] = {
+ 'type': 'selection',
+ 'string': field_info[field.name]['string'],
+ 'selection': [
+ ('set', 'Set'), ('remove_m2m', 'Remove'),
+ ('add', 'Add')]}
+ xml_group = etree.SubElement(xml_group, 'group', {
+ 'colspan': '4'})
+ etree.SubElement(xml_group, 'separator', {
+ 'string': field_info[field.name]['string'],
+ 'colspan': '2'})
+ etree.SubElement(xml_group, 'field', {
+ 'name': "selection__" + field.name,
+ 'colspan': '2', 'nolabel': '1'})
+ etree.SubElement(xml_group, 'field', {
+ 'name': field.name, 'colspan': '4', 'nolabel': '1',
+ 'attrs': (
+ "{'invisible':[('selection__"
+ + field.name + "','=','remove_m2m')]}")})
+ elif field.ttype == "one2many":
+ all_fields["selection__" + field.name] = {
+ 'type': 'selection',
+ 'string': field_info[field.name]['string'],
+ 'selection': [('set', 'Set'), ('remove', 'Remove')]}
+ all_fields[field.name] = {
+ 'type': field.ttype, 'string': field.field_description,
+ 'relation': field.relation}
+ etree.SubElement(xml_group, 'field', {
+ 'name': "selection__" + field.name, 'colspan': '2'})
+ etree.SubElement(xml_group, 'field', {
+ 'name': field.name, 'colspan': '4', 'nolabel': '1',
+ 'attrs': (
+ "{'invisible':[('selection__"
+ + field.name + "','=','remove_o2m')]}")})
+ elif field.ttype == "many2one":
+ all_fields["selection__" + field.name] = {
+ 'type': 'selection',
+ 'string': field_info[field.name]['string'],
+ 'selection': [('set', 'Set'), ('remove', 'Remove')]}
+ all_fields[field.name] = {
+ 'type': field.ttype, 'string': field.field_description,
+ 'relation': field.relation}
+ etree.SubElement(xml_group, 'field', {
+ 'name': "selection__" + field.name, 'colspan': '2'})
+ etree.SubElement(xml_group, 'field', {
+ 'name': field.name, 'nolabel': '1', 'colspan': '2',
+ 'attrs': (
+ "{'invisible':[('selection__"
+ + field.name + "','=','remove')]}")})
+ elif field.ttype == "char":
+ all_fields["selection__" + field.name] = {
+ 'type': 'selection',
+ 'string': field_info[field.name]['string'],
+ 'selection': [('set', 'Set'), ('remove', 'Remove')]}
+ all_fields[field.name] = {
+ 'type': field.ttype, 'string': field.field_description,
+ 'size': field.size or 256}
+ etree.SubElement(xml_group, 'field', {
+ 'name': "selection__" + field.name,
+ 'colspan': '2',
+ 'colspan': '2'})
+ etree.SubElement(xml_group, 'field', {
+ 'name': field.name, 'nolabel': '1',
+ 'attrs': (
+ "{'invisible':[('selection__"
+ + field.name + "','=','remove')]}"),
+ 'colspan': '2'})
+ elif field.ttype == 'selection':
+ all_fields["selection__" + field.name] = {
+ 'type': 'selection',
+ 'string': field_info[field.name]['string'],
+ 'selection': [('set', 'Set'), ('remove', 'Remove')]}
+ etree.SubElement(xml_group, 'field', {
+ 'name': "selection__" + field.name, 'colspan': '2'})
+ etree.SubElement(xml_group, 'field', {
+ 'name': field.name, 'nolabel': '1', 'colspan': '2',
+ 'attrs': (
+ "{'invisible':[('selection__"
+ + field.name + "','=','remove')]}")})
+ all_fields[field.name] = {
+ 'type': field.ttype,
+ 'string': field.field_description,
+ 'selection': field_info[field.name]['selection']}
+ else:
+ all_fields[field.name] = {
+ 'type': field.ttype, 'string': field.field_description}
+ all_fields["selection__" + field.name] = {
+ 'type': 'selection',
+ 'string': field_info[field.name]['string'],
+ 'selection': [('set', 'Set'), ('remove', 'Remove')]}
+ if field.ttype == 'text':
+ xml_group = etree.SubElement(xml_group, 'group', {
+ 'colspan': '6'})
+ etree.SubElement(xml_group, 'separator', {
+ 'string': all_fields[field.name]['string'],
+ 'colspan': '2'})
+ etree.SubElement(xml_group, 'field', {
+ 'name': "selection__" + field.name,
+ 'colspan': '2', 'nolabel': '1'})
+ etree.SubElement(xml_group, 'field', {
+ 'name': field.name, 'colspan': '4', 'nolabel': '1',
+ 'attrs': (
+ "{'invisible':[('selection__"
+ + field.name + "','=','remove')]}")})
+ else:
+ all_fields["selection__" + field.name] = {
+ 'type': 'selection',
+ 'string': field_info[field.name]['string'],
+ 'selection': [(
+ 'set', 'Set'), ('remove', 'Remove')]}
+ etree.SubElement(xml_group, 'field', {
+ 'name': "selection__" + field.name,
+ 'colspan': '2', })
+ etree.SubElement(xml_group, 'field', {
+ 'name': field.name, 'nolabel': '1',
+ 'attrs': (
+ "{'invisible':[('selection__"
+ + field.name + "','=','remove')]}"),
+ 'colspan': '2', })
+ etree.SubElement(
+ xml_form, 'separator', {'string': '', 'colspan': '4'})
+ xml_group3 = etree.SubElement(xml_form, 'footer', {})
+ etree.SubElement(xml_group3, 'button', {
+ 'string': 'Apply', 'icon': "gtk-execute",
+ 'type': 'object', 'name': "action_apply",
+ 'class': "oe_highlight"})
+ etree.SubElement(xml_group3, 'button', {
+ 'string': 'Close', 'icon': "gtk-close", 'special': 'cancel'})
+ root = xml_form.getroottree()
+ result['arch'] = etree.tostring(root)
+ result['fields'] = all_fields
+ return result
+
+ def create(self, cr, uid, vals, context=None):
+ if context.get('active_model') and context.get('active_ids'):
+ model_obj = self.pool.get(context.get('active_model'))
+ dict = {}
+ for key, val in vals.items():
+ if key.startswith('selection__'):
+ split_key = key.split('__', 1)[1]
+ if val == 'set':
+ dict.update({split_key: vals.get(split_key, False)})
+ elif val == 'remove':
+ dict.update({split_key: False})
+ elif val == 'remove_m2m':
+ dict.update({split_key: [
+ (3, id) for id in vals.get(
+ split_key, False)[0][2]]})
+ elif val == 'add':
+ m2m_list = []
+ for m2m_id in vals.get(split_key, False)[0][2]:
+ m2m_list.append((4, m2m_id))
+ dict.update({split_key: m2m_list})
+ if dict:
+ model_obj.write(
+ cr, uid, context.get('active_ids'), dict, context)
+ result = super(MassEditingWizard, self).create(cr, uid, {}, context)
+ return result
+
+ def action_apply(self, cr, uid, ids, context=None):
+ return {'type': 'ir.actions.act_window_close'}