From ebfc73ca117c452af238c424c67e81796c514989 Mon Sep 17 00:00:00 2001 From: Paula Quispe Date: Mon, 7 Oct 2019 09:05:05 -0400 Subject: [PATCH] PMCORE-552 --- .../factories/AppTimeoutActionFactory.php | 12 ++ database/factories/TaskFactory.php | 27 ++- ...TriggerFactory.php => TriggersFactory.php} | 2 +- gulliver/system/class.g.php | 1 + .../ProcessMaker/BusinessModel/CasesTest.php | 84 ++++++++- .../Model/AppTimeoutActionTest.php | 120 +++++++++++++ .../ProcessMaker/Model/ListUnassignedTest.php | 30 ++++ .../src/ProcessMaker/Model/TriggersTest.php | 72 +++++++- .../Util/Helpers/CalculateDateTest.php | 44 +++++ ...=> ChangeAbbreviationOfDirectivesTest.php} | 2 +- workflow/engine/bin/cron_single.php | 163 ++---------------- workflow/engine/classes/class.pmScript.php | 3 + .../AppTimeoutActionExecutedMapBuilder.php | 2 +- .../model/om/BaseAppTimeoutActionExecuted.php | 30 +++- .../om/BaseAppTimeoutActionExecutedPeer.php | 66 +++---- workflow/engine/config/schema.xml | 2 +- workflow/engine/data/mysql/schema.sql | 2 +- workflow/engine/methods/setup/auditLog.php | 2 +- .../engine/methods/setup/auditLogAjax.php | 2 +- .../src/ProcessMaker/BusinessModel/Cases.php | 128 ++++++++++++++ .../{AuditLog => Log}/AuditLog.php | 2 +- .../ProcessMaker/Model/AppTimeoutAction.php | 103 +++++++++++ .../src/ProcessMaker/Model/ListUnassigned.php | 36 +++- .../src/ProcessMaker/Model/Triggers.php | 60 ++++++- .../engine/src/ProcessMaker/Util/helpers.php | 30 ++++ 25 files changed, 802 insertions(+), 223 deletions(-) create mode 100644 database/factories/AppTimeoutActionFactory.php rename database/factories/{TriggerFactory.php => TriggersFactory.php} (92%) create mode 100644 tests/unit/workflow/engine/src/ProcessMaker/Model/AppTimeoutActionTest.php create mode 100644 tests/unit/workflow/engine/src/ProcessMaker/Util/Helpers/CalculateDateTest.php rename tests/unit/workflow/engine/src/ProcessMaker/Util/Helpers/{ChangeAbbreviationOfDirectives.php => ChangeAbbreviationOfDirectivesTest.php} (94%) rename workflow/engine/src/ProcessMaker/{AuditLog => Log}/AuditLog.php (99%) create mode 100644 workflow/engine/src/ProcessMaker/Model/AppTimeoutAction.php diff --git a/database/factories/AppTimeoutActionFactory.php b/database/factories/AppTimeoutActionFactory.php new file mode 100644 index 000000000..c9a120d07 --- /dev/null +++ b/database/factories/AppTimeoutActionFactory.php @@ -0,0 +1,12 @@ +define(\ProcessMaker\Model\AppTimeoutAction::class, function (Faker $faker) { + $index = $faker->unique()->numberBetween(20); + return [ + 'APP_UID' => G::generateUniqueID(), + 'DEL_INDEX' => $index, + 'EXECUTION_DATE' => $faker->dateTime() + ]; +}); diff --git a/database/factories/TaskFactory.php b/database/factories/TaskFactory.php index 90bbe13a2..d585bd3b9 100644 --- a/database/factories/TaskFactory.php +++ b/database/factories/TaskFactory.php @@ -29,10 +29,11 @@ $factory->define(\ProcessMaker\Model\Task::class, function(Faker $faker) { 'TAS_OWNER_APP' => 'FALSE', 'TAS_CAN_SEND_MESSAGE' => 'FALSE', 'TAS_SEND_LAST_EMAIL' => 'FALSE', + 'TAS_SELFSERVICE_TIMEOUT' => 0, ]; }); -// Create a delegation with the foreign keys +// Create a task with the foreign keys $factory->state(\ProcessMaker\Model\Task::class, 'foreign_keys', function (Faker $faker) { $process = factory(\ProcessMaker\Model\Process::class)->create(); return [ @@ -57,5 +58,29 @@ $factory->state(\ProcessMaker\Model\Task::class, 'foreign_keys', function (Faker 'TAS_OWNER_APP' => 'FALSE', 'TAS_CAN_SEND_MESSAGE' => 'FALSE', 'TAS_SEND_LAST_EMAIL' => 'FALSE', + 'TAS_SELFSERVICE_TIMEOUT' => 0, + ]; +}); + +// Create a task related with the self-service timeout execution +$factory->state(\ProcessMaker\Model\Task::class, 'sef_service_timeout', function (Faker $faker) { + $timeUnit = $faker->randomElement(['MINUTES', 'HOURS', 'DAYS']); + $execution = $faker->randomElement(['EVERY_TIME', 'ONCE']); + return [ + 'TAS_UID' => G::generateUniqueID(), + 'TAS_ID' => $faker->unique()->numberBetween(1, 200000), + 'TAS_TITLE' => $faker->sentence(2), + 'TAS_TYPE' => 'NORMAL', + 'TAS_TYPE_DAY' => 1, + 'TAS_DURATION' => 1, + 'TAS_ASSIGN_TYPE' => 'SELF_SERVICE', + 'TAS_ASSIGN_VARIABLE' => '@@SYS_NEXT_USER_TO_BE_ASSIGNED', + 'TAS_SELFSERVICE_TIMEOUT' => 1, + 'TAS_SELFSERVICE_TIME' => $faker->unique()->numberBetween(1, 24), + 'TAS_SELFSERVICE_TIME_UNIT' => $timeUnit, + 'TAS_SELFSERVICE_TRIGGER_UID' => function() { + return $trigger = factory(\ProcessMaker\Model\Triggers::class)->create()->TRI_UID; + }, + 'TAS_SELFSERVICE_EXECUTION' => $execution, ]; }); diff --git a/database/factories/TriggerFactory.php b/database/factories/TriggersFactory.php similarity index 92% rename from database/factories/TriggerFactory.php rename to database/factories/TriggersFactory.php index f467c626a..11117f083 100644 --- a/database/factories/TriggerFactory.php +++ b/database/factories/TriggersFactory.php @@ -12,7 +12,7 @@ $factory->define(Triggers::class, function (Faker $faker) { return factory(\ProcessMaker\Model\Process::class)->create()->PRO_UID; }, 'TRI_TYPE' => 'SCRIPT', - 'TRI_WEBBOT' => $faker->text, + 'TRI_WEBBOT' => '$var = 1;', 'TRI_PARAM' => '', ]; }); diff --git a/gulliver/system/class.g.php b/gulliver/system/class.g.php index de2d836e6..658466d62 100644 --- a/gulliver/system/class.g.php +++ b/gulliver/system/class.g.php @@ -3,6 +3,7 @@ use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Request; use ProcessMaker\Core\System; +use ProcessMaker\Log\AuditLog; use ProcessMaker\Plugins\PluginRegistry; use ProcessMaker\Services\OAuth2\Server; use ProcessMaker\Validation\ValidationUploadedFiles; diff --git a/tests/unit/workflow/engine/src/ProcessMaker/BusinessModel/CasesTest.php b/tests/unit/workflow/engine/src/ProcessMaker/BusinessModel/CasesTest.php index 55c762947..88c9294a9 100644 --- a/tests/unit/workflow/engine/src/ProcessMaker/BusinessModel/CasesTest.php +++ b/tests/unit/workflow/engine/src/ProcessMaker/BusinessModel/CasesTest.php @@ -4,10 +4,15 @@ namespace ProcessMaker\BusinessModel; use Exception; use G; +use Illuminate\Foundation\Testing\DatabaseTransactions; +use Illuminate\Support\Facades\DB; use ProcessMaker\BusinessModel\Cases; use ProcessMaker\Model\Application; use ProcessMaker\Model\Delegation; use ProcessMaker\Model\Documents; +use ProcessMaker\Model\ListUnassigned; +use ProcessMaker\Model\Task; +use ProcessMaker\Model\Triggers; use ProcessMaker\Model\User; use RBAC; use Tests\TestCase; @@ -19,7 +24,6 @@ use Tests\TestCase; */ class CasesTest extends TestCase { - /** * Set up method. */ @@ -233,4 +237,82 @@ class CasesTest extends TestCase // Call the uploadFiles method $case->uploadFiles($user->USR_UID, $application->APP_UID, $varName, -1, null, $delegation->DEL_INDEX); } + + /** + * This test the execution of trigger from cases related to the self services timeout + * + * @covers \ProcessMaker\BusinessModel\Cases::executeSelfServiceTimeout() + * @test + */ + public function it_execute_trigger_from_cases_with_self_service_timeout_every_time() + { + ListUnassigned::truncate(); + // Define the Execute Trigger = EVERY_TIME + $application = factory(Application::class)->states('foreign_keys')->create(); + // Create a trigger + $trigger = factory(Triggers::class)->create([ + 'PRO_UID' => $application->PRO_UID, + 'TRI_WEBBOT' => 'echo(1);' + ]); + // Create a task with the configuration trigger execution + $task = factory(Task::class)->states('sef_service_timeout')->create([ + 'PRO_UID' => $application->PRO_UID, + 'TAS_SELFSERVICE_EXECUTION' => 'EVERY_TIME', + 'TAS_SELFSERVICE_TRIGGER_UID' => $trigger->TRI_UID + ]); + // Create a unassigned cases + factory(ListUnassigned::class)->create([ + 'TAS_UID' => $task->TAS_UID, + 'TAS_ID' => $task->TAS_ID, + 'APP_NUMBER' => $application->APP_NUMBER, + 'APP_UID' => $application->APP_UID, + 'PRO_UID' => $application->PRO_UID + ]); + // Define the session + $_SESSION["PROCESS"] = $application->PRO_UID; + + // todo: the function Cases::loadCase is using propel we need to change this + DB::commit(); + $casesExecuted = Cases::executeSelfServiceTimeout(); + $this->assertTrue(is_array($casesExecuted)); + } + + /** + * This test the execution of trigger from cases related to the self services timeout + * + * @covers \ProcessMaker\BusinessModel\Cases::executeSelfServiceTimeout() + * @test + */ + public function it_execute_trigger_from_cases_with_self_service_timeout_once() + { + ListUnassigned::truncate(); + // Define the Execute Trigger = ONCE + $application = factory(Application::class)->states('foreign_keys')->create(); + // Create a trigger + $trigger = factory(Triggers::class)->create([ + 'PRO_UID' => $application->PRO_UID, + 'TRI_WEBBOT' => 'echo(1);' + ]); + // Create a task with the configuration trigger execution + $task = factory(Task::class)->states('sef_service_timeout')->create([ + 'PRO_UID' => $application->PRO_UID, + 'TAS_SELFSERVICE_EXECUTION' => 'ONCE', + 'TAS_SELFSERVICE_TRIGGER_UID' => $trigger->TRI_UID + ]); + // Create a unassigned cases + factory(ListUnassigned::class)->create([ + 'TAS_UID' => $task->TAS_UID, + 'TAS_ID' => $task->TAS_ID, + 'APP_NUMBER' => $application->APP_NUMBER, + 'APP_UID' => $application->APP_UID, + 'PRO_UID' => $application->PRO_UID + ]); + // Define the session + $_SESSION["PROCESS"] = $application->PRO_UID; + + // todo: the function Cases::loadCase is using propel we need to change this + DB::commit(); + $casesExecuted = Cases::executeSelfServiceTimeout(); + $this->assertTrue(is_array($casesExecuted)); + } } diff --git a/tests/unit/workflow/engine/src/ProcessMaker/Model/AppTimeoutActionTest.php b/tests/unit/workflow/engine/src/ProcessMaker/Model/AppTimeoutActionTest.php new file mode 100644 index 000000000..eafdfefec --- /dev/null +++ b/tests/unit/workflow/engine/src/ProcessMaker/Model/AppTimeoutActionTest.php @@ -0,0 +1,120 @@ +create(); + $timeout = factory(AppTimeoutAction::class)->create(); + $timeout->setCaseUid($timeout->APP_UID); + $this->assertEquals($timeout->getCaseUid(), $timeout->APP_UID); + } + + /** + * Test set and get the index property + * + * @covers \ProcessMaker\Model\AppTimeoutAction::setIndex() + * @covers \ProcessMaker\Model\AppTimeoutAction::getIndex() + * @test + */ + public function it_set_get_index() + { + factory(AppTimeoutAction::class)->create(); + $timeout = factory(AppTimeoutAction::class)->create(); + $timeout->setIndex($timeout->DEL_INDEX); + $this->assertEquals($timeout->getIndex(), $timeout->DEL_INDEX); + } + + /** + * Test a query to only include a specific case + * + * @covers \ProcessMaker\Model\AppTimeoutAction::scopeCase() + * @test + */ + public function it_filter_a_specific_case() + { + factory(AppTimeoutAction::class)->create(); + $timeout = factory(AppTimeoutAction::class)->create(); + $this->assertCount(1, $timeout->case($timeout->APP_UID)->get()); + } + + /** + * Test scope a query to only include a specific case + * + * @covers \ProcessMaker\Model\AppTimeoutAction::scopeIndex() + * @test + */ + public function it_filter_a_specific_index() + { + factory(AppTimeoutAction::class)->create(); + $timeout = factory(AppTimeoutAction::class)->create(); + $this->assertCount(1, $timeout->case($timeout->APP_UID)->index($timeout->DEL_INDEX)->get()); + } + + /** + * This checks it returns information about the self service timeout in a sequential thread + * + * @covers \ProcessMaker\Model\AppTimeoutAction::cases() + * @test + */ + public function it_return_the_case_executed_once_one_thread() + { + $records = factory(AppTimeoutAction::class, 5)->create(); + foreach ($records as $row) { + $appUid = $row->APP_UID; + $delIndex = $row->DEL_INDEX; + } + + $appTimeout = new AppTimeoutAction(); + $appTimeout->setCaseUid($appUid); + $appTimeout->setIndex($delIndex); + $caseExecuted = $appTimeout->cases(); + $this->assertNotEmpty($caseExecuted); + } + + /** + * This checks it returns information about the self service timeout in a parallel thread + * + * @covers \ProcessMaker\Model\AppTimeoutAction::cases() + * @test + */ + public function it_return_the_case_executed_once_more_than_one_thread() + { + $records = factory(AppTimeoutAction::class, 5)->create(); + foreach ($records as $row) { + $appUid = $row->APP_UID; + $delIndex = $row->DEL_INDEX; + } + // Create other thread in the same case + factory(AppTimeoutAction::class)->create([ + 'APP_UID' => $appUid, + 'DEL_INDEX' => $delIndex + 1, + ]); + + $appTimeout = new AppTimeoutAction(); + $appTimeout->setCaseUid($appUid); + $appTimeout->setIndex($delIndex); + $caseExecuted = $appTimeout->cases(); + $this->assertNotEmpty($caseExecuted); + } +} diff --git a/tests/unit/workflow/engine/src/ProcessMaker/Model/ListUnassignedTest.php b/tests/unit/workflow/engine/src/ProcessMaker/Model/ListUnassignedTest.php index 9b8e3a4c6..ed76808ce 100644 --- a/tests/unit/workflow/engine/src/ProcessMaker/Model/ListUnassignedTest.php +++ b/tests/unit/workflow/engine/src/ProcessMaker/Model/ListUnassignedTest.php @@ -16,6 +16,16 @@ use Tests\TestCase; */ class ListUnassignedTest extends TestCase { + + /** + * Set up function. + */ + public function setUp() + { + parent::setUp(); + ListUnassigned::truncate(); + } + /** * Method set up. */ @@ -300,5 +310,25 @@ class ListUnassignedTest extends TestCase $result = ListUnassigned::loadList($user->USR_UID, $filters); $this->assertCount(2, $result); } + + /** + * This checks the self-service timeout cases + * + * @covers \ProcessMaker\Model\ListUnassigned::selfServiceTimeout() + * @test + */ + public function it_should_return_cases_configured_self_service_timeout() + { + // Create some cases configured the self service timeout + for ($x = 1; $x <= 5; $x++) { + $task = factory(Task::class)->states('sef_service_timeout')->create(); + factory(ListUnassigned::class)->create([ + 'TAS_UID' => $task->TAS_UID, + 'TAS_ID' => $task->TAS_ID + ]); + } + $results = ListUnassigned::selfServiceTimeout(); + $this->assertCount(5, $results); + } } diff --git a/tests/unit/workflow/engine/src/ProcessMaker/Model/TriggersTest.php b/tests/unit/workflow/engine/src/ProcessMaker/Model/TriggersTest.php index 36b4239d9..ef411aa24 100644 --- a/tests/unit/workflow/engine/src/ProcessMaker/Model/TriggersTest.php +++ b/tests/unit/workflow/engine/src/ProcessMaker/Model/TriggersTest.php @@ -2,14 +2,40 @@ namespace Tests\unit\workflow\engine\src\ProcessMaker\Model; +use G; +use Illuminate\Foundation\Testing\DatabaseTransactions; use ProcessMaker\Model\Process; use ProcessMaker\Model\Triggers; use Tests\TestCase; +/** + * Class DelegationTest + * + * @coversDefaultClass \ProcessMaker\Model\Triggers + */ class TriggersTest extends TestCase { + use DatabaseTransactions; + + /** + * Test set and get the trigger property + * + * @covers \ProcessMaker\Model\Triggers::setTrigger() + * @covers \ProcessMaker\Model\Triggers::getTrigger() + * @test + */ + public function it_set_get_trigger() + { + factory(Triggers::class)->create(); + $trigger = factory(Triggers::class)->create(); + $trigger->setTrigger($trigger->TRI_UID); + $this->assertEquals($trigger->getTrigger(), $trigger->TRI_UID); + } + /** * It tests the process scope in the trigger model + * + * @covers \ProcessMaker\Model\Triggers::scopeProcess() * @test */ public function it_should_test_process_scope_in_trigger_model() @@ -74,4 +100,48 @@ class TriggersTest extends TestCase $this->assertEquals($process[2]['PRO_UID'], $result[0]['PRO_UID']); $this->assertEquals($process[2]['PRO_UID'], $result[1]['PRO_UID']); } -} \ No newline at end of file + + /** + * Test scope a query to only include a specific case + * + * @covers \ProcessMaker\Model\Triggers::scopeTrigger() + * @test + */ + public function it_filter_specific_tasks() + { + factory(Triggers::class)->create(); + $trigger = factory(Triggers::class)->create(); + $this->assertCount(1, $trigger->trigger($trigger->TRI_UID)->get()); + } + + /** + * This checks it returns information about the trigger + * + * @covers \ProcessMaker\Model\Triggers::triggers() + * @test + */ + public function it_return_specific_trigger_information() + { + $triggers = factory(Triggers::class, 5)->create(); + $trigger = new Triggers(); + $trigger->setTrigger($triggers[0]->TRI_UID); + $triggersList = $trigger->triggers(); + $this->assertCount(1, $triggersList); + $this->assertEquals($triggers[0]->TRI_TITLE , $triggersList[0]['TRI_TITLE']); + } + + /** + * This checks it returns empty when the trigger does not exist + * + * @covers \ProcessMaker\Model\Triggers::triggers() + * @test + */ + public function it_return_empty_when_the_trigger_not_exist() + { + factory(Triggers::class)->create(); + $trigger = new Triggers(); + $trigger->setTrigger(G::generateUniqueID()); + $triggersList = $trigger->triggers(); + $this->assertEmpty($triggersList); + } +} diff --git a/tests/unit/workflow/engine/src/ProcessMaker/Util/Helpers/CalculateDateTest.php b/tests/unit/workflow/engine/src/ProcessMaker/Util/Helpers/CalculateDateTest.php new file mode 100644 index 000000000..cf5a14803 --- /dev/null +++ b/tests/unit/workflow/engine/src/ProcessMaker/Util/Helpers/CalculateDateTest.php @@ -0,0 +1,44 @@ +assertEquals('2019-10-05 12:07:40', $newDate); + } + + /** + * It tests the addition of hours + * + * @test + */ + public function it_test_adding_hours() + { + $iniDate = '2019-10-04 12:07:40'; + $newDate = calculateDate($iniDate, 'HOURS', 1); + $this->assertEquals('2019-10-04 13:07:40', $newDate); + } + + /** + * It tests the addition of minutes + * + * @test + */ + public function it_test_adding_minutes() + { + $iniDate = '2019-10-04 12:07:40'; + $newDate = calculateDate($iniDate, 'MINUTES', 10); + $this->assertEquals('2019-10-04 12:17:40', $newDate); + } +} diff --git a/tests/unit/workflow/engine/src/ProcessMaker/Util/Helpers/ChangeAbbreviationOfDirectives.php b/tests/unit/workflow/engine/src/ProcessMaker/Util/Helpers/ChangeAbbreviationOfDirectivesTest.php similarity index 94% rename from tests/unit/workflow/engine/src/ProcessMaker/Util/Helpers/ChangeAbbreviationOfDirectives.php rename to tests/unit/workflow/engine/src/ProcessMaker/Util/Helpers/ChangeAbbreviationOfDirectivesTest.php index 4c36b2fa2..fd975b42d 100644 --- a/tests/unit/workflow/engine/src/ProcessMaker/Util/Helpers/ChangeAbbreviationOfDirectives.php +++ b/tests/unit/workflow/engine/src/ProcessMaker/Util/Helpers/ChangeAbbreviationOfDirectivesTest.php @@ -4,7 +4,7 @@ namespace Tests\unit\workflow\src\ProcessMaker\Util\Helpers; use Tests\TestCase; -class ChangeAbbreviationOfDirectives extends TestCase +class ChangeAbbreviationOfDirectivesTest extends TestCase { /** * Provider to define different types of configurations in the php.ini and the result expected diff --git a/workflow/engine/bin/cron_single.php b/workflow/engine/bin/cron_single.php index d95b12694..43e22b913 100644 --- a/workflow/engine/bin/cron_single.php +++ b/workflow/engine/bin/cron_single.php @@ -17,6 +17,7 @@ use Illuminate\Foundation\Http\Kernel; /*----------------------------------********---------------------------------*/ use ProcessMaker\BusinessModel\ActionsByEmail\ResponseReader; /*----------------------------------********---------------------------------*/ +use ProcessMaker\BusinessModel\Cases; require_once __DIR__ . '/../../../gulliver/system/class.g.php'; require_once __DIR__ . '/../../../bootstrap/autoload.php'; @@ -562,6 +563,11 @@ function executeUpdateAppTitle() } } +/** + * Check if some task unassigned has enable the setting timeout and execute the trigger related + * + * @link https://wiki.processmaker.com/3.2/Tasks#Self-Service +*/ function executeCaseSelfService() { try { @@ -570,163 +576,16 @@ function executeCaseSelfService() if ($argvx != "" && strpos($argvx, "unassigned-case") === false) { return false; } - - $criteria = new Criteria("workflow"); - - //SELECT - $criteria->addSelectColumn(AppCacheViewPeer::APP_UID); - $criteria->addSelectColumn(AppCacheViewPeer::DEL_INDEX); - $criteria->addSelectColumn(AppCacheViewPeer::DEL_DELEGATE_DATE); - $criteria->addSelectColumn(AppCacheViewPeer::APP_NUMBER); - $criteria->addSelectColumn(AppCacheViewPeer::PRO_UID); - $criteria->addSelectColumn(TaskPeer::TAS_UID); - $criteria->addSelectColumn(TaskPeer::TAS_SELFSERVICE_TIME); - $criteria->addSelectColumn(TaskPeer::TAS_SELFSERVICE_TIME_UNIT); - $criteria->addSelectColumn(TaskPeer::TAS_SELFSERVICE_TRIGGER_UID); - /*----------------------------------********---------------------------------*/ - $criteria->addSelectColumn(TaskPeer::TAS_SELFSERVICE_EXECUTION); - /*----------------------------------********---------------------------------*/ - - //FROM - $condition = array(); - $condition[] = array(AppCacheViewPeer::TAS_UID, TaskPeer::TAS_UID); - $condition[] = array(TaskPeer::TAS_SELFSERVICE_TIMEOUT, 1); - $criteria->addJoinMC($condition, Criteria::LEFT_JOIN); - - //WHERE - $criteria->add(AppCacheViewPeer::USR_UID, ""); - $criteria->add(AppCacheViewPeer::DEL_THREAD_STATUS, "OPEN"); - - //QUERY - $rsCriteria = AppCacheViewPeer::doSelectRS($criteria); - $rsCriteria->setFetchmode(ResultSet::FETCHMODE_ASSOC); - setExecutionMessage("Unassigned case"); saveLog("unassignedCase", "action", "Unassigned case", "c"); - - $calendar = new Calendar(); - - while ($rsCriteria->next()) { - $row = $rsCriteria->getRow(); - $flag = false; - - $appcacheAppUid = $row["APP_UID"]; - $appcacheDelIndex = $row["DEL_INDEX"]; - $appcacheDelDelegateDate = $row["DEL_DELEGATE_DATE"]; - $appcacheAppNumber = $row["APP_NUMBER"]; - $appcacheProUid = $row["PRO_UID"]; - $taskUid = $row["TAS_UID"]; - $taskSelfServiceTime = intval($row["TAS_SELFSERVICE_TIME"]); - $taskSelfServiceTimeUnit = $row["TAS_SELFSERVICE_TIME_UNIT"]; - $taskSelfServiceTriggerUid = $row["TAS_SELFSERVICE_TRIGGER_UID"]; - /*----------------------------------********---------------------------------*/ - $taskSelfServiceJustOneExecution = $row["TAS_SELFSERVICE_EXECUTION"]; - - if ($taskSelfServiceJustOneExecution == 'ONCE') { - $criteriaSelfService = new Criteria("workflow"); - - $criteriaSelfService->add(AppTimeoutActionExecutedPeer::APP_UID, $appcacheAppUid); - $criteriaSelfService->add(AppTimeoutActionExecutedPeer::DEL_INDEX, $appcacheDelIndex); - - $querySelfService = AppTimeoutActionExecutedPeer::doSelectRS($criteriaSelfService); - $querySelfService->setFetchmode(ResultSet::FETCHMODE_ASSOC); - - if ($querySelfService->next()) { - $row = $querySelfService->getRow(); - $flag = true; //already executed - } - } - /*----------------------------------********---------------------------------*/ - - if ($calendar->pmCalendarUid == '') { - $calendar->getCalendar(null, $appcacheProUid, $taskUid); - $calendar->getCalendarData(); - } - - $dueDate = $calendar->calculateDate( - $appcacheDelDelegateDate, - $taskSelfServiceTime, - $taskSelfServiceTimeUnit //HOURS|DAYS|MINUTES - //1 - ); - - if (time() > $dueDate["DUE_DATE_SECONDS"] && $flag == false) { - $sessProcess = null; - $sessProcessSw = 0; - - //Load data - $case = new Cases(); - $appFields = $case->loadCase($appcacheAppUid); - - $appFields["APP_DATA"]["APPLICATION"] = $appcacheAppUid; - - if (isset($_SESSION["PROCESS"])) { - $sessProcess = $_SESSION["PROCESS"]; - $sessProcessSw = 1; - } - - $_SESSION["PROCESS"] = $appFields["PRO_UID"]; - - //Execute trigger - $criteriaTgr = new Criteria(); - $criteriaTgr->add(TriggersPeer::TRI_UID, $taskSelfServiceTriggerUid); - - $rsCriteriaTgr = TriggersPeer::doSelectRS($criteriaTgr); - $rsCriteriaTgr->setFetchmode(ResultSet::FETCHMODE_ASSOC); - - if ($rsCriteriaTgr->next()) { - $row = $rsCriteriaTgr->getRow(); - - if (is_array($row) && $row["TRI_TYPE"] == "SCRIPT") { - $arrayCron = unserialize(trim(@file_get_contents(PATH_DATA . "cron"))); - $arrayCron["processcTimeProcess"] = 60; //Minutes - $arrayCron["processcTimeStart"] = time(); - @file_put_contents(PATH_DATA . "cron", serialize($arrayCron)); - - //Trigger - global $oPMScript; - - $oPMScript = new PMScript(); - $oPMScript->setDataTrigger($row); - $oPMScript->setFields($appFields["APP_DATA"]); - $oPMScript->setScript($row["TRI_WEBBOT"]); - $oPMScript->setExecutedOn(PMScript::SELF_SERVICE_TIMEOUT); - $oPMScript->execute(); - - /*----------------------------------********---------------------------------*/ - //saving the case`s data if the 'Execution' is set in ONCE. - if ($taskSelfServiceJustOneExecution == "ONCE") { - $oAppTimeoutActionExecuted = new AppTimeoutActionExecuted(); - $dataSelf = array(); - $dataSelf["APP_UID"] = $appcacheAppUid; - $dataSelf["DEL_INDEX"] = $appcacheDelIndex; - $dataSelf["EXECUTION_DATE"] = time(); - $oAppTimeoutActionExecuted->create($dataSelf); - } - /*----------------------------------********---------------------------------*/ - $appFields["APP_DATA"] = array_merge($appFields["APP_DATA"], $oPMScript->aFields); - - unset($appFields['APP_STATUS']); - unset($appFields['APP_PROC_STATUS']); - unset($appFields['APP_PROC_CODE']); - unset($appFields['APP_PIN']); - $case->updateCase($appFields["APP_UID"], $appFields); - - saveLog("unassignedCase", "action", "OK Executed trigger to the case $appcacheAppNumber"); - } - } - - unset($_SESSION["PROCESS"]); - - if ($sessProcessSw == 1) { - $_SESSION["PROCESS"] = $sessProcess; - } - } + $casesExecuted = Cases::executeSelfServiceTimeout(); + foreach ($casesExecuted as $caseNumber) { + saveLog("unassignedCase", "action", "OK Executed trigger to the case $caseNumber"); } - - setExecutionResultMessage("DONE"); + setExecutionResultMessage(count($casesExecuted) . " Cases"); } catch (Exception $e) { setExecutionResultMessage("WITH ERRORS", "error"); + saveLog("unassignedCase", "action", "Unassigned case", "c"); eprintln(" '-" . $e->getMessage(), "red"); saveLog("unassignedCase", "error", "Error in unassigned case: " . $e->getMessage()); } diff --git a/workflow/engine/classes/class.pmScript.php b/workflow/engine/classes/class.pmScript.php index 71b081dfa..881fa7453 100644 --- a/workflow/engine/classes/class.pmScript.php +++ b/workflow/engine/classes/class.pmScript.php @@ -302,6 +302,9 @@ class PMScript case 'SCRIPT_TASK': $executedOn = self::SCRIPT_TASK; break; + case 'SELF_SERVICE_TIMEOUT': + $executedOn = self::SELF_SERVICE_TIMEOUT; + break; default: $executedOn = self::UNDEFINED_ORIGIN; break; diff --git a/workflow/engine/classes/model/map/AppTimeoutActionExecutedMapBuilder.php b/workflow/engine/classes/model/map/AppTimeoutActionExecutedMapBuilder.php index 54d8b92d7..6129e543b 100644 --- a/workflow/engine/classes/model/map/AppTimeoutActionExecutedMapBuilder.php +++ b/workflow/engine/classes/model/map/AppTimeoutActionExecutedMapBuilder.php @@ -67,7 +67,7 @@ class AppTimeoutActionExecutedMapBuilder $tMap->addPrimaryKey('APP_UID', 'AppUid', 'string', CreoleTypes::VARCHAR, true, 32); - $tMap->addColumn('DEL_INDEX', 'DelIndex', 'int', CreoleTypes::INTEGER, true, null); + $tMap->addPrimaryKey('DEL_INDEX', 'DelIndex', 'int', CreoleTypes::INTEGER, true, null); $tMap->addColumn('EXECUTION_DATE', 'ExecutionDate', 'int', CreoleTypes::TIMESTAMP, false, null); diff --git a/workflow/engine/classes/model/om/BaseAppTimeoutActionExecuted.php b/workflow/engine/classes/model/om/BaseAppTimeoutActionExecuted.php index 7e5888876..4d49d049b 100644 --- a/workflow/engine/classes/model/om/BaseAppTimeoutActionExecuted.php +++ b/workflow/engine/classes/model/om/BaseAppTimeoutActionExecuted.php @@ -565,28 +565,40 @@ abstract class BaseAppTimeoutActionExecuted extends BaseObject implements Persis $criteria = new Criteria(AppTimeoutActionExecutedPeer::DATABASE_NAME); $criteria->add(AppTimeoutActionExecutedPeer::APP_UID, $this->app_uid); + $criteria->add(AppTimeoutActionExecutedPeer::DEL_INDEX, $this->del_index); return $criteria; } /** - * Returns the primary key for this object (row). - * @return string + * Returns the composite primary key for this object. + * The array elements will be in same order as specified in XML. + * @return array */ public function getPrimaryKey() { - return $this->getAppUid(); + $pks = array(); + + $pks[0] = $this->getAppUid(); + + $pks[1] = $this->getDelIndex(); + + return $pks; } /** - * Generic method to set the primary key (app_uid column). + * Set the [composite] primary key. * - * @param string $key Primary key. + * @param array $keys The elements of the composite key (order must match the order in XML file). * @return void */ - public function setPrimaryKey($key) + public function setPrimaryKey($keys) { - $this->setAppUid($key); + + $this->setAppUid($keys[0]); + + $this->setDelIndex($keys[1]); + } /** @@ -602,8 +614,6 @@ abstract class BaseAppTimeoutActionExecuted extends BaseObject implements Persis public function copyInto($copyObj, $deepCopy = false) { - $copyObj->setDelIndex($this->del_index); - $copyObj->setExecutionDate($this->execution_date); @@ -611,6 +621,8 @@ abstract class BaseAppTimeoutActionExecuted extends BaseObject implements Persis $copyObj->setAppUid(''); // this is a pkey column, so set to default value + $copyObj->setDelIndex('0'); // this is a pkey column, so set to default value + } /** diff --git a/workflow/engine/classes/model/om/BaseAppTimeoutActionExecutedPeer.php b/workflow/engine/classes/model/om/BaseAppTimeoutActionExecutedPeer.php index 7d8cddc9d..83d1f9a43 100644 --- a/workflow/engine/classes/model/om/BaseAppTimeoutActionExecutedPeer.php +++ b/workflow/engine/classes/model/om/BaseAppTimeoutActionExecutedPeer.php @@ -389,6 +389,9 @@ abstract class BaseAppTimeoutActionExecutedPeer $comparison = $criteria->getComparison(AppTimeoutActionExecutedPeer::APP_UID); $selectCriteria->add(AppTimeoutActionExecutedPeer::APP_UID, $criteria->remove(AppTimeoutActionExecutedPeer::APP_UID), $comparison); + $comparison = $criteria->getComparison(AppTimeoutActionExecutedPeer::DEL_INDEX); + $selectCriteria->add(AppTimeoutActionExecutedPeer::DEL_INDEX, $criteria->remove(AppTimeoutActionExecutedPeer::DEL_INDEX), $comparison); + } else { $criteria = $values->buildCriteria(); // gets full criteria $selectCriteria = $values->buildPkeyCriteria(); // gets criteria w/ primary key(s) @@ -450,7 +453,22 @@ abstract class BaseAppTimeoutActionExecutedPeer } else { // it must be the primary key $criteria = new Criteria(self::DATABASE_NAME); - $criteria->add(AppTimeoutActionExecutedPeer::APP_UID, (array) $values, Criteria::IN); + // primary key is composite; we therefore, expect + // the primary key passed to be an array of pkey + // values + if (count($values) == count($values, COUNT_RECURSIVE)) { + // array is not multi-dimensional + $values = array($values); + } + $vals = array(); + foreach ($values as $value) { + + $vals[0][] = $value[0]; + $vals[1][] = $value[1]; + } + + $criteria->add(AppTimeoutActionExecutedPeer::APP_UID, $vals[0], Criteria::IN); + $criteria->add(AppTimeoutActionExecutedPeer::DEL_INDEX, $vals[1], Criteria::IN); } // Set the correct dbName @@ -510,51 +528,23 @@ abstract class BaseAppTimeoutActionExecutedPeer } /** - * Retrieve a single object by pkey. - * - * @param mixed $pk the primary key. - * @param Connection $con the connection to use + * Retrieve object using using composite pkey values. + * @param string $app_uid + * @param int $del_index + * @param Connection $con * @return AppTimeoutActionExecuted */ - public static function retrieveByPK($pk, $con = null) + public static function retrieveByPK($app_uid, $del_index, $con = null) { if ($con === null) { $con = Propel::getConnection(self::DATABASE_NAME); } - - $criteria = new Criteria(AppTimeoutActionExecutedPeer::DATABASE_NAME); - - $criteria->add(AppTimeoutActionExecutedPeer::APP_UID, $pk); - - + $criteria = new Criteria(); + $criteria->add(AppTimeoutActionExecutedPeer::APP_UID, $app_uid); + $criteria->add(AppTimeoutActionExecutedPeer::DEL_INDEX, $del_index); $v = AppTimeoutActionExecutedPeer::doSelect($criteria, $con); - return !empty($v) > 0 ? $v[0] : null; - } - - /** - * Retrieve multiple objects by pkey. - * - * @param array $pks List of primary keys - * @param Connection $con the connection to use - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function retrieveByPKs($pks, $con = null) - { - if ($con === null) { - $con = Propel::getConnection(self::DATABASE_NAME); - } - - $objs = null; - if (empty($pks)) { - $objs = array(); - } else { - $criteria = new Criteria(); - $criteria->add(AppTimeoutActionExecutedPeer::APP_UID, $pks, Criteria::IN); - $objs = AppTimeoutActionExecutedPeer::doSelect($criteria, $con); - } - return $objs; + return !empty($v) ? $v[0] : null; } } diff --git a/workflow/engine/config/schema.xml b/workflow/engine/config/schema.xml index e91f90a66..c9c822fe4 100755 --- a/workflow/engine/config/schema.xml +++ b/workflow/engine/config/schema.xml @@ -4303,7 +4303,7 @@ - +
diff --git a/workflow/engine/data/mysql/schema.sql b/workflow/engine/data/mysql/schema.sql index 74f04c4cf..823012b9c 100644 --- a/workflow/engine/data/mysql/schema.sql +++ b/workflow/engine/data/mysql/schema.sql @@ -2314,7 +2314,7 @@ CREATE TABLE `APP_TIMEOUT_ACTION_EXECUTED` `APP_UID` VARCHAR(32) default '' NOT NULL, `DEL_INDEX` INTEGER default 0 NOT NULL, `EXECUTION_DATE` DATETIME, - PRIMARY KEY (`APP_UID`) + PRIMARY KEY (`APP_UID`,`DEL_INDEX`) )ENGINE=InnoDB ; #----------------------------------------------------------------------------- #-- ADDONS_STORE diff --git a/workflow/engine/methods/setup/auditLog.php b/workflow/engine/methods/setup/auditLog.php index e77ec5d57..247e105d9 100644 --- a/workflow/engine/methods/setup/auditLog.php +++ b/workflow/engine/methods/setup/auditLog.php @@ -1,6 +1,6 @@ setUserLogged($_SESSION["USER_LOGGED"]); diff --git a/workflow/engine/src/ProcessMaker/BusinessModel/Cases.php b/workflow/engine/src/ProcessMaker/BusinessModel/Cases.php index b41f880f6..c90ec590e 100644 --- a/workflow/engine/src/ProcessMaker/BusinessModel/Cases.php +++ b/workflow/engine/src/ProcessMaker/BusinessModel/Cases.php @@ -17,6 +17,7 @@ use Applications; use AppNotes; use AppNotesPeer; use AppSolr; +use AppTimeoutActionExecuted; use BasePeer; use Bootstrap; use BpmnEngineServicesSearchIndex; @@ -25,6 +26,7 @@ use CasesPeer; use Configurations; use CreoleTypes; use Criteria; +use DateTime; use DBAdapter; use EntitySolrRequestData; use Exception; @@ -44,8 +46,11 @@ use ProcessMaker\Exception\UploadException; use ProcessMaker\Exception\CaseNoteUploadFile; use ProcessMaker\Model\Application as ModelApplication; use ProcessMaker\Model\AppNotes as Notes; +use ProcessMaker\Model\AppTimeoutAction; use ProcessMaker\Model\Delegation; use ProcessMaker\Model\Documents; +use ProcessMaker\Model\ListUnassigned; +use ProcessMaker\Model\Triggers; use ProcessMaker\Plugins\PluginRegistry; use ProcessMaker\Services\OAuth2\Server; use ProcessMaker\Util\DateTime as UtilDateTime; @@ -4107,4 +4112,127 @@ class Cases return true; } + + /** + * Get the cases related to the self services timeout that needs to execute the trigger related + * + * @return array + * @throws Exception + */ + public static function executeSelfServiceTimeout() + { + try { + $casesSelfService = ListUnassigned::selfServiceTimeout(); + $casesExecuted = []; + foreach ($casesSelfService as $row) { + $appUid = $row["APP_UID"]; + $appNumber = $row["APP_NUMBER"]; + $delIndex = $row["DEL_INDEX"]; + $delegateDate = $row["DEL_DELEGATE_DATE"]; + $proUid = $row["PRO_UID"]; + $taskUid = $row["TAS_UID"]; + $taskSelfServiceTime = intval($row["TAS_SELFSERVICE_TIME"]); + $taskSelfServiceTimeUnit = $row["TAS_SELFSERVICE_TIME_UNIT"]; + $triggerUid = $row["TAS_SELFSERVICE_TRIGGER_UID"]; + + /*----------------------------------********---------------------------------*/ + $typeOfExecution = $row["TAS_SELFSERVICE_EXECUTION"]; + $flagExecuteOnce = true; + // This option will be executed just once, can check if was executed before + if ($typeOfExecution == 'ONCE') { + $appTimeout = new AppTimeoutAction(); + $appTimeout->setCaseUid($appUid); + $appTimeout->setIndex($delIndex); + $caseExecuted = $appTimeout->cases(); + $flagExecuteOnce = !empty($caseExecuted) ? false : true; + } + /*----------------------------------********---------------------------------*/ + + // Add the time in the corresponding unit to the delegation date + $delegateDate = calculateDate($delegateDate, $taskSelfServiceTimeUnit, $taskSelfServiceTime); + + // Define the current time + $datetime = new DateTime('now'); + $currentDate = $datetime->format('Y-m-d H:i:s'); + + // Check if the triggers to be executed + if ($currentDate >= $delegateDate && $flagExecuteOnce) { + // Review if the session process is defined + $sessProcess = null; + $sessProcessSw = false; + if (isset($_SESSION["PROCESS"])) { + $sessProcess = $_SESSION["PROCESS"]; + $sessProcessSw = true; + } + // Load case data + $case = new ClassesCases(); + $appFields = $case->loadCase($appUid); + $appFields["APP_DATA"]["APPLICATION"] = $appUid; + // Set the process defined in the case related + $_SESSION["PROCESS"] = $appFields["PRO_UID"]; + + // Get the trigger related and execute + $triggersList = []; + if (!empty($triggerUid)) { + $trigger = new Triggers(); + $trigger->setTrigger($triggerUid); + $triggersList = $trigger->triggers(); + } + + // If the trigger exist, let's to execute + if (!empty($triggersList)) { + // Execute the trigger defined in the self service timeout + $fieldsCase['APP_DATA'] = $case->executeTriggerFromList( + $triggersList, + $appFields['APP_DATA'], + 'SELF_SERVICE_TIMEOUT', + '', + '', + '', + false + ); + + // Update the case + $case->updateCase($appUid, $fieldsCase); + + /*----------------------------------********---------------------------------*/ + if ($typeOfExecution == 'ONCE') { + // Saving the case`s data if the 'Execution' is set in ONCE. + $appTimeoutActionExecuted = new AppTimeoutActionExecuted(); + $dataSelf = []; + $dataSelf["APP_UID"] = $appUid; + $dataSelf["DEL_INDEX"] = $delIndex; + $dataSelf["EXECUTION_DATE"] = time(); + $appTimeoutActionExecuted->create($dataSelf); + } + /*----------------------------------********---------------------------------*/ + + array_push($casesExecuted, $appNumber); // Register the cases executed + + // Logging this action + $context = [ + 'appUid' => $appUid, + 'appNumber' => $appNumber, + 'triUid' => $triggerUid, + 'proUid' => $proUid, + 'tasUid' => $taskUid, + 'selfServiceTime' => $taskSelfServiceTime, + 'selfServiceTimeUnit' => $taskSelfServiceTimeUnit, + ]; + Log::channel(':TriggerExecution')->info('Timeout trigger execution', Bootstrap::context($context)); + } + + unset($_SESSION["PROCESS"]); + + if ($sessProcessSw) { + $_SESSION["PROCESS"] = $sessProcess; + } + } + } + + return $casesExecuted; + } catch (Exception $e) { + throw $e; + } + } } diff --git a/workflow/engine/src/ProcessMaker/AuditLog/AuditLog.php b/workflow/engine/src/ProcessMaker/Log/AuditLog.php similarity index 99% rename from workflow/engine/src/ProcessMaker/AuditLog/AuditLog.php rename to workflow/engine/src/ProcessMaker/Log/AuditLog.php index c840ff646..f8e6960a8 100644 --- a/workflow/engine/src/ProcessMaker/AuditLog/AuditLog.php +++ b/workflow/engine/src/ProcessMaker/Log/AuditLog.php @@ -1,6 +1,6 @@ caseUid = $caseUid; + } + + /** + * Get Case Uid + * + * @return string + */ + public function getCaseUid() + { + return $this->caseUid; + } + + /** + * Set index + * + * @param int $index + */ + public function setIndex($index) + { + $this->index = $index; + } + + /** + * Get index + * + * @return int + */ + public function getIndex() + { + return $this->index; + } + + /** + * Scope a query to get specific case uid + * + * @param \Illuminate\Database\Eloquent\Builder $query + * @param string $appUid + * + * @return \Illuminate\Database\Eloquent\Builder + */ + public function scopeCase($query, $appUid) + { + return $query->where('APP_UID', $appUid); + } + + /** + * Scope a query to get index + * + * @param \Illuminate\Database\Eloquent\Builder $query + * @param int $index + * + * @return \Illuminate\Database\Eloquent\Builder + */ + public function scopeIndex($query, $index) + { + return $query->where('DEL_INDEX', $index); + } + + /** + * Get the records related to the case and index if it was defined + * + * @return array + */ + public function cases() + { + $query = AppTimeoutAction::query()->select(); + // Specific case uid + if (!empty($this->getCaseUid())) { + $query->case($this->getCaseUid()); + } + // Specific index + if (!empty($this->getIndex())) { + $query->index($this->getIndex()); + } + $results = $query->get()->toArray(); + + return $results; + } +} diff --git a/workflow/engine/src/ProcessMaker/Model/ListUnassigned.php b/workflow/engine/src/ProcessMaker/Model/ListUnassigned.php index ecf6f43c7..3af5059bf 100644 --- a/workflow/engine/src/ProcessMaker/Model/ListUnassigned.php +++ b/workflow/engine/src/ProcessMaker/Model/ListUnassigned.php @@ -46,8 +46,9 @@ class ListUnassigned extends Model /** * Scope a query to only include specific tasks * - * @param \Illuminate\Database\Eloquent\Builder $query - * @param array $tasks + * @param \Illuminate\Database\Eloquent\Builder $query + * @param array $tasks + * * @return \Illuminate\Database\Eloquent\Builder */ public function scopeTasksIn($query, array $tasks) @@ -58,8 +59,8 @@ class ListUnassigned extends Model /** * Scope a query to only include a specific case * - * @param \Illuminate\Database\Eloquent\Builder $query - * @param integer $appNumber + * @param \Illuminate\Database\Eloquent\Builder $query + * @param integer $appNumber * * @return \Illuminate\Database\Eloquent\Builder */ @@ -71,8 +72,8 @@ class ListUnassigned extends Model /** * Scope a query to only include a specific index * - * @param \Illuminate\Database\Eloquent\Builder $query - * @param integer $index + * @param \Illuminate\Database\Eloquent\Builder $query + * @param integer $index * * @return \Illuminate\Database\Eloquent\Builder */ @@ -84,8 +85,8 @@ class ListUnassigned extends Model /** * Scope a query to only include a specific task * - * @param \Illuminate\Database\Eloquent\Builder $query - * @param integer $task + * @param \Illuminate\Database\Eloquent\Builder $query + * @param integer $task * * @return \Illuminate\Database\Eloquent\Builder */ @@ -100,7 +101,7 @@ class ListUnassigned extends Model * @param string $userUid * @param array $filters * - * @return array + * @return int */ public static function doCount($userUid, $filters = []) { @@ -125,4 +126,21 @@ class ListUnassigned extends Model return $result; } + + /** + * Get the unassigned cases related to the self service timeout + * + * @return array + */ + public static function selfServiceTimeout() + { + $query = ListUnassigned::query()->select(); + $query->join('TASK', function ($join) { + $join->on('LIST_UNASSIGNED.TAS_ID', '=', 'TASK.TAS_ID') + ->where('TASK.TAS_SELFSERVICE_TIMEOUT', '=', 1); + }); + $results = $query->get()->toArray(); + + return $results; + } } diff --git a/workflow/engine/src/ProcessMaker/Model/Triggers.php b/workflow/engine/src/ProcessMaker/Model/Triggers.php index 08a25c818..0bc920b27 100644 --- a/workflow/engine/src/ProcessMaker/Model/Triggers.php +++ b/workflow/engine/src/ProcessMaker/Model/Triggers.php @@ -10,11 +10,34 @@ class Triggers extends Model protected $table = 'TRIGGERS'; // No timestamps public $timestamps = false; - //primary key + // Primary key protected $primaryKey = 'TRI_UID'; - //No incrementing + // No incrementing public $incrementing = false; + // Filter by a specific uid + private $triUid = ''; + + /** + * Set trigger uid + * + * @param string $triUid + */ + public function setTrigger($triUid) + { + $this->triUid = $triUid; + } + + /** + * Get trigger uid + * + * @return int + */ + public function getTrigger() + { + return $this->triUid; + } + /** * Scope a query to filter an specific process * @@ -22,8 +45,37 @@ class Triggers extends Model * @param string $columns * @return \Illuminate\Database\Eloquent\Builder */ - public function scopeProcess($query, string $proUID) + public function scopeProcess($query, string $proUid) { - return $query->where('PRO_UID', $proUID); + return $query->where('PRO_UID', $proUid); + } + + /** + * Scope a query to filter an specific trigger + * + * @param \Illuminate\Database\Eloquent\Builder $query + * @param string $triUid + * @return \Illuminate\Database\Eloquent\Builder + */ + public function scopeTrigger($query, string $triUid) + { + return $query->where('TRI_UID', $triUid); + } + + /** + * Get the records + * + * @return array + */ + public function triggers() + { + $query = Triggers::query()->select(); + // Specific trigger + if (!empty($this->getTrigger())) { + $query->trigger($this->getTrigger()); + } + $results = $query->get()->toArray(); + + return $results; } } \ No newline at end of file diff --git a/workflow/engine/src/ProcessMaker/Util/helpers.php b/workflow/engine/src/ProcessMaker/Util/helpers.php index dac3f1644..c28ad2b09 100644 --- a/workflow/engine/src/ProcessMaker/Util/helpers.php +++ b/workflow/engine/src/ProcessMaker/Util/helpers.php @@ -640,3 +640,33 @@ function saveAppDocument($file, $appUid, $appDocUid, $version = 1, $upload = tru throw $e; } } + +/** + * Add a specific date minutes, hours or days + * + * @param string $iniDate + * @param string $timeUnit + * @param int $time + * + * @return string + * + * @link https://www.php.net/manual/en/datetime.modify.php + */ +function calculateDate($iniDate, $timeUnit, $time) +{ + + $datetime = new DateTime($iniDate); + switch ($timeUnit) { + case 'DAYS': + $datetime->modify('+' . $time . ' day'); + break; + case 'HOURS': + $datetime->modify('+' . $time . ' hour'); + break; + case 'MINUTES': + $datetime->modify('+' . $time . ' minutes'); + break; + } + + return $datetime->format('Y-m-d H:i:s'); +}