diff --git a/Jenkinsfile b/Jenkinsfile new file mode 100644 index 000000000..b10158ce7 --- /dev/null +++ b/Jenkinsfile @@ -0,0 +1,96 @@ +#!groovy +node { + /** + * Branch should be in gitflow format. If not, then we'll abort. + */ + + if(!env.BRANCH_NAME.matches(/(feature|hotfix|release)\/.+/)) { + hipchatSend message: "${env.BRANCH_NAME} Build: Does not match gitflow naming. Aborted", room: 'engineering' + error "Job does not follow gitflow naming format." + } + // Parse out our short name and potential jira ticket. Null if not associated. If null, then for now we won't notify + // on jira ticket + def jiraTicket = env.BRANCH_NAME.find(/HOR-\d+/) + + def shortname = env.BRANCH_NAME.replace('/', '-').replace('.', '-').toLowerCase() + def dbSuffix = shortname.replace('-', '') + + echo "Building for ${env.BRANCH_NAME}" + + // Checkout source + checkout scm + + try { + stage('Start Notification') { + if(jiraTicket) { + jiraComment issueKey: jiraTicket, body: "Build ${env.BUILD_NUMBER} Starting.\nTicket will be updated once build is completed.\n\n${env.BUILD_URL}" + } + hipchatSend message: "${env.BRANCH_NAME} Build: ${env.BUILD_NUMBER} Starting.\n${env.BUILD_URL}", room: 'engineering' + } + + stage('Dependencies') { + echo "Running Composer" + sh 'composer install' + echo "Running rake" + sh 'rake' + } + + stage('Generate QA MySQL Databases') { + withCredentials([string(credentialsId: 'qa-rds-hostname', variable: 'rdsHostname'), usernamePassword(credentialsId: 'qa-rds-credentials', passwordVariable: 'rdsPassword', usernameVariable: 'rdsUsername')]) { + echo 'Dropping existing database and recreating.' + sh "mysql -h ${rdsHostname} -u ${rdsUsername} -p${rdsPassword} -e 'drop database if exists qa205${dbSuffix}; create database qa205${dbSuffix}'" + sh "mysql -h ${rdsHostname} -u ${rdsUsername} -p${rdsPassword} -e 'drop database if exists qa300${dbSuffix}; create database qa300${dbSuffix}'" + } + } + + stage('Publish to QA-205') { + sshagent(['processmaker-deploy']) { + echo 'Dropping existing files and recreating' + sh "ssh processmaker@build-qa205.processmaker.net 'rm -Rf /home/processmaker/${shortname}'" + sh "scp -r ./ processmaker@build-qa205.processmaker.net:~/${shortname}" + echo 'Creating necessary directories' + sh "ssh processmaker@build-qa205.processmaker.net 'mkdir -p /home/processmaker/${shortname}/workflow/engine/js/labels'" + sh "ssh processmaker@build-qa205.processmaker.net 'mkdir -p /home/processmaker/${shortname}/workflow/public_html/translations'" + } + } + + stage('Publish to QA-300') { + sshagent(['processmaker-deploy']) { + echo 'Dropping existing files and recreating' + sh "ssh processmaker@build-qa300.processmaker.net 'rm -Rf /home/processmaker/${shortname}'" + sh "scp -r ./ processmaker@build-qa300.processmaker.net:~/${shortname}" + echo 'Creating necessary directories' + sh "ssh processmaker@build-qa300.processmaker.net 'mkdir -p /home/processmaker/${shortname}/workflow/engine/js/labels'" + sh "ssh processmaker@build-qa300.processmaker.net 'mkdir -p /home/processmaker/${shortname}/workflow/public_html/translations'" + } + } + + stage('Success Notification') { + withCredentials([string(credentialsId: 'qa-rds-hostname', variable: 'rdsHostname'), usernamePassword(credentialsId: 'qa-rds-credentials', passwordVariable: 'rdsPassword', usernameVariable: 'rdsUsername')]) { + if(jiraTicket) { + jiraComment issueKey: jiraTicket, body: "" + + "Build ${env.BUILD_NUMBER} Completed.\n" + + "5.6 Build: https://${shortname}.qa205.processmaker.net\n" + + "Database Host: ${rdsHostname}\n" + + "Username: ${rdsUsername}\n" + + "Password: ${rdsPassword}\n" + + "Database: qa205${dbSuffix}\n\n" + + "7.0 Build: https://${shortname}.qa300.processmaker.net\n" + + "Database Host: ${rdsHostname}\n" + + "Username: ${rdsUsername}\n" + + "Password: ${rdsPassword}\n" + + "Database: qa300${dbSuffix}\n\n" + + "${env.BUILD_URL}" + } + hipchatSend room: 'engineering', message: "" + + "${env.BRANCH_NAME} Build: ${env.BUILD_NUMBER} Completed.\n" + + "${env.BUILD_URL}" + } + } + } catch(error) { + if(jiraTicket) { + jiraComment issueKey: jiraTicket, body: "Build ${env.BUILD_NUMBER} Failed: ${error}\n\n${env.BUILD_URL}" + } + hipchatSend message: "${env.BRANCH_NAME} Build: ${env.BUILD_NUMBER} Failed: ${error}\n${env.BUILD_URL}", room: 'engineering' + } +} \ No newline at end of file diff --git a/gulliver/system/class.g.php b/gulliver/system/class.g.php index 6b593fb25..39e22b3ff 100644 --- a/gulliver/system/class.g.php +++ b/gulliver/system/class.g.php @@ -1232,8 +1232,10 @@ class G case 'txt': G::sendHeaders( $filename, 'text/html', $download, $downloadFileName ); break; - case 'doc': case 'pdf': + G::sendHeaders( $filename, 'application/pdf', $download, $downloadFileName ); + break; + case 'doc': case 'pm': case 'po': G::sendHeaders( $filename, 'application/octet-stream', $download, $downloadFileName ); @@ -1283,12 +1285,14 @@ class G { if ($download) { if ($downloadFileName == '') { - $aAux = explode( '/', $filename ); - $downloadFileName = $aAux[count( $aAux ) - 1]; + $aAux = explode('/', $filename); + $downloadFileName = $aAux[count($aAux) - 1]; } - header( 'Content-Disposition: attachment; filename="' . $downloadFileName . '"' ); + header('Content-Disposition: attachment; filename="' . $downloadFileName . '"'); + } else { + header('Content-Disposition: inline; filename="' . $downloadFileName . '"'); } - header( 'Content-Type: ' . $contentType ); + header('Content-Type: ' . $contentType); //if userAgent (BROWSER) is MSIE we need special headers to avoid MSIE behaivor. $userAgent = strtolower( $_SERVER['HTTP_USER_AGENT'] ); diff --git a/workflow/engine/classes/class.case.php b/workflow/engine/classes/class.case.php index 8a938d803..6d56a8544 100644 --- a/workflow/engine/classes/class.case.php +++ b/workflow/engine/classes/class.case.php @@ -4433,6 +4433,11 @@ class Cases /*----------------------------------********---------------------------------*/ $this->getExecuteTriggerProcess($sApplicationUID, 'REASSIGNED'); + + //Delete record of the table LIST_UNASSIGNED + $unassigned = new ListUnassigned(); + $unassigned->remove($sApplicationUID, $iDelegation); + return true; } diff --git a/workflow/engine/classes/class.pmDynaform.php b/workflow/engine/classes/class.pmDynaform.php index 125166c24..09413f3bb 100644 --- a/workflow/engine/classes/class.pmDynaform.php +++ b/workflow/engine/classes/class.pmDynaform.php @@ -27,6 +27,7 @@ class pmDynaform private $context = array(); private $dataSources = null; private $databaseProviders = null; + private $propertiesToExclude = array(); public function __construct($fields = array()) { @@ -37,6 +38,7 @@ class pmDynaform $this->serverConf = &serverConf::getSingleton(); $this->isRTL = ($this->serverConf->isRtl(SYS_LANG)) ? 'true' : 'false'; $this->fields = $fields; + $this->propertiesToExclude = array('dataVariable'); $this->getDynaform(); $this->getDynaforms(); $this->synchronizeSubDynaform(); @@ -196,11 +198,13 @@ class pmDynaform if (is_string($value) && in_array(substr($value, 0, 2), $prefixs)) { $triggerValue = substr($value, 2); if (isset($this->fields["APP_DATA"][$triggerValue])) { - if ($key !== "dataVariable") { + if (!in_array($key, $this->propertiesToExclude)) { $json->{$key} = $this->fields["APP_DATA"][$triggerValue]; } } else { - $json->{$key} = ""; + if (!in_array($key, $this->propertiesToExclude)) { + $json->{$key} = ""; + } } } //set properties from 'formInstance' variable @@ -1909,6 +1913,12 @@ class pmDynaform if ($validatorClass !== null) { $validatorClass->validatePost($post); } + //Clears the data in the appData for grids + if (array_key_exists($json->id, $this->fields) && $json->type === 'grid' && + !array_key_exists($json->id, $post) + ) { + $post[$json->variable] = array(array()); + } } }; $json = G::json_decode($this->record["DYN_CONTENT"]); diff --git a/workflow/engine/classes/model/AppDelegation.php b/workflow/engine/classes/model/AppDelegation.php index 7feeaa1df..abb930c01 100644 --- a/workflow/engine/classes/model/AppDelegation.php +++ b/workflow/engine/classes/model/AppDelegation.php @@ -442,6 +442,7 @@ class AppDelegation extends BaseAppDelegation //Get Task properties $task = TaskPeer::retrieveByPK( $this->getTasUid() ); + $aData = array(); $aData['TAS_UID'] = $this->getTasUid(); //Added to allow User defined Timing Control at Run time from Derivation screen if (isset( $sNextTasParam['NEXT_TASK']['TAS_TRANSFER_HIDDEN_FLY'] ) && $sNextTasParam['NEXT_TASK']['TAS_TRANSFER_HIDDEN_FLY'] == 'true') { @@ -471,7 +472,7 @@ class AppDelegation extends BaseAppDelegation //Calendar - Use the dates class to calculate dates $calendar = new calendar(); - $arrayCalendarData = array(); + $arrayCalendarData = $calendar->getCalendarData($aCalendarUID); if ($calendar->pmCalendarUid == "") { $calendar->getCalendar(null, $this->getProUid(), $this->getTasUid()); @@ -480,11 +481,11 @@ class AppDelegation extends BaseAppDelegation } //Due date - /*$iDueDate = $calendar->calculateDate( $this->getDelDelegateDate(), $aData['TAS_DURATION'], $aData['TAS_TIMEUNIT'] //hours or days, ( we only accept this two types or maybe weeks - );*/ - $dueDate = $calendar->dashCalculateDate($this->getDelDelegateDate(), $aData["TAS_DURATION"], $aData["TAS_TIMEUNIT"], $arrayCalendarData); + $initDate = $this->getDelDelegateDate(); + $timeZone = \ProcessMaker\Util\DateTime::convertUtcToTimeZone($initDate); + $dueDate = $calendar->dashCalculateDate($timeZone, $aData["TAS_DURATION"], $aData["TAS_TIMEUNIT"], $arrayCalendarData); - //Return + $dueDate = \ProcessMaker\Util\DateTime::convertDataToUtc($dueDate); return $dueDate; } diff --git a/workflow/engine/methods/cases/cases_Step.php b/workflow/engine/methods/cases/cases_Step.php index 8b1b1ff3f..24f085044 100644 --- a/workflow/engine/methods/cases/cases_Step.php +++ b/workflow/engine/methods/cases/cases_Step.php @@ -1009,7 +1009,7 @@ try { $aFields['TASK'][$sKey]['NEXT_TASK']['TAS_TRANSFER_HIDDEN_FLY'] = ""; if ($aValues['NEXT_TASK']['TAS_TRANSFER_FLY'] == 'true') { $aFields['TASK'][$sKey]['NEXT_TASK']['TAS_DURATION'] = ''; - $hoursSelected = $daysSelected = ''; + $hoursSelected = $daysSelected = $minSelected = ''; if ($aFields['TASK'][$sKey]['NEXT_TASK']['TAS_TIMEUNIT'] == 'HOURS') { $hoursSelected = "selected = 'selected'"; } else { diff --git a/workflow/engine/src/ProcessMaker/Core/RoutingScreen.php b/workflow/engine/src/ProcessMaker/Core/RoutingScreen.php index d6dd9c209..dafe61a98 100644 --- a/workflow/engine/src/ProcessMaker/Core/RoutingScreen.php +++ b/workflow/engine/src/ProcessMaker/Core/RoutingScreen.php @@ -65,6 +65,9 @@ class RoutingScreen extends \Derivation } else { $aDataMerged[$key]['NEXT_ROUTING'][] = $post[$i]; } + if (isset($post[$i]['NEXT_TASK'])) { + $aDataMerged[$key]['NEXT_TASK'] = $post[$i]['NEXT_TASK']; + } } } }