Merged in bugfix/PMCORE-1160 (pull request #7257)

PMCORE-1160

Approved-by: Julio Cesar Laura Avendaño <contact@julio-laura.com>
This commit is contained in:
Paula Quispe
2020-02-19 15:00:27 +00:00
committed by Julio Cesar Laura Avendaño
11 changed files with 206 additions and 71 deletions

View File

@@ -15,7 +15,7 @@ jobs:
name: Run Test Units name: Run Test Units
command: | command: |
mkdir coverage mkdir coverage
vendor/phpunit/phpunit/phpunit --testdox-html coverage/result.html --coverage-html coverage --verbose tests/unit/ vendor/phpunit/phpunit/phpunit --stop-on-failure --testdox-html coverage/result.html --coverage-html coverage --verbose tests/unit/
- store_artifacts: - store_artifacts:
path: coverage path: coverage
destination: coverage destination: coverage

View File

@@ -0,0 +1,26 @@
<?php
use Faker\Generator as Faker;
$factory->define(\ProcessMaker\Model\AppDelay::class, function (Faker $faker) {
$actions = ['CANCEL', 'PAUSE', 'REASSIGN'];
return [
'APP_DELAY_UID' => G::generateUniqueID(),
'PRO_UID' => G::generateUniqueID(),
'APP_UID' => G::generateUniqueID(),
'APP_NUMBER' => $faker->unique()->numberBetween(1000),
'APP_THREAD_INDEX' => 1,
'APP_DEL_INDEX' => $faker->unique()->numberBetween(10),
'APP_TYPE' => $faker->randomElement($actions),
'APP_STATUS' => 'TO_DO',
'APP_NEXT_TASK' => 0,
'APP_DELEGATION_USER' => G::generateUniqueID(),
'APP_ENABLE_ACTION_USER' => G::generateUniqueID(),
'APP_ENABLE_ACTION_DATE' => $faker->dateTime(),
'APP_DISABLE_ACTION_USER' => G::generateUniqueID(),
'APP_DISABLE_ACTION_DATE' => $faker->dateTime(),
'APP_AUTOMATIC_DISABLED_DATE' => '',
'APP_DELEGATION_USER_ID' => $faker->unique()->numberBetween(1000),
'PRO_ID' => $faker->unique()->numberBetween(1000),
];
});

View File

@@ -0,0 +1,13 @@
<?php
use Faker\Generator as Faker;
$factory->define(\ProcessMaker\Model\UserReporting::class, function (Faker $faker) {
return [
'USR_UID' => G::generateUniqueID(),
'TAS_UID' => G::generateUniqueID(),
'PRO_UID' => G::generateUniqueID(),
'MONTH' => 12,
'YEAR' => 2020,
];
});

View File

@@ -11,11 +11,12 @@ use ProcessMaker\Model\EmailServerModel;
use ProcessMaker\Model\Process; use ProcessMaker\Model\Process;
use ProcessMaker\Model\Task; use ProcessMaker\Model\Task;
use ProcessMaker\Model\User; use ProcessMaker\Model\User;
use ProcessMaker\Model\UserReporting;
use ProcessMaker\Util\WsMessageResponse; use ProcessMaker\Util\WsMessageResponse;
use Tests\TestCase; use Tests\TestCase;
/** /**
* Class WsBase * Class WsBaseTest
* *
* @coversDefaultClass WsBase * @coversDefaultClass WsBase
*/ */
@@ -862,14 +863,27 @@ class WsBaseTest extends TestCase
} }
/** /**
* Review the cancel case with one thread open * Review the cancel case with one thread open was executed successfully
* *
* @covers WsBase::cancelCase() * @covers WsBase::cancelCase()
* @test * @test
*/ */
public function it_should_cancel_case() public function it_should_cancel_case()
{ {
$application = factory(Application::class)->create([ // Definition for avoid the error: Trying to get property 'aUserInfo' of non-object in the action buildAppDelayRow()
global $RBAC;
$user = User::where('USR_ID', '=', 1)->get()->first();
$_SESSION['USER_LOGGED'] = $user['USR_UID'];
$RBAC = RBAC::getSingleton(PATH_DATA, session_id());
$RBAC->initRBAC();
$RBAC->loadUserRolePermission('PROCESSMAKER', $_SESSION['USER_LOGGED']);
// Create the data related to the cancel a case
$task = factory(Task::class)->create();
factory(UserReporting::class)->create([
'TAS_UID' => $task->TAS_UID
]);
$application = factory(Application::class)->states('foreign_keys')->create([
'APP_STATUS_ID' => 2, 'APP_STATUS_ID' => 2,
'APP_STATUS' => 'TO_DO' 'APP_STATUS' => 'TO_DO'
]); ]);
@@ -881,6 +895,8 @@ class WsBaseTest extends TestCase
'DEL_INDEX' => 2 'DEL_INDEX' => 2
]); ]);
$delegation = factory(Delegation::class)->states('foreign_keys')->create([ $delegation = factory(Delegation::class)->states('foreign_keys')->create([
'TAS_UID' => $task->TAS_UID,
'PRO_UID' => $application->PRO_UID,
'APP_NUMBER' => $application->APP_NUMBER, 'APP_NUMBER' => $application->APP_NUMBER,
'APP_UID' => $application->APP_UID, 'APP_UID' => $application->APP_UID,
'DEL_THREAD_STATUS' => 'OPEN', 'DEL_THREAD_STATUS' => 'OPEN',
@@ -888,38 +904,38 @@ class WsBaseTest extends TestCase
]); ]);
$ws = new WsBase(); $ws = new WsBase();
// todo: the action Case::cancelCase() use Propel queries
$response = (object)$ws->cancelCase($delegation->APP_UID, $delegation->DEL_INDEX, $delegation->USR_UID); $response = (object)$ws->cancelCase($delegation->APP_UID, $delegation->DEL_INDEX, $delegation->USR_UID);
$this->assertNotEmpty($response); $this->assertNotEmpty($response);
$this->markTestIncomplete( $this->assertObjectHasAttribute('status_code', $response);
'This test was not fully implemented.' $this->assertEquals($response->message, G::LoadTranslation("ID_COMMAND_EXECUTED_SUCCESSFULLY"));
);
} }
/** /**
* Review the cancel case with parallel threads * Review the cancel case with parallel threads was executed successfully
* *
* @covers WsBase::cancelCase() * @covers WsBase::cancelCase()
* @test * @test
*/ */
public function it_should_cancel_case_parallel() public function it_should_cancel_case_parallel()
{ {
$application = factory(Application::class)->create([ // Definition for avoid the error: Trying to get property 'aUserInfo' of non-object in the action buildAppDelayRow()
global $RBAC;
$user = User::where('USR_ID', '=', 1)->get()->first();
$_SESSION['USER_LOGGED'] = $user['USR_UID'];
$RBAC = RBAC::getSingleton(PATH_DATA, session_id());
$RBAC->initRBAC();
$RBAC->loadUserRolePermission('PROCESSMAKER', $_SESSION['USER_LOGGED']);
// Create the data related to the cancel a case
$task = factory(Task::class)->create();
factory(UserReporting::class)->create([
'TAS_UID' => $task->TAS_UID
]);
$application = factory(Application::class)->states('foreign_keys')->create([
'APP_STATUS_ID' => 2, 'APP_STATUS_ID' => 2,
'APP_STATUS' => 'TO_DO' 'APP_STATUS' => 'TO_DO'
]); ]);
factory(AppThread::class)->create([ // Create the first thread
'APP_UID' => $application->APP_UID,
'APP_THREAD_INDEX' => 1,
'APP_THREAD_PARENT' => 1,
'APP_THREAD_STATUS' => 'OPEN',
'DEL_INDEX' => 1
]);
factory(Delegation::class)->states('foreign_keys')->create([
'APP_NUMBER' => $application->APP_NUMBER,
'APP_UID' => $application->APP_UID,
'DEL_THREAD_STATUS' => 'OPEN'
]);
factory(AppThread::class)->create([ factory(AppThread::class)->create([
'APP_UID' => $application->APP_UID, 'APP_UID' => $application->APP_UID,
'APP_THREAD_INDEX' => 2, 'APP_THREAD_INDEX' => 2,
@@ -927,20 +943,67 @@ class WsBaseTest extends TestCase
'APP_THREAD_STATUS' => 'OPEN', 'APP_THREAD_STATUS' => 'OPEN',
'DEL_INDEX' => 2 'DEL_INDEX' => 2
]); ]);
factory(Delegation::class)->states('foreign_keys')->create([
'TAS_UID' => $task->TAS_UID,
'PRO_UID' => $application->PRO_UID,
'APP_NUMBER' => $application->APP_NUMBER,
'APP_UID' => $application->APP_UID,
'DEL_THREAD_STATUS' => 'OPEN',
'DEL_INDEX' => 2,
]);
// Create the second thread
factory(AppThread::class)->create([
'APP_UID' => $application->APP_UID,
'APP_THREAD_INDEX' => 3,
'APP_THREAD_PARENT' => 1,
'APP_THREAD_STATUS' => 'OPEN',
'DEL_INDEX' => 3
]);
$delegation = factory(Delegation::class)->states('foreign_keys')->create([
'TAS_UID' => $task->TAS_UID,
'PRO_UID' => $application->PRO_UID,
'APP_NUMBER' => $application->APP_NUMBER,
'APP_UID' => $application->APP_UID,
'DEL_THREAD_STATUS' => 'OPEN',
'DEL_INDEX' => 3,
]);
$ws = new WsBase();
$response = (object)$ws->cancelCase($delegation->APP_UID, null, null);
$this->assertNotEmpty($response);
$this->assertObjectHasAttribute('status_code', $response);
$this->assertEquals($response->message, G::LoadTranslation("ID_COMMAND_EXECUTED_SUCCESSFULLY"));
}
/**
* Review the cancel case when the applications does not exist
*
* @covers WsBase::cancelCase()
* @test
*/
public function it_tried_cancel_an_undefined_case()
{
$fakeApp = G::generateUniqueID();
$application = factory(Application::class)->create([
'APP_STATUS_ID' => 2,
'APP_STATUS' => 'TO_DO'
]);
factory(AppThread::class)->create([
'APP_UID' => $application->APP_UID,
'APP_THREAD_INDEX' => 1,
'APP_THREAD_PARENT' => 1,
'APP_THREAD_STATUS' => 'OPEN',
'DEL_INDEX' => 2
]);
$delegation = factory(Delegation::class)->states('foreign_keys')->create([ $delegation = factory(Delegation::class)->states('foreign_keys')->create([
'APP_NUMBER' => $application->APP_NUMBER, 'APP_NUMBER' => $application->APP_NUMBER,
'APP_UID' => $application->APP_UID, 'APP_UID' => $application->APP_UID,
'DEL_THREAD_STATUS' => 'OPEN', 'DEL_THREAD_STATUS' => 'OPEN',
'DEL_INDEX' => 2, 'DEL_INDEX' => 2,
]); ]);
$ws = new WsBase(); $ws = new WsBase();
// todo: the action Case::cancelCase() use Propel queries $response = (object)$ws->cancelCase($fakeApp, $delegation->DEL_INDEX, $delegation->USR_UID);
$response = (object)$ws->cancelCase($delegation->APP_UID, null, null); $this->assertEquals($response->status_code, 100);
$this->assertNotEmpty($response); $this->assertEquals($response->message, "The Application row '$fakeApp' doesn't exist!");
// Stop here and mark this test as incomplete.
$this->markTestIncomplete(
'This test was not fully implemented.'
);
} }
} }

