[IMP] server_action_navigate: black, isort, prettier

This commit is contained in:
Quentin Tawry
2021-11-10 14:11:58 +01:00
committed by Sylvain LE GAL
parent b099a40ace
commit f73945cba1
6 changed files with 99 additions and 90 deletions

View File

@@ -12,9 +12,6 @@
"license": "AGPL-3", "license": "AGPL-3",
"depends": ["base"], "depends": ["base"],
"maintainers": ["legalsylvain"], "maintainers": ["legalsylvain"],
"data": [ "data": ["security/ir.model.access.csv", "views/view_ir_actions_server.xml"],
"security/ir.model.access.csv",
"views/view_ir_actions_server.xml",
],
"demo": ["demo/ir_actions_server.xml"], "demo": ["demo/ir_actions_server.xml"],
} }

View File

@@ -1,32 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8" ?>
<!-- <!--
Copyright (C) 2020 - Today: GRAP (http://www.grap.coop) Copyright (C) 2020 - Today: GRAP (http://www.grap.coop)
@author: Sylvain LE GAL (https://twitter.com/legalsylvain) @author: Sylvain LE GAL (https://twitter.com/legalsylvain)
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
--> -->
<odoo> <odoo>
<record id="navigate_partner_2_tags" model="ir.actions.server"> <record id="navigate_partner_2_tags" model="ir.actions.server">
<field name="name">See tags of Partners</field> <field name="name">See tags of Partners</field>
<field name="state">navigate</field> <field name="state">navigate</field>
<field name="model_id" ref="base.model_res_users"/> <field name="model_id" ref="base.model_res_users" />
</record> </record>
<record id="navigate_line_1" model="ir.actions.server.navigate.line"> <record id="navigate_line_1" model="ir.actions.server.navigate.line">
<field name="action_id" ref="navigate_partner_2_tags"/> <field name="action_id" ref="navigate_partner_2_tags" />
<field name="sequence">1</field> <field name="sequence">1</field>
<field name="field_id" ref="base.field_res_users__partner_id"/> <field name="field_id" ref="base.field_res_users__partner_id" />
</record> </record>
<record id="navigate_line_2" model="ir.actions.server.navigate.line"> <record id="navigate_line_2" model="ir.actions.server.navigate.line">
<field name="action_id" ref="navigate_partner_2_tags"/> <field name="action_id" ref="navigate_partner_2_tags" />
<field name="sequence">2</field> <field name="sequence">2</field>
<field name="field_id" ref="base.field_res_partner__category_id"/> <field name="field_id" ref="base.field_res_partner__category_id" />
</record> </record>
<function model="ir.actions.server" name="create_action"> <function model="ir.actions.server" name="create_action">
<value eval="[ref('navigate_partner_2_tags')]"/> <value eval="[ref('navigate_partner_2_tags')]" />
</function> </function>
</odoo> </odoo>

View File

@@ -13,25 +13,29 @@ class IrActionsServer(models.Model):
navigate_action_id = fields.Many2one( navigate_action_id = fields.Many2one(
string="Navigation Action", string="Navigation Action",
comodel_name='ir.actions.act_window', comodel_name="ir.actions.act_window",
domain="[('res_model', '=', max_navigate_line_model)]", domain="[('res_model', '=', max_navigate_line_model)]",
help="Define here the action used when the navigation will be executed" help="Define here the action used when the navigation will be executed"
" if empty, a generic action will be used.") " if empty, a generic action will be used.",
)
navigate_line_ids = fields.One2many( navigate_line_ids = fields.One2many(
comodel_name="ir.actions.server.navigate.line", comodel_name="ir.actions.server.navigate.line",
string="Navigate Lines", inverse_name="action_id") string="Navigate Lines",
inverse_name="action_id",
)
max_navigate_line_sequence = fields.Integer( max_navigate_line_sequence = fields.Integer(
string='Max Navigate sequence in lines', string="Max Navigate sequence in lines",
compute='_compute_max_navigate_line', compute="_compute_max_navigate_line",
store=True store=True,
) )
max_navigate_line_model = fields.Char( max_navigate_line_model = fields.Char(
string="Max Navigate Model in lines", string="Max Navigate Model in lines",
compute="_compute_max_navigate_line", compute="_compute_max_navigate_line",
store=True) store=True,
)
@api.depends("navigate_line_ids", "model_id") @api.depends("navigate_line_ids", "model_id")
def _compute_max_navigate_line(self): def _compute_max_navigate_line(self):
@@ -43,11 +47,13 @@ class IrActionsServer(models.Model):
""" """
for action in self: for action in self:
action.max_navigate_line_sequence = ( action.max_navigate_line_sequence = (
max(action.mapped('navigate_line_ids.sequence') or [0]) + 1) max(action.mapped("navigate_line_ids.sequence") or [0]) + 1
action.max_navigate_line_model =\ )
action.navigate_line_ids\ action.max_navigate_line_model = (
and action.navigate_line_ids[-1].field_model\ action.navigate_line_ids
and action.navigate_line_ids[-1].field_model
or action.model_id.model or action.model_id.model
)
def delete_last_line(self): def delete_last_line(self):
self.ensure_one() self.ensure_one()
@@ -56,34 +62,34 @@ class IrActionsServer(models.Model):
@api.model @api.model
def run_action_navigate_multi(self, action, eval_context=None): def run_action_navigate_multi(self, action, eval_context=None):
IrModel = self.env['ir.model'] IrModel = self.env["ir.model"]
lines = action.navigate_line_ids lines = action.navigate_line_ids
if not lines: if not lines:
raise UserError(_( raise UserError(
"The Action Server %s is not correctly set\n" _("The Action Server %s is not correctly set\n" " : No fields defined")
" : No fields defined")) )
mapped_field_value = ".".join(lines.mapped("field_id.name")) mapped_field_value = ".".join(lines.mapped("field_id.name"))
item_ids = eval_context['records'].mapped(mapped_field_value).ids item_ids = eval_context["records"].mapped(mapped_field_value).ids
domain = "[('id','in',[" + ','.join(map(str, item_ids)) + "])]" domain = "[('id','in',[" + ",".join(map(str, item_ids)) + "])]"
# Use Defined action if defined # Use Defined action if defined
if action.navigate_action_id: if action.navigate_action_id:
return_action = action.navigate_action_id return_action = action.navigate_action_id
result = return_action.read()[0] result = return_action.read()[0]
result['domain'] = domain result["domain"] = domain
else: else:
# Otherwise, return a default action # Otherwise, return a default action
model_name = action.max_navigate_line_model model_name = action.max_navigate_line_model
model = IrModel.search([('model', '=', model_name)]) model = IrModel.search([("model", "=", model_name)])
view_mode = 'tree,form' view_mode = "tree,form"
result = { result = {
'name': model.name, "name": model.name,
'domain': domain, "domain": domain,
'res_model': model_name, "res_model": model_name,
'target': 'current', "target": "current",
'type': 'ir.actions.act_window', "type": "ir.actions.act_window",
'view_mode': view_mode, "view_mode": view_mode,
} }
return result return result

View File

@@ -12,33 +12,34 @@ class IrActionsServerNavigateLine(models.Model):
sequence = fields.Integer(string="Sequence", default=1) sequence = fields.Integer(string="Sequence", default=1)
field_model = fields.Char( field_model = fields.Char(string="Model", related="field_id.relation", store=True)
string="Model", related="field_id.relation", store=True)
action_id = fields.Many2one( action_id = fields.Many2one(
comodel_name="ir.actions.server", string="Action", comodel_name="ir.actions.server",
required=True, ondelete="cascade") string="Action",
required=True,
ondelete="cascade",
)
field_id = fields.Many2one( field_id = fields.Many2one(
comodel_name="ir.model.fields", string="Field", comodel_name="ir.model.fields", string="Field", required=True
required=True) )
# when adding a record, onchange is called for every field on the # when adding a record, onchange is called for every field on the
# form, also in editable list views # form, also in editable list views
@api.onchange('field_id') @api.onchange("field_id")
def _onchange_field_id(self): def _onchange_field_id(self):
# check out the docstring of this in odoo/models.py # check out the docstring of this in odoo/models.py
lines = self.action_id.resolve_2many_commands( lines = self.action_id.resolve_2many_commands(
'navigate_line_ids', "navigate_line_ids", self.env.context.get("navigate_line_ids", []),
self.env.context.get('navigate_line_ids', []),
) )
lines = sum(map(self.new, lines), self.browse([])) lines = sum(map(self.new, lines), self.browse([]))
model = lines[-1:].field_id.relation or self.action_id.model_id.model model = lines[-1:].field_id.relation or self.action_id.model_id.model
return { return {
'domain': { "domain": {
'field_id': [ "field_id": [
('ttype', 'in', ['many2one', 'one2many', 'many2many']), ("ttype", "in", ["many2one", "one2many", "many2many"]),
('model', '=', model), ("model", "=", model),
], ],
} }
} }

View File

@@ -3,50 +3,46 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo.tests.common import TransactionCase from odoo.tests.common import TransactionCase
from odoo.tools.safe_eval import safe_eval from odoo.tools.safe_eval import safe_eval
class TestModule(TransactionCase): class TestModule(TransactionCase):
def setUp(self): def setUp(self):
super().setUp() super().setUp()
self.action_server = self.env.ref( self.action_server = self.env.ref(
"server_action_navigate.navigate_partner_2_tags") "server_action_navigate.navigate_partner_2_tags"
)
self.users = self.env["res.users"].search([]) self.users = self.env["res.users"].search([])
def test_action_result(self): def test_action_result(self):
result = self.action_server.with_context( result = self.action_server.with_context(
active_model="res.users", active_model="res.users", active_ids=self.users.ids
active_ids=self.users.ids).run() ).run()
self.assertEqual(result.get("id", False), False) self.assertEqual(result.get("id", False), False)
self.assertEqual( self.assertEqual(result.get("res_model", False), "res.partner.category")
result.get('res_model', False), 'res.partner.category')
self.assertEqual( self.assertEqual(
safe_eval(result.get('domain', [])), safe_eval(result.get("domain", [])),
[("id", "in", self.users.mapped("partner_id.category_id").ids)] [("id", "in", self.users.mapped("partner_id.category_id").ids)],
) )
def test_delete_last_line(self): def test_delete_last_line(self):
line_qty = len(self.action_server.navigate_line_ids) line_qty = len(self.action_server.navigate_line_ids)
self.action_server.delete_last_line() self.action_server.delete_last_line()
self.assertEqual( self.assertEqual(line_qty - 1, len(self.action_server.navigate_line_ids))
line_qty - 1,
len(self.action_server.navigate_line_ids)
)
def test_action_navigate_with_action(self): def test_action_navigate_with_action(self):
self.action_server.navigate_action_id = self.env.ref( self.action_server.navigate_action_id = self.env.ref(
"base.action_partner_category_form") "base.action_partner_category_form"
)
result = self.action_server.with_context( result = self.action_server.with_context(
active_model="res.users", active_model="res.users", active_ids=self.users.ids
active_ids=self.users.ids).run() ).run()
self.assertEqual( self.assertEqual(
result.get("id", False), result.get("id", False),
self.env.ref("base.action_partner_category_form").id, self.env.ref("base.action_partner_category_form").id,
) )

View File

@@ -1,40 +1,55 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8" ?>
<!-- <!--
Copyright (C) 2020 - Today: GRAP (http://www.grap.coop) Copyright (C) 2020 - Today: GRAP (http://www.grap.coop)
@author: Sylvain LE GAL (https://twitter.com/legalsylvain) @author: Sylvain LE GAL (https://twitter.com/legalsylvain)
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
--> -->
<odoo> <odoo>
<record id="view_ir_actions_server_form" model="ir.ui.view"> <record id="view_ir_actions_server_form" model="ir.ui.view">
<field name="model">ir.actions.server</field> <field name="model">ir.actions.server</field>
<field name="inherit_id" ref="base.view_server_action_form"/> <field name="inherit_id" ref="base.view_server_action_form" />
<field name="arch" type="xml"> <field name="arch" type="xml">
<xpath expr="//page[@name='code']" position="after"> <xpath expr="//page[@name='code']" position="after">
<page string="Navigation Options" name='page_navigate' autofocus="autofocus" <page
attrs="{'invisible': [('state', '!=', 'navigate')]}"> string="Navigation Options"
name='page_navigate'
autofocus="autofocus"
attrs="{'invisible': [('state', '!=', 'navigate')]}"
>
<group> <group>
<field name="max_navigate_line_sequence" invisible="1"/> <field name="max_navigate_line_sequence" invisible="1" />
<field name="max_navigate_line_model" invisible="1"/> <field name="max_navigate_line_model" invisible="1" />
<!-- we can check emptyness of a 2many like this since v10 i think /--> <!-- we can check emptyness of a 2many like this since v10 i think /-->
<button name="delete_last_line" string="Delete Last Line" type="object" <button
attrs="{'invisible': [('navigate_line_ids', '=', [])]}"/> name="delete_last_line"
<field name="navigate_line_ids" context="{'navigate_line_ids': navigate_line_ids}" nolabel="1" colspan="4"> string="Delete Last Line"
type="object"
attrs="{'invisible': [('navigate_line_ids', '=', [])]}"
/>
<field
name="navigate_line_ids"
context="{'navigate_line_ids': navigate_line_ids}"
nolabel="1"
colspan="4"
>
<tree editable="bottom" delete="false"> <tree editable="bottom" delete="false">
<!-- the handle widget takes care of the sequence /--> <!-- the handle widget takes care of the sequence /-->
<field name="sequence" widget="handle" invisible="True" /> <field
name="sequence"
widget="handle"
invisible="True"
/>
<field name="field_id" /> <field name="field_id" />
<field name="field_model"/> <field name="field_model" />
</tree> </tree>
</field> </field>
<field name="navigate_action_id" <field
attrs="{'invisible': [('navigate_line_ids', '=', [])]}"/> name="navigate_action_id"
attrs="{'invisible': [('navigate_line_ids', '=', [])]}"
/>
</group> </group>
</page> </page>
</xpath> </xpath>
</field> </field>
</record> </record>
</odoo> </odoo>