diff --git a/addons/account/models/account_journal_dashboard.py b/addons/account/models/account_journal_dashboard.py index 63a75bf323e..0bc805110e8 100644 --- a/addons/account/models/account_journal_dashboard.py +++ b/addons/account/models/account_journal_dashboard.py @@ -459,7 +459,8 @@ class account_journal(models.Model): if '.' not in action_name: action_name = 'account.%s' % action_name - action = self.env.ref(action_name).read()[0] + action = self.env["ir.actions.act_window"]._for_xml_id(action_name) + context = self._context.copy() if 'context' in action and type(action['context']) == str: context.update(ast.literal_eval(action['context'])) @@ -533,7 +534,7 @@ class account_journal(models.Model): def create_bank_statement(self): """return action to create a bank statements. This button should be called only on journals with type =='bank'""" - action = self.env.ref('account.action_bank_statement_tree').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("account.action_bank_statement_tree") action.update({ 'views': [[False, 'form']], 'context': "{'default_journal_id': " + str(self.id) + "}", diff --git a/addons/account/models/account_move.py b/addons/account/models/account_move.py index e72f4f9e2c9..5f69692cff1 100644 --- a/addons/account/models/account_move.py +++ b/addons/account/models/account_move.py @@ -2361,7 +2361,7 @@ class AccountMove(models.Model): return self.move_type == 'out_invoice' and not self.payment_reference def action_reverse(self): - action = self.env.ref('account.action_view_account_move_reversal').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("account.action_view_account_move_reversal") if self.is_invoice(): action['name'] = _('Credit Note') @@ -2614,7 +2614,7 @@ class AccountMove(models.Model): # offer the possibility to duplicate thanks to a button instead of a hidden menu, which is more visible def action_duplicate(self): self.ensure_one() - action = self.env.ref('account.action_move_journal_line').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("account.action_move_journal_line") action['context'] = dict(self.env.context) action['context']['form_view_initial_mode'] = 'edit' action['context']['view_no_maturity'] = False diff --git a/addons/account/models/account_reconcile_model.py b/addons/account/models/account_reconcile_model.py index 7f62c573ffe..6e75649cefb 100644 --- a/addons/account/models/account_reconcile_model.py +++ b/addons/account/models/account_reconcile_model.py @@ -226,7 +226,7 @@ class AccountReconcileModel(models.Model): def action_reconcile_stat(self): self.ensure_one() - action = self.env.ref('account.action_move_journal_line').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("account.action_move_journal_line") self._cr.execute(''' SELECT ARRAY_AGG(DISTINCT move_id) FROM account_move_line diff --git a/addons/account/models/company.py b/addons/account/models/company.py index 89cb05ab1a6..ce4951f0954 100644 --- a/addons/account/models/company.py +++ b/addons/account/models/company.py @@ -431,7 +431,7 @@ class ResCompany(models.Model): @api.model def action_open_account_onboarding_sale_tax(self): """ Onboarding step for the invoice layout. """ - action = self.env.ref('account.action_open_account_onboarding_sale_tax').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("account.action_open_account_onboarding_sale_tax") action['res_id'] = self.env.company.id return action @@ -485,7 +485,7 @@ class ResCompany(models.Model): with the edi_invoice_template message loaded by default. """ sample_invoice = self._get_sample_invoice() template = self.env.ref('account.email_template_edi_invoice', False) - action = self.env.ref('account.action_open_account_onboarding_sample_invoice').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("account.action_open_account_onboarding_sample_invoice") action['context'] = { 'default_res_id': sample_invoice.id, 'default_use_template': bool(template), diff --git a/addons/account/models/partner.py b/addons/account/models/partner.py index 1914a270cf3..c602a92240c 100644 --- a/addons/account/models/partner.py +++ b/addons/account/models/partner.py @@ -476,7 +476,7 @@ class ResPartner(models.Model): def action_view_partner_invoices(self): self.ensure_one() - action = self.env.ref('account.action_move_out_invoice_type').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("account.action_move_out_invoice_type") action['domain'] = [ ('move_type', 'in', ('out_invoice', 'out_refund')), ('partner_id', 'child_of', self.id), diff --git a/addons/auth_signup/models/res_config_settings.py b/addons/auth_signup/models/res_config_settings.py index 662152c2959..b4e62cecc68 100644 --- a/addons/auth_signup/models/res_config_settings.py +++ b/addons/auth_signup/models/res_config_settings.py @@ -18,7 +18,7 @@ class ResConfigSettings(models.TransientModel): config_parameter='base.template_portal_user_id') def open_template_user(self): - action = self.env.ref('base.action_res_users').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("base.action_res_users") action['res_id'] = literal_eval(self.env['ir.config_parameter'].sudo().get_param('base.template_portal_user_id', 'False')) action['views'] = [[self.env.ref('base.view_users_form').id, 'form']] return action diff --git a/addons/base_automation/models/base_automation.py b/addons/base_automation/models/base_automation.py index 77be0ddc76d..e5ef6cf2f16 100644 --- a/addons/base_automation/models/base_automation.py +++ b/addons/base_automation/models/base_automation.py @@ -164,7 +164,7 @@ class BaseAutomation(models.Model): if '__action_done' not in self._context: self = self.with_context(__action_done={}) domain = [('model_name', '=', records._name), ('trigger', 'in', triggers)] - actions = self.with_context(active_test=True).search(domain) + actions = self.with_context(active_test=True).sudo().search(domain) return actions.with_env(self.env) def _get_eval_context(self): @@ -258,7 +258,7 @@ class BaseAutomation(models.Model): 'domain_post': domain_post, } try: - self.action_server_id.with_context(**ctx).run() + self.action_server_id.sudo().with_context(**ctx).run() except Exception as e: self._add_postmortem_action(e) raise e diff --git a/addons/base_automation/security/ir.model.access.csv b/addons/base_automation/security/ir.model.access.csv index 6b1d50350d0..77253ff3e96 100644 --- a/addons/base_automation/security/ir.model.access.csv +++ b/addons/base_automation/security/ir.model.access.csv @@ -1,3 +1,2 @@ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink -access_base_automation,base.automation,model_base_automation,,1,0,0,0 access_base_automation_config,base.automation config,model_base_automation,base.group_system,1,1,1,1 diff --git a/addons/base_setup/models/res_config_settings.py b/addons/base_setup/models/res_config_settings.py index 04b695c141f..acbe5a873c5 100644 --- a/addons/base_setup/models/res_config_settings.py +++ b/addons/base_setup/models/res_config_settings.py @@ -60,7 +60,7 @@ class ResConfigSettings(models.TransientModel): } def open_default_user(self): - action = self.env.ref('base.action_res_users').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("base.action_res_users") action['res_id'] = self.env.ref('base.default_user').id action['views'] = [[self.env.ref('base.view_users_form').id, 'form']] return action diff --git a/addons/calendar/models/calendar_attendee.py b/addons/calendar/models/calendar_attendee.py index a7d5f1ccd0d..0aeb5d51a63 100644 --- a/addons/calendar/models/calendar_attendee.py +++ b/addons/calendar/models/calendar_attendee.py @@ -107,7 +107,7 @@ class Attendee(models.Model): rendering_context.update({ 'colors': colors, 'ignore_recurrence': ignore_recurrence, - 'action_id': self.env['ir.actions.act_window'].search([('view_id', '=', calendar_view.id)], limit=1).id, + 'action_id': self.env['ir.actions.act_window'].sudo().search([('view_id', '=', calendar_view.id)], limit=1).id, 'dbname': self._cr.dbname, 'base_url': self.env['ir.config_parameter'].sudo().get_param('web.base.url', default='http://localhost:8069'), }) diff --git a/addons/calendar/models/mail_activity.py b/addons/calendar/models/mail_activity.py index 71d7bf0fadb..58ca5ff75d4 100644 --- a/addons/calendar/models/mail_activity.py +++ b/addons/calendar/models/mail_activity.py @@ -17,7 +17,7 @@ class MailActivity(models.Model): def action_create_calendar_event(self): self.ensure_one() - action = self.env.ref('calendar.action_calendar_event').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("calendar.action_calendar_event") action['context'] = { 'default_activity_type_id': self.activity_type_id.id, 'default_res_id': self.env.context.get('default_res_id'), diff --git a/addons/crm/models/crm_lead.py b/addons/crm/models/crm_lead.py index 4827eddd040..88be2bb673e 100644 --- a/addons/crm/models/crm_lead.py +++ b/addons/crm/models/crm_lead.py @@ -800,7 +800,7 @@ class Lead(models.Model): :return dict: dictionary value for created Meeting view """ self.ensure_one() - action = self.env.ref('calendar.action_calendar_event').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("calendar.action_calendar_event") partner_ids = self.env.user.partner_id.ids if self.partner_id: partner_ids.append(self.partner_id.id) diff --git a/addons/crm/models/crm_team.py b/addons/crm/models/crm_team.py index 850349dc79a..e099233691b 100644 --- a/addons/crm/models/crm_team.py +++ b/addons/crm/models/crm_team.py @@ -126,7 +126,7 @@ class Team(models.Model): #TODO JEM : refactor this stuff with xml action, proper customization, @api.model def action_your_pipeline(self): - action = self.env.ref('crm.crm_lead_action_pipeline').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("crm.crm_lead_action_pipeline") user_team_id = self.env.user.sale_team_id.id if user_team_id: # To ensure that the team is readable in multi company @@ -154,7 +154,7 @@ class Team(models.Model): def action_primary_channel_button(self): if self.use_opportunities: - return self.env.ref('crm.crm_case_form_view_salesteams_opportunity').read()[0] + return self.env["ir.actions.actions"]._for_xml_id("crm.crm_case_form_view_salesteams_opportunity") return super(Team,self).action_primary_channel_button() def _graph_get_model(self): diff --git a/addons/crm/models/res_partner.py b/addons/crm/models/res_partner.py index f214c7d5549..8f429c888ec 100644 --- a/addons/crm/models/res_partner.py +++ b/addons/crm/models/res_partner.py @@ -77,7 +77,7 @@ class Partner(models.Model): def schedule_meeting(self): partner_ids = self.ids partner_ids.append(self.env.user.partner_id.id) - action = self.env.ref('calendar.action_calendar_event').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("calendar.action_calendar_event") action['context'] = { 'default_partner_ids': partner_ids, } diff --git a/addons/crm/models/utm.py b/addons/crm/models/utm.py index 3839952b286..fd093579217 100644 --- a/addons/crm/models/utm.py +++ b/addons/crm/models/utm.py @@ -23,7 +23,7 @@ class UtmCampaign(models.Model): def action_redirect_to_leads_opportunities(self): view = 'crm.crm_lead_all_leads' if self.use_leads else 'crm.crm_lead_opportunities' - action = self.env.ref(view).read()[0] + action = self.env.ref(view).sudo().read()[0] action['view_mode'] = 'tree,kanban,graph,pivot,form,calendar' action['domain'] = [('campaign_id', 'in', self.ids)] action['context'] = {'active_test': False, 'create': False} diff --git a/addons/crm/views/crm_lead_views.xml b/addons/crm/views/crm_lead_views.xml index 82ff08fc5dc..68d24df7cec 100644 --- a/addons/crm/views/crm_lead_views.xml +++ b/addons/crm/views/crm_lead_views.xml @@ -981,6 +981,7 @@ if record: Crm: My Pipeline code + action = model.action_your_pipeline() diff --git a/addons/crm_iap_lead/models/crm_iap_lead_mining_request.py b/addons/crm_iap_lead/models/crm_iap_lead_mining_request.py index 8cd41ebb3bd..f3bedd5905a 100644 --- a/addons/crm_iap_lead/models/crm_iap_lead_mining_request.py +++ b/addons/crm_iap_lead/models/crm_iap_lead_mining_request.py @@ -243,7 +243,7 @@ class CRMLeadMiningRequest(models.Model): def action_get_lead_action(self): self.ensure_one() - action = self.env.ref('crm.crm_lead_all_leads').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("crm.crm_lead_all_leads") action['domain'] = [('id', 'in', self.lead_ids.ids), ('type', '=', 'lead')] action['help'] = _("""

No leads found @@ -254,7 +254,7 @@ class CRMLeadMiningRequest(models.Model): def action_get_opportunity_action(self): self.ensure_one() - action = self.env.ref('crm.crm_lead_opportunities').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("crm.crm_lead_opportunities") action['domain'] = [('id', 'in', self.lead_ids.ids), ('type', '=', 'opportunity')] action['help'] = _("""

No opportunities found diff --git a/addons/crm_iap_lead_website/models/crm_reveal_rule.py b/addons/crm_iap_lead_website/models/crm_reveal_rule.py index d64565a55f8..58cf4093a9c 100644 --- a/addons/crm_iap_lead_website/models/crm_reveal_rule.py +++ b/addons/crm_iap_lead_website/models/crm_reveal_rule.py @@ -111,13 +111,13 @@ class CRMRevealRule(models.Model): rule.opportunity_count = mapping.get((rule.id, 'opportunity'), 0) def action_get_lead_tree_view(self): - action = self.env.ref('crm.crm_lead_all_leads').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("crm.crm_lead_all_leads") action['domain'] = [('id', 'in', self.lead_ids.ids), ('type', '=', 'lead')] action['context'] = dict(self._context, create=False) return action def action_get_opportunity_tree_view(self): - action = self.env.ref('crm.crm_lead_opportunities').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("crm.crm_lead_opportunities") action['domain'] = [('id', 'in', self.lead_ids.ids), ('type', '=', 'opportunity')] action['context'] = dict(self._context, create=False) return action diff --git a/addons/delivery/models/stock_picking.py b/addons/delivery/models/stock_picking.py index 20ad15160f2..1d561631ce8 100644 --- a/addons/delivery/models/stock_picking.py +++ b/addons/delivery/models/stock_picking.py @@ -219,7 +219,7 @@ class StockPicking(models.Model): for tracker in carrier_trackers: msg += '' + tracker[0] + '
' self.message_post(body=msg) - return self.env.ref('delivery.act_delivery_trackers_url').read()[0] + return self.env["ir.actions.actions"]._for_xml_id("delivery.act_delivery_trackers_url") client_action = { 'type': 'ir.actions.act_url', diff --git a/addons/event/models/res_partner.py b/addons/event/models/res_partner.py index 16e09995969..1311e15d2f6 100644 --- a/addons/event/models/res_partner.py +++ b/addons/event/models/res_partner.py @@ -19,7 +19,7 @@ class ResPartner(models.Model): partner.event_count = self.env['event.event'].search_count([('registration_ids.partner_id', 'child_of', partner.ids)]) def action_event_view(self): - action = self.env.ref('event.action_event_view').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("event.action_event_view") action['context'] = {} action['domain'] = [('registration_ids.partner_id', 'child_of', self.ids)] return action diff --git a/addons/event_sale/models/event_event.py b/addons/event_sale/models/event_event.py index b246a033109..1072cf73a48 100644 --- a/addons/event_sale/models/event_event.py +++ b/addons/event_sale/models/event_event.py @@ -34,7 +34,7 @@ class Event(models.Model): def action_view_linked_orders(self): """ Redirects to the orders linked to the current events """ - sale_order_action = self.env.ref('sale.action_orders').read()[0] + sale_order_action = self.env["ir.actions.actions"]._for_xml_id("sale.action_orders") sale_order_action.update({ 'domain': [('state', '!=', 'cancel'), ('order_line.event_id', 'in', self.ids)], 'context': {'create': 0}, diff --git a/addons/event_sale/models/event_registration.py b/addons/event_sale/models/event_registration.py index f7b6d79a395..1acb6126adb 100644 --- a/addons/event_sale/models/event_registration.py +++ b/addons/event_sale/models/event_registration.py @@ -58,7 +58,7 @@ class EventRegistration(models.Model): registration.utm_medium_id = False def action_view_sale_order(self): - action = self.env.ref('sale.action_orders').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("sale.action_orders") action['views'] = [(False, 'form')] action['res_id'] = self.sale_order_id.id return action diff --git a/addons/event_sale/models/sale_order.py b/addons/event_sale/models/sale_order.py index a5a7d074c09..9f170b994ce 100644 --- a/addons/event_sale/models/sale_order.py +++ b/addons/event_sale/models/sale_order.py @@ -26,11 +26,11 @@ class SaleOrder(models.Model): if any(line.event_id for line in so.order_line): return self.env['ir.actions.act_window'] \ .with_context(default_sale_order_id=so.id) \ - .for_xml_id('event_sale', 'action_sale_order_event_registration') + ._for_xml_id('event_sale.action_sale_order_event_registration') return res def action_view_attendee_list(self): - action = self.env.ref('event.event_registration_action_tree').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("event.event_registration_action_tree") action['domain'] = [('sale_order_id', 'in', self.ids)] return action diff --git a/addons/fleet/models/fleet_vehicle.py b/addons/fleet/models/fleet_vehicle.py index e2498f854d7..87519bdafd0 100644 --- a/addons/fleet/models/fleet_vehicle.py +++ b/addons/fleet/models/fleet_vehicle.py @@ -281,7 +281,8 @@ class FleetVehicle(models.Model): self.ensure_one() xml_id = self.env.context.get('xml_id') if xml_id: - res = self.env['ir.actions.act_window'].for_xml_id('fleet', xml_id) + + res = self.env['ir.actions.act_window']._for_xml_id('fleet.%s' % xml_id) res.update( context=dict(self.env.context, default_vehicle_id=self.id, group_by=False), domain=[('vehicle_id', '=', self.id)] @@ -296,7 +297,7 @@ class FleetVehicle(models.Model): self.ensure_one() copy_context = dict(self.env.context) copy_context.pop('group_by', None) - res = self.env['ir.actions.act_window'].for_xml_id('fleet', 'fleet_vehicle_costs_action') + res = self.env['ir.actions.act_window']._for_xml_id('fleet.fleet_vehicle_costs_action') res.update( context=dict(copy_context, default_vehicle_id=self.id, search_default_parent_false=True), domain=[('vehicle_id', '=', self.id)] diff --git a/addons/hr/models/res_users.py b/addons/hr/models/res_users.py index e95b7a8c57d..a00e9b1d134 100644 --- a/addons/hr/models/res_users.py +++ b/addons/hr/models/res_users.py @@ -188,7 +188,7 @@ class User(models.Model): @api.model def action_get(self): if self.env.user.employee_id: - return self.sudo().env.ref('hr.res_users_action_my').read()[0] + return self.sudo().env.ref('hr.res_users_action_my').sudo().read()[0] return super(User, self).action_get() @api.depends('employee_ids') diff --git a/addons/hr_attendance/models/hr_employee.py b/addons/hr_attendance/models/hr_employee.py index b1901554e44..bb67506dbb9 100644 --- a/addons/hr_attendance/models/hr_employee.py +++ b/addons/hr_attendance/models/hr_employee.py @@ -124,7 +124,7 @@ class HrEmployeeBase(models.AbstractModel): """ self.ensure_one() employee = self.sudo() - action_message = self.env.ref('hr_attendance.hr_attendance_action_greeting_message').read()[0] + action_message = self.env["ir.actions.actions"]._for_xml_id("hr_attendance.hr_attendance_action_greeting_message") action_message['previous_attendance_change_date'] = employee.last_attendance_id and (employee.last_attendance_id.check_out or employee.last_attendance_id.check_in) or False action_message['employee_name'] = employee.name action_message['barcode'] = employee.barcode diff --git a/addons/hr_expense/models/hr_expense.py b/addons/hr_expense/models/hr_expense.py index 114085d29a5..2635966599d 100644 --- a/addons/hr_expense/models/hr_expense.py +++ b/addons/hr_expense/models/hr_expense.py @@ -325,7 +325,7 @@ class HrExpense(models.Model): def action_get_attachment_view(self): self.ensure_one() - res = self.env['ir.actions.act_window'].for_xml_id('base', 'action_attachment') + res = self.env['ir.actions.act_window']._for_xml_id('base.action_attachment') res['domain'] = [('res_model', '=', 'hr.expense'), ('res_id', 'in', self.ids)] res['context'] = {'default_res_model': 'hr.expense', 'default_res_id': self.id} return res @@ -915,7 +915,7 @@ class HrExpenseSheet(models.Model): return res def action_get_attachment_view(self): - res = self.env['ir.actions.act_window'].for_xml_id('base', 'action_attachment') + res = self.env['ir.actions.act_window']._for_xml_id('base.action_attachment') res['domain'] = [('res_model', '=', 'hr.expense'), ('res_id', 'in', self.expense_line_ids.ids)] res['context'] = { 'default_res_model': 'hr.expense.sheet', diff --git a/addons/hr_fleet/models/fleet_vehicle_assignation_log.py b/addons/hr_fleet/models/fleet_vehicle_assignation_log.py index 95e191b8fc8..cd93fcdf97f 100644 --- a/addons/hr_fleet/models/fleet_vehicle_assignation_log.py +++ b/addons/hr_fleet/models/fleet_vehicle_assignation_log.py @@ -19,7 +19,7 @@ class FleetVehicleAssignationLog(models.Model): def action_get_attachment_view(self): self.ensure_one() - res = self.env['ir.actions.act_window'].for_xml_id('base', 'action_attachment') + res = self.env['ir.actions.act_window']._for_xml_id('base.action_attachment') res['domain'] = [('res_model', '=', 'fleet.vehicle.assignation.log'), ('res_id', 'in', self.ids)] res['context'] = {'default_res_model': 'fleet.vehicle.assignation.log', 'default_res_id': self.id} return res diff --git a/addons/hr_holidays/models/hr_leave_type.py b/addons/hr_holidays/models/hr_leave_type.py index 5841c3fab4d..772cde2ee93 100644 --- a/addons/hr_holidays/models/hr_leave_type.py +++ b/addons/hr_holidays/models/hr_leave_type.py @@ -347,7 +347,7 @@ class HolidaysType(models.Model): def action_see_days_allocated(self): self.ensure_one() - action = self.env.ref('hr_holidays.hr_leave_allocation_action_all').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("hr_holidays.hr_leave_allocation_action_all") domain = [ ('holiday_status_id', 'in', self.ids), ('holiday_type', '!=', 'employee'), @@ -366,7 +366,7 @@ class HolidaysType(models.Model): def action_see_group_leaves(self): self.ensure_one() - action = self.env.ref('hr_holidays.hr_leave_action_action_approve_department').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("hr_holidays.hr_leave_action_action_approve_department") action['domain'] = [ ('holiday_status_id', '=', self.ids[0]), ('date_from', '>=', fields.Datetime.to_string(datetime.datetime.now().replace(month=1, day=1, hour=0, minute=0, second=0, microsecond=0))) diff --git a/addons/hr_recruitment/models/hr_job.py b/addons/hr_recruitment/models/hr_job.py index edf7d025ad5..b01f311750d 100644 --- a/addons/hr_recruitment/models/hr_job.py +++ b/addons/hr_recruitment/models/hr_job.py @@ -129,7 +129,7 @@ class Job(models.Model): return self.env.ref('hr_recruitment.mt_job_new') def action_get_attachment_tree_view(self): - action = self.env.ref('base.action_attachment').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("base.action_attachment") action['context'] = { 'default_res_model': self._name, 'default_res_id': self.ids[0] diff --git a/addons/hr_recruitment/models/hr_recruitment.py b/addons/hr_recruitment/models/hr_recruitment.py index c5532974b17..321e4340ca6 100644 --- a/addons/hr_recruitment/models/hr_recruitment.py +++ b/addons/hr_recruitment/models/hr_recruitment.py @@ -339,7 +339,7 @@ class Applicant(models.Model): partners = self.partner_id | self.user_id.partner_id | self.department_id.manager_id.user_id.partner_id category = self.env.ref('hr_recruitment.categ_meet_interview') - res = self.env['ir.actions.act_window'].for_xml_id('calendar', 'action_calendar_event') + res = self.env['ir.actions.act_window']._for_xml_id('calendar.action_calendar_event') res['context'] = { 'default_partner_ids': partners.ids, 'default_user_id': self.env.uid, diff --git a/addons/im_livechat/models/im_livechat_channel.py b/addons/im_livechat/models/im_livechat_channel.py index 4cf813eb0e8..ce56ce3cfbe 100644 --- a/addons/im_livechat/models/im_livechat_channel.py +++ b/addons/im_livechat/models/im_livechat_channel.py @@ -98,7 +98,7 @@ class ImLivechatChannel(models.Model): :returns : the ir.action 'action_view_rating' with the correct domain """ self.ensure_one() - action = self.env['ir.actions.act_window'].for_xml_id('im_livechat', 'rating_rating_action_view_livechat_rating') + action = self.env['ir.actions.act_window']._for_xml_id('im_livechat.rating_rating_action_view_livechat_rating') action['domain'] = [('parent_res_id', '=', self.id), ('parent_res_model', '=', 'im_livechat.channel')] return action diff --git a/addons/link_tracker/models/link_tracker.py b/addons/link_tracker/models/link_tracker.py index 2ee2fad31ab..50b00b9011f 100644 --- a/addons/link_tracker/models/link_tracker.py +++ b/addons/link_tracker/models/link_tracker.py @@ -145,7 +145,7 @@ class LinkTracker(models.Model): raise NotImplementedError('Moved on mail.render.mixin') def action_view_statistics(self): - action = self.env['ir.actions.act_window'].for_xml_id('link_tracker', 'link_tracker_click_action_statistics') + action = self.env['ir.actions.act_window']._for_xml_id('link_tracker.link_tracker_click_action_statistics') action['domain'] = [('link_id', '=', self.id)] action['context'] = dict(self._context, create=False) return action diff --git a/addons/mass_mailing/models/mailing.py b/addons/mass_mailing/models/mailing.py index 15b38a1d1d2..d329cb2e572 100644 --- a/addons/mass_mailing/models/mailing.py +++ b/addons/mass_mailing/models/mailing.py @@ -300,7 +300,7 @@ class MassMailing(models.Model): def action_schedule(self): self.ensure_one() - action = self.env.ref('mass_mailing.mailing_mailing_schedule_date_action').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("mass_mailing.mailing_mailing_schedule_date_action") action['context'] = dict(self.env.context, default_mass_mailing_id=self.id) return action @@ -332,7 +332,7 @@ class MassMailing(models.Model): return self._action_view_traces_filtered('sent') def _action_view_traces_filtered(self, view_filter): - action = self.env.ref('mass_mailing.mailing_trace_action').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("mass_mailing.mailing_trace_action") action['name'] = _('%s Traces') % (self.name) action['context'] = {'search_default_mass_mailing_id': self.id,} filter_key = 'search_default_filter_%s' % (view_filter) diff --git a/addons/mass_mailing/models/mailing_list.py b/addons/mass_mailing/models/mailing_list.py index 57173bdbdfb..f019721894f 100644 --- a/addons/mass_mailing/models/mailing_list.py +++ b/addons/mass_mailing/models/mailing_list.py @@ -60,7 +60,7 @@ class MassMailingList(models.Model): return [(list.id, "%s (%s)" % (list.name, list.contact_nbr)) for list in self] def action_view_contacts(self): - action = self.env.ref('mass_mailing.action_view_mass_mailing_contacts').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("mass_mailing.action_view_mass_mailing_contacts") action['domain'] = [('list_ids', 'in', self.ids)] context = dict(self.env.context, search_default_filter_valid_email_recipient=1, default_list_ids=self.ids) action['context'] = context diff --git a/addons/mass_mailing_crm/models/mailing_mailing.py b/addons/mass_mailing_crm/models/mailing_mailing.py index 19af7cff904..941b1b7b076 100644 --- a/addons/mass_mailing_crm/models/mailing_mailing.py +++ b/addons/mass_mailing_crm/models/mailing_mailing.py @@ -28,7 +28,7 @@ class MassMailing(models.Model): def action_redirect_to_leads_and_opportunities(self): view = 'crm.crm_lead_all_leads' if self.use_leads else 'crm.crm_lead_opportunities' - action = self.env.ref(view).read()[0] + action = self.env.ref(view).sudo().read()[0] action['view_mode'] = 'tree,kanban,graph,pivot,form,calendar' action['domain'] = [('source_id', 'in', self.source_id.ids)] action['context'] = {'active_test': False, 'create': False} diff --git a/addons/mass_mailing_sale/models/mailing_mailing.py b/addons/mass_mailing_sale/models/mailing_mailing.py index 290875290bf..f4a5ee71fac 100644 --- a/addons/mass_mailing_sale/models/mailing_mailing.py +++ b/addons/mass_mailing_sale/models/mailing_mailing.py @@ -29,13 +29,13 @@ class MassMailing(models.Model): mass_mailing.sale_invoiced_amount = 0 def action_redirect_to_quotations(self): - action = self.env.ref('sale.action_quotations_with_onboarding').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("sale.action_quotations_with_onboarding") action['domain'] = self._get_sale_utm_domain() action['context'] = {'create': False} return action def action_redirect_to_invoiced(self): - action = self.env.ref('account.action_move_out_invoice_type').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("account.action_move_out_invoice_type") moves = self.env['account.move'].search(self._get_sale_utm_domain()) action['context'] = { 'create': False, diff --git a/addons/mass_mailing_sms/models/mailing_list.py b/addons/mass_mailing_sms/models/mailing_list.py index 56b96df552f..86b27e81566 100644 --- a/addons/mass_mailing_sms/models/mailing_list.py +++ b/addons/mass_mailing_sms/models/mailing_list.py @@ -28,7 +28,7 @@ group by list_id''', (tuple(self.ids), )) def action_view_contacts(self): if self.env.context.get('mailing_sms'): - action = self.env.ref('mass_mailing_sms.mailing_contact_action_sms').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("mass_mailing_sms.mailing_contact_action_sms") action['domain'] = [('list_ids', 'in', self.ids)] context = dict(self.env.context, search_default_filter_valid_sms_recipient=1, default_list_ids=self.ids) action['context'] = context diff --git a/addons/mass_mailing_sms/models/utm.py b/addons/mass_mailing_sms/models/utm.py index 2117a21c5f6..67c41648f97 100644 --- a/addons/mass_mailing_sms/models/utm.py +++ b/addons/mass_mailing_sms/models/utm.py @@ -19,7 +19,7 @@ class UtmCampaign(models.Model): campaign.mailing_sms_count = len(campaign.mailing_sms_ids) def action_create_mass_sms(self): - action = self.env.ref('mass_mailing.action_create_mass_mailings_from_campaign').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("mass_mailing.action_create_mass_mailings_from_campaign") action['context'] = { 'default_campaign_id': self.id, 'default_mailing_type': 'sms', @@ -30,7 +30,7 @@ class UtmCampaign(models.Model): return action def action_redirect_to_mailing_sms(self): - action = self.env.ref('mass_mailing_sms.mailing_mailing_action_sms').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("mass_mailing_sms.mailing_mailing_action_sms") action['context'] = { 'default_campaign_id': self.id, 'default_mailing_type': 'sms', diff --git a/addons/mrp/models/mrp_production.py b/addons/mrp/models/mrp_production.py index 0b725a46370..da06b8f9db6 100644 --- a/addons/mrp/models/mrp_production.py +++ b/addons/mrp/models/mrp_production.py @@ -394,7 +394,7 @@ class MrpProduction(models.Model): view, if there is only one picking to show. """ self.ensure_one() - action = self.env.ref('stock.action_picking_tree_all').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("stock.action_picking_tree_all") pickings = self.mapped('picking_ids') if len(pickings) > 1: action['domain'] = [('id', 'in', pickings.ids)] @@ -1247,7 +1247,7 @@ class MrpProduction(models.Model): 'product_expected_qty_uom': expected_qty })) ctx.update({'default_mrp_production_ids': self.ids, 'default_mrp_consumption_warning_line_ids': lines}) - action = self.env.ref('mrp.action_mrp_consumption_warning').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("mrp.action_mrp_consumption_warning") action['context'] = ctx return action @@ -1269,7 +1269,7 @@ class MrpProduction(models.Model): 'to_backorder': True })) ctx.update({'default_mrp_production_ids': self.ids, 'default_mrp_production_backorder_line_ids': lines}) - action = self.env.ref('mrp.action_mrp_production_backorder').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("mrp.action_mrp_production_backorder") action['context'] = ctx return action @@ -1559,7 +1559,7 @@ class MrpProduction(models.Model): def action_see_move_scrap(self): self.ensure_one() - action = self.env.ref('stock.action_stock_scrap').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("stock.action_stock_scrap") action['domain'] = [('production_id', '=', self.id)] action['context'] = dict(self._context, default_origin=self.name) return action diff --git a/addons/mrp/models/mrp_workcenter.py b/addons/mrp/models/mrp_workcenter.py index 6f377ceedb4..f90d8e96fff 100644 --- a/addons/mrp/models/mrp_workcenter.py +++ b/addons/mrp/models/mrp_workcenter.py @@ -192,7 +192,7 @@ class MrpWorkcenter(models.Model): return super(MrpWorkcenter, self).write(vals) def action_work_order(self): - action = self.env.ref('mrp.action_work_orders').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("mrp.action_work_orders") return action def _get_unavailability_intervals(self, start_datetime, end_datetime): diff --git a/addons/mrp/models/mrp_workorder.py b/addons/mrp/models/mrp_workorder.py index d559f9f8928..30824a7ff0d 100644 --- a/addons/mrp/models/mrp_workorder.py +++ b/addons/mrp/models/mrp_workorder.py @@ -657,13 +657,13 @@ class MrpWorkorder(models.Model): def action_see_move_scrap(self): self.ensure_one() - action = self.env.ref('stock.action_stock_scrap').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("stock.action_stock_scrap") action['domain'] = [('workorder_id', '=', self.id)] return action def action_open_wizard(self): self.ensure_one() - action = self.env.ref('mrp.mrp_workorder_mrp_production_form').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("mrp.mrp_workorder_mrp_production_form") action['res_id'] = self.id return action diff --git a/addons/mrp/models/product.py b/addons/mrp/models/product.py index a879e9d866e..b1b2f449ccf 100644 --- a/addons/mrp/models/product.py +++ b/addons/mrp/models/product.py @@ -39,7 +39,7 @@ class ProductTemplate(models.Model): def action_used_in_bom(self): self.ensure_one() - action = self.env.ref('mrp.mrp_bom_form_action').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("mrp.mrp_bom_form_action") action['domain'] = [('bom_line_ids.product_id', 'in', self.product_variant_ids.ids)] return action @@ -48,7 +48,7 @@ class ProductTemplate(models.Model): template.mrp_product_qty = float_round(sum(template.mapped('product_variant_ids').mapped('mrp_product_qty')), precision_rounding=template.uom_id.rounding) def action_view_mos(self): - action = self.env.ref('mrp.mrp_production_report').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("mrp.mrp_production_report") action['domain'] = [('state', '=', 'done'), ('product_tmpl_id', 'in', self.ids)] action['context'] = { 'graph_measure': 'product_uom_qty', @@ -97,7 +97,7 @@ class ProductProduct(models.Model): def action_used_in_bom(self): self.ensure_one() - action = self.env.ref('mrp.mrp_bom_form_action').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("mrp.mrp_bom_form_action") action['domain'] = [('bom_line_ids.product_id', '=', self.id)] return action @@ -163,7 +163,7 @@ class ProductProduct(models.Model): product.free_qty = min(ratios_free_qty) // 1 def action_view_bom(self): - action = self.env.ref('mrp.product_open_bom').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("mrp.product_open_bom") template_ids = self.mapped('product_tmpl_id').ids # bom specific to this variant or global to template action['context'] = { diff --git a/addons/mrp_account/models/mrp_production.py b/addons/mrp_account/models/mrp_production.py index b53b38d5a95..d193a98eecd 100644 --- a/addons/mrp_account/models/mrp_production.py +++ b/addons/mrp_account/models/mrp_production.py @@ -79,7 +79,7 @@ class MrpProduction(models.Model): def action_view_stock_valuation_layers(self): self.ensure_one() domain = [('id', 'in', (self.move_raw_ids + self.move_finished_ids + self.scrap_ids.move_id).stock_valuation_layer_ids.ids)] - action = self.env.ref('stock_account.stock_valuation_layer_action').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("stock_account.stock_valuation_layer_action") context = literal_eval(action['context']) context.update(self.env.context) context['no_at_date'] = True diff --git a/addons/payment/models/res_company.py b/addons/payment/models/res_company.py index 405fdff0745..b63d66804ae 100644 --- a/addons/payment/models/res_company.py +++ b/addons/payment/models/res_company.py @@ -22,7 +22,7 @@ class ResCompany(models.Model): # Fail if there are no existing accounts self.env.company.get_chart_of_accounts_or_fail() - action = self.env.ref('payment.action_open_payment_onboarding_payment_acquirer_wizard').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("payment.action_open_payment_onboarding_payment_acquirer_wizard") return action def get_account_invoice_onboarding_steps_states_names(self): diff --git a/addons/payment/wizards/payment_acquirer_onboarding_wizard.py b/addons/payment/wizards/payment_acquirer_onboarding_wizard.py index 2a9a90cc52e..24b6696af59 100644 --- a/addons/payment/wizards/payment_acquirer_onboarding_wizard.py +++ b/addons/payment/wizards/payment_acquirer_onboarding_wizard.py @@ -157,5 +157,5 @@ class PaymentWizard(models.TransientModel): def action_onboarding_other_payment_acquirer(self): self._set_payment_acquirer_onboarding_step_done() - action = self.env.ref('payment.action_payment_acquirer').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("payment.action_payment_acquirer") return action diff --git a/addons/portal/models/portal_mixin.py b/addons/portal/models/portal_mixin.py index a552277aac6..f3e86d80ccd 100644 --- a/addons/portal/models/portal_mixin.py +++ b/addons/portal/models/portal_mixin.py @@ -122,7 +122,7 @@ class PortalMixin(models.AbstractModel): @api.model def action_share(self): - action = self.env.ref('portal.portal_share_action').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("portal.portal_share_action") action['context'] = {'active_id': self.env.context['active_id'], 'active_model': self.env.context['active_model']} return action diff --git a/addons/project/models/project.py b/addons/project/models/project.py index 325c446ae59..d2b8e97d264 100644 --- a/addons/project/models/project.py +++ b/addons/project/models/project.py @@ -429,20 +429,22 @@ class Project(models.Model): favorite_projects.write({'favorite_user_ids': [(3, self.env.uid)]}) def action_view_tasks(self): - action = self.with_context(active_id=self.id, active_ids=self.ids).env.ref('project.act_project_project_2_project_task_all').read()[0] + action = self.with_context(active_id=self.id, active_ids=self.ids) \ + .env.ref('project.act_project_project_2_project_task_all') \ + .sudo().read()[0] action['display_name'] = self.name return action def action_view_account_analytic_line(self): """ return the action to see all the analytic lines of the project's analytic account """ - action = self.env.ref('analytic.account_analytic_line_action').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("analytic.account_analytic_line_action") action['context'] = {'default_account_id': self.analytic_account_id.id} action['domain'] = [('account_id', '=', self.analytic_account_id.id)] return action def action_view_all_rating(self): """ return the action to see all the rating of the project and activate default filters""" - action = self.env['ir.actions.act_window'].for_xml_id('project', 'rating_rating_action_view_project_rating') + action = self.env['ir.actions.act_window']._for_xml_id('project.rating_rating_action_view_project_rating') action['name'] = _('Ratings of %s') % (self.name,) action_context = ast.literal_eval(action['context']) if action['context'] else {} action_context.update(self._context) @@ -1320,7 +1322,7 @@ class Task(models.Model): } def action_subtask(self): - action = self.env.ref('project.project_task_action_sub_task').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("project.project_task_action_sub_task") # display all subtasks of current task action['domain'] = [('id', 'child_of', self.id), ('id', '!=', self.id)] diff --git a/addons/project/wizard/project_delete_wizard.py b/addons/project/wizard/project_delete_wizard.py index 7289de88687..9dff0454549 100644 --- a/addons/project/wizard/project_delete_wizard.py +++ b/addons/project/wizard/project_delete_wizard.py @@ -25,4 +25,4 @@ class ProjectDelete(models.TransientModel): def confirm_delete(self): self.with_context(active_test=False).project_ids.unlink() - return self.env.ref('project.open_view_project_all_config').read()[0] + return self.env["ir.actions.actions"]._for_xml_id("project.open_view_project_all_config") diff --git a/addons/project/wizard/project_task_type_delete.py b/addons/project/wizard/project_task_type_delete.py index 4e8f8f4e20e..7efbd55df57 100644 --- a/addons/project/wizard/project_task_type_delete.py +++ b/addons/project/wizard/project_task_type_delete.py @@ -55,16 +55,16 @@ class ProjectTaskTypeDelete(models.TransientModel): project_id = self.env.context.get('default_project_id') if project_id: - action = self.env.ref('project.action_view_task').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("project.action_view_task") action['domain'] = [('project_id', '=', project_id)] action['context'] = str({ 'pivot_row_groupby': ['user_id'], 'default_project_id': project_id, }) elif self.env.context.get('stage_view'): - action = self.env.ref('project.open_task_type_form').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("project.open_task_type_form") else: - action = self.env.ref('project.action_view_all_task').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("project.action_view_all_task") context = dict(ast.literal_eval(action.get('context')), active_test=True) action['context'] = context diff --git a/addons/purchase/models/product.py b/addons/purchase/models/product.py index 9c53328324a..bb5817086c9 100644 --- a/addons/purchase/models/product.py +++ b/addons/purchase/models/product.py @@ -40,7 +40,7 @@ class ProductTemplate(models.Model): return res def action_view_po(self): - action = self.env.ref('purchase.action_purchase_order_report_all').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("purchase.action_purchase_order_report_all") action['domain'] = ['&', ('state', 'in', ['purchase', 'done']), ('product_tmpl_id', 'in', self.ids)] action['context'] = { 'graph_measure': 'qty_ordered', @@ -71,7 +71,7 @@ class ProductProduct(models.Model): product.purchased_product_qty = float_round(purchased_data.get(product.id, 0), precision_rounding=product.uom_id.rounding) def action_view_po(self): - action = self.env.ref('purchase.action_purchase_order_report_all').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("purchase.action_purchase_order_report_all") action['domain'] = ['&', ('state', 'in', ['purchase', 'done']), ('product_id', 'in', self.ids)] action['context'] = { 'graph_measure': 'qty_ordered', diff --git a/addons/purchase/models/purchase.py b/addons/purchase/models/purchase.py index 1a2f9539cdf..4cf42269166 100644 --- a/addons/purchase/models/purchase.py +++ b/addons/purchase/models/purchase.py @@ -555,7 +555,7 @@ class PurchaseOrder(models.Model): self.sudo()._read(['invoice_ids']) invoices = self.invoice_ids - action = self.env.ref('account.action_move_in_invoice_type') + action = self.env.ref('account.action_move_in_invoice_type').sudo() result = action.read()[0] # choose the view_mode accordingly if len(invoices) > 1: diff --git a/addons/purchase_stock/models/stock.py b/addons/purchase_stock/models/stock.py index 1b70a05954c..0577d5a10f4 100644 --- a/addons/purchase_stock/models/stock.py +++ b/addons/purchase_stock/models/stock.py @@ -272,7 +272,7 @@ class ProductionLot(models.Model): def action_view_po(self): self.ensure_one() - action = self.env.ref('purchase.purchase_form_action').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("purchase.purchase_form_action") action['domain'] = [('id', 'in', self.mapped('purchase_order_ids.id'))] action['context'] = dict(self._context, create=False) return action diff --git a/addons/sale/models/product_product.py b/addons/sale/models/product_product.py index 2808b3034e1..f530fdf89d7 100644 --- a/addons/sale/models/product_product.py +++ b/addons/sale/models/product_product.py @@ -35,7 +35,7 @@ class ProductProduct(models.Model): return r def action_view_sales(self): - action = self.env.ref('sale.report_all_channels_sales_action').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("sale.report_all_channels_sales_action") action['domain'] = [('product_id', 'in', self.ids)] action['context'] = { 'pivot_measures': ['product_uom_qty'], diff --git a/addons/sale/models/product_template.py b/addons/sale/models/product_template.py index 005bf32a071..4f4e31f3515 100644 --- a/addons/sale/models/product_template.py +++ b/addons/sale/models/product_template.py @@ -77,7 +77,7 @@ class ProductTemplate(models.Model): 'shared product.') % (target_company.name, ', '.join(used_products))) def action_view_sales(self): - action = self.env.ref('sale.report_all_channels_sales_action').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("sale.report_all_channels_sales_action") action['domain'] = [('product_tmpl_id', 'in', self.ids)] action['context'] = { 'pivot_measures': ['product_uom_qty'], diff --git a/addons/sale/models/res_company.py b/addons/sale/models/res_company.py index 406b7dc9982..f75a010cb3d 100644 --- a/addons/sale/models/res_company.py +++ b/addons/sale/models/res_company.py @@ -33,7 +33,7 @@ class ResCompany(models.Model): def action_open_sale_onboarding_payment_acquirer(self): """ Called by onboarding panel above the quotation list.""" self.env.company.get_chart_of_accounts_or_fail() - action = self.env.ref('sale.action_open_sale_onboarding_payment_acquirer_wizard').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("sale.action_open_sale_onboarding_payment_acquirer_wizard") return action def _get_sample_sales_order(self): @@ -94,7 +94,7 @@ class ResCompany(models.Model): self.action_close_sale_quotation_onboarding() - action = self.env.ref('sale.action_orders').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("sale.action_orders") action.update({ 'views': [[self.env.ref('sale.view_order_form').id, 'form']], 'view_mode': 'form', diff --git a/addons/sale/models/sale.py b/addons/sale/models/sale.py index cb9e5b0fb96..00966eef9a1 100644 --- a/addons/sale/models/sale.py +++ b/addons/sale/models/sale.py @@ -570,7 +570,7 @@ class SaleOrder(models.Model): def action_view_invoice(self): invoices = self.mapped('invoice_ids') - action = self.env.ref('account.action_move_out_invoice_type').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("account.action_move_out_invoice_type") if len(invoices) > 1: action['domain'] = [('id', 'in', invoices.ids)] elif len(invoices) == 1: diff --git a/addons/sale/models/sales_team.py b/addons/sale/models/sales_team.py index da500582a2b..9e592561f89 100644 --- a/addons/sale/models/sales_team.py +++ b/addons/sale/models/sales_team.py @@ -130,7 +130,7 @@ class CrmTeam(models.Model): def action_primary_channel_button(self): if self._context.get('in_sales_app'): - return self.env.ref('sale.action_order_report_so_salesteam').read()[0] + return self.env["ir.actions.actions"]._for_xml_id("sale.action_order_report_so_salesteam") return super(CrmTeam, self).action_primary_channel_button() def update_invoiced_target(self, value): diff --git a/addons/sale/models/utm.py b/addons/sale/models/utm.py index 7e3ad525df2..1eec837aa90 100644 --- a/addons/sale/models/utm.py +++ b/addons/sale/models/utm.py @@ -46,13 +46,13 @@ class UtmCampaign(models.Model): campaign.invoiced_amount = 0 def action_redirect_to_quotations(self): - action = self.env.ref('sale.action_quotations_with_onboarding').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("sale.action_quotations_with_onboarding") action['domain'] = [('campaign_id', '=', self.id)] action['context'] = {'default_campaign_id': self.id} return action def action_redirect_to_invoiced(self): - action = self.env.ref('account.action_move_journal_line').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("account.action_move_journal_line") invoices = self.env['account.move'].search([('campaign_id', '=', self.id)]) action['context'] = { 'create': False, diff --git a/addons/sale_crm/models/crm_lead.py b/addons/sale_crm/models/crm_lead.py index 1c44088bece..59439949a01 100644 --- a/addons/sale_crm/models/crm_lead.py +++ b/addons/sale_crm/models/crm_lead.py @@ -34,12 +34,12 @@ class CrmLead(models.Model): def action_sale_quotations_new(self): if not self.partner_id: - return self.env.ref("sale_crm.crm_quotation_partner_action").read()[0] + return self.env["ir.actions.actions"]._for_xml_id("sale_crm.crm_quotation_partner_action") else: return self.action_new_quotation() def action_new_quotation(self): - action = self.env.ref("sale_crm.sale_action_quotations_new").read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("sale_crm.sale_action_quotations_new") action['context'] = { 'search_default_opportunity_id': self.id, 'default_opportunity_id': self.id, @@ -56,7 +56,7 @@ class CrmLead(models.Model): return action def action_view_sale_quotation(self): - action = self.env.ref('sale.action_quotations_with_onboarding').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("sale.action_quotations_with_onboarding") action['context'] = { 'search_default_draft': 1, 'search_default_partner_id': self.partner_id.id, @@ -71,7 +71,7 @@ class CrmLead(models.Model): return action def action_view_sale_order(self): - action = self.env.ref('sale.action_orders').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("sale.action_orders") action['context'] = { 'search_default_partner_id': self.partner_id.id, 'default_partner_id': self.partner_id.id, diff --git a/addons/sale_crm/models/crm_team.py b/addons/sale_crm/models/crm_team.py index 8aa03ec32d8..438d9f08575 100644 --- a/addons/sale_crm/models/crm_team.py +++ b/addons/sale_crm/models/crm_team.py @@ -15,7 +15,7 @@ class CrmTeam(models.Model): def action_primary_channel_button(self): if self._context.get('in_sales_app') and self.use_opportunities: - return self.env.ref('sale.action_order_report_so_salesteam').read()[0] + return self.env["ir.actions.actions"]._for_xml_id("sale.action_order_report_so_salesteam") return super(CrmTeam,self).action_primary_channel_button() def _graph_get_model(self): diff --git a/addons/sale_project/models/project.py b/addons/sale_project/models/project.py index d2834b4105a..9cc79509f71 100644 --- a/addons/sale_project/models/project.py +++ b/addons/sale_project/models/project.py @@ -134,7 +134,7 @@ class ProjectTask(models.Model): so_to_confirm.action_confirm() # redirect create invoice wizard (of the Sales Order) - action = self.env.ref('sale.action_view_sale_advance_payment_inv').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("sale.action_view_sale_advance_payment_inv") context = literal_eval(action.get('context', "{}")) context.update({ 'active_id': self.sale_order_id.id if len(self) == 1 else False, diff --git a/addons/sale_project/models/sale_order.py b/addons/sale_project/models/sale_order.py index 44885e0b71a..b9bb84afa90 100644 --- a/addons/sale_project/models/sale_order.py +++ b/addons/sale_project/models/sale_order.py @@ -72,7 +72,7 @@ class SaleOrder(models.Model): eval_context.update({'active_id': task_projects.id}) action['context'] = safe_eval(action['context'], eval_context) else: - action = self.env.ref('project.action_view_task').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("project.action_view_task") action['context'] = {} # erase default context to avoid default filter if len(self.tasks_ids) > 1: # cross project kanban task action['views'] = [[False, 'kanban'], [list_view_id, 'tree'], [form_view_id, 'form'], [False, 'graph'], [False, 'calendar'], [False, 'pivot']] diff --git a/addons/sale_stock/models/sale_order.py b/addons/sale_stock/models/sale_order.py index 03edef1412b..4e8dbee574d 100644 --- a/addons/sale_stock/models/sale_order.py +++ b/addons/sale_stock/models/sale_order.py @@ -180,7 +180,7 @@ class SaleOrder(models.Model): of given sales order ids. It can either be a in a list or in a form view, if there is only one delivery order to show. ''' - action = self.env.ref('stock.action_picking_tree_all').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("stock.action_picking_tree_all") pickings = self.mapped('picking_ids') if len(pickings) > 1: diff --git a/addons/sale_stock/models/stock.py b/addons/sale_stock/models/stock.py index e1d36c38f7d..9fd4787db8a 100644 --- a/addons/sale_stock/models/stock.py +++ b/addons/sale_stock/models/stock.py @@ -135,7 +135,7 @@ class ProductionLot(models.Model): def action_view_so(self): self.ensure_one() - action = self.env.ref('sale.action_orders').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("sale.action_orders") action['domain'] = [('id', 'in', self.mapped('sale_order_ids.id'))] action['context'] = dict(self._context, create=False) return action diff --git a/addons/sale_timesheet/models/project.py b/addons/sale_timesheet/models/project.py index 0354d95276f..5c66df9526f 100644 --- a/addons/sale_timesheet/models/project.py +++ b/addons/sale_timesheet/models/project.py @@ -132,7 +132,7 @@ class Project(models.Model): } def action_view_timesheet_plan(self): - action = self.env.ref('sale_timesheet.project_timesheet_action_client_timesheet_plan').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("sale_timesheet.project_timesheet_action_client_timesheet_plan") action['params'] = { 'project_ids': self.ids, } diff --git a/addons/sale_timesheet/models/project_overview.py b/addons/sale_timesheet/models/project_overview.py index e8052912d8c..dcaba19bc5d 100644 --- a/addons/sale_timesheet/models/project_overview.py +++ b/addons/sale_timesheet/models/project_overview.py @@ -542,7 +542,7 @@ def _to_action_data(model=None, *, action=None, views=None, res_id=None, domain= # pass in either action or (model, views) if action: assert model is None and views is None - act = clean_action(action.read()[0]) + act = clean_action(action.read()[0], env=action.env) model = act['res_model'] views = act['views'] # FIXME: search-view-id, possibly help? diff --git a/addons/sale_timesheet/models/sale_order.py b/addons/sale_timesheet/models/sale_order.py index 365118bdeb0..f4b47ebc552 100644 --- a/addons/sale_timesheet/models/sale_order.py +++ b/addons/sale_timesheet/models/sale_order.py @@ -52,7 +52,7 @@ class SaleOrder(models.Model): def action_view_timesheet(self): self.ensure_one() - action = self.env.ref('sale_timesheet.timesheet_action_from_sales_order').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("sale_timesheet.timesheet_action_from_sales_order") action['context'] = {} # erase default filters if self.timesheet_count > 0: action['domain'] = [('so_line', 'in', self.order_line.ids)] diff --git a/addons/sale_timesheet/wizard/project_create_invoice.py b/addons/sale_timesheet/wizard/project_create_invoice.py index 54b964a54f0..b1da206802d 100644 --- a/addons/sale_timesheet/wizard/project_create_invoice.py +++ b/addons/sale_timesheet/wizard/project_create_invoice.py @@ -51,7 +51,7 @@ class ProjectCreateInvoice(models.TransientModel): def action_create_invoice(self): if not self.sale_order_id and self.sale_order_id.invoice_status != 'to invoice': raise UserError(_("The selected Sales Order should contain something to invoice.")) - action = self.env.ref('sale.action_view_sale_advance_payment_inv').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("sale.action_view_sale_advance_payment_inv") action['context'] = { 'active_ids': self.sale_order_id.ids } diff --git a/addons/sale_timesheet/wizard/project_create_sale_order.py b/addons/sale_timesheet/wizard/project_create_sale_order.py index aad2648a0d0..89abafe8335 100644 --- a/addons/sale_timesheet/wizard/project_create_sale_order.py +++ b/addons/sale_timesheet/wizard/project_create_sale_order.py @@ -75,7 +75,7 @@ class ProjectCreateSalesOrder(models.TransientModel): sale_order = self._create_sale_order() view_form_id = self.env.ref('sale.view_order_form').id - action = self.env.ref('sale.action_orders').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("sale.action_orders") action.update({ 'views': [(view_form_id, 'form')], 'view_mode': 'form', diff --git a/addons/sale_timesheet/wizard/project_task_create_sale_order.py b/addons/sale_timesheet/wizard/project_task_create_sale_order.py index ffabb0ac9c7..9558974aae8 100644 --- a/addons/sale_timesheet/wizard/project_task_create_sale_order.py +++ b/addons/sale_timesheet/wizard/project_task_create_sale_order.py @@ -44,7 +44,7 @@ class ProjectTaskCreateSalesOrder(models.TransientModel): sale_order = self._prepare_sale_order() sale_order.action_confirm() view_form_id = self.env.ref('sale.view_order_form').id - action = self.env.ref('sale.action_orders').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("sale.action_orders") action.update({ 'views': [(view_form_id, 'form')], 'view_mode': 'form', diff --git a/addons/stock/models/product.py b/addons/stock/models/product.py index cf78e64024d..e937f070ac0 100644 --- a/addons/stock/models/product.py +++ b/addons/stock/models/product.py @@ -431,7 +431,7 @@ class Product(models.Model): return res def action_view_orderpoints(self): - action = self.env.ref('stock.action_orderpoint').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("stock.action_orderpoint") action['context'] = literal_eval(action.get('context')) action['context'].pop('search_default_trigger', False) action['context'].update({ @@ -451,7 +451,7 @@ class Product(models.Model): def action_view_stock_move_lines(self): self.ensure_one() - action = self.env.ref('stock.stock_move_line_action').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("stock.stock_move_line_action") action['domain'] = [('product_id', '=', self.id)] return action @@ -466,7 +466,7 @@ class Product(models.Model): def action_open_product_lot(self): self.ensure_one() - action = self.env.ref('stock.action_production_lot_form').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("stock.action_production_lot_form") action['domain'] = [('product_id', '=', self.id)] action['context'] = { 'default_product_id': self.id, @@ -513,7 +513,7 @@ class Product(models.Model): def action_product_forecast_report(self): self.ensure_one() - action = self.env.ref('stock.stock_replenishment_product_product_action').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("stock.stock_replenishment_product_product_action") return action @api.model @@ -758,7 +758,7 @@ class ProductTemplate(models.Model): return self.action_open_quants() else: default_product_id = len(self.product_variant_ids) == 1 and self.product_variant_id.id - action = self.env.ref('stock.action_change_product_quantity').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("stock.action_change_product_quantity") action['context'] = dict( self.env.context, default_product_id=default_product_id, @@ -780,13 +780,13 @@ class ProductTemplate(models.Model): def action_view_stock_move_lines(self): self.ensure_one() - action = self.env.ref('stock.stock_move_line_action').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("stock.stock_move_line_action") action['domain'] = [('product_id.product_tmpl_id', 'in', self.ids)] return action def action_open_product_lot(self): self.ensure_one() - action = self.env.ref('stock.action_production_lot_form').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("stock.action_production_lot_form") action['domain'] = [('product_id.product_tmpl_id', '=', self.id)] action['context'] = { 'default_product_tmpl_id': self.id, @@ -811,13 +811,13 @@ class ProductTemplate(models.Model): 'product_id': products.id, 'warehouse_ids': warehouse.ids, }, config=False) - action = self.env.ref('stock.action_stock_rules_report').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("stock.action_stock_rules_report") action['context'] = self.env.context return action def action_product_tmpl_forecast_report(self): self.ensure_one() - action = self.env.ref('stock.stock_replenishment_product_product_action').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id('stock.stock_replenishment_product_product_action') return action class ProductCategory(models.Model): diff --git a/addons/stock/models/stock_move.py b/addons/stock/models/stock_move.py index 782683e6462..5709abe0f9e 100644 --- a/addons/stock/models/stock_move.py +++ b/addons/stock/models/stock_move.py @@ -673,7 +673,7 @@ class StockMove(models.Model): """ Opens a wizard to assign SN's name on each move lines. """ self.ensure_one() - action = self.env.ref('stock.act_assign_serial_numbers').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("stock.act_assign_serial_numbers") action['context'] = { 'default_product_id': self.product_id.id, 'default_move_id': self.id, diff --git a/addons/stock/models/stock_orderpoint.py b/addons/stock/models/stock_orderpoint.py index 95de53d45db..f6835d863e7 100644 --- a/addons/stock/models/stock_orderpoint.py +++ b/addons/stock/models/stock_orderpoint.py @@ -291,7 +291,7 @@ class StockWarehouseOrderpoint(models.Model): return replenish report ir.actions.act_window """ - action = self.env.ref('stock.action_orderpoint_replenish').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("stock.action_orderpoint_replenish") action['context'] = self.env.context orderpoints = self.env['stock.warehouse.orderpoint'].search([]) # Remove previous automatically created orderpoint that has been refilled. diff --git a/addons/stock/models/stock_picking.py b/addons/stock/models/stock_picking.py index f4a6a8c6bc2..a9b50f93168 100644 --- a/addons/stock/models/stock_picking.py +++ b/addons/stock/models/stock_picking.py @@ -200,7 +200,7 @@ class PickingType(models.Model): self.show_reserved = True def _get_action(self, action_xmlid): - action = self.env.ref(action_xmlid).read()[0] + action = self.env["ir.actions.actions"]._for_xml_id(action_xmlid) if self: action['display_name'] = self.display_name @@ -1365,7 +1365,7 @@ class Picking(models.Model): def action_see_move_scrap(self): self.ensure_one() - action = self.env.ref('stock.action_stock_scrap').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("stock.action_stock_scrap") scraps = self.env['stock.scrap'].search([('picking_id', '=', self.id)]) action['domain'] = [('id', 'in', scraps.ids)] action['context'] = dict(self._context, create=False) @@ -1373,14 +1373,14 @@ class Picking(models.Model): def action_see_packages(self): self.ensure_one() - action = self.env.ref('stock.action_package_view').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("stock.action_package_view") packages = self.move_line_ids.mapped('result_package_id') action['domain'] = [('id', 'in', packages.ids)] action['context'] = {'picking_id': self.id} return action def action_picking_move_tree(self): - action = self.env.ref('stock.stock_move_action').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("stock.stock_move_action") action['views'] = [ (self.env.ref('stock.view_picking_move_tree').id, 'tree'), ] diff --git a/addons/stock/models/stock_quant.py b/addons/stock/models/stock_quant.py index 78cb6166f24..b21a2c362fc 100644 --- a/addons/stock/models/stock_quant.py +++ b/addons/stock/models/stock_quant.py @@ -202,7 +202,7 @@ class StockQuant(models.Model): def action_view_stock_moves(self): self.ensure_one() - action = self.env.ref('stock.stock_move_line_action').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("stock.stock_move_line_action") action['domain'] = [ ('product_id', '=', self.product_id.id), '|', @@ -718,7 +718,7 @@ class QuantPackage(models.Model): self.env['stock.quant']._unlink_zero_quants() def action_view_picking(self): - action = self.env.ref('stock.action_picking_tree_all').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("stock.action_picking_tree_all") domain = ['|', ('result_package_id', 'in', self.ids), ('package_id', 'in', self.ids)] pickings = self.env['stock.move.line'].search(domain).mapped('picking_id') action['domain'] = [('id', 'in', pickings.ids)] diff --git a/addons/stock_account/models/stock_picking.py b/addons/stock_account/models/stock_picking.py index 4169320109a..df5a3e07c6a 100644 --- a/addons/stock_account/models/stock_picking.py +++ b/addons/stock_account/models/stock_picking.py @@ -13,7 +13,7 @@ class StockPicking(models.Model): self.ensure_one() scraps = self.env['stock.scrap'].search([('picking_id', '=', self.id)]) domain = [('id', 'in', (self.move_lines + scraps.move_id).stock_valuation_layer_ids.ids)] - action = self.env.ref('stock_account.stock_valuation_layer_action').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("stock_account.stock_valuation_layer_action") context = literal_eval(action['context']) context.update(self.env.context) context['no_at_date'] = True diff --git a/addons/stock_account/wizard/stock_quantity_history.py b/addons/stock_account/wizard/stock_quantity_history.py index b8e275ba9f6..8897a329628 100644 --- a/addons/stock_account/wizard/stock_quantity_history.py +++ b/addons/stock_account/wizard/stock_quantity_history.py @@ -9,7 +9,7 @@ class StockQuantityHistory(models.TransientModel): def open_at_date(self): active_model = self.env.context.get('active_model') if active_model == 'stock.valuation.layer': - action = self.env.ref('stock_account.stock_valuation_layer_action').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("stock_account.stock_valuation_layer_action") action['domain'] = [('create_date', '<=', self.inventory_datetime)] action['display_name'] = str(self.inventory_datetime) return action diff --git a/addons/stock_landed_costs/models/account_move.py b/addons/stock_landed_costs/models/account_move.py index e792c9512ab..72c1b6b05e2 100644 --- a/addons/stock_landed_costs/models/account_move.py +++ b/addons/stock_landed_costs/models/account_move.py @@ -35,12 +35,12 @@ class AccountMove(models.Model): 'split_method': 'equal', }) for l in landed_costs_lines], }) - action = self.env.ref('stock_landed_costs.action_stock_landed_cost').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("stock_landed_costs.action_stock_landed_cost") return dict(action, view_mode='form', res_id=landed_costs.id, views=[(False, 'form')]) def action_view_landed_costs(self): self.ensure_one() - action = self.env.ref('stock_landed_costs.action_stock_landed_cost').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("stock_landed_costs.action_stock_landed_cost") domain = [('id', 'in', self.landed_costs_ids.ids)] context = dict(self.env.context, default_vendor_bill_id=self.id) views = [(self.env.ref('stock_landed_costs.view_stock_landed_cost_tree2').id, 'tree'), (False, 'form'), (False, 'kanban')] diff --git a/addons/stock_landed_costs/models/stock_landed_cost.py b/addons/stock_landed_costs/models/stock_landed_cost.py index 1e975f323cf..a3484f18ea4 100644 --- a/addons/stock_landed_costs/models/stock_landed_cost.py +++ b/addons/stock_landed_costs/models/stock_landed_cost.py @@ -273,7 +273,7 @@ class StockLandedCost(models.Model): def action_view_stock_valuation_layers(self): self.ensure_one() domain = [('id', 'in', self.stock_valuation_layer_ids.ids)] - action = self.env.ref('stock_account.stock_valuation_layer_action').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("stock_account.stock_valuation_layer_action") return dict(action, domain=domain) def _get_targeted_move_ids(self): diff --git a/addons/survey/models/res_partner.py b/addons/survey/models/res_partner.py index 93161222c12..1c7a5e1ec6c 100644 --- a/addons/survey/models/res_partner.py +++ b/addons/survey/models/res_partner.py @@ -25,7 +25,7 @@ class ResPartner(models.Model): self.certifications_company_count = sum(child.certifications_count for child in self.child_ids) def action_view_certifications(self): - action = self.env.ref('survey.res_partner_action_certifications').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("survey.res_partner_action_certifications") action['view_mode'] = 'tree' action['domain'] = ['|', ('partner_id', 'in', self.ids), ('partner_id', 'in', self.child_ids.ids)] diff --git a/addons/test_mail_full/tests/test_sms_server_actions.py b/addons/test_mail_full/tests/test_sms_server_actions.py index e44cb6847a4..869a61c48a0 100644 --- a/addons/test_mail_full/tests/test_sms_server_actions.py +++ b/addons/test_mail_full/tests/test_sms_server_actions.py @@ -25,6 +25,7 @@ class TestServerAction(TestMailFullCommon, TestRecipients): 'model_id': cls.env['ir.model']._get('mail.test.sms').id, 'state': 'sms', 'sms_template_id': cls.sms_template.id, + 'groups_id': cls.env.ref('base.group_user'), }) def test_action_sms(self): diff --git a/addons/web/controllers/main.py b/addons/web/controllers/main.py index 6e5bd95432c..1907064bd6b 100644 --- a/addons/web/controllers/main.py +++ b/addons/web/controllers/main.py @@ -324,12 +324,18 @@ def set_cookie_and_redirect(redirect_url): redirect.autocorrect_location_header = False return redirect -def clean_action(action): +def clean_action(action, env): action.setdefault('flags', {}) action_type = action.setdefault('type', 'ir.actions.act_window_close') if action_type == 'ir.actions.act_window': - return fix_view_modes(action) - return action + action = fix_view_modes(action) + + # When returning an action, only few information are really usefull + return { + field: value + for field, value in action.items() + if field in env[action['type']]._get_readable_fields() + } # I think generate_views,fix_view_modes should go into js ActionManager def generate_views(action): @@ -1357,7 +1363,7 @@ class DataSet(http.Controller): def call_button(self, model, method, args, kwargs): action = self._call_kw(model, method, args, kwargs) if isinstance(action, dict) and action.get('type') != '': - return clean_action(action) + return clean_action(action, env=request.env) return False @http.route('/web/dataset/resequence', type='json', auth="user") @@ -1687,7 +1693,7 @@ class Action(http.Controller): except Exception: action_id = 0 # force failed read - base_action = Actions.browse([action_id]).read(['type']) + base_action = Actions.browse([action_id]).sudo().read(['type']) if base_action: ctx = dict(request.context) action_type = base_action[0]['type'] @@ -1696,15 +1702,16 @@ class Action(http.Controller): if additional_context: ctx.update(additional_context) request.context = ctx - action = request.env[action_type].browse([action_id]).read() + action = request.env[action_type].sudo().browse([action_id]).read() if action: - value = clean_action(action[0]) + value = clean_action(action[0], env=request.env) return value @http.route('/web/action/run', type='json', auth="user") def run(self, action_id): - result = request.env['ir.actions.server'].browse([action_id]).run() - return clean_action(result) if result else False + action = request.env['ir.actions.server'].browse([action_id]) + result = action.run() + return clean_action(result, env=action.env) if result else False class Export(http.Controller): diff --git a/addons/website/models/res_company.py b/addons/website/models/res_company.py index 7f89720aa91..ae1ff1f5696 100644 --- a/addons/website/models/res_company.py +++ b/addons/website/models/res_company.py @@ -10,7 +10,7 @@ class Company(models.Model): @api.model def action_open_website_theme_selector(self): - action = self.env.ref('website.theme_install_kanban_action').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("website.theme_install_kanban_action") action['target'] = 'new' return action @@ -25,7 +25,7 @@ class Company(models.Model): def _compute_website_theme_onboarding_done(self): """ The step is marked as done if one theme is installed. """ # we need the same domain as the existing action - action = self.env.ref('website.theme_install_kanban_action').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("website.theme_install_kanban_action") domain = literal_eval(action['domain']) domain.append(('state', '=', 'installed')) installed_themes_count = self.env['ir.module.module'].sudo().search_count(domain) diff --git a/addons/website/models/res_config_settings.py b/addons/website/models/res_config_settings.py index a90210817e9..e509d237a66 100644 --- a/addons/website/models/res_config_settings.py +++ b/addons/website/models/res_config_settings.py @@ -144,7 +144,7 @@ class ResConfigSettings(models.TransientModel): super(ResConfigSettings, self).set_values() def open_template_user(self): - action = self.env.ref('base.action_res_users').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("base.action_res_users") action['res_id'] = literal_eval(self.env['ir.config_parameter'].sudo().get_param('base.template_portal_user_id', 'False')) action['views'] = [[self.env.ref('base.view_users_form').id, 'form']] return action @@ -189,6 +189,6 @@ class ResConfigSettings(models.TransientModel): def install_theme_on_current_website(self): self.website_id._force() - action = self.env.ref('website.theme_install_kanban_action').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("website.theme_install_kanban_action") action['target'] = 'main' return action diff --git a/addons/website/models/website.py b/addons/website/models/website.py index 3e810dfa729..60605f6a5c4 100644 --- a/addons/website/models/website.py +++ b/addons/website/models/website.py @@ -905,8 +905,8 @@ class Website(models.Model): @api.model def action_dashboard_redirect(self): if self.env.user.has_group('base.group_system') or self.env.user.has_group('website.group_website_designer'): - return self.env.ref('website.backend_dashboard').read()[0] - return self.env.ref('website.action_website').read()[0] + return self.env["ir.actions.actions"]._for_xml_id("website.backend_dashboard") + return self.env["ir.actions.actions"]._for_xml_id("website.action_website") def button_go_website(self): self._force() diff --git a/addons/website/views/website_views.xml b/addons/website/views/website_views.xml index 970aa309523..e6ad38088ae 100644 --- a/addons/website/views/website_views.xml +++ b/addons/website/views/website_views.xml @@ -317,13 +317,15 @@ code action = model.action_dashboard_redirect() + - Website: Dashboard + Website: Analytics code - action = model.env.ref('website.backend_dashboard').read()[0] + action = model.env.ref('website.backend_dashboard').sudo().read()[0] + diff --git a/addons/website_crm/models/crm_lead.py b/addons/website_crm/models/crm_lead.py index 4e62f808870..0ea63e3b4b1 100644 --- a/addons/website_crm/models/crm_lead.py +++ b/addons/website_crm/models/crm_lead.py @@ -28,7 +28,7 @@ class Lead(models.Model): def action_redirect_to_page_views(self): visitors = self.visitor_ids - action = self.env.ref('website.website_visitor_page_action').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("website.website_visitor_page_action") action['domain'] = [('visitor_id', 'in', visitors.ids)] # avoid grouping if only few records if len(visitors.website_track_ids.ids) > 15 and len(visitors.page_ids.ids) > 1: diff --git a/addons/website_crm_livechat/models/crm_lead.py b/addons/website_crm_livechat/models/crm_lead.py index 1b31eaa3a3f..1b2622aa8a8 100644 --- a/addons/website_crm_livechat/models/crm_lead.py +++ b/addons/website_crm_livechat/models/crm_lead.py @@ -16,6 +16,6 @@ class Lead(models.Model): def action_redirect_to_livechat_sessions(self): visitors = self.visitor_ids - action = self.env.ref('website_livechat.website_visitor_livechat_session_action').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("website_livechat.website_visitor_livechat_session_action") action['domain'] = [('livechat_visitor_id', 'in', visitors.ids), ('channel_message_ids', '!=', False)] return action diff --git a/addons/website_event_questions/models/event_question.py b/addons/website_event_questions/models/event_question.py index 0eee8eef37b..4d058569d4c 100644 --- a/addons/website_event_questions/models/event_question.py +++ b/addons/website_event_questions/models/event_question.py @@ -46,7 +46,7 @@ class EventQuestion(models.Model): (Along with secondary pivot and tree views) - A tree view showing textual answers values for text_box questions. """ self.ensure_one() - action = self.env.ref('website_event_questions.action_event_registration_report').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("website_event_questions.action_event_registration_report") action['domain'] = [('question_id', '=', self.id)] if self.question_type == 'simple_choice': action['views'] = [(False, 'graph'), (False, 'pivot'), (False, 'tree')] diff --git a/addons/website_sale/models/res_company.py b/addons/website_sale/models/res_company.py index d0bce9b1121..9326af678a6 100644 --- a/addons/website_sale/models/res_company.py +++ b/addons/website_sale/models/res_company.py @@ -13,5 +13,5 @@ class ResCompany(models.Model): def action_open_website_sale_onboarding_payment_acquirer(self): """ Called by onboarding panel above the quotation list.""" self.env.company.get_chart_of_accounts_or_fail() - action = self.env.ref('website_sale.action_open_website_sale_onboarding_payment_acquirer_wizard').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("website_sale.action_open_website_sale_onboarding_payment_acquirer_wizard") return action diff --git a/addons/website_sale/models/website.py b/addons/website_sale/models/website.py index a34f73dfcd8..2f8b4ec6a22 100644 --- a/addons/website_sale/models/website.py +++ b/addons/website_sale/models/website.py @@ -364,7 +364,7 @@ class Website(models.Model): @api.model def action_dashboard_redirect(self): if self.env.user.has_group('sales_team.group_sale_salesman'): - return self.env.ref('website.backend_dashboard').read()[0] + return self.env["ir.actions.actions"]._for_xml_id("website.backend_dashboard") return super(Website, self).action_dashboard_redirect() def get_suggested_controllers(self): diff --git a/addons/website_sale_slides/models/slide_channel.py b/addons/website_sale_slides/models/slide_channel.py index ee288fb8b64..fd6ea6d1f37 100644 --- a/addons/website_sale_slides/models/slide_channel.py +++ b/addons/website_sale_slides/models/slide_channel.py @@ -51,7 +51,7 @@ class Channel(models.Model): self.filtered(lambda channel: not channel.is_published and channel.product_id.is_published).sudo().product_id.write({'is_published': False}) def action_view_sales(self): - action = self.env.ref('website_sale_slides.sale_report_action_slides').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("website_sale_slides.sale_report_action_slides") action['domain'] = [('product_id', 'in', self.product_id.ids)] return action diff --git a/addons/website_slides/models/res_partner.py b/addons/website_slides/models/res_partner.py index fb2aff8dc9e..a36b23227c8 100644 --- a/addons/website_slides/models/res_partner.py +++ b/addons/website_slides/models/res_partner.py @@ -34,7 +34,7 @@ class ResPartner(models.Model): partner.slide_channel_company_count = 0 def action_view_courses(self): - action = self.env.ref('website_slides.slide_channel_action_overview').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("website_slides.slide_channel_action_overview") action['name'] = _('Followed Courses') action['domain'] = ['|', ('partner_ids', 'in', self.ids), ('partner_ids', 'in', self.child_ids.ids)] return action diff --git a/addons/website_slides/models/slide_channel.py b/addons/website_slides/models/slide_channel.py index fc9af7d1812..1479a51722d 100644 --- a/addons/website_slides/models/slide_channel.py +++ b/addons/website_slides/models/slide_channel.py @@ -453,7 +453,7 @@ class Channel(models.Model): # --------------------------------------------------------- def action_redirect_to_members(self, state=None): - action = self.env.ref('website_slides.slide_channel_partner_action').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("website_slides.slide_channel_partner_action") action['domain'] = [('channel_id', 'in', self.ids)] if len(self) == 1: action['display_name'] = _('Attendees of %s', self.name) @@ -600,7 +600,7 @@ class Channel(models.Model): self.env['slide.channel.partner'].sudo().search(removed_channel_partner_domain).unlink() def action_view_slides(self): - action = self.env.ref('website_slides.slide_slide_action').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("website_slides.slide_slide_action") action['context'] = { 'search_default_published': 1, 'default_channel_id': self.id @@ -609,7 +609,7 @@ class Channel(models.Model): return action def action_view_ratings(self): - action = self.env.ref('website_slides.rating_rating_action_slide_channel').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("website_slides.rating_rating_action_slide_channel") action['name'] = _('Rating of %s') % (self.name) action['domain'] = [('res_id', 'in', self.ids)] return action diff --git a/addons/website_slides_forum/models/slide_channel.py b/addons/website_slides_forum/models/slide_channel.py index fec0d88564c..c45dc14c0d8 100644 --- a/addons/website_slides_forum/models/slide_channel.py +++ b/addons/website_slides_forum/models/slide_channel.py @@ -16,7 +16,7 @@ class Channel(models.Model): def action_redirect_to_forum(self): self.ensure_one() - action = self.env.ref('website_forum.action_forum_post').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("website_forum.action_forum_post") action['view_mode'] = 'tree' action['context'] = { 'create': False diff --git a/addons/website_slides_survey/models/survey_survey.py b/addons/website_slides_survey/models/survey_survey.py index 98dc3e6a776..a5edc7f40e3 100644 --- a/addons/website_slides_survey/models/survey_survey.py +++ b/addons/website_slides_survey/models/survey_survey.py @@ -27,7 +27,7 @@ class Survey(models.Model): # --------------------------------------------------------- def action_survey_view_slide_channels(self): - action = self.env.ref('website_slides.slide_channel_action_overview').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("website_slides.slide_channel_action_overview") action['display_name'] = _("Courses") if self.slide_channel_count == 1: action.update({'views': [(False, 'form')], diff --git a/odoo/addons/base/models/ir_actions.py b/odoo/addons/base/models/ir_actions.py index aea5f3f7b0b..51440593b2f 100644 --- a/odoo/addons/base/models/ir_actions.py +++ b/odoo/addons/base/models/ir_actions.py @@ -117,7 +117,7 @@ class IrActions(models.Model): user_groups = self.env.user.groups_id for action_id, action_model, binding_type in cr.fetchall(): try: - action = self.env[action_model].browse(action_id) + action = self.env[action_model].sudo().browse(action_id) action_groups = getattr(action, 'groups_id', ()) action_model = getattr(action, 'res_model', False) if action_groups and not action_groups & user_groups: @@ -135,6 +135,38 @@ class IrActions(models.Model): result['action'] = sorted(result['action'], key=lambda vals: vals.get('sequence', 0)) return result + @api.model + def _for_xml_id(self, full_xml_id): + """ Returns the action content for the provided xml_id + + :param module: the module the act_window originates in + :param xml_id: the namespace-less id of the action (the @id + attribute from the XML file) + :return: A read() view of the ir.actions.action safe for web use + """ + record = self.env.ref(full_xml_id) + assert isinstance(self.env[record._name], type(self)) + # TO CHECK MAT: check groups_id/res_model access? + action = record.sudo().read()[0] + return { + field: value + for field, value in action.items() + if field in record._get_readable_fields() + } + + def _get_readable_fields(self): + """ return the list of fields that are safe to read + + Fetched via /web/action/load or _for_xml_id method + Only fields used by the web client should included + Accessing content useful for the server-side must + be done manually with superuser + """ + return { + "binding_model_id", "binding_type", "binding_view_types", + "display_name", "help", "id", "name", "type", "xml_id", + } + class IrActionsActWindow(models.Model): _name = 'ir.actions.act_window' @@ -232,18 +264,6 @@ class IrActionsActWindow(models.Model): values['help'] = self.with_context(**ctx).env[model].get_empty_list_help(values.get('help', '')) return result - @api.model - def for_xml_id(self, module, xml_id): - """ Returns the act_window object created for the provided xml_id - - :param module: the module the act_window originates in - :param xml_id: the namespace-less id of the action (the @id - attribute from the XML file) - :return: A read() view of the ir.actions.act_window - """ - record = self.env.ref("%s.%s" % (module, xml_id)) - return record.read()[0] - @api.model_create_multi def create(self, vals_list): self.clear_caches() @@ -268,6 +288,14 @@ class IrActionsActWindow(models.Model): return set(row[0] for row in self._cr.fetchall()) + def _get_readable_fields(self): + return super()._get_readable_fields() | { + "context", "domain", "filter", "groups_id", "limit", "res_id", + "res_model", "search_view", "search_view_id", "target", "view_id", + "view_mode", "views", + } + + VIEW_TYPES = [ ('tree', 'Tree'), ('form', 'Form'), @@ -321,6 +349,11 @@ class IrActionsActUrl(models.Model): target = fields.Selection([('new', 'New Window'), ('self', 'This Window')], string='Action Target', default='new', required=True) + def _get_readable_fields(self): + return super()._get_readable_fields() | { + "target", "url", + } + class IrActionsServer(models.Model): """ Server actions model. Server action work on a base model and offer various @@ -421,6 +454,11 @@ class IrActionsServer(models.Model): if not self._check_m2m_recursion('child_ids'): raise ValidationError(_('Recursion found in child server actions')) + def _get_readable_fields(self): + return super()._get_readable_fields() | { + "groups_id", "model_name", + } + def _get_runner(self): multi = True t = type(self) @@ -463,7 +501,7 @@ class IrActionsServer(models.Model): return True def _run_action_code_multi(self, eval_context): - safe_eval(self.sudo().code.strip(), eval_context, mode="exec", nocopy=True) # nocopy allows to return 'action' + safe_eval(self.code.strip(), eval_context, mode="exec", nocopy=True) # nocopy allows to return 'action' return eval_context.get('action') def _run_action_multi(self, eval_context=None): @@ -564,10 +602,19 @@ class IrActionsServer(models.Model): return action """ res = False - for action in self: + for action in self.sudo(): action_groups = action.groups_id - if action_groups and not (action_groups & self.env.user.groups_id): - raise AccessError(_("You don't have enough access rights to run this action.")) + if action_groups: + if not (action_groups & self.env.user.groups_id): + raise AccessError(_("You don't have enough access rights to run this action.")) + else: + try: + self.env[action.model_name].check_access_rights("write") + except AccessError: + _logger.warning("Forbidden server action %r executed while the user %s does not have access to %s.", + action.name, self.env.user.login, action.model_name, + ) + raise eval_context = self._get_eval_context(action) @@ -597,13 +644,6 @@ class IrActionsServer(models.Model): ) return res or False - def _run_actions(self, ids): - """ - Run server actions with given ids. - Allow crons to run specific server actions - """ - return self.browse(ids).run() - class IrServerObjectLines(models.Model): _name = 'ir.server.object.lines' @@ -797,3 +837,9 @@ class IrActionsActClient(models.Model): params_store = doc.find(".//field[@name='params_store']") params_store.getparent().remove(params_store) return doc + + + def _get_readable_fields(self): + return super()._get_readable_fields() | { + "context", "params", "res_model", "tag", "target", + } diff --git a/odoo/addons/base/models/ir_actions_report.py b/odoo/addons/base/models/ir_actions_report.py index 0a927ccacc0..3c9a636184d 100644 --- a/odoo/addons/base/models/ir_actions_report.py +++ b/odoo/addons/base/models/ir_actions_report.py @@ -143,6 +143,11 @@ class IrActionsReport(models.Model): else: return FALSE_DOMAIN + def _get_readable_fields(self): + return super()._get_readable_fields() | { + "params", "report_name", "report_type", "target", + } + def associated_view(self): """Used in the ir.actions.report form view in order to search naively after the view(s) used in the rendering. @@ -489,7 +494,7 @@ class IrActionsReport(models.Model): report_obj = self.env['ir.actions.report'] conditions = [('report_name', '=', report_name)] context = self.env['res.users'].context_get() - return report_obj.with_context(context).search(conditions, limit=1) + return report_obj.with_context(context).sudo().search(conditions, limit=1) @api.model def barcode(self, barcode_type, value, width=600, height=100, humanreadable=0, quiet=1, mask=None): @@ -689,10 +694,13 @@ class IrActionsReport(models.Model): data = {} data.setdefault('report_type', 'pdf') + # access the report details with sudo() but evaluation context as sudo(False) + self_sudo = self.sudo() + # In case of test environment without enough workers to perform calls to wkhtmltopdf, # fallback to render_html. if (tools.config['test_enable'] or tools.config['test_file']) and not self.env.context.get('force_report_rendering'): - return self._render_qweb_html(res_ids, data=data) + return self_sudo._render_qweb_html(res_ids, data=data) # As the assets are generated during the same transaction as the rendering of the # templates calling them, there is a scenario where the assets are unreachable: when @@ -719,21 +727,21 @@ class IrActionsReport(models.Model): # an asset bundle during the execution of test scenarios. In this case, return # the html version. if isinstance(self.env.cr, TestCursor): - return self.with_context(context)._render_qweb_html(res_ids, data=data)[0] + return self_sudo.with_context(context)._render_qweb_html(res_ids, data=data)[0] save_in_attachment = OrderedDict() if res_ids: # Dispatch the records by ones having an attachment and ones requesting a call to # wkhtmltopdf. - Model = self.env[self.model] + Model = self.env[self_sudo.model] record_ids = Model.browse(res_ids) wk_record_ids = Model - if self.attachment: + if self_sudo.attachment: for record_id in record_ids: - attachment = self.retrieve_attachment(record_id) + attachment = self_sudo.retrieve_attachment(record_id) if attachment: - save_in_attachment[record_id.id] = self._retrieve_stream_from_attachment(attachment) - if not self.attachment_use or not attachment: + save_in_attachment[record_id.id] = self_sudo._retrieve_stream_from_attachment(attachment) + if not self_sudo.attachment_use or not attachment: wk_record_ids += record_id else: wk_record_ids = record_ids @@ -744,7 +752,7 @@ class IrActionsReport(models.Model): # - The report is not fully present in attachments. if save_in_attachment and not res_ids: _logger.info('The PDF report has been generated from attachments.') - return self._post_pdf(save_in_attachment), 'pdf' + return self_sudo._post_pdf(save_in_attachment), 'pdf' if self.get_wkhtmltopdf_state() == 'install': # wkhtmltopdf is not installed @@ -753,14 +761,14 @@ class IrActionsReport(models.Model): # bypassed raise UserError(_("Unable to find Wkhtmltopdf on this system. The PDF can not be created.")) - html = self.with_context(context)._render_qweb_html(res_ids, data=data)[0] + html = self_sudo.with_context(context)._render_qweb_html(res_ids, data=data)[0] # Ensure the current document is utf-8 encoded. html = html.decode('utf-8') - bodies, html_ids, header, footer, specific_paperformat_args = self.with_context(context)._prepare_html(html) + bodies, html_ids, header, footer, specific_paperformat_args = self_sudo.with_context(context)._prepare_html(html) - if self.attachment and set(res_ids) != set(html_ids): + if self_sudo.attachment and set(res_ids) != set(html_ids): raise UserError(_("The report's template '%s' is wrong, please contact your administrator. \n\n" "Can not separate file to save as attachment because the report's template does not contains the attributes 'data-oe-model' and 'data-oe-id' on the div with 'article' classname.") % self.name) @@ -773,8 +781,8 @@ class IrActionsReport(models.Model): set_viewport_size=context.get('set_viewport_size'), ) if res_ids: - _logger.info('The PDF report has been generated for model: %s, records %s.' % (self.model, str(res_ids))) - return self._post_pdf(save_in_attachment, pdf_content=pdf_content, res_ids=html_ids), 'pdf' + _logger.info('The PDF report has been generated for model: %s, records %s.' % (self_sudo.model, str(res_ids))) + return self_sudo._post_pdf(save_in_attachment, pdf_content=pdf_content, res_ids=html_ids), 'pdf' return pdf_content, 'pdf' @api.model @@ -808,10 +816,14 @@ class IrActionsReport(models.Model): data = data and dict(data) or {} + if report_model is not None: + # _render_ may be executed in sudo but evaluation context as real user + report_model = report_model.sudo(False) data.update(report_model._get_report_values(docids, data=data)) else: - docs = self.env[self.model].browse(docids) + # _render_ may be executed in sudo but evaluation context as real user + docs = self.env[self.model].sudo(False).browse(docids) data.update({ 'doc_ids': docids, 'doc_model': self.model, @@ -854,7 +866,7 @@ class IrActionsReport(models.Model): discard_logo_check = self.env.context.get('discard_logo_check') if self.env.is_admin() and not self.env.company.external_report_layout_id and config and not discard_logo_check: - action = self.env.ref('base.action_base_document_layout_configurator').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("base.action_base_document_layout_configurator") ctx = action.get('context') py_ctx = json.loads(ctx) if ctx else {} report_action['close_on_report_download'] = True diff --git a/odoo/addons/base/models/ir_attachment.py b/odoo/addons/base/models/ir_attachment.py index 0473bc5b7bb..6854a50c8f3 100644 --- a/odoo/addons/base/models/ir_attachment.py +++ b/odoo/addons/base/models/ir_attachment.py @@ -570,7 +570,7 @@ class IrAttachment(models.Model): @api.model def action_get(self): - return self.env['ir.actions.act_window'].for_xml_id('base', 'action_attachment') + return self.env['ir.actions.act_window']._for_xml_id('base.action_attachment') @api.model def get_serve_attachment(self, url, extra_domain=None, extra_fields=None, order=None): diff --git a/odoo/addons/base/models/ir_ui_menu.py b/odoo/addons/base/models/ir_ui_menu.py index aced50ecb97..8a3790c0de3 100644 --- a/odoo/addons/base/models/ir_ui_menu.py +++ b/odoo/addons/base/models/ir_ui_menu.py @@ -80,7 +80,7 @@ class IrUiMenu(models.Model): """ Return the ids of the menu items visible to the user. """ # retrieve all menus, and determine which ones are visible context = {'ir.ui.menu.full_list': True} - menus = self.with_context(context).search([]) + menus = self.with_context(context).search([]).sudo() groups = self.env.user.groups_id if not debug: diff --git a/odoo/addons/base/models/res_company.py b/odoo/addons/base/models/res_company.py index f05e029475e..3208df545ae 100644 --- a/odoo/addons/base/models/res_company.py +++ b/odoo/addons/base/models/res_company.py @@ -260,7 +260,7 @@ class Company(models.Model): @api.model def action_open_base_onboarding_company(self): """ Onboarding step for company basic information. """ - action = self.env.ref('base.action_open_base_onboarding_company').read()[0] + action = self.env["ir.actions.actions"]._for_xml_id("base.action_open_base_onboarding_company") action['res_id'] = self.env.company.id return action diff --git a/odoo/addons/base/security/ir.model.access.csv b/odoo/addons/base/security/ir.model.access.csv index ae568207ce3..220116ea7c0 100644 --- a/odoo/addons/base/security/ir.model.access.csv +++ b/odoo/addons/base/security/ir.model.access.csv @@ -76,23 +76,16 @@ "access_res_users_apikeys_description_employee","API key wizard employees","model_res_users_apikeys_description","group_user",1,0,1,0 "access_res_users_apikeys_description_portal","API key wizard","model_res_users_apikeys_description","group_portal",1,0,1,0 "access_res_users_apikeys_show_employee","API key result employees","model_res_users_apikeys_show","group_user",1,0,1,0 -"access_ir_actions_all","ir_actions_all","model_ir_actions_actions",,1,0,0,0 "access_ir_actions_group_system","ir_actions_group_system","model_ir_actions_actions","group_system",1,1,1,1 -"access_ir_actions_act_window_all","ir_actions_act_window_all","model_ir_actions_act_window",,1,0,0,0 "access_ir_actions_act_window_system","ir_actions_act_window_system","model_ir_actions_act_window","group_system",1,1,1,1 -"access_ir_actions_act_window_close_all","ir_actions_act_window_close_all","model_ir_actions_act_window_close",,1,0,0,0 "access_ir_actions_act_window_close_group_system","ir_actions_act_window_close_group_system","model_ir_actions_act_window_close","group_system",1,1,1,1 -"access_ir_actions_report_all","ir_actions_report","model_ir_actions_report",,1,0,0,0 "access_ir_actions_report_group_system","ir_actions_report_group_system","model_ir_actions_report","group_system",1,1,1,1 "access_ir_actions_todo_group_system","ir_actions_todo group system","model_ir_actions_todo","group_system",1,1,1,1 -"access_ir_actions_act_window_view_all","ir_actions_act_window_view_all","model_ir_actions_act_window_view",,1,0,0,0 "access_ir_actions_act_window_view_group_system","ir_actions_act_window_view_group_system","model_ir_actions_act_window_view","group_system",1,1,1,1 -"access_ir_actions_act_url_all","ir_actions_act_url_all","model_ir_actions_act_url",,1,0,0,0 "access_ir_actions_act_url_group_system","ir_actions_act_url_group_system","model_ir_actions_act_url","group_system",1,1,1,1 -"access_ir_server_object_lines_all","ir_server_object_lines_all","model_ir_server_object_lines",,1,0,0,0 "access_ir_server_object_lines_group_system","ir_server_object_lines_group_system","model_ir_server_object_lines","group_system",1,1,1,1 -"access_ir_actions_server_all","ir_actions_server_all","model_ir_actions_server",,1,0,0,0 "access_ir_actions_server_group_system","ir_actions_server_group_system","model_ir_actions_server","group_system",1,1,1,1 +"access_ir_actions_client","ir_actions_client all","model_ir_actions_client","group_system",1,1,1,1 "access_res_bank_group_system","res_bank_group_system","model_res_bank","group_system",1,1,1,1 "access_res_bank_group_partner_manager","res_bank_group_partner_manager","model_res_bank","group_partner_manager",1,1,1,1 "access_res_bank_user","res_bank user","model_res_bank","group_user",1,0,0,0 @@ -102,7 +95,6 @@ "access_ir_filter_public","ir_filters all","model_ir_filters","group_public",1,1,1,1 "access_ir_config_parameter_system","ir_config_parameter_system","model_ir_config_parameter","group_system",1,1,1,1 "access_ir_mail_server","ir_mail_server","model_ir_mail_server","group_system",1,1,1,1 -"access_ir_actions_client","ir_actions_client all","model_ir_actions_client",,1,0,0,0 "access_ir_logging","ir_logging admin","model_ir_logging","group_erp_manager",1,1,1,1 "paperformat_access_portal","ir_actions_report_paperformat group_portal","model_report_paperformat",,1,0,0,0 "paperformat_access_employee","ir_actions_report_paperformat group_system","model_report_paperformat",group_system,1,1,1,1 diff --git a/odoo/addons/base/wizard/base_document_layout.py b/odoo/addons/base/wizard/base_document_layout.py index 5232acb7f06..e93a63e1bfd 100644 --- a/odoo/addons/base/wizard/base_document_layout.py +++ b/odoo/addons/base/wizard/base_document_layout.py @@ -182,7 +182,7 @@ class BaseDocumentLayout(models.TransientModel): def action_open_base_document_layout(self, action_ref=None): if not action_ref: action_ref = 'base.action_base_document_layout_configurator' - return self.env.ref(action_ref).read()[0] + return self.env["ir.actions.actions"]._for_xml_id(action_ref) def document_layout_save(self): # meant to be overridden