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 / 56
CRAP
0.00% covered (danger)
0.00%
0 / 990
NBAPOAttainmentTreeService
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 56
38612.00
0.00% covered (danger)
0.00%
0 / 990
 __construct
0.00% covered (danger)
0.00%
0 / 1
2.00
0.00% covered (danger)
0.00%
0 / 3
 __clone
n/a
0 / 0
1
n/a
0 / 0
 getInstance
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 4
 addPOAttainmentTree
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 10
 getPOAttainmentTree
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 11
 getPOAttainmentTreeById
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 10
 updatePOAttainmentTree
0.00% covered (danger)
0.00%
0 / 1
30.00
0.00% covered (danger)
0.00%
0 / 20
 deletePOAttainmentTreeById
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 10
 setCoPoRootNodes
0.00% covered (danger)
0.00%
0 / 1
42.00
0.00% covered (danger)
0.00%
0 / 25
 addPOAttainmentMasterData
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 10
 getPOAttainmentMasterData
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 10
 getPOAttainmentMasterDataById
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 11
 updatePOAttainmentMasterData
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 10
 deletePOAttainmentMasterDataById
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 10
 addNodeToTree
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 10
 updateNodeDetails
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 10
 deleteNodeById
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 10
 getLeafNodesByTreeId
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 10
 getChildNodesByNodeId
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 9
 getChildNodesByNodeIdWIthOutSubjectId
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 9
 getChildNodesByNodeIdAndSubjectId
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 10
 getRootNodeByTreeId
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 9
 addAssessmentNodeMapping
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 9
 removeAssessmentNodeMapping
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 9
 getAssessmentNodeMappingByNodeId
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 9
 getOeExamQuestionListByExamId
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 42
 deleteAssessmentNodeMapping
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 8
 deleteAssessmentNodeMappingByNodeId
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 8
 addSubjectLeafNodeCoValue
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 10
 addSubjectLeafNodePoValue
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 10
 addSubjectLeafNodeCoValueDirectly
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 9
 addSubjectLeafNodePoValueDirectly
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 9
 addSubjectIntermediateNodeCoValue
0.00% covered (danger)
0.00%
0 / 1
30.00
0.00% covered (danger)
0.00%
0 / 31
 addSubjectIntermediateNodePoValue
0.00% covered (danger)
0.00%
0 / 1
20.00
0.00% covered (danger)
0.00%
0 / 23
 getSubjectNodePoValue
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 8
 addSubjectIntermediateNodePoValueFromCoValueForCourseWise
0.00% covered (danger)
0.00%
0 / 1
72.00
0.00% covered (danger)
0.00%
0 / 36
 deleteSubjectTreeCoValue
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 11
 deleteSubjectTreeCoValueWithNodeId
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 11
 deleteSubjectTreePoValue
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 11
 deleteSubjectTreePoValueWithNodeId
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 11
 getSubjectAssessmentCoByNodeId
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 9
 getSubjectAssessmentPoByNodeId
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 9
 getSubjectAssessmentNodeCoValue
0.00% covered (danger)
0.00%
0 / 1
210.00
0.00% covered (danger)
0.00%
0 / 66
 getSubjectAssessmentNodePoValue
0.00% covered (danger)
0.00%
0 / 1
182.00
0.00% covered (danger)
0.00%
0 / 61
 getNodeDetailsById
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 9
 updateNodeLeafNodeStatus
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 10
 addSubjectTreeMapping
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 11
 deleteSubjectTreeMapping
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 11
 getSubjectTree
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 12
 copyTreeToAllDepartments_bkp
0.00% covered (danger)
0.00%
0 / 1
72.00
0.00% covered (danger)
0.00%
0 / 32
 getAllNodesByTreeId
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 11
 getAllNodesByTreeIdAndSubjectId
0.00% covered (danger)
0.00%
0 / 1
42.00
0.00% covered (danger)
0.00%
0 / 17
 getUniversityAttainmentLeafNodeId
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 10
 updateNodeEnableEdit
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 9
 updateNodeIsDelete
0.00% covered (danger)
0.00%
0 / 1
30.00
0.00% covered (danger)
0.00%
0 / 49
 getAssessmentMaxMark
0.00% covered (danger)
0.00%
0 / 1
420.00
0.00% covered (danger)
0.00%
0 / 112
 getSubjectAssessmentNodeCoValueForCourseWiseCalCulation
