70 lines
3.0 KiB
Python
70 lines
3.0 KiB
Python
from odoo import fields, models, api
|
|
|
|
|
|
class SchoolProgress(models.Model):
|
|
"""学习进展——记录每位学员在每门课程中的学习情况。"""
|
|
|
|
_name = 'yuthon.school.progress'
|
|
_description = '学习进展'
|
|
_order = 'course_id, student_id'
|
|
_rec_name = 'name'
|
|
|
|
name = fields.Char(string='名称', compute='_compute_name', store=True)
|
|
course_id = fields.Many2one(
|
|
'yuthon.school.course', string='课程', required=True, ondelete='cascade')
|
|
student_id = fields.Many2one(
|
|
'yuthon.school.student', string='学员', required=True, ondelete='cascade')
|
|
teacher_id = fields.Many2one(
|
|
'res.users', string='任课教师',
|
|
related='course_id.teacher_id', readonly=True, store=True)
|
|
|
|
# 章节进度(基于课程章节完成情况动态计算,仅用于展示,不入库)
|
|
chapter_total = fields.Integer(string='章节总数', compute='_compute_chapter_progress')
|
|
chapter_done = fields.Integer(string='已完成章节', compute='_compute_chapter_progress')
|
|
progress_rate = fields.Float(string='学习进度(%)', compute='_compute_chapter_progress')
|
|
|
|
# 状态:普通可写字段(搜索/过滤需用 stored 字段),由章节完成情况触发更新
|
|
status = fields.Selection(
|
|
[('not_started', '未开始'), ('in_progress', '进行中'), ('completed', '已完成')],
|
|
string='状态', default='not_started', index=True, required=True)
|
|
|
|
last_study_date = fields.Date(string='最近学习日期')
|
|
score = fields.Float(string='综合得分')
|
|
note = fields.Text(string='备注')
|
|
active = fields.Boolean(string='启用', default=True)
|
|
|
|
def _compute_chapter_progress(self):
|
|
"""根据课程章节的「已完成学员」计算该学员的进度(展示用)。"""
|
|
for r in self:
|
|
chapters = r.course_id.chapter_ids if r.course_id else self.env['yuthon.school.course.chapter']
|
|
total = len(chapters)
|
|
done = sum(1 for c in chapters if r.student_id in c.completed_student_ids)
|
|
r.chapter_total = total
|
|
r.chapter_done = done
|
|
r.progress_rate = (done / total * 100.0) if total else 0.0
|
|
|
|
def recompute_status(self):
|
|
"""依据章节完成情况刷新状态(在章节完成状态变化时调用)。"""
|
|
for r in self:
|
|
total = r.chapter_total
|
|
done = r.chapter_done
|
|
if total == 0 or done == 0:
|
|
new_status = 'not_started'
|
|
elif done >= total:
|
|
new_status = 'completed'
|
|
else:
|
|
new_status = 'in_progress'
|
|
if r.status != new_status:
|
|
r.write({'status': new_status})
|
|
|
|
@api.model_create_multi
|
|
def create(self, vals_list):
|
|
recs = super().create(vals_list)
|
|
recs.recompute_status()
|
|
return recs
|
|
|
|
@api.depends('course_id', 'student_id')
|
|
def _compute_name(self):
|
|
for r in self:
|
|
r.name = '%s · %s' % (r.course_id.name or '', r.student_id.name or '')
|