2026-09-28 11:03:02 +05:30

130 lines
4.6 KiB
Python

from odoo import api, fields, models
from odoo.exceptions import ValidationError
class DanceBatch(models.Model):
_name = "dance.batch"
_description = "Dance Batch"
_order = "start_date desc, name"
name = fields.Char(required=True)
dance_style = fields.Selection(
[
("bharatanatyam", "Bharatanatyam"),
("kathak", "Kathak"),
("hiphop", "Hip-Hop"),
("contemporary", "Contemporary"),
("zumba", "Zumba"),
],
string="Dance Style",
required=True,
)
level = fields.Selection(
[
("beginner", "Beginner"),
("intermediate", "Intermediate"),
("advanced", "Advanced"),
],
required=True,
)
instructor_id = fields.Many2one("hr.employee", string="Instructor", required=True)
room = fields.Char()
capacity = fields.Integer(default=20)
active_enrollment_count = fields.Integer(
string="Current Strength",
compute="_compute_enrollment_counts",
store=True,
)
enrollment_count = fields.Integer(compute="_compute_enrollment_counts", store=True)
available_seats = fields.Integer(compute="_compute_enrollment_counts", store=True)
is_almost_full = fields.Boolean(compute="_compute_capacity_warning")
capacity_warning = fields.Char(compute="_compute_capacity_warning")
start_date = fields.Date(required=True)
end_date = fields.Date()
start_time = fields.Float(string="Start Time")
end_time = fields.Float(string="End Time")
schedule_days = fields.Char(
string="Schedule Days",
help="Example: Sat or Mon/Wed",
)
status = fields.Selection(
[
("upcoming", "Upcoming"),
("active", "Active"),
("completed", "Completed"),
("cancelled", "Cancelled"),
],
default="upcoming",
required=True,
)
enrollment_ids = fields.One2many(
"dance.enrollment",
"batch_id",
string="Enrollments",
)
@api.depends("enrollment_ids.status", "capacity")
def _compute_enrollment_counts(self):
for batch in self:
active_enrollments = batch.enrollment_ids.filtered(
lambda enrollment: enrollment.status == "active"
)
batch.active_enrollment_count = len(active_enrollments)
batch.enrollment_count = len(batch.enrollment_ids)
batch.available_seats = max(batch.capacity - len(active_enrollments), 0)
@api.depends("active_enrollment_count", "capacity", "available_seats")
def _compute_capacity_warning(self):
for batch in self:
batch.is_almost_full = bool(
batch.capacity
and batch.active_enrollment_count < batch.capacity
and batch.available_seats <= 2
)
if batch.is_almost_full:
batch.capacity_warning = "Batch almost full (%s/%s)" % (
batch.active_enrollment_count,
batch.capacity,
)
elif batch.capacity and batch.active_enrollment_count >= batch.capacity:
batch.capacity_warning = "Batch is full (%s/%s)" % (
batch.active_enrollment_count,
batch.capacity,
)
else:
batch.capacity_warning = False
@api.constrains("capacity")
def _check_capacity(self):
for batch in self:
if batch.capacity < 0:
raise ValidationError("Capacity cannot be negative.")
if batch.capacity and batch.active_enrollment_count > batch.capacity:
raise ValidationError("Capacity cannot be less than current strength.")
@api.constrains("start_date", "end_date")
def _check_dates(self):
for batch in self:
if batch.end_date and batch.start_date and batch.end_date < batch.start_date:
raise ValidationError("End date cannot be before start date.")
@api.constrains("start_time", "end_time")
def _check_times(self):
for batch in self:
if batch.end_time and batch.start_time and batch.end_time <= batch.start_time:
raise ValidationError("End time must be after start time.")
def action_view_enrollments(self):
self.ensure_one()
return {
"name": "Enrollments",
"type": "ir.actions.act_window",
"res_model": "dance.enrollment",
"view_mode": "tree,form",
"domain": [("batch_id", "=", self.id)],
"context": {"default_batch_id": self.id},
}