From 0713bce9d5bcc74ecdad2ce6532ab549626175d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julio=20Cesar=20Laura=20Avenda=C3=B1o?= Date: Tue, 13 Oct 2020 23:20:30 +0000 Subject: [PATCH] PMCORE-2320 --- .../engine/classes/model/ListUnassigned.php | 90 +++++++++-- .../methods/cases/proxyNewCasesList.php | 14 ++ .../src/ProcessMaker/Model/Delegation.php | 142 ++++++++++++++++-- 3 files changed, 223 insertions(+), 23 deletions(-) diff --git a/workflow/engine/classes/model/ListUnassigned.php b/workflow/engine/classes/model/ListUnassigned.php index 4cafc2681..41ec094cb 100644 --- a/workflow/engine/classes/model/ListUnassigned.php +++ b/workflow/engine/classes/model/ListUnassigned.php @@ -2,6 +2,8 @@ require_once 'classes/model/om/BaseListUnassigned.php'; +use ProcessMaker\Model\Delegation; + /** * Skeleton subclass for representing a row from the 'LIST_UNASSIGNED' table. @@ -232,19 +234,86 @@ class ListUnassigned extends BaseListUnassigned implements ListInterface /** * This function get the information in the corresponding cases list - * @param string $usr_uid, must be show cases related to this user + * + * @param string $usrUid, must be show cases related to this user * @param array $filters for apply in the result * @param callable $callbackRecord * @return array $data - * @throws PropelException */ - public function loadList($usr_uid, $filters = array(), callable $callbackRecord = null) + public function loadList($usrUid, $filters = [], callable $callbackRecord = null) { + // Get criteria base and the additional columns $pmTable = new PmTable(); $criteria = $pmTable->addPMFieldsToList('unassigned'); $this->setAdditionalClassName($pmTable->tableClassName); $additionalColumns = $criteria->getSelectColumns(); + // Check if exists the custom cases list configured for the unassigned list, if NOT exists we're using the new improved query + if (empty($additionalColumns)) { + // Initialize required parameters + $selectedColumns = [ + // APP_DELEGATION table + 'APP_DELEGATION.APP_NUMBER', + 'APP_DELEGATION.DEL_INDEX', + 'APP_DELEGATION.APP_UID', + 'APP_DELEGATION.TAS_UID', + 'APP_DELEGATION.PRO_UID', + 'APP_DELEGATION.DEL_DELEGATE_DATE', + 'APP_DELEGATION.DEL_TASK_DUE_DATE', + 'APP_DELEGATION.DEL_PRIORITY', + 'APP_DELEGATION.DEL_PREVIOUS', + // TASK table + 'TASK.TAS_TITLE', + // APPLICATION table + 'APPLICATION.APP_TITLE', + 'APPLICATION.APP_UPDATE_DATE', + // PROCESS table + 'PROCESS.PRO_TITLE' + ]; + $sortMap = [ + 'APP_NUMBER' => 'APP_NUMBER', + 'DEL_DUE_DATE' => 'DEL_TASK_DUE_DATE', + 'DEL_DELEGATE_DATE' => 'DEL_DELEGATE_DATE', + 'APP_TITLE' => 'APP_TITLE', + 'APP_PRO_TITLE' => 'PRO_TITLE', + 'APP_TAS_TITLE' => 'TAS_TITLE', + 'DEL_PREVIOUS_USR_UID' => 'USR_ID' + ]; + $categoryUid = $filters['category'] ?? null; + $processUid = $filters['process'] ?? null; + $textToSearch = $filters['search'] ?? null; + $sort = $sortMap[$filters['sort']] ?? null; + $dir = $filters['dir'] ?? null; + $offset = $filters['start'] ?? null; + $limit = $filters['limit'] ?? null; + + // Get data + $data = Delegation::getSelfService($usrUid, $selectedColumns, $categoryUid, $processUid, $textToSearch, $sort, $dir, $offset, $limit); + + // Transform and complete the data + foreach ($data as &$row) { + $row = is_null($callbackRecord) ? $row : $callbackRecord($row); + } + } else { + // Use the old Propel query that is compatible with the custom cases list + $data = $this->loadListWithAdditionalColumns($criteria, $usrUid, $filters, $additionalColumns, $callbackRecord); + } + + return $data; + } + + /** + * Get the data for unassigned list with the information of additional columns + * + * @param object $criteria + * @param string $usr_uid + * @param array $filters + * @param array $additionalColumns + * @param callable $callbackRecord + * @return array + */ + private function loadListWithAdditionalColumns($criteria, $usr_uid, $filters, $additionalColumns, callable $callbackRecord) + { $criteria->addSelectColumn(ListUnassignedPeer::APP_UID); $criteria->addSelectColumn(ListUnassignedPeer::DEL_INDEX); $criteria->addSelectColumn(ListUnassignedPeer::TAS_UID); @@ -460,17 +529,20 @@ class ListUnassigned extends BaseListUnassigned implements ListInterface /** * Returns the number of cases of a user * - * @param string $userUid + * @param string $usrUid * @param array $filters * * @return int $total */ - public function getCountList($userUid, $filters = array()) + public function getCountList($usrUid, $filters = []) { - $criteria = new Criteria('workflow'); - $this->getCriteriaWhereSelfService($criteria, $userUid); - $total = ListUnassignedPeer::doCount($criteria); - return (int)$total; + // Initialize required parameters + $categoryUid = $filters['category'] ?? null; + $processUid = $filters['process'] ?? null; + $textToSearch = $filters['search'] ?? null; + + // Get counter + return Delegation::countSelfService($usrUid, $categoryUid, $processUid, $textToSearch); } /** diff --git a/workflow/engine/methods/cases/proxyNewCasesList.php b/workflow/engine/methods/cases/proxyNewCasesList.php index fb8221c01..aa236282a 100644 --- a/workflow/engine/methods/cases/proxyNewCasesList.php +++ b/workflow/engine/methods/cases/proxyNewCasesList.php @@ -1,5 +1,7 @@ error = G::LoadTranslation('ID_LOGIN_AGAIN'); @@ -156,6 +158,12 @@ try { $record["PREVIOUS_USR_USERNAME"] = $record["DEL_PREVIOUS_USR_USERNAME"]; $record["PREVIOUS_USR_FIRSTNAME"] = $record["DEL_PREVIOUS_USR_FIRSTNAME"]; $record["PREVIOUS_USR_LASTNAME"] = $record["DEL_PREVIOUS_USR_LASTNAME"]; + } elseif (!empty($record["USR_ID"])) { + $user = User::where("USR_ID", $record["USR_ID"])->first(); + $record["PREVIOUS_USR_UID"] = $record["DEL_PREVIOUS_USR_UID"] = $user->USR_UID; + $record["PREVIOUS_USR_USERNAME"] = $record["DEL_PREVIOUS_USR_USERNAME"] = $user->USR_USERNAME; + $record["PREVIOUS_USR_FIRSTNAME"] = $record["DEL_PREVIOUS_USR_FIRSTNAME"] = $user->USR_FIRSTNAME; + $record["PREVIOUS_USR_LASTNAME"] = $record["DEL_PREVIOUS_USR_LASTNAME"] = $user->USR_LASTNAME; } if (isset($record["DEL_DUE_DATE"])) { @@ -175,12 +183,18 @@ try { if (isset($record['DEL_CURRENT_TAS_TITLE']) && $record['DEL_CURRENT_TAS_TITLE'] != '') { $record['APP_TAS_TITLE'] = $record['DEL_CURRENT_TAS_TITLE']; + } elseif (!empty($record["TAS_TITLE"]) && empty($record["APP_TAS_TITLE"])) { + $record["APP_TAS_TITLE"] = $record["TAS_TITLE"]; } if (isset($record["APP_STATUS"])) { $record["APP_STATUS_LABEL"] = G::LoadTranslation("ID_" . $record["APP_STATUS"]); } + if (!empty($record["PRO_TITLE"]) && empty($record["APP_PRO_TITLE"])) { + $record["APP_PRO_TITLE"] = $record["PRO_TITLE"]; + } + return $record; } catch (Exception $e) { throw $e; diff --git a/workflow/engine/src/ProcessMaker/Model/Delegation.php b/workflow/engine/src/ProcessMaker/Model/Delegation.php index 9457679c7..d5a892e9b 100644 --- a/workflow/engine/src/ProcessMaker/Model/Delegation.php +++ b/workflow/engine/src/ProcessMaker/Model/Delegation.php @@ -72,7 +72,7 @@ class Delegation extends Model */ public function scopeIsThreadOpen($query) { - return $query->where('DEL_THREAD_STATUS', '=', 'OPEN'); + return $query->where('APP_DELEGATION.DEL_THREAD_STATUS', '=', 'OPEN'); } /** @@ -83,7 +83,7 @@ class Delegation extends Model */ public function scopeNoUserInThread($query) { - return $query->where('USR_ID', '=', 0); + return $query->where('APP_DELEGATION.USR_ID', '=', 0); } /** @@ -487,10 +487,17 @@ class Delegation extends Model * * @param string $usrUid * @param bool $count + * @param array $selectedColumns + * @param string $categoryUid + * @param string $processUid + * @param string $textToSearch + * @param string $sort + * @param string $dir * * @return \Illuminate\Database\Query\Builder | string */ - public static function getSelfServiceQuery($usrUid, $count = false) + public static function getSelfServiceQuery($usrUid, $count = false, $selectedColumns = ['APP_DELEGATION.APP_NUMBER', 'APP_DELEGATION.DEL_INDEX'], + $categoryUid = null, $processUid = null, $textToSearch = null, $sort = null, $dir = null) { // Set the 'usrUid' property to preserve Delegation::$usrUid = $usrUid; @@ -507,10 +514,23 @@ class Delegation extends Model // Set the 'groups' property to preserve Delegation::$groups = $groups; - // Start the first query - $query1 = Delegation::query()->select(['APP_NUMBER', 'DEL_INDEX']); + // Add an extra column with alias if is needed to join with the previous delegation + if (array_search('APP_DELEGATION.DEL_PREVIOUS', $selectedColumns) !== false) { + $selectedColumns[] = 'ADP.USR_ID'; + } - // Add the join clause + // Start the first query + $query1 = Delegation::query()->select($selectedColumns); + + // Add join clause with the previous APP_DELEGATION record if required + if (array_search('APP_DELEGATION.DEL_PREVIOUS', $selectedColumns) !== false) { + $query1->join('APP_DELEGATION AS ADP', function ($join) { + $join->on('APP_DELEGATION.APP_NUMBER', '=', 'ADP.APP_NUMBER'); + $join->on('APP_DELEGATION.DEL_PREVIOUS', '=', 'ADP.DEL_INDEX'); + }); + } + + // Add the join clause with TASK table $query1->join('TASK', function ($join) { // Build partial plain query for a complex Join, because Eloquent doesn't support this type of Join $complexJoin = " @@ -540,6 +560,33 @@ class Delegation extends Model whereRaw($complexJoin); }); + // Add join clause with APPLICATION table if required + if (array_search('APPLICATION.APP_TITLE', $selectedColumns) !== false || !empty($textToSearch) || $sort == 'APP_TITLE') { + $query1->join('APPLICATION', function ($join) { + $join->on('APP_DELEGATION.APP_NUMBER', '=', 'APPLICATION.APP_NUMBER'); + }); + } + + // Add join clause with PROCESS table if required + if (array_search('PROCESS.PRO_TITLE', $selectedColumns) !== false || !empty($categoryUid) || !empty($processUid) || !empty($textToSearch) || $sort == 'PRO_TITLE') { + $query1->join('PROCESS', function ($join) use ($categoryUid, $processUid) { + $join->on('APP_DELEGATION.PRO_ID', '=', 'PROCESS.PRO_ID'); + if (!empty($categoryUid)) { + $join->where('PROCESS.PRO_CATEGORY', $categoryUid); + } + if (!empty($processUid)) { + $join->where('PROCESS.PRO_UID', $processUid); + } + }); + } + + // Build where clause for the text to search + if (!empty($textToSearch)) { + $query1->where('APPLICATION.APP_TITLE', 'LIKE', "%$textToSearch%") + ->orWhere('TASK.TAS_TITLE', 'LIKE', "%$textToSearch%") + ->orWhere('PROCESS.PRO_TITLE', 'LIKE', "%$textToSearch%"); + } + // Clean static properties Delegation::$usrUid = ''; Delegation::$groups = []; @@ -549,17 +596,63 @@ class Delegation extends Model if (!empty($selfServiceTasks)) { // Start the second query - $query2 = Delegation::query()->select(['APP_NUMBER', 'DEL_INDEX']); + $query2 = Delegation::query()->select($selectedColumns); $query2->tasksIn($selfServiceTasks); $query2->isThreadOpen(); $query2->noUserInThread(); + // Add join clause with the previous APP_DELEGATION record if required + if (array_search('APP_DELEGATION.DEL_PREVIOUS', $selectedColumns) !== false) { + $query2->join('APP_DELEGATION AS ADP', function ($join) { + $join->on('APP_DELEGATION.APP_NUMBER', '=', 'ADP.APP_NUMBER'); + $join->on('APP_DELEGATION.DEL_PREVIOUS', '=', 'ADP.DEL_INDEX'); + }); + } + + // Add the join clause with TASK table if required + if (array_search('TASK.TAS_TITLE', $selectedColumns) !== false || !empty($textToSearch) || $sort == 'TAS_TITLE') { + $query2->join('TASK', function ($join) { + $join->on('APP_DELEGATION.TAS_ID', '=', 'TASK.TAS_ID'); + }); + + } + // Add join clause with APPLICATION table if required + if (array_search('APPLICATION.APP_TITLE', $selectedColumns) !== false || !empty($textToSearch) || $sort == 'APP_TITLE') { + $query2->join('APPLICATION', function ($join) { + $join->on('APP_DELEGATION.APP_NUMBER', '=', 'APPLICATION.APP_NUMBER'); + }); + } + + // Add join clause with PROCESS table if required + if (array_search('PROCESS.PRO_TITLE', $selectedColumns) !== false || !empty($categoryUid) || !empty($processUid) || !empty($textToSearch) || $sort == 'PRO_TITLE') { + $query2->join('PROCESS', function ($join) use ($categoryUid, $processUid) { + $join->on('APP_DELEGATION.PRO_ID', '=', 'PROCESS.PRO_ID'); + if (!empty($categoryUid)) { + $join->where('PROCESS.PRO_CATEGORY', $categoryUid); + } + if (!empty($processUid)) { + $join->where('PROCESS.PRO_UID', $processUid); + } + }); + } + + // Build where clause for the text to search + if (!empty($textToSearch)) { + $query2->where('APPLICATION.APP_TITLE', 'LIKE', "%$textToSearch%") + ->orWhere('TASK.TAS_TITLE', 'LIKE', "%$textToSearch%") + ->orWhere('PROCESS.PRO_TITLE', 'LIKE', "%$textToSearch%"); + } + // Build the complex query that uses "UNION DISTINCT" clause - $query = sprintf('select ' . ($count ? 'count(*) as aggregate' : 'APP_NUMBER') . - ' from ((%s) union distinct (%s)) self_service_cases', toSqlWithBindings($query1), toSqlWithBindings($query2)); + $query = sprintf('select ' . ($count ? 'count(*) as aggregate' : '*') . + ' from ((%s) union distinct (%s)) self_service_cases' . (!empty($sort) && !empty($dir) ? ' ORDER BY %s %s' : ''), + toSqlWithBindings($query1), toSqlWithBindings($query2), $sort, $dir); return $query; } else { + if (!empty($sort) && !empty($dir)) { + $query1->orderBy($sort, $dir); + } return $query1; } } @@ -568,24 +661,41 @@ class Delegation extends Model * Get the self-services cases by user * * @param string $usrUid - * + * @param array $selectedColumns + * @param string $categoryUid + * @param string $processUid + * @param string $textToSearch + * @param string $sort + * @param string $dir + * @param int $offset + * @param int $limit * @return array */ - public static function getSelfService($usrUid) + public static function getSelfService($usrUid, $selectedColumns = ['APP_DELEGATION.APP_NUMBER', 'APP_DELEGATION.DEL_INDEX'], + $categoryUid = null, $processUid = null, $textToSearch = null, $sort = null, $dir = null, $offset = null, $limit = null) { // Initializing the variable to return $data = []; // Get the query - $query = self::getSelfServiceQuery($usrUid); + $query = self::getSelfServiceQuery($usrUid, false, $selectedColumns, $categoryUid, $processUid, $textToSearch, $sort, $dir); // Get data if (!is_string($query)) { + // Set offset and limit if were sent + if (!is_null($offset) && !is_null($limit)) { + $query->offset($offset); + $query->limit($limit); + } $items = $query->get(); $items->each(function ($item) use (&$data) { $data[] = get_object_vars($item); }); } else { + // Set offset and limit if were sent + if (!is_null($offset) && !is_null($limit)) { + $query .= " LIMIT {$offset}, {$limit}"; + } $items = DB::select($query); foreach ($items as $item) { $data[] = get_object_vars($item); @@ -600,13 +710,17 @@ class Delegation extends Model * Count the self-services cases by user * * @param string $usrUid + * @param string $categoryUid + * @param string $processUid + * @param string $textToSearch * * @return integer */ - public static function countSelfService($usrUid) + public static function countSelfService($usrUid, $categoryUid = null, $processUid = null, $textToSearch = null) { // Get the query - $query = self::getSelfServiceQuery($usrUid, true); + $query = self::getSelfServiceQuery($usrUid, true, ['APP_DELEGATION.APP_NUMBER', 'APP_DELEGATION.DEL_INDEX'], + $categoryUid, $processUid, $textToSearch); // Get count value if (!is_string($query)) {