2026-09-22 10:51:28 +05:30

186 lines
6.8 KiB
Python

# pyrefly: ignore [missing-import]
from odoo import api, fields, models
# pyrefly: ignore [missing-import]
from odoo.exceptions import ValidationError
import secrets
import string
class EducationStudent(models.Model):
_inherit = 'education.student'
portal_user_id = fields.Many2one(
'res.users',
string='Portal User',
domain=[('share', '=', True)],
tracking=True,
copy=False,
help='Portal user linked to this student.'
)
portal_status = fields.Selection([
('draft', 'Not Created'),
('active', 'Active'),
('deactivated', 'Deactivated')
], string='Portal Status', default='draft', compute='_compute_portal_status', store=True, tracking=True)
portal_username = fields.Char(
string='Portal Username',
related='portal_user_id.login',
readonly=True
)
portal_email = fields.Char(
string='Portal Email',
related='portal_user_id.email',
readonly=True
)
portal_last_login = fields.Datetime(
string='Last Login',
related='portal_user_id.login_date',
readonly=True
)
is_education_admin = fields.Boolean(compute='_compute_is_education_admin')
@api.depends('portal_user_id', 'portal_user_id.active')
def _compute_portal_status(self):
for rec in self:
if not rec.portal_user_id:
rec.portal_status = 'draft'
elif rec.portal_user_id.active:
rec.portal_status = 'active'
else:
rec.portal_status = 'deactivated'
def _compute_is_education_admin(self):
is_admin = self.env.user.has_group('education_student.group_education_student_admin')
for rec in self:
rec.is_education_admin = is_admin
@api.constrains('portal_user_id')
def _check_unique_portal_user(self):
for rec in self:
if rec.portal_user_id:
duplicate = self.search([
('portal_user_id', '=', rec.portal_user_id.id),
('id', '!=', rec.id)
])
if duplicate:
raise ValidationError("This Portal User is already linked to another student.")
def action_create_portal_user(self):
self.ensure_one()
if self.portal_user_id:
raise ValidationError("This student already has a portal user linked.")
if not self.email:
raise ValidationError("An email address is required to create a portal user.")
# Check if a user with this login/email already exists
existing_user = self.env['res.users'].sudo().search([('login', '=', self.email)], limit=1)
if existing_user:
# Check if this user is already linked to another student
other_student = self.search([('portal_user_id', '=', existing_user.id)], limit=1)
if other_student:
raise ValidationError(f"A user with email {self.email} already exists and is linked to student {other_student.display_name}.")
# Link to the existing user
self.portal_user_id = existing_user
return True
# Check or create res.partner
partner = self.env['res.partner'].sudo().search([('email', '=', self.email)], limit=1)
if not partner:
partner = self.env['res.partner'].sudo().create({
'name': self.full_name,
'email': self.email,
'phone': self.phone or self.mobile,
'type': 'contact',
'company_id': self.company_id.id,
})
# Generate secure temporary password
alphabet = string.ascii_letters + string.digits + string.punctuation
temp_password = ''.join(secrets.choice(alphabet) for i in range(12))
# Create user linked to partner
portal_group = self.env.ref('base.group_portal')
new_user = self.env['res.users'].sudo().create({
'name': self.full_name,
'login': self.email,
'email': self.email,
'partner_id': partner.id,
'company_id': self.company_id.id,
'company_ids': [(4, self.company_id.id)],
'group_ids': [(6, 0, [portal_group.id])],
'password': temp_password,
})
self.portal_user_id = new_user
# Log details to chatter
self.message_post(body=f"Portal user created.<br/><b>Username:</b> {self.email}<br/><b>Temporary Password:</b> {temp_password}")
# Check if SMTP is configured
smtp_configured = self.env['ir.mail_server'].sudo().search_count([('active', '=', True)]) > 0
if smtp_configured:
try:
template = self.env.ref('auth_signup.set_password_email', raise_if_not_found=False)
if template:
new_user.partner_id.signup_prepare()
template.send_mail(new_user.id, force_send=True)
else:
mail_values = {
'subject': f"Welcome to the University Portal, {self.full_name}",
'body_html': f"""
<p>Dear {self.full_name},</p>
<p>Your portal account has been created.</p>
<p><b>Username:</b> {self.email}</p>
<p><b>Temporary Password:</b> {temp_password}</p>
<p>Please log in and update your password.</p>
""",
'email_to': self.email,
}
mail = self.env['mail.mail'].sudo().create(mail_values)
mail.send()
except Exception:
smtp_configured = False
if not smtp_configured:
return {
'type': 'ir.actions.client',
'tag': 'display_notification',
'params': {
'title': 'Portal User Created',
'message': 'Portal user created successfully. Invitation email was not sent because no outgoing mail server is configured.',
'sticky': True,
'type': 'warning',
}
}
return True
def action_open_portal_user(self):
self.ensure_one()
if self.portal_user_id:
return {
'type': 'ir.actions.act_window',
'name': 'Portal User',
'res_model': 'res.users',
'res_id': self.portal_user_id.id,
'view_mode': 'form',
'target': 'current',
}
class ResUsers(models.Model):
_inherit = 'res.users'
student_ids = fields.One2many('education.student', 'portal_user_id', string='Students')
@property
def student_id(self):
return self.student_ids[0] if self.student_ids else self.env['education.student']