from odoo import api, fields, models class CourseScoreItem(models.Model): _name = 'course.score.item' _description = '成绩项目' _rec_name = 'name' _order = 'course_id, weight desc, id' _inherit = ['mail.thread'] name = fields.Char(string='项目名称', required=True) description = fields.Char(string='项目描述') course_id = fields.Many2one('learning.course', string='课程', required=True, ondelete='cascade') course_name = fields.Char(related="course_id.name", string="课程名称", readonly=True) course_code = fields.Char(related="course_id.code", string="课程代码", readonly=True) course_credit = fields.Float(related="course_id.credit", string="学分", readonly=True) course_exam_type = fields.Selection(related="course_id.exam_type", string="考核方式", readonly=True) homework_id = fields.Many2one('course.homework', string='作业', required=True, ondelete='cascade') sequence = fields.Integer(string="排序", default=10) score_type = fields.Selection([ ('homework', '作业'), ('exam', '考试'), ('experiment', '实验'), ('attendance', '考勤'), ('midterm', '期中考试'), ('final', '期末考试'), ('other', '其他'), ], string='成绩类型', required=True) weight = fields.Float(string='权重(%)', required=True) full_score = fields.Float(string='满分', default=100.0) is_active = fields.Boolean(string='是否启用', default=True) homework_ids = fields.Many2many('course.homework', string='关联作业') # 统计字段 student_count = fields.Integer(string='学生人数', compute='_compute_stats') avg_score = fields.Float(string='平均分', compute='_compute_stats') max_score = fields.Float(string='最高分', compute='_compute_stats') min_score = fields.Float(string='最低分', compute='_compute_stats') score_detail_ids = fields.One2many('course.student.score.detail', 'score_item_id', string='成绩明细') def action_toggle_active(self): for record in self: record.is_active = not record.is_active def _compute_stats(self): for record in self: details = self.env['course.student.score.detail'].search([ ('score_item_id', '=', record.id) ]) scores = details.mapped('score') record.student_count = len(details) record.avg_score = sum(scores) / len(scores) if scores else 0 record.max_score = max(scores) if scores else 0 record.min_score = min(scores) if scores else 0