server-ux/mass_editing/wizard/mass_editing_wizard.py

259 lines
12 KiB
Python
Raw Normal View History

2021-03-23 19:38:33 +00:00
# © 2016 Serpent Consulting Services Pvt. Ltd. (support@serpentcs.com)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from lxml import etree
import flectra.tools as tools
from flectra import api, models
class MassEditingWizard(models.TransientModel):
_name = 'mass.editing.wizard'
@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_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)
})
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')]
}
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_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': '4',
})
etree.SubElement(xml_group, 'field', {
'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')],
}
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': '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')],
}
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',
})
etree.SubElement(xml_group, 'field', {
'name': field.name,
'nolabel': '1',
'attrs': ("{'invisible':[('selection__" +
field.name + "','=','remove')]}"),
'colspan': '4',
})
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': '4',
'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')]
}
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': '4',
})
# Patch fields with required extra data
for field in all_fields.values():
field.setdefault("views", {})
etree.SubElement(xml_form, 'separator', {
'string': '',
'colspan': '6',
'col': '6',
})
xml_group3 = etree.SubElement(xml_form, 'footer', {})
etree.SubElement(xml_group3, 'button', {
'string': 'Apply',
'class': 'btn-primary',
'type': 'object',
'name': 'action_apply',
})
etree.SubElement(xml_group3, 'button', {
'string': 'Close',
'class': 'btn-default',
'special': 'cancel',
})
root = xml_form.getroottree()
result['arch'] = etree.tostring(root)
result['fields'] = all_fields
return result
@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')]
model_field_obj = self.env['ir.model.fields']
translation_obj = self.env['ir.translation']
values = {}
for key, val in vals.items():
if key.startswith('selection_') and '__' in key:
split_key = key.split('__', 1)[1]
if val == 'set':
values.update({split_key: vals.get(split_key, False)})
elif val == 'remove':
values.update({split_key: False})
# If field to remove is translatable,
# its translations have to be removed
model_field = model_field_obj.search([
('model', '=', self._context.get('active_model')),
('name', '=', split_key)])
if model_field and model_field.translate:
translation_ids = translation_obj.search([
('res_id', 'in', self._context.get(
'active_ids')),
('type', '=', 'model'),
('name', '=', u"{0},{1}".format(
self._context.get('active_model'),
split_key))])
translation_ids.unlink()
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 = []
for m2m_id in vals.get(split_key, False)[0][2]:
m2m_list.append((4, m2m_id))
values.update({split_key: m2m_list})
if values:
model_obj.browse(self._context.get('active_ids')).write(values)
return super(MassEditingWizard, self).create({})
@api.multi
def action_apply(self):
return {'type': 'ir.actions.act_window_close'}
def read(self, fields, load='_classic_read'):
""" Without this call, dynamic fields build by fields_view_get()
generate a log warning, i.e.:
flectra.models:mass.editing.wizard.read() with unknown field 'myfield'
flectra.models:mass.editing.wizard.read()
with unknown field 'selection__myfield'
"""
real_fields = fields
if fields:
# We remove fields which are not in _fields
real_fields = [x for x in fields if x in self._fields]
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