179 lines
8.1 KiB
Python
179 lines
8.1 KiB
Python
from odoo import api, fields, models
|
|
from odoo.exceptions import ValidationError
|
|
|
|
class CourseHomework(models.Model):
|
|
_name = 'course.homework'
|
|
_description = '课程作业'
|
|
_rec_name = 'name'
|
|
_inherit = ['mail.thread']
|
|
_order = 'course_id, deadline, id'
|
|
|
|
name = fields.Char(string='作业名称', required=True)
|
|
description = fields.Html(string='作业描述')
|
|
requirement = fields.Html(string='作业要求')
|
|
course_id = fields.Many2one('learning.course', string='所属课程', required=True, ondelete='cascade')
|
|
chapter_id = fields.Many2one('course.chapter', string='关联章节')
|
|
total_score = fields.Float(string='作业总分', default=100.0, required=True)
|
|
publish_time = fields.Datetime(string='发布时间', default=fields.Datetime.now)
|
|
deadline = fields.Datetime(string='提交截止时间', required=True)
|
|
late_deadline = fields.Datetime(string='补交截止时间')
|
|
state = fields.Selection([
|
|
('draft', '草稿'),
|
|
('published', '已发布'),
|
|
('closed', '已关闭'),
|
|
], string='状态', default='draft', tracking=True)
|
|
is_submit_open = fields.Boolean(string='提交通道开启', default=True)
|
|
allow_late = fields.Boolean(string='允许补交', default=False)
|
|
total_students = fields.Integer(string='应提交人数', compute='_compute_submit_stats')
|
|
submitted_count = fields.Integer(string='已提交人数', compute='_compute_submit_stats')
|
|
late_count = fields.Integer(string='逾期提交人数', compute='_compute_submit_stats')
|
|
unsubmitted_count = fields.Integer(string='未提交人数', compute='_compute_submit_stats')
|
|
# 添加教学班关联
|
|
teaching_class_id = fields.Many2one('course.teaching_class', string='教学班',
|
|
ondelete='cascade', domain="[('course_id', '=', course_id)]")
|
|
submit_ids = fields.One2many('course.homework.submit', 'homework_id', string='提交记录')
|
|
score_item_ids = fields.One2many('course.score.item', 'homework_id', string='提交记录')
|
|
|
|
def _compute_submit_stats(self):
|
|
for record in self:
|
|
# 按教学班 + 选课状态筛选学生
|
|
domain = [('state', '=', 'enrolled')]
|
|
if record.teaching_class_id:
|
|
# 优先按当前作业所属教学班统计(核心修正)
|
|
domain.append(('teaching_class_id', '=', record.teaching_class_id.id))
|
|
else:
|
|
# 无教学班时,回退到整门课程统计
|
|
domain.append(('course_id', '=', record.course_id.id))
|
|
|
|
enrollments = self.env['course.teaching_class.enrollment'].search(domain)
|
|
student_ids = enrollments.mapped('student_id')
|
|
record.total_students = len(student_ids)
|
|
|
|
# 该作业所有提交记录
|
|
base_domain = [('homework_id', '=', record.id)]
|
|
all_submit = self.env['course.homework.submit'].search(base_domain)
|
|
total_submit = len(all_submit)
|
|
|
|
deadline_val = record.deadline
|
|
if deadline_val:
|
|
# 按时提交
|
|
on_time_submit = all_submit.filtered(lambda s: s.submit_time and s.submit_time <= deadline_val)
|
|
# 逾期提交
|
|
late_submit = all_submit.filtered(lambda s: s.submit_time and s.submit_time > deadline_val)
|
|
record.submitted_count = len(on_time_submit)
|
|
record.late_count = len(late_submit)
|
|
else:
|
|
record.submitted_count = total_submit
|
|
record.late_count = 0
|
|
|
|
# 未提交 = 班级总人数 - 所有提交人数
|
|
record.unsubmitted_count = record.total_students - total_submit
|
|
|
|
def action_publish(self):
|
|
self.state = 'published'
|
|
self.publish_time = fields.Datetime.now()
|
|
|
|
def action_draft(self):
|
|
self.state = 'draft'
|
|
|
|
def action_close(self):
|
|
self.state = 'closed'
|
|
self.is_submit_open = False
|
|
|
|
@api.constrains('deadline', 'late_deadline')
|
|
def _check_deadline(self):
|
|
for record in self:
|
|
if record.late_deadline and record.late_deadline < record.deadline:
|
|
raise ValidationError('补交截止时间必须晚于提交截止时间')
|
|
|
|
def _get_current_student(self):
|
|
"""获取当前登录的学生"""
|
|
student = self.env['student.info'].search([('user_id', '=', self.env.uid)], limit=1)
|
|
return student
|
|
|
|
# 当前学生的提交记录
|
|
my_submit_id = fields.Many2one('course.homework.submit', string='我的提交',
|
|
compute='_compute_my_submit')
|
|
my_submit_state = fields.Char(string='提交状态', compute='_compute_my_submit')
|
|
my_submit_time = fields.Datetime(string='提交时间', compute='_compute_my_submit')
|
|
my_score = fields.Float(string='我的得分', compute='_compute_my_submit')
|
|
my_grade_level = fields.Char(string='我的等级', compute='_compute_my_submit')
|
|
my_comment = fields.Html(string='我的评语', compute='_compute_my_submit')
|
|
my_submit_file = fields.Binary(string='我的提交文件', compute='_compute_my_submit')
|
|
my_submit_filename = fields.Char(string='文件名', compute='_compute_my_submit')
|
|
my_submit_content = fields.Html(string='提交内容', compute='_compute_my_submit')
|
|
|
|
# 提交状态(用于前端显示)
|
|
submit_state = fields.Selection([
|
|
('not_submitted', '未提交'),
|
|
('submitted', '已提交'),
|
|
('graded', '已批改'),
|
|
('late', '逾期提交'),
|
|
], string='提交状态', compute='_compute_my_submit')
|
|
|
|
# 是否可以提交
|
|
can_submit = fields.Boolean(string='可以提交', compute='_compute_can_submit')
|
|
|
|
@api.depends('submit_ids')
|
|
def _compute_my_submit(self):
|
|
for record in self:
|
|
student = self._get_current_student()
|
|
if student:
|
|
submit = record.submit_ids.filtered(lambda s: s.student_id == student)
|
|
if submit:
|
|
record.my_submit_id = submit.id
|
|
record.my_submit_state = submit.state
|
|
record.my_submit_time = submit.submit_time
|
|
record.my_score = submit.score
|
|
record.my_grade_level = submit.grade_level
|
|
record.my_comment = submit.comment
|
|
record.my_submit_file = submit.submit_file
|
|
record.my_submit_filename = submit.submit_filename
|
|
record.my_submit_content = submit.submit_content
|
|
|
|
# 计算提交状态
|
|
if submit.state == 'graded':
|
|
record.submit_state = 'graded'
|
|
elif submit.is_late:
|
|
record.submit_state = 'late'
|
|
else:
|
|
record.submit_state = 'submitted'
|
|
else:
|
|
record.submit_state = 'not_submitted'
|
|
else:
|
|
record.submit_state = 'not_submitted'
|
|
|
|
def _compute_can_submit(self):
|
|
for record in self:
|
|
# 作业已发布、提交通道开启、未截止、且未提交
|
|
can = (record.state == 'published' and
|
|
record.is_submit_open and
|
|
record.deadline and
|
|
record.deadline > fields.Datetime.now() and
|
|
record.my_submit_state != 'submitted' and
|
|
record.my_submit_state != 'graded')
|
|
record.can_submit = can
|
|
|
|
def action_submit_homework(self):
|
|
"""学生提交作业"""
|
|
self.ensure_one()
|
|
student = self._get_current_student()
|
|
if not student:
|
|
raise ValidationError('请先关联学生信息')
|
|
|
|
# 检查提交权限
|
|
if not self.can_submit:
|
|
raise ValidationError('当前无法提交作业')
|
|
|
|
# 打开提交表单
|
|
return {
|
|
'type': 'ir.actions.act_window',
|
|
'name': '提交作业',
|
|
'res_model': 'course.homework.submit',
|
|
'view_mode': 'form',
|
|
'target': 'new',
|
|
'context': {
|
|
'default_homework_id': self.id,
|
|
'default_student_id': student.id,
|
|
},
|
|
} |