Odoo_Dance_SCL/addons/dance_web/models/dance_enrollment_request.py
2026-09-28 11:03:02 +05:30

196 lines
7.2 KiB
Python

from odoo import api, fields, models
from odoo.exceptions import UserError
STYLE_SELECTION = [
("bharatanatyam", "Bharatanatyam"),
("kathak", "Kathak"),
("hiphop", "Hip-Hop"),
("contemporary", "Contemporary"),
("zumba", "Zumba"),
]
LEVEL_SELECTION = [
("beginner", "Beginner"),
("intermediate", "Intermediate"),
("advanced", "Advanced"),
]
class DanceEnrollmentRequest(models.Model):
_name = "dance.enrollment.request"
_description = "Website Enrollment Request"
_inherit = ["mail.thread"]
_order = "create_date desc, id desc"
_rec_name = "reference"
reference = fields.Char(default="New", readonly=True, copy=False, index=True)
student_name = fields.Char(string="Student Name", required=True, tracking=True)
date_of_birth = fields.Date()
gender = fields.Selection(
[("male", "Male"), ("female", "Female"), ("other", "Other")]
)
guardian_name = fields.Char(string="Parent / Guardian", required=True, tracking=True)
guardian_email = fields.Char(string="Email", required=True, tracking=True)
guardian_phone = fields.Char(string="Phone", required=True, tracking=True)
dance_style = fields.Selection(STYLE_SELECTION, string="Dance Style", tracking=True)
preferred_level = fields.Selection(LEVEL_SELECTION, string="Preferred Level")
batch_id = fields.Many2one("dance.batch", string="Preferred Batch")
message = fields.Text()
state = fields.Selection(
[
("new", "New Request"),
("contacted", "Contacted"),
("approved", "Approved"),
("rejected", "Rejected"),
("converted", "Enrolled"),
],
default="new",
required=True,
tracking=True,
)
student_id = fields.Many2one(
"res.partner", string="Student Record", readonly=True, copy=False
)
enrollment_id = fields.Many2one(
"dance.enrollment", string="Enrollment", readonly=True, copy=False
)
portal_user_id = fields.Many2one(
"res.users", string="Guardian Login", readonly=True, copy=False
)
@api.model_create_multi
def create(self, vals_list):
for vals in vals_list:
if vals.get("reference", "New") in ("New", False):
vals["reference"] = (
self.env["ir.sequence"].next_by_code("dance.enrollment.request")
or "New"
)
return super().create(vals_list)
# ── Workflow ──────────────────────────────────────────────────────────────
def action_mark_contacted(self):
self.filtered(lambda r: r.state == "new").write({"state": "contacted"})
def action_approve(self):
self.filtered(lambda r: r.state in ("new", "contacted")).write(
{"state": "approved"}
)
def action_reject(self):
self.filtered(lambda r: r.state not in ("converted",)).write(
{"state": "rejected"}
)
def action_reset_to_new(self):
self.filtered(lambda r: r.state != "converted").write({"state": "new"})
def action_convert(self):
for req in self:
if req.state == "converted":
continue
if req.state != "approved":
raise UserError(
"Only approved requests can be converted into an enrollment."
)
guardian = req._find_or_create_guardian()
student = req._create_student(guardian)
enrollment = self.env["dance.enrollment"]
if req.batch_id:
enrollment = enrollment.create(
{
"student_id": student.id,
"batch_id": req.batch_id.id,
"status": "active",
}
)
req.write(
{
"student_id": student.id,
"enrollment_id": enrollment.id if enrollment else False,
"state": "converted",
}
)
req._grant_guardian_portal(guardian)
req.message_post(
body="Enrollment request converted — student record %s created."
% student.display_name
)
return True
def action_open_student(self):
self.ensure_one()
return {
"type": "ir.actions.act_window",
"res_model": "res.partner",
"res_id": self.student_id.id,
"view_mode": "form",
}
# ── Conversion helpers ────────────────────────────────────────────────────
def _find_or_create_guardian(self):
self.ensure_one()
Partner = self.env["res.partner"]
guardian = Partner.browse()
if self.guardian_email:
guardian = Partner.search(
[("email", "=ilike", self.guardian_email)], limit=1
)
if not guardian:
guardian = Partner.create(
{
"name": self.guardian_name,
"email": self.guardian_email,
"phone": self.guardian_phone,
"is_student": False,
}
)
return guardian
def _create_student(self, guardian):
self.ensure_one()
return self.env["res.partner"].create(
{
"name": self.student_name,
"is_student": True,
"date_of_birth": self.date_of_birth,
"gender": self.gender,
"dance_style": self.dance_style,
"level": self.preferred_level,
"guardian_id": guardian.id,
"guardian_ids": [(4, guardian.id)],
"guardian_phone": self.guardian_phone,
"student_status": "active",
"join_date": fields.Date.context_today(self),
}
)
def _grant_guardian_portal(self, guardian):
"""Create a portal login for the guardian so they can reach /parent."""
self.ensure_one()
if self.portal_user_id or not guardian.email:
return
Users = self.env["res.users"].sudo()
existing = Users.with_context(active_test=False).search(
[("login", "=", guardian.email)], limit=1
)
if existing:
self.portal_user_id = existing
return
portal_group = self.env.ref("base.group_portal")
user = Users.with_context(no_reset_password=True).create(
{
"name": guardian.name,
"login": guardian.email,
"email": guardian.email,
"partner_id": guardian.id,
"groups_id": [(6, 0, [portal_group.id])],
}
)
self.portal_user_id = user
try:
user.with_context(create_user=True).action_reset_password()
except Exception:
# Mail server may not be configured — login still works once a
# password is set manually. Don't block the conversion.
pass