112 lines
6.0 KiB
Python
112 lines
6.0 KiB
Python
from odoo import api, fields, models
|
|
from odoo.exceptions import ValidationError
|
|
class CourseStudentScore(models.Model):
|
|
_name = 'course.student.score'
|
|
_description = '学生成绩'
|
|
_rec_name = 'display_name'
|
|
_order = 'course_id, student_id'
|
|
_inherit = ['mail.thread']
|
|
display_name = fields.Char(string='显示名称', compute='_compute_display_name', store=True)
|
|
|
|
@api.depends('course_name', 'stu_name')
|
|
def _compute_display_name(self):
|
|
for record in self:
|
|
record.display_name = f"{record.stu_name} - {record.course_name}"
|
|
|
|
course_id = fields.Many2one('learning.course', string='课程', required=True, ondelete='cascade')
|
|
# 课程扩展只读字段(替代视图嵌套写法)
|
|
course_code = fields.Char(string="课程代码", related="course_id.code", readonly=True)
|
|
course_credit = fields.Float(string="学分", related="course_id.credit", readonly=True)
|
|
course_exam_type = fields.Selection(string="考核方式", related="course_id.exam_type", readonly=True)
|
|
course_name = fields.Char(related='course_id.name', string='课程', required=True, ondelete='cascade')
|
|
student_id = fields.Many2one('student.info', string='学生', required=True)
|
|
student_no = fields.Char(string="学号", related="student_id.stu_num", readonly=True)
|
|
student_class_id = fields.Many2one( string="班级", related="student_id.class_id", readonly=True)
|
|
student_major_id = fields.Many2one( string="专业", related="student_id.major_id", readonly=True)
|
|
stu_name=fields.Char(related='student_id.stu_name',required=True, ondelete='cascade',string='学生姓名')
|
|
score_ids = fields.One2many('course.student.score.detail', 'student_score_id', string='成绩明细')
|
|
teaching_class_id=fields.Many2one('course.teaching_class',string='教学班')
|
|
# 教学班相关只读关联字段
|
|
teaching_class_name = fields.Char(string="教学班名称", related="teaching_class_id.display_name", readonly=True)
|
|
teaching_class_semester = fields.Selection(string="学期", related="teaching_class_id.semester", readonly=True)
|
|
teaching_class_main_teacher = fields.Many2one('hr.employee', string="主讲教师",
|
|
related="teaching_class_id.main_teacher_id", readonly=True)
|
|
total_score = fields.Float(string='综合成绩', compute='_compute_total_score', store=True)
|
|
|
|
grade_level = fields.Selection([
|
|
('A', '优秀(A)'),
|
|
('B', '良好(B)'),
|
|
('C', '中等(C)'),
|
|
('D', '及格(D)'),
|
|
('F', '不及格(F)'),
|
|
], string='等级', compute='_compute_total_score', store=True)
|
|
|
|
@api.depends('score_ids.score', 'score_ids.weight')
|
|
def _compute_total_score(self):
|
|
for record in self:
|
|
total = 0.0
|
|
for detail in record.score_ids:
|
|
if detail.score and detail.weight:
|
|
total += detail.score * detail.weight / 100
|
|
record.total_score = round(total, 2)
|
|
|
|
if record.total_score >= 90:
|
|
record.grade_level = 'A'
|
|
elif record.total_score >= 80:
|
|
record.grade_level = 'B'
|
|
elif record.total_score >= 70:
|
|
record.grade_level = 'C'
|
|
elif record.total_score >= 60:
|
|
record.grade_level = 'D'
|
|
else:
|
|
record.grade_level = 'F'
|
|
|
|
|
|
class CourseStudentScoreDetail(models.Model):
|
|
_name = 'course.student.score.detail'
|
|
_description = '学生成绩明细'
|
|
_rec_name = 'display_name'
|
|
_order = 'student_score_id, score_item_id'
|
|
_inherit = ['mail.thread']
|
|
display_name = fields.Char(string='显示名称', compute='_compute_display_name', store=True)
|
|
@api.depends('student_score_displayname', 'score_item_id.name')
|
|
def _compute_display_name(self):
|
|
for record in self:
|
|
record.display_name = f"{record.student_score_displayname} - {record.score_item_id.name}"
|
|
# 关联学生成绩主表
|
|
student_score_id = fields.Many2one('course.student.score', string='学生成绩', required=True, ondelete='cascade')
|
|
student_score_displayname=fields.Char(related='student_score_id.display_name',required=True, ondelete='cascade',string='显示名称')
|
|
# 关联成绩项目
|
|
score_item_id = fields.Many2one('course.score.item', string='成绩项目', required=True, ondelete='restrict')
|
|
|
|
# 得分
|
|
score = fields.Float(string='得分', help='该项目实际得分')
|
|
|
|
# 从成绩项目继承的字段(用于显示和计算)
|
|
weight = fields.Float(string='权重(%)', related='score_item_id.weight', store=True, readonly=True)
|
|
full_score = fields.Float(string='满分', related='score_item_id.full_score', store=True, readonly=True)
|
|
score_type = fields.Selection(string='成绩类型', related='score_item_id.score_type', store=True, readonly=True)
|
|
# 备注
|
|
remark = fields.Char(string='备注')
|
|
# 关联课程和学生(用于视图显示)
|
|
course_id = fields.Many2one('learning.course', string='课程', related='student_score_id.course_id', store=True,
|
|
readonly=True)
|
|
student_id = fields.Many2one('student.info', string='学生', related='student_score_id.student_id', store=True,
|
|
readonly=True)
|
|
# 完成率(得分/满分)
|
|
completion_rate = fields.Float(string='完成率(%)', compute='_compute_completion_rate', store=True)
|
|
@api.depends('score', 'full_score')
|
|
def _compute_completion_rate(self):
|
|
for record in self:
|
|
if record.full_score and record.score:
|
|
record.completion_rate = round(record.score / record.full_score * 100, 1)
|
|
else:
|
|
record.completion_rate = 0.0
|
|
|
|
@api.constrains('score', 'full_score')
|
|
def _check_score(self):
|
|
for record in self:
|
|
if record.score and record.full_score and record.score > record.full_score:
|
|
raise ValidationError(f'得分({record.score})不能超过满分({record.full_score})')
|
|
if record.score and record.score < 0:
|
|
raise ValidationError('得分不能为负数') |