[REM] multi from ir.actions.act_window

Task 1843603

* src_model is redundant with binding_model_id
* multi -> binding_view_types (if empty => all views) (maybe should be
empty by default yo?)
* in convert, type => rec.get(type) but no @type possible on <act_window>...
* removed deprecated auto_refresh & auto_search (not used anywhere (?))

closes odoo/odoo#24738

Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
This commit is contained in:
Xavier Morel
2019-05-27 12:00:39 +00:00
parent 0679d0d542
commit 10f1a1a0c4
67 changed files with 330 additions and 214 deletions
+2 -2
View File
@@ -34,10 +34,10 @@
<act_window name="Send Receipt By Email"
res_model="mail.compose.message"
src_model="account.payment"
binding_model="account.payment"
view_mode="form"
target="new"
key2="client_action_relate"
binding_views="form"
id="account_send_payment_receipt_by_email_action"
context="{
'default_model': 'account.payment',
@@ -937,6 +937,8 @@ action = action_values
context="{'search_default_journal_id': [active_id], 'search_default_unpaid':1, 'default_journal_id': active_id}"
domain="[('journal_id','=', active_id)]"
res_model="account.invoice"
src_model="account.journal"/>
binding_model="account.journal"
binding_views="form"/>
</data>
</odoo>
+3 -3
View File
@@ -420,7 +420,7 @@
name="Journal Items"
context="{'search_default_account_id': [active_id]}"
res_model="account.move.line"
src_model="account.account"/>
binding_model="account.account" binding_views="form"/>
<act_window
id="action_move_line_select_by_partner"
@@ -446,7 +446,7 @@
name="Journal Items for Tax Audit"
context="{'search_default_account_id': [active_id]}"
res_model="account.move.line"
src_model="account.account"
binding_model="account.account" binding_views="form"
view_id="account.view_move_line_tax_audit_tree"/>
<record id="action_account_moves_all_a" model="ir.actions.act_window">
@@ -514,7 +514,7 @@
name="Journal Items"
context="{'search_default_move_id': active_id, 'default_move_id': active_id}"
res_model="account.move.line"
src_model="account.move"
binding_model="account.move" binding_views="form"
view_mode="tree"/>
<!-- MENUS -->
+2 -1
View File
@@ -377,7 +377,8 @@ action = model.setting_init_bank_account_action()
name="Bank statements"
context="{'search_default_journal_id': active_id, 'default_journal_id': active_id}"
res_model="account.bank.statement"
src_model="account.journal"/>
binding_model="account.journal"
binding_views="form"/>
<!-- Tags -->
<record id="account_tag_view_form" model="ir.ui.view">
@@ -74,13 +74,11 @@
<act_window
name="Send"
id="invoice_send"
multi="True"
key2="client_action_multi"
res_model="account.invoice.send"
src_model="account.invoice"
binding_model="account.invoice"
binding_views="list"
view_mode="form"
target="new"
view_type="form"
context="{
'default_template_id': ref('account.email_template_edi_invoice'),
'mark_invoice_as_sent': True,
@@ -21,10 +21,10 @@
</record>
<act_window id="action_account_invoice_confirm"
multi="True"
key2="client_action_multi" name="Confirm Draft Invoices"
res_model="account.invoice.confirm" src_model="account.invoice"
view_mode="form" target="new" view_type="form" />
name="Confirm Draft Invoices"
res_model="account.invoice.confirm"
binding_model="account.invoice" binding_views="list"
view_mode="form" target="new" view_type="form"/>
</data>
</odoo>
+4 -6
View File
@@ -19,13 +19,12 @@
</field>
</record>
<act_window
<act_window
name="Put Money In"
res_model="cash.box.in"
src_model="account.bank.statement"
binding_model="account.bank.statement"
view_mode="form"
target="new"
key2="client_action_multi"
id="action_cash_box_in" />
<record model="ir.ui.view" id="cash_box_out_form">
@@ -47,13 +46,12 @@
</field>
</record>
<act_window
<act_window
name="Take Money Out"
res_model="cash.box.out"
src_model="account.bank.statement"
binding_model="account.bank.statement"
view_mode="form"
target="new"
key2="client_action_multi"
id="action_cash_box_out" />
</data>
</odoo>
@@ -116,7 +116,8 @@
name="Analytic Rules"
id="analytic_rule_action_user"
res_model="account.analytic.default"
src_model="res.users"
binding_model="res.users"
binding_views="form"
context="{'search_default_user_id': [active_id], 'default_user_id': active_id}"
groups="analytic.group_analytic_accounting"/>
</odoo>
@@ -156,7 +156,8 @@
name="Voucher Entries"
context="{'search_default_journal_id': active_id, 'default_journal_id': active_id}"
res_model="account.voucher"
src_model="account.journal"/>
binding_model="account.journal"
binding_views="form"/>
<record model="ir.actions.act_window" id="action_review_voucher_list">
<field name="name">Vouchers Entries</field>
+1 -2
View File
@@ -4,11 +4,10 @@
<!-- Add action entry in the Action Menu for Events -->
<act_window id="sms_message_send_action_mutli"
name="Send SMS to attendees"
src_model="calendar.event"
binding_model="calendar.event"
res_model="sms.send_sms"
view_type="form"
view_mode="form"
key2="client_action_multi"
target="new"/>
</odoo>
+2 -3
View File
@@ -831,11 +831,10 @@
-->
<act_window name="Send an email"
res_model="mail.compose.message"
src_model="crm.lead"
binding_model="crm.lead"
binding_views="list"
view_mode="form"
multi="True"
target="new"
key2="client_action_multi"
id="crm.action_lead_mass_mail"
context="{
'default_composition_mode': 'mass_mail',
+1 -1
View File
@@ -4,7 +4,7 @@
<!-- open meetings related to given partner -->
<record id="calendar_event_partner" model="ir.actions.act_window">
<field name="name">Meetings</field>
<field name="src_model">res.partner</field>
<field name="binding_model_id" ref="base.model_res_partner"/>
<field name="res_model">calendar.event</field>
<field name="view_mode">calendar,tree,form</field>
<field name="context">{'default_partner_ids': [active_id], 'search_default_partner_ids': [active_id]}</field>
@@ -104,9 +104,9 @@
<act_window
id="action_crm_send_mass_convert"
multi="True"
key2="client_action_multi" name="Convert to opportunities"
res_model="crm.lead2opportunity.partner.mass" src_model="crm.lead"
name="Convert to opportunities"
res_model="crm.lead2opportunity.partner.mass"
binding_model="crm.lead" binding_views="list"
view_mode="form" target="new" view_type="form"
context="{'mass_convert' : True}"
view_id="view_crm_lead2opportunity_partner_mass"
@@ -46,10 +46,9 @@
<act_window
id="action_merge_opportunities"
name="Merge"
multi="True"
key2="client_action_multi"
res_model="crm.merge.opportunity"
src_model="crm.lead"
binding_model="crm.lead"
binding_views="list"
view_mode="form"
target="new"
view_type="form"
+2 -1
View File
@@ -16,7 +16,8 @@
id="act_server_history"
name="Messages"
res_model="mail.mail"
src_model="fetchmail.server"
binding_model="fetchmail.server"
binding_views="form"
domain="[('email_from', '!=', False), ('fetchmail_server_id', '=', active_id)]"
context="{'search_default_server_id': active_id, 'default_fetchmail_server_id': active_id}"/>
@@ -263,7 +263,8 @@
id="act_renew_contract"
name="Renew Contract"
res_model="fleet.vehicle.log.contract"
src_model="fleet.vehicle.log.contract"
binding_model="fleet.vehicle.log.contract"
binding_views="form"
view_mode="form"
view_type="form"
/>
@@ -114,7 +114,7 @@
<field name="name">Time Off</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">hr.leave.report</field>
<field name="src_model">hr.employee</field>
<field name="binding_model_id" ref="hr.model_hr_employee"/>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="context">{
+1 -1
View File
@@ -592,7 +592,7 @@
<field name="name">Time Off</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">hr.leave</field>
<field name="view_type">form</field>
<field name="binding_model_id" ref="model_hr_employee"/>
<field name="view_mode">tree,kanban,form,calendar,activity</field>
<field name="context">{}</field>
<field name="domain">[]</field>
+2 -1
View File
@@ -202,7 +202,8 @@
<act_window id="project_task_action_view_timesheet"
name="Timesheet Entries"
src_model="project.task"
binding_model="project.task"
binding_views="form"
res_model="account.analytic.line"
view_mode="tree"
view_id="hr_timesheet_line_tree"
-1
View File
@@ -266,7 +266,6 @@ class MailTemplate(models.Model):
'name': button_name,
'type': 'ir.actions.act_window',
'res_model': 'mail.compose.message',
'src_model': template.model_id.model,
'view_type': 'form',
'context': "{'default_composition_mode': 'mass_mail', 'default_template_id' : %d, 'default_use_template': True}" % (template.id),
'view_mode': 'form,tree',
+2 -3
View File
@@ -103,11 +103,10 @@
<!-- Replace the default mass-mailing wizard in base with the composition wizard -->
<act_window name="Send Email"
res_model="mail.compose.message"
src_model="res.partner"
binding_model="res.partner"
binding_views="list"
view_mode="form"
multi="True"
target="new"
key2="client_action_multi"
id="action_partner_mass_mail"
context="{
'default_composition_mode': 'mass_mail',
@@ -39,7 +39,7 @@
<record id="wizard_email_template_preview" model="ir.actions.act_window">
<field name="name">Template Preview</field>
<field name="res_model">email_template.preview</field>
<field name="src_model">mail.template</field>
<field name="binding_model_id" ref="mail.model_mail_template"/>
<field name="type">ir.actions.act_window</field>
<field name="view_type">form</field>
<field name="view_mode">form</field>
@@ -88,7 +88,7 @@
<record id="action_email_compose_message_wizard" model="ir.actions.act_window">
<field name="name">Compose Email</field>
<field name="res_model">mail.compose.message</field>
<field name="src_model">mail.compose.message</field>
<field name="binding_model_id" ref="mail.model_mail_compose_message"/>
<field name="type">ir.actions.act_window</field>
<field name="view_type">form</field>
<field name="view_mode">form</field>
@@ -266,7 +266,7 @@
<record id="hr_equipment_request_action_from_equipment" model="ir.actions.act_window">
<field name="name">Maintenance Requests</field>
<field name="res_model">maintenance.request</field>
<field name="src_model">maintenance.equipment</field>
<field name="binding_model_id" ref="maintenance.model_maintenance_equipment"/>
<field name="view_mode">kanban,tree,form,pivot,graph,calendar</field>
<field name="context">{
'default_equipment_id': active_id,
@@ -27,7 +27,7 @@
</record>
<act_window id="mass_mailing_list_merge_action" name="Merge Selected Mailing Lists"
multi="True" key2="client_action_multi"
res_model="mass.mailing.list.merge" src_model="mail.mass_mailing.list"
res_model="mass.mailing.list.merge"
binding_model="mail.mass_mailing.list" binding_views="list"
view_mode="form" target="new" view_type="form"/>
</odoo>
@@ -29,9 +29,8 @@
<act_window name="Invoice Membership"
res_model="membership.invoice"
src_model="res.partner"
multi="True"
key2="client_action_multi"
binding_model="res.partner"
binding_views="list"
view_mode="form"
id="action_membership_invoice_view"/>
@@ -529,7 +529,8 @@
<act_window
id="act_pos_config_sessions"
name="Sessions"
src_model="pos.config"
binding_model="pos.config"
binding_views="form"
res_model="pos.session"
domain="[('config_id', '=', active_id)]" />
@@ -3,7 +3,8 @@
<act_window
id="act_pos_session_orders"
name="Orders"
src_model="pos.session"
binding_model="pos.session"
binding_views="form"
res_model="pos.order"
context="{'search_default_session_id': active_id, 'default_session_id' : active_id }"/>
+6 -8
View File
@@ -1,20 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<odoo>
<act_window
<act_window
id="action_pos_box_in"
name="Put Money In"
res_model="cash.box.in"
src_model="pos.session"
binding_model="pos.session"
view_mode="form"
target="new"
key2="client_action_multi"/>
target="new"/>
<act_window
<act_window
id="action_pos_box_out"
name="Take Money Out"
res_model="cash.box.out"
src_model="pos.session"
binding_model="pos.session"
view_mode="form"
target="new"
key2="client_action_multi"/>
target="new"/>
</odoo>
@@ -18,10 +18,9 @@
id="act_pos_open_statement"
name="Open Statements"
res_model="pos.open.statement"
src_model="account.bank.statement"
binding_model="account.bank.statement"
view_mode="form"
target="new"
key2="client_action_multi"/>
target="new"/>
<record id="action_pos_open_statement" model="ir.actions.act_window">
<field name="name">Open Cash Register</field>
+1 -1
View File
@@ -28,7 +28,7 @@
<record id="portal_share_action" model="ir.actions.act_window">
<field name="name">Share Document</field>
<field name="res_model">portal.share</field>
<field name="src_model">portal.share</field>
<field name="binding_model_id" ref="model_portal_share"/>
<field name="view_mode">form</field>
<field name="target">new</field>
</record>
+2 -3
View File
@@ -3,10 +3,9 @@
<!-- wizard action on res.partner -->
<act_window id="partner_wizard_action"
name="Grant Portal Access"
src_model="res.partner"
binding_model="res.partner"
res_model="portal.wizard"
view_type="form" view_mode="form"
key2="client_action_multi" target="new"
view_type="form" view_mode="form" target="new"
groups="base.group_partner_manager"/>
<!-- wizard view -->
+1 -1
View File
@@ -13,7 +13,7 @@
<record id="pos_session_action_from_crm_team" model="ir.actions.act_window">
<field name="name">Open Sessions</field>
<field name="src_model">crm.team</field>
<field name="binding_model_id" ref="crm.model_crm_team"/>
<field name="res_model">pos.session</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
@@ -24,10 +24,10 @@
</record>
<act_window id="action_product_price_list"
key2="client_print_multi"
name="Price List"
res_model="product.price_list"
src_model="product.product"
binding_model="product.product"
binding_type="report"
groups="product.group_sale_pricelist"
view_mode="form" target="new" view_type="form" />
</odoo>
@@ -20,10 +20,9 @@
<act_window name="Product Margins"
res_model="product.margin"
src_model="product.product"
binding_model="product.product"
view_mode="form"
target="new"
key2="client_action_multi"
id="product_margin_act_window"/>
</odoo>
+4 -3
View File
@@ -517,9 +517,9 @@
id="portal_share_action"
name="Share"
res_model="portal.share"
src_model="project.task"
binding_model="project.task"
binding_views="form"
view_type="form"
view_mode="form"
target="new"
/>
@@ -897,7 +897,8 @@
<!-- User Form -->
<act_window context="{'search_default_user_id': [active_id], 'default_user_id': active_id}"
id="act_res_users_2_project_task_opened" name="Assigned Tasks"
res_model="project.task" src_model="res.users" view_mode="tree,form,calendar,graph" view_type="form"/>
res_model="project.task" view_mode="tree,form,calendar,graph" view_type="form"
binding_model="res.users" binding_views="form"/>
<!-- Tags -->
<record model="ir.ui.view" id="project_tags_search_view">
@@ -43,6 +43,6 @@
domain="[('requisition_id', '=', active_id)]"
context="{'default_requisition_id': active_id}"
res_model="purchase.order"
src_model="purchase.requisition"/>
binding_model="purchase.requisition" binding_views="form"/>
</odoo>
@@ -20,14 +20,13 @@
</field>
</record>
<act_window name="Create Invoice"
<act_window name="Create Invoice"
res_model="repair.order.make_invoice"
src_model="repair.order"
binding_model="repair.order"
binding_views="list"
view_mode="form"
target="new"
key2="client_action_multi"
id="act_repair_invoice"
multi="True"/>
target="new"
id="act_repair_invoice"/>
</data>
</odoo>
</odoo>
+4 -2
View File
@@ -171,7 +171,8 @@
id="resource_calendar_closing_days"
name="Closing Days"
res_model="resource.calendar.leaves"
src_model="resource.calendar"
binding_model="resource.calendar"
binding_views="form"
view_mode="calendar,tree,form"
context="{'default_calendar_id': active_id}"
domain="[('calendar_id','=',active_id), ('resource_id','=',False)]"/>
@@ -180,7 +181,8 @@
id="resource_calendar_resources_leaves"
name="Resources Time Off"
res_model="resource.calendar.leaves"
src_model="resource.calendar"
binding_model="resource.calendar"
binding_views="form"
view_mode="calendar,tree,form"
context="{'default_calendar_id': active_id}"
domain="[('calendar_id','=',active_id), ('resource_id','!=',False)]"/>
@@ -21,13 +21,11 @@
<record id="project_project_action_multi_create_invoice" model="ir.actions.act_window">
<field name="name">Create Invoice</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">project.create.invoice</field>
<field name="view_type">form</field>
<field name="view_mode">form</field>
<field name="view_id" ref="project_create_invoice_view_form"/>
<field name="target">new</field>
<field name="multi" eval="False"/>
<field name="groups_id" eval="[(4, ref('sales_team.group_sale_salesman_all_leads'))]"/>
</record>
@@ -44,13 +44,11 @@
<record id="project_project_action_multi_create_sale_order" model="ir.actions.act_window">
<field name="name">Create a Sales Order</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">project.create.sale.order</field>
<field name="view_type">form</field>
<field name="view_mode">form</field>
<field name="view_id" ref="project_create_sale_order_view_form"/>
<field name="target">new</field>
<field name="multi" eval="False"/>
<field name="groups_id" eval="[(4, ref('sales_team.group_sale_salesman'))]"/>
</record>
+1 -2
View File
@@ -34,11 +34,10 @@
<!-- Add action entry in the Action Menu for Partners -->
<act_window id="send_sms_action"
name="Send SMS"
src_model="res.partner"
binding_model="res.partner"
res_model="sms.send_sms"
view_type="form"
view_mode="form"
key2="client_action_multi"
target="new"/>
</odoo>
+2 -1
View File
@@ -6,7 +6,8 @@
id="act_product_location_open"
name="Products"
res_model="product.product"
src_model="stock.location"/>
binding_model="stock.location"
binding_views="form"/>
<record id="view_location_form" model="ir.ui.view">
<field name="name">stock.location.form</field>
+2 -1
View File
@@ -270,7 +270,8 @@
id="act_stock_warehouse_2_stock_warehouse_orderpoint"
name="Reordering Rules"
res_model="stock.warehouse.orderpoint"
src_model="stock.warehouse"
binding_model="stock.warehouse"
binding_views="form"
groups="stock.group_stock_user"/>
</odoo>
@@ -48,7 +48,7 @@
<field name="name">Replenish</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">product.replenish</field>
<field name="src_model">product.product</field>
<field name="binding_model_id" ref="product.model_product_product"/>
<field name="view_type">form</field>
<field name="view_mode">form</field>
<field name="view_id" ref="view_product_replenish"/>
@@ -28,9 +28,10 @@
</record>
<act_window id="stock_picking_to_batch_action_stock_picking"
multi="True"
key2="client_action_multi" name="Add to Batch"
res_model="stock.picking.to.batch" src_model="stock.picking"
name="Add to Batch"
res_model="stock.picking.to.batch"
binding_model="stock.picking"
binding_views="list"
view_mode="form" target="new" view_type="form"
/>
@@ -45,9 +45,10 @@
<field name="target">new</field>
</record>
<act_window id="action_crm_send_mass_forward" multi="True"
key2="client_action_multi" name="Forward to Partner" res_model="crm.lead.forward.to.partner"
src_model="crm.lead" view_mode="form" target="new" view_type="form"
<act_window id="action_crm_send_mass_forward"
name="Forward to Partner" res_model="crm.lead.forward.to.partner"
binding_model="crm.lead" binding_views="list"
view_mode="form" target="new" view_type="form"
groups="sales_team.group_sale_manager"
context="{'default_composition_mode' : 'mass_mail'}" view_id="crm_lead_forward_to_partner_form" />
+3 -4
View File
@@ -1386,7 +1386,7 @@ Wizards are launched by ``ir.actions.act_window`` records, with the field
popup window. The action may be triggered by a menu item.
There is another way to launch the wizard: using an ``ir.actions.act_window``
record like above, but with an extra field ``src_model`` that specifies in the
record like above, but with an extra field ``binding_model_id`` that specifies in the
context of which model the action is available. The wizard will appear in the
contextual actions of the model, above the main view. Because of some internal
hooks in the ORM, such an action is declared in XML with the tag ``act_window``.
@@ -1395,11 +1395,10 @@ hooks in the ORM, such an action is declared in XML with the tag ``act_window``.
<act_window id="launch_the_wizard"
name="Launch the Wizard"
src_model="context.model.name"
binding_model="context.model.name"
res_model="wizard.model.name"
view_mode="form"
target="new"
key2="client_action_multi"/>
target="new"/>
Wizards use regular views and their buttons may use the attribute
``special="cancel"`` to close the wizard window without saving.
+3 -4
View File
@@ -17,7 +17,7 @@ Index: addons/openacademy/views/openacademy.xml
===================================================================
--- addons.orig/openacademy/views/openacademy.xml
+++ addons/openacademy/views/openacademy.xml
@@ -223,4 +223,25 @@
@@ -223,4 +223,24 @@
parent="openacademy_menu"
action="session_list_action"/>
@@ -36,10 +36,9 @@ Index: addons/openacademy/views/openacademy.xml
+
+ <act_window id="launch_session_wizard"
+ name="Add Attendees"
+ src_model="openacademy.session"
+ binding_model="openacademy.session"
+ res_model="openacademy.wizard"
+ view_mode="form"
+ target="new"
+ key2="client_action_multi"/>
+ target="new"/>
+
</odoo>
+23 -5
View File
@@ -32,6 +32,29 @@ A number
A dictionary
treat as a client action descriptor and execute
Bindings
========
Aside from their two mandatory attributes, all actions also share *optional*
attributes used to present an action in an arbitrary model's contextual menu:
``binding_model_id``
specifies which model the action is bound to
``binding_type``
specifies the type of binding, which is mostly which contextual menu the
action will appear under
``action`` (default)
Specifies that the action will appear in the :menuselection:`Action`
contextual menu of the bound model.
``report``
Specifies that the action will appear in the :menuselection:`Print`
contextual menu of the bound model.
``binding_view_types``
a comma-separated list of view types for which the action appears in the
contextual menu, mostly "list" and / or "form". Defaults to ``list,form``
(both list and form )
.. _reference/actions/window:
Window Actions (``ir.actions.act_window``)
@@ -74,9 +97,6 @@ Its fields are:
``limit`` (optional)
number of records to display in lists by default. Defaults to 80 in the
web client
``auto_search`` (optional)
whether a search should be performed immediately after loading the default
view. Defaults to ``True``
For instance, to open customers (partner with the ``customer`` flag set) with
list and form views::
@@ -136,8 +156,6 @@ The server-side composition of the ``views`` sequence is the following:
.. todo::
* ``src_model``, ``multi`` seem linked to "sidebar" actions?
* ``auto_refresh`` looks ignored/deprecated
* ``usage``?
* ``groups_id``?
* ``filter``?
+4 -8
View File
@@ -45,9 +45,9 @@ class IrActions(models.Model):
binding_model_id = fields.Many2one('ir.model', ondelete='cascade',
help="Setting a value makes this action available in the sidebar for the given model.")
binding_type = fields.Selection([('action', 'Action'),
('action_form_only', "Form-only"),
('report', 'Report')],
required=True, default='action')
binding_view_types = fields.Char(default='list,form')
def _compute_xml_id(self):
res = self.get_external_id()
@@ -134,13 +134,13 @@ class IrActionsActWindow(models.Model):
_sequence = 'ir_actions_id_seq'
_order = 'name'
@api.constrains('res_model', 'src_model')
@api.constrains('res_model', 'binding_model_id')
def _check_model(self):
for action in self:
if action.res_model not in self.env:
raise ValidationError(_('Invalid model name %r in action definition.') % action.res_model)
if action.src_model and action.src_model not in self.env:
raise ValidationError(_('Invalid model name %r in action definition.') % action.src_model)
if action.binding_model_id and action.binding_model_id.model not in self.env:
raise ValidationError(_('Invalid model name %r in action definition.') % action.binding_model_id.model)
@api.depends('view_ids.view_mode', 'view_mode', 'view_id.type')
def _compute_views(self):
@@ -180,8 +180,6 @@ class IrActionsActWindow(models.Model):
res_id = fields.Integer(string='Record ID', help="Database ID of record to open in form view, when ``view_mode`` is set to 'form' only")
res_model = fields.Char(string='Destination Model', required=True,
help="Model name of the object to open in the view window")
src_model = fields.Char(string='Source Model',
help="Optional model name of the objects on which this action should be visible")
target = fields.Selection([('current', 'Current Window'), ('new', 'New Window'), ('inline', 'Inline Edit'), ('fullscreen', 'Full Screen'), ('main', 'Main action of Current Window')], default="current", string='Target Window')
view_mode = fields.Char(required=True, default='tree,form',
help="Comma-separated list of allowed view modes, such as 'form', 'tree', 'calendar', etc. (Default: tree,form)")
@@ -199,9 +197,7 @@ class IrActionsActWindow(models.Model):
'act_id', 'gid', string='Groups')
search_view_id = fields.Many2one('ir.ui.view', string='Search View Ref.')
filter = fields.Boolean()
auto_search = fields.Boolean(default=True)
search_view = fields.Text(compute='_compute_search_view')
multi = fields.Boolean(string='Restrict to lists', help="If checked and the action is bound to a model, it will only appear in the More menu on list views")
@api.multi
def read(self, fields=None, load='_classic_read'):
-48
View File
@@ -253,54 +253,6 @@ class TestServerActions(TestServerActionsBase):
self.assertEqual(self.test_country.vat_label, 'VatFromTest', 'vat label should be changed to VatFromTest')
class TestActionBindings(common.TransactionCase):
def test_bindings(self):
""" check the action bindings on models """
Actions = self.env['ir.actions.actions']
# first make sure there is no bound action
self.env.ref('base.action_partner_merge').unlink()
bindings = Actions.get_bindings('res.partner')
self.assertFalse(bindings['action'])
self.assertFalse(bindings['report'])
# create action bindings, and check the returned bindings
action1 = self.env.ref('base.action_attachment')
action2 = self.env.ref('base.ir_default_menu_action')
action3 = self.env['ir.actions.report'].search([('groups_id', '=', False)], limit=1)
action1.binding_model_id = action2.binding_model_id \
= action3.binding_model_id \
= self.env['ir.model']._get('res.partner')
bindings = Actions.get_bindings('res.partner')
self.assertItemsEqual(
bindings['action'],
(action1 + action2).read(),
"Wrong action bindings",
)
self.assertItemsEqual(
bindings['report'],
action3.read(),
"Wrong action bindings",
)
# add a group on an action, and check that it is not returned
group = self.env.ref('base.group_user')
action2.groups_id += group
self.env.user.groups_id -= group
bindings = Actions.get_bindings('res.partner')
self.assertItemsEqual(
bindings['action'],
action1.read(),
"Wrong action bindings",
)
self.assertItemsEqual(
bindings['report'],
action3.read(),
"Wrong action bindings",
)
class TestCustomFields(common.TransactionCase):
@@ -86,7 +86,6 @@
</page>
<page name='advanced' string="Advanced Properties">
<group>
<field name="multi"/>
<field name="attachment_use"/>
<field name="attachment"/>
</group>
@@ -163,7 +162,6 @@
<field name="name"/>
<field name="xml_id" string="External ID"/>
<field name="res_model" string="Object"/>
<field name="src_model" string="Source Object"/>
</group>
<group name="action_details">
<field name="usage"/>
@@ -183,9 +181,7 @@
<field name="domain"/>
<field name="context"/>
<field name="limit"/>
<field name="auto_search"/>
<field name="filter"/>
<field name="multi"/>
</group>
</group>
<group name="help" string="Help">
+1 -1
View File
@@ -121,7 +121,7 @@
</record>
<act_window id="reset_view_arch_wizard_action"
name="Reset View Architecture"
src_model="ir.ui.view"
binding_model="ir.ui.view" binding_views="form"
res_model="reset.view.arch.wizard"
view_type="form"
view_mode="form"
+2 -3
View File
@@ -29,10 +29,9 @@
</record>
<act_window id="change_password_wizard_action"
name="Change Password"
src_model="res.users"
binding_model="res.users"
res_model="change.password.wizard"
view_type="form" view_mode="form"
key2="client_action_multi" target="new"
view_type="form" view_mode="form" target="new"
groups="base.group_erp_manager"/>
<!-- res.groups -->
@@ -102,10 +102,9 @@
<act_window
id="action_partner_merge"
res_model="base.partner.merge.automatic.wizard"
src_model="res.partner"
binding_model="res.partner"
binding_views="list"
target="new"
multi="True"
key2="client_action_multi"
view_mode="form"
name="Merge Contacts"/>
</odoo>
@@ -0,0 +1,2 @@
# -*- coding: utf-8 -*-
from . import models
@@ -0,0 +1,7 @@
{
'name': "Test Action Bindings",
'data': [
'ir.model.access.csv',
'test_data.xml',
],
}
@@ -0,0 +1,3 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_tab_a,access_tab_a,model_tab_a,,1,1,1,1
access_tab_b,access_tab_b,model_tab_b,,1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_tab_a access_tab_a model_tab_a 1 1 1 1
3 access_tab_b access_tab_b model_tab_b 1 1 1 1
@@ -0,0 +1,9 @@
# -*- coding: utf-8 -*-
from odoo import models
class A(models.Model):
_name = _description = 'tab.a'
class B(models.Model):
_name = _description = 'tab.b'
@@ -0,0 +1,40 @@
<odoo>
<!-- bind to all views -->
<act_window
id="act1"
name="Action 1"
res_model="tab.a"
binding_model="tab.a"
binding_views=""/>
<!-- bind to form views -->
<act_window
id="act2"
name="Action 2"
res_model="tab.a"
binding_model="tab.a"
binding_views="form"/>
<!-- bind to default views (list, form) -->
<act_window
id="act3"
name="Action 3"
res_model="tab.a"
binding_model="tab.a"/>
<record id="r1" model="ir.actions.act_window">
<field name="name">Record 1</field>
<field name="res_model">tab.b</field>
<field name="binding_model_id" ref="model_tab_b"/>
<field name="binding_view_types"/>
</record>
<record id="r2" model="ir.actions.act_window">
<field name="name">Record 2</field>
<field name="res_model">tab.b</field>
<field name="binding_model_id" ref="model_tab_b"/>
<field name="binding_view_types">form</field>
</record>
<record id="r3" model="ir.actions.act_window">
<field name="name">Record 3</field>
<field name="res_model">tab.b</field>
<field name="binding_model_id" ref="model_tab_b"/>
</record>
</odoo>
@@ -0,0 +1 @@
from . import test_bindings
@@ -0,0 +1,93 @@
from odoo.tests import common
class TestActionBindings(common.TransactionCase):
def test_bindings(self):
""" check the action bindings on models """
Actions = self.env['ir.actions.actions']
# first make sure there is no bound action
self.env.ref('base.action_partner_merge').unlink()
bindings = Actions.get_bindings('res.partner')
self.assertFalse(bindings['action'])
self.assertFalse(bindings['report'])
# create action bindings, and check the returned bindings
action1 = self.env.ref('base.action_attachment')
action2 = self.env.ref('base.ir_default_menu_action')
action3 = self.env['ir.actions.report'].search([('groups_id', '=', False)], limit=1)
action1.binding_model_id = action2.binding_model_id \
= action3.binding_model_id \
= self.env['ir.model']._get('res.partner')
bindings = Actions.get_bindings('res.partner')
self.assertItemsEqual(
bindings['action'],
(action1 + action2).read(),
"Wrong action bindings",
)
self.assertItemsEqual(
bindings['report'],
action3.read(),
"Wrong action bindings",
)
# add a group on an action, and check that it is not returned
group = self.env.ref('base.group_user')
action2.groups_id += group
self.env.user.groups_id -= group
bindings = Actions.get_bindings('res.partner')
self.assertItemsEqual(
bindings['action'],
action1.read(),
"Wrong action bindings",
)
self.assertItemsEqual(
bindings['report'],
action3.read(),
"Wrong action bindings",
)
class TestBindingViewFilters(common.TransactionCase):
def test_act_window(self):
A = self.env['tab.a']
form_act = A.fields_view_get(toolbar=True)['toolbar']['action']
self.assertEqual(
[a['name'] for a in form_act],
['Action 1', 'Action 2', 'Action 3'],
"forms should have all actions")
list_act = A.fields_view_get(view_type='tree', toolbar=True)['toolbar']['action']
self.assertEqual(
[a['name'] for a in list_act],
['Action 1', 'Action 3'],
"lists should not have the form-only action")
kanban_act = A.fields_view_get(view_type='kanban', toolbar=True)['toolbar']['action']
self.assertEqual(
[a['name'] for a in kanban_act],
['Action 1'],
"kanban should only have the universal action")
def test_act_record(self):
B = self.env['tab.b']
form_act = B.fields_view_get(toolbar=True)['toolbar']['action']
self.assertEqual(
[a['name'] for a in form_act],
['Record 1', 'Record 2', 'Record 3'],
"forms should have all actions")
list_act = B.fields_view_get(view_type='tree', toolbar=True)['toolbar']['action']
self.assertEqual(
[a['name'] for a in list_act],
['Record 1', 'Record 3'],
"lists should not have the form-only action")
kanban_act = B.fields_view_get(view_type='kanban', toolbar=True)['toolbar']['action']
self.assertEqual(
[a['name'] for a in kanban_act],
['Record 1'],
"kanban should only have the universal action")
+23 -5
View File
@@ -6,6 +6,12 @@
<rng:optional><rng:attribute name="context" /></rng:optional>
</rng:define>
<rng:define name="views">
<rng:data type="string">
<rng:param name="pattern">([a-z]+(,[a-z]+)*)?</rng:param>
</rng:data>
</rng:define>
<rng:define name="any">
<rng:element>
<rng:anyName/>
@@ -243,18 +249,30 @@
<rng:attribute name="name" />
<rng:attribute name="res_model" />
<rng:optional><rng:attribute name="domain" /> </rng:optional>
<rng:optional><rng:attribute name="src_model" /></rng:optional>
<rng:optional><rng:attribute name="context" /></rng:optional>
<rng:optional> <rng:attribute name="view_id"/> </rng:optional>
<rng:optional> <rng:attribute name="view_type"/> </rng:optional>
<rng:optional><rng:attribute name="view_type"><rng:ref name="views"/></rng:attribute></rng:optional>
<rng:optional> <rng:attribute name="view_mode"/> </rng:optional>
<rng:optional> <rng:attribute name="multi"/> </rng:optional>
<rng:optional> <rng:attribute name="target"/> </rng:optional>
<rng:optional> <rng:attribute name="key2"/> </rng:optional>
<rng:optional> <rng:attribute name="groups"/> </rng:optional>
<rng:optional> <rng:attribute name="limit"/> </rng:optional>
<rng:optional> <rng:attribute name="usage"/> </rng:optional>
<rng:optional> <rng:attribute name="auto_refresh"/> </rng:optional>
<rng:optional>
<rng:attribute name="binding_model"/>
<rng:optional>
<rng:attribute name="binding_type">
<rng:choice>
<rng:value>action</rng:value>
<rng:value>report</rng:value>
</rng:choice>
</rng:attribute>
</rng:optional>
<rng:optional>
<rng:attribute name="binding_views">
<rng:ref name="views"/>
</rng:attribute>
</rng:optional>
</rng:optional>
<rng:empty />
</rng:element>
</rng:define>
+3 -9
View File
@@ -1484,24 +1484,18 @@ class BaseModel(MetaModel('DummyModel', (object,), {'_register': False})):
# Add related action information if aksed
if toolbar:
vt = 'list' if view_type == 'tree' else view_type
bindings = self.env['ir.actions.actions'].get_bindings(self._name)
resreport = [action
for action in bindings['report']
if view_type == 'tree' or not action.get('multi')]
if vt in (action.get('binding_view_types') or vt).split(',')]
resaction = [action
for action in bindings['action']
if view_type == 'tree' or not action.get('multi')]
resrelate = []
if view_type == 'form':
resrelate = bindings['action_form_only']
for res in itertools.chain(resreport, resaction):
res['string'] = res['name']
if vt in (action.get('binding_view_types') or vt).split(',')]
result['toolbar'] = {
'print': resreport,
'action': resaction,
'relate': resrelate,
}
return result
+11 -16
View File
@@ -328,13 +328,12 @@ form: module.record_id""" % (xml_id,)
name = rec.get('name')
xml_id = rec.get('id','')
self._test_xml_id(xml_id)
type = rec.get('type') or 'ir.actions.act_window'
view_id = False
if rec.get('view_id'):
view_id = self.id_get(rec.get('view_id'))
domain = rec.get('domain') or '[]'
res_model = rec.get('res_model')
src_model = rec.get('src_model')
binding_model = rec.get('binding_model')
view_type = rec.get('view_type') or 'form'
view_mode = rec.get('view_mode') or 'tree,form'
usage = rec.get('usage')
@@ -359,16 +358,16 @@ form: module.record_id""" % (xml_id,)
eval_context = {
'name': name,
'xml_id': xml_id,
'type': type,
'type': 'ir.actions.act_window',
'view_id': view_id,
'domain': domain,
'res_model': res_model,
'src_model': src_model,
'src_model': binding_model,
'view_type': view_type,
'view_mode': view_mode,
'usage': usage,
'limit': limit,
'uid' : uid,
'uid': uid,
'active_id': active_id,
'active_ids': active_ids,
'active_model': active_model,
@@ -386,12 +385,11 @@ form: module.record_id""" % (xml_id,)
domain, xml_id or 'n/a', exc_info=True)
res = {
'name': name,
'type': type,
'type': 'ir.actions.act_window',
'view_id': view_id,
'domain': domain,
'context': context,
'res_model': res_model,
'src_model': src_model,
'view_type': view_type,
'view_mode': view_mode,
'usage': usage,
@@ -412,15 +410,12 @@ form: module.record_id""" % (xml_id,)
if rec.get('target'):
res['target'] = rec.get('target','')
if rec.get('multi'):
res['multi'] = safe_eval(rec.get('multi', 'False'))
if src_model:
res['binding_model_id'] = self.env['ir.model']._get(src_model).id
res['binding_type'] = 'report' if rec.get('key2') == 'client_print_multi' else 'action'
if rec.get('key2') in (None, 'client_action_relate'):
if not res.get('multi'):
res['binding_type'] = 'action_form_only'
if binding_model:
res['binding_model_id'] = self.env['ir.model']._get(binding_model).id
res['binding_type'] = rec.get('binding_type') or 'action'
views = rec.get('binding_views')
if views is not None:
res['binding_view_types'] = views
xid = self.make_xml_id(xml_id)
data = dict(xml_id=xid, values=res, noupdate=self.noupdate)
self.env['ir.actions.act_window']._load_records([data], self.mode == 'update')
+1 -1
View File
@@ -140,7 +140,7 @@ def try_report_action(cr, uid, action_id, active_model=None, active_ids=None,
env = env(context=context)
if action['type'] in ['ir.actions.act_window', 'ir.actions.submenu']:
for key in ('res_id', 'res_model', 'view_type', 'view_mode',
'limit', 'search_view', 'auto_search', 'search_view_id'):
'limit', 'search_view', 'search_view_id'):
datas[key] = action.get(key, datas.get(key, None))
view_id = False