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 / 29
CRAP
0.00% covered (danger)
0.00%
0 / 924
CoPoAttainmentService
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 29
35910.00
0.00% covered (danger)
0.00%
0 / 924
 __construct
0.00% covered (danger)
0.00%
0 / 1
2.00
0.00% covered (danger)
0.00%
0 / 3
 __clone
0.00% covered (danger)
0.00%
0 / 1
2.00
0.00% covered (danger)
0.00%
0 / 2
 getInstance
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 5
 getMaxDescriptorDetails
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 12
 calculateCoAttainment
0.00% covered (danger)
0.00%
0 / 1
1640.00
0.00% covered (danger)
0.00%
0 / 175
 upsertCoAttainment
0.00% covered (danger)
0.00%
0 / 1
42.00
0.00% covered (danger)
0.00%
0 / 26
 getCoWiseStudentListForAttainmentCalculation
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 21
 getAllCoAttainmentOfANode
0.00% covered (danger)
0.00%
0 / 1
42.00
0.00% covered (danger)
0.00%
0 / 34
 processAllCoAttainmentDataOfANodeToArray
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 6
 getTreeDetailsByDepartmentId
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 10
 calculatePoAttainment
0.00% covered (danger)
0.00%
0 / 1
1892.00
0.00% covered (danger)
0.00%
0 / 205
 calculatePoAttainmentForStudentMarkEntryMethod
0.00% covered (danger)
0.00%
0 / 1
20.00
0.00% covered (danger)
0.00%
0 / 24
 getPoWiseStudentListForAttainmentCalculation
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 25
 upsertPoAttainment
0.00% covered (danger)
0.00%
0 / 1
42.00
0.00% covered (danger)
0.00%
0 / 26
 getAllPoAttainmentOfANode
0.00% covered (danger)
0.00%
0 / 1
20.00
0.00% covered (danger)
0.00%
0 / 34
 getRuleForCoAndPoAttainmentInTreeNode
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 13
 getRulesForCoAndPoAttainment
0.00% covered (danger)
0.00%
0 / 1
110.00
0.00% covered (danger)
0.00%
0 / 61
 getRulesForCoAndPoAttainmentForSubject
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 18
 getRulesForCoAndPoAttainmentForDepartment
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 15
 upsertCoPoAttainmentRules
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 10
 upsertCoPoAttainmentRulesForDepartment
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 10
 deleteCoPoAttainmentRule
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 9
 deleteCoPoAttainmentRuleForDepartment
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 9
 populateDescriptorValuesFromIds
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 9
 getDataForPoAttainmentMatrix
0.00% covered (danger)
0.00%
0 / 1
42.00
0.00% covered (danger)
0.00%
0 / 46
 getAttainmentOfADepartment
0.00% covered (danger)
0.00%
0 / 1
110.00
0.00% covered (danger)
0.00%
0 / 38
 getAttainmentOfPoGroup
0.00% covered (danger)
0.00%
0 / 1
182.00
0.00% covered (danger)
0.00%
0 / 52
 processSubjectListForDepartmentAttainmentReport
0.00% covered (danger)
0.00%
0 / 1
30.00
0.00% covered (danger)
0.00%
0 / 14
 getSubjectAcademicYearForCOAattainmentReport
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 12
<?php
namespace com\linways\core\ams\professional\service\nba;
use com\linways\core\ams\professional\util\CommonUtil;
use com\linways\core\ams\professional\util\nba\NbaUtil;
use com\linways\core\ams\professional\service\BaseService;
use com\linways\core\ams\professional\dto\nba\CoAttainment;
use com\linways\core\ams\professional\dto\nba\PoAttainment;
use com\linways\core\ams\professional\service\BatchService;
use com\linways\core\ams\professional\dto\SettingsConstents;
use com\linways\core\ams\professional\constant\nba\NbaMethod;
use com\linways\core\ams\professional\service\DepartmentService;
use com\linways\core\ams\professional\service\nba\NbaCoPoService;
use com\linways\core\ams\professional\service\nba\NBAPOAttainmentTreeService;
use com\linways\core\ams\professional\request\nba\SearchFeedbacks;
use com\linways\core\ams\professional\util\nba\NbaCoPoServiceUtil;
use com\linways\core\ams\professional\exception\ProfessionalException;
use com\linways\core\ams\professional\request\nba\GetAllCoAttainments;
use com\linways\core\ams\professional\request\nba\SearchPoGroupRequest;
use com\linways\core\ams\professional\constant\nba\AttainmentCalculationType;
use com\linways\core\ams\professional\mapper\nba\CoPoAttainmentServiceMapper;
use com\linways\core\ams\professional\mapper\nba\ExtraActivitiesServiceMapper;
use com\linways\core\ams\professional\request\nba\GetAllActivitiesAssignedToStudentsInABatchRequest;
use com\linways\core\ams\professional\request\nba\GetCoWiseStudentListForAttainmentCalculationRequest;
use com\linways\core\ams\professional\constant\SettingsConstants;
use com\linways\core\ams\professional\service\CommonService;
class CoPoAttainmentService extends BaseService
{
    // /Condition 1 - Presence of a static member variable
    private static $_instance = null;
    private $mapper = [];
    // /Condition 2 - Locked down the constructor
    private function __construct()
    {
        $this->mapper = CoPoAttainmentServiceMapper::getInstance()->getMapper();
    }
    // Prevent any oustide instantiation of this class
    
    // /Condition 3 - Prevent any object or instance of that class to be cloned
    private function __clone()
    {
    }
    // Prevent any copy of this object
    
