from odoo import models, fields, api from odoo.exceptions import ValidationError import re import base64 class SchoolApplication(models.Model): _name = 'school.application' _description = 'Student Application' _order = 'name' _rec_name = 'name' _inherit = ['mail.thread', 'mail.activity.mixin'] # Link to res.partner partner_id = fields.Many2one('res.partner', string="Student Contact", ondelete="cascade") # Basic Info name = fields.Char(string="Student Name", required=True) roll_no = fields.Char(string="Roll Number", readonly=False) email = fields.Char(string="Email") phone_no = fields.Char(string="Phone Number") image = fields.Binary("Profile Photo", store=True) address = fields.Text(string="Address") # Class and Academic Info class_name = fields.Selection([ ('1', 'Class 1'), ('2', 'Class 2'), ('3', 'Class 3'), ('4', 'Class 4'), ('5', 'Class 5'), ('6', 'Class 6'), ('7', 'Class 7'), ('8', 'Class 8'), ('9', 'Class 9'), ('10', 'Class 10'), ('11', 'Class 11'), ('12', 'Class 12'), ], string="Class", required=True) academic_year = fields.Char(string="Academic Year") gender = fields.Selection([ ('male', 'Male'), ('female', 'Female'), ('other', 'Other') ], string="Gender") date_of_birth = fields.Date(string="Date of Birth") parent_email = fields.Char(string="Parent Email") blood_group = fields.Selection([ ('a+', 'A+'), ('a-', 'A-'), ('b+', 'B+'), ('b-', 'B-'), ('ab+', 'AB+'), ('ab-', 'AB-'), ('o+', 'O+'), ('o-', 'O-') ], string="Blood Group") school_name = fields.Char(string="Previous School") has_disability = fields.Boolean(string="Any Disability") is_ex_service_child = fields.Boolean(string="Ex-Service Man's Child") caste = fields.Selection([ ('general', 'General'), ('OBC', 'OBC'), ('SC', 'SC'), ('ST', 'ST'), ('other', 'Other') ], string="Caste") status = fields.Selection([ ('pending', 'Pending'), ('approved', 'Approved'), ('rejected', 'Rejected') ], default='pending') # Parent Info father_name = fields.Char(string="Father's Name") father_phone = fields.Char(string="Father's Phone") mother_name = fields.Char(string="Mother's Name") mother_phone = fields.Char(string="Mother's Phone") father_occupation = fields.Char(string="Father's Occupation") mother_occupation = fields.Char(string="Mother's Occupation") # Admission Query admission_query = fields.Text(string="Admission Query") # Documents (File Uploads) birth_certificate = fields.Binary(string="Birth Certificate") birth_certificate_filename = fields.Char(string="Filename") tc_certificate = fields.Binary(string="Transfer Certificate") tc_certificate_filename = fields.Char(string="TC Filename") aadhaar_card = fields.Binary(string="Aadhaar Card") aadhaar_card_filename = fields.Char(string="Filename") @api.onchange('roll_no') def _onchange_roll_no(self): """Auto-generate roll number only when it's empty and user clicks the field.""" if not self.roll_no: self.roll_no = self.env['ir.sequence'].next_by_code('school.application') # Constraint on phone number @api.constrains('phone_no') def _check_phone_no(self): for record in self: if record.phone_no and not re.fullmatch(r'\d{10}', record.phone_no): raise ValidationError("Phone number must contain exactly 10 digits.") # Show ID card action def action_show_id_card(self): self.ensure_one() return { 'type': 'ir.actions.act_window', 'name': 'ID Card', 'view_mode': 'form', 'res_model': 'school.application', 'res_id': self.id, 'view_id': self.env.ref('school_management.view_school_id_card_form').id, 'target': 'new', } # Optional: Sync partner details with application @api.onchange('partner_id') def _onchange_partner_id(self): if self.partner_id: self.name = self.partner_id.name self.email = self.partner_id.email self.phone_no = self.partner_id.phone self.image = self.partner_id.image_1920 self.address = self.partner_id.contact_address def print_id_card(self): self.ensure_one() return self.env.ref('school_management.report_school_id_card').report_action(self)