Code Coverage
 
Classes and Traits
Functions and Methods
Lines
Total
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 11
CRAP
0.00% covered (danger)
0.00%
0 / 505
ExamAttendanceService
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 11
5852.00
0.00% covered (danger)
0.00%
0 / 505
 __construct
0.00% covered (danger)
0.00%
0 / 1
2.00
0.00% covered (danger)
0.00%
0 / 2
 getAllAssessmentsForExamAttendance
0.00% covered (danger)
0.00%
0 / 1
56.00
0.00% covered (danger)
0.00%
0 / 35
 checkIfAttendanceTakenForSingleAssessment
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 16
 getNotArrangedExamAttendanceEntry
0.00% covered (danger)
0.00%
0 / 1
110.00
0.00% covered (danger)
0.00%
0 / 48
 getAllExamRegisteredStudentDetailsWithAttendanceStatus
0.00% covered (danger)
0.00%
0 / 1
240.00
0.00% covered (danger)
0.00%
0 / 112
 saveExamAttendanceDetails
0.00% covered (danger)
0.00%
0 / 1
156.00
0.00% covered (danger)
0.00%
0 / 51
 getStudentDetailsByRegisterNo
0.00% covered (danger)
0.00%
0 / 1
30.00
0.00% covered (danger)
0.00%
0 / 23
 getStudentAssessmentDetailsByRegisterNo
0.00% covered (danger)
0.00%
0 / 1
110.00
0.00% covered (danger)
0.00%
0 / 62
 getAllSubjectsForAttendanceReportByExamRegistrationId
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 32
 getExamAttendanceDetailsBySubject
0.00% covered (danger)
0.00%
0 / 1
72.00
0.00% covered (danger)
0.00%
0 / 75
 getAttendanceDetailsByAssessmentId
