from odoo import api,models,fields from odoo.exceptions import ValidationError class StudentInfo(models.Model): _name="student.info" stu_name=fields.Char(string="姓名",tracking=True) stu_num=fields.Char(string="学号",tracking=True) stu_sex = fields.Selection([('male', '男'),('female', '女')], string="性别", default='male', required=True) stu_birthday = fields.Date(string="出生日期", tracking=True) stu_id_card = fields.Char(string="身份证号", index=True, tracking=True) stu_nation = fields.Char(string="民族", default="汉族") stu_shenfen = fields.Selection([ ('mass', '群众'), ('league', '共青团员'), ('party', '中共党员'), ('other', '其他') ], string="政治面貌", default='mass') stu_phone = fields.Char(string="手机号") stu_email = fields.Char(string="邮箱") stu_address = fields.Text(string="家庭地址") stu_emergency_contact = fields.Char(string="紧急联系人") stu_emergency_phone = fields.Char(string="紧急联系电话") stu_photo = fields.Binary(string="照片", attachment=True) stu_begin_date = fields.Date(string="入学日期", required=True, tracking=True) stu_end_date = fields.Date(string="毕业日期") stu_grade_xx = fields.Many2one('basic.grade.xx',string="年级", tracking=True,domain = lambda self: self.env['basic.grade.xx']._get_current_year_range_domain()) stu_grade_bx=fields.Many2one('basic.grade.xx',string='年级',readonly=1) stu_status = fields.Selection([ ('studying', '在读'), ('graduated', '已毕业'), ('suspended', '休学'), ('expelled', '退学'), ('transferred', '转出') ], string="学籍状态", default='studying', tracking=True) org_path = fields.Char(string='组织路径', compute='_compute_org_path', store=True, index=True) class_id = fields.Many2one('student.organization', string="行政班", tracking=True,domain="[('org_type', '=', 'class')]") parent_path = fields.Char(related='class_id.parent_path',store=True) class_name = fields.Char(string="班级名称", related='class_id.name', store=True) major_id = fields.Many2one('student.organization', string="专业", tracking=True,domain="[('org_type', '=', 'major')]") major_name = fields.Char(string="专业名称", related='major_id.name', store=True) department_id = fields.Many2one('student.organization', string="院系",store=True,domain="[('org_type', '=', 'college')]") # 新增:关联系统登录用户(解决之前作业通知报错缺少user_id的问题) user_id = fields.Many2one('res.users', string="系统登录账号", ondelete='restrict') @api.depends('parent_path') def _compute_org_path(self): for record in self: if record.class_id: record.org_path = f"{record.class_id.parent_path}{record.class_id.id}/" else: record.org_path = False @api.model def create(self, vals): # 1. 先校验学号,提前取出学号避免多次读取 stu_num = vals.get('stu_num', '').strip() new_user = None # 2. 学号不为空才执行创建用户逻辑 if stu_num: # 校验学号对应的登录账号是否已存在 exist_user = self.env['res.users'].search([('login', '=', stu_num)], limit=1) if not exist_user: # 获取两个权限组,并双重校验存在性 internal_group = self.env.ref('base.group_user', raise_if_not_found=False) student_group = self.env.ref('edu_base.group_student', raise_if_not_found=False) if not internal_group: raise ValidationError("系统内置内部用户组 base.group_user 缺失,无法创建登录账号!") if not student_group: raise ValidationError("权限组 edu_base.group_student 不存在,请先创建该学生权限组!") # 组装用户参数,优先取学生填写的邮箱,无则自动生成 stu_email = vals.get('stu_email') if not stu_email: stu_email = f"{stu_num}@edu.local" user_vals = { 'name': vals.get('stu_name', ''), 'login': stu_num, 'password': stu_num, 'email': stu_email, 'phone': vals.get('stu_phone', ''), # 同时分配后台登录组 + 学生业务权限组 'groups_id': [(6, 0, [student_group.id, internal_group.id])], } # 先创建用户,事务内失败会整体回滚 new_user = self.env['res.users'].create(user_vals) # 3. 创建学生档案,如果已生成用户则绑定user_id if new_user: vals['user_id'] = new_user.id student_info = super().create(vals) return student_info