67 lines
2.0 KiB
PL/PgSQL
67 lines
2.0 KiB
PL/PgSQL
-- =====================================================
|
|
-- Attendance Rollup
|
|
--
|
|
-- RPC that returns a per-participant attendance summary
|
|
-- for a given course: total sessions, sessions attended,
|
|
-- and attendance rate (%).
|
|
-- =====================================================
|
|
|
|
CREATE OR REPLACE FUNCTION public.get_course_attendance_summary(p_course_id uuid)
|
|
RETURNS TABLE (
|
|
participant_id uuid,
|
|
participant_name text,
|
|
enrollment_status public.enrollment_status,
|
|
total_sessions bigint,
|
|
sessions_attended bigint,
|
|
attendance_rate numeric
|
|
)
|
|
LANGUAGE plpgsql
|
|
STABLE
|
|
SECURITY DEFINER
|
|
SET search_path = ''
|
|
AS $$
|
|
BEGIN
|
|
-- Access check
|
|
IF NOT public.has_role_on_account(
|
|
(SELECT account_id FROM public.courses WHERE id = p_course_id)
|
|
) THEN
|
|
RAISE EXCEPTION 'Access denied'
|
|
USING ERRCODE = '42501';
|
|
END IF;
|
|
|
|
RETURN QUERY
|
|
WITH session_count AS (
|
|
SELECT count(*)::bigint AS cnt
|
|
FROM public.course_sessions
|
|
WHERE course_id = p_course_id
|
|
AND is_cancelled = false
|
|
)
|
|
SELECT
|
|
cp.id AS participant_id,
|
|
(cp.first_name || ' ' || cp.last_name)::text AS participant_name,
|
|
cp.status AS enrollment_status,
|
|
sc.cnt AS total_sessions,
|
|
COALESCE(count(ca.id) FILTER (WHERE ca.present = true), 0)::bigint AS sessions_attended,
|
|
CASE WHEN sc.cnt > 0 THEN
|
|
ROUND(
|
|
COALESCE(count(ca.id) FILTER (WHERE ca.present = true), 0)::numeric
|
|
/ sc.cnt * 100,
|
|
1
|
|
)
|
|
ELSE 0 END AS attendance_rate
|
|
FROM public.course_participants cp
|
|
CROSS JOIN session_count sc
|
|
LEFT JOIN public.course_attendance ca ON ca.participant_id = cp.id
|
|
LEFT JOIN public.course_sessions cs
|
|
ON cs.id = ca.session_id
|
|
AND cs.is_cancelled = false
|
|
WHERE cp.course_id = p_course_id
|
|
AND cp.status IN ('enrolled', 'completed')
|
|
GROUP BY cp.id, cp.first_name, cp.last_name, cp.status, sc.cnt
|
|
ORDER BY cp.last_name, cp.first_name;
|
|
END;
|
|
$$;
|
|
|
|
GRANT EXECUTE ON FUNCTION public.get_course_attendance_summary(uuid) TO authenticated;
|
|
GRANT EXECUTE ON FUNCTION public.get_course_attendance_summary(uuid) TO service_role;
|