0.00% covered (danger)
0.00%
0 / 1
210.00
0.00% covered (danger)
0.00%
0 / 66
<?php
namespace com\linways\core\ams\professional\service\nba;
use com\linways\core\ams\professional\util\nba\NbaUtil;
use com\linways\core\ams\professional\service\BaseService;
use com\linways\core\ams\professional\service\BatchService;
use com\linways\core\ams\professional\constant\nba\NbaMethod;
use com\linways\core\ams\professional\service\SubjectService;
use com\linways\core\ams\professional\service\SemesterService;
use com\linways\core\ams\professional\exception\ProfessionalException;
use com\linways\core\ams\professional\request\nba\RequestForAttainment;
use com\linways\core\ams\professional\logging\Events;
use com\linways\core\ams\professional\logging\AMSLogger;
use com\linways\core\ams\professional\logging\entities\Staff;
use com\linways\core\ams\professional\logging\entities\TreeNode;
use com\linways\core\ams\professional\dto\notification\Notification;
use com\linways\core\ams\professional\constant\UserType;
use com\linways\core\ams\professional\constant\notification\NotificationContextConstant;
use com\linways\core\ams\professional\constant\notification\NotificationFeatureConstant;
use com\linways\core\ams\professional\service\notification\NotificationService;
use com\linways\core\ams\professional\service\notification\NotificationUtilityService;
use com\linways\core\ams\professional\dto\notification\NotificationRecipient;
use com\linways\core\ams\professional\service\nba\NbaCoPoService;
use com\linways\core\ams\professional\constant\nba\AssessmentType;
use com\linways\core\ams\professional\service\UniversityExamService;
use com\linways\core\ams\professional\request\GetGradePointOfStudentExamRequest;
use com\linways\core\ams\professional\service\CommonService;
use com\linways\core\ams\professional\constant\SettingsConstants;
use com\linways\core\ams\professional\util\nba\NbaCoPoServiceUtil;
use com\linways\core\ams\professional\mapper\nba\ObeTreeServiceMapper;
class NBAPOAttainmentTreeService extends BaseService
{
    // /Condition 1 - Presence of a static member variable
    private static $_instance = null;
    // /Condition 2 - Locked down the constructor
    private function __construct() {
        $this->logger = AMSLogger::getLogger();
        $this->mapper = ObeTreeServiceMapper::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;
    }
    /**
     * Create new tree - name, dept...
     *
     * @param object $poAttainmentTree
     * @throws ProfessionalException
     * @return object|NULL|\com\linways\base\util\$objectList[]
     */
    public function addPOAttainmentTree ( $poAttainmentTree ) {
        $poAttainmentTree = $this->realEscapeObject($poAttainmentTree);
        $sql = "INSERT INTO nba_po_attainment_tree ( name, deptID, createdBy, createdDate, updatedBy, updatedDate ) VALUES ('$poAttainmentTree->name', $poAttainmentTree->deptId$poAttainmentTree->createdBy, utc_timestamp(), $poAttainmentTree->updatedBy, utc_timestamp())";
        try {
            $id = $this->executeQueryForObject($sql, true);
        }
         catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $id;
    }
    /**
     * Get all the trees in a department
     * @param int $dept_id
     * @throws ProfessionalException
     * @return object|array|\com\linways\base\util\$objectList[]
     */
    public function getPOAttainmentTree($dept_id) {
        $tree = null;
        $dept_id = $this->realEscapeString($dept_id);
        $sql = "SELECT id, name, co_root_node_id, po_root_node_id, deptID FROM nba_po_attainment_tree WHERE deptID = $dept_id";
        try {
            $tree = $this->executeQueryForList($sql);
        }
        catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $tree;
    }
    /**
     * Get tree details by its id
     * @param int $tree_id
     * @throws ProfessionalException
     * @return object|NULL|\com\linways\base\util\$objectList[]
     */
    public function getPOAttainmentTreeById($treeId) {
        $tree = null;
        $sql = "SELECT id, name, deptID, co_root_node_id, po_root_node_id FROM nba_po_attainment_tree WHERE id = '$treeId'";
        try {
            $tree = $this->executeQueryForObject($sql);
        }
        catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $tree;
    }
    /**
     * Update PO attainment tree by id
     * @param object $poAttainmentTree
     * @throws ProfessionalException
     * @return boolean
     */
    public function updatePOAttainmentTree ( $poAttainmentTree ) {
        $poAttainmentTree = $this->realEscapeObject($poAttainmentTree);
        $sql_update = '';
        if ( $poAttainmentTree->name ) {
            $sql_update .= "name = '$poAttainmentTree->name',";
        }
        if ( $poAttainmentTree->poRootNodeId ) {
            $sql_update .= "po_root_node_id = '$poAttainmentTree->poRootNodeId',";
        }
        if ( $poAttainmentTree->coRootNodeId ) {
            $sql_update .= "co_root_node_id = '$poAttainmentTree->coRootNodeId',";
        }
        $sql = "UPDATE nba_po_attainment_tree SET ".$sql_update." updatedBy = $poAttainmentTree->updatedBy, updatedDate = utc_timestamp() WHERE id = $poAttainmentTree->id";
        try {
            $this->executeQuery($sql);
        }
        catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return true;
    }
    /**
     * Delete Tree by its id
     * @param int $tree_id
     * @throws ProfessionalException
     * @return boolean
     */
    public function deletePOAttainmentTreeById($tree_id) {
        $tree_id = $this->realEscapeString($tree_id);
        $sql = "DELETE FROM nba_po_attainment_tree WHERE id = $tree_id";
        try {
            $this->executeQuery($sql);
        }
        catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return true;
    }
    /**
     * For setting CO & PO root nodes for taking report from. It will be always
     * update query
     * @param object $tree
     * @throws ProfessionalException
     * @return boolean
     */
    public function setCoPoRootNodes($tree, $nodeId) {
        $tree = $this->realEscapeObject($tree);
        $nodeId = $this->realEscapeString($nodeId);
        $treeData = $this->getPOAttainmentTreeById($tree->id);
        $sql_update = null;
        // For setting and unsetting co po roots
        if ( $tree->coRootNodeId ) {
            $sql_update .= " co_root_node_id = ".$tree->coRootNodeId.", ";
        }
        else if ( $treeData->co_root_node_id == $nodeId ) {
            $sql_update .= " co_root_node_id = NULL, ";
        }
        if ( $tree->poRootNodeId ) {
            $sql_update .= " po_root_node_id = ".$tree->poRootNodeId.", ";
        }
        else if ( $treeData->po_root_node_id == $nodeId ) {
            $sql_update .= " po_root_node_id = NULL, ";
        }
        $sql = "UPDATE nba_po_attainment_tree SET ".$sql_update." updatedDate = utc_timestamp() WHERE id = ".$tree->id."";
        try {
            $this->executeQuery($sql);
        }
        catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return true;
    }
    /**
     * Add Master data  - done by all HOD
     * @param object $poAttainmentMasterData
     * @throws ProfessionalException
     * @return object|NULL|\com\linways\base\util\$objectList[]
     */
    public function addPOAttainmentMasterData ( $poAttainmentMasterData ) {
        $poAttainmentMasterData = $this->realEscapeObject($poAttainmentMasterData);
        $sql = "INSERT INTO nba_po_attainment_master ( name, description, createdBy, createdDate, updatedBy, updatedDate ) VALUES ('$poAttainmentMasterData->name', '$poAttainmentMasterData->description', $poAttainmentMasterData->createdBy, utc_timestamp(), $poAttainmentMasterData->updatedBy, utc_timestamp())";
        try {
            $id = $this->executeQueryForObject($sql, true);
        }
        catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $id;
    }
    /**
     * Get all po attainment tree master data.
     * @throws ProfessionalException
     * @return object|array|\com\linways\base\util\$objectList[]
     */
    public function getPOAttainmentMasterData() {
        $masterData = null;
        $sql = "SELECT id, name, description FROM nba_po_attainment_master";
        try {
            $masterData = $this->executeQueryForList($sql);
        }
        catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $masterData;
    }
    /**
     * Get PO attainment master data by id
     * @param int $data_id
     * @throws ProfessionalException
     * @return object|NULL|\com\linways\base\util\$objectList[]
     */
    public function getPOAttainmentMasterDataById($data_id) {
        $data_id = $this->realEscapeString($data_id);
        $masterData = null;
        $sql = "SELECT id, name, description FROM nba_po_attainment_master WHERE id = $data_id";
        try {
            $masterData = $this->executeQueryForObject($sql);
        }
        catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $masterData;
    }
    /**
     * Update PO attainment master data by id
     * @param object $poAttainmentMasterData
     * @throws ProfessionalException
     * @return boolean
     */
    public function updatePOAttainmentMasterData ( $poAttainmentMasterData ) {
        $poAttainmentMasterData = $this->realEscapeObject($poAttainmentMasterData);
        $sql = "UPDATE nba_po_attainment_master SET name = '$poAttainmentMasterData->name', description = '$poAttainmentMasterData->description', updatedBy = $poAttainmentMasterData->updatedBy, updatedDate = utc_timestamp() WHERE id = $poAttainmentMasterData->id";
        try {
            $this->executeQuery($sql);
        }
        catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return true;
    }
    /**
     * Delete PO atainment master data by id
     * @param int $data_id
     * @throws ProfessionalException
     * @return boolean
     */
    public function deletePOAttainmentMasterDataById($data_id) {
        $data_id = $this->realEscapeString($data_id);
        $sql = "DELETE FROM nba_po_attainment_master WHERE id = $data_id";
        try {
            $this->executeQuery($sql);
        }
        catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return true;
    }
    /**
     * Add new node to the tree
     * @param object $node
     * @throws ProfessionalException
     * @return object|NULL|\com\linways\base\util\$objectList[]
     */
    public function addNodeToTree($node) {
        $node = $this->realEscapeObject($node);
        $sql = "INSERT INTO nba_po_attainment_node (nba_po_attainment_master_id, parent_nba_po_attainment_node_id, nba_po_attainment_tree_id, is_leaf_node, contribution, tree_edited_subject_id, createdBy, createdDate, updatedBy, updatedDate) VALUES ( $node->masterId$node->parentNodeId$node->treeId$node->isLeafNode, '$node->contribution', $node->treeEditedSubjectId$node->createdBy, utc_timestamp(), $node->updatedBy, utc_timestamp() )";
        try {
            $id = $this->executeQueryForObject($sql, true);
        }
        catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $id;
    }
    /**
     * Update a node's details
     * @param object $node
     * @throws ProfessionalException
     * @return object|NULL|\com\linways\base\util\$objectList[]
     */
    public function updateNodeDetails($node) {
        $node = $this->realEscapeObject($node);
        $sql = "UPDATE nba_po_attainment_node SET nba_po_attainment_master_id = $node->masterId, parent_nba_po_attainment_node_id = $node->parentNodeId, nba_po_attainment_tree_id = $node->treeId, is_leaf_node = $node->isLeafNode, contribution = $node->contribution, updatedBy = $node->updatedBy, updatedDate = utc_timestamp() WHERE id = $node->id";
        try {
            $this->executeQuery($sql);
        }
        catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return true;
    }
    /**
     * Delete node by node id
     * @param int $nodeId
     * @throws ProfessionalException
     * @return object|array|\com\linways\base\util\$objectList[]
     */
    public function deleteNodeById ( $nodeId ) {
        $nodeId = $this->realEscapeString($nodeId);
        $sql = "DELETE FROM nba_po_attainment_node WHERE id = $nodeId";
        try {
            $this->executeQuery($sql);
        }
        catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return true;
    }
    /**
     * Get all the leaf nodes in a tree by its tree id
     * @param int $tree_id
     * @throws ProfessionalException
     * @return object|array|\com\linways\base\util\$objectList[]
     * @deprecated
     */
    public function getLeafNodesByTreeId($tree_id) {
        $tree_id = $this->realEscapeString($tree_id);
        $leafNodes = [];
        $sql = "SELECT node.id, node.is_leaf_node, master.name, node.contribution FROM nba_po_attainment_node node INNER JOIN nba_po_attainment_master master ON ( node.nba_po_attainment_master_id = master.id ) WHERE node.is_leaf_node = 1 AND node.nba_po_attainment_tree_id = ".$tree_id."";
        try {
            $leafNodes = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $leafNodes;
    }
    /**
     * Get all the child nodes of a node in a tree by its parent id
     * @param int $parent_id (parent_id)
     * @throws ProfessionalException
     * @return object|array|\com\linways\base\util\$objectList[]
     */
    public function getChildNodesByNodeId($parentId) {
        $parentId = $this->realEscapeString($parentId);
        $sql = "SELECT node.id, node.is_leaf_node, master.name, node.contribution,node.faculty_can_edit as facultyCanEdit,node.tree_edited_subject_id as treeEditedSubjectId FROM nba_po_attainment_node node INNER JOIN nba_po_attainment_master master ON (node.nba_po_attainment_master_id = master.id) WHERE node.parent_nba_po_attainment_node_id = $parentId AND node.is_deleted = 0";
        try {
            $childNodes = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $childNodes;
    }
    public function getChildNodesByNodeIdWIthOutSubjectId($parentId) {
        $parentId = $this->realEscapeString($parentId);
        $sql = "SELECT node.id, node.is_leaf_node, master.name, node.contribution,node.faculty_can_edit as facultyCanEdit,node.tree_edited_subject_id as treeEditedSubjectId FROM nba_po_attainment_node node INNER JOIN nba_po_attainment_master master ON (node.nba_po_attainment_master_id = master.id) WHERE node.parent_nba_po_attainment_node_id = $parentId AND node.tree_edited_subject_id is NULL AND node.is_deleted = 0";
        try {
            $childNodes = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $childNodes;
    }
    public function getChildNodesByNodeIdAndSubjectId($parentId,$subjectId) {
        $parentId = $this->realEscapeString($parentId);
        $subjectId = $this->realEscapeString($subjectId);
        $sql = "SELECT node.id, node.is_leaf_node, master.name, node.contribution,node.faculty_can_edit as facultyCanEdit,node.tree_edited_subject_id as treeEditedSubjectId FROM nba_po_attainment_node node INNER JOIN nba_po_attainment_master master ON (node.nba_po_attainment_master_id = master.id) WHERE node.is_deleted = 0 AND node.parent_nba_po_attainment_node_id = $parentId AND (node.tree_edited_subject_id is NULL OR node.tree_edited_subject_id = '$subjectId' )";
        try {
            $childNodes = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $childNodes;
    }
    /**
     * Get the root node of a tree by its tree id
     * @param int $treeId
     * @throws ProfessionalException
     * @return object|array|\com\linways\base\util\$objectList[]
     */
    public function getRootNodeByTreeId($treeId) {
        $treeId = $this->realEscapeString($treeId);
        $sql = "SELECT node.id, master.name, true AS is_root FROM nba_po_attainment_node node INNER JOIN nba_po_attainment_master master ON ( node.nba_po_attainment_master_id = master.id ) WHERE node.parent_nba_po_attainment_node_id IS NULL AND node.nba_po_attainment_tree_id = '".$treeId."'";
        try {
            $rootNode = $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $rootNode;
    }
    /**
     * Map an assessment ot each leaf node in a tree
     * @param unknown $nodeAssessment
     * @throws ProfessionalException
     * @return boolean
     */
    public function addAssessmentNodeMapping($nodeAssessment) {
        $nodeAssessment = $this->realEscapeObject($nodeAssessment);
        $sql = "INSERT INTO nba_po_attainment_node_assessment (nba_po_attainment_node_id, assessment_id, assessment_type_id, staff_id, batch_id, sem_id, subject_id, createdBy, createdDate, updatedBy, updatedDate) VALUES (".$nodeAssessment->nodeId.", '".$nodeAssessment->assessmentId."', ".$nodeAssessment->assessmentTypeId.", ".$nodeAssessment->staffId.", ".$nodeAssessment->batchId.", ".$nodeAssessment->semId.", ".$nodeAssessment->subjectId.", ".$nodeAssessment->staffId.", utc_timestamp(), ".$nodeAssessment->staffId.", utc_timestamp()) ON DUPLICATE KEY UPDATE assessment_id = VALUES(assessment_id), assessment_type_id = VALUES(assessment_type_id)";
        try {
            $nodeAssessmentId = $this->executeQueryForObject($sql, true);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $nodeAssessmentId;
    }
    /**
     * Remove mapped assessment to a leaf node in a tree
     * @param unknown $nodeAssessment
     * @throws ProfessionalException
     * @return boolean
     */
    public function removeAssessmentNodeMapping($nodeAssessment) {
        $nodeAssessment = $this->realEscapeObject($nodeAssessment);
        $sql = "DELETE FROM nba_po_attainment_node_assessment WHERE nba_po_attainment_node_id = ".$nodeAssessment->nodeId." AND batch_id = ".$nodeAssessment->batchId." AND sem_id = ".$nodeAssessment->semId." AND subject_id = ".$nodeAssessment->subjectId."";
        try {
            $this->executeQuery($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return true;
    }
    /**
     * Get the assessment mapped to a leaf node in a tree
     * @param unknown $subjectAssessmentNodeReq
     * @throws ProfessionalException
     * @return object|NULL|\com\linways\base\util\$objectList[]
     */
    public function getAssessmentNodeMappingByNodeId ( $subjectAssessmentNodeReq ) {
        $obj = $this->realEscapeObject($subjectAssessmentNodeReq);
        $sql = "SELECT nba_po_attainment_node_id, assessment_id, assessment_type_id, staff_id, batch_id, sem_id, subject_id FROM nba_po_attainment_node_assessment WHERE nba_po_attainment_node_id = ".$obj->nodeId." AND batch_id = ".$obj->batchId." AND sem_id = ".$obj->semId." AND subject_id = ".$obj->subjectId."";
        try {
            $assessmentNodeMapping = $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $assessmentNodeMapping;
    }
    /**
     * Fetch all question id by exam id
     *
     * @param String $oeExamId
     * @return Array
     */
    public function getOeExamQuestionListByExamId($oeExamId){
        $sql="SELECT
                oeq.id as questionId,
                oeq.mark ,
                oeq.properties->>'$.COURSE_OUTCOME[0].coList[0].coId' as coId,
                oeq.properties->>'$.COURSE_OUTCOME[0].coList[0].code' as coCode,
                if(oeq2.id is null,
                1,
                0) as mainQuestion
            FROM
                oe_exam_questions oeq
            left join oe_exam_questions oeq2 on
                oeq.id = oeq2.mainQuestionId
                and oeq.oe_exams_id = oeq2.oe_exams_id
            left join oe_exam_questions oeq3 on
                oeq.mainQuestionId = oeq3.id
                and oeq.oe_exams_id = oeq3.oe_exams_id
            left join oe_exam_sections oes on
                oes.id = json_extract(oeq.properties,
                '$.section')
            left join oe_exam_sections oes2 on
                oes2.id = json_extract(oeq3.properties,
                '$.section')
            left join oe_exams oe on
                oe.id = oeq.oe_exams_id
            where
                1 = 1
                and oeq.oe_exams_id = '$oeExamId'
            order by
                cast(ifnull(oes2.properties->>'$.orderNo' , oes.properties->>'$.orderNo') as UNSIGNED ) ,
                cast(oes.properties->>'$.orderNo' as UNSIGNED ) ,
                cast(if(oeq3.properties->>'$.orderNo' is null,1,0 ) as UNSIGNED ),
                cast(oeq3.properties->>'$.orderNo'  as UNSIGNED ),
                cast(oeq.properties->>'$.orderNo'  as UNSIGNED ) " ;
        try {
            $questionsList = (array)$this->executeQueryForList($sql);
            $questionsList = array_values(array_filter($questionsList,function($obj){
                return $obj->mainQuestion=='1';
            }));
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $questionsList;
    }
    public function deleteAssessmentNodeMapping ( $attainmentReq ) {
        $obj = $this->realEscapeObject($attainmentReq);
        $sql = "DELETE FROM nba_po_attainment_node_assessment WHERE batch_id = ".$obj->batchId." AND sem_id = ".$obj->semId." AND subject_id = ".$obj->subjectId."";
        try {
            $this->executeQuery($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    public function deleteAssessmentNodeMappingByNodeId ( $nodeId ) {
        $nodeId = $this->realEscapeString($nodeId);
        $sql = "DELETE FROM nba_po_attainment_node_assessment WHERE nba_po_attainment_node_id = ".$nodeId."";
        try {
            $this->executeQuery($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    // CO calculation services
    /**
     * Add or Insert the node CO value for each leaf node in a tree from the subject assessment
     * CO
     * @param unknown $subjectAssessmentNodeReq
     * @throws ProfessionalException
     * @return boolean
     */
    public function addSubjectLeafNodeCoValue($subjectAssessmentNodeReq) {
        $obj = $this->realEscapeObject($subjectAssessmentNodeReq);
        $sql = "INSERT INTO nba_subject_node_co_value (student_id, node_id, co_id, value, staff_id, batch_id, sem_id, subject_id, createdBy, createdDate, updatedBy, updatedDate) (
        SELECT student_id, '".$obj->nodeId."' AS node_id, co_id, value, staff_id, batch_id, sem_id, subject_id, createdBy, createdDate, updatedBy, utc_timestamp() as updatedDate FROM nba_subject_assessment_co_value WHERE assessment_id = '".$obj->assessmentId."' AND assessment_type_id = ".$obj->assessmentTypeId." AND batch_id = ".$obj->batchId." AND sem_id = ".$obj->semId." AND subject_id = ".$obj->subjectId.") ON DUPLICATE KEY UPDATE value = VALUES(value), createdBy = VALUES(createdBy), createdDate = VALUES(createdDate), updatedBy = VALUES(updatedBy), updatedDate = utc_timestamp()";
        try {
            $this->executeQuery($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return true;
    }
    /**
     * Add or Insert the node PO value for each leaf node in a tree from the subject PO
     * @param unknown $subjectAssessmentNodeReq
     * @throws ProfessionalException
     * @return boolean
     */
    public function addSubjectLeafNodePoValue($subjectAssessmentNodeReq) {
        $obj = $this->realEscapeObject($subjectAssessmentNodeReq);
        $sql = "INSERT INTO nba_subject_node_po_value (student_id, node_id, po_id, value, staff_id, batch_id, sem_id, subject_id, createdBy, createdDate, updatedBy, updatedDate) (
        SELECT student_id, '".$obj->nodeId."' AS node_id, po_id, value, staff_id, batch_id, sem_id, subject_id, createdBy, createdDate, updatedBy, utc_timestamp() as updatedDate FROM nba_subject_assessment_po_value WHERE assessment_id = '".$obj->assessmentId."' AND assessment_type_id = ".$obj->assessmentTypeId." AND batch_id = ".$obj->batchId." AND sem_id = ".$obj->semId." AND subject_id = ".$obj->subjectId.") ON DUPLICATE KEY UPDATE value = VALUES(value), createdBy = VALUES(createdBy), createdDate = VALUES(createdDate), updatedBy = VALUES(updatedBy), updatedDate = utc_timestamp()";
        try {
            $this->executeQuery($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return true;
    }
    /**
     * Add or Insert the node CO value for each leaf node in a tree directly
     * CO
     * @param unknown $subjectAssessmentNodeReq
     * @throws ProfessionalException
     * @return boolean
     */
    public function addSubjectLeafNodeCoValueDirectly($subjectAssessmentNodeReq) {
        $subjectAssessmentNodeReq = $this->realEscapeObject($subjectAssessmentNodeReq);
        $sql = "INSERT INTO nba_subject_node_co_value (student_id, node_id, co_id, value, staff_id, batch_id, sem_id, subject_id, createdBy, createdDate, updatedBy, updatedDate) VALUES (null, $subjectAssessmentNodeReq->nodeId$subjectAssessmentNodeReq->coId$subjectAssessmentNodeReq->value$subjectAssessmentNodeReq->staffId$subjectAssessmentNodeReq->batchId$subjectAssessmentNodeReq->semId$subjectAssessmentNodeReq->subjectId$subjectAssessmentNodeReq->createdBy, UTC_TIMESTAMP(), $subjectAssessmentNodeReq->updatedBy,  UTC_TIMESTAMP()) ON DUPLICATE KEY UPDATE value = VALUES(value), updatedBy = VALUES(updatedBy), updatedDate = utc_timestamp()";
        try {
            $this->executeQuery($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return true;
    }
    /**
     * Add or Insert the node CO value for each leaf node in a tree directly
     * CO
     * @param unknown $subjectAssessmentNodeReq
     * @throws ProfessionalException
     * @return boolean
     */
    public function addSubjectLeafNodePoValueDirectly($subjectAssessmentNodeReq) {
        $obj = $this->realEscapeObject($subjectAssessmentNodeReq);
        $sql = "INSERT INTO nba_subject_node_po_value (student_id, node_id, co_id, value, staff_id, batch_id, sem_id, subject_id, createdBy, createdDate, updatedBy, updatedDate) VALUES (null, $subjectAssessmentNodeReq->nodeId$subjectAssessmentNodeReq->poId$subjectAssessmentNodeReq->value$subjectAssessmentNodeReq->staffId$subjectAssessmentNodeReq->batchId$subjectAssessmentNodeReq->semId$subjectAssessmentNodeReq->subjectId$subjectAssessmentNodeReq->createdBy, UTC_TIMESTAMP(), $subjectAssessmentNodeReq->updatedBy,  UTC_TIMESTAMP()) ON DUPLICATE KEY UPDATE value = VALUES(value), updatedBy = VALUES(updatedBy), updatedDate = utc_timestamp()";
        try {
            $this->executeQuery($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return true;
    }
    /**
     * Add or Insert the node CO value for each intermediate node from the node CO itself
     * @param unknown $subjectAssessmentNodeReq
     * @param unknown $node_contributions
     * @throws ProfessionalException
     * @return boolean
     */
    public function addSubjectIntermediateNodeCoValue($subjectAssessmentNodeReq, $node_contributions, $co_contributions) {
        $obj = $this->realEscapeObject($subjectAssessmentNodeReq);
        $coPoCourseWiseCalculationDisplayStyle = CommonService::getInstance()->getSettings(SettingsConstants::NBA, NbaMethod::OBE_CO_PO_CALCULATION_DISPlAY_STYLE_IN_TREE_NODE);
        $sql_case = "CASE ";
        $node_ids = "";
        foreach ($node_contributions as $node_id => $node_contribution) {
            $sql_case .= " WHEN node_id = ".$node_id." THEN CASE";
            foreach ($co_contributions as $co_id => $co_contribution) {
                if ($coPoCourseWiseCalculationDisplayStyle==NbaMethod::OBE_CO_PO_CALCULATION_COURSE_WISE_DISPlAY_AND_CALCULATION_TWO){
                $contribution = 100;
                }else{
                    $contribution = array_sum($co_contribution);
                }
                $sql_case .= " WHEN co_id = ".$co_id." THEN value * ".$node_contribution." / ".$contribution." ";
            }
            $sql_case .= " END";
            $node_ids .= ",".$node_id;
        }
        $sql_case .= " END";
        $node_ids = substr($node_ids, 1);
        $sql = "INSERT INTO nba_subject_node_co_value (node_id, co_id, value, student_id, staff_id, batch_id, sem_id, subject_id, createdBy, createdDate, updatedBy, updatedDate) (
        SELECT ".$obj->nodeId.", co_id, SUM(".$sql_case.") AS calculated_value, student_id, staff_id, batch_id, sem_id, subject_id, createdBy, createdDate, updatedBy, utc_timestamp() FROM nba_subject_node_co_value WHERE node_id IN (".$node_ids.") AND batch_id = ".$obj->batchId." AND sem_id = ".$obj->semId." AND subject_id = ".$obj->subjectId." GROUP BY student_id, co_id ORDER BY student_id ASC )";
        $sql_course_wise="INSERT INTO nba_course_wise_node_co_value (node_id, co_id, value, staff_id, batch_id, sem_id, subject_id, createdBy, createdDate, updatedBy, updatedDate) (
            SELECT ".$obj->nodeId.", co_id, SUM(".$sql_case.") AS calculated_value, staff_id, batch_id, sem_id, subject_id, createdBy, createdDate, updatedBy, utc_timestamp() FROM nba_course_wise_node_co_value WHERE node_id IN (".$node_ids.") AND batch_id = ".$obj->batchId." AND sem_id = ".$obj->semId." AND subject_id = ".$obj->subjectId." GROUP BY co_id )";
        try {
            $this->executeQuery($sql);
            $this->executeQuery($sql_course_wise);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return true;
    }
    /**
     * Add or Insert the node PO value for each intermediate node from the node PO itself
     * @param unknown $subjectAssessmentNodeReq
     * @param unknown $node_contributions
     * @throws ProfessionalException
     * @return boolean
     */
    public function addSubjectIntermediateNodePoValue($subjectAssessmentNodeReq, $node_contributions, $po_contributions) {
        $obj = $this->realEscapeObject($subjectAssessmentNodeReq);
        $sql_case = "CASE ";
        $node_ids = "";
        foreach ($node_contributions as $node_id => $node_contribution) {
            $sql_case .= " WHEN node_id = ".$node_id." THEN CASE";
            foreach ($po_contributions as $po_id => $po_contribution) {
                $contribution = array_sum($po_contribution);
                $sql_case .= " WHEN po_id = ".$po_id." THEN value * ".$node_contribution." / ".$contribution." ";
            }
            $sql_case .= " END";
            $node_ids .= ",".$node_id;
        }
        $sql_case .= " END";
        $node_ids = substr($node_ids, 1);
        $sql = "INSERT INTO nba_subject_node_po_value (node_id, po_id, value, student_id, staff_id, batch_id, sem_id, subject_id, createdBy, createdDate, updatedBy, updatedDate) (
        SELECT ".$obj->nodeId.", po_id, SUM(".$sql_case.") AS calculated_value, student_id, staff_id, batch_id, sem_id, subject_id, createdBy, createdDate, updatedBy, utc_timestamp() FROM nba_subject_node_po_value WHERE node_id IN (".$node_ids.") AND batch_id = ".$obj->batchId." AND sem_id = ".$obj->semId." AND subject_id = ".$obj->subjectId." GROUP BY student_id, po_id ORDER BY student_id ASC )";
        try {
            $this->executeQuery($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return true;
    }
    public function getSubjectNodePoValue($bId, $nodeId, $semId, $subId) {
        $sql = "SELECT node_po.node_id, node_po.po_id as poId, node_po.value as value, node_po.batch_id, node_po.sem_id, node_po.subject_id FROM nba_course_wise_node_po_value node_po WHERE node_po.batch_id ='$bId' AND node_po.node_id ='$nodeId'  AND node_po.sem_id ='$semId' AND node_po.subject_id ='$subId'  ORDER BY  node_po.po_id ASC";
        try {
           return $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return true;
    }
    /**
     * Add or Insert the node PO value for each intermediate node from the node CO value
     * @param unknown $subjectAssessmentNodeReq
     * @throws ProfessionalException
     * @return boolean
     */
    public function addSubjectIntermediateNodePoValueFromCoValueForCourseWise($subjectAssessmentNodeReq) {
        $obj = $this->realEscapeObject($subjectAssessmentNodeReq);
        $courseWisePoList = NbaCoPoService::getInstance()->getAllCalculatedCourseWiseCosFromNodeCoValueTable($obj->nodeId, $obj->batchId, $obj->semId, $obj->subjectId);//result is mapped as student
        if (empty($courseWisePoList)) {
            return null;
        }
        $sql = "";
        $sql = "INSERT INTO `nba_course_wise_node_po_value` (`node_id`, `po_id`, `value`, `staff_id`, `batch_id`, `sem_id`, `subject_id`, `createdBy`, `createdDate`, `updatedBy`, `updatedDate`) VALUES ";
        foreach ($courseWisePoList as $po) {
            if (empty($po->coList)) {
                continue;
            }
            $poValueInPercent = 0;
            $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_AND_CALCULATION_TWO){
                $maxDescriptorValue = CoPoAttainmentService::getInstance()->getMaxDescriptorDetails();
                foreach ($po->coList as $co) {
                    $poValueInPercent += ($co->coContribution) * ($co->descriptorValue / $maxDescriptorValue->descriptorValue);
                }
                $poValueInPercent = $poValueInPercent/count($po->coList);
            }else{
                $sumOfDescriptors = 0;
                $sumOfDescriptors = NbaCoPoServiceUtil::findSumOfCoDescriptors($po->coList);
                foreach ($po->coList as $co) {
                    $poValueInPercent += ($co->coContribution) * ($co->descriptorValue / $sumOfDescriptors);
                }
            }
            $valuesCourseWise[] = "('$obj->nodeId', '$po->id', '$poValueInPercent', '$po->staffId', '$obj->batchId', '$obj->semId', '$obj->subjectId', '$po->staffId', UTC_TIMESTAMP(), '$po->staffId', UTC_TIMESTAMP())";
        }
        $sql .= implode(",", $valuesCourseWise);
        try {
            $this->executeQuery($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return true;
    }
    /**
     * Deleting CO values of the entire nodes of the tree
     * @param unknown $attainmentReq
     * @throws ProfessionalException
     * @return boolean
     */
    public function deleteSubjectTreeCoValue($attainmentReq) {
        $obj = $this->realEscapeObject($attainmentReq);
        $sql = "DELETE FROM nba_subject_node_co_value WHERE batch_id = ".$obj->batchId." AND sem_id = ".$obj->semId." AND subject_id = ".$obj->subjectId."";
        $sql_course_wise = "DELETE FROM nba_course_wise_node_co_value WHERE batch_id = ".$obj->batchId." AND sem_id = ".$obj->semId." AND subject_id = ".$obj->subjectId."";
        try {
            $this->executeQuery($sql);
            $this->executeQuery($sql_course_wise);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return true;
    }
    public function deleteSubjectTreeCoValueWithNodeId($attainmentReq) {
        $obj = $this->realEscapeObject($attainmentReq);
        $sql = "DELETE FROM nba_subject_node_co_value WHERE batch_id = ".$obj->batchId." AND sem_id = ".$obj->semId." AND subject_id = ".$obj->subjectId." AND node_id = ".$obj->nodeId."";
        $sql_course_wise = "DELETE FROM nba_course_wise_node_co_value WHERE batch_id = ".$obj->batchId." AND sem_id = ".$obj->semId." AND subject_id = ".$obj->subjectId." AND node_id = ".$obj->nodeId."";
        try {
            $this->executeQuery($sql);
            $this->executeQuery($sql_course_wise);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return true;
    }
    /**
     * Deleting PO values of the entire nodes of the tree
     * @param unknown $attainmentReq
     * @throws ProfessionalException
     * @return boolean
     */
    public function deleteSubjectTreePoValue($attainmentReq) {
        $obj = $this->realEscapeObject($attainmentReq);
        $sql = "DELETE FROM nba_subject_node_po_value WHERE batch_id = ".$obj->batchId." AND sem_id = ".$obj->semId." AND subject_id = ".$obj->subjectId."";
        $sql_course_wise = "DELETE FROM nba_course_wise_node_po_value WHERE batch_id = ".$obj->batchId." AND sem_id = ".$obj->semId." AND subject_id = ".$obj->subjectId."";
        try {
            $this->executeQuery($sql);
            $this->executeQuery($sql_course_wise);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return true;
    }
    public function deleteSubjectTreePoValueWithNodeId($attainmentReq) {
        $obj = $this->realEscapeObject($attainmentReq);
        $sql = "DELETE FROM nba_subject_node_po_value WHERE batch_id = ".$obj->batchId." AND sem_id = ".$obj->semId." AND subject_id = ".$obj->subjectId." AND node_id = ".$obj->nodeId."";
        $sql_course_wise = "DELETE FROM nba_course_wise_node_po_value WHERE batch_id = ".$obj->batchId." AND sem_id = ".$obj->semId." AND subject_id = ".$obj->subjectId." AND node_id = ".$obj->nodeId."";
        try {
            $this->executeQuery($sql);
            $this->executeQuery($sql_course_wise);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return true;
    }
    /**
     * Get assessment's CO by node id
     * @param unknown $subjectAssessmentNodeReq
     * @throws ProfessionalException
     * @return object|array|\com\linways\base\util\$objectList[]
     */
    public function getSubjectAssessmentCoByNodeId ( $subjectAssessmentNodeReq ) {
        $obj = $this->realEscapeObject($subjectAssessmentNodeReq);
        $sql = "SELECT DISTINCT node_co.co_id, co.code FROM nba_subject_node_co_value node_co INNER JOIN nba_course_outcome co ON ( node_co.co_id = co.id) WHERE node_co.node_id = ".$obj->nodeId." AND node_co.batch_id = ".$obj->batchId." AND node_co.sem_id = ".$obj->semId." AND node_co.subject_id = ".$obj->subjectId." ORDER BY node_co.co_id ASC";
        try {
            $subjectAssessmentCo = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $subjectAssessmentCo;
    }
    /**
     * Get assessment's PO by node id
     * @param unknown $subjectAssessmentNodeReq
     * @throws ProfessionalException
     * @return object|array|\com\linways\base\util\$objectList[]
     */
    public function getSubjectAssessmentPoByNodeId ( $subjectAssessmentNodeReq ) {
        $obj = $this->realEscapeObject($subjectAssessmentNodeReq);
        $sql = "SELECT DISTINCT node_po.po_id, po.poCode FROM nba_subject_node_po_value node_po INNER JOIN nba_program_outcome po ON ( node_po.po_id = po.id) WHERE node_po.node_id = ".$obj->nodeId." AND node_po.batch_id = ".$obj->batchId." AND node_po.sem_id = ".$obj->semId." AND node_po.subject_id = ".$obj->subjectId."";
        try {
            $subjectAssessmentCo = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $subjectAssessmentCo;
    }
    /**
     * Get node's subjectwise CO value by node id
     * @param unknown $subjectAssessmentNodeReq
     * @throws ProfessionalException
     * @return object|array|\com\linways\base\util\$objectList[]
     */
    public function getSubjectAssessmentNodeCoValue ( $subjectAssessmentNodeReq ) {
        $obj = $this->realEscapeObject($subjectAssessmentNodeReq);
        $nbaMethod = NbaUtil::getNbaMethod();
        $isCurrentSem = SemesterService::getInstance()->isCurrentSemester($obj->batchId, $obj->semId);
        $subjectDetails = SubjectService::getInstance()->getSubject($subjectAssessmentNodeReq->subjectId);
        //check if subbatch
        $subbatchDetails = BatchService::getInstance()->getSubbatchBySubject($obj->subjectId, $obj->semId, $obj->batchId, $obj->staffId);
        $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){
            //since students are not considered here we need only a single query
            $sql = "SELECT node_co.node_id, node_co.co_id, node_co.value, '".$subjectDetails->name."' as studentName, node_co.batch_id, node_co.sem_id, node_co.subject_id FROM nba_course_outcome co INNER JOIN nba_course_wise_node_co_value node_co ON ( node_co.co_id = co.id AND node_co.batch_id = co.batchID AND node_co.sem_id = co.semID AND node_co.subject_id = co.subjectID) AND node_co.node_id = ".$obj->nodeId."  AND node_co.sem_id = ".$obj->semId." AND node_co.subject_id = ".$obj->subjectId." WHERE node_co.batch_id = ".$obj->batchId." AND node_co.node_id = ".$obj->nodeId."  AND node_co.sem_id = ".$obj->semId." AND node_co.subject_id = ".$obj->subjectId."  ORDER BY  node_co.co_id ASC";
        }
        // $sql = "SELECT node_co.node_id, node_co.co_id, node_co.value, node_co.student_id, sa.studentName, node_co.batch_id, node_co.sem_id, node_co.subject_id FROM nba_subject_node_co_value node_co INNER JOIN studentaccount sa ON ( node_co.student_id = sa.studentID ) WHERE node_co.node_id = ".$obj->nodeId." AND node_co.batch_id = ".$obj->batchId." AND node_co.sem_id = ".$obj->semId." AND node_co.subject_id = ".$obj->subjectId."  ORDER BY node_co.student_id, node_co.co_id ASC";
        elseif($nbaMethod == NbaMethod::STUDENT_MARK_ENTRY_IN_EXAT_METHOD){
            //since students are not considered here we need only a single query
            $sql = "SELECT node_co.node_id, node_co.co_id, node_co.value, node_co.student_id, '".$subjectDetails->name."' as studentName, node_co.batch_id, node_co.sem_id, node_co.subject_id FROM nba_course_outcome co INNER JOIN nba_subject_node_co_value node_co ON ( node_co.co_id = co.id AND node_co.batch_id = co.batchID AND node_co.sem_id = co.semID AND node_co.subject_id = co.subjectID) AND node_co.node_id = ".$obj->nodeId."  AND node_co.sem_id = ".$obj->semId." AND node_co.subject_id = ".$obj->subjectId." WHERE node_co.batch_id = ".$obj->batchId." AND node_co.node_id = ".$obj->nodeId."  AND node_co.sem_id = ".$obj->semId." AND node_co.subject_id = ".$obj->subjectId."  ORDER BY  node_co.co_id ASC";
        }else{
            if(empty($subbatchDetails))
            {
                if($isCurrentSem)
                {
                    $sql = "SELECT node_co.node_id, node_co.co_id, node_co.value, node_co.student_id, sa.studentName, node_co.batch_id, node_co.sem_id, node_co.subject_id FROM studentaccount sa inner JOIN nba_subject_node_co_value node_co ON ( node_co.student_id = sa.studentID ) AND node_co.node_id = ".$obj->nodeId."  AND node_co.sem_id = ".$obj->semId." AND node_co.subject_id = ".$obj->subjectId." WHERE sa.batchID = ".$obj->batchId." ORDER BY sa.rollNo, node_co.co_id ASC";
                }
                else
                {
                    $sql = "SELECT node_co.node_id, node_co.co_id, node_co.value, node_co.student_id, sa.studentName, node_co.batch_id, node_co.sem_id, node_co.subject_id, fs.* FROM studentaccount sa left join failed_students fs on sa.studentID = fs.studentID inner JOIN nba_subject_node_co_value node_co ON ( node_co.student_id = sa.studentID ) AND node_co.node_id = ".$obj->nodeId."  AND node_co.sem_id = ".$obj->semId." AND node_co.subject_id = ".$obj->subjectId." WHERE sa.studentID in (select studentID from studentaccount where batchID = ".$obj->batchId." union select studentID from failed_students where previousBatch = ".$obj->batchId." and failedInSemester > ".$obj->semId.") ORDER BY sa.rollNo, node_co.co_id ASC";
                }
            }
            else
            {
                if($isCurrentSem)
                {
                    $sql =  "select distinct node_co.node_id, node_co.co_id, node_co.value, node_co.student_id, sa.studentName, node_co.batch_id, node_co.sem_id, node_co.subject_id from sbs_relation sr inner join subbatch_sbs ssbs on sr.sbsID = ssbs.sbsID inner join subbatch_student ss on ss.subbatchID = ssbs.subbatchID inner join studentaccount sa on sa.studentID = ss.studentID inner join nba_subject_node_co_value node_co ON ( node_co.student_id = sa.studentID ) and sr.semID = node_co.sem_id and sr.batchID = node_co.batch_id and sr.subjectID=  node_co.subject_id  where  sr.semID = ".$obj->semId." AND sr.subjectID = ".$obj->subjectId." and sr.batchID = ".$obj->batchId." AND node_co.node_id = ".$obj->nodeId." ORDER BY sa.rollNo, node_co.co_id ASC;";
                }
                else
                {
                    $sql =  "select distinct node_co.node_id, node_co.co_id, node_co.value, node_co.student_id, sa.studentName, node_co.batch_id, node_co.sem_id, node_co.subject_id from sbs_relation sr inner join subbatch_sbs ssbs on sr.sbsID = ssbs.sbsID inner join subbatch_student ss on ss.subbatchID = ssbs.subbatchID inner join studentaccount sa on sa.studentID = ss.studentID inner join nba_subject_node_co_value node_co ON ( node_co.student_id = sa.studentID ) and sr.semID = node_co.sem_id and sr.batchID = node_co.batch_id and sr.subjectID=  node_co.subject_id  where  sr.semID = ".$obj->semId." AND sr.subjectID = ".$obj->subjectId." and sr.batchID = ".$obj->batchId." AND node_co.node_id = ".$obj->nodeId." and sa.studentID in (select studentID from studentaccount where batchID = ".$obj->batchId." union select studentID from failed_students where previousBatch = ".$obj->batchId." and failedInSemester > ".$obj->semId.") ORDER BY sa.rollNo, node_co.co_id ASC;";
                }
            }
        }
        try {
            $subjectNodeCoNew =[];
            $subjectNodeCo = $this->executeQueryForList($sql);
            $sqlAssessmentNode = "select assessment_id as assessmentId, assessment_type_id as assessmentTypeId from nba_po_attainment_node_assessment where nba_po_attainment_node_id = '$obj->nodeId' AND batch_id = '$obj->batchId' AND sem_id = '$obj->semId' AND subject_id = '$obj->subjectId'";
            $assessmentTypeDetails = $this->executeQueryForObject($sqlAssessmentNode);
            $assessmentType = NbaCoPoService::getInstance()->getAssessmentTypeCodeFromId($assessmentTypeDetails->assessmentTypeId);
            if($assessmentType == AssessmentType::UNIVERSITY_EXAM && $coPoCourseWiseCalculationDisplayStyle == NbaMethod::OBE_CO_PO_CALCULATION_STUDENT_WISE_DISPlAY_IN_TREE_NODE){
                $getGradePointRequest = new GetGradePointOfStudentExamRequest ();
                $getGradePointRequest->examId = $assessmentTypeDetails->assessmentId;
                $getGradePointRequest->batchId = $obj->batchId;
                $getGradePointRequest->semId = $obj->semId;
                $getGradePointRequest->subjectId = $obj->subjectId;
                $studentUniversityMarks = UniversityExamService::getInstance()->getGradePointsOfStudentsForAnExam($getGradePointRequest);
                foreach($subjectNodeCo as $key => $studentCo){
                    $isAttend = false;
                    foreach($studentUniversityMarks as $studentUniversity){
                        if($studentCo->student_id == $studentUniversity->studentId){
                            $isAttend = true;
                        }
                    }
                    if($isAttend == true){
                        array_push($subjectNodeCoNew, $studentCo);
                    }
                }
                $subjectNodeCo = $subjectNodeCoNew;
            }
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $subjectNodeCo;
    }
    /**
     * Get node's subjectwise PO value by node id
     * @param unknown $subjectAssessmentNodeReq
     * @throws ProfessionalException
     * @return object|array|\com\linways\base\util\$objectList[]
     */
    public function getSubjectAssessmentNodePoValue ( $subjectAssessmentNodeReq ) {
        $obj = $this->realEscapeObject($subjectAssessmentNodeReq);
        // $sql = "SELECT node_po.node_id, node_po.po_id, node_po.value, node_po.student_id, sa.studentName, node_po.batch_id, node_po.sem_id, node_po.subject_id FROM nba_subject_node_po_value node_po INNER JOIN studentaccount sa ON ( node_po.student_id = sa.studentID ) WHERE node_po.node_id = ".$obj->nodeId." AND node_po.batch_id = ".$obj->batchId." AND node_po.sem_id = ".$obj->semId." AND node_po.subject_id = ".$obj->subjectId."  ORDER BY node_po.student_id, node_po.po_id ASC";
        $isCurrentSem = SemesterService::getInstance()->isCurrentSemester($obj->batchId, $obj->semId);
        $subjectDetails = SubjectService::getInstance()->getSubject($subjectAssessmentNodeReq->subjectId);
        //check if subbatch
        $subbatchDetails = BatchService::getInstance()->getSubbatchBySubject($obj->subjectId, $obj->semId, $obj->batchId, $obj->staffId);
        $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) {
            //since students are not considered here we need only a single query
            $sql = "SELECT node_po.node_id, node_po.po_id, node_po.value, '".$subjectDetails->name."' as studentName, node_po.batch_id, node_po.sem_id, node_po.subject_id FROM nba_course_wise_node_po_value node_po WHERE node_po.batch_id = ".$obj->batchId." AND node_po.node_id = ".$obj->nodeId."  AND node_po.sem_id = ".$obj->semId." AND node_po.subject_id = ".$obj->subjectId."  ORDER BY  node_po.po_id ASC";
        }
        elseif(empty($subbatchDetails))
        {
            if($isCurrentSem)
            {
                $sql = "SELECT node_po.node_id, node_po.po_id, node_po.value, node_po.student_id, sa.studentName, node_po.batch_id, node_po.sem_id, node_po.subject_id FROM studentaccount sa inner JOIN nba_subject_node_po_value node_po ON ( node_po.student_id = sa.studentID ) AND node_po.node_id = ".$obj->nodeId."  AND node_po.sem_id = ".$obj->semId." AND node_po.subject_id = ".$obj->subjectId." WHERE sa.batchID = ".$obj->batchId." ORDER BY sa.rollNo, node_po.po_id ASC;";
            }
            else
            {
                $sql = "SELECT node_po.node_id, node_po.po_id, node_po.value, node_po.student_id, sa.studentName, node_po.batch_id, node_po.sem_id, node_po.subject_id FROM studentaccount sa left join failed_students fs on sa.studentID = fs.studentID inner JOIN nba_subject_node_po_value node_po ON ( node_po.student_id = sa.studentID ) AND node_po.node_id = ".$obj->nodeId."  AND node_po.sem_id = ".$obj->semId." AND node_po.subject_id = ".$obj->subjectId." WHERE sa.studentID in (select studentID from studentaccount where batchID = ".$obj->batchId." union select studentID from failed_students where previousBatch = ".$obj->batchId." and failedInSemester > ".$obj->semId.") ORDER BY sa.rollNo, node_po.po_id ASC;";
            }
        }
        else
        {
            if($isCurrentSem)
            {
                $sql =  "SELECT node_po.node_id, node_po.po_id, node_po.value, node_po.student_id, sa.studentName, node_po.batch_id, node_po.sem_id, node_po.subject_id from sbs_relation sr inner join subbatch_sbs ssbs on sr.sbsID = ssbs.sbsID inner join subbatch_student ss on ss.subbatchID = ssbs.subbatchID inner join studentaccount sa on sa.studentID = ss.studentID inner join nba_subject_node_po_value node_po ON ( node_po.student_id = sa.studentID ) and sr.semID = node_po.sem_id and sr.batchID = node_po.batch_id and sr.subjectID=  node_po.subject_id  where  sr.semID = ".$obj->semId." AND sr.subjectID = ".$obj->subjectId." and sr.batchID = ".$obj->batchId." AND node_po.node_id = ".$obj->nodeId." ORDER BY sa.rollNo, node_po.po_id ASC;";
            }
            else
            {
                $sql =  "SELECT node_po.node_id, node_po.po_id, node_po.value, node_po.student_id, sa.studentName, node_po.batch_id, node_po.sem_id, node_po.subject_id from sbs_relation sr inner join subbatch_sbs ssbs on sr.sbsID = ssbs.sbsID inner join subbatch_student ss on ss.subbatchID = ssbs.subbatchID inner join studentaccount sa on sa.studentID = ss.studentID inner join nba_subject_node_po_value node_po ON ( node_po.student_id = sa.studentID ) and sr.semID = node_po.sem_id and sr.batchID = node_po.batch_id and sr.subjectID=  node_po.subject_id  where  sr.semID = ".$obj->semId." AND sr.subjectID = ".$obj->subjectId." and sr.batchID = ".$obj->batchId." AND node_po.node_id = ".$obj->nodeId." and sa.studentID in (select studentID from studentaccount where batchID = ".$obj->batchId." union select studentID from failed_students where previousBatch = ".$obj->batchId." and failedInSemester > ".$obj->semId.") ORDER BY sa.rollNo, node_po.po_id ASC;";
            }
        }
        try {
            $subjectNodePoNew =[];
            $subjectNodePo = $this->executeQueryForList($sql);
            $sqlAssessmentNode = "select assessment_id as assessmentId, assessment_type_id as assessmentTypeId from nba_po_attainment_node_assessment where nba_po_attainment_node_id = '$obj->nodeId' AND batch_id = '$obj->batchId' AND sem_id = '$obj->semId' AND subject_id = '$obj->subjectId'";
            $assessmentTypeDetails = $this->executeQueryForObject($sqlAssessmentNode);
            $assessmentType = NbaCoPoService::getInstance()->getAssessmentTypeCodeFromId($assessmentTypeDetails->assessmentTypeId);
            if($assessmentType == AssessmentType::UNIVERSITY_EXAM  && $coPoCourseWiseCalculationDisplayStyle == NbaMethod::OBE_CO_PO_CALCULATION_STUDENT_WISE_DISPlAY_IN_TREE_NODE){
                $getGradePointRequest = new GetGradePointOfStudentExamRequest ();
                $getGradePointRequest->examId = $assessmentTypeDetails->assessmentId;
                $getGradePointRequest->batchId = $obj->batchId;
                $getGradePointRequest->semId = $obj->semId;
                $getGradePointRequest->subjectId = $obj->subjectId;
                $studentUniversityMarks = UniversityExamService::getInstance()->getGradePointsOfStudentsForAnExam($getGradePointRequest);
                foreach($subjectNodePo as $key => $studentPo){
                    $isAttend = false;
                    foreach($studentUniversityMarks as $studentUniversity){
                        if($studentPo->student_id == $studentUniversity->studentId){
                            $isAttend = true;
                        }
                    }
                    if($isAttend == true){
                        array_push($subjectNodePoNew, $studentPo);
                    }
                }
                $subjectNodePo = $subjectNodePoNew;
            }
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $subjectNodePo;
    }
    public function getNodeDetailsById($nodeId) {
        $nodeId = $this->realEscapeString($nodeId);
        $sql = "SELECT node.id, master.id AS masterId, master.name, master.description, node.parent_nba_po_attainment_node_id AS parentNodeId, node.nba_po_attainment_tree_id AS treeId,node.faculty_can_edit as facultyCanEdit,node.tree_edited_subject_id as treeEditedSubjectId, node.is_deleted as isDeleted, node.createdBy, node.updatedBy, (SELECT master1.name FROM nba_po_attainment_master master1 INNER JOIN nba_po_attainment_node node1 ON (node1.nba_po_attainment_master_id = master1.id) WHERE node1.id = node.parent_nba_po_attainment_node_id) AS parent_name, node.is_leaf_node AS isLeafNode, node.contribution FROM nba_po_attainment_master master INNER JOIN nba_po_attainment_node node ON (master.id = node.nba_po_attainment_master_id) WHERE node.id = $nodeId";
        try {
            $node = $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $node;
    }
    /**
     * Update isLeafNode statusof a node
     * @param int $nodeId
     * @param int $isLeafNode
     * @throws ProfessionalException
     * @return object|NULL|\com\linways\base\util\$objectList[]
     */
    public function updateNodeLeafNodeStatus($nodeId, $isLeafNode) {
        $node = $this->realEscapeObject($node);
        $sql = "UPDATE nba_po_attainment_node SET is_leaf_node = $isLeafNode WHERE id = $nodeId";
        try {
            $this->executeQuery($sql);
        }
        catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return true;
    }
    public function addSubjectTreeMapping( $attainmentReq ) {
        $attainmentReq = $this->realEscapeObject($attainmentReq);
        $staffId = $_SESSION['staffID'];
        $sql = "INSERT INTO nba_subject_tree_mapping (treeId, batchId, semId, subjectId, createdBy, createdDate, updatedBy, updatedDate) VALUES (".$attainmentReq->treeId.", ".$attainmentReq->batchId.", ".$attainmentReq->semId.", ".$attainmentReq->subjectId.", ".$staffId.", utc_timestamp(), ".$staffId.", utc_timestamp()) ON DUPLICATE KEY UPDATE treeId = VALUES(treeId), updatedBy = VALUES(updatedBy), updatedDate = utc_timestamp()";
        try {
            $id = $this->executeQueryForObject($sql, true);
        }
        catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $id;
    }
    public function deleteSubjectTreeMapping( $attainmentReq ) {
        $attainmentReq = $this->realEscapeObject($attainmentReq);
        $staffId = $_SESSION['staffID'];
        $sql = "DELETE FROM nba_subject_tree_mapping WHERE batchId = ".$attainmentReq->batchId." AND semId = ".$attainmentReq->semId." AND subjectId = ".$attainmentReq->subjectId."";
        try {
            $id = $this->executeQueryForObject($sql, true);
        }
        catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $id;
    }
    public function getSubjectTree($batchId, $semId, $subjectId) {
        $batchId = $this->realEscapeString($batchId);
        $semId = $this->realEscapeString($semId);
        $subjectId = $this->realEscapeString($subjectId);
        $sql = "SELECT id, treeId, batchId, semId, subjectId, createdBy FROM nba_subject_tree_mapping WHERE batchId = ".$batchId." AND semId = ".$semId." AND subjectId = ".$subjectId."";
        try {
            $subjectTree = $this->executeQueryForObject($sql);
        }
        catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $subjectTree;
    }
    /**
     * This function is only for tesing purpose - which is called only from test..
     * Donot use this function anywhere else
     * Used to Copy all the tree from one department to all other departments
     * @param INT $deptId
     * @author Ambu
     */
    public function copyTreeToAllDepartments_bkp ( $deptId ) {
        $deptId = $this->realEscapeString($deptId);
        $sql = "SELECT deptID FROM department WHERE deptShow = 1 AND deptID != ".$deptId."";
        $deptList = $this->executeQueryForList ( $sql );
        foreach ( $deptList as $dept ) {
            $sql = "SELECT id, co_root_node_id, po_root_node_id FROM nba_po_attainment_tree WHERE deptID = ".$deptId."";
            $treeList = $this->executeQueryForList ( $sql );
            foreach ( $treeList as $tree ) {
                $sql = "INSERT INTO nba_po_attainment_tree (name, deptID, createdBy, createdDate, updatedBy, updatedDate) (SELECT name, ".$dept->deptID." , createdBy, utc_timestamp(), updatedBy, utc_timestamp() FROM nba_po_attainment_tree WHERE id = ".$tree->id.")";
                $newTreeId = $this->executeQueryForObject ( $sql, true );
                $sql = "SELECT id, parent_nba_po_attainment_node_id AS parentId FROM nba_po_attainment_node WHERE nba_po_attainment_tree_id = ".$tree->id." ORDER BY id ASC";
                $nodeList = $this->executeQueryForList ( $sql );
                $parentNodeArray = [];
                if ( !empty ( $nodeList ) ) {
                    foreach ( $nodeList as $node ) {
                        $parentNodeId = $parentNodeArray[$node->parentId] ? $parentNodeArray[$node->parentId] : 'NULL';
                        $sql = "INSERT INTO nba_po_attainment_node (nba_po_attainment_master_id, parent_nba_po_attainment_node_id, nba_po_attainment_tree_id, is_leaf_node, contribution, createdBy, createdDate, updatedBy, updatedDate) (SELECT nba_po_attainment_master_id, ".$parentNodeId.", ".$newTreeId.", is_leaf_node, contribution, createdBy, utc_timestamp(), updatedBy, utc_timestamp() FROM nba_po_attainment_node WHERE id = ".$node->id.")";
                        $newNodeId = $this->executeQueryForObject ( $sql, true );
                        $parentNodeArray[$node->id] = $newNodeId;
                    }
                }
                $sqlUpdate = '';
                if ( $tree->co_root_node_id ) {
                    $sqlUpdate .= ", co_root_node_id = ".$parentNodeArray[$tree->co_root_node_id]."";
                }
                if ( $tree->po_root_node_id ) {
                    $sqlUpdate .= ", po_root_node_id = ".$parentNodeArray[$tree->po_root_node_id]."";
                }
                $sql = "UPDATE nba_po_attainment_tree SET updatedDate = utc_timestamp() ".$sqlUpdate." WHERE id = ".$newTreeId."";
                $this->executeQuery ( $sql );
            }
        }
    }
    public function getAllNodesByTreeId ( $treeId ) {
        $treeId = $this->realEscapeString($treeId);
        $treeNodes = [];
        $sql = "SELECT node.id, node.nba_po_attainment_master_id AS masterId, master.name, node.parent_nba_po_attainment_node_id AS parentId, node.nba_po_attainment_tree_id, node.is_leaf_node, node.contribution FROM nba_po_attainment_node node INNER JOIN nba_po_attainment_master master ON (master.id = node.nba_po_attainment_master_id) WHERE node.nba_po_attainment_tree_id = ".$treeId."";
        try {
            $treeNodes = $this->executeQueryForList($sql);
        }
        catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $treeNodes;
    }
    public function getAllNodesByTreeIdAndSubjectId ( $treeId,$subjectId ) {
        $treeId = $this->realEscapeString($treeId);
        $subjectId = $this->realEscapeString($subjectId);
        $treeNodes = [];
        if($subjectId && $treeId){
            $sql = "SELECT node.id, node.nba_po_attainment_master_id AS masterId, master.name, node.parent_nba_po_attainment_node_id AS parentId, node.nba_po_attainment_tree_id, node.is_leaf_node, node.contribution FROM nba_po_attainment_node node INNER JOIN nba_po_attainment_master master ON (master.id = node.nba_po_attainment_master_id) WHERE node.nba_po_attainment_tree_id = ".$treeId." AND node.tree_edited_subject_id = ".$subjectId."";
        }else if($treeId){
            $sql = "SELECT node.id, node.nba_po_attainment_master_id AS masterId, master.name, node.parent_nba_po_attainment_node_id AS parentId, node.nba_po_attainment_tree_id, node.is_leaf_node, node.contribution FROM nba_po_attainment_node node INNER JOIN nba_po_attainment_master master ON (master.id = node.nba_po_attainment_master_id) WHERE node.nba_po_attainment_tree_id = ".$treeId." AND node.tree_edited_subject_id is NULL ";
        }
        try {
            if($sql)
            $treeNodes = $this->executeQueryForList($sql);
        }
        catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $treeNodes;
    }
          /**
     * Get university attainment leaf node
     * @param int $tree_id
     * @throws ProfessionalException
     * @return object|array|\com\linways\base\util\$objectList[]
     * @deprecated
     */
    public function getUniversityAttainmentLeafNodeId($tree_id) {
        $tree_id = $this->realEscapeString($tree_id);
        $universityAttainment = null;
        $sql = "SELECT node.id, node.is_leaf_node, master.name, node.contribution FROM nba_po_attainment_node node INNER JOIN nba_po_attainment_master master ON ( node.nba_po_attainment_master_id = master.id ) WHERE node.is_leaf_node = 1 AND node.nba_po_attainment_tree_id = ".$tree_id." AND master.name = 'External'";
        try {
            $universityAttainment = $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $universityAttainment;
    }
    public function updateNodeEnableEdit($nodeId,$isEnableEdit){
        $nodeId = $this->realEscapeString($nodeId);
        $sql = "UPDATE nba_po_attainment_node SET faculty_can_edit = '$isEnableEdit' WHERE id = $nodeId";
        try {
            $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
         return true;
    }
    public function updateNodeIsDelete($nodeIdList,$staffId,$nodeList,$nodeId){
        $nodeIdList = $this->realEscapeArray($nodeIdList);
        $staffId = $this->realEscapeString($staffId);
        $ids = implode("','", $nodeIdList);
        $sql = "UPDATE nba_po_attainment_node SET is_deleted = '1' WHERE id IN ('".$ids."')";
        try {
            $this->executeQuery($sql);
            $sql = "UPDATE nba_po_attainment_node SET is_leaf_node = '1' WHERE id = $nodeId";
            $this->executeQuery($sql);
            $this->logger->info(Events::DISABLE_TREE_EDIT_OPTION_AND_DELETE_EXISTING_NODES, [
                "staff" => new Staff(["id" => $staffId]),
                "deletedNodes" => $nodeList,
                ]);
                $sqlStaffDetails="select staffID,staffName from staffaccounts where staffID = '$staffId'";
                $staffDetails = $this->executeQueryForObject($sqlStaffDetails);
                $sqlStaffListToSendNotification = "SELECT sbs.staffID,nstm.subjectId,subjects.subjectName,npat.name as treeName,npam.name as masterNodeName from sbs_relation sbs
                                                    INNER JOIN
                                                nba_subject_tree_mapping nstm ON (nstm.subjectId = sbs.subjectID AND nstm.semId = sbs.semID AND nstm.batchId = sbs.batchID )
                                                    INNER JOIN
                                                nba_po_attainment_node npan ON ( npan.nba_po_attainment_tree_id = nstm.treeId)
                                                    INNER JOIN
                                                subjects ON (subjects.subjectID = nstm.subjectId)
                                                    INNER JOIN
                                                nba_po_attainment_tree npat ON (npat.id = npan.nba_po_attainment_tree_id)
                                                    INNER JOIN
                                                nba_po_attainment_master npam ON (npam.id = npan.nba_po_attainment_master_id)
                                                    WHERE
                                                npan.id = '$nodeId'";
                $staffListToSendNotification=$this->executeQueryForList($sqlStaffListToSendNotification);
            if(count( $staffListToSendNotification)){
                $notification = new Notification();
                $notification->context = NotificationContextConstant::NBA;
                $notification->feature = NotificationFeatureConstant::SENT_NOTIFICATION_TO_STAFF_WHEN_HOD_DISABLE_NODE_EDIT_OPTION;
                $notification->recipientType = UserType::STAFF;
                $notification->createdBy = $staffId?$staffId:0;
                foreach($staffListToSendNotification as $staff)
                {
                    $recipient = new NotificationRecipient();
                    $recipient->recipientId = $staff->staffID;
                    $recipient->recipientType = UserType::STAFF;
                    $recipient->templateParameters = ["nodeName" => $staff->masterNodeName,"subjectName" => $staff->subjectName,"staffName" => $staffDetails->staffName,"treeName" => $staffDetails->treeName];
                    $notification->recipient [] = $recipient;
                }
                NotificationService::getInstance()->sendNotification($notification);
            }
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
         return true;
    }
    public function getAssessmentMaxMark ( $assessmentDetails,$type ) {
        if ($type === 'ONLINE_EXAM' || $type === 'POLLS_SURVEY'){
            try{
                $sql = "SELECT
                            oee.id,
                            oee.name,
                            oee.properties,
                            SUM(oeq.mark) as totalMark
                        FROM
                            oe_exams oee
                            INNER JOIN
                            oe_exam_questions oeq ON (oee.id = oeq.oe_exams_id)
                        WHERE
                            oee.is_deleted = 0 AND
                            oee.id = '$assessmentDetails->assessment_id'";
            $exam = $this->executeQueryForObject($sql);
            $exam->properties= json_decode($exam->properties);
            $randomize = false;
            if ($type === 'ONLINE_EXAM' && property_exists($exam->properties, "randomize")){
                $randomize = $exam->properties->randomize->enable;
            }
            if($randomize === true){
                $questionLimit = $exam->properties->randomize->questionsLimit;
                $questionMark = $exam->properties->randomize->questionsMark;
                $maxMark = $questionLimit * $questionMark;
               return $maxMark;
            } else {
                $sql = "SELECT
                            section.id, section.name, section.properties
                        FROM
                            oe_exam_sections  section
                                INNER JOIN
                            oe_exams oee ON (section.oe_exams_id = oee.id)
                        WHERE
                            oee.id = '$exam->id'";
            $sectionDetails = $this->executeQueryForList($sql);
            $totalMark=0;
            if(count($sectionDetails)){
                foreach($sectionDetails as $section){
                    $section->properties= json_decode($section->properties);
                    if(property_exists($section->properties, "noOfQuestionsToAnswer") && $section->properties->noOfQuestionsToAnswer>0){
                        $totalMark=$totalMark+$section->properties->sectionQuestionMark;
                    }else{
                        $conditions="";
                        $sectionTotalMark=0;
                        $contexts =[];
                        if ( $section->id ) {
                            $contexts[] = '"section":"'.$section->id.'"';
                        }
                        $conditions .= " AND JSON_CONTAINS(oeq.properties, '{" . implode (",", $contexts ) . "}')";
                        $sql ="SELECT
                               oeq.id,
                               oeq.properties,
                               oeq.mark
                            FROM
                                oe_exam_questions oeq
                            WHERE
                                oeq.oe_exams_id = '$exam->id'  $conditions ";
                        $sectionQuestions = $this->executeQueryForList($sql);
                        foreach($sectionQuestions as $question){
                            $question->properties= json_decode($question->properties);
                            if(!property_exists($question->properties, "mainQuestionId")){
                                $totalMark=$totalMark+$question->mark;
                            }
                        }
                    }
                }
                $exam->examMaxMark = $totalMark;
            }else{
                $sql ="SELECT
                               oeq.id,
                               oeq.properties,
                               oeq.mark
                            FROM
                                oe_exam_questions oeq
                            WHERE
                                oeq.oe_exams_id = '$exam->id'";
                        $sectionQuestions = $this->executeQueryForList($sql);
                        foreach($sectionQuestions as $question){
                            $question->properties= json_decode($question->properties);
                            if(!property_exists($question->properties, "mainQuestionId")){
                                $totalMark= $totalMark+$question->mark;
                            }
                        }
                        $exam->examMaxMark = $totalMark;
            }
            }
             return $exam->examMaxMark;
            } catch (\Exception $e) {
                throw new ProfessionalException($e->getCode(), $e->getMessage());
            }
        } else if ($type === 'InternalExam') {
            $batchId = $this->realEscapeString($assessmentDetails->batch_id);
            $semId = $this->realEscapeString($assessmentDetails->sem_id);
            $subjectId = $this->realEscapeString($assessmentDetails->subject_id);
            $sql = "SELECT distinct examTypeID, typeName, examTotalMarks from exam ex inner join exam_type et on ex.examTypeID = et.typeID where subjectID = $subjectId AND batchID = $batchId AND semID = $semId AND ex.canShow = 1 and et.canShow= 1 and et.isInternal = 1 and examTypeID = $assessmentDetails->assessment_id ";
            try {
                return $this->executeQueryForObject($sql);
            } catch (\Exception $e) {
                throw new ProfessionalException($e->getCode(), $e->getMessage());
            }
        } else if ($type === 'EXAM'){
            $batchId = $this->realEscapeString($assessmentDetails->batch_id);
            $semId = $this->realEscapeString($assessmentDetails->sem_id);
            $subjectId = $this->realEscapeString($assessmentDetails->subject_id);
            $sql = "SELECT distinct examTypeID, typeName, examTotalMarks from exam ex inner join exam_type et on ex.examTypeID = et.typeID where subjectID = $subjectId AND batchID = $batchId AND semID = $semId AND ex.canShow = 1 and et.canShow= 1 and examTypeID = $assessmentDetails->assessment_id ";
            try {
                return $this->executeQueryForObject($sql);
            } catch (\Exception $e) {
                throw new ProfessionalException($e->getCode(), $e->getMessage());
            }
        }
    }
    /**
     * Get node's subjectwise CO value by node id only in the case of Course Wise calculation For student details
     * @param unknown $subjectAssessmentNodeReq
     * @throws ProfessionalException
     * @return object|array|\com\linways\base\util\$objectList[]
     */
    public function getSubjectAssessmentNodeCoValueForCourseWiseCalCulation ( $subjectAssessmentNodeReq ) {
        $obj = $this->realEscapeObject($subjectAssessmentNodeReq);
        $nbaMethod = NbaUtil::getNbaMethod();
        $isCurrentSem = SemesterService::getInstance()->isCurrentSemester($obj->batchId, $obj->semId);
        $subjectDetails = SubjectService::getInstance()->getSubject($subjectAssessmentNodeReq->subjectId);
        //check if subbatch
        $subbatchDetails = BatchService::getInstance()->getSubbatchBySubject($obj->subjectId, $obj->semId, $obj->batchId, $obj->staffId);
        $coPoCourseWiseCalculationDisplayStyle = "OBE_CO_PO_CALCULATION_STUDENT_WISE_DISPlAY_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){
            //since students are not considered here we need only a single query
            $sql = "SELECT node_co.node_id, node_co.co_id, node_co.value, '".$subjectDetails->name."' as studentName, node_co.batch_id, node_co.sem_id, node_co.subject_id FROM nba_course_outcome co INNER JOIN nba_course_wise_node_co_value node_co ON ( node_co.co_id = co.id AND node_co.batch_id = co.batchID AND node_co.sem_id = co.semID AND node_co.subject_id = co.subjectID) AND node_co.node_id = ".$obj->nodeId."  AND node_co.sem_id = ".$obj->semId." AND node_co.subject_id = ".$obj->subjectId." WHERE node_co.batch_id = ".$obj->batchId." AND node_co.node_id = ".$obj->nodeId."  AND node_co.sem_id = ".$obj->semId." AND node_co.subject_id = ".$obj->subjectId."  ORDER BY  node_co.co_id ASC";
        }
        // $sql = "SELECT node_co.node_id, node_co.co_id, node_co.value, node_co.student_id, sa.studentName, node_co.batch_id, node_co.sem_id, node_co.subject_id FROM nba_subject_node_co_value node_co INNER JOIN studentaccount sa ON ( node_co.student_id = sa.studentID ) WHERE node_co.node_id = ".$obj->nodeId." AND node_co.batch_id = ".$obj->batchId." AND node_co.sem_id = ".$obj->semId." AND node_co.subject_id = ".$obj->subjectId."  ORDER BY node_co.student_id, node_co.co_id ASC";
        elseif($nbaMethod == NbaMethod::STUDENT_MARK_ENTRY_IN_EXAT_METHOD){
            //since students are not considered here we need only a single query
            $sql = "SELECT node_co.node_id, node_co.co_id, node_co.value, node_co.student_id, '".$subjectDetails->name."' as studentName, node_co.batch_id, node_co.sem_id, node_co.subject_id FROM nba_course_outcome co INNER JOIN nba_subject_node_co_value node_co ON ( node_co.co_id = co.id AND node_co.batch_id = co.batchID AND node_co.sem_id = co.semID AND node_co.subject_id = co.subjectID) AND node_co.node_id = ".$obj->nodeId."  AND node_co.sem_id = ".$obj->semId." AND node_co.subject_id = ".$obj->subjectId." WHERE node_co.batch_id = ".$obj->batchId." AND node_co.node_id = ".$obj->nodeId."  AND node_co.sem_id = ".$obj->semId." AND node_co.subject_id = ".$obj->subjectId."  ORDER BY  node_co.co_id ASC";
        }else{
            if(empty($subbatchDetails))
            {
                if($isCurrentSem)
                {
                    $sql = "SELECT node_co.node_id, node_co.co_id, node_co.value, node_co.student_id, sa.studentName, node_co.batch_id, node_co.sem_id, node_co.subject_id FROM studentaccount sa inner JOIN nba_subject_node_co_value node_co ON ( node_co.student_id = sa.studentID ) AND node_co.node_id = ".$obj->nodeId."  AND node_co.sem_id = ".$obj->semId." AND node_co.subject_id = ".$obj->subjectId." WHERE sa.batchID = ".$obj->batchId." ORDER BY sa.rollNo, node_co.co_id ASC";
                }
                else
                {
                    $sql = "SELECT node_co.node_id, node_co.co_id, node_co.value, node_co.student_id, sa.studentName, node_co.batch_id, node_co.sem_id, node_co.subject_id, fs.* FROM studentaccount sa left join failed_students fs on sa.studentID = fs.studentID inner JOIN nba_subject_node_co_value node_co ON ( node_co.student_id = sa.studentID ) AND node_co.node_id = ".$obj->nodeId."  AND node_co.sem_id = ".$obj->semId." AND node_co.subject_id = ".$obj->subjectId." WHERE sa.studentID in (select studentID from studentaccount where batchID = ".$obj->batchId." union select studentID from failed_students where previousBatch = ".$obj->batchId." and failedInSemester > ".$obj->semId.") ORDER BY sa.rollNo, node_co.co_id ASC";
                }
            }
            else
            {
                if($isCurrentSem)
                {
                    $sql =  "select distinct node_co.node_id, node_co.co_id, node_co.value, node_co.student_id, sa.studentName, node_co.batch_id, node_co.sem_id, node_co.subject_id from sbs_relation sr inner join subbatch_sbs ssbs on sr.sbsID = ssbs.sbsID inner join subbatch_student ss on ss.subbatchID = ssbs.subbatchID inner join studentaccount sa on sa.studentID = ss.studentID inner join nba_subject_node_co_value node_co ON ( node_co.student_id = sa.studentID ) and sr.semID = node_co.sem_id and sr.batchID = node_co.batch_id and sr.subjectID=  node_co.subject_id  where  sr.semID = ".$obj->semId." AND sr.subjectID = ".$obj->subjectId." and sr.batchID = ".$obj->batchId." AND node_co.node_id = ".$obj->nodeId." ORDER BY sa.rollNo, node_co.co_id ASC;";
                }
                else
                {
                    $sql =  "select distinct node_co.node_id, node_co.co_id, node_co.value, node_co.student_id, sa.studentName, node_co.batch_id, node_co.sem_id, node_co.subject_id from sbs_relation sr inner join subbatch_sbs ssbs on sr.sbsID = ssbs.sbsID inner join subbatch_student ss on ss.subbatchID = ssbs.subbatchID inner join studentaccount sa on sa.studentID = ss.studentID inner join nba_subject_node_co_value node_co ON ( node_co.student_id = sa.studentID ) and sr.semID = node_co.sem_id and sr.batchID = node_co.batch_id and sr.subjectID=  node_co.subject_id  where  sr.semID = ".$obj->semId." AND sr.subjectID = ".$obj->subjectId." and sr.batchID = ".$obj->batchId." AND node_co.node_id = ".$obj->nodeId." and sa.studentID in (select studentID from studentaccount where batchID = ".$obj->batchId." union select studentID from failed_students where previousBatch = ".$obj->batchId." and failedInSemester > ".$obj->semId.") ORDER BY sa.rollNo, node_co.co_id ASC;";
                }
            }
        }
        try {
            $subjectNodeCoNew =[];
            $subjectNodeCo = $this->executeQueryForList($sql);
            $sqlAssessmentNode = "select assessment_id as assessmentId, assessment_type_id as assessmentTypeId from nba_po_attainment_node_assessment where nba_po_attainment_node_id = '$obj->nodeId' AND batch_id = '$obj->batchId' AND sem_id = '$obj->semId' AND subject_id = '$obj->subjectId'";
            $assessmentTypeDetails = $this->executeQueryForObject($sqlAssessmentNode);
            $assessmentType = NbaCoPoService::getInstance()->getAssessmentTypeCodeFromId($assessmentTypeDetails->assessmentTypeId);
            if($assessmentType == AssessmentType::UNIVERSITY_EXAM && $coPoCourseWiseCalculationDisplayStyle == NbaMethod::OBE_CO_PO_CALCULATION_STUDENT_WISE_DISPlAY_IN_TREE_NODE){
                $getGradePointRequest = new GetGradePointOfStudentExamRequest ();
                $getGradePointRequest->examId = $assessmentTypeDetails->assessmentId;
                $getGradePointRequest->batchId = $obj->batchId;
                $getGradePointRequest->semId = $obj->semId;
                $getGradePointRequest->subjectId = $obj->subjectId;
                $studentUniversityMarks = UniversityExamService::getInstance()->getGradePointsOfStudentsForAnExam($getGradePointRequest);
                foreach($subjectNodeCo as $key => $studentCo){
                    $isAttend = false;
                    foreach($studentUniversityMarks as $studentUniversity){
                        if($studentCo->student_id == $studentUniversity->studentId){
                            $isAttend = true;
                        }
                    }
                    if($isAttend == true){
                        array_push($subjectNodeCoNew, $studentCo);
                    }
                }
                $subjectNodeCo = $subjectNodeCoNew;
            }
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $subjectNodeCo;
    }
}