    // /Condition 4 - Have a single globally accessible static method
    public static function getInstance()
    {
        if (!is_object(self::$_instance)) // or if( is_null(self::$_instance) ) or if( self::$_instance == null )
        self::$_instance = new self();
        return self::$_instance;
    }
    public function getMaxDescriptorDetails()
    {
        $sql = "";
        $sql = "SELECT MAX(weightage) as descriptorValue
                FROM
                    nba_descriptor";
        try {
            $maxDescriptor = $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $maxDescriptor;
    }
    /**
     * 
     *
     * @param GetCoWiseStudentListForAttainmentCalculationRequest $request
     * @return void
     */
    public function calculateCoAttainment($request)
    {
        $coPoCourseWiseCalculationDisplayStyle = CommonService::getInstance()->getSettings(SettingsConstants::NBA, NbaMethod::OBE_CO_PO_CALCULATION_DISPlAY_STYLE_IN_TREE_NODE);
        $request = $this->realEscapeObject($request);
        $coWiseStudentList = $this->getCoWiseStudentListForAttainmentCalculation($request);
        if (empty($coWiseStudentList)) {
            return null;
        }
        $coAttainmentRuleDetails = $this->getRulesForCoAndPoAttainment($request->batchId, $request->semId, $request->subjectId);
        if (empty($coAttainmentRuleDetails)&& $coPoCourseWiseCalculationDisplayStyle==NbaMethod::OBE_CO_PO_CALCULATION_STUDENT_WISE_DISPlAY_IN_TREE_NODE) {
            throw new ProfessionalException(ProfessionalException::ATTAINMENT_RULES_NOT_DEFINED, 'Please Define Co And Po Attainment rules...');
        }else{
            $coAttainmentRule = $coAttainmentRuleDetails->rule;
        }
        $maxDescriptorValue = $this->getMaxDescriptorDetails();
        if (empty($maxDescriptorValue)) {
            throw new ProfessionalException(ProfessionalException::DESCRIPTOR_VALUES_NOT_DEFINED, 'Please Make Sure Descriptor Values Are Defined');
        }
        $maxDescriptorValue = $maxDescriptorValue->descriptorValue;
        switch ($coAttainmentRule->type) {
            case AttainmentCalculationType::SIMPLE_AVERAGE:
                $coAttainmentList = [];
                foreach ($coWiseStudentList as $co) {
                    $coValue = 0;
                    $coValue = CommonUtil::getSumOfAnAttributeInAnObjectList($co->studentList, "coValueInPercent");
                    $coValue = $coValue / sizeof($co->studentList);
                    $coValue = ($coValue / 100) * $maxDescriptorValue;
                    $coAttainment = new CoAttainment();
                    $coAttainment->coId = $co->coId;
                    $coAttainment->value = $coValue;
                    $coAttainment->nodeId = $request->nodeId;
                    $coAttainment->batchId = $request->batchId;
                    $coAttainment->semId = $request->semId;
                    $coAttainment->subjectId = $request->subjectId;
                    $coAttainment->createdBy = $_SESSION["staffID"];
                    $coAttainment->updatedBy = $_SESSION["staffID"];
                    $coAttainmentList[] = $coAttainment;
                }
                $this->upsertCoAttainment($coAttainmentList);
                break;
            case AttainmentCalculationType::SLABBED_AVERAGE:
                $coAttainmentList = [];
                foreach ($coWiseStudentList as $co) {
                    $didNotMatchToAnySlab = true;
                    $coValue = 0;
                    $coValue = CommonUtil::getSumOfAnAttributeInAnObjectList($co->studentList, "coValueInPercent");
                    $coValue = $coValue / sizeof($co->studentList);
                    foreach ($coAttainmentRule->slabs as $slab) {
                        if (($coValue >= $slab->min->percent && $coValue < $slab->max->percent) || ($slab->min->percent == $slab->max->percent && $coValue == $slab->max->percent) || ($coValue == $slab->max->percent && $coValue == 100)) {
                            $didNotMatchToAnySlab = false;
                            
                            if(($slab->max->percent - $slab->min->percent) == 0)
                                $coValue = $slab->min->descriptor;
                            else 
                                $coValue = $slab->min->descriptor + (($coValue - $slab->min->percent) / ($slab->max->percent - $slab->min->percent)); //coValue = min_range + (coValueInPercent - lower_range_slab)/ (higher_range_slab - lower_range_slab) This formula converts out co to descriptor range
                        }
                    }
                    if ($didNotMatchToAnySlab) {
                        continue;
                    }
                    $coAttainment = new CoAttainment();
                    $coAttainment->coId = $co->coId;
                    $coAttainment->value = $coValue;
                    $coAttainment->nodeId = $request->nodeId;
                    $coAttainment->batchId = $request->batchId;
                    $coAttainment->semId = $request->semId;
                    $coAttainment->subjectId = $request->subjectId;
                    try {
                        $coAttainment->createdBy = $_SESSION["staffID"];
                    } catch (\Exception $e) {
                        error_log("staffID not defined in session variable in co attainment service");
                    }
                    try {
                        $coAttainment->updatedBy = $_SESSION["staffID"];
                    } catch (\Exception $e) {
                        error_log("staffID not defined in session variable in co attainment service");
                    }
                    $coAttainmentList[] = $coAttainment;
                }
                $this->upsertCoAttainment($coAttainmentList);
                break;
            case AttainmentCalculationType::NSTUDENT_NPERCENT:
                $coAttainmentList = [];
                $coAttainmentRule->goals = $this->populateDescriptorValuesFromIds($coAttainmentRule->goals);
                foreach ($coWiseStudentList as $co) {
                    $ruleMatched = false;
                    foreach($coAttainmentRule->goals as $goal){
                        $numberOfStudentsWithSpecifiedAttainment = CommonUtil::getNumberOfElementsInAnObjectListByComparingAnAttributeWithGivenValue($co->studentList, "coValueInPercent", ">=", $goal->attain_percent);
                        $totalNumberOfStudents = sizeof($co->studentList);
                        $percentageOfStudentsWithSpecifiedAttainment = 0;
                        if($totalNumberOfStudents){
                            $percentageOfStudentsWithSpecifiedAttainment = ($numberOfStudentsWithSpecifiedAttainment/$totalNumberOfStudents)*100;
                        }
                        
                        
                        if($percentageOfStudentsWithSpecifiedAttainment >= $goal->student_percent){
                            $coAttainment = new CoAttainment();
                            $coAttainment->coId = $co->coId;
                            $coAttainment->value = $goal->descriptor->weightage?$goal->descriptor->weightage:0;
                            $coAttainment->nodeId = $request->nodeId;
                            $coAttainment->batchId = $request->batchId;
                            $coAttainment->semId = $request->semId;
                            $coAttainment->subjectId = $request->subjectId;
                            $coAttainment->createdBy = $_SESSION["staffID"];
                            $coAttainment->updatedBy = $_SESSION["staffID"];
        
                            $coAttainmentList[] = $coAttainment;
                            $ruleMatched = true;
                            break;
                        }
                    }
                    if(!$ruleMatched){
                        $coAttainment = new CoAttainment();
                        $coAttainment->coId = $co->coId;
                        $coAttainment->value = 0;
                        $coAttainment->nodeId = $request->nodeId;
                        $coAttainment->batchId = $request->batchId;
                        $coAttainment->semId = $request->semId;
                        $coAttainment->subjectId = $request->subjectId;
                        $coAttainment->createdBy = $_SESSION["staffID"];
                        $coAttainment->updatedBy = $_SESSION["staffID"];
                        $coAttainmentList[] = $coAttainment;
                    }
                }
                $this->upsertCoAttainment($coAttainmentList);
                break;
                
                case AttainmentCalculationType::N_STUDENT_N_PERCENT_SLABBED_AVERAGE:
                    $coAttainmentList = [];
                    foreach ( $coWiseStudentList as $co ) {
                        $goalCount= count($coAttainmentRule->goalsWithSlab);
                        foreach($coAttainmentRule->goalsWithSlab as $gIndex => $goal){
                            $numberOfStudentsWithSpecifiedAttainment=0;
                            $percentageOfStudentsWithSpecifiedAttainment=0;
                            $numberOfStudentsWithSpecifiedAttainment = CommonUtil::getNumberOfElementsInAnObjectListByComparingAnAttributeWithGivenValue($co->studentList, "coValueInPercent", ">=", $goal->thresholdMark);
                            $totalNumberOfStudents = sizeof($co->studentList);
                            $didNotMatchToAnyGoalsSlab = true;
                            if($totalNumberOfStudents){
                                $percentageOfStudentsWithSpecifiedAttainment = ($numberOfStudentsWithSpecifiedAttainment/$totalNumberOfStudents)*100;
                                if (($percentageOfStudentsWithSpecifiedAttainment >= $goal->min->percent && $percentageOfStudentsWithSpecifiedAttainment < $goal->max->percent) || ($goal->min->percent == $goal->max->percent && $percentageOfStudentsWithSpecifiedAttainment == $goal->max->percent) || ($percentageOfStudentsWithSpecifiedAttainment == $goal->max->percent && $percentageOfStudentsWithSpecifiedAttainment == 100)) {
                                    $didNotMatchToAnyGoalsSlab = false;
                                    if(($goal->max->percent - $goal->min->percent) == 0)
                                        $coValue = $goal->min->descriptor;
                                    else if($goal->max->descriptor == $goal->min->descriptor)
                                        $coValue = $goal->min->descriptor;
                                    else 
                                        $coValue = $goal->min->descriptor + (($percentageOfStudentsWithSpecifiedAttainment - $goal->min->percent) / ($goal->max->percent - $goal->min->percent)); //coValue = min_range + (coValueInPercent - lower_range_slab)/ (higher_range_slab - lower_range_slab) This formula converts out co to descriptor range
                                    break;
                                }
                            }
                        }
                        if($didNotMatchToAnyGoalsSlab){
                            $coValue = 0;
                            $coAttainment = new CoAttainment();
                            $coAttainment->coId = $co->coId;
                            $coAttainment->value = $coValue;
                            $coAttainment->nodeId = $request->nodeId;
                            $coAttainment->batchId = $request->batchId;
                            $coAttainment->semId = $request->semId;
                            $coAttainment->subjectId = $request->subjectId;
                            $coAttainment->createdBy = $_SESSION["staffID"];
                            $coAttainment->updatedBy = $_SESSION["staffID"];
        
                            $coAttainmentList[] = $coAttainment;
                            $ruleMatched = true;    
                        }else{
                            // $coValue = round($coValue,0);
                            $coAttainment = new CoAttainment();
                            $coAttainment->coId = $co->coId;
                            $coAttainment->value = $coValue;
                            $coAttainment->nodeId = $request->nodeId;
                            $coAttainment->batchId = $request->batchId;
                            $coAttainment->semId = $request->semId;
                            $coAttainment->subjectId = $request->subjectId;
                            $coAttainment->createdBy = $_SESSION["staffID"];
                            $coAttainment->updatedBy = $_SESSION["staffID"];
                            $coAttainmentList[] = $coAttainment;
    
                        }
                    }
                $this->upsertCoAttainment($coAttainmentList);
                break;
        }
    }
    /**
     * 
     *
     * @param [CoAttainment[]] $coAttainmentList
     * @return void
     */
    public function upsertCoAttainment($coAttainmentList)
    {
        if (empty($coAttainmentList)) {
            return null;
        }
        $coAttainment = $coAttainmentList[0];
        $sql = "";
        $coIdString = CommonUtil::implodeAnAttributeInAnObjectList($coAttainmentList, 'coId', ',');
        if ($coIdString != "") {
            $sql = "DELETE FROM nba_co_attainment WHERE co_id NOT IN ($coIdString) AND batch_id =  $coAttainment->batchId AND sem_id =  $coAttainment->semId AND subject_id =  $coAttainment->subjectId AND node_id = $coAttainment->nodeId";
            try {
                $this->executeQuery($sql);
            } catch (\Exception $e) {
                throw new ProfessionalException($e->getCode(), $e->getMessage());
            }
        }
        foreach ($coAttainmentList as $coAttainment) {
            $sql = "";
            $sql = "INSERT INTO nba_co_attainment (co_id,value, node_id,batch_id, sem_id, subject_id, created_by, created_date, updated_by, updated_date) VALUES ($coAttainment->coId$coAttainment->value,$coAttainment->nodeId$coAttainment->batchId$coAttainment->semId$coAttainment->subjectId$coAttainment->createdBy, UTC_TIMESTAMP(), $coAttainment->updatedBy, UTC_TIMESTAMP())
            ON DUPLICATE KEY UPDATE value= $coAttainment->value, updated_by= $coAttainment->updatedBy, updated_date=UTC_TIMESTAMP()";
            try {
                $this->executeQuery($sql);
            } catch (\Exception $e) {
                throw new ProfessionalException($e->getCode(), $e->getMessage());
            }
        }
    }
    /**
     * 
     * @param GetCoWiseStudentListForAttainmentCalculationRequest 
     * $request
     * @return void
     */
    public function getCoWiseStudentListForAttainmentCalculation($request)
    {
        $request = $this->realEscapeObject($request);
        $coWiseStudentList = [];
        $sql = "";
        $sql = "SELECT 
                    co_id AS coId,
                    student_id AS studentId,
                    value AS coValueInPercent
 
                FROM
                    nba_subject_node_co_value
                WHERE
                    node_id = $request->nodeId AND batch_id = $request->batchId
                        AND sem_id = $request->semId
                        AND subject_id = $request->subjectId";
        try {
            $coWiseStudentList = $this->executeQueryForList($sql, $this->mapper[CoPoAttainmentServiceMapper::GET_CO_WISE_STUDENT_LIST]);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $coWiseStudentList;
    }
    
    /**
     * 
     *
     * @param GetAllCoAttainments $request
     * @return void
     */
    public function getAllCoAttainmentOfANode($request)
    {
        $request = $this->realEscapeObject($request);
        $sql = "";
        $responseList = [];
        $nbaMethod = NbaUtil::getNbaMethod();
        $coPoCourseWiseCalculationDisplayStyle = CommonService::getInstance()->getSettings(SettingsConstants::NBA, NbaMethod::OBE_CO_PO_CALCULATION_DISPlAY_STYLE_IN_TREE_NODE);
        if($nbaMethod == NbaMethod::STUDENT_MARK_ENTRY_IN_EXAT_METHOD){
            $tableForAttainment = "nba_subject_node_co_value";
        }else{
            $tableForAttainment = "nba_co_attainment";
        }
        if($nbaMethod != NbaMethod::STUDENT_MARK_ENTRY_IN_EXAT_METHOD && ($coPoCourseWiseCalculationDisplayStyle==NbaMethod::OBE_CO_PO_CALCULATION_COURSE_WISE_DISPlAY_IN_TREE_NODE || $coPoCourseWiseCalculationDisplayStyle==NbaMethod::OBE_CO_PO_CALCULATION_COURSE_WISE_DISPlAY_AND_CALCULATION_TWO)){
            $tableForAttainment = "nba_course_wise_node_co_value";
        }
        $sql = "SELECT 
                    ca.co_id AS coId,
                    co.code AS coCode,
                    co.objective AS coDescription,
                    ca.value AS coValue
                FROM
                    $tableForAttainment ca
                        INNER JOIN
                    nba_course_outcome co ON ca.co_id = co.id AND ca.batch_id=co.batchID AND ca.sem_id=co.semID AND ca.subject_id=co.subjectID
                WHERE
                    ca.node_id = '$request->nodeId' AND ca.batch_id = '$request->batchId'
                        AND ca.sem_id = '$request->semId'
                        AND ca.subject_id = '$request->subjectId' order by co.order_no";
        try {
            $responseList = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $responseList;
    }
    public function processAllCoAttainmentDataOfANodeToArray($attainmentCoList){
        $responseList = [];
        foreach($attainmentCoList as $coAttainment){
            $responseList[$coAttainment->coId] = $coAttainment->coValue;
        }
        return $responseList;
    }
    public function getTreeDetailsByDepartmentId($departmentId){
        $sql = "";
        $departmentId = $this->realEscapeString($departmentId);
        $sql = "SELECT id, name,co_root_node_id as selectedCoNodeId, po_root_node_id as selectedPoNodeId FROM nba_po_attainment_tree WHERE deptID = '$departmentId'";
        try {
            $response = $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $response;
    }
    /**
     * method for calculating po attainment
     *
     * @param [RequestForAttainment] $request
     * @return void
     */
    public function calculatePoAttainment($request)
    {
        $coPoCourseWiseCalculationDisplayStyle = CommonService::getInstance()->getSettings(SettingsConstants::NBA, NbaMethod::OBE_CO_PO_CALCULATION_DISPlAY_STYLE_IN_TREE_NODE);
        $request = $this->realEscapeObject($request);
        $poWiseStudentList = $this->getPoWiseStudentListForAttainmentCalculation($request);
        $poCalculationDisplayStyle = CommonService::getInstance()->getSettings(SettingsConstants::NBA, 'OBE_PO_CALCULATION_DISPlAY_STYLE_IN_TREE_NODE');
        if (empty($poWiseStudentList)) {
            return null;
        }
        $attainmentRuleDetails = $this->getRulesForCoAndPoAttainment($request->batchId, $request->semId, $request->subjectId);
        if (empty($attainmentRuleDetails) &&$coPoCourseWiseCalculationDisplayStyle==NbaMethod::OBE_CO_PO_CALCULATION_STUDENT_WISE_DISPlAY_IN_TREE_NODE) {
            throw new ProfessionalException(ProfessionalException::ATTAINMENT_RULES_NOT_DEFINED, 'Please Define Co And Po Attainment rules...');
        }else{
            $attainmentRule = $attainmentRuleDetails->rule;
        }
        $maxDescriptorValue = $this->getMaxDescriptorDetails();
        if (empty($maxDescriptorValue)) {
            throw new ProfessionalException(ProfessionalException::DESCRIPTOR_VALUES_NOT_DEFINED, 'Please Make Sure Descriptor Values Are Defined');
        }
        $maxDescriptorValue = $maxDescriptorValue->descriptorValue;
        $sql = "DELETE FROM nba_po_attainment_subject WHERE batch_id = '$request->batchId' AND sem_id = '$request->semId' AND subject_id = '$request->subjectId' AND node_id != '$request->nodeId'";
        try {
            $this->executeQuery($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        if ($poCalculationDisplayStyle == 'PO_CALCULATION_FROM_CO_VALUES'){
            $bId = $request->batchId;
            $nodeId = $request->nodeId;
            $semId = $request->semId;
            $subId = $request->subjectId;
            
            $subjectNodePo =  NBAPOAttainmentTreeService::getInstance()->getSubjectNodePoValue($bId, $nodeId, $semId, $subId);
            $poAttainmentList = [];
            foreach ($subjectNodePo as $po) {
                $poValue = round($po->value,2);
                $poAttainment = new PoAttainment();
                $poAttainment->poId = $po->poId;
                $poAttainment->value = $poValue;
                $poAttainment->nodeId = $request->nodeId;
                $poAttainment->batchId = $request->batchId;
                $poAttainment->semId = $request->semId;
                $poAttainment->subjectId = $request->subjectId;
                $poAttainment->createdBy = $_SESSION["staffID"];
                $poAttainment->updatedBy = $_SESSION["staffID"];
                $poAttainmentList[] = $poAttainment;
            }
            $this->upsertPoAttainment($poAttainmentList);
        } else {
            switch ($attainmentRule->type) {
                case AttainmentCalculationType::SIMPLE_AVERAGE:
                    $poAttainmentList = [];
                    foreach ($poWiseStudentList as $po) {
                        $poValue = 0;
                        $poValue = CommonUtil::getSumOfAnAttributeInAnObjectList($po->studentList, "poValueInPercent");
                        $poValue = $poValue / sizeof($po->studentList);//this should be number of students which have that co1
                        $poValue = ($poValue / 100) * $maxDescriptorValue;
                        $poAttainment = new PoAttainment();
                        $poAttainment->poId = $po->poId;
                        $poAttainment->value = $poValue;
                        $poAttainment->nodeId = $request->nodeId;
                        $poAttainment->batchId = $request->batchId;
                        $poAttainment->semId = $request->semId;
                        $poAttainment->subjectId = $request->subjectId;
                        $poAttainment->createdBy = $_SESSION["staffID"];
                        $poAttainment->updatedBy = $_SESSION["staffID"];
                        $poAttainmentList[] = $poAttainment;
                    }
                    $this->upsertPoAttainment($poAttainmentList);
                    break;
                case AttainmentCalculationType::SLABBED_AVERAGE:
                    $poAttainmentList = [];
                    foreach ($poWiseStudentList as $po) {
                        $didNotMatchToAnySlab = true;
                        $poValue = 0;
                        $poValue = CommonUtil::getSumOfAnAttributeInAnObjectList($po->studentList, "poValueInPercent");
                        $poValue = $poValue / sizeof($po->studentList);
                        foreach ($attainmentRule->slabs as $slab) {
                            if (($poValue >= $slab->min->percent && $poValue < $slab->max->percent) || ($slab->min->percent == $slab->max->percent && $poValue == $slab->max->percent) || ($poValue == $slab->max->percent && $poValue == 100)){
                                $didNotMatchToAnySlab = false;
                                if(($slab->max->percent - $slab->min->percent) == 0)
                                    $poValue = $slab->min->descriptor;
                                else
                                    $poValue = $slab->min->descriptor + (($poValue - $slab->min->percent) / ($slab->max->percent - $slab->min->percent)); //poValue = min_range + (poValueInPercent - lower_range_slab)/ (higher_range_slab - lower_range_slab) This formula converts out co to descriptor range
                            }
                        }
                        if ($didNotMatchToAnySlab) {
                            continue;
                        }
                        $poAttainment = new CoAttainment();
                        $poAttainment->poId = $po->poId;
                        $poAttainment->value = $poValue;
                        $poAttainment->nodeId = $request->nodeId;
                        $poAttainment->batchId = $request->batchId;
                        $poAttainment->semId = $request->semId;
                        $poAttainment->subjectId = $request->subjectId;
                        try {
                            $poAttainment->createdBy = $_SESSION["staffID"];
                        } catch (\Exception $e) {
                            error_log("staffID not defined in session variable in co attainment service");
                        }
                        try {
                            $poAttainment->updatedBy = $_SESSION["staffID"];
                        } catch (\Exception $e) {
                            error_log("staffID not defined in session variable in co attainment service");
                        }
                        $poAttainmentList[] = $poAttainment;
                    }
                    $this->upsertPoAttainment($poAttainmentList);
                    break;
                case AttainmentCalculationType::NSTUDENT_NPERCENT:
                    $poAttainmentList = [];
                    $attainmentRule->goals = $this->populateDescriptorValuesFromIds($attainmentRule->goals);
                    foreach ($poWiseStudentList as $po) {
                        $ruleMatched = false;
                        foreach($attainmentRule->goals as $goal){
                            $numberOfStudentsWithSpecifiedAttainment = CommonUtil::getNumberOfElementsInAnObjectListByComparingAnAttributeWithGivenValue($po->studentList, "poValueInPercent", ">=", $goal->attain_percent);
                            $totalNumberOfStudents = sizeof($po->studentList);
                            $percentageOfStudentsWithSpecifiedAttainment = 0;
                            if($totalNumberOfStudents){
                                $percentageOfStudentsWithSpecifiedAttainment = ($numberOfStudentsWithSpecifiedAttainment/$totalNumberOfStudents)*100;
                            }
                            
                            
                            if($percentageOfStudentsWithSpecifiedAttainment >= $goal->student_percent){
                                $poAttainment = new PoAttainment();
                                $poAttainment->poId = $po->poId;
                                $poAttainment->value = $goal->descriptor->weightage?$goal->descriptor->weightage:0;
                                $poAttainment->nodeId = $request->nodeId;
                                $poAttainment->batchId = $request->batchId;
                                $poAttainment->semId = $request->semId;
                                $poAttainment->subjectId = $request->subjectId;
                                $poAttainment->createdBy = $_SESSION["staffID"];
                                $poAttainment->updatedBy = $_SESSION["staffID"];
            
                                $poAttainmentList[] = $poAttainment;
                                $ruleMatched = true;
                                break;
                            }
                        }
                        if(!$ruleMatched){
                            $poAttainment = new PoAttainment();
                            $poAttainment->poId = $po->poId;
                            $poAttainment->value = 0;
                            $poAttainment->nodeId = $request->nodeId;
                            $poAttainment->batchId = $request->batchId;
                            $poAttainment->semId = $request->semId;
                            $poAttainment->subjectId = $request->subjectId;
                            $poAttainment->createdBy = $_SESSION["staffID"];
                            $poAttainment->updatedBy = $_SESSION["staffID"];
                            $poAttainmentList[] = $poAttainment;
                        }
                    }
                    $this->upsertPoAttainment($poAttainmentList);
                    break;
                    case AttainmentCalculationType::N_STUDENT_N_PERCENT_SLABBED_AVERAGE:
                        $poAttainmentList = [];
                        foreach ( $poWiseStudentList as $po ) {
                            $goalCount= count($attainmentRule->goalsWithSlab);
                            foreach($attainmentRule->goalsWithSlab as $gIndex => $goal){
                                $numberOfStudentsWithSpecifiedAttainment=0;
                                $percentageOfStudentsWithSpecifiedAttainment=0;
                                $numberOfStudentsWithSpecifiedAttainment = CommonUtil::getNumberOfElementsInAnObjectListByComparingAnAttributeWithGivenValue($po->studentList, "poValueInPercent", ">=", $goal->thresholdMark);
                                $totalNumberOfStudents = sizeof($po->studentList);
                                $didNotMatchToAnyGoalsSlab = true;
                                if($totalNumberOfStudents){
                                    $percentageOfStudentsWithSpecifiedAttainment = ($numberOfStudentsWithSpecifiedAttainment/$totalNumberOfStudents)*100;
                                    if (($percentageOfStudentsWithSpecifiedAttainment >= $goal->min->percent && $percentageOfStudentsWithSpecifiedAttainment < $goal->max->percent) || ($goal->min->percent == $goal->max->percent && $percentageOfStudentsWithSpecifiedAttainment == $goal->max->percent) || ($percentageOfStudentsWithSpecifiedAttainment == $goal->max->percent && $percentageOfStudentsWithSpecifiedAttainment == 100)) {
                                        $didNotMatchToAnyGoalsSlab = false;
                                        if(($goal->max->percent - $goal->min->percent) == 0)
                                            $poValue = $goal->min->descriptor;
                                        else if($goal->max->descriptor == $goal->min->descriptor)
                                            $poValue = $goal->min->descriptor;
                                        else 
                                            $poValue = $goal->min->descriptor + (($percentageOfStudentsWithSpecifiedAttainment - $goal->min->percent) / ($goal->max->percent - $goal->min->percent)); //poValue = min_range + (poValueInPercent - lower_range_slab)/ (higher_range_slab - lower_range_slab) This formula converts out co to descriptor range
                                        break;
                                    }
                                }
                            }
                            if($didNotMatchToAnyGoalsSlab){
                                $poValue = 0;
                                $poAttainment = new PoAttainment();
                                $poAttainment->poId = $po->poId;
                                $poAttainment->value = $poValue;
                                $poAttainment->nodeId = $request->nodeId;
                                $poAttainment->batchId = $request->batchId;
                                $poAttainment->semId = $request->semId;
                                $poAttainment->subjectId = $request->subjectId;
                                $poAttainment->createdBy = $_SESSION["staffID"];
                                $poAttainment->updatedBy = $_SESSION["staffID"];
            
                                $poAttainmentList[] = $poAttainment;
                                $ruleMatched = true;    
                            }else{
                                // $poValue = round($poValue,0);
                                $poAttainment = new PoAttainment();
                                $poAttainment->poId = $po->poId;
                                $poAttainment->value = $poValue;
                                $poAttainment->nodeId = $request->nodeId;
                                $poAttainment->batchId = $request->batchId;
                                $poAttainment->semId = $request->semId;
                                $poAttainment->subjectId = $request->subjectId;
                                $poAttainment->createdBy = $_SESSION["staffID"];
                                $poAttainment->updatedBy = $_SESSION["staffID"];
                                $poAttainmentList[] = $poAttainment;
        
                            }
                        }
                    $this->upsertPoAttainment($poAttainmentList);
                    break;
            }
        }
    }
    /**
     * Undocumented function
     *
     * @param [type] $request
     * @return void
     */
    public function calculatePoAttainmentForStudentMarkEntryMethod($request){
        $request = $this->realEscapeObject($request);
        $poListForAttainment = [];
        $poListForAttainment = $this->getDataForPoAttainmentMatrix($request);
        foreach($poListForAttainment as $po){
            $sumOfDescriptors = NbaCoPoServiceUtil::findSumOfCoDescriptorsInsideDescriptorObject($po->coList);
            $poAttainmentValue = 0;
            foreach($po->coList as $co){
                if($co->attainment->value){
                    $poAttainmentValue += $co->attainment->value*($co->descriptor->weightage/$sumOfDescriptors);
                }
            }
            $poAttainment = new PoAttainment();
            $poAttainment->poId = $po->id;
            $poAttainment->value = $poAttainmentValue;
            $poAttainment->nodeId = $request->nodeId;
            $poAttainment->batchId = $request->batchId;
            $poAttainment->semId = $request->semId;
            $poAttainment->subjectId = $request->subjectId;
            $poAttainment->createdBy = $_SESSION["staffID"];
            $poAttainment->updatedBy = $_SESSION["staffID"];
            $poAttainmentList[] = $poAttainment;
        }
        $this->upsertPoAttainment($poAttainmentList);
    }
    /**
     * 
     *
     * @param [type] $request
     * @return void
     */
    public function getPoWiseStudentListForAttainmentCalculation($request)
    {
        $request = $this->realEscapeObject($request);
        $poWiseStudentList = [];
        $sql = "";
        $sql = "SELECT 
                        po_id AS poId,
                        student_id AS studentId,
                        value AS poValueInPercent,
                        staff_id AS staffId,
                        batch_id AS batchId,
                        sem_id AS semId,
                        subject_id AS subjectId
                    FROM
                        nba_subject_node_po_value
                WHERE
                    node_id = $request->nodeId AND batch_id = $request->batchId
                        AND sem_id = $request->semId
                        AND subject_id = $request->subjectId";
        try {
            $poWiseStudentList = $this->executeQueryForList($sql, $this->mapper[CoPoAttainmentServiceMapper::GET_PO_WISE_STUDENT_LIST]);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $poWiseStudentList;
    }
    /**
     * 
     *
     * @param [PoAttainment[]] $poAttainmentList
     * @return void
     */
    public function upsertPoAttainment($poAttainmentList)
    {
        if (empty($poAttainmentList)) {
            return null;
        }
        $poAttainment = $poAttainmentList[0];
        $sql = "";
        $poIdString = CommonUtil::implodeAnAttributeInAnObjectList($poAttainmentList, 'poId', ',');
        if ($poIdString != "") {
            $sql = "DELETE FROM nba_po_attainment_subject WHERE po_id NOT IN ($poIdString) AND batch_id =  $poAttainment->batchId AND sem_id =  $poAttainment->semId AND subject_id =  $poAttainment->subjectId AND node_id = $poAttainment->nodeId";
            try {
                $this->executeQuery($sql);
            } catch (\Exception $e) {
                throw new ProfessionalException($e->getCode(), $e->getMessage());
            }
        }
        foreach ($poAttainmentList as $poAttainment) {
            $sql = "";
            $sql = "INSERT INTO nba_po_attainment_subject (po_id,value, node_id,batch_id, sem_id, subject_id, created_by, created_date, updated_by, updated_date) VALUES ($poAttainment->poId$poAttainment->value,$poAttainment->nodeId$poAttainment->batchId$poAttainment->semId$poAttainment->subjectId$poAttainment->createdBy, UTC_TIMESTAMP(), $poAttainment->updatedBy, UTC_TIMESTAMP())
            ON DUPLICATE KEY UPDATE value= $poAttainment->value, updated_by= $poAttainment->updatedBy, updated_date=UTC_TIMESTAMP()";
            try {
                $this->executeQuery($sql);
            } catch (\Exception $e) {
                throw new ProfessionalException($e->getCode(), $e->getMessage());
            }
        }
    }
    public function getAllPoAttainmentOfANode( $request)
    {
        $request = $this->realEscapeObject($request);
        $sql = "";
        $responseList = [];
        $coPoCourseWiseCalculationDisplayStyle = CommonService::getInstance()->getSettings(SettingsConstants::NBA, NbaMethod::OBE_CO_PO_CALCULATION_DISPlAY_STYLE_IN_TREE_NODE);
        if($coPoCourseWiseCalculationDisplayStyle==NbaMethod::OBE_CO_PO_CALCULATION_COURSE_WISE_DISPlAY_IN_TREE_NODE || $coPoCourseWiseCalculationDisplayStyle==NbaMethod::OBE_CO_PO_CALCULATION_COURSE_WISE_DISPlAY_AND_CALCULATION_TWO){
            $tableForAttainment = "nba_course_wise_node_po_value";
        }
        else{
            $tableForAttainment = "nba_po_attainment_subject";
        }
        $sql = "SELECT 
                    pas.po_id AS poId,
                    po.poName,
                    po.poCode,
                    po.poDesc ,
                    po.isPSO,
                    pas.value AS poValue
                FROM
                    $tableForAttainment pas
                        INNER JOIN
                    nba_program_outcome po ON pas.po_id = po.id
                WHERE
                    pas.node_id = '$request->nodeId' AND pas.batch_id = '$request->batchId'
                        AND pas.sem_id = '$request->semId'
                        AND pas.subject_id = '$request->subjectId'
                        ORDER BY po.order_no";
        try {
            $responseList = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $responseList;
    }
    public function getRuleForCoAndPoAttainmentInTreeNode($batchId, $semId, $subjectId,$nodeId){
        $ruleDetails = $this->getRulesForCoAndPoAttainmentForSubject($batchId, $semId, $subjectId,$nodeId);
        if(!empty($ruleDetails)){
            return $ruleDetails;
        }else{
            $parentNodeDetailsSql= "select t2.id,t2.is_leaf_node,t2.parent_nba_po_attainment_node_id from nba_po_attainment_node t1 inner join nba_po_attainment_node t2 ON (t1.parent_nba_po_attainment_node_id =t2.id) where t1.id =$nodeId  and t2.is_deleted=0";
            $parentNodeDetails = $this->executeQueryForObject($parentNodeDetailsSql);
            if(!empty($parentNodeDetails)){
                return $this->getRuleForCoAndPoAttainmentInTreeNode($batchId, $semId, $subjectId,$parentNodeDetails->id);
            }else{
                return $ruleDetails;
            }
        }
    }
    public function getRulesForCoAndPoAttainment($batchId, $semId, $subjectId, $nodeId=0, $ruleForCalculation = false)
    {
        $coPoCourseWiseCalculationDisplayStyle = CommonService::getInstance()->getSettings(SettingsConstants::NBA, NbaMethod::OBE_CO_PO_CALCULATION_DISPlAY_STYLE_IN_TREE_NODE);
       
        try{
            $deptId = DepartmentService::getInstance()->getDepartmentByBatchId($batchId)->deptID;
        }catch(\Exception $e){
            $deptId = null;
        }
        try{
            $ruleDetails = $this->getRulesForCoAndPoAttainmentForDepartment($deptId);
        }catch(\Exception $e){
            $ruleDetails = null;
        }
        if(empty($ruleDetails)){
            try{
                if($coPoCourseWiseCalculationDisplayStyle==NbaMethod::OBE_CO_PO_CALCULATION_COURSE_WISE_DISPlAY_IN_TREE_NODE || $coPoCourseWiseCalculationDisplayStyle==NbaMethod::OBE_CO_PO_CALCULATION_COURSE_WISE_DISPlAY_AND_CALCULATION_TWO){
                    if($ruleForCalculation){
                        $ruleDetails = $this->getRuleForCoAndPoAttainmentInTreeNode($batchId, $semId, $subjectId,$nodeId);
                    }else{
                        $ruleDetails = $this->getRulesForCoAndPoAttainmentForSubject($batchId, $semId, $subjectId,$nodeId);
                    }
                    if(!empty($ruleDetails)){
                        $ruleDetails->departmentRule = false;
                        $ruleDetails->batchId = $batchId;
                        $ruleDetails->semId = $semId;
                        $ruleDetails->subjectId = $subjectId;
                        $ruleDetails->treeNodeWiseRule = true;
                    }else{
                        $rule = new \stdClass();
                        $rule->type = "";
                        $rule->slabs = [];
                        $rule->goals = [];
                        $rule->goalsWithSlab = [];
                        $ruleDetails->rule=$rule;
                        $ruleDetails->departmentRule = false;
                        $ruleDetails->batchId = $batchId;
                        $ruleDetails->semId = $semId;
                        $ruleDetails->subjectId = $subjectId;
                        $ruleDetails->treeNodeWiseRule = false;
                    }
                }else{
                    $ruleDetails = $this->getRulesForCoAndPoAttainmentForSubject($batchId, $semId, $subjectId);
                    if(!empty($ruleDetails)){
                        $ruleDetails->departmentRule = false;
                        $ruleDetails->batchId = $batchId;
                        $ruleDetails->semId = $semId;
                        $ruleDetails->subjectId = $subjectId;
                        $ruleDetails->treeNodeWiseRule = false;
                    }
                }
            }catch(\Exception $e){
                $ruleDetails = null;
            }
        }else{
            $ruleDetails->batchId = $batchId;
            $ruleDetails->semId = $semId;
            $ruleDetails->subjectId = $subjectId;
            $ruleDetails->departmentRule = true;
            $ruleDetails->treeNodeWiseRule = false;
        }
        
        return $ruleDetails;
    }
    public function getRulesForCoAndPoAttainmentForSubject($batchId, $semId, $subjectId, $nodeId =0)
    {
        $batchId = $this->realEscapeString($batchId);
        $semId = $this->realEscapeString($semId);
        $subjectId = $this->realEscapeString($subjectId);
        $nodeId = $this->realEscapeString($nodeId);
        $ruleDetails = [];
        $sql = "";
        $sql = "SELECT rule, batch_id as batchId, sem_id as semId, subject_id as subjectId FROM nba_co_attainment_rules WHERE batch_id = '$batchId' AND sem_id = '$semId' AND subject_id = '$subjectId' AND node_id = '$nodeId'";
        try {
            $ruleDetails = $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        if (!empty($ruleDetails)) {
            $ruleDetails->rule = json_decode($ruleDetails->rule);
        }
        return $ruleDetails;
    }
    public function getRulesForCoAndPoAttainmentForDepartment($deptId)
    {
        $deptId = $this->realEscapeString($deptId);
        $ruleDetails = [];
        $sql = "";
        $sql = "SELECT rule, department_id as deptId, enforce_rule as enforceRule FROM nba_co_attainment_rules_for_department WHERE department_id = '$deptId'";
        try {
            $ruleDetails = $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        if (!empty($ruleDetails)) {
            $ruleDetails->rule = json_decode($ruleDetails->rule);
        }
        return $ruleDetails;
    }
    /**
     * Undocumented function
     *
     * @param [type] $coPoAttainmentRule
     * @return void
     */
    public function upsertCoPoAttainmentRules($coPoAttainmentRule){
        $coPoAttainmentRule = $this->realEscapeObject($coPoAttainmentRule);
        $coPoAttainmentRule->rule = json_encode($coPoAttainmentRule->rule);
        $sql = "INSERT INTO `nba_co_attainment_rules` (`batch_id`, `sem_id`, `subject_id`, `node_id`, `rule`, `created_by`, `created_date`, `updated_by`, `updated_date`) VALUES ('$coPoAttainmentRule->batchId', '$coPoAttainmentRule->semId', '$coPoAttainmentRule->subjectId', '$coPoAttainmentRule->nodeId', '$coPoAttainmentRule->rule', '$coPoAttainmentRule->createdBy', UTC_TIMESTAMP(), '$coPoAttainmentRule->updatedBy', UTC_TIMESTAMP()) ON DUPLICATE KEY UPDATE rule='$coPoAttainmentRule->rule'";
        try {
            $this->executeQuery($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return true;
    }
    public function upsertCoPoAttainmentRulesForDepartment($coPoAttainmentRule){
        $coPoAttainmentRule = $this->realEscapeObject($coPoAttainmentRule);
        $coPoAttainmentRule->rule = json_encode($coPoAttainmentRule->rule);
        $sql = "INSERT INTO `nba_co_attainment_rules_for_department` (`department_id`,`enforce_rule`, `rule`, `created_by`, `created_date`, `updated_by`, `updated_date`) VALUES ('$coPoAttainmentRule->deptId', '$coPoAttainmentRule->enforceRule', '$coPoAttainmentRule->rule', '$coPoAttainmentRule->createdBy', UTC_TIMESTAMP(), '$coPoAttainmentRule->updatedBy', UTC_TIMESTAMP()) ON DUPLICATE KEY UPDATE rule='$coPoAttainmentRule->rule', enforce_rule='$coPoAttainmentRule->enforceRule'";
        try {
            $this->executeQuery($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return true;
    }
    /**
     * Undocumented function
     *
     * @param [type] $request
     * @return void
     */
    public function deleteCoPoAttainmentRule($request){
        $request = $this->realEscapeObject($request);
        $sql = "DELETE  FROM nba_co_attainment_rules WHERE batch_id = $request->batchId AND sem_id = $request->semId AND subject_id = $request->subjectId  AND node_id = $request->nodeId";
        try {
            $this->executeQuery($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return true;
    }
    public function deleteCoPoAttainmentRuleForDepartment($request){
        $request = $this->realEscapeObject($request);
        $sql = "DELETE  FROM nba_co_attainment_rules_for_department WHERE department_id = $request->deptId ";
        try {
            $this->executeQuery($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return true;
    }
    public function populateDescriptorValuesFromIds($goals){
        foreach($goals as $goal){
            try{
                $goal->descriptor = NbaCoPoService::getInstance()->getDescriptorById ($goal->descriptor);
            }catch(\Exception $e){
                $goal->descriptor = null;
            }
        }
        return $goals;
    }
    /**
     * Returns CO PO relation and attainment if any
     *
     * @param RequestForAttainment $request
     * @return void
     */
    public function getDataForPoAttainmentMatrix($request){
        $request = $this->realEscapeObject($request);
        $poList = [];
        $sql = "";
        $nbaMethod = NbaUtil::getNbaMethod();
        $coPoCourseWiseCalculationDisplayStyle = CommonService::getInstance()->getSettings(SettingsConstants::NBA, NbaMethod::OBE_CO_PO_CALCULATION_DISPlAY_STYLE_IN_TREE_NODE);
        if($nbaMethod == NbaMethod::STUDENT_MARK_ENTRY_IN_EXAT_METHOD){
            $tableForAttainment = "nba_subject_node_co_value";
        }else{
            $tableForAttainment = "nba_co_attainment";
        }
        if($nbaMethod != NbaMethod::STUDENT_MARK_ENTRY_IN_EXAT_METHOD &&($coPoCourseWiseCalculationDisplayStyle==NbaMethod::OBE_CO_PO_CALCULATION_COURSE_WISE_DISPlAY_IN_TREE_NODE || $coPoCourseWiseCalculationDisplayStyle==NbaMethod::OBE_CO_PO_CALCULATION_COURSE_WISE_DISPlAY_AND_CALCULATION_TWO)){
            $tableForAttainment = "nba_course_wise_node_co_value";
        }
        $sql = "SELECT 
                    co.id AS coId,
                    co.code AS coCode,
                    po.id AS poId,
                    po.poCode,
                    po.poName,
                    po.department_id AS poDepartmentId,
                    ndesc.id AS descriptorId,
                    ndesc.descriptorName,
                    ndesc.weightage AS descriptorWeightage,
                    coatt.id as coAttainmentId,
                    coatt.value as coAttainmentValue
                FROM
                    nba_course_outcome co
                        INNER JOIN
                    nba_co_po_relation cpr ON co.id = cpr.nba_course_outcome_id
                        INNER JOIN
                    nba_program_outcome po ON po.id = cpr.nba_program_outcome_id
                        INNER JOIN
                    nba_descriptor ndesc ON cpr.nba_descriptor_id = ndesc.id
                        INNER JOIN 
                    $tableForAttainment coatt ON coatt.batch_id = co.batchID AND coatt.sem_id = co.semID AND coatt.subject_id = co.subjectID AND coatt.co_id = co.id
                WHERE
                    co.batchID = '$request->batchId' AND co.subjectID = '$request->subjectId'
                        AND co.semID = '$request->semId' AND coatt.node_id = $request->nodeId
                ORDER BY po.order_no";
                try{
                    $poList = $this->executeQueryForList($sql, $this->mapper[CoPoAttainmentServiceMapper::GET_DATA_FOR_PO_ATTAINMENT_REPORT]);
                }catch(\Exception $e){
                    throw new ProfessionalException($e->getCode(), $e->getMessage());
                }
                return $poList;
    }
    public function getAttainmentOfADepartment($deptId, $batchId = null){
        $deptId = $this->realEscapeString($deptId);
        $searchPoGroup = new SearchPoGroupRequest();
        $searchPoGroup->deptId = $deptId;
        try{
            $poGroupList = PoGroupService::getInstance()->searchPoGroup($searchPoGroup);
        }catch(\Exception $e){
            $poGroupList = [];
        }
        if(empty($poGroupList)){
            return null;
        }
        $coPoCourseWiseCalculationDisplayStyle = CommonService::getInstance()->getSettings(SettingsConstants::NBA, NbaMethod::OBE_CO_PO_CALCULATION_DISPlAY_STYLE_IN_TREE_NODE);
        if($coPoCourseWiseCalculationDisplayStyle==NbaMethod::OBE_CO_PO_CALCULATION_COURSE_WISE_DISPlAY_IN_TREE_NODE || $coPoCourseWiseCalculationDisplayStyle==NbaMethod::OBE_CO_PO_CALCULATION_COURSE_WISE_DISPlAY_AND_CALCULATION_TWO){
            $tableForAttainment = "nba_course_wise_node_po_value";
        }
        else{
            $tableForAttainment = "nba_po_attainment_subject";
        }
        foreach ($poGroupList as  $poGroup) {
            foreach ($poGroup->batchList as $batchIndex => $batch) {
                if($batchId){
                    if($batch->id != $batchId){
                        unset($poGroup->batchList[$batchIndex]);
                        continue;
                    }
                }
                $batch->subjectList = [];
                
                $sql = "";
                $sql = "SELECT po_att.po_id as poId, po_att.value, po_att.subject_id as subjectId, sub.subjectName, sub.subjectDesc FROM $tableForAttainment po_att INNER JOIN subjects sub ON sub.subjectID = po_att.subject_id WHERE po_att.batch_id = '$batch->id'   AND po_att.sem_id='$batch->semId' AND po_att.subject_id IN (SELECT DISTINCT subjectID FROM sbs_relation WHERE batchID = '$batch->id' AND semID = '$batch->semId')";
                try{
                    $batch->subjectList = $this->executeQueryForList($sql, $this->mapper[CoPoAttainmentServiceMapper::GET_DATA_FOR_PO_ATTAINMENT_OF_DEPARTMENT_REPORT]);
                }catch(\Exception $e){
                    throw new ProfessionalException($e->getCode(), $e->getMessage());
                }
            }
        }
        
        
        return $poGroupList;
    }
    public function getAttainmentOfPoGroup($groupIds, $batchId = null){
        $groupIds = $this->realEscapeArray($groupIds);
        $searchPoGroup = new SearchPoGroupRequest();
        $searchPoGroup->groupIds = $groupIds;
        
        try{
            $searchPoGroup->isSeparatePso = 1;
            $poGroupListPoOnly = PoGroupService::getInstance()->searchPoGroup($searchPoGroup);
            $searchPoGroup->isSeparatePso = 2;
            $poGroupListPsoOnly = PoGroupService::getInstance()->searchPoGroup($searchPoGroup);
            foreach ($poGroupListPoOnly as $poGroup) {
                $poGroup->isPso = 0;
            }   
            foreach ($poGroupListPsoOnly as $poGroup) {
                $poGroup->isPso = 1;
            }     
            $poGroupList=array_merge($poGroupListPoOnly, $poGroupListPsoOnly);
            // array_push($poGroupList, $poGroupListPsoOnly);
        }catch(\Exception $e){
            $poGroupList = [];
        }
        if(empty($poGroupList)){
            return null;
        }
        $coPoCourseWiseCalculationDisplayStyle = CommonService::getInstance()->getSettings(SettingsConstants::NBA, NbaMethod::OBE_CO_PO_CALCULATION_DISPlAY_STYLE_IN_TREE_NODE);
        if($coPoCourseWiseCalculationDisplayStyle==NbaMethod::OBE_CO_PO_CALCULATION_COURSE_WISE_DISPlAY_IN_TREE_NODE || $coPoCourseWiseCalculationDisplayStyle==NbaMethod::OBE_CO_PO_CALCULATION_COURSE_WISE_DISPlAY_AND_CALCULATION_TWO){
            $tableForAttainment = "nba_course_wise_node_po_value";
        }
        else{
            $tableForAttainment = "nba_po_attainment_subject";
        }
        foreach ($poGroupList as  $poGroup) {
            foreach ($poGroup->batchList as $batchIndex => $batch) {
                if($batchId){
                    if($batch->id != $batchId){
                        unset($poGroup->batchList[$batchIndex]);
                        continue;
                    }
                }
                $batch->subjectList = [];
                $sql = "";
                if($batchId){
                    $sql = "SELECT po_att.po_id as poId, po_att.value, po_att.subject_id as subjectId, sub.subjectName, sub.subjectDesc FROM $tableForAttainment po_att INNER JOIN subjects sub ON sub.subjectID = po_att.subject_id WHERE po_att.batch_id = '$batch->id' AND po_att.subject_id IN (SELECT DISTINCT subjectID FROM sbs_relation WHERE batchID = '$batch->id' )";
                }else{
                    $sql = "SELECT po_att.po_id as poId, po_att.value, po_att.subject_id as subjectId, sub.subjectName, sub.subjectDesc FROM $tableForAttainment po_att INNER JOIN subjects sub ON sub.subjectID = po_att.subject_id WHERE po_att.batch_id = '$batch->id' AND po_att.sem_id = '$batch->semId' AND po_att.subject_id IN (SELECT DISTINCT subjectID FROM sbs_relation WHERE batchID = '$batch->id' and semID ='$batch->semId')";
                }
                try{
                    $batch->subjectList = $this->executeQueryForList($sql, $this->mapper[CoPoAttainmentServiceMapper::GET_DATA_FOR_PO_ATTAINMENT_OF_DEPARTMENT_REPORT]);
                }catch(\Exception $e){
                    throw new ProfessionalException($e->getCode(), $e->getMessage());
                }
            }
        }
        
        
        return $poGroupList;
    }
    
    public function processSubjectListForDepartmentAttainmentReport($poGroupList){
        foreach ($poGroupList as  $poGroup) {
            foreach ($poGroup->batchList as $batch) {
                $batch->subjectIdList = [];
                foreach ($batch->subjectList as $subject) {
                    $batch->subjectIdList[$subject->id] = new \StdClass();
                    $batch->subjectIdList[$subject->id]->poIdList = [];
                    foreach ($subject->poAttainmentList as $poAttainment) {
                        $batch->subjectIdList[$subject->id]->poIdList[$poAttainment->id] = $poAttainment->value;
                     }
                 }
            }
        }
        
        return $poGroupList;
    }
    public function getSubjectAcademicYearForCOAattainmentReport($subjectId, $batchId, $semId){
        $semId = $this->realEscapeString($semId);
        $subjectId = $this->realEscapeString($subjectId);
        $batchId = $this->realEscapeString($batchId);
        // $staffId = $this->realEscapeString($staffId);
        $result="";
        $sql = "SELECT sbsID,staffID,createdDate from sbs_relation where subjectID='$subjectId' and batchID='$batchId' and semID='$semId'";
        try {
            $result =$this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $result;
        
        
    }
    
}