diff --git a/Rakefile b/Rakefile index 5a16724d1..18c9b6432 100644 --- a/Rakefile +++ b/Rakefile @@ -153,6 +153,38 @@ def buildPmdynaform(homeDir, targetDir, mode) system("rm #{pmdynaformDir}/build/appBuild.js") readyForm = "" system("echo '#{readyForm}' >> #{pmdynaformDir}/build/appBuild.js ") + system("cp #{Dir.pwd}/workflow/engine/templates/cases/cases_Step_Pmdynaform.html #{pmdynaformDir}/build/cases_Step_Pmdynaform.html") + system("cp #{Dir.pwd}/workflow/engine/templates/cases/cases_Step_Pmdynaform_Preview.html #{pmdynaformDir}/build/cases_Step_Pmdynaform_Preview.html") + + template = "" + config = File.read "#{homeDir}/config/templates.json" + json = JSON.parse config + json.each do |key| + s = "" + key["files"].each do |source| + s += File.read "#{homeDir}/#{source}" + s += "\n" + end + template += s + end + + target = "#{pmdynaformDir}/build/cases_Step_Pmdynaform.html" + html = File.read target + while html['###TEMPLATES##'] do + html['###TEMPLATES###'] = template + end + File.open(target, 'w+') do |file| + file.write html + end + + target = "#{pmdynaformDir}/build/cases_Step_Pmdynaform_Preview.html" + html = File.read target + while html['###TEMPLATES##'] do + html['###TEMPLATES###'] = template + end + File.open(target, 'w+') do |file| + file.write html + end puts "\nPmDynaform Build Finished!".magenta end diff --git a/features/backend/admin_setup/pm_user/main_tests_pm_user.feature b/features/backend/admin_setup/pm_user/main_tests_pm_user.feature index f55700f9a..918238d65 100644 --- a/features/backend/admin_setup/pm_user/main_tests_pm_user.feature +++ b/features/backend/admin_setup/pm_user/main_tests_pm_user.feature @@ -290,4 +290,11 @@ Feature: User Main Tests Then the response status code should be 200 And the response charset is "UTF-8" And the type is "array" - And the response has 63 records \ No newline at end of file + And the response has 63 records + + + Scenario: Delete a user when assigned to a process and has initiated cases + Given that I want to delete a "User" + And I request "user/24166330352d56730cdd525035621101" + Then the response status code should be 400 + And the response status message should have the following text "cannot be deleted" \ No newline at end of file diff --git a/features/backend/projects/adhoc_assignee/main_tests_adhoc_assignee.feature b/features/backend/projects/adhoc_assignee/main_tests_adhoc_assignee.feature index 122e407b2..32d020db1 100644 --- a/features/backend/projects/adhoc_assignee/main_tests_adhoc_assignee.feature +++ b/features/backend/projects/adhoc_assignee/main_tests_adhoc_assignee.feature @@ -132,4 +132,63 @@ Requirements: And the type is "array" + +#BUG 15041 Inactive Groups are display in list of available groups Accounting + +Scenario Outline: BUG 15041 Get the list of available groups- Task2 + Given I request "project//activity//adhoc-available-assignee?filter=&start=&limit=" + Then the response status code should be 200 + And the response charset is "UTF-8" + And the content type is "application/json" + And the type is "array" + And the response has records + And the "ada_uid" property in row 0 equals "" + And the "ada_type" property in row 0 equals "" + + Examples: + | test_description | project | activity | filter | start | limit | records | ada_uid | ada_type| + | "Accounting" group is available | 4224292655297723eb98691001100052 | 68911670852a22d93c22c06005808422 | Accounting | 0 | 50 | 1 | 54731929352d56741de9d42002704749 | group | + + +Scenario: BUG 15041 Update Group to disable group + Given PUT this data: + """ + { + "grp_title": "Accounting", + "grp_status": "INACTIVE" + } + """ + And I request "group/54731929352d56741de9d42002704749" + And the content type is "application/json" + Then the response status code should be 200 + And the response charset is "UTF-8" + And the type is "object" + + +Scenario Outline: BUG 15041 Get the list of available users and groups to be assigned to an activity using filter + Given I request "project//activity//adhoc-available-assignee?filter=&start=&limit=" + Then the response status code should be 200 + And the response charset is "UTF-8" + And the content type is "application/json" + And the type is "array" + And the response has records + + Examples: + | test_description | project | activity | filter | start | limit | records | + | "Accounting" group is available | 4224292655297723eb98691001100052 | 68911670852a22d93c22c06005808422 | Accounting | 0 | 50 | 0 | + + +Scenario: BUG 15041 Update Group to enable group + Given PUT this data: + """ + { + "grp_title": "Accounting", + "grp_status": "ACTIVE" + } + """ + And I request "group/54731929352d56741de9d42002704749" + And the content type is "application/json" + Then the response status code should be 200 + And the response charset is "UTF-8" + And the type is "object" \ No newline at end of file diff --git a/framework/src/templates/Exception.phtml b/framework/src/templates/Exception.phtml index 873864706..0d821fb2f 100644 --- a/framework/src/templates/Exception.phtml +++ b/framework/src/templates/Exception.phtml @@ -59,6 +59,9 @@ border-radius: 10px; border: 1px solid #ccc; } + pre { + font: 18px Georgia, "Times New Roman", Times, serif; + } @@ -67,7 +70,7 @@

RuntimeException: - +

