Browse Source

[MIG] mass_editing: Migration to 11.0

pull/5/head
Juan Negrete 7 years ago
committed by Pedro M. Baeza
parent
commit
6cda892544
  1. 20
      mass_editing/ChangeLog.txt
  2. 29
      mass_editing/README.rst
  3. 1
      mass_editing/__init__.py
  4. 10
      mass_editing/__manifest__.py
  5. 8
      mass_editing/hooks.py
  6. 129
      mass_editing/i18n/mass_editing.pot
  7. 1
      mass_editing/models/__init__.py
  8. 7
      mass_editing/models/ir_model_fields.py
  9. 26
      mass_editing/models/mass_object.py
  10. 1
      mass_editing/tests/__init__.py
  11. 59
      mass_editing/tests/test_mass_editing.py
  12. 3
      mass_editing/views/mass_editing_view.xml
  13. 12
      mass_editing/wizard/mass_editing_wizard.py

20
mass_editing/ChangeLog.txt

@ -1,20 +0,0 @@
===============================================================================
Version Change Log (mass_editing)
===============================================================================
1.6 * June 01,2016 : Serpent Consulting Services
* Added Unit Test Cases
1.5 * March 23,2016 : Serpent Consulting Services
* Added README and index.html file.
1.4 * March 19,2016 : Serpent Consulting Services
* Improved and migrated the code as per API and OCA standards.
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

29
mass_editing/README.rst

