106 lines
4.6 KiB
Python
106 lines
4.6 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
|
|
|
|
|
|
class EducationStudentCertificate(models.Model):
|
|
_name = 'education.student.certificate'
|
|
_description = 'Student Certificate'
|
|
_inherit = ['mail.thread', 'mail.activity.mixin']
|
|
_order = 'issue_date desc, id desc'
|
|
|
|
name = fields.Char(string='Certificate Number', readonly=True, copy=False, index=True)
|
|
student_id = fields.Many2one(
|
|
'education.student',
|
|
string='Student',
|
|
required=True,
|
|
ondelete='cascade',
|
|
index=True,
|
|
tracking=True
|
|
)
|
|
certificate_type = fields.Selection([
|
|
('bonafide', 'Bonafide Certificate'),
|
|
('id_card', 'Student ID Card'),
|
|
('course_completion', 'Course Completion Certificate'),
|
|
('conduct', 'Conduct / Character Certificate'),
|
|
], string='Certificate Type', required=True, default='bonafide', tracking=True)
|
|
|
|
state = fields.Selection([
|
|
('draft', 'Draft'),
|
|
('requested', 'Requested'),
|
|
('approved', 'Approved'),
|
|
('issued', 'Issued'),
|
|
('rejected', 'Rejected'),
|
|
], string='Status', default='draft', required=True, tracking=True, index=True)
|
|
|
|
request_date = fields.Date(string='Request Date', default=fields.Date.context_today, readonly=True)
|
|
issue_date = fields.Date(string='Issue Date', readonly=True, tracking=True)
|
|
expiry_date = fields.Date(string='Expiry Date')
|
|
issued_by = fields.Many2one('res.users', string='Issued By', readonly=True)
|
|
|
|
document_file = fields.Binary(string='Certificate PDF', attachment=True, readonly=True)
|
|
file_name = fields.Char(string='Certificate Filename', readonly=True)
|
|
remarks = fields.Text(string='Student Purpose / Remarks')
|
|
rejection_reason = fields.Text(string='Rejection Reason')
|
|
|
|
company_id = fields.Many2one(
|
|
'res.company',
|
|
string='Company',
|
|
related='student_id.company_id',
|
|
store=True,
|
|
index=True
|
|
)
|
|
|
|
def action_request(self):
|
|
for rec in self:
|
|
if rec.student_id.status not in ('active', 'admitted'):
|
|
raise ValidationError("Only active or admitted students are eligible to request certificates.")
|
|
rec.state = 'requested'
|
|
|
|
def action_approve(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 approve certificate requests.")
|
|
rec.state = 'approved'
|
|
|
|
def action_issue(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 issue certificates.")
|
|
if rec.student_id.status not in ('active', 'admitted'):
|
|
raise ValidationError("Cannot issue official certificate for a student with inactive status.")
|
|
if not rec.name:
|
|
rec.name = self.env['ir.sequence'].next_by_code('education.student.certificate') or f"CERT-{rec.id}"
|
|
rec.issue_date = fields.Date.context_today(self)
|
|
rec.issued_by = self.env.user.id
|
|
rec.state = 'issued'
|
|
|
|
# Generate PDF using existing report if available
|
|
report_ref = None
|
|
if rec.certificate_type == 'bonafide':
|
|
report_ref = 'education_reports.action_report_bonafide_certificate'
|
|
elif rec.certificate_type == 'id_card':
|
|
report_ref = 'education_reports.action_report_student_id_card'
|
|
|
|
if report_ref and self.env.ref(report_ref, raise_if_not_found=False):
|
|
try:
|
|
pdf_content, _ = self.env['ir.actions.report'].sudo()._render_qweb_pdf(report_ref, rec.student_id.ids)
|
|
if pdf_content:
|
|
rec.document_file = base64.b64encode(pdf_content)
|
|
clean_code = (rec.name or 'CERT').replace('/', '_')
|
|
rec.file_name = f"{clean_code}.pdf"
|
|
except Exception:
|
|
# Non-blocking if wkhtmltopdf not present in current environment
|
|
pass
|
|
|
|
def action_reject(self, reason=None):
|
|
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 certificate requests.")
|
|
rec.state = 'rejected'
|
|
if reason:
|
|
rec.rejection_reason = reason
|