diff --git a/app/Console/Commands/ScheduleRunCommand.php b/app/Console/Commands/ScheduleRunCommand.php
new file mode 100755
index 000000000..329a05e63
--- /dev/null
+++ b/app/Console/Commands/ScheduleRunCommand.php
@@ -0,0 +1,59 @@
+startedAt = Carbon::now();
+ $this->signature = "schedule:run";
+ $this->signature .= '
+ {--workspace=workflow : ProcessMaker Indicates the workspace to be processed.}
+ {--processmakerPath=./ : ProcessMaker path.}
+ ';
+ $this->description .= ' (ProcessMaker has extended this command)';
+ parent::__construct($schedule);
+ }
+
+
+ /**
+ * Execute the console command.
+ *
+ * @return void
+ */
+ public function handle()
+ {
+ $that = $this;
+ $workspace = $this->option('workspace');
+ if (!empty($workspace)) {
+ $webApplication = new WebApplication();
+ $webApplication->setRootDir($this->option('processmakerPath'));
+ $webApplication->loadEnvironment($workspace, false);
+ }
+ TaskScheduler::all()->each(function($p) use ($that){
+ if($p->isDue()){
+ Log::info("Si se ejecuta" . $p->expression);
+ }
+ if($p->enable == '1'){
+ $that->schedule->exec($p->body)->cron($p->expression)->between($p->startingTime, $p->endingTime);
+ }
+ });
+ parent::handle();
+ }
+}
+
+
+
diff --git a/workflow/engine/classes/model/Scheduler.php b/workflow/engine/classes/model/Scheduler.php
new file mode 100755
index 000000000..43db632c6
--- /dev/null
+++ b/workflow/engine/classes/model/Scheduler.php
@@ -0,0 +1,19 @@
+dbMap !== null);
+ }
+
+ /**
+ * Gets the databasemap this map builder built.
+ *
+ * @return the databasemap
+ */
+ public function getDatabaseMap()
+ {
+ return $this->dbMap;
+ }
+
+ /**
+ * The doBuild() method builds the DatabaseMap
+ *
+ * @return void
+ * @throws PropelException
+ */
+ public function doBuild()
+ {
+ $this->dbMap = Propel::getDatabaseMap('workflow');
+
+ $tMap = $this->dbMap->addTable('SCHEDULER');
+ $tMap->setPhpName('Scheduler');
+
+ $tMap->setUseIdGenerator(true);
+
+ $tMap->addPrimaryKey('ID', 'Id', 'string', CreoleTypes::BIGINT, true, 20);
+
+ $tMap->addColumn('TITLE', 'Title', 'string', CreoleTypes::VARCHAR, false, 255);
+
+ $tMap->addColumn('STARTINGTIME', 'Startingtime', 'string', CreoleTypes::VARCHAR, false, 100);
+
+ $tMap->addColumn('ENDINGTIME', 'Endingtime', 'string', CreoleTypes::VARCHAR, false, 100);
+
+ $tMap->addColumn('DESCRIPTION', 'Description', 'string', CreoleTypes::VARCHAR, false, 255);
+
+ $tMap->addColumn('EXPRESSION', 'Expression', 'string', CreoleTypes::VARCHAR, false, 255);
+
+ $tMap->addColumn('BODY', 'Body', 'string', CreoleTypes::VARCHAR, false, 255);
+
+ $tMap->addColumn('TYPE', 'Type', 'string', CreoleTypes::VARCHAR, false, 255);
+
+ $tMap->addColumn('CATEGORY', 'Category', 'string', CreoleTypes::VARCHAR, false, 255);
+
+ $tMap->addColumn('SYSTEM', 'System', 'int', CreoleTypes::TINYINT, false, 3);
+
+ $tMap->addColumn('TIMEZONE', 'Timezone', 'string', CreoleTypes::VARCHAR, false, 255);
+
+ $tMap->addColumn('ENABLE', 'Enable', 'int', CreoleTypes::TINYINT, false, 3);
+
+ } // doBuild()
+
+} // SchedulerMapBuilder
diff --git a/workflow/engine/config/schema.xml b/workflow/engine/config/schema.xml
old mode 100644
new mode 100755
index 725884961..0110d7fc4
--- a/workflow/engine/config/schema.xml
+++ b/workflow/engine/config/schema.xml
@@ -6008,4 +6008,22 @@
+
+
+
+
+
+
+
+
+ }
+
+
+
+
+
+
+
+
+
diff --git a/workflow/engine/methods/scheduler/index.php b/workflow/engine/methods/scheduler/index.php
new file mode 100755
index 000000000..d3717c64c
--- /dev/null
+++ b/workflow/engine/methods/scheduler/index.php
@@ -0,0 +1,31 @@
+\n" .
+ "var timezoneArray = " . G::json_encode($arrayTimeZoneId) . ";\n" .
+ "\n";
+ echo($js);
+ }
+ $js = "" .
+ "\n";
+ echo($js);
+
+ $file = file_get_contents(PATH_HOME . 'public_html/lib/taskscheduler/index.html');
+ echo $file;
+} catch (Exception $e) {
+
+}
+?>
\ No newline at end of file
diff --git a/workflow/engine/src/ProcessMaker/BusinessModel/TaskSchedulerBM.php b/workflow/engine/src/ProcessMaker/BusinessModel/TaskSchedulerBM.php
new file mode 100755
index 000000000..66b9f1fa0
--- /dev/null
+++ b/workflow/engine/src/ProcessMaker/BusinessModel/TaskSchedulerBM.php
@@ -0,0 +1,253 @@
+each(function($p){
+ if($p->isDue()){
+ Log::info("EXECUTE::" . $p->title . " -->" . $p->expression);
+ }
+ });
+ }
+
+ public static function getSchedule($category){
+ $tasks = TaskScheduler::all();
+ $count = $tasks->count();
+ if($count == 0){
+ TaskSchedulerBM::generateInitialData();
+ $tasks = TaskScheduler::all();
+ }
+ if(is_null($category)){
+ return $tasks;
+ }else{
+ return TaskScheduler::where('category', $category)->get();
+ }
+ }
+
+ public static function saveSchedule(array $request_data){
+ $task = TaskScheduler::find($request_data['id']);
+ if(isset($request_data['expression'])){
+ $task->expression = $request_data['expression'];
+ }
+ if(isset($request_data['enable'])){
+ $task->enable = $request_data['enable'];
+ }
+ if(isset($request_data['startingTime'])){
+ $task->startingTime = $request_data['startingTime'];
+ }
+ if(isset($request_data['endingTime'])){
+ $task->endingTime = $request_data['endingTime'];
+ }
+ if(isset($request_data['timezone'])){
+ $task->timezone = $request_data['timezone'];
+ }
+ $task->save();
+ return array();
+ }
+
+ public static function generateInitialData(){
+ $arraySystemConfiguration = System::getSystemConfiguration('', '', config("system.workspace"));
+ $toSave = array();
+ $services = array(
+ array(
+ "title" => "ProcessMaker Events",
+ "service" => "events",
+ "category" => "case_actions",
+ "file" => "workflow/engine/bin/cron.php",
+ "startingTime" => "0:00",
+ "endingTime" => "23:59",
+ "expression" => "* * * * *",
+ "description" => "Unpauses any case whose pause time has expired"
+ ),
+ array(
+ "title" => "ProcessMaker Scheduler",
+ "enable" => "1",
+ "service" => "scheduler",
+ "category" => "case_actions",
+ "file" => "workflow/engine/bin/cron.php",
+ "startingTime" => "0:00",
+ "endingTime" => "23:59",
+ "expression" => "* * */1 * *",
+ "description" => "Unpauses any case whose pause time has expired"
+ ),
+ array(
+ "title" => "Unpause Cases",
+ "enable" => "0",
+ "service" => "unpause",
+ "category" => "case_actions",
+ "file" => "workflow/engine/bin/cron.php",
+ "startingTime" => "0:00",
+ "endingTime" => "23:59",
+ "expression" => "* */1 * * *",
+ "description" => "Unpauses any case whose pause time has expired"
+ ),
+ array(
+ "title" => "Case Emails",
+ "enable" => "1",
+ "service" => "emails",
+ "category" => "emails_notifications",
+ "file" => "workflow/engine/bin/cron.php",
+ "startingTime" => "0:00",
+ "endingTime" => "23:59",
+ "expression" => "*/5 * * * *",
+ "description" => "Task, triggers, and actions by email notifications"
+ ),
+ array(
+ "title" => "ProcessMaker Plugins",
+ "enable" => "0",
+ "service" => "plugins",
+ "category" => "plugins",
+ "file" => "workflow/engine/bin/cron.php",
+ "startingTime" => "0:00",
+ "endingTime" => "23:59",
+ "expression" => "* * */1 * *",
+ "description" => "Custom plugins execution"
+ ),
+ array(
+ "title" => "Calculate the elapsed time",
+ "service" => "calculate",
+ "category" => "case_actions",
+ "file" => "workflow/engine/bin/cron.php",
+ "startingTime" => "0:00",
+ "endingTime" => "23:59",
+ "expression" => "* * */1 * *",
+ "description" => 'Calculates the elapsed time "according to the configured calendar" of all open tasks in active cases)'
+ ),
+ array(
+ "title" => "Calculate App data",
+ "service" => "calculateapp",
+ "category" => "case_actions",
+ "file" => "workflow/engine/bin/cron.php",
+ "startingTime" => "0:00",
+ "endingTime" => "23:59",
+ "expression" => "* * */1 * *",
+ "description" => 'Calculates the elapsed time "according to the configured calendar" of all open tasks in active cases)'
+ ),
+ array(
+ "title" => "Unassigned Case",
+ "service" => "unassigned-case",
+ "category" => "case_actions",
+ "file" => "workflow/engine/bin/cron.php",
+ "startingTime" => "0:00",
+ "endingTime" => "23:59",
+ "expression" => "* */1 * * *",
+ "description" => 'Run the trigger for self-service cases that have a configured timeout setting)'
+ ),
+ array(
+ "title" => "Clean self service tables",
+ "service" => "clean-self-service-tables",
+ "category" => "case_actions",
+ "file" => "workflow/engine/bin/cron.php",
+ "startingTime" => "0:00",
+ "endingTime" => "23:59",
+ "expression" => "* * */1 * *",
+ "description" => 'Clean unused records for Self-Service Value-Based feature. It is a maintenance command'
+ ),
+ array(
+ "title" => "Report by Users",
+ "enable" => "0",
+ "service" => "report_by_user",
+ "category" => "case_actions",
+ "file" => "workflow/engine/bin/cron.php",
+ "startingTime" => "0:00",
+ "endingTime" => "23:59",
+ "expression" => "* */1 * * *",
+ "description" => "Report by Users"
+
+ ),
+ array(
+ "title" => "Report by process",
+ "enable" => "0",
+ "service" => "report_by_process",
+ "category" => "case_actions",
+ "file" => "workflow/engine/bin/cron.php",
+ "startingTime" => "0:00",
+ "endingTime" => "23:59",
+ "expression" => "* */1 * * *",
+ "description" => "Report by process"
+ ),
+ array(
+ "title" => "Message Events",
+ "enable" => "1",
+ "service" => "",
+ "category" => "emails_notifications",
+ "file" => "workflow/engine/bin/messageeventcron.php",
+ "startingTime" => "0:00",
+ "endingTime" => "23:59",
+ "expression" => "*/5 * * * *",
+ "description" => "Intermediate and End Email Event"
+ ),
+ array(
+ "title" => "ProcessMaker timer event cron",
+ "enable" => "0",
+ "service" => "",
+ "category" => "case_actions",
+ "file" => "workflow/engine/bin/timereventcron.php",
+ "startingTime" => "0:00",
+ "endingTime" => "23:59",
+ "expression" => "* * */1 * *",
+ "description" => "ProcessMaker timer event cron"
+ ),
+ array(
+ "title" => "ProcessMaker LDAP cron",
+ "enable" => "0",
+ "service" => "",
+ "category" => "processmaker_sync",
+ "file" => "workflow/engine/bin/ldapcron.php",
+ "startingTime" => "0:00",
+ "endingTime" => "23:59",
+ "expression" => "* * */1 * *",
+ "description" => "Synchronize Advance LDAP Attributes from their settings"
+ ),
+ array(
+ "title" => "Send notifications",
+ "enable" => "1",
+ "service" => "",
+ "category" => "emails_notifications",
+ "file" => "workflow/engine/bin/sendnotificationscron.php",
+ "startingTime" => "0:00",
+ "endingTime" => "23:59",
+ "expression" => "*/5 * * * *",
+ "description" => "ProcessMaker Mobile Notifications"
+ ),
+ array(
+ "title" => "Action by emails response",
+ "enable" => "1",
+ "service" => "",
+ "category" => "emails_notifications",
+ "file" => "workflow/engine/bin/actionsByEmailEmailResponse.php",
+ "startingTime" => "0:00",
+ "endingTime" => "23:59",
+ "expression" => "*/5 * * * *",
+ "description" => "Actions by email response account email revision"
+ )
+ );
+
+ for($i = 0; $i < count($services); ++$i) {
+ $task = new TaskScheduler;
+ $task->title = $services[$i]["title"];
+ $task->category = $services[$i]["category"];
+ $task->description = $services[$i]["description"];
+ $task->startingTime = $services[$i]["startingTime"];
+ $task->endingTime = $services[$i]["endingTime"];
+ $task->body = 'su -s /bin/sh -c "php '. PATH_TRUNK . $services[$i]["file"] . " " . $services[$i]["service"] . ' +w' . config("system.workspace") . ' +force"';
+ $task->expression = $services[$i]["expression"];
+ $task->type = "shell";
+ $task->system = 1;
+ $task->timezone = $arraySystemConfiguration['time_zone'];
+ $task->enable = $services[$i]["enable"];
+ $task->startingTime = "0:00";
+ $task->endingTime = "23:59";
+ $task->save();
+ }
+ }
+}
\ No newline at end of file
diff --git a/workflow/engine/src/ProcessMaker/Model/TaskScheduler.php b/workflow/engine/src/ProcessMaker/Model/TaskScheduler.php
new file mode 100755
index 000000000..59203a654
--- /dev/null
+++ b/workflow/engine/src/ProcessMaker/Model/TaskScheduler.php
@@ -0,0 +1,26 @@
+expression)->isDue($date->toDateTimeString());
+ }
+}
diff --git a/workflow/engine/src/ProcessMaker/Services/Api/Scheduler.php b/workflow/engine/src/ProcessMaker/Services/Api/Scheduler.php
new file mode 100755
index 000000000..0f13f24f5
--- /dev/null
+++ b/workflow/engine/src/ProcessMaker/Services/Api/Scheduler.php
@@ -0,0 +1,47 @@
+getMessage());
+ }
+ }
+
+ /**
+ * @url POST
+ * @status 200
+ *
+ * @param array $request_data
+ *
+ * @return array
+ * @throws RestException
+ *
+ */
+ public function doPost(array $request_data) {
+ try {
+ return TaskSchedulerBM::saveSchedule($request_data);
+ } catch (\Exception $e) {
+ throw new RestException(Api::STAT_APP_EXCEPTION, $e->getMessage());
+ }
+ }
+}