Odoo14动态生成菜单

from odoo import api, fields, models, _
from ast import literal_eval


class SpsScheduleType(models.Model):
    _name = "sps.schedule.type"
    _description = """档期类型"""


    name = fields.Char(string="档期类型名称", )
    menu_schedular_id = fields.Many2one(comodel_name='ir.ui.menu',
                                        ondelete="set null",
                                        string='档期菜单',
                                        )
    menu_job_ids = fields.Many2many(comodel_name='hr.job',
                                    string='可见岗位')


    @api.model_create_multi
    def create(self, vals_list):
        res = super(SpsScheduleType, self).create(vals_list)
        # 创建记录时自动生成档期类型菜单
        for record in res:
            self._create_booking_menu(record)
        return res


    def write(self, vals):

        res = super(SpsScheduleType, self).write(vals)
        # 修改档期可见岗位时,档期类型菜单的群组也同时修改
        if "menu_job_ids" in vals:
            role_list = []
            for job in self.menu_job_ids:
                for role in job.role_ids:
                    role_list.append(role.group_id.id)
                        
            self.menu_schedular_id.groups_id = [(6, 0, role_list)]

        # 修改档期类型名称时,档期类型菜单的名称也同时修改
        if "menu_job_ids" in vals:
            self.menu_schedular_id.name = self.name
        
        return res

    # 重写删除方法,当删除记录时,档期生成的菜单也删除
    def unlink(self):
        self.menu_schedular_id.unlink()
        res = super(SpsScheduleType, self).unlink()
        return res


    def _create_booking_menu(self, record):
        """
        动态生成菜单
        :return:
        """
        # 获取档期主菜单用来做生成菜单的父亲菜单
        schedular_menu_id = self.env.ref('sps_sale_order_schedular.schedular')
        # 复制一个原有的档期动作
        action_id = self.env.ref('sps_sale_order_schedular.sps_sale_order_schedular_config_action').copy()
        # 动作过滤条件
        action_id.domain = [("schedule_type", "=", record.id)]
        # 动作名称
        action_id.name = record.name
      action_id.context = context
# 动作中传递上下文参数,将当前的档期类型id传递过去
        context = literal_eval(action_id['context'])
        context['schedular_type_id'] = record.id

        menu_vals = {'name': record.name,
                        'parent_id': schedular_menu_id.id,
                        'action': 'ir.actions.act_window,%s' % action_id.id,
                        'sequence': record.id * 10,
                        'groups_id': [(6, 0, [role_id.group_id.id for menu_job_id in record.menu_job_ids
                                                                for role_id in menu_job_id.role_ids])]}
        record.menu_schedular_id = self.env['ir.ui.menu'].create(menu_vals)
原文地址:https://www.cnblogs.com/wangdianchao/p/15151577.html