@ -1,6 +1,6 @@
.. image:: https://img.shields.io/badge/license-LGPLv3-blue.svg
:target: https://www.gnu.org/licenses/lgpl.html
:alt: License: LGPL-3
.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
============
Mass Editing
@ -12,12 +12,6 @@ This module provides the following features:
* You can configure mass editing for any Odoo 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
Installation
============
@ -37,7 +31,7 @@ This module allows to add, update or remove the values of more than one records
.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas
:alt: Try me on Runbot
:target: https://runbot.odoo-community.org/runbot/149/9.0
:target: https://runbot.odoo-community.org/runbot/149/11.0
As shown in figure you have to configure the object and fields for mass editing.
@ -70,13 +64,13 @@ Bug Tracker
===========
Bugs are tracked on `GitHub Issues
<https://github.com/OCA/server-tools/issues>`_. In case of trouble, please
<https://github.com/OCA/server-ux/issues>`_. In case of trouble, please
check there if your issue has already been reported. If you spotted it first,
help us smashing it by providing a detailed and welcomed `feedback
<https://github.com/OCA/
server-tools/issues/new?body=module:%20
server-tools%0Aversion:%20
9.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
server-ux/issues/new?body=module:%20
server-ux%0Aversion:%20
11.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
Credits
=======
@ -91,14 +85,16 @@ Contributors
* Oihane Crucelaegui <oihanecrucelaegi@gmail.com>
* Serpent Consulting Services Pvt. Ltd. <support@serpentcs.com>
* Jay Vora <jay.vora@serpentcs.com>
* Jairo Llopis <jairo.llopis@tecnativa.com>
* Juan Negrete <jnegrete@casasalce.com>
Maintainer
----------
.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: http://odoo-community.org
:target: https://odoo-community.org
This module is maintained by the OCA.
@ -106,5 +102,4 @@ OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.
To contribute to this module, please visit http://odoo-community.org.
To contribute to this module, please visit https://odoo-community.org.

1
mass_editing/__init__.py

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# © 2016 Serpent Consulting Services Pvt. Ltd. (support@serpentcs.com)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

10
mass_editing/__manifest__.py

@ -1,20 +1,14 @@
# -*- coding: utf-8 -*-
# © 2016 Serpent Consulting Services Pvt. Ltd. (support@serpentcs.com)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
{
'name': 'Mass Editing',
'version': '10.0.1.1.0',
'version': '11.0.1.0.0',
'author': 'Serpent Consulting Services Pvt. Ltd., '
'Tecnativa, '
'Odoo Community Association (OCA)',
'contributors': [
'Oihane Crucelaegui <oihanecrucelaegi@gmail.com>',
'Serpent Consulting Services Pvt. Ltd. <support@serpentcs.com>',
'Jay Vora <jay.vora@serpentcs.com>'
],
'category': 'Tools',
'website': 'http://www.serpentcs.com',
'license': 'GPL-3 or any later version',
'license': 'AGPL-3',
'summary': 'Mass Editing',
'uninstall_hook': 'uninstall_hook',
'depends': ['base'],

8
mass_editing/hooks.py

@ -1,12 +1,10 @@
# -*- coding: utf-8 -*-
# © 2016 Serpent Consulting Services Pvt. Ltd. (support@serpentcs.com)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
def uninstall_hook(cr, registry):
cr.execute("""SELECT id FROM ir_act_window
"""Delete the actions that were created with mass_editing when
the module is uninstalled"""
cr.execute("""DELETE FROM ir_act_window
WHERE res_model = 'mass.editing.wizard'""")
for res in cr.dictfetchall():
value = 'ir.actions.act_window,%s' % res.get('id')
cr.execute("DELETE FROM ir_values WHERE value = %s", (value, ))
return True

129
mass_editing/i18n/mass_editing.pot

@ -1,129 +0,0 @@
# 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_id: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_id: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_id: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_id:0
msgid "Sidebar button to open the sidebar action"
msgstr ""

1
mass_editing/models/__init__.py

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# © 2016 Serpent Consulting Services Pvt. Ltd. (support@serpentcs.com)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

7
mass_editing/models/ir_model_fields.py

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# © 2016 Serpent Consulting Services Pvt. Ltd. (support@serpentcs.com)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
@ -12,11 +11,11 @@ class IrModelFields(models.Model):
def search(self, args, offset=0, limit=0, order=None, count=False):
model_domain = []
for domain in args:
if (len(domain) > 2 and domain[0] == 'model_id' and
isinstance(domain[2], basestring) and
if (len(domain) > 2 and domain[0] == 'mass_editing_domain' and
isinstance(domain[2], str) and
list(domain[2][1:-1])):
model_domain += [('model_id', 'in',
map(int, domain[2][1:-1].split(',')))]
list(map(int, domain[2][1:-1].split(','))))]
else:
model_domain.append(domain)
return super(IrModelFields, self).search(model_domain, offset=offset,

26
mass_editing/models/mass_object.py

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# © 2016 Serpent Consulting Services Pvt. Ltd. (support@serpentcs.com)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
@ -24,14 +23,10 @@ class MassObject(models.Model):
"template available on "
"records of the related "
"document model.")
ref_ir_value_id = fields.Many2one('ir.values', 'Sidebar button',
readonly=True,
help="Sidebar button to open "
"the sidebar action.")
model_list = fields.Char('Model List')
_sql_constraints = [
('name_uniq', 'unique (name)', _('Name must be unique!')),
('name_uniq', 'unique (name)', 'Name must be unique!'),
]
@api.onchange('model_id')
@ -43,7 +38,7 @@ class MassObject(models.Model):
model_list = [self.model_id.id]
active_model_obj = self.env[self.model_id.model]
if active_model_obj._inherits:
keys = active_model_obj._inherits.keys()
keys = list(active_model_obj._inherits.keys())
inherits_model_list = model_obj.search([('model', 'in', keys)])
model_list.extend((inherits_model_list and
inherits_model_list.ids or []))
@ -65,25 +60,16 @@ class MassObject(models.Model):
'context': "{'mass_editing_object' : %d}" % (self.id),
'view_mode': 'form, tree',
'target': 'new',
}).id
# We make sudo as any user with rights in this model should be able
# to create the action, not only admin
vals['ref_ir_value_id'] = self.env['ir.values'].sudo().create({
'name': button_name,
'model': src_obj,
'key2': 'client_action_multi',
'value': "ir.actions.act_window," +
str(vals['ref_ir_act_window_id']),
'binding_model_id': self.model_id.id,
'binding_type': 'action',
'multi': True,
}).id
self.write(vals)
return True
@api.multi
def unlink_action(self):
# We make sudo as any user with rights in this model should be able
# to delete the action, not only admin
self.mapped('ref_ir_act_window_id').sudo().unlink()
self.mapped('ref_ir_value_id').sudo().unlink()
self.mapped('ref_ir_act_window_id').unlink()
return True
@api.multi

1
mass_editing/tests/__init__.py

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# © 2016 Serpent Consulting Services Pvt. Ltd. (support@serpentcs.com)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

59
mass_editing/tests/test_mass_editing.py

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# © 2016 Serpent Consulting Services Pvt. Ltd. (support@serpentcs.com)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
@ -89,6 +88,27 @@ class TestMassEditing(common.TransactionCase):
self.assertTrue(self.user_model.id in model_list,
'Onchange model list must contains model_id.')
def test_wiz_read_fields(self):
"""Test whether read method returns all fields or not."""
ctx = {
'mass_editing_object': self.mass.id,
'active_id': self.partner.id,
'active_ids': self.partner.ids,
'active_model': 'res.partner',
}
fields_view = self.mass_wiz_obj.with_context(ctx).fields_view_get()
fields = list(fields_view['fields'].keys())
# add a real field
fields.append('display_name')
vals = {
'selection__email': 'remove',
'selection__phone': 'remove',
}
mass_wiz_obj = self._apply_action(self.partner, vals)
result = mass_wiz_obj.read(fields)[0]
self.assertTrue(all([field in result for field in fields]),
'Read must return all fields.')
def test_mass_edit_email(self):
"""Test Case for MASS EDITING which will remove and after add
Partner's email and will assert the same."""
@ -121,13 +141,23 @@ class TestMassEditing(common.TransactionCase):
'Partner\'s category should be removed.')
# Add m2m categories
dist_categ_id = self.env.ref('base.res_partner_category_13').id
vend_categ_id = self.env.ref('base.res_partner_category_1').id
vals = {
'selection__category_id': 'add',
'category_id': [[6, 0, [dist_categ_id]]],
'category_id': [[6, 0, [dist_categ_id, vend_categ_id]]],
}
wiz_action = self._apply_action(self.partner, vals)
self.assertTrue(dist_categ_id in self.partner.category_id.ids,
self.assertTrue(all(item in self.partner.category_id.ids
for item in [dist_categ_id, vend_categ_id]),
'Partner\'s category should be added.')
# Remove one m2m category
vals = {
'selection__category_id': 'remove_m2m',
'category_id': [[6, 0, [vend_categ_id]]],
}
wiz_action = self._apply_action(self.partner, vals)
self.assertTrue([dist_categ_id] == self.partner.category_id.ids,
'Partner\'s category should be removed.')
# Check window close action
res = wiz_action.action_apply()
self.assertTrue(res['type'] == 'ir.actions.act_window_close',
@ -142,21 +172,23 @@ class TestMassEditing(common.TransactionCase):
def test_sidebar_action(self):
"""Test if Sidebar Action is added / removed to / from give object."""
action = self.mass.ref_ir_act_window_id and self.mass.ref_ir_value_id
action = self.mass.ref_ir_act_window_id\
and self.mass.ref_ir_act_window_id.binding_model_id
self.assertTrue(action, 'Sidebar action must be exists.')
# Remove the sidebar actions
self.mass.unlink_action()
action = self.mass.ref_ir_act_window_id and self.mass.ref_ir_value_id
action = self.mass.ref_ir_act_window_id
self.assertFalse(action, 'Sidebar action must be removed.')
def test_unlink_mass(self):
"""Test if related actions are removed when mass editing
record is unlinked."""
mass_action_id = "ir.actions.act_window," + str(self.mass.id)
self.mass.unlink()
value_cnt = self.env['ir.values'].search([('value', '=',
mass_action_id)],
count=True)
mass_action_id = self.mass.ref_ir_act_window_id.id
mass_object_id = self.mass.id
mass_id = self.env['mass.object'].browse(mass_object_id)
mass_id.unlink()
value_cnt = self.env['ir.actions.act_window'].search([
('id', '=', mass_action_id)], count=True)
self.assertTrue(value_cnt == 0,
"Sidebar action must be removed when mass"
" editing is unlinked.")
@ -165,10 +197,9 @@ class TestMassEditing(common.TransactionCase):
"""Test if related actions are removed when mass editing
record is uninstalled."""
uninstall_hook(self.cr, registry)
mass_action_id = "ir.actions.act_window," + str(self.mass.id)
value_cnt = self.env['ir.values'].search([('value', '=',
mass_action_id)],
count=True)
mass_action_id = self.mass.ref_ir_act_window_id.id
value_cnt = len(self.env['ir.actions.act_window'].browse(
mass_action_id))
self.assertTrue(value_cnt == 0,
"Sidebar action must be removed when mass"
" editing module is uninstalled.")

3
mass_editing/views/mass_editing_view.xml

@ -41,12 +41,11 @@
<notebook colspan="4">
<page string="Fields">
<field name="field_ids" colspan="4" nolabel="1"
domain="[('ttype', 'not in', ['reference', 'function']), ('model_id', 'in', model_list)]"/>
domain="[('ttype', 'not in', ['reference', 'function']), ('mass_editing_domain', 'in', model_list)]"/>
</page>
<page string="Advanced" attrs="{'invisible':[('ref_ir_act_window_id','=',False)]}">
<group colspan="2" col="2">
<field name="ref_ir_act_window_id"/>
<field name="ref_ir_value_id"/>
</group>
</page>
</notebook>

12
mass_editing/wizard/mass_editing_wizard.py

@ -246,6 +246,13 @@ class MassEditingWizard(models.TransientModel):
elif val == 'remove':
values.update({split_key: False})
elif val == 'remove_m2m':
m2m_list = []
if vals.get(split_key):
for m2m_id in vals.get(split_key)[0][2]:
m2m_list.append((3, m2m_id))
if m2m_list:
values.update({split_key: m2m_list})
else:
values.update({split_key: [(5, 0, [])]})
elif val == 'add':
m2m_list = []
@ -271,4 +278,7 @@ class MassEditingWizard(models.TransientModel):
if fields:
# We remove fields which are not in _fields
real_fields = [x for x in fields if x in self._fields]
return super(MassEditingWizard, self).read(real_fields, load=load)
result = super(MassEditingWizard, self).read(real_fields, load=load)
# adding fields to result
[result[0].update({x: False}) for x in fields if x not in real_fields]
return result
Loading…
Cancel
Save