diff --git a/workflow/engine/classes/model/BpmnData.php b/workflow/engine/classes/model/BpmnData.php index 9ddcc5bef..d64d88b50 100644 --- a/workflow/engine/classes/model/BpmnData.php +++ b/workflow/engine/classes/model/BpmnData.php @@ -14,6 +14,163 @@ require_once 'classes/model/om/BaseBpmnData.php'; * * @package classes.model */ -class BpmnData extends BaseBpmnData { +class BpmnData extends BaseBpmnData +{ + private $bound; + public function __construct($generateUid = true) + { + $this->bound = new BpmnBound(); + $this->setBoundDefaults(); + } + + public function getBound() + { + return $this->bound; + } + + private function setBoundDefaults() + { + $this->bound->setBouElementType(lcfirst(str_replace(__NAMESPACE__, '', __CLASS__))); + $this->bound->setBouElement('pm_canvas'); + $this->bound->setBouContainer('bpmnDiagram'); + + $this->bound->setPrjUid($this->getPrjUid()); + $this->bound->setElementUid($this->getDatUid()); + + $process = BpmnProcessPeer::retrieveByPK($this->getProUid()); + + if (is_object($process)) { + $this->bound->setDiaUid($process->getDiaUid()); + } + } + + public static function findOneBy($field, $value) + { + $rows = self::findAllBy($field, $value); + + return empty($rows) ? null : $rows[0]; + } + + public static function findAllBy($field, $value) + { + $c = new Criteria('workflow'); + $c->add($field, $value, Criteria::EQUAL); + + return BpmnDataPeer::doSelect($c); + } + + public static function getAll($prjUid = null, $start = null, $limit = null, $filter = '', $changeCaseTo = CASE_UPPER) + { + $c = new Criteria('workflow'); + $c->addSelectColumn("BPMN_DATA.*"); + $c->addSelectColumn("BPMN_BOUND.*"); + $c->addJoin(BpmnDataPeer::DAT_UID, BpmnBoundPeer::ELEMENT_UID, Criteria::LEFT_JOIN); + + if (! is_null($prjUid)) { + $c->add(BpmnDataPeer::PRJ_UID, $prjUid, Criteria::EQUAL); + } + + $rs = BpmnDataPeer::doSelectRS($c); + $rs->setFetchmode(\ResultSet::FETCHMODE_ASSOC); + + $data = array(); + + while ($rs->next()) { + $data[] = $changeCaseTo !== CASE_UPPER ? array_change_key_case($rs->getRow(), CASE_LOWER) : $rs->getRow(); + } + + return $data; + } + + // OVERRIDES + + public function setDatUid($DatUid) + { + parent::setDatUid($DatUid); + $this->bound->setElementUid($this->getDatUid()); + } + + public function setPrjUid($prjUid) + { + parent::setPrjUid($prjUid); + $this->bound->setPrjUid($this->getPrjUid()); + } + + public function setProUid($proUid) + { + parent::setProUid($proUid); + + $process = BpmnProcessPeer::retrieveByPK($this->getProUid()); + $this->bound->setDiaUid($process->getDiaUid()); + } + + public function save($con = null) + { + parent::save($con); + + $this->setBoundDefaults(); + + if ($this->bound->getBouUid() == "") { + $this->bound->setBouUid(\ProcessMaker\Util\Common::generateUID()); + } + + $this->bound->save($con); + } + + public function delete($con = null) + { + // first, delete the related bound object + if (! is_object($this->bound) || $this->bound->getBouUid() == "") { + $this->bound = BpmnBound::findByElement('Data', $this->getDatUid()); + } + + if (is_object($this->bound)) { + $this->bound->delete($con); + } + + parent::delete($con); + } + + public function fromArray($data, $type = BasePeer::TYPE_FIELDNAME) + { + parent::fromArray($data, $type); + + $bound = BpmnBound::findByElement('Data', $this->getDatUid()); + + if (is_object($bound)) { + $this->bound = $bound; + } else { + $this->bound = new BpmnBound(); + $this->bound->setBouUid(ProcessMaker\Util\Common::generateUID()); + } + + $this->bound->fromArray($data, BasePeer::TYPE_FIELDNAME); + } + + public function toArray($type = BasePeer::TYPE_FIELDNAME) + { + $data = parent::toArray($type); + $bouUid = $this->bound->getBouUid(); + + if (empty($bouUid)) { + $bound = BpmnBound::findByElement('Data', $this->getDatUid()); + + if (is_object($bound)) { + $this->bound = $bound; + } + } + + $data = array_merge($data, $this->bound->toArray($type)); + + return $data; + } + + public static function exists($DatUid) + { + $c = new Criteria("workflow"); + $c->add(BpmnDataPeer::DAT_UID, $DatUid); + + return BpmnDataPeer::doCount($c) > 0 ? true : false; + } } // BpmnData diff --git a/workflow/engine/classes/model/BpmnParticipant.php b/workflow/engine/classes/model/BpmnParticipant.php index 751baa018..b74b2245e 100644 --- a/workflow/engine/classes/model/BpmnParticipant.php +++ b/workflow/engine/classes/model/BpmnParticipant.php @@ -14,6 +14,163 @@ require_once 'classes/model/om/BaseBpmnParticipant.php'; * * @package classes.model */ -class BpmnParticipant extends BaseBpmnParticipant { +class BpmnParticipant extends BaseBpmnParticipant +{ + private $bound; + public function __construct($generateUid = true) + { + $this->bound = new BpmnBound(); + $this->setBoundDefaults(); + } + + public function getBound() + { + return $this->bound; + } + + private function setBoundDefaults() + { + $this->bound->setBouElementType(lcfirst(str_replace(__NAMESPACE__, '', __CLASS__))); + $this->bound->setBouElement('pm_canvas'); + $this->bound->setBouContainer('bpmnDiagram'); + + $this->bound->setPrjUid($this->getPrjUid()); + $this->bound->setElementUid($this->getParUid()); + + $process = BpmnProcessPeer::retrieveByPK($this->getProUid()); + + if (is_object($process)) { + $this->bound->setDiaUid($process->getDiaUid()); + } + } + + public static function findOneBy($field, $value) + { + $rows = self::findAllBy($field, $value); + + return empty($rows) ? null : $rows[0]; + } + + public static function findAllBy($field, $value) + { + $c = new Criteria('workflow'); + $c->add($field, $value, Criteria::EQUAL); + + return BpmnParticipantPeer::doSelect($c); + } + + public static function getAll($prjUid = null, $start = null, $limit = null, $filter = '', $changeCaseTo = CASE_UPPER) + { + $c = new Criteria('workflow'); + $c->addSelectColumn("BPMN_PARTICIPANT.*"); + $c->addSelectColumn("BPMN_BOUND.*"); + $c->addJoin(BpmnParticipantPeer::PAR_UID, BpmnBoundPeer::ELEMENT_UID, Criteria::LEFT_JOIN); + + if (! is_null($prjUid)) { + $c->add(BpmnParticipantPeer::PRJ_UID, $prjUid, Criteria::EQUAL); + } + + $rs = BpmnParticipantPeer::doSelectRS($c); + $rs->setFetchmode(\ResultSet::FETCHMODE_ASSOC); + + $participants = array(); + + while ($rs->next()) { + $participants[] = $changeCaseTo !== CASE_UPPER ? array_change_key_case($rs->getRow(), CASE_LOWER) : $rs->getRow(); + } + + return $participants; + } + + // OVERRIDES + + public function setParUid($actUid) + { + parent::setParUid($actUid); + $this->bound->setElementUid($this->getParUid()); + } + + public function setPrjUid($prjUid) + { + parent::setPrjUid($prjUid); + $this->bound->setPrjUid($this->getPrjUid()); + } + + public function setProUid($proUid) + { + parent::setProUid($proUid); + + $process = BpmnProcessPeer::retrieveByPK($this->getProUid()); + $this->bound->setDiaUid($process->getDiaUid()); + } + + public function save($con = null) + { + parent::save($con); + + $this->setBoundDefaults(); + + if ($this->bound->getBouUid() == "") { + $this->bound->setBouUid(\ProcessMaker\Util\Common::generateUID()); + } + + $this->bound->save($con); + } + + public function delete($con = null) + { + // first, delete the related bound object + if (! is_object($this->bound) || $this->bound->getBouUid() == "") { + $this->bound = BpmnBound::findByElement('Participant', $this->getParUid()); + } + + if (is_object($this->bound)) { + $this->bound->delete($con); + } + + parent::delete($con); + } + + public function fromArray($data, $type = BasePeer::TYPE_FIELDNAME) + { + parent::fromArray($data, $type); + + $bound = BpmnBound::findByElement('Participant', $this->getParUid()); + + if (is_object($bound)) { + $this->bound = $bound; + } else { + $this->bound = new BpmnBound(); + $this->bound->setBouUid(ProcessMaker\Util\Common::generateUID()); + } + + $this->bound->fromArray($data, BasePeer::TYPE_FIELDNAME); + } + + public function toArray($type = BasePeer::TYPE_FIELDNAME) + { + $data = parent::toArray($type); + $bouUid = $this->bound->getBouUid(); + + if (empty($bouUid)) { + $bound = BpmnBound::findByElement('Participant', $this->getParUid()); + + if (is_object($bound)) { + $this->bound = $bound; + } + } + + $data = array_merge($data, $this->bound->toArray($type)); + + return $data; + } + + public static function exists($actUid) + { + $c = new Criteria("workflow"); + $c->add(BpmnParticipantPeer::PAR_UID, $actUid); + + return BpmnParticipantPeer::doCount($c) > 0 ? true : false; + } } // BpmnParticipant diff --git a/workflow/engine/js/cases/core/cases_Step_Pmdynaform.js b/workflow/engine/js/cases/core/cases_Step_Pmdynaform.js new file mode 100644 index 000000000..088ec1d44 --- /dev/null +++ b/workflow/engine/js/cases/core/cases_Step_Pmdynaform.js @@ -0,0 +1,39 @@ +function dynaFormChanged (frm) { + for (var i1 = 0; i1 <= frm.elements.length - 1; i1++) { + if ((frm.elements[i1].type == "radio" || frm.elements[i1].type == "checkbox") && (frm.elements[i1].checked != frm.elements[i1].defaultChecked)) { + return true; + } + if ((frm.elements[i1].type == "textarea" || frm.elements[i1].type == "text" || frm.elements[i1].type == "file") && (frm.elements[i1].value != frm.elements[i1].defaultValue)) { + return true; + } + if (frm.elements[i1].tagName.toLowerCase() == "select") { + var selectDefaultValue = frm.elements[i1].value; + for (var i2 = 0; i2 <= frm.elements[i1].options.length - 1; i2++) { + if (frm.elements[i1].options[i2].defaultSelected) { + selectDefaultValue = frm.elements[i1].options[i2].value; + break; + } + } + if (frm.elements[i1].value != selectDefaultValue) { + return true; + } + } + } + return false; +} + +window.onload = function () { + var data = JSON.parse(jsondata); + var modelPMDynaform = new PMDynaform.Model.Form(data); + var viewPMDynaform = new PMDynaform.View.Form({tagName: "div", renderTo: $(".container"), model: modelPMDynaform}); + + if (pm_run_outside_main_app === 'true') { + if (parent.showCaseNavigatorPanel) { + parent.showCaseNavigatorPanel('DRAFT'); + } + + if (parent.setCurrent) { + parent.setCurrent(dyn_uid); + } + } +}; \ No newline at end of file diff --git a/workflow/engine/methods/cases/cases_Step.php b/workflow/engine/methods/cases/cases_Step.php index e3ba4277f..b490bae8e 100755 --- a/workflow/engine/methods/cases/cases_Step.php +++ b/workflow/engine/methods/cases/cases_Step.php @@ -257,7 +257,33 @@ try { $oDbConnections->loadAdditionalConnections(); $_SESSION['CURRENT_DYN_UID'] = $_GET['UID']; - $G_PUBLISH->AddContent( 'dynaform', 'xmlform', $_SESSION['PROCESS'] . '/' . $_GET['UID'], '', $Fields['APP_DATA'], 'cases_SaveData?UID=' . $_GET['UID'] . '&APP_UID=' . $_SESSION['APPLICATION'], '', (strtolower( $oStep->getStepMode() ) != 'edit' ? strtolower( $oStep->getStepMode() ) : '') ); + /* + * Checks the type of Dynaform. + * DYN_VERSION: 1 is classic Dynaform, 2 is Pmdynaform (responsive form). + */ + $a = new Criteria("workflow"); + $a->addSelectColumn(DynaformPeer::DYN_VERSION); + $a->addSelectColumn(DynaformPeer::DYN_CONTENT); + $a->add(DynaformPeer::DYN_UID, $_GET['UID'], Criteria::EQUAL); + $ds = ProcessPeer::doSelectRS($a); + $ds->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $ds->next(); + $row = $ds->getRow(); + if (isset($row) && $row["DYN_VERSION"] == 2) { + //$oTemplatePower = new TemplatePower(PATH_TPL . 'cases/cases_Step_Pmdynaform.html'); + $oTemplatePower = new TemplatePower(PATH_HOME . 'public_html/lib/pmdynaform/build/cases_Step_Pmdynaform.html'); + $oTemplatePower->prepare(); + $oTemplatePower->assign("JSON_DATA", $row["DYN_CONTENT"]); + $oTemplatePower->assign("CASE", $array["CASE"]); + $oTemplatePower->assign("APP_NUMBER", $array["APP_NUMBER"]); + $oTemplatePower->assign("TITLE", $array["TITLE"]); + $oTemplatePower->assign("APP_TITLE", $array["APP_TITLE"]); + $oTemplatePower->assign("PM_RUN_OUTSIDE_MAIN_APP", (!isset($_SESSION["PM_RUN_OUTSIDE_MAIN_APP"])) ? "true" : "false"); + $oTemplatePower->assign("DYN_UID", $_GET['UID']); + } else { + $G_PUBLISH->AddContent('dynaform', 'xmlform', $_SESSION['PROCESS'] . '/' . $_GET['UID'], '', $Fields['APP_DATA'], 'cases_SaveData?UID=' . $_GET['UID'] . '&APP_UID=' . $_SESSION['APPLICATION'], '', (strtolower($oStep->getStepMode()) != 'edit' ? strtolower($oStep->getStepMode()) : '')); + } + break; case 'INPUT_DOCUMENT': if ($noShowTitle == 0) { @@ -1018,29 +1044,36 @@ try { die(); } -$oHeadPublisher = & headPublisher::getSingleton(); -$oHeadPublisher->addScriptFile( "/jscore/cases/core/cases_Step.js" ); +/* + * Checks the type of Dynaform. + * DYN_VERSION: 1 is classic Dynaform, 2 is Pmdynaform (responsive form). + */ +if (isset($row) && $row["DYN_VERSION"] == 2) { + $oTemplatePower->printToScreen(); +} else { + $oHeadPublisher = & headPublisher::getSingleton(); + $oHeadPublisher->addScriptFile( "/jscore/cases/core/cases_Step.js" ); -if (!isset($_SESSION["PM_RUN_OUTSIDE_MAIN_APP"])) { - $oHeadPublisher->addScriptCode( " - if (typeof parent != 'undefined') { - if (parent.showCaseNavigatorPanel) { - parent.showCaseNavigatorPanel('$sStatus'); - } + if (!isset($_SESSION["PM_RUN_OUTSIDE_MAIN_APP"])) { + $oHeadPublisher->addScriptCode( " + if (typeof parent != 'undefined') { + if (parent.showCaseNavigatorPanel) { + parent.showCaseNavigatorPanel('$sStatus'); + } - if (parent.setCurrent) { - parent.setCurrent('" . $_GET['UID'] . "'); - } - }" ); + if (parent.setCurrent) { + parent.setCurrent('" . $_GET['UID'] . "'); + } + }" ); + } + + G::RenderPage( 'publish', 'blank' ); + + if ($_SESSION['TRIGGER_DEBUG']['ISSET']) { + G::evalJScript( ' + if (typeof showdebug != \'undefined\') { + showdebug(); + }' ); + } } - -G::RenderPage( 'publish', 'blank' ); - -if ($_SESSION['TRIGGER_DEBUG']['ISSET']) { - G::evalJScript( ' - if (typeof showdebug != \'undefined\') { - showdebug(); - }' ); -} - diff --git a/workflow/engine/src/ProcessMaker/BusinessModel/DynaForm.php b/workflow/engine/src/ProcessMaker/BusinessModel/DynaForm.php index 83244e39d..6243de63f 100644 --- a/workflow/engine/src/ProcessMaker/BusinessModel/DynaForm.php +++ b/workflow/engine/src/ProcessMaker/BusinessModel/DynaForm.php @@ -1001,5 +1001,168 @@ class DynaForm throw $e; } } + + /** + * Get data of a DynaForm + * + * @param string $projectUid Unique id of Project + * @param string $dynaFormUid Unique id of DynaForm + * + * return array Return an array with data of a DynaForm + */ + public function getDynaFormFields($projectUid, $dynaFormUid) + { + try { + $arrayVariables = array(); + //Verify data + Validator::proUid($projectUid, '$prj_uid'); + $this->throwExceptionIfNotExistsDynaForm($dynaFormUid, "", $this->arrayFieldNameForException["dynaFormUid"]); + + //Get data + $criteria = new \Criteria("workflow"); + $criteria->addSelectColumn(\DynaformPeer::DYN_CONTENT); + $criteria->add(\DynaformPeer::DYN_UID, $dynaFormUid, \Criteria::EQUAL); + $rsCriteria = \DynaformPeer::doSelectRS($criteria); + $rsCriteria->setFetchmode(\ResultSet::FETCHMODE_ASSOC); + $rsCriteria->next(); + + $aRow = $rsCriteria->getRow(); + $contentDecode = json_decode($aRow['DYN_CONTENT'],true); + + $content = $contentDecode['items'][0]['items']; + + foreach ($content as $key => $value) { + + $valueType = (isset($value[0]["valueType"])) ? $value[0]["valueType"]:null; + $maxLength = (isset($value[0]["maxLength"])) ? $value[0]["maxLength"]:null; + $label = (isset($value[0]["label"])) ? $value[0]["label"]:null; + $defaultValue = (isset($value[0]["defaultValue"])) ? $value[0]["defaultValue"]:null; + $required = (isset($value[0]["required"])) ? $value[0]["required"]:null; + $dbConnection = (isset($value[0]["dbConnection"])) ? $value[0]["dbConnection"]:null; + $sql = (isset($value[0]["sql"])) ? $value[0]["sql"]:null; + $options = (isset($value[0]["options"])) ? $value[0]["options"]:null; + //fields properties + $type = (isset($value[0]["type"])) ? $value[0]["type"]:null; + $colSpan = (isset($value[0]["colSpan"])) ? $value[0]["colSpan"]:null; + $name = (isset($value[0]["name"])) ? $value[0]["name"]:null; + $readonly = (isset($value[0]["readonly"])) ? $value[0]["readonly"]:null; + $hint = (isset($value[0]["hint"])) ? $value[0]["hint"]:null; + $dependentsField = (isset($value[0]["dependentsField"])) ? $value[0]["dependentsField"]:null; + $placeHolder = (isset($value[0]["placeHolder"])) ? $value[0]["placeHolder"]:null; + $pickType = (isset($value[0]["pickType"])) ? $value[0]["pickType"]:null; + + if (isset($value[0]["variable"])) { + $variable = $value[0]["variable"]; + + $criteria = new \Criteria("workflow"); + $criteria->addSelectColumn(\ProcessVariablesPeer::VAR_UID); + $criteria->addSelectColumn(\ProcessVariablesPeer::PRJ_UID); + $criteria->addSelectColumn(\ProcessVariablesPeer::VAR_NAME); + $criteria->addSelectColumn(\ProcessVariablesPeer::VAR_FIELD_TYPE); + $criteria->addSelectColumn(\ProcessVariablesPeer::VAR_FIELD_SIZE); + $criteria->addSelectColumn(\ProcessVariablesPeer::VAR_LABEL); + $criteria->addSelectColumn(\ProcessVariablesPeer::VAR_DBCONNECTION); + $criteria->addSelectColumn(\ProcessVariablesPeer::VAR_SQL); + $criteria->addSelectColumn(\ProcessVariablesPeer::VAR_NULL); + $criteria->addSelectColumn(\ProcessVariablesPeer::VAR_DEFAULT); + $criteria->addSelectColumn(\ProcessVariablesPeer::VAR_ACCEPTED_VALUES); + $criteria->add(\ProcessVariablesPeer::PRJ_UID, $projectUid, \Criteria::EQUAL); + $criteria->add(\ProcessVariablesPeer::VAR_NAME, $variable, \Criteria::EQUAL); + $rsCriteria = \ProcessVariablesPeer::doSelectRS($criteria); + $rsCriteria->setFetchmode(\ResultSet::FETCHMODE_ASSOC); + $rsCriteria->next(); + + while ($aRow = $rsCriteria->getRow()) { + + if ($valueType == null && $valueType == '') { + $valueTypeMerged = $aRow['VAR_FIELD_TYPE']; + } else { + $valueTypeMerged = $valueType; + } + if ($maxLength == null && $maxLength == '') { + $maxLengthMerged = (int)$aRow['VAR_FIELD_SIZE']; + } else { + $maxLengthMerged = $maxLength; + } + if ($label == null && $label == '') { + $labelMerged = $aRow['VAR_LABEL']; + } else { + $labelMerged = $label; + } + if ($defaultValue == null && $defaultValue == '') { + $defaultValueMerged = $aRow['VAR_DEFAULT']; + } else { + $defaultValueMerged = $defaultValue; + } + if ($required == null && $required == '') { + $requiredMerged = ($aRow['VAR_NULL']==1) ? true:false; + } else { + $requiredMerged = $required; + } + if ($dbConnection == null && $dbConnection == '') { + $dbConnectionMerged = $aRow['VAR_DBCONNECTION']; + } else { + $dbConnectionMerged = $dbConnection; + } + if ($sql == null && $sql == '') { + $sqlMerged = $aRow['VAR_SQL']; + } else { + $sqlMerged = $sql; + } + if ($options == null && $options == '') { + $optionsMerged = $aRow['VAR_ACCEPTED_VALUES']; + } else { + $optionsMerged = $options; + } + + $arrayVariables[] = array( 'variable' => $variable, + 'valueType' => $valueTypeMerged, + 'maxLength' => $maxLengthMerged, + 'label' => $labelMerged, + 'defaultValue' => $defaultValueMerged, + 'required' => $requiredMerged, + 'dbConnection' => $dbConnectionMerged, + 'sql' => $sqlMerged, + 'options' => $optionsMerged, + //values from fields properties + 'type' => $type, + 'colSpan' => $colSpan, + 'name' => $name, + 'readonly' => $readonly, + 'hint' => $hint, + 'dependentsField' => $dependentsField, + 'placeHolder' => $placeHolder, + 'pickType' => $pickType); + $rsCriteria->next(); + + } + + } else { + $arrayVariables[] = array( 'valueType' => $valueType, + 'maxLength' => $maxLength, + 'label' => $label, + 'defaultValue' => $defaultValue, + 'required' => $required, + 'dbConnection' => $dbConnection, + 'sql' => $sql, + 'options' => $options, + 'type' => $type, + 'colSpan' => $colSpan, + 'name' => $name, + 'readonly' => $readonly, + 'hint' => $hint, + 'dependentsField' => $dependentsField, + 'placeHolder' => $placeHolder, + 'pickType' => $pickType); + } + } + //Return + return $arrayVariables; + + } catch (\Exception $e) { + throw $e; + } + } + } diff --git a/workflow/engine/src/ProcessMaker/BusinessModel/ProcessSupervisor.php b/workflow/engine/src/ProcessMaker/BusinessModel/ProcessSupervisor.php index 052b1357d..8ed7dd426 100644 --- a/workflow/engine/src/ProcessMaker/BusinessModel/ProcessSupervisor.php +++ b/workflow/engine/src/ProcessMaker/BusinessModel/ProcessSupervisor.php @@ -40,6 +40,7 @@ class ProcessSupervisor 'grp_name' => $aRow['GRP_TITLE']); $oDataset->next(); } + // Users $oCriteria = new \Criteria('workflow'); $oCriteria->addSelectColumn(\ProcessUserPeer::USR_UID); @@ -201,7 +202,7 @@ class ProcessSupervisor $permission = $userRole->loadUserRolePermission('PROCESSMAKER', $value["USR_UID"]); foreach ($permission as $values) { if ($values["PER_CODE"] == 'PM_SUPERVISOR') { - $aRespLi[] = array('grp_uid' => $aRow['GRP_UID'], + $aRespLiGroups[] = array('grp_uid' => $aRow['GRP_UID'], 'grp_name' => $aRow['GRP_TITLE'], 'obj_type' => "group"); } @@ -210,6 +211,13 @@ class ProcessSupervisor $oDataset->next(); } } + $exclude = array(""); + for ($i = 0; $i<=count($aRespLiGroups)-1; $i++) { + if (!in_array(trim($aRespLiGroups[$i]["grp_uid"]) ,$exclude)) { + $aRespLi[] = $aRespLiGroups[$i]; + $exclude[] = trim($aRespLiGroups[$i]["grp_uid"]); + } + } $sDelimiter = \DBAdapter::getStringDelimiter(); $oCriteria = new \Criteria('workflow'); $oCriteria->addSelectColumn(\UsersPeer::USR_UID); diff --git a/workflow/engine/src/ProcessMaker/BusinessModel/Variable.php b/workflow/engine/src/ProcessMaker/BusinessModel/Variable.php index 45db27736..9338fd43f 100644 --- a/workflow/engine/src/ProcessMaker/BusinessModel/Variable.php +++ b/workflow/engine/src/ProcessMaker/BusinessModel/Variable.php @@ -372,9 +372,6 @@ class Variable throw new \Exception(\G::LoadTranslation("ID_INVALID_VALUE_ONLY_ACCEPTS_VALUES", array('$var_null','0, 1' ))); } } - if (isset($aData["VAR_DEFAULT"])) { - Validator::isString($aData['VAR_DEFAULT'], '$var_default'); - } if (isset($aData["VAR_ACCEPTED_VALUES"])) { Validator::isString($aData['VAR_ACCEPTED_VALUES'], '$var_accepted_values'); } diff --git a/workflow/engine/src/ProcessMaker/Project/Adapter/BpmnWorkflow.php b/workflow/engine/src/ProcessMaker/Project/Adapter/BpmnWorkflow.php index 638f61040..6aaa0ce29 100644 --- a/workflow/engine/src/ProcessMaker/Project/Adapter/BpmnWorkflow.php +++ b/workflow/engine/src/ProcessMaker/Project/Adapter/BpmnWorkflow.php @@ -672,6 +672,8 @@ class BpmnWorkflow extends Project\Bpmn $diagram["artifacts"] = $bwp->getArtifacts($configList); $diagram["laneset"] = $bwp->getLanesets($configList); $diagram["lanes"] = $bwp->getLanes($configList); + $diagram["data"] = $bwp->getDataCollection($configList); + $diagram["participants"] = $bwp->getParticipants($configList); $project["diagrams"][] = $diagram; } @@ -862,6 +864,7 @@ class BpmnWorkflow extends Project\Bpmn $bwp->removeGateway($gatewayData["GAT_UID"]); } } + /* * Diagram's Events Handling */ @@ -914,6 +917,99 @@ class BpmnWorkflow extends Project\Bpmn } } + /* + * Diagram's Data Handling + */ + $whiteList = array(); + foreach ($diagram["data"] as $i => $dataObjectData) { + $dataObjectData = array_change_key_case($dataObjectData, CASE_UPPER); + unset($dataObjectData["_EXTENDED"]); + + $dataObject = $bwp->getData($dataObjectData["DAT_UID"]); + + if ($forceInsert || is_null($dataObject)) { + if ($generateUid) { + //Event + unset($dataObjectData["BOU_UID"]); + + $uidOld = $dataObjectData["DAT_UID"]; + $dataObjectData["DAT_UID"] = Util\Common::generateUID(); + + $result[] = array( + "object" => "data", + "old_uid" => $uidOld, + "new_uid" => $dataObjectData["DAT_UID"] + ); + } + + $bwp->addData($dataObjectData); + } elseif (! $bwp->isEquals($dataObject, $dataObjectData)) { + $bwp->updateData($dataObjectData["DAT_UID"], $dataObjectData); + } else { + Util\Logger::log("Update Data ({$dataObjectData["DAT_UID"]}) Skipped - No changes required"); + } + + $diagram["data"][$i] = $dataObjectData; + $whiteList[] = $dataObjectData["DAT_UID"]; + } + + $dataCollection = $bwp->getDataCollection(); + + // looking for removed elements + foreach ($dataCollection as $dataObjectData) { + if (! in_array($dataObjectData["DAT_UID"], $whiteList)) { + // If it is not in the white list, then remove them + $bwp->removeData($dataObjectData["DAT_UID"]); + } + } + + //// + /* + * Diagram's Participant Handling + */ + $whiteList = array(); + foreach ($diagram["participants"] as $i => $participantData) { + $participantData = array_change_key_case($participantData, CASE_UPPER); + unset($participantData["_EXTENDED"]); + + $dataObject = $bwp->getParticipant($participantData["PAR_UID"]); + + if ($forceInsert || is_null($dataObject)) { + if ($generateUid) { + //Event + unset($participantData["BOU_UID"]); + + $uidOld = $participantData["PAR_UID"]; + $participantData["PAR_UID"] = Util\Common::generateUID(); + + $result[] = array( + "object" => "participant", + "old_uid" => $uidOld, + "new_uid" => $participantData["PAR_UID"] + ); + } + + $bwp->addParticipant($participantData); + } elseif (! $bwp->isEquals($dataObject, $participantData)) { + $bwp->updateParticipant($participantData["PAR_UID"], $participantData); + } else { + Util\Logger::log("Update Participant ({$participantData["PAR_UID"]}) Skipped - No changes required"); + } + + $diagram["participant"][$i] = $participantData; + $whiteList[] = $participantData["PAR_UID"]; + } + + $dataCollection = $bwp->getParticipants(); + + // looking for removed elements + foreach ($dataCollection as $participantData) { + if (! in_array($participantData["PAR_UID"], $whiteList)) { + // If it is not in the white list, then remove them + $bwp->removeParticipant($participantData["PAR_UID"]); + } + } + /* * Diagram's Flows Handling diff --git a/workflow/engine/src/ProcessMaker/Project/Bpmn.php b/workflow/engine/src/ProcessMaker/Project/Bpmn.php index f3da8e4ce..394d50a7a 100644 --- a/workflow/engine/src/ProcessMaker/Project/Bpmn.php +++ b/workflow/engine/src/ProcessMaker/Project/Bpmn.php @@ -24,6 +24,8 @@ use \BpmnEventPeer as EventPeer; use \BpmnGatewayPeer as GatewayPeer; use \BpmnFlowPeer as FlowPeer; use \BpmnArtifactPeer as ArtifactPeer; +use \BpmnParticipant as Participant; +use \BpmnParticipantPeer as ParticipantPeer; use \BasePeer; @@ -71,7 +73,9 @@ class Bpmn extends Handler "PRJ_UID", "PRO_UID", "BOU_ELEMENT", "BOU_ELEMENT_TYPE", "BOU_REL_POSITION", "BOU_SIZE_IDENTICAL", "DIA_UID", "BOU_UID", "ELEMENT_UID" ), - "flow" => array("PRJ_UID", "DIA_UID", "FLO_ELEMENT_DEST_PORT", "FLO_ELEMENT_ORIGIN_PORT") + "flow" => array("PRJ_UID", "DIA_UID", "FLO_ELEMENT_DEST_PORT", "FLO_ELEMENT_ORIGIN_PORT"), + "data" => array("PRJ_UID"), + "participant" => array("PRJ_UID"), ); @@ -788,6 +792,170 @@ class Bpmn extends Handler } } + //////1111 + public function addData($data) + { + // setting defaults + $data['DATA_UID'] = array_key_exists('DAT_UID', $data) ? $data['DAT_UID'] : Common::generateUID(); + try { + self::log("Add BpmnData with data: ", $data); + $bpmnData = new \BpmnData(); + $bpmnData->fromArray($data, BasePeer::TYPE_FIELDNAME); + $bpmnData->setPrjUid($this->getUid()); + $bpmnData->setProUid($this->getProcess("object")->getProUid()); + $bpmnData->save(); + self::log("Add BpmnData Success!"); + } catch (\Exception $e) { + self::log("Exception: ", $e->getMessage(), "Trace: ", $e->getTraceAsString()); + throw $e; + } + + return $bpmnData->getDatUid(); + } + + public function updateData($datUid, $data) + { + try { + self::log("Update BpmnData: $datUid", "With data: ", $data); + + $bpmnData = ArtifactPeer::retrieveByPk($datUid); + + $bpmnData->fromArray($data); + $bpmnData->save(); + + self::log("Update BpmnData Success!"); + } catch (\Exception $e) { + self::log("Exception: ", $e->getMessage(), "Trace: ", $e->getTraceAsString()); + throw $e; + } + } + + public function getData($datUid, $retType = 'array') + { + $bpmnData = ArtifactPeer::retrieveByPK($datUid); + + if ($retType != "object" && ! empty($bpmnData)) { + $bpmnData = $bpmnData->toArray(); + $bpmnData = self::filterArrayKeys($bpmnData, self::$excludeFields["data"]); + } + + return $bpmnData; + } + + public function getDataCollection($start = null, $limit = null, $filter = '', $changeCaseTo = CASE_UPPER) + { + if (is_array($start)) { + extract($start); + } + + $filter = $changeCaseTo != CASE_UPPER ? array_map("strtolower", self::$excludeFields["data"]) : self::$excludeFields["data"]; + + return self::filterCollectionArrayKeys( + \BpmnData::getAll($this->getUid(), $start, $limit, $filter, $changeCaseTo), + $filter + ); + } + + public function removeData($datUid) + { + try { + self::log("Remove BpmnData: $datUid"); + + $bpmnData = \BpmnDataPeer::retrieveByPK($datUid); + $bpmnData->delete(); + + // remove related object (flows) + Flow::removeAllRelated($datUid); + + self::log("Remove BpmnData Success!"); + } catch (\Exception $e) { + self::log("Exception: ", $e->getMessage(), "Trace: ", $e->getTraceAsString()); + throw $e; + } + } + //////2222 + + public function addParticipant($data) + { + // setting defaults + $data['PAR_UID'] = array_key_exists('PAR_UID', $data) ? $data['PAR_UID'] : Common::generateUID(); + try { + self::log("Add Participant with data: ", $data); + $participant = new Participant(); + $participant->fromArray($data, BasePeer::TYPE_FIELDNAME); + $participant->setPrjUid($this->getUid()); + $participant->setProUid($this->getProcess("object")->getProUid()); + $participant->save(); + self::log("Add Participant Success!"); + } catch (\Exception $e) { + self::log("Exception: ", $e->getMessage(), "Trace: ", $e->getTraceAsString()); + throw $e; + } + + return $participant->getParUid(); + } + + public function updateParticipant($parUid, $data) + { + try { + self::log("Update Participant: $parUid", "With data: ", $data); + + $participant = ParticipantPeer::retrieveByPk($parUid); + + $participant->fromArray($data); + $participant->save(); + + self::log("Update Participant Success!"); + } catch (\Exception $e) { + self::log("Exception: ", $e->getMessage(), "Trace: ", $e->getTraceAsString()); + throw $e; + } + } + + public function getParticipant($parUid, $retType = 'array') + { + $participant = ParticipantPeer::retrieveByPK($parUid); + + if ($retType != "object" && ! empty($participant)) { + $participant = $participant->toArray(); + $participant = self::filterArrayKeys($participant, self::$excludeFields["participant"]); + } + + return $participant; + } + + public function getParticipants($start = null, $limit = null, $filter = '', $changeCaseTo = CASE_UPPER) + { + if (is_array($start)) { + extract($start); + } + + $filter = $changeCaseTo != CASE_UPPER ? array_map("strtolower", self::$excludeFields["participant"]) : self::$excludeFields["participant"]; + + return self::filterCollectionArrayKeys( + Participant::getAll($this->getUid(), $start, $limit, $filter, $changeCaseTo), + $filter + ); + } + + public function removeParticipant($parUid) + { + try { + self::log("Remove Participant: $parUid"); + + $participant = ParticipantPeer::retrieveByPK($parUid); + $participant->delete(); + + // remove related object (flows) + Flow::removeAllRelated($parUid); + + self::log("Remove Participant Success!"); + } catch (\Exception $e) { + self::log("Exception: ", $e->getMessage(), "Trace: ", $e->getTraceAsString()); + throw $e; + } + } + public function addLane($data) { // TODO: Implement update() method. diff --git a/workflow/engine/src/ProcessMaker/Services/Api/Project/DynaForm.php b/workflow/engine/src/ProcessMaker/Services/Api/Project/DynaForm.php index a8c78edd2..612a60a86 100644 --- a/workflow/engine/src/ProcessMaker/Services/Api/Project/DynaForm.php +++ b/workflow/engine/src/ProcessMaker/Services/Api/Project/DynaForm.php @@ -92,5 +92,25 @@ class DynaForm extends Api throw (new RestException(Api::STAT_APP_EXCEPTION, $e->getMessage())); } } + + /** + * @url GET /:prj_uid/dynaform/:dyn_uid/fields + * + * @param string $dyn_uid {@min 32}{@max 32} + * @param string $prj_uid {@min 32}{@max 32} + */ + public function doGetDynaFormFields($dyn_uid, $prj_uid) + { + try { + $dynaForm = new \ProcessMaker\BusinessModel\DynaForm(); + $dynaForm->setFormatFieldNameInUppercase(false); + + $response = $dynaForm->getDynaFormFields($prj_uid, $dyn_uid); + + return $response; + } catch (\Exception $e) { + throw (new RestException(Api::STAT_APP_EXCEPTION, $e->getMessage())); + } + } } diff --git a/workflow/engine/templates/cases/cases_Step_Pmdynaform.html b/workflow/engine/templates/cases/cases_Step_Pmdynaform.html new file mode 100644 index 000000000..010e8e66b --- /dev/null +++ b/workflow/engine/templates/cases/cases_Step_Pmdynaform.html @@ -0,0 +1,37 @@ + + + + PMDynaform + + + + + + + + + + + + + + +
+ ###TEMPLATES### + + + + + + + + +
{CASE} #: {APP_NUMBER}     {TITLE}: {APP_TITLE}
+ Previous Step + Next step + + diff --git a/workflow/engine/templates/cases/cases_Step_Pmdynaform_Preview.html b/workflow/engine/templates/cases/cases_Step_Pmdynaform_Preview.html new file mode 100644 index 000000000..8f5e95589 --- /dev/null +++ b/workflow/engine/templates/cases/cases_Step_Pmdynaform_Preview.html @@ -0,0 +1,25 @@ + + + + PMDynaform + + + + + + + + + + + + + + +
+ ###TEMPLATES### + + Previous Step + Next step + +