[MERGE] *: remove read access to ir.actions.*
Remove all acccess rights on `ir.actions.*` models. Interacting with the models is done using sudo or via the `/web/action/load` controller. Part of task 8203 closes odoo/odoo#53335 Related: odoo/enterprise#11797 Signed-off-by: Martin Trigaux (mat) <mat@odoo.com>
This commit is contained in:
@@ -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) + "}",
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
@@ -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
|
||||
|
||||
@@ -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'),
|
||||
})
|
||||
|
||||
@@ -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'),
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -981,6 +981,7 @@ if record:
|
||||
<field name="name">Crm: My Pipeline</field>
|
||||
<field name="model_id" ref="crm.model_crm_team"/>
|
||||
<field name="state">code</field>
|
||||
<field name="groups_id" eval="[(4, ref('base.group_user'))]"/>
|
||||
<field name="code">action = model.action_your_pipeline()</field>
|
||||
</record>
|
||||
|
||||
|
||||
@@ -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'] = _("""<p class="o_view_nocontent_empty_folder">
|
||||
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'] = _("""<p class="o_view_nocontent_empty_folder">
|
||||
No opportunities found
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -219,7 +219,7 @@ class StockPicking(models.Model):
|
||||
for tracker in carrier_trackers:
|
||||
msg += '<a href=' + tracker[1] + '>' + tracker[0] + '</a><br/>'
|
||||
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',
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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},
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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)]
|
||||
|
||||
@@ -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')
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)))
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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'] = {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)]
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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'],
|
||||
|
||||
@@ -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'],
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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']]
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
|
||||
@@ -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?
|
||||
|
||||
@@ -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)]
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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'),
|
||||
]
|
||||
|
||||
@@ -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)]
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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')]
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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)]
|
||||
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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):
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -317,13 +317,15 @@
|
||||
<field name="model_id" ref="website.model_website"/>
|
||||
<field name="state">code</field>
|
||||
<field name="code">action = model.action_dashboard_redirect()</field>
|
||||
<field name="groups_id" eval="[(4, ref('base.group_user'))]"/>
|
||||
</record>
|
||||
|
||||
<record id="ir_actions_server_website_google_analytics" model="ir.actions.server">
|
||||
<field name="name">Website: Dashboard</field>
|
||||
<field name="name">Website: Analytics</field>
|
||||
<field name="model_id" ref="website.model_website"/>
|
||||
<field name="state">code</field>
|
||||
<field name="code">action = model.env.ref('website.backend_dashboard').read()[0]</field>
|
||||
<field name="code">action = model.env.ref('website.backend_dashboard').sudo().read()[0]</field>
|
||||
<field name="groups_id" eval="[(4, ref('base.group_user'))]"/>
|
||||
</record>
|
||||
|
||||
<!-- Custom module kanban : install button (even if already installed) which -->
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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')]
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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')],
|
||||
|
||||
@@ -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",
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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):
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user