Browse Source
Added Mass Editing v9 (#315)
Added Mass Editing v9 (#315)
* Added Mass Editing v9 * [IMP] Improved the coding standard as per API and PEP8. * [ADD] Added README and index file. * [IMP] Improved the indentation of the code as per travis test suggestion. * [IMP] Improved the README.rst * Update mass_object.py * Delete index.html * [ADD] Added unit test cases for MassEditing module. * Corrected as per @api.multi * Correction for the travis test * Correction for the travis test * [IMP] Improved the code as per review comments, improved copyrights, added test more cases and uninstall hook. * [ADD] Added Unit test case for m2m fields. * [ADD] Further added unit test case for unlink and multiple fields. * [ADD] Added unit test case for model_id onchange. * [IMP] Fixed the issue of eval in unit test case. * [ADD] Added unit test case for uninstall hook. * [ADD] Added unit test case for uninstall hook. * [ADD] Added unit test case for wizard's fields_view_get method. * [IMP] Improved the unit test case to cover more lines of code of fields view get. * [IMP] Improved the unit test case to cover more lines of code of fields view get.pull/29/head
Serpent Consulting Services Pvt Ltd
8 years ago
committed by
Aitor Bouzas
28 changed files with 718 additions and 501 deletions
-
9mass_editing/ChangeLog.txt
-
109mass_editing/README.rst
-
24mass_editing/__init__.py
-
57mass_editing/__openerp__.py
-
12mass_editing/hooks.py
-
8mass_editing/i18n/de.po
-
8mass_editing/i18n/es.po
-
8mass_editing/i18n/fr.po
-
8mass_editing/i18n/fr_CA.po
-
8mass_editing/i18n/it.po
-
8mass_editing/i18n/mass_editing.pot
-
8mass_editing/i18n/pt_BR.po
-
8mass_editing/i18n/ru.po
-
8mass_editing/i18n/sl.po
-
22mass_editing/models/__init__.py
-
46mass_editing/models/ir_model_fields.py
-
174mass_editing/models/mass_object.py
-
0mass_editing/security/ir.model.access.csv
-
BINmass_editing/static/description/mass_editing-1.png
-
BINmass_editing/static/description/mass_editing-2.png
-
BINmass_editing/static/description/mass_editing-3.png
-
BINmass_editing/static/description/mass_editing-4.png
-
BINmass_editing/static/description/mass_editing-5.png
-
5mass_editing/tests/__init__.py
-
174mass_editing/tests/test_mass_editing.py
-
78mass_editing/views/mass_editing_view.xml
-
22mass_editing/wizard/__init__.py
-
279mass_editing/wizard/mass_editing_wizard.py
@ -0,0 +1,109 @@ |
|||
.. image:: https://img.shields.io/badge/license-LGPLv3-blue.svg |
|||
:target: https://www.gnu.org/licenses/lgpl.html |
|||
:alt: License: LGPL-3 |
|||
|
|||
============ |
|||
Mass Editing |
|||
============ |
|||
|
|||
This module provides the following features: |
|||
|
|||
* You can 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 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 |
|||
============ |
|||
|
|||
No external library is used. |
|||
|
|||
Configuration |
|||
============= |
|||
|
|||
To configure this module, you need to: |
|||
|
|||
* Go to *Settings / Mass Editing / Mass Editing* and configure the object and fields for Mass Editing. |
|||
|
|||
Usage |
|||
===== |
|||
|
|||
This module allows to add, update or remove the values of more than one records on the fly at the same time. |
|||
|
|||
.. 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 |
|||
|
|||
As shown in figure you have to configure the object and fields for mass editing. |
|||
|
|||
* Select the object and add the fields of that object on which you want to apply mass editing. |
|||
|
|||
.. image:: /mass_editing/static/description/mass_editing-1.png |
|||
:width: 70% |
|||
|
|||
* *Add Action*: As shown in figure click on *Add Sidebar Button* to add mass editing option in *Action* option in action. |
|||
|
|||
.. image:: /mass_editing/static/description/mass_editing-2.png |
|||
:width: 70% |
|||
|
|||
* *Go for Mass Editing*: As shown in figure, select the records which you want to modify and click on *Action* to open mass editing popup. |
|||
|
|||
.. image:: /mass_editing/static/description/mass_editing-3.png |
|||
:width: 70% |
|||
|
|||
* Select *Set / Remove* action and write down the value to set or remove the value for the given field. |
|||
|
|||
.. image:: /mass_editing/static/description/mass_editing-4.png |
|||
:width: 70% |
|||
|
|||
* This way you can set / remove the values of the fields. |
|||
|
|||
.. image:: /mass_editing/static/description/mass_editing-5.png |
|||
:width: 70% |
|||
|
|||
Bug Tracker |
|||
=========== |
|||
|
|||
Bugs are tracked on `GitHub Issues |
|||
<https://github.com/OCA/server-tools/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**>`_. |
|||
|
|||
Credits |
|||
======= |
|||
|
|||
Images |
|||
------ |
|||
|
|||
* Odoo Community Association: `Icon <https://github.com/OCA/maintainer-tools/blob/master/template/module/static/description/icon.svg>`_. |
|||
|
|||
Contributors |
|||
------------ |
|||
|
|||
* Oihane Crucelaegui <oihanecrucelaegi@gmail.com> |
|||
* Serpent Consulting Services Pvt. Ltd. <support@serpentcs.com> |
|||
|
|||
Maintainer |
|||
---------- |
|||
|
|||
.. image:: https://odoo-community.org/logo.png |
|||
:alt: Odoo Community Association |
|||
:target: http://odoo-community.org |
|||
|
|||
This module is maintained by the OCA. |
|||
|
|||
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. |
|||
|
@ -1,24 +1,8 @@ |
|||
# -*- coding: utf-8 -*- |
|||
############################################################################## |
|||
# |
|||
# This module uses OpenERP, Open Source Management Solution Framework. |
|||
# Copyright (C): |
|||
# 2012-Today Serpent Consulting Services (<http://www.serpentcs. |
|||
# |
|||
# 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/> |
|||
# |
|||
############################################################################## |
|||
# © 2016 Serpent Consulting Services Pvt. Ltd. (support@serpentcs.com) |
|||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). |
|||
|
|||
from . import models |
|||
from . import wizard |
|||
from . import tests |
|||
from .hooks import uninstall_hook |
@ -1,51 +1,26 @@ |
|||
# -*- coding: utf-8 -*- |
|||
############################################################################## |
|||
# |
|||
# This module uses OpenERP, Open Source Management Solution Framework. |
|||
# Copyright (C): |
|||
# 2012-Today Serpent Consulting Services (<http://www.serpentcs.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/> |
|||
# |
|||
############################################################################## |
|||
# © 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": "8.0.1.3.0", |
|||
"author": "Serpent Consulting Services,Odoo Community Association (OCA)", |
|||
"contributors": [ |
|||
"Oihane Crucelaegui <oihanecrucelaegi@gmail.com>", |
|||
'name': 'Mass Editing', |
|||
'version': '9.0.1.0.0', |
|||
'author': 'Serpent Consulting Services Pvt. Ltd., ' |
|||
'Odoo Community Association (OCA)', |
|||
'contributors': [ |
|||
'Oihane Crucelaegui <oihanecrucelaegi@gmail.com>', |
|||
'Serpent Consulting Services Pvt. Ltd. <support@serpentcs.com>', |
|||
], |
|||
"category": "Tools", |
|||
"website": "http://www.serpentcs.com", |
|||
"license": "GPL-3 or any later version", |
|||
"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. |
|||
""", |
|||
'category': 'Tools', |
|||
'website': 'http://www.serpentcs.com', |
|||
'license': 'GPL-3 or any later version', |
|||
'summary': 'Mass Editing', |
|||
'uninstall_hook': 'uninstall_hook', |
|||
'depends': ['base'], |
|||
'data': [ |
|||
"security/ir.model.access.csv", |
|||
'security/ir.model.access.csv', |
|||
'views/mass_editing_view.xml', |
|||
], |
|||
'installable': True, |
|||
'application': True, |
|||
'application': False, |
|||
'auto_install': False, |
|||
} |
@ -0,0 +1,12 @@ |
|||
# -*- 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 |
|||
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 |
@ -1,24 +1,6 @@ |
|||
# -*- coding: utf-8 -*- |
|||
############################################################################## |
|||
# |
|||
# This module uses OpenERP, Open Source Management Solution Framework. |
|||
# Copyright (C): |
|||
# 2012-Today Serpent Consulting Services (<http://www.serpentcs.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/> |
|||
# |
|||
############################################################################## |
|||
# © 2016 Serpent Consulting Services Pvt. Ltd. (support@serpentcs.com) |
|||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). |
|||
|
|||
from . import ir_model_fields |
|||
from . import mass_object |
@ -1,45 +1,23 @@ |
|||
# -*- coding: utf-8 -*- |
|||
############################################################################## |
|||
# |
|||
# This module uses OpenERP, Open Source Management Solution Framework. |
|||
# Copyright (C): |
|||
# 2012-Today Serpent Consulting Services (<http://www.serpentcs.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/> |
|||
# |
|||
############################################################################## |
|||
# © 2016 Serpent Consulting Services Pvt. Ltd. (support@serpentcs.com) |
|||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). |
|||
|
|||
from openerp.osv import orm |
|||
from openerp import api, models |
|||
|
|||
|
|||
class IrModelFields(orm.Model): |
|||
class IrModelFields(models.Model): |
|||
_inherit = 'ir.model.fields' |
|||
|
|||
def search( |
|||
self, cr, uid, args, offset=0, limit=0, order=None, context=None, |
|||
count=False): |
|||
@api.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 |
|||
if (len(domain) > 2 and domain[0] == 'model_id' and |
|||
isinstance(domain[2], basestring)): |
|||
model_domain += [ |
|||
('model_id', 'in', map(int, domain[2][1:-1].split(','))) |
|||
] |
|||
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 |
|||
) |
|||
return super(IrModelFields, self).search(model_domain, offset=offset, |
|||
limit=limit, order=order, |
|||
count=count) |
@ -1,138 +1,102 @@ |
|||
# -*- coding: utf-8 -*- |
|||
############################################################################## |
|||
# |
|||
# This module uses OpenERP, Open Source Management Solution Framework. |
|||
# Copyright (C): |
|||
# 2012-Today Serpent Consulting Services (<http://www.serpentcs.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/> |
|||
# |
|||
############################################################################## |
|||
# © 2016 Serpent Consulting Services Pvt. Ltd. (support@serpentcs.com) |
|||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). |
|||
|
|||
from openerp import SUPERUSER_ID |
|||
from openerp.osv import orm, fields |
|||
from openerp.tools.translate import _ |
|||
from openerp.exceptions import UserError |
|||
from openerp import api, fields, models, _ |
|||
|
|||
|
|||
class MassObject(orm.Model): |
|||
class MassObject(models.Model): |
|||
_name = "mass.object" |
|||
_description = "Mass Editing 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') |
|||
} |
|||
name = fields.Char('Name', required=True, select=1) |
|||
model_id = fields.Many2one('ir.model', 'Model', required=True, |
|||
help="Model is used for Selecting Fields. " |
|||
"This is editable until Sidebar menu " |
|||
"is not created.") |
|||
field_ids = fields.Many2many('ir.model.fields', 'mass_field_rel', |
|||
'mass_id', 'field_id', 'Fields') |
|||
ref_ir_act_window_id = 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_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!')), |
|||
] |
|||
|
|||
def onchange_model_id(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) |
|||
@api.onchange('model_id') |
|||
def _onchange_model_id(self): |
|||
self.field_ids = [(6, 0, [])] |
|||
model_list = [] |
|||
if self.model_id: |
|||
model_obj = self.env['ir.model'] |
|||
model_list = [self.model_id.id] |
|||
active_model_obj = self.env[self.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)]}} |
|||
keys = 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 [])) |
|||
self.model_list = model_list |
|||
|
|||
def create_action(self, cr, uid, ids, context=None): |
|||
@api.multi |
|||
def create_action(self): |
|||
self.ensure_one() |
|||
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, |
|||
{ |
|||
action_obj = self.env['ir.actions.act_window'] |
|||
src_obj = self.model_id.model |
|||
button_name = _('Mass Editing (%s)') % self.name |
|||
vals['ref_ir_act_window_id'] = action_obj.create({ |
|||
'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', |
|||
'context': "{'mass_editing_object' : %d}" % (self.id), |
|||
'view_mode': 'form, tree', |
|||
'target': 'new', |
|||
'auto_refresh': 1, |
|||
}, |
|||
context) |
|||
vals['ref_ir_value'] = ir_values_obj.create( |
|||
cr, SUPERUSER_ID, |
|||
{ |
|||
}).id |
|||
vals['ref_ir_value_id'] = self.env['ir.values'].create({ |
|||
'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) |
|||
'value': "ir.actions.act_window," + |
|||
str(vals['ref_ir_act_window_id']), |
|||
}).id |
|||
self.write(vals) |
|||
return True |
|||
|
|||
def unlink_action(self, cr, uid, ids, context=None): |
|||
for template in self.browse(cr, uid, ids, context=context): |
|||
@api.multi |
|||
def unlink_action(self): |
|||
for mass in self: |
|||
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) |
|||
if mass.ref_ir_act_window_id: |
|||
mass.ref_ir_act_window_id.unlink() |
|||
if mass.ref_ir_value_id: |
|||
mass.ref_ir_value_id.unlink() |
|||
except: |
|||
raise orm.except_orm( |
|||
_("Warning"), |
|||
_("Deletion of the action record failed.")) |
|||
raise UserError(_("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) |
|||
@api.multi |
|||
def unlink(self): |
|||
self.unlink_action() |
|||
return super(MassObject, self).unlink() |
|||
|
|||
def copy(self, cr, uid, record_id, default=None, context=None): |
|||
@api.returns('self', lambda value: value.id) |
|||
def copy(self, default=None): |
|||
if default is None: |
|||
default = {} |
|||
default.update({'name': '', 'field_ids': []}) |
|||
return super(MassObject, self).copy( |
|||
cr, uid, record_id, default, context=context) |
|||
default.update({'name': _("%s (copy)" % self.name), 'field_ids': []}) |
|||
return super(MassObject, self).copy(default) |
After Width: 1366 | Height: 570 | Size: 66 KiB |
After Width: 1366 | Height: 518 | Size: 69 KiB |
After Width: 1366 | Height: 333 | Size: 70 KiB |
After Width: 1366 | Height: 340 | Size: 50 KiB |
After Width: 1366 | Height: 329 | Size: 57 KiB |
@ -0,0 +1,5 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# © 2016 Serpent Consulting Services Pvt. Ltd. (support@serpentcs.com) |
|||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). |
|||
|
|||
from . import test_mass_editing |
@ -0,0 +1,174 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# © 2016 Serpent Consulting Services Pvt. Ltd. (support@serpentcs.com) |
|||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). |
|||
|
|||
import ast |
|||
|
|||
from openerp.tests import common |
|||
from openerp.modules import registry |
|||
from openerp.addons.mass_editing.hooks import uninstall_hook |
|||
|
|||
|
|||
class TestMassEditing(common.TransactionCase): |
|||
|
|||
def setUp(self): |
|||
super(TestMassEditing, self).setUp() |
|||
model_obj = self.env['ir.model'] |
|||
self.mass_wiz_obj = self.env['mass.editing.wizard'] |
|||
self.mass_object_model = self.env['mass.object'] |
|||
self.res_partner_model = self.env['res.partner'] |
|||
self.partner = self._create_partner() |
|||
self.partner_model = model_obj.\ |
|||
search([('model', '=', 'res.partner')]) |
|||
self.user_model = model_obj.search([('model', '=', 'res.users')]) |
|||
self.fields_model = self.env['ir.model.fields'].\ |
|||
search([('model_id', '=', self.partner_model.id), |
|||
('name', 'in', ['email', 'phone', 'category_id', 'comment', |
|||
'country_id', 'customer', 'child_ids', |
|||
'title'])]) |
|||
self.mass = self._create_mass_editing(self.partner_model, |
|||
self.fields_model) |
|||
self.copy_mass = self.mass.copy() |
|||
self.user = self._create_user() |
|||
|
|||
def _create_partner(self): |
|||
"""Create a Partner.""" |
|||
categ_ids = self.env['res.partner.category'].search([]).ids |
|||
return self.res_partner_model.create({ |
|||
'name': 'Test Partner', |
|||
'email': 'example@yourcompany.com', |
|||
'phone': 123456, |
|||
'category_id': [(6, 0, categ_ids)], |
|||
}) |
|||
|
|||
def _create_user(self): |
|||
return self.env['res.users'].create({ |
|||
'name': 'Test User', |
|||
'login': 'test_login', |
|||
'email': 'test@test.com', |
|||
}) |
|||
|
|||
def _create_mass_editing(self, model, fields): |
|||
"""Create a Mass Editing with Partner as model and |
|||
email field of partner.""" |
|||
mass = self.mass_object_model.create({ |
|||
'name': 'Mass Editing for Partner', |
|||
'model_id': model.id, |
|||
'field_ids': [(6, 0, fields.ids)] |
|||
}) |
|||
mass.create_action() |
|||
return mass |
|||
|
|||
def _apply_action(self, partner, vals): |
|||
"""Create Wizard object to perform mass editing to |
|||
REMOVE field's value.""" |
|||
ctx = { |
|||
'active_id': partner.id, |
|||
'active_ids': partner.ids, |
|||
'active_model': 'res.partner', |
|||
} |
|||
return self.mass_wiz_obj.with_context(ctx).create(vals) |
|||
|
|||
def test_wiz_fields_view_get(self): |
|||
"""Test whether fields_view_get method returns arch or not.""" |
|||
ctx = { |
|||
'mass_editing_object': self.mass.id, |
|||
'active_id': self.partner.id, |
|||
'active_ids': self.partner.ids, |
|||
'active_model': 'res.partner', |
|||
} |
|||
result = self.mass_wiz_obj.with_context(ctx).fields_view_get() |
|||
self.assertTrue(result.get('arch'), |
|||
'Fields view get must return architecture.') |
|||
|
|||
def test_onchange_model(self): |
|||
"""Test whether onchange model_id returns model_id in list""" |
|||
new_mass = self.mass_object_model.new({'model_id': self.user_model.id}) |
|||
new_mass._onchange_model_id() |
|||
model_list = ast.literal_eval(new_mass.model_list) |
|||
self.assertTrue(self.user_model.id in model_list, |
|||
'Onchange model list must contains model_id.') |
|||
|
|||
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.""" |
|||
# Remove email address |
|||
vals = { |
|||
'selection__email': 'remove', |
|||
'selection__phone': 'remove', |
|||
} |
|||
self._apply_action(self.partner, vals) |
|||
self.assertEqual(self.partner.email, False, |
|||
'Partner\'s Email should be removed.') |
|||
# Set email address |
|||
vals = { |
|||
'selection__email': 'set', |
|||
'email': 'sample@mycompany.com', |
|||
} |
|||
self._apply_action(self.partner, vals) |
|||
self.assertNotEqual(self.partner.email, False, |
|||
'Partner\'s Email should be set.') |
|||
|
|||
def test_mass_edit_m2m_categ(self): |
|||
"""Test Case for MASS EDITING which will remove and add |
|||
Partner's category m2m.""" |
|||
# Remove m2m categories |
|||
vals = { |
|||
'selection__category_id': 'remove_m2m', |
|||
} |
|||
self._apply_action(self.partner, vals) |
|||
self.assertNotEqual(self.partner.category_id, False, |
|||
'Partner\'s category should be removed.') |
|||
# Add m2m categories |
|||
dist_categ_id = self.env.ref('base.res_partner_category_13').id |
|||
vals = { |
|||
'selection__category_id': 'add', |
|||
'category_id': [[6, 0, [dist_categ_id]]], |
|||
} |
|||
wiz_action = self._apply_action(self.partner, vals) |
|||
self.assertTrue(dist_categ_id in self.partner.category_id.ids, |
|||
'Partner\'s category should be added.') |
|||
# Check window close action |
|||
res = wiz_action.action_apply() |
|||
self.assertTrue(res['type'] == 'ir.actions.act_window_close', |
|||
'IR Action must be window close.') |
|||
|
|||
def test_mass_edit_copy(self): |
|||
"""Test if fields one2many field gets blank when mass editing record |
|||
is copied. |
|||
""" |
|||
self.assertEqual(self.copy_mass.field_ids.ids, [], |
|||
'Fields must be blank.') |
|||
|
|||
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 |
|||
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 |
|||
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) |
|||
self.assertTrue(value_cnt == 0, |
|||
"Sidebar action must be removed when mass" |
|||
" editing is unlinked.") |
|||
|
|||
def test_uninstall_hook(self): |
|||
"""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) |
|||
self.assertTrue(value_cnt == 0, |
|||
"Sidebar action must be removed when mass" |
|||
" editing module is uninstalled.") |
@ -1,23 +1,5 @@ |
|||
# -*- coding: utf-8 -*- |
|||
############################################################################## |
|||
# |
|||
# This module uses OpenERP, Open Source Management Solution Framework. |
|||
# Copyright (C): |
|||
# 2012-Today Serpent Consulting Services (<http://www.serpentcs. |
|||
# |
|||
# 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/> |
|||
# |
|||
############################################################################## |
|||
# © 2016 Serpent Consulting Services Pvt. Ltd. (support@serpentcs.com) |
|||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). |
|||
|
|||
from . import mass_editing_wizard |
@ -1,213 +1,258 @@ |
|||
# -*- coding: utf-8 -*- |
|||
############################################################################## |
|||
# |
|||
# This module uses OpenERP, Open Source Management Solution Framework. |
|||
# Copyright (C): |
|||
# 2012-Today Serpent Consulting Services (<http://www.serpentcs.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/> |
|||
# |
|||
############################################################################## |
|||
# © 2016 Serpent Consulting Services Pvt. Ltd. (support@serpentcs.com) |
|||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). |
|||
|
|||
from openerp.osv import orm |
|||
import openerp.tools as tools |
|||
from lxml import etree |
|||
|
|||
import openerp.tools as tools |
|||
from openerp import api, models |
|||
|
|||
|
|||
class MassEditingWizard(orm.TransientModel): |
|||
class MassEditingWizard(models.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) |
|||
@api.model |
|||
def fields_view_get(self, view_id=None, view_type='form', toolbar=False, |
|||
submenu=False): |
|||
result =\ |
|||
super(MassEditingWizard, self).fields_view_get(view_id=view_id, |
|||
view_type=view_type, |
|||
toolbar=toolbar, |
|||
submenu=submenu) |
|||
context = self._context |
|||
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) |
|||
mass_obj = self.env['mass.object'] |
|||
editing_data = mass_obj.browse(context.get('mass_editing_object')) |
|||
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'}) |
|||
'string': tools.ustr(editing_data.name) |
|||
}) |
|||
xml_group = etree.SubElement(xml_form, 'group', { |
|||
'colspan': '6', |
|||
'col': '6', |
|||
}) |
|||
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) |
|||
'string': '', |
|||
'colspan': '2', |
|||
}) |
|||
xml_group = etree.SubElement(xml_form, 'group', { |
|||
'colspan': '6', |
|||
'col': '6', |
|||
}) |
|||
model_obj = self.env[context.get('active_model')] |
|||
field_info = model_obj.fields_get() |
|||
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')]} |
|||
'selection': [('set', 'Set'), |
|||
('remove_m2m', 'Remove'), |
|||
('add', 'Add')] |
|||
} |
|||
xml_group = etree.SubElement(xml_group, 'group', { |
|||
'colspan': '4'}) |
|||
'colspan': '6', |
|||
'col': '6', |
|||
}) |
|||
etree.SubElement(xml_group, 'separator', { |
|||
'string': field_info[field.name]['string'], |
|||
'colspan': '2'}) |
|||
'colspan': '6', |
|||
}) |
|||
etree.SubElement(xml_group, 'field', { |
|||
'name': "selection__" + field.name, |
|||
'colspan': '2', 'nolabel': '1'}) |
|||
'colspan': '6', |
|||
'nolabel': '1' |
|||
}) |
|||
etree.SubElement(xml_group, 'field', { |
|||
'name': field.name, 'colspan': '4', 'nolabel': '1', |
|||
'attrs': ( |
|||
"{'invisible':[('selection__" + |
|||
field.name + "','=','remove_m2m')]}")}) |
|||
'name': field.name, |
|||
'colspan': '6', |
|||
'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')]} |
|||
'selection': [('set', 'Set'), ('remove', 'Remove')], |
|||
} |
|||
all_fields[field.name] = { |
|||
'type': field.ttype, 'string': field.field_description, |
|||
'relation': field.relation} |
|||
'type': field.ttype, |
|||
'string': field.field_description, |
|||
'relation': field.relation, |
|||
} |
|||
etree.SubElement(xml_group, 'field', { |
|||
'name': "selection__" + field.name, 'colspan': '2'}) |
|||
'name': "selection__" + field.name, |
|||
'colspan': '4', |
|||
}) |
|||
etree.SubElement(xml_group, 'field', { |
|||
'name': field.name, 'colspan': '4', 'nolabel': '1', |
|||
'attrs': ( |
|||
"{'invisible':[('selection__" + |
|||
field.name + "','=','remove_o2m')]}")}) |
|||
'name': field.name, |
|||
'colspan': '6', |
|||
'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')]} |
|||
'selection': [('set', 'Set'), ('remove', 'Remove')], |
|||
} |
|||
all_fields[field.name] = { |
|||
'type': field.ttype, 'string': field.field_description, |
|||
'relation': field.relation} |
|||
'type': field.ttype, |
|||
'string': field.field_description, |
|||
'relation': field.relation, |
|||
} |
|||
etree.SubElement(xml_group, 'field', { |
|||
'name': "selection__" + field.name, 'colspan': '2'}) |
|||
'name': "selection__" + field.name, |
|||
'colspan': '2', |
|||
}) |
|||
etree.SubElement(xml_group, 'field', { |
|||
'name': field.name, 'nolabel': '1', 'colspan': '2', |
|||
'attrs': ( |
|||
"{'invisible':[('selection__" + |
|||
field.name + "','=','remove')]}")}) |
|||
'name': field.name, |
|||
'nolabel': '1', |
|||
'colspan': '4', |
|||
'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')]} |
|||
'selection': [('set', 'Set'), ('remove', 'Remove')], |
|||
} |
|||
all_fields[field.name] = { |
|||
'type': field.ttype, 'string': field.field_description, |
|||
'size': field.size or 256} |
|||
'type': field.ttype, |
|||
'string': field.field_description, |
|||
'size': field.size or 256, |
|||
} |
|||
etree.SubElement(xml_group, 'field', { |
|||
'name': "selection__" + field.name, |
|||
'colspan': '2', |
|||
}) |
|||
etree.SubElement(xml_group, 'field', { |
|||
'name': field.name, 'nolabel': '1', |
|||
'attrs': ( |
|||
"{'invisible':[('selection__" + |
|||
'name': field.name, |
|||
'nolabel': '1', |
|||
'attrs': ("{'invisible':[('selection__" + |
|||
field.name + "','=','remove')]}"), |
|||
'colspan': '2'}) |
|||
'colspan': '4', |
|||
}) |
|||
elif field.ttype == 'selection': |
|||
all_fields["selection__" + field.name] = { |
|||
'type': 'selection', |
|||
'string': field_info[field.name]['string'], |
|||
'selection': [('set', 'Set'), ('remove', 'Remove')]} |
|||
'selection': [('set', 'Set'), ('remove', 'Remove')] |
|||
} |
|||
etree.SubElement(xml_group, 'field', { |
|||
'name': "selection__" + field.name, 'colspan': '2'}) |
|||
'name': "selection__" + field.name, |
|||
'colspan': '2', |
|||
}) |
|||
etree.SubElement(xml_group, 'field', { |
|||
'name': field.name, 'nolabel': '1', 'colspan': '2', |
|||
'attrs': ( |
|||
"{'invisible':[('selection__" + |
|||
field.name + "','=','remove')]}")}) |
|||
'name': field.name, |
|||
'nolabel': '1', |
|||
'colspan': '4', |
|||
'attrs': ("{'invisible':[('selection__" + |
|||
field.name + "', '=', 'remove')]}"), |
|||
}) |
|||
all_fields[field.name] = { |
|||
'type': field.ttype, |
|||
'string': field.field_description, |
|||
'selection': field_info[field.name]['selection']} |
|||
'selection': field_info[field.name]['selection'], |
|||
} |
|||
else: |
|||
all_fields[field.name] = { |
|||
'type': field.ttype, 'string': field.field_description} |
|||
'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')]} |
|||
'selection': [('set', 'Set'), ('remove', 'Remove')] |
|||
} |
|||
if field.ttype == 'text': |
|||
xml_group = etree.SubElement(xml_group, 'group', { |
|||
'colspan': '6'}) |
|||
'colspan': '6', |
|||
'col': '6', |
|||
}) |
|||
etree.SubElement(xml_group, 'separator', { |
|||
'string': all_fields[field.name]['string'], |
|||
'colspan': '2'}) |
|||
'colspan': '6', |
|||
}) |
|||
etree.SubElement(xml_group, 'field', { |
|||
'name': "selection__" + field.name, |
|||
'colspan': '2', 'nolabel': '1'}) |
|||
'colspan': '6', |
|||
'nolabel': '1', |
|||
}) |
|||
etree.SubElement(xml_group, 'field', { |
|||
'name': field.name, 'colspan': '4', 'nolabel': '1', |
|||
'attrs': ( |
|||
"{'invisible':[('selection__" + |
|||
field.name + "','=','remove')]}")}) |
|||
'name': field.name, |
|||
'colspan': '6', |
|||
'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')]} |
|||
'selection': [('set', 'Set'), ('remove', 'Remove')] |
|||
} |
|||
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__" + |
|||
'name': field.name, |
|||
'nolabel': '1', |
|||
'attrs': ("{'invisible':[('selection__" + |
|||
field.name + "','=','remove')]}"), |
|||
'colspan': '2', }) |
|||
etree.SubElement( |
|||
xml_form, 'separator', {'string': '', 'colspan': '4'}) |
|||
'colspan': '4', |
|||
}) |
|||
etree.SubElement(xml_form, 'separator', { |
|||
'string': '', |
|||
'colspan': '6', |
|||
'col': '6', |
|||
}) |
|||
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"}) |
|||
'string': 'Apply', |
|||
'class': 'btn-primary', |
|||
'type': 'object', |
|||
'name': 'action_apply', |
|||
}) |
|||
etree.SubElement(xml_group3, 'button', { |
|||
'string': 'Close', 'icon': "gtk-close", 'special': 'cancel'}) |
|||
'string': 'Close', |
|||
'class': 'btn-default', |
|||
'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 = {} |
|||
@api.model |
|||
def create(self, vals): |
|||
if (self._context.get('active_model') and |
|||
self._context.get('active_ids')): |
|||
model_obj = self.env[self._context.get('active_model')] |
|||
values = {} |
|||
for key, val in vals.items(): |
|||
if key.startswith('selection__'): |
|||
if key.startswith('selection_'): |
|||
split_key = key.split('__', 1)[1] |
|||
if val == 'set': |
|||
dict.update({split_key: vals.get(split_key, False)}) |
|||
values.update({split_key: vals.get(split_key, False)}) |
|||
elif val == 'remove': |
|||
dict.update({split_key: False}) |
|||
values.update({split_key: False}) |
|||
elif val == 'remove_m2m': |
|||
dict.update({split_key: [ |
|||
(3, id) for id in vals.get( |
|||
split_key, False)[0][2]]}) |
|||
values.update({split_key: [(5, 0, [])]}) |
|||
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 |
|||
values.update({split_key: m2m_list}) |
|||
if values: |
|||
model_obj.browse(self._context.get('active_ids')).write(values) |
|||
return super(MassEditingWizard, self).create({}) |
|||
|
|||
def action_apply(self, cr, uid, ids, context=None): |
|||
@api.multi |
|||
def action_apply(self): |
|||
return {'type': 'ir.actions.act_window_close'} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue