103 lines
4.2 KiB
Python
103 lines
4.2 KiB
Python
# -*- coding: utf-8 -*-
|
|
# pyrefly: ignore [missing-import]
|
|
from odoo import api, fields, models
|
|
# pyrefly: ignore [missing-import]
|
|
from odoo.exceptions import ValidationError
|
|
import base64
|
|
|
|
MAX_FILE_SIZE_BYTES = 5 * 1024 * 1024 # 5 MB
|
|
|
|
|
|
class EducationStudentDocument(models.Model):
|
|
_name = 'education.student.document'
|
|
_description = 'Student Document'
|
|
_inherit = ['mail.thread', 'mail.activity.mixin']
|
|
_order = 'upload_date desc, id desc'
|
|
|
|
name = fields.Char(string='Document Title', required=True, tracking=True)
|
|
student_id = fields.Many2one(
|
|
'education.student',
|
|
string='Student',
|
|
required=True,
|
|
ondelete='cascade',
|
|
index=True,
|
|
tracking=True
|
|
)
|
|
category = fields.Selection([
|
|
('identity', 'Identity Proof'),
|
|
('academic', 'Academic Certificate / Marksheet'),
|
|
('transfer', 'Transfer / Migration Certificate'),
|
|
('address', 'Address Proof'),
|
|
('other', 'Other Document'),
|
|
], string='Category', required=True, default='academic', tracking=True)
|
|
|
|
document_file = fields.Binary(string='Document File', required=True, attachment=True)
|
|
file_name = fields.Char(string='Filename')
|
|
file_size = fields.Integer(string='File Size (Bytes)', compute='_compute_file_metadata', store=True)
|
|
mime_type = fields.Char(string='MIME Type')
|
|
|
|
verification_status = fields.Selection([
|
|
('submitted', 'Submitted'),
|
|
('verified', 'Verified'),
|
|
('rejected', 'Rejected'),
|
|
], string='Verification Status', default='submitted', required=True, tracking=True, index=True)
|
|
|
|
verified_by = fields.Many2one('res.users', string='Verified By', readonly=True, tracking=True)
|
|
verification_date = fields.Datetime(string='Verification Date', readonly=True, tracking=True)
|
|
rejection_reason = fields.Text(string='Rejection Reason', tracking=True)
|
|
upload_date = fields.Datetime(string='Upload Date', default=fields.Datetime.now, readonly=True)
|
|
|
|
company_id = fields.Many2one(
|
|
'res.company',
|
|
string='Company',
|
|
related='student_id.company_id',
|
|
store=True,
|
|
index=True
|
|
)
|
|
|
|
@api.depends('document_file')
|
|
def _compute_file_metadata(self):
|
|
for rec in self:
|
|
if rec.document_file:
|
|
try:
|
|
decoded = base64.b64decode(rec.document_file)
|
|
rec.file_size = len(decoded)
|
|
except Exception:
|
|
rec.file_size = 0
|
|
else:
|
|
rec.file_size = 0
|
|
|
|
@api.constrains('document_file', 'file_name')
|
|
def _check_file_validity(self):
|
|
for rec in self:
|
|
if rec.document_file:
|
|
decoded = base64.b64decode(rec.document_file)
|
|
if len(decoded) > MAX_FILE_SIZE_BYTES:
|
|
raise ValidationError(f"File size exceeds the maximum allowed limit of 5 MB ({len(decoded)} bytes).")
|
|
if rec.file_name:
|
|
ext = rec.file_name.split('.')[-1].lower() if '.' in rec.file_name else ''
|
|
if ext not in ['pdf', 'jpg', 'jpeg', 'png']:
|
|
raise ValidationError("Invalid file type. Allowed formats: PDF, JPG, JPEG, PNG.")
|
|
|
|
def action_verify(self):
|
|
for rec in self:
|
|
if not (self.env.is_admin() or self.env.user.has_group('education_student.group_education_student_user')):
|
|
raise ValidationError("Only authorized staff can verify student documents.")
|
|
rec.write({
|
|
'verification_status': 'verified',
|
|
'verified_by': self.env.user.id,
|
|
'verification_date': fields.Datetime.now(),
|
|
'rejection_reason': False,
|
|
})
|
|
|
|
def action_reject(self, reason="Document details could not be verified."):
|
|
for rec in self:
|
|
if not (self.env.is_admin() or self.env.user.has_group('education_student.group_education_student_user')):
|
|
raise ValidationError("Only authorized staff can reject student documents.")
|
|
rec.write({
|
|
'verification_status': 'rejected',
|
|
'verified_by': self.env.user.id,
|
|
'verification_date': fields.Datetime.now(),
|
|
'rejection_reason': reason,
|
|
})
|