View File

@@ -4374,7 +4374,7 @@ class Cases
/** Create a register in APP_DELAY */ /** Create a register in APP_DELAY */
$delay = new AppDelay(); $delay = new AppDelay();
foreach ($indexesClosed as $value){ foreach ($indexesClosed as $value) {
$dataList = []; $dataList = [];
$rowDelay = AppDelay::buildAppDelayRow( $rowDelay = AppDelay::buildAppDelayRow(
$caseFields['PRO_UID'], $caseFields['PRO_UID'],
@@ -4402,6 +4402,7 @@ class Cases
$dataList = array_merge($caseFields, $dataList); $dataList = array_merge($caseFields, $dataList);
$listCanceled = new ListCanceled(); $listCanceled = new ListCanceled();
// This action requires interaction with IndicatorsCalculator class
$listCanceled->create($dataList); $listCanceled->create($dataList);
/*----------------------------------********---------------------------------*/ /*----------------------------------********---------------------------------*/
} }

View File

@@ -766,32 +766,32 @@ class IndicatorsCalculator
return $returnVal; return $returnVal;
} }
public function suggestedTimeForTask($taskId) /**
* Get some calculations related to the specific task
* Returns population standard deviation of the expression from timeByTask/totalCase
* Return the average from timeByTask/totalCase
*
* @param string $tasUid
*
* @return array
* @throws Exception
*/
public function suggestedTimeForTask($tasUid)
{ {
$qryParams = array(); try {
$qryParams[':taskId'] = $taskId; $criteria = new Criteria('workflow');
$sqlString = 'select $criteria->addSelectColumn(UsrReportingPeer::TOTAL_CASES_OUT);
ROUND(AVG(TOTAL_TIME_BY_TASK/TOTAL_CASES_OUT), 2) as average, $criteria->addAsColumn('average', 'ROUND(AVG(TOTAL_TIME_BY_TASK/TOTAL_CASES_OUT), 2)');
ROUND(STDDEV(TOTAL_TIME_BY_TASK/TOTAL_CASES_OUT), 2) as sdv $criteria->addAsColumn('sdv', 'ROUND(STDDEV(TOTAL_TIME_BY_TASK/TOTAL_CASES_OUT), 2)');
from USR_REPORTING where TAS_UID = :taskId'; $criteria->add(UsrReportingPeer::TAS_UID, $tasUid);
$retval = $this->pdoExecutor($sqlString, $qryParams); $dataset = UsrReportingPeer::doSelectRS($criteria);
return $retval[0]; $dataset->setFetchmode(ResultSet::FETCHMODE_ASSOC);
} $dataset->next();
$result = $dataset->getRow();
return $result;
/* For debug only: } catch (Exception $error) {
* public function interpolateQuery($query, $params) { throw $error;
$keys = array();
# build a regular expression for each parameter
foreach ($params as $key => $value) {
echo "<br>key", $key, " -- value", $value;
if (is_string($key)) {
$keys[] = '/:'.$key.'/';
} else {
$keys[] = '/[?]/';
}
} }
$query = preg_replace($keys, $params, $query, 1, $count); }
return $query;
}*/
} }

