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 / 16
CRAP
0.00% covered (danger)
0.00%
0 / 252
StreamService
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 16
2652.00
0.00% covered (danger)
0.00%
0 / 252
 __construct
0.00% covered (danger)
0.00%
0 / 1
2.00
0.00% covered (danger)
0.00%
0 / 2
 saveStream
0.00% covered (danger)
0.00%
0 / 1
56.00
0.00% covered (danger)
0.00%
0 / 25
 validateSaveStreamRequest
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 4
 insertStream
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 14
 updateStream
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 17
 deleteStream
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 17
 restoreStream
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 17
 searchStream
0.00% covered (danger)
0.00%
0 / 1
132.00
0.00% covered (danger)
0.00%
0 / 48
 getStreamDetails
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 23
 deleteStreamPermanently
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 11
 validateStreamBeforeDelete
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 22
 findPatternDepartmentCourseByIds
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 13
 haveId
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 4
 haveIds
0.00% covered (danger)
0.00%
0 / 1
20.00
0.00% covered (danger)
0.00%
0 / 10
 insertPatternDeptCourse
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 12
 updatePatternDeptCourse
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 13
<?php
namespace com\linways\core\ams\professional\service\academic;
use com\linways\base\util\SecurityUtils;
use com\linways\base\util\MakeSingletonTrait;
use com\linways\core\ams\professional\service\BaseService;
use com\linways\core\ams\professional\exception\ProfessionalException;
use com\linways\core\ams\professional\mapper\academic\StreamServiceMapper;
use com\linways\core\ams\professional\request\academic\SearchStreamRequest;
use com\linways\core\ams\professional\constant\academic\StatusConstants;
use com\linways\core\ams\professional\dto\api\Stream;
use com\linways\core\ams\professional\request\academic\SearchProgramRequest;
class StreamService extends BaseService
{
    use MakeSingletonTrait;
    private function __construct() {
        $this->mapper = StreamServiceMapper::getInstance()->getMapper();
    }
    /**
     * Save stream
     * @param Stream $stream
     * @return String $id
     */
    public function saveStream (Stream $stream)
    {
        $stream = $this->realEscapeObject($stream);
        $stream->createdBy = $GLOBALS['userId'] ?? $stream->createdBy;
        $stream->updatedBy = $GLOBALS['userId'] ?? $stream->updatedBy;
        try{
            $this->validateSaveStreamRequest($stream);
            
            if(!empty($stream->id))
            {
                $stream->id = $this->updateStream($stream);
            }
            else
            {
                $stream->id = $this->insertStream($stream);
            }
        }catch(\Exception $e) {
            if($e->getCode() !== ProfessionalException::INVALID_PARAMETER && $e->getCode() !== ProfessionalException::EMPTY_PARAMETERS && $e->getCode() !== ProfessionalException::DUPLICATE_ENTRY) {
                throw new ProfessionalException($e->getCode(),"Failed to save Stream! Please try again");
            } else if ($e->getCode() === ProfessionalException::DUPLICATE_ENTRY) {
                throw new ProfessionalException (ProfessionalException::DUPLICATE_ENTRY,"Cannot create stream $stream->name already exists!");
            } else {
                throw new ProfessionalException ($e->getCode(),$e->getMessage());
            }
        }
        
        return $stream->id;
    }
    
    /**
     * Validate Stream Request Before Saving
     * @param Stream $stream
     * @return NULL
     */
    private function validateSaveStreamRequest(Stream $stream)
    {
        if(empty($stream->name))
            throw new ProfessionalException(ProfessionalException::EMPTY_PARAMETERS,"Stream name is empty! Please enter a name for stream");
    }
    
