Merge remote-tracking branch 'upstream/release/3.2' into bugfix/FBI-1501

This commit is contained in:
Rodrigo Quelca
2017-01-31 06:10:52 -05:00
15 changed files with 203 additions and 133 deletions

95
Jenkinsfile vendored Normal file
View File

@@ -0,0 +1,95 @@
#!groovy
node {
/**
* Branch should be in gitflow format. If not, then we'll abort.
*/
if(!env.BRANCH_NAME.matches(/(feature|hotfix|bugfix|release)\/.+/) && !env.BRANCH_NAME.matches(/^PR-.*$/)) {
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'
}
}

View File

@@ -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'] );

View File

@@ -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;
}

View File

@@ -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"]);

View File

@@ -527,13 +527,27 @@ function WSLogin ($user, $pass, $endpoint = "")
function WSOpen ($force = false)
{
if (isset( $_SESSION["WS_SESSION_ID"] ) || $force) {
$optionsHeaders = array(
"cache_wsdl" => WSDL_CACHE_NONE,
"soap_version" => SOAP_1_1,
"trace" => 1,
"stream_context" => stream_context_create(
array(
'ssl' => array(
'verify_peer' => 0,
'verify_peer_name' => 0
)
)
)
);
if (! isset( $_SESSION["WS_END_POINT"] )) {
$defaultEndpoint = "http://" . $_SERVER["SERVER_NAME"] . ":" . $_SERVER["SERVER_PORT"] . "/sys" . SYS_SYS . "/en/classic/services/wsdl2";
$defaultEndpoint = $_SERVER["REQUEST_SCHEME"] . "://" . $_SERVER["SERVER_NAME"] . ":" . $_SERVER["SERVER_PORT"] . "/sys" . SYS_SYS . "/en/classic/services/wsdl2";
}
$endpoint = isset( $_SESSION["WS_END_POINT"] ) ? $_SESSION["WS_END_POINT"] : $defaultEndpoint;
$client = new SoapClient( $endpoint );
$client = new SoapClient( $endpoint, $optionsHeaders);
return $client;
} else {

View File

@@ -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;
}

View File

@@ -64,6 +64,30 @@ if ($actionAjax == "userValues") {
$users = filterUserListArray($users, $query);
//now get users, just for the Search action
switch ($action) {
case 'to_reassign':
$cUsers = $oAppCache->getToReassignListCriteria(null);
$cUsers->addSelectColumn(AppCacheViewPeer::USR_UID);
if (g::MySQLSintaxis()) {
$cUsers->addGroupByColumn(AppCacheViewPeer::USR_UID);
}
if (!is_null($query)) {
$filters = $cUsers->getNewCriterion(UsersPeer::USR_FIRSTNAME, '%' . $query . '%', Criteria::LIKE)->addOr(
$cUsers->getNewCriterion(UsersPeer::USR_LASTNAME, '%' . $query . '%', Criteria::LIKE)->addOr(
$cUsers->getNewCriterion(UsersPeer::USR_USERNAME, '%' . $query . '%', Criteria::LIKE)));
$cUsers->addAnd($filters);
}
$cUsers->setLimit(20);
$cUsers->addAscendingOrderByColumn(AppCacheViewPeer::APP_CURRENT_USER);
$oDataset = AppCacheViewPeer::doSelectRS($cUsers, Propel::getDbConnection('workflow_ro'));
$oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC);
$oDataset->next();
while ($aRow = $oDataset->getRow()) {
$users[] = array("USR_UID" => $aRow['USR_UID'], "USR_FULLNAME" => $aRow['APP_CURRENT_USER']);
$oDataset->next();
}
break;
case 'search_simple':
case 'search':
G::LoadClass("configuration");

View File

@@ -9,9 +9,6 @@ switch ($action) {
case 'getAllCounters':
getAllCounters();
break;
case 'getProcess':
getProcess();
break;
/*----------------------------------********---------------------------------*/
case 'getAllCountersEnterprise':
getAllCountersEnterprise();
@@ -218,64 +215,6 @@ function getLoadTreeMenuData ()
print $xml;*/
}
// get the process summary of specific case list type,
function getProcess ()
{
global $G_TMP_MENU;
global $userId;
if (! isset( $_GET['item'] )) {
die();
}
$oMenu = new Menu();
$oMenu->load( 'cases' );
$type = $_GET['item'];
$oCases = new AppCacheView();
$aTypesID = array ();
$aTypesID['CASES_INBOX'] = 'to_do';
$aTypesID['CASES_DRAFT'] = 'draft';
$aTypesID['CASES_CANCELLED'] = 'cancelled';
$aTypesID['CASES_SENT'] = 'sent';
$aTypesID['CASES_PAUSED'] = 'paused';
$aTypesID['CASES_COMPLETED'] = 'completed';
$aTypesID['CASES_SELFSERVICE'] = 'selfservice';
//$aTypesID['CASES_TO_REVISE'] = 'to_revise';
//$aTypesID['CASES_TO_REASSIGN'] = 'to_reassign';
$aTypesID = Array ('CASES_INBOX' => 'to_do','CASES_DRAFT' => 'draft','CASES_CANCELLED' => 'cancelled','CASES_SENT' => 'sent','CASES_PAUSED' => 'paused','CASES_COMPLETED' => 'completed','CASES_SELFSERVICE' => 'selfservice','CASES_TO_REVISE' => 'to_revise','CASES_TO_REASSIGN' => 'to_reassign');
$aCount = $oCases->getAllCounters( Array ($aTypesID[$type]
), $userId, true );
$response = Array ();
//disabling the summary...
/*
$i=0;
foreach($aCount[$aTypesID[$type]]['sumary'] as $PRO_UID=>$process){
//{"text":"state","id":"src\/state","cls":"folder", loaded:true},
$response[$i] = new stdClass();
$response[$i]->text = $process['name'] . ' ('.$process['count'].')';
$response[$i]->id = $process['name'];
$response[$i]->cls = 'folder';
$response[$i]->loaded = true;
$i++;
}
*/
//ordering
/*for($i=0; $i<=count($response)-1; $i++){
for($j=$i+1; $j<=count($response); $j++){
echo $response[$j]->text .'<'. $response[$i]->text;
if($response[$j]->text[0] < $response[$i]->text[0]){
$x = $response[$i];
$response[$i] = $response[$j];
$response[$j] = $x;
}
}
}*/
echo G::json_encode( $response );
}
/*----------------------------------********---------------------------------*/
function getAllCountersEnterprise()
{

View File

@@ -1009,7 +1009,7 @@ try {
$aFields['TASK'][$sKey]['NEXT_TASK']['TAS_TRANSFER_HIDDEN_FLY'] = "<input type=hidden name='" . $hiddenName . "[NEXT_TASK][TAS_TRANSFER_HIDDEN_FLY]' id='" . $hiddenName . "[NEXT_TASK][TAS_TRANSFER_HIDDEN_FLY]' value=" . $aValues['NEXT_TASK']['TAS_TRANSFER_FLY'] . ">";
if ($aValues['NEXT_TASK']['TAS_TRANSFER_FLY'] == 'true') {
$aFields['TASK'][$sKey]['NEXT_TASK']['TAS_DURATION'] = '<input type="text" size="5" name="' . $hiddenName . '[NEXT_TASK][TAS_DURATION]" id="' . $hiddenName . '[NEXT_TASK][TAS_DURATION]" value="' . $aValues['NEXT_TASK']['TAS_DURATION'] . '">';
$hoursSelected = $daysSelected = '';
$hoursSelected = $daysSelected = $minSelected = '';
if ($aFields['TASK'][$sKey]['NEXT_TASK']['TAS_TIMEUNIT'] == 'HOURS') {
$hoursSelected = "selected = 'selected'";
} else {

View File

@@ -199,11 +199,6 @@ class NotificationDevice
$devices = $oNoti->loadUsersArrayId($userIds);
} else {
$devices = $oNoti->loadByUsersId($userIds);
$lists = new \ProcessMaker\BusinessModel\Lists();
$counter = $lists->getCounters($userIds);
$light = new \ProcessMaker\Services\Api\Light();
$result = $light->parserCountersCases($counter);
$data['counters'] = $result;
}
$devicesAndroidIds = array();

View File

@@ -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'];
}
}
}
}

View File

@@ -30,6 +30,31 @@ class Light extends Api
'delRiskDate'
];
public function __isAllowed()
{
try {
$methodName = $this->restler->apiMethodInfo->methodName;
$arrayArgs = $this->restler->apiMethodInfo->arguments;
switch ($methodName) {
case 'doIfAlreadyRoute':
$applicationUid = $this->parameters[$arrayArgs['app_uid']];
$delIndex = $this->parameters[$arrayArgs['cas_index']];
$userUid = $this->getUserId();
//Check if the user has the case
$appDelegation = new \AppDelegation();
$aCurUser = $appDelegation->getCurrentUsers($applicationUid, $delIndex);
if (!empty($aCurUser) && in_array($userUid, $aCurUser)) {
return true;
}
return false;
break;
}
return false;
} catch (\Exception $e) {
throw new RestException(Api::STAT_APP_EXCEPTION, $e->getMessage());
}
}
/**
* Constructor of the class
*
@@ -793,6 +818,8 @@ class Light extends Api
/**
* Get Already Route
*
* @access protected
* @class AccessControl {@className \ProcessMaker\Services\Api\Light}
* @param string $app_uid {@min 1}{@max 32}
* @param int $cas_index
*

View File

@@ -2050,7 +2050,8 @@ Ext.onReady ( function() {
btnReassign,
"->",
_("ID_USER"),
comboAllUsers,
suggestUser,
resetSuggestButton,
"-",
_("ID_CATEGORY"),
comboCategory,

View File

@@ -16,7 +16,6 @@ var propStore;
var triggerStore;
var debugVariablesFilter;
var ReloadTreeMenuItemDetail;
var NOTIFIER_FLAG = false;
var result;
var _action = '';
@@ -258,39 +257,6 @@ Ext.onReady(function(){
}
});
var treeMenuItemDetail = new Ext.tree.TreePanel({
id: 'tree_menuItem_detail',
region: 'south',
animate:true,
autoScroll:true,
loader: new Ext.tree.TreeLoader({
dataUrl:'casesMenuLoader?action=getProcess'
}),
enableDD:true,
containerScroll: true,
border: false,
width: 250,
height: 120,
dropConfig: {appendOnly:true},
collapsible: true,
split: true,
margins: '0 2 2 2',
cmargins: '2 2 2 2',
rootVisible: false,
root: new Ext.tree.AsyncTreeNode()/*,
tbar: [{
text: 'reload',
handler: ReloadTreeMenuItemDetail
}]*/
});
ReloadTreeMenuItemDetail = function(params){
treeMenuItemDetail.loader.dataUrl = 'casesMenuLoader?action=getProcess&item='+params.item;
treeMenuItemDetail.root.reload();
}
// set the root node
var root = new Ext.tree.AsyncTreeNode({
text: 'Ext JS',
@@ -300,8 +266,6 @@ Ext.onReady(function(){
expanded:true
});
treeMenuItemDetail.setRootNode(root);
mainMenu = new Ext.Panel({
id:'menuTreePanel',
title: '',
@@ -317,8 +281,7 @@ Ext.onReady(function(){
margins: '0 0 0 2',
items: [
treeMenuItems,
treeMenuItemDetail
treeMenuItems
]
});
mainMenu.setTitle("<div style=\"height: 18px;\"><a href=\"javascript:;\"><img id=\"refreshNotifiers\" src=\"/images/refresh.gif\" onclick=\"updateCasesTree(); updateCasesView();\" /></a></div>");
@@ -530,15 +493,6 @@ Ext.onReady(function(){
menuPanelC.hide();
menuPanelC.ownerCt.doLayout();
/**show*/
//w.show();
//w.ownerCt.doLayout();
//w.expand();
var menuPanelDetail = Ext.getCmp('tree_menuItem_detail');
menuPanelDetail.hide();
menuPanelDetail.ownerCt.doLayout();
//FORMATS.casesListRefreshTime is in seconds
setTimeout("timer()", parseInt(FORMATS.casesListRefreshTime) * 1000);
});
@@ -571,9 +525,7 @@ function updateCasesTree() {
document.getElementById('refreshNotifiers').src = '/images/ext/default/grid/loading.gif';
itemsTypes = Array('CASES_INBOX', 'CASES_DRAFT', 'CASES_CANCELLED', 'CASES_SENT', 'CASES_PAUSED', 'CASES_COMPLETED', 'CASES_SELFSERVICE');
if (currentSelectedTreeMenuItem) {
ReloadTreeMenuItemDetail({item: currentSelectedTreeMenuItem});
}
Ext.Ajax.request({
url: urlProxy + Math.random(),
success: function (response) {

View File

@@ -32,7 +32,7 @@
var storeUsersToReassign = new Ext.data.Store({
remoteSort: false,
autoLoad:true,
autoLoad:false,
proxy : proxyUsersToReassignList,
reader: readerUsersToReassignList,
writer: writerUsersToReassignList, // <-- plug a DataWriter into the store just as you would a Reader