View File

@@ -152,6 +152,7 @@ class AppDelay extends BaseAppDelay
/** /**
* Build the row for the appDelay to be inserted * Build the row for the appDelay to be inserted
* This function check the instance of RBAC
* *
* @param string $proUid * @param string $proUid
* @param integer $proId * @param integer $proId

View File

@@ -111,6 +111,7 @@ class ListCanceled extends BaseListCanceled implements ListInterface
} }
if (!empty($data['TAS_UID'])) { if (!empty($data['TAS_UID'])) {
$t = new Task(); $t = new Task();
// The load task gets some calculations related to the Indicators
$data['TAS_ID'] = $t->load($data['TAS_UID'])['TAS_ID']; $data['TAS_ID'] = $t->load($data['TAS_UID'])['TAS_ID'];
} }
$con = Propel::getConnection(ListCanceledPeer::DATABASE_NAME); $con = Propel::getConnection(ListCanceledPeer::DATABASE_NAME);

View File

@@ -487,32 +487,38 @@ class Task extends BaseTask
return $row; return $row;
} }
public function load($TasUid) /**
* Load the properties related to the task
*
* @param string $tasUid
*
* @return array
* @throws Exception
*/
public function load($tasUid)
{ {
try { try {
$oRow = TaskPeer::retrieveByPK($TasUid); $rows = TaskPeer::retrieveByPK($tasUid);
if (!is_null($oRow)) { if (!is_null($rows)) {
$aFields = $oRow->toArray(BasePeer::TYPE_FIELDNAME); $fields = $rows->toArray(BasePeer::TYPE_FIELDNAME);
$this->fromArray($fields, BasePeer::TYPE_FIELDNAME); //Populating an object from of the array
$this->fromArray($aFields, BasePeer::TYPE_FIELDNAME); //Populating an object from of the array //Populating attributes
//Populating attributes
$this->setNew(false); $this->setNew(false);
/*----------------------------------********---------------------------------*/ /*----------------------------------********---------------------------------*/
$indicator = new IndicatorsCalculator(); $indicator = new IndicatorsCalculator();
$data = $indicator->suggestedTimeForTask($TasUid); $data = $indicator->suggestedTimeForTask($tasUid);
$aFields["TAS_AVERAGE"] = $data['average']; $fields["TAS_AVERAGE"] = $data['average'];
$aFields["TAS_SDV"] = $data['sdv']; $fields["TAS_SDV"] = $data['sdv'];
/*----------------------------------********---------------------------------*/ /*----------------------------------********---------------------------------*/
/////// return $fields;
return $aFields;
} else { } else {
throw (new Exception("The row '" . $TasUid . "' in table TASK doesn't exist!")); throw new Exception("The row '" . $tasUid . "' in table TASK doesn't exist!");
} }
} catch (Exception $oError) { } catch (Exception $error) {
throw ($oError); throw $error;
} }
} }

View File

@@ -0,0 +1,11 @@
<?php
namespace ProcessMaker\Model;
use Illuminate\Database\Eloquent\Model;
class AppDelay extends Model
{
protected $table = 'APP_DELAY';
public $timestamps = false;
}

View File

@@ -0,0 +1,13 @@
<?php
namespace ProcessMaker\Model;
use Illuminate\Database\Eloquent\Model;
class UserReporting extends Model
{
protected $table = "USR_REPORTING";
public $timestamps = false;
}