selvi 40f4b9dc81
Some checks failed
CI / Brand-leak check (push) Has been cancelled
CI / flake8 / pylint-odoo / manifest completeness (push) Has been cancelled
CI / Install all modules with --test-enable (push) Has been cancelled
assignment submission updated
2026-10-06 20:36:21 +05:30

114 lines
4.2 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import base64
from odoo import api, fields, models
from odoo.exceptions import ValidationError
class CommunitySchoolAssignment(models.Model):
_name = 'community.school.assignment'
_description = 'School Assignment'
_order = 'due_date asc, id desc'
_inherit = ['mail.thread', 'mail.activity.mixin']
name = fields.Char(string='Title', required=True, tracking=True)
class_id = fields.Many2one(
'community.school.class', string='Class', required=True, ondelete='cascade',
)
term_id = fields.Many2one(related='class_id.term_id', store=True)
teacher_id = fields.Many2one(related='class_id.teacher_id', store=True)
description = fields.Html(string='Instructions')
due_date = fields.Datetime(string='Due Date', required=True, tracking=True)
max_score = fields.Integer(string='Max Score', default=100)
state = fields.Selection(
[('draft', 'Draft'), ('published', 'Published'), ('closed', 'Closed')],
default='draft', required=True, tracking=True,
)
submission_ids = fields.One2many('community.school.submission', 'assignment_id')
submission_count = fields.Integer(compute='_compute_submission_count', store=True)
@api.depends('submission_ids')
def _compute_submission_count(self):
for assignment in self:
assignment.submission_count = len(assignment.submission_ids)
def action_publish(self):
for rec in self:
rec.state = 'published'
def action_close(self):
for rec in self:
rec.state = 'closed'
def action_reset_draft(self):
for rec in self:
rec.state = 'draft'
def action_view_submissions(self):
self.ensure_one()
return {
'type': 'ir.actions.act_window',
'name': f'Submissions – {self.name}',
'res_model': 'community.school.submission',
'view_mode': 'list,form',
'domain': [('assignment_id', '=', self.id)],
'context': {'default_assignment_id': self.id},
}
class CommunitySchoolSubmission(models.Model):
_name = 'community.school.submission'
_description = 'Assignment Submission'
_order = 'submitted_on desc, id desc'
assignment_id = fields.Many2one(
'community.school.assignment', required=True, ondelete='cascade',
)
enrollment_id = fields.Many2one(
'community.school.enrollment', string='Student Enrollment', required=True, ondelete='cascade',
)
student_id = fields.Many2one(related='enrollment_id.student_id', store=True)
class_id = fields.Many2one(related='assignment_id.class_id', store=True)
submitted_on = fields.Datetime(string='Submitted On', readonly=True)
notes = fields.Text(string='Student Notes')
# File attachment stored as binary
attachment_name = fields.Char(string='File Name')
attachment_data = fields.Binary(string='Uploaded File', attachment=True)
# Grading
score = fields.Integer(string='Score')
feedback = fields.Text(string='Teacher Feedback')
state = fields.Selection(
[('submitted', 'Submitted'), ('graded', 'Graded')],
default='submitted', required=True,
)
is_late = fields.Boolean(compute='_compute_is_late', store=True)
_assignment_enrollment_uniq = models.Constraint(
'unique(assignment_id, enrollment_id)',
'A submission for this assignment by this student already exists.',
)
@api.depends('submitted_on', 'assignment_id.due_date')
def _compute_is_late(self):
for sub in self:
if sub.submitted_on and sub.assignment_id.due_date:
sub.is_late = sub.submitted_on > sub.assignment_id.due_date
else:
sub.is_late = False
@api.constrains('score', 'assignment_id')
def _check_score(self):
for sub in self:
if sub.score < 0:
raise ValidationError('Score cannot be negative.')
if sub.assignment_id and sub.score > sub.assignment_id.max_score:
raise ValidationError(
f'Score ({sub.score}) cannot exceed max score ({sub.assignment_id.max_score}).'
)
def action_grade(self):
for sub in self:
sub.state = 'graded'