Files
old-wiaas-legacy/api-wiaas/server/components/v1/processes/ProcessesModel.php
2018-06-11 11:09:35 +02:00

772 lines
26 KiB
PHP

<?php
/**
*
*/
class ProcessesModel{
const ID_PACKAGE_OPTION_TYPE = 2;
function __construct(){
$this->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<count($steps); $i++) {
if($steps[$i]['idStep'] !== $originalProcessSteps[$i]['idStep']) {
$changeFound = true;
}
}
}
if(!$changeFound) {
$data['messageData'][] = [
'code' => '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);
}
}