    /**
     * Insert Stream
     * @param Stream $stream
     * @return String $id
     */
    private function insertStream(Stream $stream)
    {
        $properties = !empty($stream->properties) ? "'" . json_encode($stream->properties) . "'" : "NULL";
        $id = SecurityUtils::getRandomString();
        $query = 
        "INSERT INTO `stream`
            (`id`,`name`,`properties`,`created_by`,`updated_by`)
        VALUES ('$id','$stream->name',$properties,'$stream->createdBy','$stream->updatedBy')";
        
        
        try {
            $this->executeQuery($query);
            // $this->insertPatternDeptCourse($id);
            return $id;
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(),$e->getMessage());
        }
    }
    /**
     * Update Stream
     * @param Stream $stream
     * @return NULL
     */
    private function updateStream(Stream $stream)
    {
        $properties = !empty($stream->properties) ? "'".json_encode($stream->properties)."'" : "NULL";
        
        $query = "UPDATE
                    `stream`
                SET
                    `name` = '$stream->name',
                    `properties` = $properties,
                    `updated_by` = '$stream->updatedBy'
                WHERE
                    `id` = '$stream->id'";
        try {
            // $this->updatePatternDeptCourse($stream);
            $this->executeQuery($query);
            return $stream->id;
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(),$e->getMessage());
        }
    }
    /**
     * Delete Stream (Soft Delete)
     * @param String $id
     * @return NULL
     */
    public function deleteStream($id)
    {
        $id = $this->realEscapeString($id);
        $updatedBy = $GLOBALS['userId'];
        $this->haveId($id);
        $query = "UPDATE
                    `stream`
                SET
                    `trashed` = UTC_TIMESTAMP(),
                    `updated_by` = '$updatedBy'
                WHERE
                    `id` = '$id'";
        try {
            $this->executeQuery($query);
        } catch (\Exception $e) {
            throw new ProfessionalException(ProfessionalException::ERROR_DELETING,"Error deleting stream! Please try again");
        }
    }
    /**
     * Restore Stream
     * @param String $id
     * @return NULL
     */
    public function restoreStream($id)
    {
        $id = $this->realEscapeString($id);
        $updatedBy = $GLOBALS['userId'];
        $this->haveId($id);
        $query = "UPDATE
                    `stream`
                SET
                    `trashed` = NULL,
                    `updated_by` = '$updatedBy'
                WHERE
                    `id` = '$id'";
        try {
            $this->executeQuery($query);
        } catch (\Exception $e) {
            throw new ProfessionalException(ProfessionalException::ERROR_RESTORING,"Error restoring academic term! Please try again");
        }
    }
    
    /**
     * Search Academic term Details
     * @param SearchStreamRequest $request
     * @return Stream
     */
    public function searchStream(SearchStreamRequest $request)
    {
        $request = $this->realEscapeObject($request);
        $whereQuery = "";
        $limitQuery = "";
        if(!empty($request->id)) {
            $whereQuery .= " AND st.id='$request->id";
        }
        if(!empty($request->ids)) {
            $whereQuery .= " AND st.id in ("."'".implode("','", $request->ids)."'".") ";
        }
        if($request->trashed === StatusConstants::ACTIVE) {
            $whereQuery .= " AND st.trashed IS NULL ";
        }
        if($request->trashed === StatusConstants::TRASHED) {
            $whereQuery .= " AND st.trashed IS NOT NULL ";
        }
        if(!empty($request->name)) {
            $whereQuery .= " AND  st.name LIKE '%$request->name%' ";
        } 
        if(!empty($request->checkIsActive)) {
            $whereQuery .= " AND  st.properties->>'$.isActive' = '".($request->isActive ? '1':'0')."' ";
        } 
        if($request->startIndex !== "" && $request->endIndex !== "")
        {
            $limitQuery .= " LIMIT $request->startIndex,$request->endIndex";
        }
        $orderBy = " ORDER BY st.created_date DESC ";
        
        $query = "SELECT
            st.id,
            st.name,
            st.properties,
            st.departmentId,
            st.trashed,
            st.created_by,
            st.created_date,
            st.updated_by,
            st.updated_date
        FROM
            `stream` st
        WHERE
            1 = 1";
        try {
            $streams = $this->executeQueryForList($query.$whereQuery.$orderBy.$limitQuery, $this->mapper[StreamServiceMapper::SEARCH_STREAMS]);
        } catch (\Exception $e) {
            throw new ProfessionalException(ProfessionalException::ERROR_FETCHING,"Cannot fetch stream details! Please try again.");
        }
        return $streams;
    } 
    /**
     * get Academic term by id
     * @param String $id
     * @return Stream
     */
    public function getStreamDetails($id)
    {
        $id = $this->realEscapeObject($id);
        $this->haveId($id);
            $query = "SELECT
            st.id,
            st.name,
            st.properties,
            st.trashed,
            st.created_by,
            st.created_date,
            st.updated_by,
            st.updated_date
        FROM
            `stream` st
        WHERE
            `id` = '$id'";
        try {
            $stream = $this->executeQueryForObject($query,false, $this->mapper[StreamServiceMapper::SEARCH_STREAMS]);
        } catch (\Exception $e) {
            throw new ProfessionalException(ProfessionalException::ERROR_FETCHING,"Cannot fetch stream details! Please try again");
        }
        return $stream;
    }
    /**
     * Delete Stream (Permanently Delete)
     * @param String $id
     * @return NULL
     */
    public function deleteStreamPermanently($id)
    {
        $id = $this->realEscapeString($id);
        $this->haveId($id);
        $this->validateStreamBeforeDelete($id);
        $query = "DELETE FROM `stream` WHERE `id` = '$id';";
        try {
            $this->executeQuery($query);
        } catch (\Exception $e) {
            throw new ProfessionalException(ProfessionalException::ERROR_DELETING,"Error deleting stream! Please try again");
        }
    }
    /**
     * Delete Stream (Permanently Delete)
     * @param String $id
     * @return NULL
     */
    public function validateStreamBeforeDelete($id)
    {
        $id = $this->realEscapeString($id);
        $this->haveId($id);
        $request = new SearchProgramRequest();
        $request->streamIds [] = $id;
        $programs = ProgramService::getInstance()->searchProgram($request);
        if(!count($programs)){
            try {
                $this->executeQuery("UPDATE pattern_deptcourses p
                    INNER JOIN (SELECT pd.patterncourseID AS id,JSON_ARRAYAGG(s2.id) AS stream_ids FROM pattern_deptcourses pd 
                    INNER JOIN stream s ON json_contains(pd.stream_ids,CONCAT('\"',s.id,'\"'),'$')
                    INNER JOIN stream s2 ON json_contains(pd.stream_ids,CONCAT('\"',s2.id,'\"'),'$') AND s.id <> s2.id
                    WHERE s.id = '$id'
                    GROUP BY pd.patterncourseID) t ON p.patterncourseID = t.id
                    SET p.stream_ids = t.stream_ids;");
            } catch (\Exception $e) {
                throw new ProfessionalException(ProfessionalException::ERROR_DELETING,"Error while deleting! Please try again");
            }
        }else{
            throw new ProfessionalException(ProfessionalException::HAVE_RELATIONS,"Cannot delete stream! Please try again.");
        }
    }
    /**
     * Find pattern-department-course 
     * @param ARRAY $ids
     * @return NULL
     */
    public function findPatternDepartmentCourseByIds($request)
    {
        $request = $this->realEscapeObject($request);
        $streamIds = $this->haveIds($request->streamIds);
        
        try {
            return $this->executeQueryForObject(
                "SELECT `patterncourseID` AS `id`, `patterncourseName` AS name, `patternID` AS `patternId`, `deptID` AS `departmentId`, `patterncourseCode` AS `code`, `patternAbbreviation` AS `abbreviation`, `extraSettings`, `stream_ids`, `isHide` 
                FROM `pattern_deptcourses` 
                WHERE JSON_CONTAINS(`stream_ids`,concat('\"','$streamIds[0]','\"'),'$');"
            );
        } catch (\Exception $e) {
            throw new ProfessionalException(ProfessionalException::ERROR_DELETING,"Error while deleting! Please try again");
        }
    }
    public function haveId($id,$msg = null){
        $msg = $msg ? $msg : 'Stream';
        if(empty($id))
            throw new ProfessionalException(ProfessionalException::EMPTY_PARAMETERS,"$msg is invalid! Please enter a valid ".strtolower($msg));
    }
    
    public function haveIds($ids){
        $returnIds = [];
        foreach ($ids as $id) {
            $id ? $returnIds [] = $id : ""; 
        }
        if(count($ids)){
            return $returnIds;
        }else{
            throw new ProfessionalException(ProfessionalException::EMPTY_PARAMETERS,"Stream is invalid! Please enter a valid streams");
        }
    }
    
    /**
     * Insert pattern dept course
     * @param Stream $id
     */
    private function insertPatternDeptCourse($streamId)
    {
        $streamId = $this->realEscapeString($streamId);
        $query = 
        "INSERT INTO `pattern_deptcourses` (`patterncourseName`, `deptID`, `patterncourseCode`, `patternAbbreviation`, `stream_ids`, `isHide`)
        SELECT `name`, `departmentId`, s.properties->'$.code', s.properties->'$.abbreviation', json_array(`id`), if(s.properties->'$.isActive',0,1) as `isHide`
        from `stream` s where s.id = '".$streamId."';";
        try {
            $this->executeQuery($query);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(),$e->getMessage());
        }
    }
    
    /**
     * Insert pattern dept course
     * @param Stream $id
     * @deprecated
     */
    private function updatePatternDeptCourse($stream)
    {
        $stream = $this->realEscapeObject($stream);
        $query = 
        "UPDATE `pattern_deptcourses` pdc
        INNER JOIN `stream` s ON JSON_CONTAINS(pdc.stream_ids,concat('\"',s.id,'\"'),'$')
        SET pdc.patternAbbreviation = REPLACE(pdc.patternAbbreviation, s.name, '$stream->name')
        WHERE s.id = '".$stream->id."';";
        try {
            $this->executeQuery($query);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(),$e->getMessage());
        }
    }
}