0.00% covered (danger)
0.00%
0 / 1
20.00
0.00% covered (danger)
0.00%
0 / 49
<?php
namespace com\linways\ec\core\service;
use com\linways\base\util\MakeSingletonTrait;
use com\linways\ec\core\exception\ExamControllerException;
use com\linways\ec\core\service\ExamRegistrationSubjectService;
use com\linways\core\ams\professional\service\CommonService;
use com\linways\core\ams\professional\constant\SettingsConstants;
use com\linways\ec\core\mapper\ExamAttendanceServiceMapper;
use com\linways\core\ams\professional\constant\examcontroller\ExamRegistrationFeePaymentConstants;
use com\linways\oe\core\service\ExamUserMarkService;
use com\linways\base\util\TwigRenderer;
use com\linways\core\ams\professional\util\PdfUtil;
class ExamAttendanceService extends BaseService
{
    use MakeSingletonTrait;
    private function __construct() {
        $this->mapper = ExamAttendanceServiceMapper::getInstance()->getMapper();
    }
      /**
     * get All assessment for exam attendance
     * @param $searchRequest 
     * @return $response 
     * @author Krishnajith
     */
    public function getAllAssessmentsForExamAttendance($searchRequest) {
        $searchRequest = $this->realEscapeObject($searchRequest);
        try{
            $isQPCodeDisplayInExamAttedance = CommonService::getInstance()->getSettings(SettingsConstants::EXAM_ATTENDANCE, SettingsConstants::IS_DISPALY_QP_CODE_IN_EXAM_ATTENDANCE);
            $examRegistrationDetails = new \stdClass;
            $response = new \stdClass;
            $request = new \stdClass;
            $request->courseTypeId = $searchRequest->courseTypeId;
            $request->examType = $searchRequest->examType;
            $request->examDate = $searchRequest->examDate;
            $request->examRegistrationId = $searchRequest->examRegistrationId;
            $assessments = [];
            $assessments = ExamRegistrationSubjectService::getInstance()->getAllAssessmentDetails($request);
            if(empty($assessments)){
                throw new ExamControllerException(ExamControllerException::NO_ASSESSMENTS_IN_THIS_EXAM_REGISTRATION,"No Exam(s) Found");
            }
            foreach($assessments as $assessment){
                $assessment->groupNames = array_column($assessment->groups, 'groupName');
                $assessment->groupName =  implode(", ",$assessment->groupNames);
                $assessment->assessmentStartTime =  $assessment->assessmentStartTime ? date("h:i A", strtotime($assessment->assessmentStartTime)) : '';
                $assessment->assessmentEndTime =  $assessment->assessmentEndTime ? date("h:i A", strtotime($assessment->assessmentEndTime)) : '';
            }
            $examRegistrationDetails->examRegistrationName = reset($assessments)->examRegistrationName;
            $examRegistrationDetails->assessmentDate = date("d-M-Y", strtotime(reset($assessments)->assessmentDate));
            foreach($assessments as $assessment){
                $assessment->isAttendanceTaken = $this->checkIfAttendanceTakenForSingleAssessment($assessment->id);
            }
            $response->assessments = $assessments;
            $response->isQPCodeDisplay = (int)$isQPCodeDisplayInExamAttedance;
            $response->examRegistrationDetails = $examRegistrationDetails;
            
            return $response;
        }
        catch (\Exception $e){
            throw new ExamControllerException($e->getCode(),$e->getMessage());
        }
    }
    /**
     * check If Attendance Taken For  Single Assessment
     * @param $assessmentId 
     * @return $isAttendanceTaken 
     * @author Krishnajith
     */
    public function checkIfAttendanceTakenForSingleAssessment($assessmentId){
        $assessmentId = $this->realEscapeString($assessmentId);
        try {
            $query = "SELECT EXISTS (SELECT
                        id
                    FROM
                        oe_student_total_mark ostm
                    WHERE
                        ostm.am_assessment_id = '$assessmentId') AS isAttendanceTaken";
            $isAttendanceTaken  = $this->executeQueryForObject($query);
        }
        catch (\Exception $e)
        {
            throw new ExamControllerException($e->getCode(),$e->getMessage());
        }
        return $isAttendanceTaken->isAttendanceTaken;
    }
     /**
     * get Not Arranged Exam Attendance Entry
     * @param $searchRequest 
     * @return $response 
     * @author Krishnajith
     */
    public function getNotArrangedExamAttendanceEntry($searchRequest) {
        $searchRequest = $this->realEscapeObject($searchRequest);
        try{
            $isQPCodeDisplayInExamAttedance = CommonService::getInstance()->getSettings(SettingsConstants::EXAM_ATTENDANCE, SettingsConstants::IS_DISPALY_QP_CODE_IN_EXAM_ATTENDANCE);
            $assessmentDetails = new \stdClass;
            $response = new \stdClass;
            $request = new \stdClass;
            $request->assessmentId = $searchRequest->assessmentId;
            $request->examRegistrationId = $searchRequest->examRegistrationId;
            if(empty($request->assessmentId) || empty($request->examRegistrationId)){
                throw new ExamControllerException(ExamControllerException::EMPTY_PARAMETERS_EXAM_ATTENDANCE,"Invailed Request For Exam Attendance");
            }
            $examRegisteredStudents = [];
            $examRegisteredStudents = $this->getAllExamRegisteredStudentDetailsWithAttendanceStatus($request);
            if(empty($examRegisteredStudents)){
                throw new ExamControllerException(ExamControllerException::NO_STUDENTS_REGISTEDED_OR_PAID,"No Student(s) Found");
            }
            $assessmentDetails->isEnablePrint = false;
            $assessmentDetails->examRegistrationName = reset($examRegisteredStudents)->examRegistrationName;
            $assessmentDetails->groupNames = array_column($examRegisteredStudents, 'groupName');
            $assessmentDetails->groupNames = array_unique($assessmentDetails->groupNames);
            $assessmentDetails->groupName =  implode(", ",$assessmentDetails->groupNames);
            // $assessmentDetails->groupName = reset($examRegisteredStudents)->groupName;
            $assessmentDetails->degreeName = reset($examRegisteredStudents)->degreeName;
            $assessmentDetails->academicTermName = reset($examRegisteredStudents)->academicTermName;
            $assessmentDetails->assessmentDate = date("d-M-Y", strtotime(reset($examRegisteredStudents)->assessmentDate));
            $assessmentDetails->subjectCode = reset($examRegisteredStudents)->subjectCode;
            $assessmentDetails->subjectName = reset($examRegisteredStudents)->subjectName;
            $assessmentDetails->subjectIsTheory = reset($examRegisteredStudents)->subjectIsTheory;
            $assessmentDetails->assessmentStartTime = reset($examRegisteredStudents)->assessmentStartTime ? date("h:i A", strtotime(reset($examRegisteredStudents)->assessmentStartTime)) : '';
            $assessmentDetails->assessmentEndTime = reset($examRegisteredStudents)->assessmentEndTime ? date("h:i A", strtotime(reset($examRegisteredStudents)->assessmentEndTime)) : '';
            $assessmentDetails->qpCode = reset($examRegisteredStudents)->qpCode;
            $assessmentDetails->isAttendanceTaken = $this->checkIfAttendanceTakenForSingleAssessment(reset($examRegisteredStudents)->assessmentId);
            if($assessmentDetails->isAttendanceTaken == 1){
                $assessmentDetails->isEnablePrint = true;
            }
            foreach($examRegisteredStudents as $student){
                if(empty($student->attendanceStatus)){
                    $student->attendanceStatus = "PRESENT";
                }
            }
            $response->examRegisteredStudents = $examRegisteredStudents;
            $response->isQPCodeDisplay = (int)$isQPCodeDisplayInExamAttedance;
            $response->assessmentDetails = $assessmentDetails;
            
            return $response;
        }
        catch (\Exception $e){
            throw new ExamControllerException($e->getCode(),$e->getMessage());
        }
    }
    /**
     * check If Attendance Taken For  Single Assessment
     * @param $searchRequest 
     * @return $registeredStudentsDetails 
     * @author Krishnajith
     */
    public function getAllExamRegisteredStudentDetailsWithAttendanceStatus($searchRequest){
        $searchRequest = $this->realEscapeObject($searchRequest);
        try{
            $whereQuery = null;
            $orderBy = " ORDER BY sa.regNo ASC ";
            $whereQuery = "";
            if(!empty($searchRequest->assessmentId)) {
                $assessmentIdString = is_array($searchRequest->assessmentId) ? "'" . implode("','",$searchRequest->assessmentId) . "'" : "'".$searchRequest->assessmentId."'";
                $whereQuery .= " AND aa.id IN ( $assessmentIdString )";
            }
            if(!empty($searchRequest->examRegistrationId)) {
                $examRegistrationIdString = is_array($searchRequest->examRegistrationId) ? "'" . implode("','",$searchRequest->examRegistrationId) . "'" : "'".$searchRequest->examRegistrationId."'";
                $whereQuery .= " AND eer.id IN ( $examRegistrationIdString )";
            }
            if(!empty($searchRequest->subjectId)) {
                $subjectIdString = is_array($searchRequest->subjectId) ? "" . implode(",",$searchRequest->subjectId) . "" : "".$searchRequest->subjectId."";
                $whereQuery .= " AND s.id IN ( $subjectIdString )";
            }
            if($searchRequest->registrationStatus == "REGISTERED") {
                $whereQuery .= "AND esar.properties ->> '$.registrationStatus' = 'REGISTERED'";
            }
            if($searchRequest->examDate) {
                $examDateString = is_array($searchRequest->examDate) ? "'" . implode("','",$searchRequest->examDate) . "'" : "'".$searchRequest->examDate."'";
                $whereQuery .= " AND aa.properties_value ->>'$.assessmentDate' IN ( $examDateString )";
            }
            $joinRoom = "";
            if($searchRequest->roomNo && $searchRequest->getRoomNo) {
                $joinRoom = " INNER JOIN subjectWiseSubmissions sws ON sws.userId = sa.studentID AND sws.identifier =  eer.id AND identifierType ='EXAM_REGISTRATION' AND userType ='STUDENT' AND entryType ='EXAM_REG_STUDENT_ROOM_NO' ";
                $whereQuery .= " AND sws.properties ->> '$.roomNo' = '".$searchRequest->roomNo."'";
            }
            $joinTable = "";
            if($joinRoom){
                $joinTable .= $joinRoom;
            }
            $query = "SELECT
                        DISTINCT 
                        sa.studentID AS id,
                        sa.studentID AS studentId,
                        sa.studentName,
                        sa.regNo,
                        sa.rollNo,
                        eers.am_assessment_id as assessmentId,
                        g.id as groupId,
                        g.name as groupName,
                        eer.id as examRegistrationId,
                        eer.name as examRegistrationName,
                        s.code as subjectCode,
                        s.name as subjectName,
                        IF(aps.properties ->> '$.classType' = 'THEORY',1,0) AS isTheory,
                        aps.properties ->> '$.syllabusName' AS syllabusName,
                        oe.id as oeExamId,
                        aa.properties_value ->>'$.assessmentDate' AS assessmentDate,
                        aa.properties_value ->>'$.startTime' AS assessmentStartTime,
                        aa.properties_value ->>'$.endTime' AS assessmentEndTime,
                        act.id as academicTermId,
                        act.name as academicTermName,
                        dept.deptID,
                        dept.deptName,
                        deg.id as degreeId,
                        deg.name as degreeName,
                        ostmf.attendance_status as attendanceStatus,
                        ostmf.properties as markProperties,
                        ostmf.mark_obtained as finalizedMark,
                        eqc.qpCode  
                    FROM
                        `groups` g
                    INNER JOIN ec_exam_registration_batch eerb ON
                        eerb.groups_id = g.id
                    INNER JOIN ec_exam_registration eer ON
                        eer.id = eerb.ec_exam_registration_id
                    INNER JOIN ec_exam_registration_subject eers ON
                        eers.ec_exam_registration_batch_id = eerb.id
                    INNER JOIN  cm_academic_paper_subjects aps ON 
                        eers.cm_academic_paper_subjects_id = aps.id
                    INNER JOIN am_assessment aa ON
                        aa.id = eers.am_assessment_id
                    INNER JOIN oe_exams oe ON
                        oe.assessment_id =  aa.id AND oe.is_deleted = 0
                    INNER JOIN  v4_ams_subject s ON 
                        aps.ams_subject_id = s.id
                    INNER JOIN ec_student_assessment_registration esar ON
                        esar.am_assessment_id = eers.am_assessment_id AND CAST(esar.properties ->> '$.registrationStatus' AS CHAR) = 'REGISTERED' AND CAST(esar.properties ->> '$.feeStatus' AS CHAR) = 'PAID' AND esar.ec_exam_registration_type = eer.type
                    INNER JOIN studentaccount sa ON 
                        sa.studentID = esar.student_id
                    INNER JOIN department dept ON
                        dept.deptID = g.properties ->> '$.departmentId'
                    INNER JOIN  academic_term act ON 
                        act.id = CAST(eerb.properties ->> '$.academicTermId'AS CHAR)
                    INNER JOIN program p ON
                        p.id = g.properties ->> '$.programId'
                    INNER JOIN student_program_account spa ON 
                        spa.current_program_id = p.id AND 
                        spa.student_id = esar.student_id 
                    INNER JOIN degree deg ON
                        deg.id = p.degree_id
                    LEFT JOIN examQpCodes eqc ON
                        eqc.cm_academic_paper_subjects_id = aps.id AND eqc.ec_exam_registration_id = eer.id
                    LEFT JOIN oe_student_total_mark ostmf ON 
                        ostmf.student_id = sa.studentID AND ostmf.am_assessment_id = esar.am_assessment_id AND ostmf.valuation_count = 'FINALIZED'
                    $joinTable
                    WHERE 1=1  AND (CAST(esar.properties ->> '$.syllabusSubType' AS CHAR) != 'MOOC' OR esar.properties ->> '$.syllabusSubType' IS NULL) ";
            if($searchRequest->excludeMapper){
                $registeredStudentsDetails = $this->executeQueryForList($query.$whereQuery.$orderBy);
            }else{
                $registeredStudentsDetails = $this->executeQueryForList($query.$whereQuery.$orderBy, $this->mapper[ExamAttendanceServiceMapper::GET_STUDENT_ATTENDANCE_DETAILS] );
            }
        }
        catch (\Exception $e)
        {
            throw new ExamControllerException($e->getCode(),$e->getMessage());
        }
        return $registeredStudentsDetails;
    }
    /**
     * save Exam Attendance Details
     * @param $searchRequest 
     * @return $registeredStudentsDetails 
     * @author Krishnajith
     */
    public function saveExamAttendanceDetails($searchRequest){
        $searchRequest = $this->realEscapeObject($searchRequest);
        try{
            $staffId = $GLOBALS['userId'];
            $insertionValues = [];
            $properties = new \Stdclass();
            $properties->valuationType = "FINALIZED";
            $properties = !empty($properties) ? "'" . json_encode($properties) . "'" : "NULL";
            $studentExamAttendanceDetails = $searchRequest->studentExamAttendanceDetails;
            if(empty($studentExamAttendanceDetails)){
                throw new ExamControllerException(ExamControllerException::EMPTY_PARAMETERS_EXAM_ATTENDANCE,"No Student(s) Found");
            }
            foreach($studentExamAttendanceDetails as $student){
                if(empty($student['studentId']) || empty($student['assessmentId'])){
                    throw new ExamControllerException(ExamControllerException::EMPTY_PARAMETERS_EXAM_ATTENDANCE,"Invailed Request For Save Exam Attendance");
                }
                else{
                    $attendanceStatus = "'PRESENT'";
                    if($student['attendanceStatus'] == "MALPRACTICE"){
                        $attendanceStatus = "MALPRACTICE";
                    }
                    elseif($student['attendanceStatus'] == "ABSENT"){
                        $attendanceStatus = "ABSENT";
                    }
                    elseif($student['attendanceStatus'] == "PRESENT"){
                        $attendanceStatus = "PRESENT";
                    }
                    $markEntryObj = new \stdClass();
                    $markEntryObj->studentId = $student['studentId'];
                    $markEntryObj->assessmentId = $student['assessmentId'];
                    $markEntryObj->oeExamsId = $student['oeExamId'];
                    $markEntryObj->markObtained = $student['finalizedMark'] ?? null;
                    $markEntryObj->attendanceStatus = $attendanceStatus;
                    $markEntryObj->valuationCount = 'FINALIZED';
                    $markproperties = "";
                    if($student['markProperties']){
                        $markproperties = (object)$student['markProperties'];
                    }
                    $markEntryObj->properties  = $markproperties;
                    $markEntryObj->valuationType = null;
                    $insertionValues[] = $markEntryObj;
                }
            }
            if( !empty ( $insertionValues ) ){
                ExamUserMarkService::getInstance()->saveExamUserTotalMark($insertionValues);
            }
        }
        catch (\Exception $e)
        {
            throw new ExamControllerException($e->getCode(),$e->getMessage());
        }
    }
 
    /**
     * get Student Details By register no
     * @param $studentDetailsRequest 
     * @return $studentRegisterNoList 
     * @author Krishnajith
     */
    public function getStudentDetailsByRegisterNo($studentDetailsRequest){
        $studentDetailsRequest = $this->realEscapeObject($studentDetailsRequest);
        try{
            $registerNoList = $studentDetailsRequest->registerNoList;
            $studentRegisterNoList = [];
            if($registerNoList == null || empty($registerNoList)){
                throw new ExamControllerException(ExamControllerException::EMPTY_PARAMETERS,"Invailed Request For Get Student Details By Register No");
            }
            $registerNoList = is_array($registerNoList) ? "'" . implode("','",$registerNoList) . "'" : "'".$registerNoList."'";
            $query = "SELECT
                        spa.student_id AS id, 
                        spa.properties->>'$.registerNumber' as registerNo
                    FROM
                        student_program_account spa
                    WHERE
                        spa.properties->>'$.registerNumber' IN ( $registerNoList )";
            $studentList = $this->executeQueryForList($query );
            $studentRegisterNoList = array_column($studentList, null, 'registerNo');
        }
        catch (\Exception $e){
            throw new ExamControllerException($e->getCode(),$e->getMessage());
        }
        return $studentRegisterNoList;
    }
    /**
     * get Student Assessment Details By register no
     * @param $studentAssessmentRequest 
     * @param $fetchNotInRegisterNo 
     * @return $studentAssessmentDetailsByRegNo 
     * @throws ExamControllerException
     */
    public function getStudentAssessmentDetailsByRegisterNo($studentAssessmentRequest,$fetchNotInRegisterNo = false){
        $studentAssessmentRequest = $this->realEscapeObject($studentAssessmentRequest);
        try{
            $whereQuery = null;
            $groupBy = " GROUP by spa.student_id";
            $registerNoList = $studentAssessmentRequest->registerNoList;
            $examDate = $studentAssessmentRequest->examDate;
            $examRegistrationId = $studentAssessmentRequest->examRegistrationId;
            $studentAssessmentDetailsByRegNo = [];
            if($registerNoList == null || empty($registerNoList) || empty($examDate) || empty($examRegistrationId)){
                throw new ExamControllerException(ExamControllerException::EMPTY_PARAMETERS,"Invailed Request For Get Student Assessment Details By Register No");
            }
            $registerNoList = is_array($registerNoList) ? "'" . implode("','",$registerNoList) . "'" : "'".$registerNoList."'";
            if($fetchNotInRegisterNo){
                $whereQuery .= " AND spa.properties->>'$.registerNumber' NOT IN ( $registerNoList ) ";
            }
            else{
                $whereQuery .= " AND spa.properties->>'$.registerNumber' IN ( $registerNoList ) ";
            }
            $registerNoList = is_array($registerNoList) ? "'" . implode("','",$registerNoList) . "'" : "'".$registerNoList."'";
            $query = "SELECT
                        spa.student_id AS id,
                         spa.student_id AS studentId,
                        spa.properties->>'$.registerNumber' AS registerNo,
                        aa.id as assessmentId,
                        eerb.groups_id as groupId,
                        oe.id as oeExamId,
                        ostmf.id as studentTotalMarkId,
                        ostmf.properties as markProperties,
                        ostmf.mark_obtained as finalizedMark,
                        ostmf.attendance_status as attendanceStatus
                    FROM
                        ec_student_assessment_registration esar
                    INNER JOIN student_program_account spa ON 
                        spa.student_id = esar.student_id
                    INNER JOIN am_assessment aa ON
                        aa.id = esar.am_assessment_id
                    INNER JOIN oe_exams oe ON
                        oe.assessment_id = aa.id AND oe.is_deleted = 0
                    INNER JOIN ec_exam_registration_subject eers ON
                        eers.am_assessment_id = aa.id
                    INNER JOIN ec_exam_registration_batch eerb ON
                        eerb.id = eers.ec_exam_registration_batch_id
                    INNER JOIN ec_exam_registration eer ON
                        eer.id = eerb.ec_exam_registration_id    
                    LEFT JOIN oe_student_total_mark ostmf ON    
                        ostmf.student_id = esar.student_id AND ostmf.am_assessment_id = esar.am_assessment_id AND ostmf.valuation_count = 'FINALIZED'    
                    WHERE 1=1 AND esar.properties ->> '$.registrationStatus' = 'REGISTERED'
                    AND aa.properties_value ->>'$.assessmentDate' = '$examDate
                    AND eerb.ec_exam_registration_id = '$examRegistrationId
                    AND esar.ec_exam_registration_type = eer.type ";
            $studentAssessmentDetails = $this->executeQueryForList($query.$whereQuery.$groupBy );
            foreach($studentAssessmentDetails as $student){
                $student->markProperties = json_decode($student->markProperties ?? null);
                $studentAssessmentDetailsByRegNo[$student->registerNo] = $student;
            }
            return $studentAssessmentDetailsByRegNo;
        }
        catch (\Exception $e){
            throw new ExamControllerException($e->getCode(),$e->getMessage());
        }
        return $studentAssessmentDetailsByRegNo;
    }
 
      /**
     * get All Subjects For QP Code By Exam Registration Id
     * @param $examRegistrationId 
     * @param $examRegistrationBatchId
     * @return $subjects 
     */
     public function getAllSubjectsForAttendanceReportByExamRegistrationId($request)
     {
         $request = $this->realEscapeObject($request);
         
         try
         {
             $query = "SELECT
                         aps.id as academicPaperSubjectId,
                         eers.am_assessment_id as assessmentId,
                         s.code as code,
                         s.name as name,
                         s.id as subjectId,
                         IF(aps.properties ->> '$.classType' = 'THEORY',1,0) AS isTheory,
                         eqc.qpCode
                     FROM
                         ec_exam_registration_subject eers
                     INNER JOIN ec_exam_registration_batch eerb ON
                             eerb.id = eers.ec_exam_registration_batch_id
                     INNER JOIN  cm_academic_paper_subjects aps ON 
                             eers.cm_academic_paper_subjects_id = aps.id
                     INNER JOIN  v4_ams_subject s ON 
                             aps.ams_subject_id = s.id
                     LEFT JOIN examQpCodes eqc ON
                         eqc.cm_academic_paper_subjects_id = aps.id AND eqc.ec_exam_registration_id = eerb.ec_exam_registration_id
                     WHERE
                         eerb.ec_exam_registration_id='$request->examRegistrationId' ORDER BY s.code ASC ";
             $subjects = $this->executeQueryForList($query);
         }
         catch (\Exception $e)
         {
             throw new ExamControllerException($e->getCode(),$e->getMessage());
         }
         return $subjects;
     }
 
    /**
     * print Subject QP code
     * @param request $request
     */
    public function getExamAttendanceDetailsBySubject($request)
    {
        $request = $this->realEscapeObject($request);
        try
        {
            $attendanaceDetails = new \stdClass();
            $studentAttendance = $this->getAttendanceDetailsByAssessmentId($request);
            if(empty($studentAttendance))
            {
                throw new ExamControllerException(ExamControllerException::NO_SUBJECTS,"No Details Founds");
            }
            else
            {
               foreach($studentAttendance as $student){
                    $attendanaceDetails->attendedStudentsCount++;
                    $attendanaceDetails->code = $student->subjectCode;
                    $attendanaceDetails->subjectName = $student->subjectName;
                    $attendanaceDetails->examRegName = $student->examRegName;
                    $attendanaceDetails->qpCode = $student->qpCode;
                    if ( empty($student->attendanceStatus) )
                    {
                        $attendanaceDetails->notMarkedStudents[] = $student->registerNumber;
                        $attendanaceDetails->notMarkedStudentsCount++;
                    }
                    else if ( $student->attendanceStatus == "ABSENT" )
                    {
                        $attendanaceDetails->absentStudents[] = $student->registerNumber;
                        $attendanaceDetails->absentStudentsCount++;
                    }
                    else if ( $student->attendanceStatus == "PRESENT" )
                    {
                        $attendanaceDetails->presentStudents[] = $student->registerNumber;
                        $attendanaceDetails->presentStudentsCount++;
                    }
                    else if ( $student->attendanceStatus == "MALPRACTICE" )
                    {
                        $attendanaceDetails->malpracticeStudents[] = $student->registerNumber;
                        $attendanaceDetails->malpracticeStudentsCount++;
                    }
               }
                $attendanaceDetails->presentStudents = array_chunk($attendanaceDetails->presentStudents, ceil($attendanaceDetails->presentStudentsCount/3));
                $attendanaceDetails->reportDate = date("d-m-Y");
                $attendanaceDetails->reportTime = date("h:i:s A");
                $attendanaceDetails->collegeData = CommonExamService::getInstance()->getCollegeDetails();
                $templateName = "examAttendanceReport";
                $responseHtml = TwigRenderer::renderTemplateFileToHtml(realpath(DOCUMENT_ROOT."../examcontroller-api/src/com/linways/web/templates/examAttendanceReport/$templateName.twig"), [ 'attendanaceDetails'=>$attendanaceDetails ]);
                $prtContent = NULL;
                    $prtContent .= '<html><head>';
                    $prtContent .= "<style>
                        
                        </style>";
                    $prtContent .= '</head><title>QP Code Report</title><body>';
                    $prtContent .= $responseHtml;
                    $prtContent .= '</body></html>';
                    $totalWidth = 210;
                    $totalHeight = 297;
                    $options = array(
                        'page-width'     => $totalWidth."mm",
                        'page-height'    => $totalHeight."mm",
                        'dpi'            => 96,
                        'margin-top' => "9mm",
                        'margin-left' => "1mm",
                        'margin-right' => "1mm",
                        'margin-bottom' => "9mm",
                        // 'binary' => "/usr/local/bin/wkhtmltopdf", // For Mac
                        'user-style-sheet' => realpath(DOCUMENT_ROOT . "/libcommon/bootstrap/css/bootstrap.min.css")
                    );
                $programResult = new \stdClass;
                $programResult->displayData = $responseHtml;
                $programResult->pdf = PdfUtil::renderPdf($prtContent, $options);
                return  $programResult;
            }
        }
        catch (\Exception $e)
        {
            throw new ExamControllerException($e->getCode(),$e->getMessage());
        }
        
    }
    /**
     * Retrieves attendance details based on the provided assessment ID(s).
     *
     * @param object $request The request object containing the assessment ID(s).
     * @return array The list of attendance details.
     * @throws ExamControllerException If an error occurs during the query execution.
     */
    public function getAttendanceDetailsByAssessmentId($request){
        $request = $this->realEscapeObject($request);
        try
        {
            $whereQuery = null;
            $orderBy = "ORDER BY CAST(spa.properties->>'$.registerNumber' AS UNSIGNED) ASC, spa.properties->>'$.registerNumber' ASC";
            if($request->assessmentId){
                $assessmentIdString = is_array($request->assessmentId) ? "'" . implode("','",$request->assessmentId) . "'" : "'".$request->assessmentId."'";
                $whereQuery .= " AND esar.am_assessment_id IN ( $assessmentIdString ) ";
            }
            $query = "SELECT
                vas.code as subjectCode,
                vas.name as subjectName,
                eer.name as examRegName,
                eqc.qpCode,
                ostm.attendance_status as attendanceStatus,
                spa.properties->>'$.registerNumber' as registerNumber
            FROM
                ec_student_assessment_registration esar
            INNER JOIN ec_exam_registration_subject eers ON
                eers.am_assessment_id = esar.am_assessment_id
            INNER JOIN ec_exam_registration_batch eerb On
                eerb.id = eers.ec_exam_registration_batch_id
            INNER JOIN ec_exam_registration eer ON
                eer.id = eerb.ec_exam_registration_id
            INNER JOIN cm_academic_paper_subjects caps ON
                caps.id = eers.cm_academic_paper_subjects_id
            INNER JOIN v4_ams_subject vas ON
                vas.id = caps.ams_subject_id
            INNER JOIN student_program_account spa ON
                spa.student_id = esar.student_id
            LEFT JOIN oe_student_total_mark ostm ON
                ostm.am_assessment_id = esar.am_assessment_id
                AND ostm.student_id = esar.student_id
                AND (ostm.valuation_type IS NULL
                    OR ostm.valuation_type = '')
                AND valuation_count = 'FINALIZED'
            LEFT JOIN examQpCodes eqc ON
                eqc.cm_academic_paper_subjects_id = caps.id
                AND eqc.ec_exam_registration_id = eerb.ec_exam_registration_id
            WHERE
                esar.properties ->>'$.registrationStatus' = 'REGISTERED' ";
            $subjects = $this->executeQueryForList($query.$whereQuery.$orderBy);
        }
        catch (\Exception $e)
        {
            throw new ExamControllerException($e->getCode(),$e->getMessage());
        }
        return $subjects;
    }
}