defaultSteps = [1, 2]; } /** * Get and format info about processes * @param - optional string $nameToSearch is the name of the package or process to be searched * @return array - returns a formatted array with process details */ public function getProcessInfo($nameToSearch = '') { global $database; $whereClause = ''; $processInfo = []; if(!empty($nameToSearch)) { $whereClause = " WHERE c.name LIKE '%".$database->escapeValue($nameToSearch)."%' OR proc.name LIKE '%".$database->escapeValue($nameToSearch)."%' "; } $sql = "SELECT proc.id AS idProcess, proc.name AS processName, ps.shortDesc AS processStep, ps.isVisibleForCustomer AS isVisibleForCustomer, c.id AS idCountry, c.name AS countryName FROM ".TABLES['process_step']." ps INNER JOIN ".TABLES['rel_process_steps']." rps ON rps.idStep = ps.id INNER JOIN ( SELECT rps_last.idProcess, MAX(rps_last.processInstance) as lastInstace FROM ".TABLES['rel_process_steps']." rps_last GROUP BY rps_last.idProcess ) last_inst ON last_inst.idProcess=rps.idProcess AND last_inst.lastInstace=rps.processInstance INNER JOIN ".TABLES['processes']." proc ON proc.id = rps.idProcess INNER JOIN ".TABLES['countries']." c ON c.id=proc.idCountry $whereClause ORDER BY processName, rps.idParent"; $query = $database->query($sql); while($row = $database->fetchArray($query)){ if(!isset($processInfo[$row['idCountry']])){ $processInfo[$row['idCountry']] = [ 'idCountry' => $row['idCountry'], 'countryName' => $row['countryName'] ]; } if(!isset($processInfo[$row['idCountry']]['processes'][$row['idProcess']])){ $processInfo[$row['idCountry']]['processes'][$row['idProcess']] = $row; } $processInfo[$row['idCountry']]['processes'][$row['idProcess']]['steps'][] = [ 'stepName' => $row['processStep'], 'isVisibleForCustomer' => $row['isVisibleForCustomer'] ]; } return $processInfo; } /** * Get only the processes that match the wanted string * @param string $nameToSearch is the name of the package or process to be searched * @return array - returns a formatted array with process details */ public function searchProcess($nameToSearch) { if(empty($nameToSearch)) { return [ 'messageData'=> [ 'status' => 'error', 'message' => 'SEARCH_EMPTY' ] ]; } $processesFound = $this->getProcessInfo($nameToSearch); if($processesFound) { $data['data'] = $processesFound; $data['messageData'] = [ 'status' => 'success', 'message' => 'SEARCH_SUCCESS' ]; } else { $data['messageData'] = [ 'status' => 'warning', 'message' => 'SEARCH_SUCCESS_EMPTY' ]; } return $data; } /** * add or remove links between processes and package * @param INT $idPackage id of the package * @param Array[Objects] $selectedProcesses processes that need to be linked to the package * @return Array update message */ public function linkProcessesToPackage($idPackage, $selectedProcesses){ global $database; $idPackage = $database->escapeValue($idPackage); $selectedProcesses = json_decode($selectedProcesses); $data = []; $valuesSql = ""; $notToDelSql = ""; if($idPackage == 0){ $data['messages'][] = [ 'code' => 'error', 'message' => 'NO_COUNTRY_OR_PACKAGE' ]; return $data; } if(count($selectedProcesses) === 0){ $data['messages'][] = [ 'code' => 'error', 'message' => 'NO_PROCESS_SELECTED' ]; return $data; } foreach ($selectedProcesses as $process) { $idProcess = $database->escapeValue($process->idProcess); $valuesSql .= "(".$idPackage.", ".$idProcess." ),"; $notToDelSql .= $idProcess . ','; } if($valuesSql !== "") { $valuesSql = rtrim($valuesSql, ','); $sql = "INSERT IGNORE INTO ".TABLES['rel_package_processes']." (idPackage, idProcess) VALUES $valuesSql"; $database->query($sql); $insertedProcesses = $database->affectedRows(); $notToDelSql = rtrim($notToDelSql, ','); $sql = "DELETE FROM ".TABLES['rel_package_processes']." WHERE idPackage=$idPackage AND idProcess NOT IN ($notToDelSql)"; $database->query($sql); $deletedProcesses = $database->affectedRows(); if($insertedProcesses < 1 && $deletedProcesses < 1){ $data['messages'][] = [ 'code' => 'warning', 'message' => 'NO_CHANGES_PROCESS' ]; }else{ $data['messages'][] = [ 'code' => 'success', 'message' => 'PROCESSES_LINKED' ]; } } return $data; } /** * get the list of packages that don't have processes associated * @return Array array of packages */ public function getPackagesAndProcesses($idCountry = 0) { global $database; $sql = "SELECT p.id AS idPackage, p.name AS packageName FROM ".TABLES['packages']." p LEFT OUTER JOIN ".TABLES['rel_package_processes']." rpp ON rpp.idPackage=p.id WHERE p.idCountry = $idCountry AND p.idPackageType!=".self::ID_PACKAGE_OPTION_TYPE; return $database->fetchResultArray($sql); } /** * get info and steps for processes * @param INT $idPackage id for package (only to get also linked processes) * @return Array list of steps and processes */ public function getProcesses($idPackage){ global $database; $idPackage = $database->escapeValue($idPackage); $data = []; $sql = "SELECT ps.shortDesc, rps.idProcess, ps.isVisibleForCustomer FROM ".TABLES['process_step']." ps INNER JOIN ".TABLES['rel_process_steps']." rps ON ps.id=rps.idStep INNER JOIN ( SELECT rps_last.idProcess, MAX(rps_last.processInstance) as lastInstace FROM ".TABLES['rel_process_steps']." rps_last GROUP BY rps_last.idProcess ) last_inst ON last_inst.idProcess=rps.idProcess AND last_inst.lastInstace=rps.processInstance ORDER BY rps.idParent"; $query = $database->query($sql); while($row = $database->fetchArray($query)){ $data['steps'][$row['idProcess']][] = [ 'shortDesc' => $row['shortDesc'], 'isVisibleForCustomer' => $row['isVisibleForCustomer'] ]; } $sql = "SELECT proc.id AS idProcess, proc.name AS processName, CASE WHEN rel_proc.idProcess IS NULL THEN '0' ELSE '1' END AS isSelected FROM ".TABLES['processes']." proc LEFT OUTER JOIN (SELECT rp.idProcess FROM ".TABLES['rel_package_processes']." rp WHERE rp.idPackage=$idPackage ) rel_proc ON proc.id=rel_proc.idProcess ORDER by proc.name ASC"; $data['processes'] = $database->fetchResultArray($sql); return $data; } /** * get processes names and ids for editing * @return array of ids and names for all available processes */ public function getProcessNames() { global $database; $sql = "SELECT p.id, p.idCountry, p.name FROM " . TABLES['processes'] ." p ORDER BY p.name "; return $database->fetchResultArray($sql); } /** * get info and steps for processes available for editing * @param idProcess - the id of the process selected for editing * @return Array - list of steps and processes */ public function getStepsForProcessSelected($idProcess, $getAllSteps = false){ global $database; $data = []; $whereClause = ''; $stepsInProcess = ''; if($idProcess) { $whereClause = " AND rps.idProcess = $idProcess"; } if(!$getAllSteps){ $whereClause .= " AND idStep NOT IN("; foreach($this->defaultSteps as $idStep) { $whereClause .= $idStep.','; } $whereClause = rtrim($whereClause, ',') . ')'; } foreach($this->defaultSteps as $idStep) { $stepsInProcess .= $idStep.','; } $sql = "SELECT ps.id, ps.shortDesc, ps.isVisibleForCustomer, rps.idStep AS idStep FROM ".TABLES['process_step']." ps INNER JOIN ".TABLES['rel_process_steps']." rps ON ps.id=rps.idStep INNER JOIN ( SELECT rps_last.idProcess, MAX(rps_last.processInstance) as lastInstace FROM ".TABLES['rel_process_steps']." rps_last GROUP BY rps_last.idProcess ) last_inst ON last_inst.idProcess=rps.idProcess AND last_inst.lastInstace=rps.processInstance WHERE 1=1 $whereClause ORDER BY rps.idParent"; $query = $database->query($sql); while($row = $database->fetchArray($query)){ $data['processSteps'][] = $row; $stepsInProcess .= $row['idStep'] . ','; } $stepsInProcess = $stepsInProcess ? rtrim($stepsInProcess, ',') : ''; $sql = "SELECT proc.id AS idStep, proc.shortDesc, proc.isVisibleForCustomer FROM ".TABLES['process_step']." proc WHERE proc.id NOT IN ($stepsInProcess) ORDER by proc.shortDesc ASC"; $query = $database->query($sql); while($row = $database->fetchArray($query)){ $data['steps'][$row['idStep']] = [ 'shortDesc' => $row['shortDesc'], 'isVisibleForCustomer' => $row['isVisibleForCustomer'] ]; } return $data; } /** * Edit a process - name and steps * @param $idProcess - the id of the process needed to be updated * @param $processData - the information regarding the process - name and steps * @return array - status message */ public function editProcess($idProcess, $processData) { global $database; $idProcess = $database->escapeValue($idProcess); $processName = $database->escapeValue($processData['processName']); $idCountry = $database->escapeValue($processData['idCountry']); $steps = $processData['processSteps']; $data['idProcess'] = $idProcess; $changeFound = false; if($data['messageData'] = $this->validateEditProcessData($idProcess, $processName, $idCountry)) { return $data; } $sql = "UPDATE ".TABLES['processes']." SET name='".$processName."', idCountry='".$idCountry."' WHERE id=$idProcess "; $result = $database->query($sql); if($database->affectedRows() > 0) { $data['messageData'][] = [ 'code' => 'success', 'message' => 'PROCESS_NAME_UPDATED' ]; } $originalProcessSteps = $this->getStepsForProcessSelected($idProcess, false)['processSteps']; if(count($originalProcessSteps) !== count($steps)){ $changeFound = true; }else{ for($i=0; $i 'warning', 'message' => 'PROCESS_STEPS_NOT_CHANGED' ]; return $data; } $idStepsUpdated = ''; $idStepInserted = 0; $sql = "SELECT MAX(rps.processInstance) AS processInstance FROM ".TABLES['rel_process_steps']." rps WHERE idProcess=$idProcess LIMIT 1"; $processInstance = $database->fetchResultArray($sql); $processInstance = isset($processInstance[0]['processInstance']) ? $processInstance[0]['processInstance'] + 1 : 1; $idStepInserted = $this->addProcessDefaultSteps($idProcess, $idStepInserted, $processInstance); foreach($steps as $index => $processStep) { $idStepInserted = $this->addProcessStepsInDb($processStep['idStep'], $idProcess, $idStepInserted, $processInstance); } if($idStepInserted > 0) { $data['messageData'][] = [ 'code' => 'success', 'message' => 'PROCESS_STEPS_UPDATED' ]; } return $data; } /** * validate the data required for a process * @param INT $idProcess id for the process * @param String $processName name for the process * @param INT $idCountry id for country * @return Array error message array or null in case of success */ private function validateEditProcessData($idProcess, $processName, $idCountry) { global $database; if($idProcess <= 0) { $message[] = [ 'code' => 'error', 'message' => 'PROCESS_NOT_FOUND' ]; return $message; } if(empty($idCountry) || $idCountry == 0){ $message[] = [ 'code' => 'error', 'message' => 'COUNTRY_MANDATORY' ]; return $message; } $sql = "SELECT p.name FROM " . TABLES['processes'] . " p WHERE p.name = '".$processName."' AND p.id <> $idProcess "; $result = $database->query($sql); if($database->affectedRows() > 0) { $message[] = [ 'code' => 'error', 'message' => 'PROCESS_NAME_EXISTS' ]; return $message; } return; } /** * Add process and relations to package and process steps in DB * @param array $data contains the details for every step * @param string $processName is the name of the process which will be added * @param int $idCountry io for the country * @return array - returns a failure or success message for adding the process in the DB */ public function addProcess($data, $processName, $idCountry) { $messages['messageData'] = []; if(empty($data) || empty($processName) || empty($idCountry) || $idCountry == 0) { $messages['messageData'][] = [ 'code' => 'error', 'message' => 'PROCESS_DATA_MISSING' ]; return $messages; } if(strlen($processName) > 150) { $messages['messageData'][] = [ 'code' => 'error', 'message' => 'STRING_TOO_LONG', 'type' => 'Process name', 'limit' => 150 ]; return $messages; } if($this->checkIfProcessExists($processName)) { $messages['messageData'][] = [ 'code' => 'error', 'message' => 'PROCESS_NAME_EXISTS' ]; return $messages; } $idProcess = $this->addProcessName($processName, $idCountry); $idStepInserted = 0; $idStepInserted = $this->addProcessDefaultSteps($idProcess, $idStepInserted, 1); foreach($data as $index => $processStep) { $idStepInserted = $this->addProcessStepsInDb($processStep->id, $idProcess, $idStepInserted, 1); } $messages['messageData'][] = [ 'code' => 'success', 'message' => 'PROCESS_ADDED' ]; return $messages; } /** * add the default steps for a process * @param INT $idProcess id for the process * @param INT $idStepInserted id of last insterted step * @param INT $processInstance instance of the process */ private function addProcessDefaultSteps($idProcess, $idStepInserted, $processInstance){ foreach($this->defaultSteps as $idProcessStep){ $idStepInserted = $this->addProcessStepsInDb($idProcessStep, $idProcess, $idStepInserted, $processInstance); } return $idStepInserted; } /** * check if a process already exists * @param String $processName process name * @return Boolean returns true in case a process with this name is found */ private function checkIfProcessExists($processName) { global $database; $sql = "SELECT p.name FROM ".TABLES['processes']." p WHERE p.name = '".$database->escapeValue(trim($processName))."' "; $result = $database->query($sql); $numRows = $database->numRows($result); return $numRows > 0; } /** * Insert in the DB the process steps for the recently added process * @param array or object $processStep contains the details and/or chidren for every step * @param int $idProcess is the id of the process name added in the corresponding table */ private function addProcessStepsInDb($idProcessStep, $idProcess, $idStepInserted = 0, $processInstance = 1) { global $database; $sql = "INSERT INTO ".TABLES['rel_process_steps']." (idProcess, processInstance, idStep, idParent) VALUES( ".$database->escapeValue($idProcess).", ".$database->escapeValue($processInstance).", ".$database->escapeValue($idProcessStep).", ".$database->escapeValue($idStepInserted)." )"; $database->query($sql); return $database->getInsertId(); } /** * Add process name in the corresponding table and return the inserted id * @param string $processName is the name of the process which will be added * @param INT $idCountry id for country * @return int - returns the latest inserted process name */ private function addProcessName($processName, $idCountry) { global $database; $sql = "INSERT INTO ".TABLES['processes']." (name, idCountry) VALUES( '".$database->escapeValue($processName)."', '".$database->escapeValue($idCountry)."' )"; $result = $database->query($sql); return $database->getInsertId(); } /** * Get existing process steps * @param int $idPackage is the id of the package selected * @return int - returns number of products added in the package */ public function getProcessSteps($idPackage) { $processSteps = $this->getProcessStepsFromDB(); return [ 'steps'=> $processSteps, 'process'=> [] ]; } /** * Get existing process steps from DB * @return array - returns array with process steps existing in DB */ private function getProcessStepsFromDB() { global $database; $sql = "SELECT proc.id, proc.shortDesc, proc.fullDesc, proc.idUserType, proc.isVisibleForCustomer FROM ".TABLES['process_step']." proc WHERE proc.id NOT IN(1, 2) ORDER BY proc.shortDesc"; return $database->fetchResultArray($sql); } /** * Add process step in DB * @param string $shortDesc is the short description of the process step * @param string $fullDesc is the full description of the process step * @param int $idUserType is the id of the user type selected that is able to modify the step * @param int $isStepVisible is a flag for making the step visible or not for the customer * @param string $extraActionCode is the extra action name, if it is the case * @return array - returns a failure or success message for adding the process step in the DB */ public function addProcessStep($shortDesc, $fullDesc, $idUserType, $isStepVisible, $extraActionCode) { global $database; $extraInsertFields = ''; $extraInsertValues = ''; if($shortDesc === '' || $fullDesc === ''){ $data['messageData'][] = [ 'code' => 'error', 'message' => 'DESC_MISSING' ]; return $data; } if($idUserType == 0) { $data['messageData'][] = [ 'code' => 'error', 'message' => 'USER_TYPE_MISSING' ]; return $data; } if(strlen($shortDesc) > 100) { $data['messageData'][] = [ 'code' => 'error', 'message' => 'STRING_TOO_LONG', 'type' => 'Short description', 'limit' => 100 ]; return $data; } if(strlen($fullDesc) > 500) { return [ 'messageData' => [ 'code' => 'error', 'message' => 'STRING_TOO_LONG', 'type' => 'Full description', 'limit' => 500 ] ]; } if($this->checkIfProcessStepExists($shortDesc)) { $data['messageData'][] = [ 'code' => 'error', 'message' => 'PROCESS_STEP_EXISTS' ]; return $data; } if($extraActionCode) { $extraActionCode = $database->escapeValue($extraActionCode); $extraInsertFields = ', idActionCode'; $extraInsertValues = ", '$extraActionCode'"; } $sql = "INSERT INTO ".TABLES['process_step']." (shortDesc, fullDesc, idUserType, isVisibleForCustomer $extraInsertFields) VALUES( '".$database->escapeValue($shortDesc)."', '".$database->escapeValue($fullDesc)."', ".$database->escapeValue($idUserType).", ".$database->escapeValue($isStepVisible)." $extraInsertValues )"; $database->query($sql); $data['idInserted'] = $database->getInsertId(); $data['messageData'][] = [ 'code' => 'success', 'message' => 'STEP_ADDED' ]; return $data; } /** * Check if processStep to be added already exists in the DB * @param string $shortDesc is the short description of the process step * @return bool - returns true if the processStep already exists in the DB, false otherwise */ private function checkIfProcessStepExists($shortDesc) { global $database; $sql = "SELECT shortDesc FROM ".TABLES['process_step']." WHERE shortDesc = '".$database->escapeValue(trim($shortDesc))."' "; $result = $database->query($sql); $numRows = $database->numRows($result); return $numRows > 0; } /** * Get all available user types * @return array - returns an array with all available user types (commercial lead, broker, customer) */ public function getUserTypes() { global $database; $sql = "SELECT u.id, u.type FROM ".TABLES['user_types']." u"; return $database->fetchResultArray($sql); } /** * Get all available extra actions for processes * @return array - returns an array with all available extra actions */ public function getExtraActionsAvailable() { global $database; $sql = " SELECT psa.id as idActionCode, psa.actionCode FROM ".TABLES['process_step_actions']." psa WHERE psa.stepType='extraAction' ORDER BY actionCode"; return $database->fetchResultArray($sql); } }