diff --git a/app/Jobs/CasesDispatch.php b/app/Jobs/CasesDispatch.php
new file mode 100644
index 000000000..4ea2cb317
--- /dev/null
+++ b/app/Jobs/CasesDispatch.php
@@ -0,0 +1,8 @@
+define(\ProcessMaker\Model\Application::class, function(Faker $faker) {
- $statuses = ['DRAFT', 'TO_DO'];
- $status = $faker->randomElement($statuses);
- $statusId = array_search($status, $statuses) + 1;
+ $user = factory(\ProcessMaker\Model\User::class)->create();
$appNumber = $faker->unique()->numberBetween(1000);
+
+ //APP_TITLE field is used in 'MYSQL: MATCH() AGAINST()' function, string size should not be less than 3.
+ $appTitle = $faker->lexify(str_repeat('?', rand(3, 5)) . ' ' . str_repeat('?', rand(3, 5)));
+
+ //APP_STATUS must start in TO_DO because all tests require this state.
+
return [
'APP_UID' => G::generateUniqueID(),
- 'APP_TITLE' => $faker->sentence(3),
+ 'APP_TITLE' => $appTitle,
'APP_NUMBER' => $appNumber,
- 'APP_STATUS' => $status,
- 'APP_STATUS_ID' => $statusId,
- 'PRO_UID' => G::generateUniqueID(),
+ 'APP_STATUS' => 'TO_DO',
+ 'APP_STATUS_ID' => 2,
+ 'PRO_UID' => function() {
+ return factory(\ProcessMaker\Model\Process::class)->create()->PRO_UID;
+ },
'APP_PARALLEL' => 'N',
- 'APP_INIT_USER' => G::generateUniqueID(),
- 'APP_CUR_USER' => G::generateUniqueID(),
+ 'APP_INIT_USER' => $user->USR_UID,
+ 'APP_CUR_USER' => $user->USR_UID,
'APP_PIN' => G::generateUniqueID(),
'APP_CREATE_DATE' => $faker->dateTime(),
'APP_UPDATE_DATE' => $faker->dateTime(),
@@ -30,17 +36,19 @@ $factory->state(\ProcessMaker\Model\Application::class, 'foreign_keys', function
// Create values in the foreign key relations
$process = factory(\ProcessMaker\Model\Process::class)->create();
$user = factory(\ProcessMaker\Model\User::class)->create();
- // Get other random values
- $statuses = ['DRAFT', 'TO_DO'];
- $status = $faker->randomElement($statuses);
- $statusId = array_search($status, $statuses) + 1;
$appNumber = $faker->unique()->numberBetween(1000);
+
+ //APP_TITLE field is used in 'MYSQL: MATCH() AGAINST()' function, string size should not be less than 3.
+ $appTitle = $faker->lexify(str_repeat('?', rand(3, 5)) . ' ' . str_repeat('?', rand(3, 5)));
+
+ //APP_STATUS must start in TO_DO because all tests require this state.
+
return [
'APP_UID' => G::generateUniqueID(),
- 'APP_TITLE' => $faker->sentence(3),
+ 'APP_TITLE' => $appTitle,
'APP_NUMBER' => $appNumber,
- 'APP_STATUS' => $status,
- 'APP_STATUS_ID' => $statusId,
+ 'APP_STATUS' => 'TO_DO',
+ 'APP_STATUS_ID' => 2,
'PRO_UID' => $process->PRO_UID,
'APP_PARALLEL' => 'N',
'APP_INIT_USER' => $user->USR_UID,
@@ -51,4 +59,4 @@ $factory->state(\ProcessMaker\Model\Application::class, 'foreign_keys', function
'APP_INIT_DATE' => $faker->dateTime(),
'APP_DATA' => serialize(['APP_NUMBER' => $appNumber])
];
-});
\ No newline at end of file
+});
diff --git a/database/factories/DelegationFactory.php b/database/factories/DelegationFactory.php
index edfc13b01..fffbb43c4 100644
--- a/database/factories/DelegationFactory.php
+++ b/database/factories/DelegationFactory.php
@@ -3,15 +3,26 @@
use Faker\Generator as Faker;
$factory->define(\ProcessMaker\Model\Delegation::class, function(Faker $faker) {
+ $user = factory(\ProcessMaker\Model\User::class)->create();
+ $process = factory(\ProcessMaker\Model\Process::class)->create();
+ $task = factory(\ProcessMaker\Model\Task::class)->create([
+ 'PRO_UID' => $process->PRO_UID,
+ 'PRO_ID' => $process->PRO_ID
+ ]);
+ $application = factory(\ProcessMaker\Model\Application::class)->create([
+ 'PRO_UID' => $process->PRO_UID,
+ 'APP_INIT_USER' => $user->USR_UID,
+ 'APP_CUR_USER' => $user->USR_UID
+ ]);
// Return with default values
return [
- 'APP_UID' => G::generateUniqueID(),
+ 'APP_UID' => $application->APP_UID,
'DEL_INDEX' => 1,
- 'APP_NUMBER' => $faker->unique()->numberBetween(1, 100000),
+ 'APP_NUMBER' => $application->APP_NUMBER,
'DEL_PREVIOUS' => 0,
- 'PRO_UID' => G::generateUniqueID(),
- 'TAS_UID' => G::generateUniqueID(),
- 'USR_UID' => G::generateUniqueID(),
+ 'PRO_UID' => $process->PRO_UID,
+ 'TAS_UID' => $task->TAS_UID,
+ 'USR_UID' => $user->USR_UID,
'DEL_TYPE' => 'NORMAL',
'DEL_THREAD' => 1,
'DEL_THREAD_STATUS' => 'OPEN',
@@ -20,9 +31,9 @@ $factory->define(\ProcessMaker\Model\Delegation::class, function(Faker $faker) {
'DEL_INIT_DATE' => $faker->dateTime(),
'DEL_TASK_DUE_DATE' => $faker->dateTime(),
'DEL_RISK_DATE' => $faker->dateTime(),
- 'USR_ID' => 0,
- 'PRO_ID' => 0,
- 'TAS_ID' => 0,
+ 'USR_ID' => $user->USR_ID,
+ 'PRO_ID' => $process->PRO_ID,
+ 'TAS_ID' => $task->TAS_ID,
'DEL_DATA' => ''
];
});
@@ -30,10 +41,17 @@ $factory->define(\ProcessMaker\Model\Delegation::class, function(Faker $faker) {
// Create a delegation with the foreign keys
$factory->state(\ProcessMaker\Model\Delegation::class, 'foreign_keys', function (Faker $faker) {
// Create values in the foreign key relations
- $application = factory(\ProcessMaker\Model\Application::class)->create();
- $process = factory(\ProcessMaker\Model\Process::class)->create();
- $task = factory(\ProcessMaker\Model\Task::class)->create();
$user = factory(\ProcessMaker\Model\User::class)->create();
+ $process = factory(\ProcessMaker\Model\Process::class)->create();
+ $task = factory(\ProcessMaker\Model\Task::class)->create([
+ 'PRO_UID' => $process->PRO_UID,
+ 'PRO_ID' => $process->PRO_ID
+ ]);
+ $application = factory(\ProcessMaker\Model\Application::class)->create([
+ 'PRO_UID' => $process->PRO_UID,
+ 'APP_INIT_USER' => $user->USR_UID,
+ 'APP_CUR_USER' => $user->USR_UID
+ ]);
// Return with default values
return [
diff --git a/database/factories/GroupwfFactory.php b/database/factories/GroupwfFactory.php
index 7ab6ca271..0a7e77198 100644
--- a/database/factories/GroupwfFactory.php
+++ b/database/factories/GroupwfFactory.php
@@ -7,7 +7,7 @@ use Faker\Generator as Faker;
$factory->define(\ProcessMaker\Model\Groupwf::class, function(Faker $faker) {
return [
'GRP_UID' => G::generateUniqueID(),
- 'GRP_ID' => $faker->unique()->numberBetween(1, 2000),
+ //'GRP_ID' The incremental fields of the tables must not be specified in the creation list.
'GRP_TITLE' => $faker->sentence(2),
'GRP_STATUS' => 'ACTIVE',
'GRP_LDAP_DN' => '',
diff --git a/database/factories/ProcessFactory.php b/database/factories/ProcessFactory.php
index 4cd3e026c..5465309c2 100644
--- a/database/factories/ProcessFactory.php
+++ b/database/factories/ProcessFactory.php
@@ -6,9 +6,10 @@ use Faker\Generator as Faker;
$factory->define(\ProcessMaker\Model\Process::class, function(Faker $faker) {
// Return with default values
+ //The incremental fields of the tables must not be specified in the creation list.
return [
'PRO_UID' => G::generateUniqueID(),
- 'PRO_ID' => $faker->unique()->numberBetween(1, 1000000),
+ //'PRO_ID' The incremental fields of the tables must not be specified in the creation list.
'PRO_TITLE' => $faker->sentence(3),
'PRO_DESCRIPTION' => $faker->paragraph(3),
'PRO_CREATE_USER' => '00000000000000000000000000000001',
@@ -19,7 +20,9 @@ $factory->define(\ProcessMaker\Model\Process::class, function(Faker $faker) {
'PRO_TYPE_PROCESS' => 'PUBLIC',
'PRO_UPDATE_DATE' => $faker->dateTime(),
'PRO_CREATE_DATE' => $faker->dateTime(),
- 'PRO_CATEGORY' => '',
+ 'PRO_CATEGORY' => function() {
+ return factory(\ProcessMaker\Model\ProcessCategory::class)->create()->CATEGORY_UID;
+ },
];
});
@@ -28,7 +31,7 @@ $factory->state(\ProcessMaker\Model\Process::class, 'foreign_keys', function (Fa
$user = factory(\ProcessMaker\Model\User::class)->create();
return [
'PRO_UID' => G::generateUniqueID(),
- 'PRO_ID' => $faker->unique()->numberBetween(1, 1000000),
+ //'PRO_ID' The incremental fields of the tables must not be specified in the creation list.
'PRO_TITLE' => $faker->sentence(3),
'PRO_DESCRIPTION' => $faker->paragraph(3),
'PRO_CREATE_USER' => $user->USR_UID,
@@ -49,7 +52,7 @@ $factory->state(\ProcessMaker\Model\Process::class, 'flow', function (Faker $fak
$user = factory(\ProcessMaker\Model\User::class)->create();
$process = [
'PRO_UID' => G::generateUniqueID(),
- 'PRO_ID' => $faker->unique()->numberBetween(1, 1000000),
+ //'PRO_ID' The incremental fields of the tables must not be specified in the creation list.
'PRO_TITLE' => $faker->sentence(3),
'PRO_DESCRIPTION' => $faker->paragraph(3),
'PRO_CREATE_USER' => $user->USR_UID,
diff --git a/database/factories/StepTriggerFactory.php b/database/factories/StepTriggerFactory.php
new file mode 100644
index 000000000..6d63cdd80
--- /dev/null
+++ b/database/factories/StepTriggerFactory.php
@@ -0,0 +1,18 @@
+define(\ProcessMaker\Model\StepTrigger::class, function (Faker $faker) {
+ return [
+ 'STEP_UID' => $faker->regexify("/[a-zA-Z]{32}/"),
+ 'TAS_UID' => function() {
+ return factory(\ProcessMaker\Model\Task::class)->create()->TAS_UID;
+ },
+ 'TRI_UID' => function() {
+ return factory(\ProcessMaker\Model\Triggers::class)->create()->TRI_UID;
+ },
+ 'ST_TYPE' => 'BEFORE',
+ 'ST_CONDITION' => '',
+ 'ST_POSITION' => 1,
+ ];
+});
diff --git a/database/factories/TaskFactory.php b/database/factories/TaskFactory.php
index a8347b2f9..367734efb 100644
--- a/database/factories/TaskFactory.php
+++ b/database/factories/TaskFactory.php
@@ -6,11 +6,12 @@
use Faker\Generator as Faker;
$factory->define(\ProcessMaker\Model\Task::class, function(Faker $faker) {
+ $process = factory(\ProcessMaker\Model\Process::class)->create();
return [
- 'PRO_UID' => G::generateUniqueID(),
- 'PRO_ID' => $faker->unique()->numberBetween(),
+ 'PRO_UID' => $process->PRO_UID,
+ 'PRO_ID' => $process->PRO_ID,
'TAS_UID' => G::generateUniqueID(),
- 'TAS_ID' => $faker->unique()->numberBetween(),
+ //'TAS_ID' The incremental fields of the tables must not be specified in the creation list.
'TAS_TITLE' => $faker->sentence(2),
'TAS_TYPE' => 'NORMAL',
'TAS_TYPE_DAY' => 1,
@@ -39,7 +40,7 @@ $factory->state(\ProcessMaker\Model\Task::class, 'foreign_keys', function (Faker
'PRO_UID' => $process->PRO_UID,
'PRO_ID' => $process->PRO_ID,
'TAS_UID' => G::generateUniqueID(),
- 'TAS_ID' => $faker->unique()->numberBetween(1, 200000),
+ //'TAS_ID' The incremental fields of the tables must not be specified in the creation list.
'TAS_TITLE' => $faker->sentence(2),
'TAS_TYPE' => 'NORMAL',
'TAS_TYPE_DAY' => 1,
diff --git a/database/factories/TriggerFactory.php b/database/factories/TriggerFactory.php
index e0b9adfe6..f467c626a 100644
--- a/database/factories/TriggerFactory.php
+++ b/database/factories/TriggerFactory.php
@@ -5,12 +5,14 @@ use ProcessMaker\Model\Triggers;
$factory->define(Triggers::class, function (Faker $faker) {
return [
- 'TRI_UID' => G::generateUniqueID(),
+ 'TRI_UID' => $faker->regexify("/[a-zA-Z]{32}/"),
'TRI_TITLE' => $faker->sentence(5),
'TRI_DESCRIPTION' => $faker->text,
- 'PRO_UID' => G::generateUniqueID(),
+ 'PRO_UID' => function() {
+ return factory(\ProcessMaker\Model\Process::class)->create()->PRO_UID;
+ },
'TRI_TYPE' => 'SCRIPT',
'TRI_WEBBOT' => $faker->text,
'TRI_PARAM' => '',
];
-});
\ No newline at end of file
+});
diff --git a/tests/unit/workflow/engine/src/ProcessMaker/Cases/CasesTraitTest.php b/tests/unit/workflow/engine/src/ProcessMaker/Cases/CasesTraitTest.php
new file mode 100644
index 000000000..60a064336
--- /dev/null
+++ b/tests/unit/workflow/engine/src/ProcessMaker/Cases/CasesTraitTest.php
@@ -0,0 +1,291 @@
+get()->first();
+
+ $process = factory(Process::class)->create([
+ 'PRO_CREATE_USER' => $user->USR_UID
+ ]);
+ $task = factory(Task::class)->create([
+ 'TAS_ASSIGN_TYPE' => 'BALANCED',
+ 'TAS_GROUP_VARIABLE' => '',
+ 'PRO_UID' => $process->PRO_UID
+ ]);
+ factory(TaskUser::class)->create([
+ 'TAS_UID' => $task->TAS_UID,
+ 'USR_UID' => $user->USR_UID,
+ 'TU_RELATION' => 1,
+ 'TU_TYPE' => 1
+ ]);
+ $task2 = factory(Task::class)->create([
+ 'TAS_ASSIGN_TYPE' => 'BALANCED',
+ 'TAS_GROUP_VARIABLE' => '',
+ 'PRO_UID' => $process->PRO_UID
+ ]);
+ factory(TaskUser::class)->create([
+ 'TAS_UID' => $task2->TAS_UID,
+ 'USR_UID' => $user->USR_UID,
+ 'TU_RELATION' => 1,
+ 'TU_TYPE' => 1
+ ]);
+
+
+ $application = factory(Application::class)->create([
+ 'PRO_UID' => $process->PRO_UID
+ ]);
+ $appDelegation = factory(Delegation::class)->create([
+ 'USR_UID' => $user->USR_UID,
+ 'PRO_UID' => $process->PRO_UID,
+ 'APP_UID' => $application->APP_UID,
+ 'TAS_UID' => $task->TAS_UID,
+ 'DEL_INDEX' => 1,
+ ]);
+ factory(Delegation::class)->create([
+ 'USR_UID' => $user->USR_UID,
+ 'PRO_UID' => $process->PRO_UID,
+ 'APP_UID' => $application->APP_UID,
+ 'TAS_UID' => $task2->TAS_UID,
+ 'DEL_INDEX' => 2,
+ 'DEL_PREVIOUS' => $appDelegation->DEL_INDEX
+ ]);
+ factory(Route::class)->create([
+ 'TAS_UID' => $task->TAS_UID,
+ 'ROU_NEXT_TASK' => $task2->TAS_UID,
+ 'PRO_UID' => $process->PRO_UID
+ ]);
+
+ $step = factory(Step::class)->create([
+ 'PRO_UID' => $process->PRO_UID,
+ 'TAS_UID' => $appDelegation->TAS_UID,
+ 'STEP_POSITION' => 2,
+ 'STEP_CONDITION' => '1 == 1'
+ ]);
+
+
+ $triggers = factory(Triggers::class)->create([
+ 'PRO_UID' => $process->PRO_UID,
+ 'TRI_WEBBOT' => '$a = 0;'
+ ]);
+ factory(StepTrigger::class)->create([
+ 'STEP_UID' => -2,
+ 'TAS_UID' => $task->TAS_UID,
+ 'TRI_UID' => $triggers->TRI_UID,
+ 'ST_CONDITION' => '1 == 1',
+ 'ST_TYPE' => 'BEFORE'
+ ]);
+
+
+ $triggers = factory(Triggers::class)->create([
+ 'PRO_UID' => $process->PRO_UID,
+ 'TRI_WEBBOT' => '$b = 0;'
+ ]);
+ factory(StepTrigger::class)->create([
+ 'STEP_UID' => -2,
+ 'TAS_UID' => $task->TAS_UID,
+ 'TRI_UID' => $triggers->TRI_UID,
+ 'ST_CONDITION' => '2 == 2',
+ 'ST_TYPE' => 'AFTER'
+ ]);
+
+ $result = [
+ 'application' => $application,
+ 'user' => $user,
+ 'task' => $task,
+ 'task2' => $task2,
+ ];
+ return (object) $result;
+ }
+
+ /**
+ * This test verifies that the derivation of the case has closed the delegation
+ * with single task.
+ * @test
+ * @covers \Cases::routeCase
+ */
+ public function it_should_test_a_derivate_case_with_single_task()
+ {
+ $result = $this->prepareDerivationData();
+ $application = $result->application;
+ $user = $result->user;
+ $task = $result->task;
+ $task2 = $result->task2;
+
+ $processUid = $application->PRO_UID;
+ $application = $application->APP_UID;
+ $postForm = [
+ 'ROU_TYPE' => 'SEQUENTIAL',
+ 'TASKS' => [
+ 1 => [
+ 'TAS_UID' => $task->TAS_UID,
+ 'USR_UID' => $user->USR_UID,
+ 'TAS_ASSIGN_TYPE' => "BALANCED",
+ 'TAS_DEF_PROC_CODE' => "",
+ 'DEL_PRIORITY' => "",
+ 'TAS_PARENT' => "",
+ 'ROU_CONDITION' => "",
+ 'SOURCE_UID' => $task->TAS_UID,
+ ]
+ ]
+ ];
+ $status = 'TO_DO';
+ $flagGmail = true;
+ $tasUid = $task->TAS_UID;
+ $index = '1';
+ $userLogged = $user->USR_UID;
+
+ $cases = new Cases();
+ $cases->routeCase($processUid, $application, $postForm, $status, $flagGmail, $tasUid, $index, $userLogged);
+
+ $result = Delegation::where('APP_UID', '=', $application)->where('DEL_INDEX', '=', $index)->get()->first();
+
+ $this->assertEquals('CLOSED', $result->DEL_THREAD_STATUS);
+ }
+
+ /**
+ * This test verifies that the derivation of the case has closed the delegation
+ * with multiple task.
+ * @test
+ * @covers \Cases::routeCase
+ */
+ public function it_should_test_a_derivate_case_with_multiple_task()
+ {
+ $result = $this->prepareDerivationData();
+ $application = $result->application;
+ $user = $result->user;
+ $task = $result->task;
+ $task2 = $result->task2;
+
+ $processUid = $application->PRO_UID;
+ $application = $application->APP_UID;
+ $postForm = [
+ 'ROU_TYPE' => 'SEQUENTIAL',
+ 'TASKS' => [
+ 1 => [
+ 'TAS_UID' => $task->TAS_UID,
+ 'USR_UID' => $user->USR_UID,
+ 'TAS_ASSIGN_TYPE' => "BALANCED",
+ 'TAS_DEF_PROC_CODE' => "",
+ 'DEL_PRIORITY' => "",
+ 'TAS_PARENT' => "",
+ 'ROU_CONDITION' => "",
+ 'SOURCE_UID' => $task->TAS_UID,
+ ],
+ 2 => [
+ 'TAS_UID' => $task2->TAS_UID,
+ 'USR_UID' => $user->USR_UID,
+ 'TAS_ASSIGN_TYPE' => "BALANCED",
+ 'TAS_DEF_PROC_CODE' => "",
+ 'DEL_PRIORITY' => "",
+ 'TAS_PARENT' => "",
+ 'ROU_CONDITION' => "",
+ 'SOURCE_UID' => $task2->TAS_UID,
+ ]
+ ]
+ ];
+ $status = 'TO_DO';
+ $flagGmail = true;
+ $tasUid = $task->TAS_UID;
+ $index = '1';
+ $userLogged = $user->USR_UID;
+
+ $cases = new Cases();
+ $cases->routeCase($processUid, $application, $postForm, $status, $flagGmail, $tasUid, $index, $userLogged);
+
+ $result = Delegation::where('APP_UID', '=', $application)->where('DEL_INDEX', '=', $index)->get()->first();
+
+ $this->assertEquals('CLOSED', $result->DEL_THREAD_STATUS);
+ }
+
+ /**
+ * This test verifies that the 'CasesDispath' job is in the queue.
+ * @test
+ * @covers \Cases::routeCase
+ */
+ public function this_should_add_a_cases_dispath_job_to_the_queue()
+ {
+ $result = $this->prepareDerivationData();
+ $application = $result->application;
+ $user = $result->user;
+ $task = $result->task;
+ $task2 = $result->task2;
+
+ $_SESSION['PROCESS'] = $application->PRO_UID;
+ $_SESSION['APPLICATION'] = $application->APP_UID;
+ $_POST['form'] = [
+ 'ROU_TYPE' => 'SEQUENTIAL',
+ 'TASKS' => [
+ 1 => [
+ 'TAS_UID' => $task->TAS_UID,
+ 'USR_UID' => $user->USR_UID,
+ 'TAS_ASSIGN_TYPE' => "BALANCED",
+ 'TAS_DEF_PROC_CODE' => "",
+ 'DEL_PRIORITY' => "",
+ 'TAS_PARENT' => "",
+ 'ROU_CONDITION' => "",
+ 'SOURCE_UID' => $task->TAS_UID,
+ ],
+ 2 => [
+ 'TAS_UID' => $task2->TAS_UID,
+ 'USR_UID' => $user->USR_UID,
+ 'TAS_ASSIGN_TYPE' => "BALANCED",
+ 'TAS_DEF_PROC_CODE' => "",
+ 'DEL_PRIORITY' => "",
+ 'TAS_PARENT' => "",
+ 'ROU_CONDITION' => "",
+ 'SOURCE_UID' => $task2->TAS_UID,
+ ]
+ ]
+ ];
+ $status = 'TO_DO';
+ $flagGmail = true;
+ $_SESSION['TASK'] = $task->TAS_UID;
+ $_SESSION["INDEX"] = '1';
+ $_SESSION['USER_LOGGED'] = $user->USR_UID;
+
+ global $RBAC;
+ $RBAC = RBAC::getSingleton(PATH_DATA, session_id());
+ $RBAC->initRBAC();
+ $RBAC->loadUserRolePermission('PROCESSMAKER', $_SESSION['USER_LOGGED']);
+
+ Queue::fake();
+ Queue::assertNothingPushed();
+
+ require_once PATH_METHODS . 'cases/cases_Derivate.php';
+
+ Queue::assertPushed(CasesDispatch::class);
+ }
+}
diff --git a/tests/unit/workflow/engine/src/ProcessMaker/Model/DelegationTest.php b/tests/unit/workflow/engine/src/ProcessMaker/Model/DelegationTest.php
index a9314cd26..de9231d22 100644
--- a/tests/unit/workflow/engine/src/ProcessMaker/Model/DelegationTest.php
+++ b/tests/unit/workflow/engine/src/ProcessMaker/Model/DelegationTest.php
@@ -27,6 +27,15 @@ class DelegationTest extends TestCase
{
use DatabaseTransactions;
+ /**
+ * Set up function.
+ */
+ public function setUp()
+ {
+ parent::setUp();
+ Delegation::truncate();
+ }
+
/**
* This checks to make sure pagination is working properly
*
@@ -255,6 +264,7 @@ class DelegationTest extends TestCase
$this->assertCount(1, $results['data']);
$this->assertEquals($application->APP_NUMBER, $results['data'][0]['APP_NUMBER']);
}
+
/**
* This ensures searching by case number and review the order
*
@@ -263,28 +273,23 @@ class DelegationTest extends TestCase
*/
public function it_should_search_and_filter_by_app_title()
{
- $title = '';
- for ($x = 1; $x <= 10; $x++) {
- $application = factory(Application::class)->states('foreign_keys')->create();
- factory(Delegation::class)->states('foreign_keys')->create([
- 'APP_UID' => $application->APP_UID,
- 'APP_NUMBER' => $application->APP_NUMBER,
- 'PRO_UID' => $application->PRO_UID,
- 'PRO_ID' => $application->PRO_ID
- ]);
- $title = $application->APP_TITLE;
- }
+ $delegations = factory(Delegation::class, 1)
+ ->states('foreign_keys')
+ ->create();
+ $title = $delegations->last()
+ ->application
+ ->APP_TITLE;
// We need to commit the records inserted because is needed for the "fulltext" index
DB::commit();
// Searching by a existent case title, result ordered by APP_NUMBER, filter by APP_NUMBER in DESC mode
$results = Delegation::search(null, 0, 10, $title, null, null, 'DESC',
- 'APP_NUMBER', null, null, null, 'APP_TITLE');
+ 'APP_NUMBER', null, null, null, 'APP_TITLE');
$this->assertCount(1, $results['data']);
$this->assertEquals($title, $results['data'][0]['APP_TITLE']);
// Searching by a existent case title, result ordered by APP_NUMBER, filter by APP_NUMBER in ASC mode
$results = Delegation::search(null, 0, 10, $title, null, null, 'ASC',
- 'APP_NUMBER', null, null, null, 'APP_TITLE');
+ 'APP_NUMBER', null, null, null, 'APP_TITLE');
$this->assertCount(1, $results['data']);
$this->assertEquals($title, $results['data'][0]['APP_TITLE']);
}
@@ -536,7 +541,6 @@ class DelegationTest extends TestCase
// Process with the category to search
$category = factory(ProcessCategory::class)->create();
$processSearch = factory(Process::class)->create([
- 'PRO_ID' => 5,
'PRO_CATEGORY' => $category->CATEGORY_UID
]);
// Delegations to found
diff --git a/tests/unit/workflow/engine/src/ProcessMaker/Model/ProcessTest.php b/tests/unit/workflow/engine/src/ProcessMaker/Model/ProcessTest.php
index 41af3a3d8..9168176e5 100644
--- a/tests/unit/workflow/engine/src/ProcessMaker/Model/ProcessTest.php
+++ b/tests/unit/workflow/engine/src/ProcessMaker/Model/ProcessTest.php
@@ -25,10 +25,10 @@ class ProcessTest extends TestCase
*/
public function it_has_tasks()
{
- $process = factory(Process::class)->create([
- 'PRO_ID' => function () {
- return factory(Task::class)->create()->PRO_ID;
- }
+ $process = factory(Process::class)->create();
+ factory(Task::class)->create([
+ 'PRO_UID' => $process->PRO_UID,
+ 'PRO_ID' => $process->PRO_ID
]);
$this->assertInstanceOf(Task::class, $process->tasks);
}
diff --git a/tests/unit/workflow/engine/src/ProcessMaker/Services/OAuth2/ServerTest.php b/tests/unit/workflow/engine/src/ProcessMaker/Services/OAuth2/ServerTest.php
index d99f8885a..9684efc69 100644
--- a/tests/unit/workflow/engine/src/ProcessMaker/Services/OAuth2/ServerTest.php
+++ b/tests/unit/workflow/engine/src/ProcessMaker/Services/OAuth2/ServerTest.php
@@ -192,11 +192,12 @@ class ServerTest extends TestCase
if (!is_dir(PATH_DB)) {
mkdir(PATH_DB);
}
- if (!is_dir(PATH_WORKSPACE)) {
- mkdir(PATH_WORKSPACE);
+ $pathWorkspace = PATH_DB . config('system.workspace') . PATH_SEP;
+ if (!is_dir($pathWorkspace)) {
+ mkdir($pathWorkspace);
}
$info = $this->getLicenseInfo();
- $filename = PATH_WORKSPACE . $info['name'];
+ $filename = $pathWorkspace . $info['name'];
$data = $info['content'];
file_put_contents($filename, $data);
diff --git a/workflow/engine/classes/Cases.php b/workflow/engine/classes/Cases.php
index 2ad834515..fdeade4d8 100644
--- a/workflow/engine/classes/Cases.php
+++ b/workflow/engine/classes/Cases.php
@@ -2,6 +2,7 @@
use ProcessMaker\BusinessModel\User as BusinessModelUser;
use ProcessMaker\BusinessModel\WebEntryEvent;
+use ProcessMaker\Cases\CasesTrait;
/*----------------------------------********---------------------------------*/
use ProcessMaker\ChangeLog\ChangeLog;
/*----------------------------------********---------------------------------*/
@@ -16,6 +17,7 @@ use ProcessMaker\Util\DateTime;
*/
class Cases
{
+ use CasesTrait;
private $appSolr = null;
public $dir = 'ASC';
public $sort = 'APP_MSG_DATE';
diff --git a/workflow/engine/classes/Derivation.php b/workflow/engine/classes/Derivation.php
index 9e09638f5..49302cd53 100644
--- a/workflow/engine/classes/Derivation.php
+++ b/workflow/engine/classes/Derivation.php
@@ -888,7 +888,7 @@ class Derivation
define( 'TASK_FINISH_TASK', - 2 );
}
- $this->case = new cases();
+ $this->case = new Cases();
//Get data for this DEL_INDEX current
$appFields = $this->case->loadCase( $currentDelegation['APP_UID'], $currentDelegation['DEL_INDEX'] );
diff --git a/workflow/engine/classes/class.pmScript.php b/workflow/engine/classes/class.pmScript.php
index 9beeca206..71b081dfa 100644
--- a/workflow/engine/classes/class.pmScript.php
+++ b/workflow/engine/classes/class.pmScript.php
@@ -2,9 +2,14 @@
use ProcessMaker\Plugins\PluginRegistry;
-spl_autoload_register(function($sClassName) {
- if (!empty(config("system.workspace"))) {
- $sPath = PATH_DB . config("system.workspace") . PATH_SEP . 'classes' . PATH_SEP;
+/**
+ * The helper 'config()' is loaded via 'spl_autoload_register()' in unit testing.
+ * The helper is pulled out to avoid an infinite loop.
+ */
+$workspace = config("system.workspace", null);
+spl_autoload_register(function($sClassName) use($workspace) {
+ if (!empty($workspace)) {
+ $sPath = PATH_DB . $workspace . PATH_SEP . 'classes' . PATH_SEP;
if (file_exists($sPath . $sClassName . '.php')) {
require_once $sPath . $sClassName . '.php';
}
diff --git a/workflow/engine/methods/cases/cases_Derivate.php b/workflow/engine/methods/cases/cases_Derivate.php
index ce16237a7..5acfad207 100644
--- a/workflow/engine/methods/cases/cases_Derivate.php
+++ b/workflow/engine/methods/cases/cases_Derivate.php
@@ -1,37 +1,40 @@
- var olink = document.location.href;
- olink = ( olink.search("gmail") == -1 ) ? parent.document.location.href : olink;
- if(olink.search("gmail") == -1){
- parent.location = "../cases/casesStartPage?action=startCase";
- } else {
- var data = olink.split("?");
- var odata = data[1].split("&");
- var appUid = odata[0].split("=");
+ $script = '
+ ');
+ var dataToSend = {
+ "action": "credentials",
+ "operation": "refreshPmSession",
+ "type": "processCall",
+ "funParams": [
+ appUid[1],
+ ""
+ ],
+ "expectReturn": false
+ };
+ var x = parent.postMessage(JSON.stringify(dataToSend), "*");
+ if (x == undefined){
+ x = parent.parent.postMessage(JSON.stringify(dataToSend), "*");
+ }
+ }
+ ';
+ die($script);
}
/* Permissions */
@@ -53,6 +56,7 @@ switch ($RBAC->userCanAccess('PM_CASES')) {
if (!isset($_POST['form'])) {
$_POST['form'] = [];
}
+$postForm = $_POST['form'];
/* GET , POST & $_SESSION Vars */
/* Process the info */
@@ -61,15 +65,11 @@ $sStatus = 'TO_DO';
try {
//Load Session variables
$processUid = isset($_SESSION['PROCESS']) ? $_SESSION['PROCESS'] : '';
- //load data
- $oCase = new Cases();
// check if a task was already derivated
- if (isset($_SESSION["APPLICATION"])
- && isset($_SESSION["INDEX"])) {
- $_SESSION['LAST_DERIVATED_APPLICATION'] = isset($_SESSION['LAST_DERIVATED_APPLICATION'])?$_SESSION['LAST_DERIVATED_APPLICATION']:'';
- $_SESSION['LAST_DERIVATED_INDEX'] = isset($_SESSION['LAST_DERIVATED_INDEX'])?$_SESSION['LAST_DERIVATED_INDEX']:'';
- if ($_SESSION["APPLICATION"] === $_SESSION['LAST_DERIVATED_APPLICATION']
- && $_SESSION["INDEX"] === $_SESSION['LAST_DERIVATED_INDEX']) {
+ if (isset($_SESSION["APPLICATION"]) && isset($_SESSION["INDEX"])) {
+ $_SESSION['LAST_DERIVATED_APPLICATION'] = isset($_SESSION['LAST_DERIVATED_APPLICATION']) ? $_SESSION['LAST_DERIVATED_APPLICATION'] : '';
+ $_SESSION['LAST_DERIVATED_INDEX'] = isset($_SESSION['LAST_DERIVATED_INDEX']) ? $_SESSION['LAST_DERIVATED_INDEX'] : '';
+ if ($_SESSION["APPLICATION"] === $_SESSION['LAST_DERIVATED_APPLICATION'] && $_SESSION["INDEX"] === $_SESSION['LAST_DERIVATED_INDEX']) {
throw new Exception(G::LoadTranslation('ID_INVALID_APPLICATION_ID_MSG', [G::LoadTranslation('ID_REOPEN')]));
} else {
$appDel = new AppDelegation();
@@ -84,116 +84,6 @@ try {
throw new Exception(G::LoadTranslation('ID_INVALID_APPLICATION_ID_MSG', [G::LoadTranslation('ID_REOPEN')]));
}
- //warning: we are not using the result value of function thisIsTheCurrentUser, so I'm commenting to optimize speed.
- //$oCase->thisIsTheCurrentUser( $_SESSION['APPLICATION'], $_SESSION['INDEX'], $_SESSION['USER_LOGGED'], 'REDIRECT', 'casesListExtJs');
- $appFields = $oCase->loadCase($_SESSION['APPLICATION']);
- $appFields['APP_DATA'] = array_merge($appFields['APP_DATA'], G::getSystemConstants());
- //cleaning debug variables
- $_SESSION['TRIGGER_DEBUG']['DATA'] = [];
- $_SESSION['TRIGGER_DEBUG']['TRIGGERS_NAMES'] = [];
- $_SESSION['TRIGGER_DEBUG']['TRIGGERS_VALUES'] = [];
- $_SESSION['TRIGGER_DEBUG']['TRIGGERS_EXECUTION_TIME'] = [];
-
- $triggers = $oCase->loadTriggers($_SESSION['TASK'], 'ASSIGN_TASK', -2, 'BEFORE');
-
- //if there are some triggers to execute
- if (sizeof($triggers) > 0) {
- //Execute triggers before derivation
- $appFields['APP_DATA'] = $oCase->ExecuteTriggers($_SESSION['TASK'], 'ASSIGN_TASK', -2, 'BEFORE',
- $appFields['APP_DATA']);
-
- //save trigger variables for debugger
- $_SESSION['TRIGGER_DEBUG']['info'][0]['NUM_TRIGGERS'] = sizeof($triggers);
- $_SESSION['TRIGGER_DEBUG']['info'][0]['TIME'] = G::toUpper(G::loadTranslation('ID_BEFORE'));
- $_SESSION['TRIGGER_DEBUG']['info'][0]['TRIGGERS_NAMES'] = array_column($triggers, 'TRI_TITLE');
- $_SESSION['TRIGGER_DEBUG']['info'][0]['TRIGGERS_VALUES'] = $triggers;
- $_SESSION['TRIGGER_DEBUG']['info'][0]['TRIGGERS_EXECUTION_TIME'] = $oCase->arrayTriggerExecutionTime;
- }
-
- unset($appFields['APP_STATUS']);
- unset($appFields['APP_PROC_STATUS']);
- unset($appFields['APP_PROC_CODE']);
- unset($appFields['APP_PIN']);
-
- $appFields["DEL_INDEX"] = $_SESSION["INDEX"];
- $appFields["TAS_UID"] = $_SESSION["TASK"];
- $appFields["USER_UID"] = $_SESSION["USER_LOGGED"];
- $appFields["CURRENT_DYNAFORM"] = "-2";
- $appFields["OBJECT_TYPE"] = "ASSIGN_TASK";
-
- $oCase->updateCase($_SESSION["APPLICATION"], $appFields); //Save data
-
- //Prepare information for the derivation
- $oDerivation = new Derivation();
- $aCurrentDerivation = [
- 'APP_UID' => $_SESSION['APPLICATION'],
- 'DEL_INDEX' => $_SESSION['INDEX'],
- 'APP_STATUS' => $sStatus,
- 'TAS_UID' => $_SESSION['TASK'],
- 'ROU_TYPE' => $_POST['form']['ROU_TYPE']
- ];
- $aDataForPrepareInfo = [
- 'USER_UID' => $_SESSION['USER_LOGGED'],
- 'APP_UID' => $_SESSION['APPLICATION'],
- 'DEL_INDEX' => $_SESSION['INDEX']
- ];
-
- //We define some parameters in the before the derivation
- //Then this function will be route the case
- $arrayDerivationResult = $oDerivation->beforeDerivate(
- $aDataForPrepareInfo,
- $_POST['form']['TASKS'],
- $_POST['form']['ROU_TYPE'],
- $aCurrentDerivation
- );
-
- if (!empty($arrayDerivationResult)) {
- foreach ($_POST['form']['TASKS'] as $key => $value) {
- if (isset($value['TAS_UID'])) {
- foreach ($arrayDerivationResult as $value2) {
- if ($value2['TAS_UID'] == $value['TAS_UID']) {
- $_POST['form']['TASKS'][$key]['DEL_INDEX'] = $value2['DEL_INDEX'];
- break;
- }
- }
- }
- }
- }
-
- $appFields = $oCase->loadCase($_SESSION['APPLICATION']); //refresh appFields, because in derivations should change some values
- $triggers = $oCase->loadTriggers($_SESSION['TASK'], 'ASSIGN_TASK', -2,
- 'AFTER'); //load the triggers after derivation
- if (sizeof($triggers) > 0) {
- $appFields['APP_DATA'] = $oCase->ExecuteTriggers($_SESSION['TASK'], 'ASSIGN_TASK', -2, 'AFTER',
- $appFields['APP_DATA']); //Execute triggers after derivation
-
-
- $_SESSION['TRIGGER_DEBUG']['info'][1]['NUM_TRIGGERS'] = sizeof($triggers);
- $_SESSION['TRIGGER_DEBUG']['info'][1]['TIME'] = G::toUpper(G::loadTranslation('ID_AFTER'));
- $_SESSION['TRIGGER_DEBUG']['info'][1]['TRIGGERS_NAMES'] = array_column($triggers, 'TRI_TITLE');
- $_SESSION['TRIGGER_DEBUG']['info'][1]['TRIGGERS_VALUES'] = $triggers;
- $_SESSION['TRIGGER_DEBUG']['info'][1]['TRIGGERS_EXECUTION_TIME'] = $oCase->arrayTriggerExecutionTime;
- }
- unset($appFields['APP_STATUS']);
- unset($appFields['APP_PROC_STATUS']);
- unset($appFields['APP_PROC_CODE']);
- unset($appFields['APP_PIN']);
-
- $appFields["DEL_INDEX"] = $_SESSION["INDEX"];
- $appFields["TAS_UID"] = $_SESSION["TASK"];
- $appFields["USER_UID"] = $_SESSION["USER_LOGGED"];
- $appFields["CURRENT_DYNAFORM"] = "-2";
- $appFields["OBJECT_TYPE"] = "ASSIGN_TASK";
-
- $oCase->updateCase($_SESSION['APPLICATION'], $appFields);
-
- // Send notifications - Start
- $oUser = new Users();
- $aUser = $oUser->load($_SESSION['USER_LOGGED']);
- $fromName = $aUser['USR_FIRSTNAME'] . ' ' . $aUser['USR_LASTNAME'];
-
- $sFromData = $fromName . ($aUser['USR_EMAIL'] != '' ? ' <' . $aUser['USR_EMAIL'] . '>' : '');
-
$flagGmail = false;
/*----------------------------------********---------------------------------*/
$licensedFeatures = PMLicensedFeatures::getSingleton();
@@ -201,80 +91,29 @@ try {
$pmGoogle = new PmGoogleApi();
if ($pmGoogle->getServiceGmailStatus()) {
$flagGmail = true;
-
- $appDel = new AppDelegation();
- $actualThread = $appDel->Load($_SESSION ['APPLICATION'], $_SESSION ['INDEX']);
-
- $appDelPrev = $appDel->LoadParallel($_SESSION ['APPLICATION']);
- $Pmgmail = new \ProcessMaker\BusinessModel\Pmgmail();
- foreach ($appDelPrev as $app) {
- if (($app ['DEL_INDEX'] != $_SESSION ['INDEX']) && ($app ['DEL_PREVIOUS'] != $actualThread ['DEL_PREVIOUS'])) {
- $Pmgmail->gmailsIfSelfServiceValueBased($_SESSION ['APPLICATION'], $app ['DEL_INDEX'], $_POST ['form'] ['TASKS'], $appFields ['APP_DATA']);
- }
- }
}
}
/*----------------------------------********---------------------------------*/
- try {
- $oCase->sendNotifications(
- $_SESSION['TASK'],
- $_POST['form']['TASKS'],
- $appFields['APP_DATA'],
- $_SESSION['APPLICATION'],
- $_SESSION['INDEX'],
- $sFromData
- );
- } catch (Exception $e) {
- G::SendTemporalMessage(G::loadTranslation('ID_NOTIFICATION_ERROR') . ' - ' . $e->getMessage(), 'warning',
- 'string', null, '100%');
- }
- // Send notifications - End
- // Events - Start
- $oEvent = new Event();
-
- $oEvent->closeAppEvents($processUid, $_SESSION['APPLICATION'], $_SESSION['INDEX'], $_SESSION['TASK']);
- $oCurrentAppDel = AppDelegationPeer::retrieveByPk($_SESSION['APPLICATION'], $_SESSION['INDEX'] + 1);
- $multipleDelegation = false;
- // check if there are multiple derivations
- if (count($_POST['form']['TASKS']) > 1) {
- $multipleDelegation = true;
- }
- // If the case has been delegated
- if (isset($oCurrentAppDel)) {
- // if there is just a single derivation the TASK_UID can be set by the delegation data
- if (!$multipleDelegation) {
- $aCurrentAppDel = $oCurrentAppDel->toArray(BasePeer::TYPE_FIELDNAME);
- $oEvent->createAppEvents($aCurrentAppDel['PRO_UID'], $aCurrentAppDel['APP_UID'],
- $aCurrentAppDel['DEL_INDEX'], $aCurrentAppDel['TAS_UID']);
- } else {
- // else we need to check every task and create the events if it have any
- foreach ($_POST['form']['TASKS'] as $taskDelegated) {
- $aCurrentAppDel = $oCurrentAppDel->toArray(BasePeer::TYPE_FIELDNAME);
- $oEvent->createAppEvents($aCurrentAppDel['PRO_UID'], $aCurrentAppDel['APP_UID'],
- $aCurrentAppDel['DEL_INDEX'], $taskDelegated['TAS_UID']);
- }
- }
- }
- //Events - End
-
- /*----------------------------------********---------------------------------*/
- // Set users drive - start
- $licensedFeatures = PMLicensedFeatures::getSingleton();
- if ($licensedFeatures->verifyfeature('AhKNjBEVXZlWUFpWE8wVTREQ0FObmo0aTdhVzhvalFic1M=')) {
- $drive = new AppDocumentDrive();
- if ($drive->getStatusDrive()) {
- //add users email next task
- $drive->addUsersDocumentDrive($appFields['APP_UID']);
- }
- }
- // Set users drive - End
- /*----------------------------------********---------------------------------*/
+ $application = $_SESSION['APPLICATION'];
+ $tasUid = $_SESSION['TASK'];
+ $index = $_SESSION["INDEX"];
+ $userLogged = $_SESSION["USER_LOGGED"];
+
+ //Now we dispatch the derivation of the case through Jobs Laravel.
+ $closure = function() use($processUid, $application, $postForm, $sStatus, $flagGmail, $tasUid, $index, $userLogged) {
+ $cases = new Cases();
+ $cases->routeCase($processUid, $application, $postForm, $sStatus, $flagGmail, $tasUid, $index, $userLogged);
+ };
+ JobsManager::getSingleton()->dispatch("CasesDispatch", $closure);
+
+ //We close the related threads.
+ $cases = new Cases();
+ $cases->CloseCurrentDelegation($application, $index);
$debuggerAvailable = true;
-
$casesRedirector = 'casesListExtJsRedirector';
- if (isset ($_SESSION ['user_experience']) && $flagGmail === false) {
+ if (isset($_SESSION ['user_experience']) && $flagGmail === false) {
$aNextStep ['PAGE'] = $casesRedirector . '?ux=' . $_SESSION ['user_experience'];
$debuggerAvailable = false;
} else {
@@ -285,43 +124,24 @@ try {
}
}
- if (isset($_SESSION['PMDEBUGGER']) && $_SESSION['PMDEBUGGER'] && $debuggerAvailable) {
- $_SESSION['TRIGGER_DEBUG']['BREAKPAGE'] = $aNextStep['PAGE'];
- $loc = 'cases_Step?' . 'breakpoint=triggerdebug';
- } else {
- $loc = $aNextStep['PAGE'];
- }
+ $loc = $aNextStep['PAGE'];
+
//Triggers After
$isIE = Bootstrap::isIE();
-
- if (isset($_SESSION['TRIGGER_DEBUG']['ISSET']) && !$isIE) {
- if ($_SESSION['TRIGGER_DEBUG']['ISSET'] == 1) {
- $oTemplatePower = new TemplatePower(PATH_TPL . 'cases/cases_Step.html');
- $oTemplatePower->prepare();
- $G_PUBLISH = new Publisher();
- $G_PUBLISH->AddContent('template', '', '', '', $oTemplatePower);
- $_POST['NextStep'] = $loc;
- $G_PUBLISH->AddContent('view', 'cases/showDebugFrameLoader');
- $G_PUBLISH->AddContent('view', 'cases/showDebugFrameBreaker');
- $_SESSION['TRIGGER_DEBUG']['ISSET'] == 0;
- G::RenderPage('publish', 'blank');
- exit();
- } else {
- unset($_SESSION['TRIGGER_DEBUG']);
- }
- }
+ unset($_SESSION['TRIGGER_DEBUG']);
//close tab only if IE11 add a validation was added if the current skin is uxs
if ($isIE && !isset($_SESSION['__OUTLOOK_CONNECTOR__']) && SYS_SKIN !== "uxs") {
- $script = "";
+ $script = "
+ ";
die($script);
}
diff --git a/workflow/engine/src/ProcessMaker/Cases/CasesTrait.php b/workflow/engine/src/ProcessMaker/Cases/CasesTrait.php
new file mode 100644
index 000000000..d7d35bdf3
--- /dev/null
+++ b/workflow/engine/src/ProcessMaker/Cases/CasesTrait.php
@@ -0,0 +1,205 @@
+loadCase($application);
+ $appFields['APP_DATA'] = array_merge($appFields['APP_DATA'], G::getSystemConstants());
+
+ $triggerDebug = [];
+ $triggers = $this->loadTriggers($tasUid, 'ASSIGN_TASK', -2, 'BEFORE');
+
+ //if there are some triggers to execute
+ if (sizeof($triggers) > 0) {
+ //Execute triggers before derivation
+ $appFields['APP_DATA'] = $this->executeTriggers($tasUid, 'ASSIGN_TASK', -2, 'BEFORE', $appFields['APP_DATA']);
+
+ //save trigger variables for debugger
+ $triggerDebug[] = [
+ 'NUM_TRIGGERS' => sizeof($triggers),
+ 'TIME' => G::toUpper(G::loadTranslation('ID_BEFORE')),
+ 'TRIGGERS_NAMES' => array_column($triggers, 'TRI_TITLE'),
+ 'TRIGGERS_VALUES' => $triggers,
+ 'TRIGGERS_EXECUTION_TIME' => $this->arrayTriggerExecutionTime
+ ];
+ }
+
+ unset($appFields['APP_STATUS']);
+ unset($appFields['APP_PROC_STATUS']);
+ unset($appFields['APP_PROC_CODE']);
+ unset($appFields['APP_PIN']);
+
+ $appFields["DEL_INDEX"] = $index;
+ $appFields["TAS_UID"] = $tasUid;
+ $appFields["USER_UID"] = $userLogged;
+ $appFields["CURRENT_DYNAFORM"] = "-2";
+ $appFields["OBJECT_TYPE"] = "ASSIGN_TASK";
+
+ //save data
+ $this->updateCase($application, $appFields);
+
+ //prepare information for the derivation
+ $derivation = new Derivation();
+ $currentDerivation = [
+ 'APP_UID' => $application,
+ 'DEL_INDEX' => $index,
+ 'APP_STATUS' => $status,
+ 'TAS_UID' => $tasUid,
+ 'ROU_TYPE' => $postForm['ROU_TYPE']
+ ];
+ $dataForPrepareInfo = [
+ 'USER_UID' => $userLogged,
+ 'APP_UID' => $application,
+ 'DEL_INDEX' => $index
+ ];
+
+ //we define some parameters in the before the derivation
+ //then this function will be route the case
+ $arrayDerivationResult = $derivation->beforeDerivate(
+ $dataForPrepareInfo,
+ $postForm['TASKS'],
+ $postForm['ROU_TYPE'],
+ $currentDerivation
+ );
+
+ if (!empty($arrayDerivationResult)) {
+ foreach ($postForm['TASKS'] as $key => $value) {
+ if (isset($value['TAS_UID'])) {
+ foreach ($arrayDerivationResult as $value2) {
+ if ($value2['TAS_UID'] == $value['TAS_UID']) {
+ $postForm['TASKS'][$key]['DEL_INDEX'] = $value2['DEL_INDEX'];
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ $appFields = $this->loadCase($application); //refresh appFields, because in derivations should change some values
+ $triggers = $this->loadTriggers($tasUid, 'ASSIGN_TASK', -2, 'AFTER'); //load the triggers after derivation
+ if (sizeof($triggers) > 0) {
+ $appFields['APP_DATA'] = $this->ExecuteTriggers($tasUid, 'ASSIGN_TASK', -2, 'AFTER', $appFields['APP_DATA']); //Execute triggers after derivation
+
+ $triggerDebug[] = [
+ 'NUM_TRIGGERS' => sizeof($triggers),
+ 'TIME' => G::toUpper(G::loadTranslation('ID_AFTER')),
+ 'TRIGGERS_NAMES' => array_column($triggers, 'TRI_TITLE'),
+ 'TRIGGERS_VALUES' => $triggers,
+ 'TRIGGERS_EXECUTION_TIME' => $this->arrayTriggerExecutionTime
+ ];
+ }
+ unset($appFields['APP_STATUS']);
+ unset($appFields['APP_PROC_STATUS']);
+ unset($appFields['APP_PROC_CODE']);
+ unset($appFields['APP_PIN']);
+
+ $appFields["DEL_INDEX"] = $index;
+ $appFields["TAS_UID"] = $tasUid;
+ $appFields["USER_UID"] = $userLogged;
+ $appFields["CURRENT_DYNAFORM"] = "-2";
+ $appFields["OBJECT_TYPE"] = "ASSIGN_TASK";
+
+ $this->updateCase($application, $appFields);
+
+ // Send notifications - Start
+ $oUser = new Users();
+ $aUser = $oUser->load($userLogged);
+ $fromName = $aUser['USR_FIRSTNAME'] . ' ' . $aUser['USR_LASTNAME'];
+
+ $sFromData = $fromName . ($aUser['USR_EMAIL'] != '' ? ' <' . $aUser['USR_EMAIL'] . '>' : '');
+
+ if ($flagGmail === true) {
+ $appDel = new AppDelegation();
+ $actualThread = $appDel->Load($application, $index);
+
+ $appDelPrev = $appDel->LoadParallel($application);
+ $Pmgmail = new Pmgmail();
+ foreach ($appDelPrev as $app) {
+ if (($app['DEL_INDEX'] != $index) && ($app['DEL_PREVIOUS'] != $actualThread['DEL_PREVIOUS'])) {
+ $Pmgmail->gmailsIfSelfServiceValueBased($application, $app['DEL_INDEX'], $postForm['TASKS'], $appFields['APP_DATA']);
+ }
+ }
+ }
+
+ try {
+ $this->sendNotifications($tasUid, $postForm['TASKS'], $appFields['APP_DATA'], $application, $index, $sFromData);
+ } catch (Exception $e) {
+ G::SendTemporalMessage(G::loadTranslation('ID_NOTIFICATION_ERROR') . ' - ' . $e->getMessage(), 'warning', 'string', null, '100%');
+ }
+ // Send notifications - End
+ // Events - Start
+ $event = new Event();
+
+ $event->closeAppEvents($processUid, $application, $index, $tasUid);
+ $currentAppDel = AppDelegationPeer::retrieveByPk($application, $index + 1);
+ $multipleDelegation = false;
+ // check if there are multiple derivations
+ if (count($postForm['TASKS']) > 1) {
+ $multipleDelegation = true;
+ }
+ // If the case has been delegated
+ if (isset($currentAppDel)) {
+ // if there is just a single derivation the TASK_UID can be set by the delegation data
+ if (!$multipleDelegation) {
+ $arrayResult = $currentAppDel->toArray(BasePeer::TYPE_FIELDNAME);
+ $event->createAppEvents($arrayResult['PRO_UID'], $arrayResult['APP_UID'], $arrayResult['DEL_INDEX'], $arrayResult['TAS_UID']);
+ } else {
+ // else we need to check every task and create the events if it have any
+ foreach ($postForm['TASKS'] as $taskDelegated) {
+ $arrayResult = $currentAppDel->toArray(BasePeer::TYPE_FIELDNAME);
+ $event->createAppEvents($arrayResult['PRO_UID'], $arrayResult['APP_UID'], $arrayResult['DEL_INDEX'], $taskDelegated['TAS_UID']);
+ }
+ }
+ }
+ //Events - End
+
+ /*----------------------------------********---------------------------------*/
+ // Set users drive - start
+ $licensedFeatures = PMLicensedFeatures::getSingleton();
+ if ($licensedFeatures->verifyfeature('AhKNjBEVXZlWUFpWE8wVTREQ0FObmo0aTdhVzhvalFic1M=')) {
+ $drive = new AppDocumentDrive();
+ if ($drive->getStatusDrive()) {
+ //add users email next task
+ $drive->addUsersDocumentDrive($appFields['APP_UID']);
+ }
+ }
+ // Set users drive - End
+ /*----------------------------------********---------------------------------*/
+
+ $result = [
+ 'appFields' => $appFields,
+ 'triggerDebug' => $triggerDebug
+ ];
+ return (object) $result;
+ }
+}
diff --git a/workflow/engine/src/ProcessMaker/Model/StepTrigger.php b/workflow/engine/src/ProcessMaker/Model/StepTrigger.php
new file mode 100644
index 000000000..5285cd179
--- /dev/null
+++ b/workflow/engine/src/ProcessMaker/Model/StepTrigger.php
@@ -0,0 +1,14 @@
+