124 lines
4.9 KiB
Python

from odoo import fields, http
from odoo.http import request
from odoo.addons.portal.controllers.portal import CustomerPortal
class DanceCustomerPortal(CustomerPortal):
def _prepare_home_portal_values(self, counters):
values = super()._prepare_home_portal_values(counters)
if "dance_student_count" in counters:
values["dance_student_count"] = request.env["res.partner"].sudo().search_count(
self._get_portal_student_domain()
)
return values
def _get_portal_student_domain(self):
partner = request.env.user.partner_id
return [
("is_student", "=", True),
"|",
("guardian_id", "=", partner.id),
("guardian_ids", "in", [partner.id]),
]
def _get_portal_student(self, student_id):
student = request.env["res.partner"].sudo().browse(student_id)
if not student.exists() or not student.is_student:
return request.env["res.partner"]
if student in request.env["res.partner"].sudo().search(self._get_portal_student_domain()):
return student
return request.env["res.partner"]
def _get_student_portal_values(self, student):
today = fields.Date.context_today(request.env.user)
attendance = request.env["dance.attendance"].sudo().search(
[("student_id", "=", student.id)],
order="date desc, id desc",
)
invoices = request.env["account.move"].sudo().search(
[
("move_type", "=", "out_invoice"),
("state", "!=", "cancel"),
"|",
("dance_student_id", "=", student.id),
("partner_id", "=", student.id),
],
order="invoice_date desc, id desc",
)
enrollments = request.env["dance.enrollment"].sudo().search(
[("student_id", "=", student.id)],
order="enrollment_date desc, id desc",
)
active_batches = enrollments.filtered(lambda enrollment: enrollment.status == "active").mapped("batch_id")
upcoming_sessions = request.env["dance.session"].sudo().search(
[
("batch_id", "in", active_batches.ids),
("date", ">=", today),
("status", "=", "scheduled"),
],
order="date asc, start_time asc, id asc",
limit=20,
)
upcoming_events = request.env["dance.event.performance"].sudo().search(
[
("student_id", "=", student.id),
("event_id.date", ">=", today),
("event_id.state", "!=", "cancelled"),
],
order="id asc",
limit=20,
).sorted(lambda performance: (performance.event_id.date, performance.sequence, performance.id))
upcoming_rehearsals = request.env["dance.rehearsal"].sudo().search(
[
("event_id.performance_ids.student_id", "=", student.id),
("date", ">=", today),
("status", "=", "scheduled"),
],
order="date asc, start_time asc, id asc",
limit=20,
)
total_sessions = len(attendance)
present_sessions = len(attendance.filtered(lambda line: line.status != "absent"))
attendance_percent = (
round((present_sessions / total_sessions) * 100, 2)
if total_sessions
else 0.0
)
return {
"page_name": "dance_student",
"student": student,
"attendance": attendance,
"attendance_percent": attendance_percent,
"absent_count": len(attendance.filtered(lambda line: line.status == "absent")),
"invoices": invoices,
"enrollments": enrollments,
"upcoming_sessions": upcoming_sessions,
"upcoming_events": upcoming_events,
"upcoming_rehearsals": upcoming_rehearsals,
}
@http.route(["/my/students"], type="http", auth="user", website=True)
def portal_my_students(self, **kwargs):
students = request.env["res.partner"].sudo().search(
self._get_portal_student_domain(),
order="name",
)
values = self._prepare_portal_layout_values()
values.update(
{
"page_name": "dance_students",
"students": students,
}
)
return request.render("dance_portal.portal_my_students", values)
@http.route(["/my/students/<int:student_id>"], type="http", auth="user", website=True)
def portal_my_student_detail(self, student_id, **kwargs):
student = self._get_portal_student(student_id)
if not student:
return request.redirect("/my/students")
values = self._prepare_portal_layout_values()
values.update(self._get_student_portal_values(student))
return request.render("dance_portal.portal_my_student_detail", values)