Browse Source

[MRG] Add mass_editing module

pull/78/head
Stefan Rijnhart 11 years ago
committed by Maxime Chambreuil
parent
commit
965ca1468d
  1. 27
      mass_editing/__init__.py
  2. 47
      mass_editing/__openerp__.py
  3. 118
      mass_editing/i18n/mass_editing.pot
  4. 105
      mass_editing/mass_editing.py
  5. 73
      mass_editing/mass_editing_view.xml
  6. 2
      mass_editing/security/ir.model.access.csv
  7. 25
      mass_editing/wizard/__init__.py
  8. 129
      mass_editing/wizard/mass_editing_wizard.py

27
mass_editing/__init__.py

@ -0,0 +1,27 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2012 Serpent Consulting Services (<http://www.serpentcs.com>)
# Copyright (C) 2010-Today OpenERP SA (<http://www.openerp.com>)
#
# 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 <http://www.gnu.org/licenses/>
#
##############################################################################
import mass_editing
import wizard
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

47
mass_editing/__openerp__.py

@ -0,0 +1,47 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2012 Serpent Consulting Services (<http://www.serpentcs.com>)
# Copyright (C) 2010-Today OpenERP SA (<http://www.openerp.com>)
#
# 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 <http://www.gnu.org/licenses/>
#
##############################################################################
{
"name" : "Mass Editing",
"version" : "1.1",
"author" : "Serpent Consulting Services",
"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 feature is available at http://t.co/wukYMx1A
The menu is now Under Settings/Configuration.
For more details/customization/feedback contact us on contact@serpentcs.com.
""",
'depends': ['base'],
'init_xml': [],
'update_xml': [
"security/ir.model.access.csv",
'mass_editing_view.xml',
],
'installable': True,
'application': True,
'auto_install': False,
}
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

118
mass_editing/i18n/mass_editing.pot

@ -0,0 +1,118 @@
# Translation of OpenERP Server.
# This file contains the translation of the following modules:
# * mass_editing
#
msgid ""
msgstr ""
"Project-Id-Version: OpenERP Server 6.1\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-08-20 03:41+0000\n"
"PO-Revision-Date: 2013-08-20 03:41+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: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:96
#, python-format
msgid "Deletion of the action record failed."
msgstr ""
#. module: mass_editing
#: view:mass.object:0
#: field:mass.object,field_ids:0
msgid "Fields"
msgstr ""
#. module: mass_editing
#: code:addons/mass_editing/mass_editing.py:62
#, python-format
msgid "Mass Editing (%s)"
msgstr ""
#. module: mass_editing
#: view:mass.object:0
msgid "Object"
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
#: 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:96
#, python-format
msgid "Warning"
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
#: 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 ""

105
mass_editing/mass_editing.py

@ -0,0 +1,105 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2012 Serpent Consulting Services (<http://www.serpentcs.com>)
# Copyright (C) 2010-Today OpenERP SA (<http://www.openerp.com>)
#
# 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 <http://www.gnu.org/licenses/>
#
##############################################################################
from osv import fields, osv
from tools.translate import _
class mass_object(osv.osv):
_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')
}
def onchange_model(self, cr, uid, ids, model_id):
model_ids = []
if model_id:
model_obj = self.pool.get('ir.model')
model_data = model_obj.browse(cr, uid, model_id)
model_ids = [model_id]
active_model_obj = self.pool.get(model_data.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)])
if found_model_ids:
model_ids.append(found_model_ids[0])
return {'value': {'model_ids': [(6, 0, model_ids)]}}
def create_action(self, cr, uid, ids, context=None):
vals = {}
action_obj = self.pool.get('ir.actions.act_window')
data_obj = self.pool.get('ir.model.data')
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, uid, {
'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'] = self.pool.get('ir.values').create(cr, uid, {
'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:
self.pool.get('ir.actions.act_window').unlink(cr, uid, template.ref_ir_act_window.id, context)
if template.ref_ir_value:
ir_values_obj = self.pool.get('ir.values')
ir_values_obj.unlink(cr, uid, template.ref_ir_value.id, context)
except:
raise osv.except_osv(_("Warning"), _("Deletion of the action record failed."))
return True
def unlink(self, cr, uid, ids, context=None):
self.unlink_action(cr, uid, ids, context)
return super(mass_object, self).unlink(cr, uid, ids, context)
mass_object()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

73
mass_editing/mass_editing_view.xml

@ -0,0 +1,73 @@
<?xml version="1.0" encoding="UTF-8"?>
<openerp>
<data>
<record model="ir.ui.view" id="view_mass_object_form">
<field name="name">mass.object.form</field>
<field name="model">mass.object</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Object">
<field name="name"/>
<field name="model_id" on_change="onchange_model(model_id)"/>
<field name="model_ids" invisible="1"/>
<notebook colspan="4">
<page string="Fields">
<field name="field_ids" colspan="4" nolabel="1"
domain="[('ttype', 'not in', ['reference','function']), ('model_id', 'in', model_ids[0][2])]"/>
</page>
<page string="Advanced">
<group colspan="2" col="2">
<button name="create_action" string="Add sidebar button" type="object" icon="gtk-execute"
colspan="2" attrs="{'invisible':[('ref_ir_act_window','!=',False)]}"
help="Display a button in the sidebar of related documents to open a composition wizard"/>
<field name="ref_ir_act_window" attrs="{'invisible':[('ref_ir_act_window','=',False)]}"/>
<field name="ref_ir_value" attrs="{'invisible':[('ref_ir_act_window','=',False)]}"/>
<button name="unlink_action" string="Remove sidebar button" type="object" icon="gtk-delete"
attrs="{'invisible':[('ref_ir_act_window','=',False)]}" colspan="2" />
</group>
</page>
</notebook>
</form>
</field>
</record>
<record model="ir.ui.view" id="view_mass_object_tree">
<field name="name">mass.object.tree</field>
<field name="model">mass.object</field>
<field name="type">form</field>
<field name="arch" type="xml">
<tree string="Object">
<field name="name"/>
<field name="model_id"/>
</tree>
</field>
</record>
<record model="ir.actions.act_window" id="action_mass_object_form">
<field name="name">Mass Editing</field>
<field name="res_model">mass.object</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="view_id" ref="view_mass_object_tree" />
</record>
<record id="action_mass_object_form_view1" model="ir.actions.act_window.view">
<field eval="10" name="sequence"/>
<field name="view_mode">tree</field>
<field name="view_id" ref="view_mass_object_tree"/>
<field name="act_window_id" ref="action_mass_object_form"/>
</record>
<record id="action_mass_object_form_view2" model="ir.actions.act_window.view">
<field eval="20" name="sequence"/>
<field name="view_mode">form</field>
<field name="view_id" ref="view_mass_object_form"/>
<field name="act_window_id" ref="action_mass_object_form"/>
</record>
<menuitem id="menu_mass_editing" name="Mass Editing" parent="base.menu_config" sequence="6"/>
<menuitem id="menu_mass_object_view" action="action_mass_object_form" parent="menu_mass_editing"/>
</data>
</openerp>

2
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

25
mass_editing/wizard/__init__.py

@ -0,0 +1,25 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2012 Serpent Consulting Services (<http://www.serpentcs.com>)
# Copyright (C) 2010-Today OpenERP SA (<http://www.openerp.com>)
#
# 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 <http://www.gnu.org/licenses/>
#
##############################################################################
import mass_editing_wizard
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

129
mass_editing/wizard/mass_editing_wizard.py

@ -0,0 +1,129 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2012 Serpent Consulting Services (<http://www.serpentcs.com>)
# Copyright (C) 2010-Today OpenERP SA (<http://www.openerp.com>)
#
# 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 <http://www.gnu.org/licenses/>
#
##############################################################################
from osv import osv
from osv import fields
from lxml import etree
import tools
class mass_editing_wizard(osv.osv_memory):
_name = 'mass.editing.wizard'
_columns = {
}
def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False):
result = super(mass_editing_wizard, self).fields_view_get(cr, uid, view_id, view_type, context, toolbar,submenu)
if context.get('mass_editing_object'):
mass_object = self.pool.get('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)})
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'})
model_obj = self.pool.get(context.get('active_model'))
for field in editing_data.field_ids:
if field.ttype == "many2many":
field_info = model_obj.fields_get(cr, uid, [field.name], context)
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 == "many2one":
field_info = model_obj.fields_get(cr, uid, [field.name], context)
if field_info:
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":
field_info = model_obj.fields_get(cr, uid, [field.name], context)
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':
field_info = model_obj.fields_get(cr, uid, [field.name], context)
all_fields["selection_"+field.name] = {'type':'selection', 'string': field_info[field.name]['string'],'selection':[('set','Set'),('remove','Remove')]}
field_info = model_obj.fields_get(cr, uid, [field.name], context)
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:
field_info = model_obj.fields_get(cr, uid, [field.name], context)
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': '6'})
xml_group3 = etree.SubElement(xml_form, 'group', {'col': '2', 'colspan': '4'})
etree.SubElement(xml_group3, 'button', {'string' :'Close','icon': "gtk-close", 'special' :'cancel'})
etree.SubElement(xml_group3, 'button', {'string' :'Apply','icon': "gtk-execute", 'type' :'object','name':"action_apply"})
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'))
model_vals = {}
for key, val in vals.items():
if key.startswith('selection_'):
model_field = key.split('_', 1)[1]
if val == 'set':
model_vals[model_field] = vals[model_field]
elif val == 'remove':
model_vals[model_field] = False
elif val == 'remove_m2m':
m2m_list = []
for m2m_id in vals[model_field][0][2] or []:
m2m_list.append((3, m2m_id))
model_vals[model_field] = m2m_list
elif val == 'add':
m2m_list = []
for m2m_id in vals[model_field][0][2] or []:
m2m_list.append((4, m2m_id))
model_vals[model_field] = m2m_list
if model_vals:
model_obj.write(cr, uid, context['active_ids'], model_vals, context)
result = super(mass_editing_wizard, self).create(cr, uid, {}, context)
return result
def action_apply(self, cr, uid, ids, context=None):
return {'type': 'ir.actions.act_window_close'}
mass_editing_wizard()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
Loading…
Cancel
Save