Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion server_action_mass_edit/models/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
from . import ir_actions_server
from . import ir_actions_server_mass_edit_line
from . import ir_ui_view
31 changes: 19 additions & 12 deletions server_action_mass_edit/models/ir_actions_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,27 +46,34 @@ def _compute_mass_edit_apply_domain_in_lines(self):
record.mass_edit_line_ids.mapped("apply_domain")
)

def _add_mass_edit_server_action_to_context(self, context):
"""Force webclient to fetch updated view by adding a specific cache value in
context, take a look on cache key mechanism in `viewService.loadViews` from
`odoo/addons/web/static/src/views/view_service.js`
Also note that the same cache mechanism is used in server View class but only
when xml "dev_mode" is not active: `['ir.ui.view']._get_view_cache_key` from
`odoo/odoo/addons/base/models/ir_ui_view.py`
"""
self.ensure_one()
value = {
"write_date": fields.Datetime.to_string(self.write_date),
"server_action_id": self.id,
}
# convert dict to string to avoid problems with unhashable types in context
context["nocache_server_action_mass_edit_view_ref"] = str(value)

def _run_action_mass_edit_multi(self, eval_context=None):
"""Show report label wizard"""
self.ensure_one()
context = dict(self.env.context)
context.update({"server_action_id": self.id})
view_id = self.env.ref("server_action_mass_edit.view_mass_editing_wizard_form")
view_id.mass_server_action_id = self.id
if view_id:
view_temp = view_id.copy(
{
"name": "Temporary Mass Editing Wizard",
"type": "form",
"model": "mass.editing.wizard",
}
)

self._add_mass_edit_server_action_to_context(context)
return {
"name": self.name,
"type": "ir.actions.act_window",
"res_model": "mass.editing.wizard",
"context": str(context),
"view_mode": "form",
"views": [[view_temp.id, "form"]],
"views": [[view_id.id, "form"]],
"target": "new",
}
7 changes: 0 additions & 7 deletions server_action_mass_edit/models/ir_ui_view.py

This file was deleted.

14 changes: 4 additions & 10 deletions server_action_mass_edit/tests/test_mass_editing.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,6 @@ def test_wiz_fields_view_get(self):
with dynamic fields.
"""
view_id = self.env.ref("server_action_mass_edit.view_mass_editing_wizard_form")
view_id.mass_server_action_id = False
result = self.MassEditingWizard.with_context(
active_ids=[],
).get_view(view_id=view_id.id)
Expand All @@ -143,11 +142,9 @@ def test_wiz_fields_view_get(self):
"selection__email" not in arch,
"Fields view get must return architecture w/o fields" "created dynamicaly",
)
view_id.mass_server_action_id = self.mass_editing_user
result = self.MassEditingWizard.with_context(
server_action_id=self.mass_editing_user.id,
active_ids=[],
).get_view(view_id=view_id.id)
ctx = {"active_ids": []}
self.mass_editing_user._add_mass_edit_server_action_to_context(ctx)
result = self.MassEditingWizard.with_context(**ctx).get_view(view_id=view_id.id)
arch = result.get("arch", "")
self.assertTrue(
"selection__email" in arch,
Expand All @@ -162,10 +159,7 @@ def test_wiz_fields_view_get(self):
]
).unlink()
self.env.ref("base.res_partner_view_form_private").model = "res.users"
result = self.MassEditingWizard.with_context(
server_action_id=self.mass_editing_user.id,
active_ids=[],
).get_view(view_id=view_id.id)
result = self.MassEditingWizard.with_context(**ctx).get_view(view_id=view_id.id)
arch = result.get("arch", "")
self.assertIn(
"<list editable=",
Expand Down
57 changes: 28 additions & 29 deletions server_action_mass_edit/wizard/mass_editing_wizard.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from lxml import etree

from odoo import _, api, fields, models
from odoo.tools.safe_eval import safe_eval


class MassEditingWizard(models.TransientModel):
Expand Down Expand Up @@ -86,7 +87,10 @@ def onchange(self, values, field_names, fields_spec):
server_action_id = self.env.context.get("server_action_id")
server_action = self.env["ir.actions.server"].sudo().browse(server_action_id)
if not server_action:
return super().onchange(values, field_names, fields_spec)
if field_names:
return super().onchange(values, field_names, fields_spec)
else:
return {}
dynamic_fields = {}

for line in server_action.mapped("mass_edit_line_ids"):
Expand All @@ -102,21 +106,13 @@ def onchange(self, values, field_names, fields_spec):
self._fields.update(dynamic_fields)

res = super().onchange(values, field_names, fields_spec)
if not res["value"]:
if not res.get("value"):
value = {key: value for key, value in values.items() if value is not False}
res["value"] = value

for field in dynamic_fields:
self._fields.pop(field)

view_temp = (
self.env["ir.ui.view"]
.sudo()
.search([("name", "=", "Temporary Mass Editing Wizard")], limit=1)
)
if view_temp:
view_temp.unlink()

return res

@api.model
Expand Down Expand Up @@ -213,23 +209,27 @@ def _get_field_options(self, field):
"class": "w-75",
}

@api.model
def get_views(self, views, options=None):
for view, _type in views:
if view:
view = self.env["ir.ui.view"].sudo().browse(view)
server_action = view.mass_server_action_id
self = self.with_context(server_action_id=server_action.id)
return super().get_views(views, options)
def _get_mass_edit_server_action_from_context(self):
"""Retrieve server action from client context"""
server_action = None
if self.env.context.get("nocache_server_action_mass_edit_view_ref"):
# convert string back to dict
context_dict = safe_eval(
self.env.context["nocache_server_action_mass_edit_view_ref"]
)
server_action_id = context_dict.get("server_action_id")
server_action = (
self.env["ir.actions.server"].sudo().browse(server_action_id)
)
return server_action

@api.model
def get_view(self, view_id=None, view_type="form", **options):
view = self.env["ir.ui.view"].sudo().browse(view_id)
server_action = view.mass_server_action_id
self = self.with_context(server_action_id=server_action.id)
if not server_action:
return super().get_view(view_id, view_type, **options)
result = super().get_view(view_id, view_type, **options)
server_action = self._get_mass_edit_server_action_from_context()
if not server_action:
return result
# Hook XML view to add fields dynamically
arch = etree.fromstring(result["arch"])
main_xml_group = arch.find('.//group[@name="group_field_list"]')
for line in server_action.mapped("mass_edit_line_ids"):
Expand All @@ -244,11 +244,10 @@ def get_view(self, view_id=None, view_type="form", **options):

@api.model
def fields_get(self, allfields=None, attributes=None):
server_action_id = self.env.context.get("server_action_id")
server_action = self.env["ir.actions.server"].sudo().browse(server_action_id)
result = super().fields_get(allfields, attributes)
server_action = self._get_mass_edit_server_action_from_context()
if not server_action:
return super().fields_get(allfields, attributes)
res = super().fields_get(allfields, attributes)
return result
fields_info = self.env[server_action.model_id.model].fields_get()
for line in server_action.mapped("mass_edit_line_ids"):
field = line.field_id
Expand All @@ -258,8 +257,8 @@ def fields_get(self, allfields=None, attributes=None):
field_info["relation_field"] = False
if not line.apply_domain and "domain" in field_info:
field_info["domain"] = "[]"
res.update(self._prepare_fields(line, field, field_info))
return res
result.update(self._prepare_fields(line, field, field_info))
return result

@api.model
def _clean_check_company_field_domain(self, TargetModel, field, field_info):
Expand Down