Skip to content
Snippets Groups Projects
ReportRun.php 232 KiB
Newer Older
Prasad's avatar
Prasad committed
<?php
/*+********************************************************************************
 * The contents of this file are subject to the vtiger CRM Public License Version 1.0
 * ("License"); You may not use this file except in compliance with the License
 * The Original Code is:  vtiger CRM Open Source
 * The Initial Developer of the Original Code is vtiger.
 * Portions created by vtiger are Copyright (C) vtiger.
 * All Rights Reserved.
 ********************************************************************************/
Prasad's avatar
Prasad committed

Prasad's avatar
Prasad committed
global $calpath;
Prasad's avatar
Prasad committed
global $app_strings, $mod_strings;
Prasad's avatar
Prasad committed
global $theme;
global $log;

Prasad's avatar
Prasad committed
$theme_path = "themes/" . $theme . "/";
$image_path = $theme_path . "images/";
Prasad's avatar
Prasad committed
require_once('include/database/PearDatabase.php');
require_once('data/CRMEntity.php');
require_once("modules/Reports/Reports.php");
require_once 'modules/Reports/ReportUtils.php';
require_once("vtlib/Vtiger/Module.php");
require_once('modules/Vtiger/helpers/Util.php');
require_once('include/RelatedListView.php');
require_once('vtlib/Vtiger/PDF/TCPDF.php');
Prasad's avatar
Prasad committed

/*
 * Helper class to determine the associative dependency between tables.
 */
class ReportRunQueryDependencyMatrix {
Prasad's avatar
Prasad committed

Prasad's avatar
Prasad committed
	protected $matrix = array();
	protected $computedMatrix = null;

	function setDependency($table, array $dependents) {
		$this->matrix[$table] = $dependents;
	}

	function addDependency($table, $dependent) {
		if (isset($this->matrix[$table]) && !in_array($dependent, $this->matrix[$table])) {
			$this->matrix[$table][] = $dependent;
		} else {
			$this->setDependency($table, array($dependent));
		}
	}

	function getDependents($table) {
		$this->computeDependencies();
Prasad's avatar
Prasad committed
		return isset($this->computedMatrix[$table]) ? $this->computedMatrix[$table] : array();
Prasad's avatar
Prasad committed
	}

	protected function computeDependencies() {
Prasad's avatar
Prasad committed
		if ($this->computedMatrix !== null)
			return;
Prasad's avatar
Prasad committed

		$this->computedMatrix = array();
		foreach ($this->matrix as $key => $values) {
Prasad's avatar
Prasad committed
			$this->computedMatrix[$key] = $this->computeDependencyForKey($key, $values);
Prasad's avatar
Prasad committed
		}
	}
Prasad's avatar
Prasad committed

Prasad's avatar
Prasad committed
	protected function computeDependencyForKey($key, $values) {
		$merged = array();
		foreach ($values as $value) {
			$merged[] = $value;
			if (isset($this->matrix[$value])) {
				$merged = array_merge($merged, $this->matrix[$value]);
			}
		}
		return $merged;
	}
Prasad's avatar
Prasad committed

Prasad's avatar
Prasad committed
}

class ReportRunQueryPlanner {
Prasad's avatar
Prasad committed

Prasad's avatar
Prasad committed
	// Turn-off the query planning to revert back - backward compatiblity
	protected $disablePlanner = false;
	protected $tables = array();
	protected $tempTables = array();
	protected $tempTablesInitialized = false;
	// Turn-off in case the query result turns-out to be wrong.
	protected $allowTempTables = true;
	protected $tempTablePrefix = 'vtiger_reptmptbl_';
Prasad's avatar
Prasad committed
	protected static $tempTableCounter = 0;
Prasad's avatar
Prasad committed
	protected $registeredCleanup = false;
Prasad's avatar
Prasad committed
	var $reportRun = false;
Prasad's avatar
Prasad committed

Prasad's avatar
Prasad committed
	function addTable($table) {
		if (!empty($table))
			$this->tables[$table] = $table;
Prasad's avatar
Prasad committed
	}

Prasad's avatar
Prasad committed
	function requireTable($table, $dependencies = null) {
Prasad's avatar
Prasad committed

		if ($this->disablePlanner) {
			return true;
		}

		if (isset($this->tables[$table])) {
			return true;
		}
		if (is_array($dependencies)) {
			foreach ($dependencies as $dependentTable) {
				if (isset($this->tables[$dependentTable])) {
					return true;
				}
			}
		} else if ($dependencies instanceof ReportRunQueryDependencyMatrix) {
			$dependents = $dependencies->getDependents($table);
			if ($dependents) {
				return php7_count(array_intersect($this->tables, $dependents)) > 0;
Prasad's avatar
Prasad committed
			}
		}
		return false;
	}

	function getTables() {
		return $this->tables;
	}

	function newDependencyMatrix() {
		return new ReportRunQueryDependencyMatrix();
	}

Prasad's avatar
Prasad committed
	function registerTempTable($query, $keyColumns, $module = null) {
Prasad's avatar
Prasad committed
		if ($this->allowTempTables && !$this->disablePlanner) {
			global $current_user;

Prasad's avatar
Prasad committed
			$keyColumns = is_array($keyColumns) ? array_unique($keyColumns) : array($keyColumns);
Prasad's avatar
Prasad committed

			// Minor optimization to avoid re-creating similar temporary table.
			$uniqueName = NULL;
			foreach ($this->tempTables as $tmpUniqueName => $tmpTableInfo) {
Prasad's avatar
Prasad committed
				if (strcasecmp($query, $tmpTableInfo['query']) === 0 && $tmpTableInfo['module'] == $module) {
Prasad's avatar
Prasad committed
					// Capture any additional key columns
					$tmpTableInfo['keycolumns'] = array_unique(array_merge($tmpTableInfo['keycolumns'], $keyColumns));
					$uniqueName = $tmpUniqueName;
					break;
				}
			}

			// Nothing found?
			if ($uniqueName === NULL) {
Prasad's avatar
Prasad committed
				// TODO Adding randomness in name to avoid concurrency
				// even when same-user opens the report multiple instances at same-time.
				$uniqueName = $this->tempTablePrefix .
						str_replace('.', '', uniqid($current_user->id, true)) . (self::$tempTableCounter++);

				$this->tempTables[$uniqueName] = array(
					'query' => $query,
					'keycolumns' => is_array($keyColumns) ? array_unique($keyColumns) : array($keyColumns),
					'module' => $module
Prasad's avatar
Prasad committed
				);
			}

			return $uniqueName;
		}
		return "($query)";
	}

	function initializeTempTables() {
		global $adb;

		$oldDieOnError = $adb->dieOnError;
		$adb->dieOnError = false; // If query planner is re-used there could be attempt for temp table...
		foreach ($this->tempTables as $uniqueName => $tempTableInfo) {
Prasad's avatar
Prasad committed
			$reportConditions = $this->getReportConditions($tempTableInfo['module']);
			if ($tempTableInfo['module'] == 'Emails') {
				$query1 = sprintf('CREATE TEMPORARY TABLE %s AS %s', $uniqueName, $tempTableInfo['query']);
			} else {
				$query1 = sprintf('CREATE TEMPORARY TABLE %s AS %s %s', $uniqueName, $tempTableInfo['query'], $reportConditions);
			}
Prasad's avatar
Prasad committed
			$adb->pquery($query1, array());

			$keyColumns = $tempTableInfo['keycolumns'];
			foreach ($keyColumns as $keyColumn) {
				$query2 = sprintf('ALTER TABLE %s ADD INDEX (%s)', $uniqueName, $keyColumn);
Prasad's avatar
Prasad committed
				$adb->pquery($query2, array());
Prasad's avatar
Prasad committed
			}
		}

		$adb->dieOnError = $oldDieOnError;

		// Trigger cleanup of temporary tables when the execution of the request ends.
		// NOTE: This works better than having in __destruct
		// (as the reference to this object might end pre-maturely even before query is executed)
		if (!$this->registeredCleanup) {
			register_shutdown_function(array($this, 'cleanup'));
			// To avoid duplicate registration on this instance.
			$this->registeredCleanup = true;
		}
	}

	function cleanup() {
		global $adb;

		$oldDieOnError = $adb->dieOnError;
		$adb->dieOnError = false; // To avoid abnormal termination during shutdown...
		foreach ($this->tempTables as $uniqueName => $tempTableInfo) {
			$adb->pquery('DROP TABLE ' . $uniqueName, array());
		}
		$adb->dieOnError = $oldDieOnError;

		$this->tempTables = array();
	}
Prasad's avatar
Prasad committed

	/**
	 * Function to get report condition query for generating temporary table based on condition given on report.
	 * It generates condition query by considering fields of $module's base table or vtiger_crmentity table fields.
	 * It doesn't add condition for reference fields in query.
	 * @param String $module Module name for which temporary table is generated (Reports secondary module)
	 * @return string Returns condition query for generating temporary table.
	 */
	function getReportConditions($module) {
		$db = PearDatabase::getInstance();
		$moduleModel = Vtiger_Module_Model::getInstance($module);
		$moduleBaseTable = $moduleModel->get('basetable');
		$reportId = $this->reportRun->reportid;
		if (isset($_REQUEST['mode']) && $_REQUEST['mode'] == 'generate') {
			$advanceFilter = $_REQUEST['advanced_filter'];
			$advfilterlist = transformAdvFilterListToDBFormat(json_decode($advanceFilter, true));
		} else {
			$advfilterlist = $this->reportRun->getAdvFilterList($reportId);
		}
		$newAdvFilterList = array();
		$k = 0;

		foreach ($advfilterlist as $i => $columnConditions) {
			$conditionGroup = $advfilterlist[$i]['columns'];
			reset($conditionGroup);
			$firstConditionKey = key($conditionGroup);
			$oldColumnCondition = $advfilterlist[$i]['columns'][$firstConditionKey]['column_condition'];
			foreach ($columnConditions['columns'] as $j => $condition) {
				$columnName = $condition['columnname'];
				$columnParts = explode(':', $columnName);
				list($moduleName, $fieldLabel) = explode('_', $columnParts[2], 2);
				$fieldInfo = getFieldByReportLabel($moduleName, $columnParts[3], 'name');
				if(!empty($fieldInfo)) {
					$fieldInstance = WebserviceField::fromArray($db, $fieldInfo);
					$dataType = $fieldInstance->getFieldDataType();
					$uiType = $fieldInfo['uitype'];
					$fieldTable = $fieldInfo['tablename'];
					$allowedTables = array('vtiger_crmentity', $moduleBaseTable);
					$columnCondition = $advfilterlist[$i]['columns'][$j]['column_condition'];
					if (!in_array($fieldTable, $allowedTables) || $moduleName != $module || isReferenceUIType($uiType) || $columnCondition == 'or' || $oldColumnCondition == 'or' || in_array($dataType, array('reference', 'multireference'))) {
						$oldColumnCondition = $advfilterlist[$i]['columns'][$j]['column_condition'];
					} else {
						$columnParts[0] = $fieldTable;
						$newAdvFilterList[$i]['columns'][$k]['columnname'] = implode(':', $columnParts);
						$newAdvFilterList[$i]['columns'][$k]['comparator'] = $advfilterlist[$i]['columns'][$j]['comparator'];
						$newAdvFilterList[$i]['columns'][$k]['value'] = $advfilterlist[$i]['columns'][$j]['value'];
						$newAdvFilterList[$i]['columns'][$k++]['column_condition'] = $oldColumnCondition;
					}
				}
			}
			if (!empty($newAdvFilterList) && (php7_count($newAdvFilterList[$i]))) {
Prasad's avatar
Prasad committed
				$newAdvFilterList[$i]['condition'] = $advfilterlist[$i]['condition'];
			}
			if (isset($newAdvFilterList[$i]['columns'][$k - 1])) {
				$newAdvFilterList[$i]['columns'][$k - 1]['column_condition'] = '';
			}
			if (!empty($newAdvFilterList) && (php7_count($newAdvFilterList[$i]) != 2)) {
Prasad's avatar
Prasad committed
				unset($newAdvFilterList[$i]);
			}
		}
		end($newAdvFilterList);
		$lastConditionsGrpKey = key($newAdvFilterList);
		if (!empty($newAdvFilterList) && (php7_count($newAdvFilterList[$lastConditionsGrpKey]))) {
Prasad's avatar
Prasad committed
			$newAdvFilterList[$lastConditionsGrpKey]['condition'] = '';
		}

		$advfiltersql = $this->reportRun->generateAdvFilterSql($newAdvFilterList);
		if ($advfiltersql && !empty($advfiltersql)) {
			$advfiltersql = ' AND ' . $advfiltersql;
		}
		return $advfiltersql;
	}

Prasad's avatar
Prasad committed
class ReportRun extends CRMEntity {

Prasad's avatar
Prasad committed
	// Maximum rows that should be emitted in HTML view.
	static $HTMLVIEW_MAX_ROWS = 1000;
	var $reportid;
	var $primarymodule;
	var $secondarymodule;
	var $orderbylistsql;
	var $orderbylistcolumns;
	var $selectcolumns;
	var $groupbylist;
	var $reporttype;
	var $reportname;
	var $totallist;
Prasad's avatar
Prasad committed
	var $_groupinglist = false;
    var $_groupbycondition = false;
    var $_reportquery = false;
    var $_tmptablesinitialized = false;
	var $_columnslist = false;
Prasad's avatar
Prasad committed
	var $_stdfilterlist = false;
	var $_columnstotallist = false;
	var $_advfiltersql = false;
Prasad's avatar
Prasad committed
	// All UItype 72 fields are added here so that in reports the values are append currencyId::value
	var $append_currency_symbol_to_value = array('Products_Unit_Price', 'Services_Price',
		'Invoice_Total', 'Invoice_Sub_Total', 'Invoice_Pre_Tax_Total', 'Invoice_S&H_Amount', 'Invoice_Discount_Amount', 'Invoice_Adjustment',
		'Quotes_Total', 'Quotes_Sub_Total', 'Quotes_Pre_Tax_Total', 'Quotes_S&H_Amount', 'Quotes_Discount_Amount', 'Quotes_Adjustment',
		'SalesOrder_Total', 'SalesOrder_Sub_Total', 'SalesOrder_Pre_Tax_Total', 'SalesOrder_S&H_Amount', 'SalesOrder_Discount_Amount', 'SalesOrder_Adjustment',
		'PurchaseOrder_Total', 'PurchaseOrder_Sub_Total', 'PurchaseOrder_Pre_Tax_Total', 'PurchaseOrder_S&H_Amount', 'PurchaseOrder_Discount_Amount', 'PurchaseOrder_Adjustment',
		'Invoice_Received', 'PurchaseOrder_Paid', 'Invoice_Balance', 'PurchaseOrder_Balance'
	);
Prasad's avatar
Prasad committed
	var $ui10_fields = array();
	var $ui101_fields = array();
Prasad's avatar
Prasad committed
	var $groupByTimeParent = array('Quarter' => array('Year'),
		'Month' => array('Year')
	);
Prasad's avatar
Prasad committed
	var $queryPlanner = null;
Prasad's avatar
Prasad committed
	protected static $instances = false;
Prasad's avatar
Prasad committed
	// Added to support line item fields calculation, if line item fields
	// are selected then module fields cannot be selected and vice versa
	var $lineItemFieldsInCalculation = false;

Prasad's avatar
Prasad committed
	/** Function to set reportid,primarymodule,secondarymodule,reporttype,reportname, for given reportid
Prasad's avatar
Prasad committed
	 *  This function accepts the $reportid as argument
	 *  It sets reportid,primarymodule,secondarymodule,reporttype,reportname for the given reportid
Prasad's avatar
Prasad committed
	 *  To ensure single-instance is present for $reportid
	 *  as we optimize using ReportRunPlanner and setup temporary tables.
Prasad's avatar
Prasad committed
	 */
        function __construct($reportid) {
            $oReport = new Reports($reportid);
            $this->reportid = $reportid;
            $this->primarymodule = $oReport->primodule;
            $this->secondarymodule = $oReport->secmodule;
            $this->reporttype = $oReport->reporttype;
            $this->reportname = $oReport->reportname;
            $this->queryPlanner = new ReportRunQueryPlanner();
            $this->queryPlanner->reportRun = $this;
        }
Prasad's avatar
Prasad committed
	function ReportRun($reportid) {
            self::__construct($reportid);
Prasad's avatar
Prasad committed
	public static function getInstance($reportid) {
		if (self::$instances === false || !is_array(self::$instances)) {
            self::$instances = array();
        }
Prasad's avatar
Prasad committed
		if (!isset(self::$instances[$reportid])) {
			self::$instances[$reportid] = new ReportRun($reportid);
		}
		return self::$instances[$reportid];
	}
Prasad's avatar
Prasad committed

	/** Function to get the columns for the reportid
	 *  This function accepts the $reportid and $outputformat (optional)
	 *  This function returns  $columnslist Array($tablename:$columnname:$fieldlabel:$fieldname:$typeofdata=>$tablename.$columnname As Header value,
Prasad's avatar
Prasad committed
	 * 					      $tablename1:$columnname1:$fieldlabel1:$fieldname1:$typeofdata1=>$tablename1.$columnname1 As Header value,
	 * 					      					|
	 * 					      $tablenamen:$columnnamen:$fieldlabeln:$fieldnamen:$typeofdatan=>$tablenamen.$columnnamen As Header value
	 * 				      	     )
Prasad's avatar
Prasad committed
	 *
	 */
Prasad's avatar
Prasad committed
	function getQueryColumnsList($reportid, $outputformat = '') {
Prasad's avatar
Prasad committed
		// Have we initialized information already?
Prasad's avatar
Prasad committed
		if ($this->_columnslist !== false) {
Prasad's avatar
Prasad committed
			return $this->_columnslist;
		}

		global $adb;
		global $modules;
Prasad's avatar
Prasad committed
		global $log, $current_user, $current_language;
Prasad's avatar
Prasad committed
		$ssql = "select vtiger_selectcolumn.* from vtiger_report inner join vtiger_selectquery on vtiger_selectquery.queryid = vtiger_report.queryid";
		$ssql .= " left join vtiger_selectcolumn on vtiger_selectcolumn.queryid = vtiger_selectquery.queryid";
		$ssql .= " where vtiger_report.reportid = ?";
		$ssql .= " order by vtiger_selectcolumn.columnindex";
		$result = $adb->pquery($ssql, array($reportid));
		$permitted_fields = Array();
		$module = '';
Prasad's avatar
Prasad committed
        $selectedModuleFields = array();
        require('user_privileges/user_privileges_'.$current_user->id.'.php');
		while ($columnslistrow = $adb->fetch_array($result)) {
			$fieldname = "";
			$fieldcolname = isset($columnslistrow["columnname"]) ? $columnslistrow["columnname"] : '';
			if ($fieldcolname != null && substr_count($fieldcolname, ':') >= 4) {
				list($tablename, $colname, $module_field, $fieldname, $single) = explode(':', $fieldcolname);
				if ($module_field != null && substr_count($module_field, '_') >= 1) {
					list($module, $field) = explode('_', $module_field, 2);
				}
			}
Prasad's avatar
Prasad committed
            $selectedModuleFields[$module][] = $fieldname;
Prasad's avatar
Prasad committed
			$inventory_fields = array('serviceid');
			$inventory_modules = getInventoryModules();
			if (empty($permitted_fields[$module]) && $is_admin == false && $profileGlobalPermission[1] == 1 && $profileGlobalPermission[2] == 1) {
Prasad's avatar
Prasad committed
				$permitted_fields[$module] = $this->getaccesfield($module);
			}
Prasad's avatar
Prasad committed
			if (in_array($module, $inventory_modules)) {
				if (!empty($permitted_fields)) {
Prasad's avatar
Prasad committed
					foreach ($inventory_fields as $value) {
						array_push($permitted_fields[$module], $value);
					}
				}
			}
Prasad's avatar
Prasad committed
			$selectedfields = explode(":", $fieldcolname);
			if ($is_admin == false && $profileGlobalPermission[1] == 1 && $profileGlobalPermission[2] == 1 && !in_array($selectedfields[3], $permitted_fields[$module])) {
Prasad's avatar
Prasad committed
				//user has no access to this field, skip it.
				continue;
			}
			$querycolumns = $this->getEscapedColumns($selectedfields);
Prasad's avatar
Prasad committed
			if (isset($module) && $module != "") {
				$mod_strings = return_module_language($current_language, $module);
			$targetTableName = isset($tablename) ? $tablename : '';
Prasad's avatar
Prasad committed

			$fieldlabel = trim(preg_replace("/$module/", " ", isset($selectedfields[2]) ? $selectedfields[2] :'', 1));
Prasad's avatar
Prasad committed
			$mod_arr = explode('_', $fieldlabel);
			$fieldlabel = trim(str_replace("_", " ", $fieldlabel));
Prasad's avatar
Prasad committed
			//modified code to support i18n issue
Prasad's avatar
Prasad committed
			$fld_arr = explode(" ", $fieldlabel);
			if (($mod_arr[0] == '')) {
Prasad's avatar
Prasad committed
				$mod = $module;
Prasad's avatar
Prasad committed
				$mod_lbl = getTranslatedString($module, $module); //module
Prasad's avatar
Prasad committed
			} else {
				$mod = $mod_arr[0];
				array_shift($fld_arr);
Prasad's avatar
Prasad committed
				$mod_lbl = getTranslatedString($fld_arr[0], $mod); //module
			}
			$fld_lbl_str = implode(" ", $fld_arr);
			$fld_lbl = getTranslatedString($fld_lbl_str, $module); //fieldlabel
			$fieldlabel = $mod_lbl . " " . $fld_lbl;
			if (($selectedfields[0] == "vtiger_usersRel1") && ($selectedfields[1] == 'user_name') && ($selectedfields[2] == 'Quotes_Inventory_Manager')) {
				$concatSql = getSqlForNameInDisplayFormat(array('first_name' => $selectedfields[0] . ".first_name", 'last_name' => $selectedfields[0] . ".last_name"), 'Users');
				$columnslist[$fieldcolname] = "trim( $concatSql ) as " . $module . "_Inventory_Manager";
				$this->queryPlanner->addTable($selectedfields[0]);
Prasad's avatar
Prasad committed
				continue;
Prasad's avatar
Prasad committed
			} 
			if ((CheckFieldPermission($fieldname, $mod) != 'true' && isset($colname) && $colname != "crmid" && (!in_array($fieldname, $inventory_fields) && in_array($module, $inventory_modules))) || empty($fieldname)) {
Prasad's avatar
Prasad committed
				continue;
Prasad's avatar
Prasad committed
			} else {
				$this->labelMapping[$selectedfields[2]] = str_replace(" ", "_", $fieldlabel);
Prasad's avatar
Prasad committed

				// To check if the field in the report is a custom field
				// and if yes, get the label of this custom field freshly from the vtiger_field as it would have been changed.
				// Asha - Reference ticket : #4906

Prasad's avatar
Prasad committed
				if ($querycolumns == "") {
					$columnslist[$fieldcolname] = $this->getColumnSQL($selectedfields);
Prasad's avatar
Prasad committed
				} else {
					$columnslist[$fieldcolname] = $querycolumns;
				}

				$this->queryPlanner->addTable($targetTableName);
			}
		}

		if ($outputformat == "HTML" || $outputformat == "PDF" || $outputformat == "PRINT") {
Prasad's avatar
Prasad committed
			if($this->primarymodule == 'ModComments') {
				$columnslist['vtiger_modcomments:related_to:ModComments_Related_To_Id:related_to:V'] = "vtiger_modcomments.related_to AS '".$this->primarymodule."_LBL_ACTION'";
			} else {
				$columnslist['vtiger_crmentity:crmid:LBL_ACTION:crmid:I'] = 'vtiger_crmentity.crmid AS "' . $this->primarymodule . '_LBL_ACTION"';
			}
			if ($this->secondarymodule) {
				$secondaryModules = explode(':', $this->secondarymodule);
				foreach ($secondaryModules as $secondaryModule) {
                    $columnsSelected = isset($selectedModuleFields[$secondaryModule]) ? (array)$selectedModuleFields[$secondaryModule] : array();
Prasad's avatar
Prasad committed
					$moduleModel = Vtiger_Module_Model::getInstance($secondaryModule);
                    /**
                     * To check whether any column is selected from secondary module. If so, then only add 
                     * that module table to query planner
                     */
                    $moduleFields = $moduleModel->getFields();
                    $moduleFieldNames = array_keys($moduleFields);
                    $commonFields = array_intersect($moduleFieldNames, $columnsSelected);
                    if(php7_count($commonFields) > 0){
Prasad's avatar
Prasad committed
						$baseTable = $moduleModel->get('basetable');
						$this->queryPlanner->addTable($baseTable);
						if ($secondaryModule == "Emails") {
							$baseTable .= "Emails";
						}
						$baseTableId = $moduleModel->get('basetableid');
						$columnslist[$baseTable . ":" . $baseTableId . ":" . $secondaryModule . ":" . $baseTableId . ":I"] = $baseTable . "." . $baseTableId . " AS " . $secondaryModule . "_LBL_ACTION";
					}
				}
			}
		}
Prasad's avatar
Prasad committed
		// Save the information
		$this->_columnslist = $columnslist;

Prasad's avatar
Prasad committed
		$log->info("ReportRun :: Successfully returned getQueryColumnsList" . $reportid);
Prasad's avatar
Prasad committed
		return $columnslist;
	}

	function getColumnSQL($selectedfields) {
Prasad's avatar
Prasad committed
		global $adb;
		$header_label = $selectedfields[2] = addslashes($selectedfields[2]); // Header label to be displayed in the reports table

		list($module, $field) = explode('_', $selectedfields[2]);
Prasad's avatar
Prasad committed
		$concatSql = getSqlForNameInDisplayFormat(array('first_name' => $selectedfields[0] . ".first_name", 'last_name' => $selectedfields[0] . ".last_name"), 'Users');
		$emailTableName = "vtiger_activity";
		if ($module != $this->primarymodule) {
			$emailTableName .="Emails";
		}

		if ($selectedfields[0] == 'vtiger_inventoryproductrel') {

			if ($selectedfields[1] == 'discount_amount') {
				$columnSQL = "CASE WHEN (vtiger_inventoryproductreltmp{$module}.discount_amount != '') THEN vtiger_inventoryproductreltmp{$module}.discount_amount ELSE ROUND((vtiger_inventoryproductreltmp{$module}.listprice * vtiger_inventoryproductreltmp{$module}.quantity * (vtiger_inventoryproductreltmp{$module}.discount_percent/100)),3) END AS '" . decode_html($header_label) . "'";
				$this->queryPlanner->addTable($selectedfields[0].'tmp'.$module);
			} else if ($selectedfields[1] == 'productid') {
				$columnSQL = "CASE WHEN (vtiger_products{$module}.productname NOT LIKE '') THEN vtiger_products{$module}.productname ELSE vtiger_service{$module}.servicename END AS '" . decode_html($header_label) . "'";
				$this->queryPlanner->addTable("vtiger_products{$module}");
				$this->queryPlanner->addTable("vtiger_service{$module}");
			} else if ($selectedfields[1] == 'listprice') {
				$moduleInstance = CRMEntity::getInstance($module);
				$fieldName = $selectedfields[0] .'tmp'. $module . "." . $selectedfields[1];
				$columnSQL = "CASE WHEN vtiger_currency_info{$module}.id = vtiger_users{$module}.currency_id THEN $fieldName/vtiger_currency_info{$module}.conversion_rate ELSE $fieldName/$moduleInstance->table_name.conversion_rate END AS '" . decode_html($header_label) . "'";
				$this->queryPlanner->addTable($selectedfields[0] .'tmp'. $module);
				$this->queryPlanner->addTable('vtiger_currency_info' . $module);
				$this->queryPlanner->addTable('vtiger_users' . $module);
			} else if(in_array($this->primarymodule, array('Products', 'Services'))) {
				$columnSQL = $selectedfields[0] . 'tmp' . $module . ".$selectedfields[1] AS '" . decode_html($header_label) . "'";
				$this->queryPlanner->addTable($selectedfields[0] . $module);
			} else {
				if($selectedfields[0] == 'vtiger_inventoryproductrel'){
					$selectedfields[0] = $selectedfields[0]. 'tmp';
				}
				$columnSQL = $selectedfields[0] . $module . ".$selectedfields[1] AS '" . decode_html($header_label) . "'";
				$this->queryPlanner->addTable($selectedfields[0] . $module);
			}
		} else if($selectedfields[0] == 'vtiger_pricebookproductrel'){
			if ($selectedfields[1] == 'listprice') {
				$listPriceFieldName = $selectedfields[0].'tmp'. $module . "." . $selectedfields[1];
				$currencyPriceFieldName = $selectedfields[0].'tmp'. $module . "." . 'usedcurrency';
				$columnSQL = 'CONCAT('.$currencyPriceFieldName.",'::',". $listPriceFieldName .")". " AS '" . decode_html($header_label) . "'";
				$this->queryPlanner->addTable($selectedfields[0] .'tmp'. $module);
			}
		} else if ($selectedfields[4] == 'C') {
			$field_label_data = explode('_', $selectedfields[2]);
Prasad's avatar
Prasad committed
			$module = $field_label_data[0];
			if ($module != $this->primarymodule) {
				$columnSQL = "case when (" . $selectedfields[0] . "." . $selectedfields[1] . "='1')then 'yes' else case when (vtiger_crmentity$module.crmid !='') then 'no' else '-' end end AS '" . decode_html($selectedfields[2]) . "'";
				$this->queryPlanner->addTable("vtiger_crmentity$module");
			} else {
				$columnSQL = "case when (" . $selectedfields[0] . "." . $selectedfields[1] . "='1')then 'yes' else case when (vtiger_crmentity.crmid !='') then 'no' else '-' end end AS '" . decode_html($selectedfields[2]) . "'";
				$this->queryPlanner->addTable($selectedfields[0]);
			}
		} elseif ($selectedfields[4] == 'D' || $selectedfields[4] == 'DT') {
			if ($selectedfields[5] == 'Y') {
				if ($selectedfields[0] == 'vtiger_activity' && $selectedfields[1] == 'date_start') {
					if ($module == 'Emails') {
						$columnSQL = "YEAR(cast(concat($emailTableName.date_start,'  ',$emailTableName.time_start) as DATE)) AS Emails_Date_Sent_Year";
					} else {
						$columnSQL = "YEAR(concat(vtiger_activity.date_start,' ',vtiger_activity.time_start)) AS Calendar_Start_Date_and_Time_Year";
Prasad's avatar
Prasad committed
					}
				} else if ($selectedfields[0] == "vtiger_crmentity" . $this->primarymodule) {
					$columnSQL = "YEAR(vtiger_crmentity." . $selectedfields[1] . ") AS '" . decode_html($header_label) . "_Year'";
				} else {
					$columnSQL = 'YEAR(' . $selectedfields[0] . "." . $selectedfields[1] . ") AS '" . decode_html($header_label) . "_Year'";
				}
				$this->queryPlanner->addTable($selectedfields[0]);
			} elseif ($selectedfields[5] == 'M') {
				if ($selectedfields[0] == 'vtiger_activity' && $selectedfields[1] == 'date_start') {
					if ($module == 'Emails') {
						$columnSQL = "MONTHNAME(cast(concat($emailTableName.date_start,'  ',$emailTableName.time_start) as DATE)) AS Emails_Date_Sent_Month";
					} else {
						$columnSQL = "MONTHNAME(concat(vtiger_activity.date_start,'  ',vtiger_activity.time_start)) AS Calendar_Start_Date_and_Time_Month";
Prasad's avatar
Prasad committed
					}
				} else if ($selectedfields[0] == "vtiger_crmentity" . $this->primarymodule) {
					$columnSQL = "MONTHNAME(vtiger_crmentity." . $selectedfields[1] . ") AS '" . decode_html($header_label) . "_Month'";
				} else {
					$columnSQL = 'MONTHNAME(' . $selectedfields[0] . "." . $selectedfields[1] . ") AS '" . decode_html($header_label) . "_Month'";
				}
				$this->queryPlanner->addTable($selectedfields[0]);
			} elseif ($selectedfields[5] == 'W') {
				if ($selectedfields[0] == 'vtiger_activity' && $selectedfields[1] == 'date_start') {
					if ($module == 'Emails') {
						$columnSQL = "CONCAT('Week ',WEEK(cast(concat($emailTableName.date_start,'  ',$emailTableName.time_start) as DATE), 1)) AS Emails_Date_Sent_Week";
					} else {
						$columnSQL = "CONCAT('Week ',WEEK(concat(vtiger_activity.date_start,'  ',vtiger_activity.time_start), 1)) AS Calendar_Start_Date_and_Time_Week";
Prasad's avatar
Prasad committed
					}
				} else if ($selectedfields[0] == "vtiger_crmentity" . $this->primarymodule) {
					$columnSQL = "CONCAT('Week ',WEEK(vtiger_crmentity." . $selectedfields[1] . ", 1)) AS '" . decode_html($header_label) . "_Week'";
				} else {
					$columnSQL = "CONCAT('Week ',WEEK(" . $selectedfields[0] . "." . $selectedfields[1] . ", 1)) AS '" . decode_html($header_label) . "_Week'";
				}
				$this->queryPlanner->addTable($selectedfields[0]);
			} elseif ($selectedfields[5] == 'MY') { // used in charts to get the year also, which will be used for click throughs
				if ($selectedfields[0] == 'vtiger_activity' && $selectedfields[1] == 'date_start') {
					if ($module == 'Emails') {
						$columnSQL = "date_format(cast(concat($emailTableName.date_start,'  ',$emailTableName.time_start) as DATE), '%M %Y') AS Emails_Date_Sent_Month";
					} else {
						$columnSQL = "date_format(concat(vtiger_activity.date_start,'  ',vtiger_activity.time_start), '%M %Y') AS Calendar_Start_Date_and_Time_Month";
Prasad's avatar
Prasad committed
					}
				} else if ($selectedfields[0] == "vtiger_crmentity" . $this->primarymodule) {
					$columnSQL = "date_format(vtiger_crmentity." . $selectedfields[1] . ", '%M %Y') AS '" . decode_html($header_label) . "_Month'";
				} else {
					$columnSQL = 'date_format(' . $selectedfields[0] . "." . $selectedfields[1] . ", '%M %Y') AS '" . decode_html($header_label) . "_Month'";
				}
				$this->queryPlanner->addTable($selectedfields[0]);
			} else {
				if ($selectedfields[0] == 'vtiger_activity' && $selectedfields[1] == 'date_start') {
					if ($module == 'Emails') {
						$columnSQL = "cast(concat($emailTableName.date_start,'  ',$emailTableName.time_start) as DATE) AS Emails_Date_Sent";
					} else {
						$columnSQL = "concat(vtiger_activity.date_start,'  ',vtiger_activity.time_start) AS Calendar_Start_Date_and_Time";
Prasad's avatar
Prasad committed
					}
				} else if ($selectedfields[0] == "vtiger_crmentity" . $this->primarymodule) {
					$columnSQL = "vtiger_crmentity." . $selectedfields[1] . " AS '" . decode_html($header_label) . "'";
				} else {
					$columnSQL = $selectedfields[0] . "." . $selectedfields[1] . " AS '" . decode_html($header_label) . "'";
				}
				$this->queryPlanner->addTable($selectedfields[0]);
			}
		} elseif ($selectedfields[0] == 'vtiger_activity' && $selectedfields[1] == 'status') {
			$columnSQL = " case when (vtiger_activity.status not like '') then vtiger_activity.status else vtiger_activity.eventstatus end AS Calendar_Status";
		} elseif ($selectedfields[0] == 'vtiger_activity' && $selectedfields[1] == 'date_start') {
			if ($module == 'Emails') {
				$columnSQL = "cast(concat($emailTableName.date_start,'  ',$emailTableName.time_start) as DATE) AS Emails_Date_Sent";
Prasad's avatar
Prasad committed
			} else {
				$columnSQL = "concat(vtiger_activity.date_start,'  ',vtiger_activity.time_start) AS Calendar_Start_Date_and_Time";
Prasad's avatar
Prasad committed
			}
Prasad's avatar
Prasad committed
		} elseif (stristr($selectedfields[0], "vtiger_users") && ($selectedfields[1] == 'user_name')) {
			$temp_module_from_tablename = str_replace("vtiger_users", "", $selectedfields[0]);
			if ($module != $this->primarymodule) {
				$condition = "and vtiger_crmentity" . $module . ".crmid!=''";
Prasad's avatar
Prasad committed
				$this->queryPlanner->addTable("vtiger_crmentity$module");
			} else {
				$condition = "and vtiger_crmentity.crmid!=''";
			}
Prasad's avatar
Prasad committed
			if ($temp_module_from_tablename == $module) {
				$concatSql = getSqlForNameInDisplayFormat(array('first_name' => $selectedfields[0] . ".first_name", 'last_name' => $selectedfields[0] . ".last_name"), 'Users');
				$columnSQL = " case when(" . $selectedfields[0] . ".last_name NOT LIKE '' $condition ) THEN " . $concatSql . " else vtiger_groups" . $module . ".groupname end AS '" . decode_html($header_label) . "'";
				$this->queryPlanner->addTable('vtiger_groups' . $module); // Auto-include the dependent module table.
Prasad's avatar
Prasad committed
			} else {//Some Fields can't assigned to groups so case avoided (fields like inventory manager)
Prasad's avatar
Prasad committed
				$columnSQL = $selectedfields[0] . ".user_name AS '" . decode_html($header_label) . "'";
Prasad's avatar
Prasad committed
			}
			$this->queryPlanner->addTable($selectedfields[0]);
Prasad's avatar
Prasad committed
		} elseif (stristr($selectedfields[0], "vtiger_crmentity") && ($selectedfields[1] == 'modifiedby')) {
			$targetTableName = 'vtiger_lastModifiedBy' . $module;
			$concatSql = getSqlForNameInDisplayFormat(array('last_name' => $targetTableName . '.last_name', 'first_name' => $targetTableName . '.first_name'), 'Users');
Prasad's avatar
Prasad committed
			$columnSQL = "trim($concatSql) AS $header_label";
			$this->queryPlanner->addTable("vtiger_crmentity$module");
			$this->queryPlanner->addTable($targetTableName);

			// Added when no fields from the secondary module is selected but lastmodifiedby field is selected
			$moduleInstance = CRMEntity::getInstance($module);
			$this->queryPlanner->addTable($moduleInstance->table_name);
Prasad's avatar
Prasad committed
		} else if (stristr($selectedfields[0], "vtiger_crmentity") && ($selectedfields[1] == 'smcreatorid')) {
			$targetTableName = 'vtiger_createdby' . $module;
			$concatSql = getSqlForNameInDisplayFormat(array('last_name' => $targetTableName . '.last_name', 'first_name' => $targetTableName . '.first_name'), 'Users');
			$columnSQL = "trim($concatSql) AS " . decode_html($header_label) . "";
Prasad's avatar
Prasad committed
			$this->queryPlanner->addTable("vtiger_crmentity$module");
			$this->queryPlanner->addTable($targetTableName);

Prasad's avatar
Prasad committed
			// Added when no fields from the secondary module is selected but creator field is selected
Prasad's avatar
Prasad committed
			$moduleInstance = CRMEntity::getInstance($module);
			$this->queryPlanner->addTable($moduleInstance->table_name);
Prasad's avatar
Prasad committed
		} elseif ($selectedfields[0] == "vtiger_crmentity" . $this->primarymodule) {
			$columnSQL = "vtiger_crmentity." . $selectedfields[1] . " AS '" . decode_html($header_label) . "'";
		} elseif ($selectedfields[0] == 'vtiger_products' && $selectedfields[1] == 'unit_price') {
			$columnSQL = "concat(" . $selectedfields[0] . ".currency_id,'::',innerProduct.actual_unit_price) AS '" . decode_html($header_label) . "'";
Prasad's avatar
Prasad committed
			$this->queryPlanner->addTable("innerProduct");
Prasad's avatar
Prasad committed
		} elseif (in_array(decode_html($selectedfields[2]), $this->append_currency_symbol_to_value)) {
			if ($selectedfields[1] == 'discount_amount') {
				$columnSQL = "CONCAT(" . $selectedfields[0] . ".currency_id,'::', IF(" . $selectedfields[0] . ".discount_amount != ''," . $selectedfields[0] . ".discount_amount, (" . $selectedfields[0] . ".discount_percent/100) * " . $selectedfields[0] . ".subtotal)) AS " . decode_html($header_label);
Prasad's avatar
Prasad committed
			} else {
Prasad's avatar
Prasad committed
				$columnSQL = "concat(" . $selectedfields[0] . ".currency_id,'::'," . $selectedfields[0] . "." . $selectedfields[1] . ") AS '" . decode_html($header_label) . "'";
Prasad's avatar
Prasad committed
			}
Prasad's avatar
Prasad committed
		} elseif ($selectedfields[0] == 'vtiger_notes' && ($selectedfields[1] == 'filelocationtype' || $selectedfields[1] == 'filesize' || $selectedfields[1] == 'folderid' || $selectedfields[1] == 'filestatus')) {
			if ($selectedfields[1] == 'filelocationtype') {
				$columnSQL = "case " . $selectedfields[0] . "." . $selectedfields[1] . " when 'I' then 'Internal' when 'E' then 'External' else '-' end AS '" . decode_html($selectedfields[2]) . "'";
			} else if ($selectedfields[1] == 'folderid') {
Prasad's avatar
Prasad committed
				$columnSQL = "vtiger_attachmentsfolder.foldername AS '$selectedfields[2]'";
				$this->queryPlanner->addTable("vtiger_attachmentsfolder");
Prasad's avatar
Prasad committed
			} elseif ($selectedfields[1] == 'filestatus') {
				$columnSQL = "case " . $selectedfields[0] . "." . $selectedfields[1] . " when '1' then 'yes' when '0' then 'no' else '-' end AS '" . decode_html($selectedfields[2]) . "'";
			} elseif ($selectedfields[1] == 'filesize') {
				$columnSQL = "case " . $selectedfields[0] . "." . $selectedfields[1] . " when '' then '-' else concat(" . $selectedfields[0] . "." . $selectedfields[1] . "/1024,'  ','KB') end AS '" . decode_html($selectedfields[2]) . "'";
Prasad's avatar
Prasad committed
			}
		} else {
Prasad's avatar
Prasad committed
			$tableName = $selectedfields[0];
			if ($module != $this->primarymodule && $module == "Emails" && $tableName == "vtiger_activity") {
				$tableName = $emailTableName;
			}
			$columnSQL = $tableName . "." . $selectedfields[1] . " AS '" . decode_html($header_label) . "'";
			$this->queryPlanner->addTable($selectedfields[0]);
		}
		return $columnSQL;
Prasad's avatar
Prasad committed
	}

	/** Function to get field columns based on profile
	 *  @ param $module : Type string
	 *  returns permitted fields in array format
	 */
	function getaccesfield($module) {
		global $current_user;
		global $adb;
		$access_fields = Array();

                //Reports should not be allowed to access user module fields.
                if($module == "Users"){
                    return $access_fields;
                }
Prasad's avatar
Prasad committed
		$profileList = getCurrentUserProfileList();
		$query = "select vtiger_field.fieldname from vtiger_field inner join vtiger_profile2field on vtiger_profile2field.fieldid=vtiger_field.fieldid inner join vtiger_def_org_field on vtiger_def_org_field.fieldid=vtiger_field.fieldid where";
		$params = array();
Prasad's avatar
Prasad committed
		if ($module == "Calendar") {
			if (php7_count($profileList) > 0) {
Prasad's avatar
Prasad committed
				$query .= " vtiger_field.tabid in (9,16) and vtiger_field.displaytype in (1,2,3) and vtiger_profile2field.visible=0 and vtiger_def_org_field.visible=0
Prasad's avatar
Prasad committed
								and vtiger_field.presence IN (0,2) and vtiger_profile2field.profileid in (" . generateQuestionMarks($profileList) . ") group by vtiger_field.fieldid order by block,sequence";
Prasad's avatar
Prasad committed
				array_push($params, $profileList);
			} else {
				$query .= " vtiger_field.tabid in (9,16) and vtiger_field.displaytype in (1,2,3) and vtiger_profile2field.visible=0 and vtiger_def_org_field.visible=0
								and vtiger_field.presence IN (0,2) group by vtiger_field.fieldid order by block,sequence";
			}
Prasad's avatar
Prasad committed
		} else {
Prasad's avatar
Prasad committed
			array_push($params, $module);
			if (php7_count($profileList) > 0) {
Prasad's avatar
Prasad committed
				$query .= " vtiger_field.tabid in (select tabid from vtiger_tab where vtiger_tab.name in (?)) and vtiger_field.displaytype in (1,2,3,5) and vtiger_profile2field.visible=0
Prasad's avatar
Prasad committed
								and vtiger_field.presence IN (0,2) and vtiger_def_org_field.visible=0 and vtiger_profile2field.profileid in (" . generateQuestionMarks($profileList) . ") group by vtiger_field.fieldid order by block,sequence";
Prasad's avatar
Prasad committed
				array_push($params, $profileList);
			} else {
				$query .= " vtiger_field.tabid in (select tabid from vtiger_tab where vtiger_tab.name in (?)) and vtiger_field.displaytype in (1,2,3,5) and vtiger_profile2field.visible=0
								and vtiger_field.presence IN (0,2) and vtiger_def_org_field.visible=0 group by vtiger_field.fieldid order by block,sequence";
			}
		}
		$result = $adb->pquery($query, $params);

Prasad's avatar
Prasad committed
		while ($collistrow = $adb->fetch_array($result)) {
Prasad's avatar
Prasad committed
			$access_fields[] = $collistrow["fieldname"];
		}
		//added to include ticketid for Reports module in select columnlist for all users
Prasad's avatar
Prasad committed
		if ($module == "HelpDesk")
Prasad's avatar
Prasad committed
			$access_fields[] = "ticketid";
		return $access_fields;
	}

	/** Function to get Escapedcolumns for the field in case of multiple parents
	 *  @ param $selectedfields : Type Array
	 *  returns the case query for the escaped columns
	 */
	function getEscapedColumns($selectedfields) {
		$queryColumn = '';
Prasad's avatar
Prasad committed
		$tableName = $selectedfields[0];
		$columnName = isset($selectedfields[1]) ? $selectedfields[1] : '';
		$moduleFieldLabel = isset($selectedfields[2]) ? $selectedfields[2] : '';
		$fieldName = isset($selectedfields[3]) ? $selectedfields[3] : '';
		if ($moduleFieldLabel !=null && substr_count($moduleFieldLabel, '_') >= 1) {
			list($moduleName, $fieldLabel) = explode('_', $moduleFieldLabel, 2);
			$fieldInfo = getFieldByReportLabel($moduleName, $fieldLabel);
		}
Prasad's avatar
Prasad committed

		if (isset($moduleName) && $moduleName == 'ModComments' && $fieldName == 'creator') {
Prasad's avatar
Prasad committed
			$concatSql = getSqlForNameInDisplayFormat(array('first_name' => 'vtiger_usersModComments.first_name',
Prasad's avatar
Prasad committed
				'last_name' => 'vtiger_usersModComments.last_name'), 'Users');
Prasad's avatar
Prasad committed
			$queryColumn = "trim(case when (vtiger_usersModComments.user_name not like '' and vtiger_crmentity.crmid!='') then $concatSql end) AS ModComments_Creator";
			$this->queryPlanner->addTable('vtiger_usersModComments');
Prasad's avatar
Prasad committed
			$this->queryPlanner->addTable("vtiger_usersModComments");
		} elseif (isset($fieldInfo) && (($fieldInfo['uitype'] == '10' || isReferenceUIType($fieldInfo['uitype'])) && $fieldInfo['tablename'] != 'vtiger_inventoryproductrel') && $fieldInfo['uitype'] != '52' && $fieldInfo['uitype'] != '53') {
Prasad's avatar
Prasad committed
			$fieldSqlColumns = $this->getReferenceFieldColumnList($moduleName, $fieldInfo);
			if (php7_count($fieldSqlColumns) > 0) {
Prasad's avatar
Prasad committed
				$queryColumn = "(CASE WHEN $tableName.$columnName NOT LIKE '' THEN (CASE";
Prasad's avatar
Prasad committed
				foreach ($fieldSqlColumns as $columnSql) {
Prasad's avatar
Prasad committed
					$queryColumn .= " WHEN $columnSql NOT LIKE '' THEN $columnSql";
				}
Prasad's avatar
Prasad committed
				$queryColumn .= " ELSE '' END) ELSE '' END) AS '".decode_html($moduleFieldLabel)."'";
Prasad's avatar
Prasad committed
				$this->queryPlanner->addTable($tableName);
			}
		}
		return $queryColumn;
	}

	/** Function to get selectedcolumns for the given reportid
	 *  @ param $reportid : Type Integer
	 *  returns the query of columnlist for the selected columns
	 */
Prasad's avatar
Prasad committed
	function getSelectedColumnsList($reportid) {
Prasad's avatar
Prasad committed

		global $adb;
		global $modules;
		global $log;

		$ssql = "select vtiger_selectcolumn.* from vtiger_report inner join vtiger_selectquery on vtiger_selectquery.queryid = vtiger_report.queryid";
		$ssql .= " left join vtiger_selectcolumn on vtiger_selectcolumn.queryid = vtiger_selectquery.queryid where vtiger_report.reportid = ? ";
		$ssql .= " order by vtiger_selectcolumn.columnindex";

		$result = $adb->pquery($ssql, array($reportid));
		$noofrows = $adb->num_rows($result);

Prasad's avatar
Prasad committed
		if ($this->orderbylistsql != "") {
			$sSQL .= $this->orderbylistsql . ", ";
Prasad's avatar
Prasad committed
		for ($i = 0; $i < $noofrows; $i++) {
			$fieldcolname = $adb->query_result($result, $i, "columnname");
Prasad's avatar
Prasad committed
			$ordercolumnsequal = true;
Prasad's avatar
Prasad committed
			if ($fieldcolname != "") {
				for ($j = 0; $j < php7_count($this->orderbylistcolumns); $j++) {
Prasad's avatar
Prasad committed
					if ($this->orderbylistcolumns[$j] == $fieldcolname) {
Prasad's avatar
Prasad committed
						$ordercolumnsequal = false;
						break;
Prasad's avatar
Prasad committed
					} else {
Prasad's avatar
Prasad committed
						$ordercolumnsequal = true;
					}
				}
Prasad's avatar
Prasad committed
				if ($ordercolumnsequal) {
					$selectedfields = explode(":", $fieldcolname);
					if ($selectedfields[0] == "vtiger_crmentity" . $this->primarymodule)
Prasad's avatar
Prasad committed
						$selectedfields[0] = "vtiger_crmentity";
Prasad's avatar
Prasad committed
					$sSQLList[] = $selectedfields[0] . "." . $selectedfields[1] . " '" . $selectedfields[2] . "'";
Prasad's avatar
Prasad committed
		$sSQL .= implode(",", $sSQLList);
Prasad's avatar
Prasad committed

Prasad's avatar
Prasad committed
		$log->info("ReportRun :: Successfully returned getSelectedColumnsList" . $reportid);
Prasad's avatar
Prasad committed
		return $sSQL;
	}

	/** Function to get advanced comparator in query form for the given Comparator and value
	 *  @ param $comparator : Type String
	 *  @ param $value : Type String
	 *  returns the check query for the comparator
	 */
Prasad's avatar
Prasad committed
	function getAdvComparator($comparator, $value, $datatype = "", $columnName = '') {
Prasad's avatar
Prasad committed

Prasad's avatar
Prasad committed
		global $log, $adb, $default_charset, $ogReport;
		$value = html_entity_decode(trim($value), ENT_QUOTES, $default_charset);
Prasad's avatar
Prasad committed
		$value_len = strlen($value);
		$is_field = false;
Prasad's avatar
Prasad committed
		if ($value_len > 1 && $value[0] == '$' && $value[$value_len - 1] == '$') {
			$temp = str_replace('$', '', $value);
Prasad's avatar
Prasad committed
			$is_field = true;
		}
Prasad's avatar
Prasad committed
		if ($datatype == 'C') {
			$value = str_replace("yes", "1", str_replace("no", "0", $value));
Prasad's avatar
Prasad committed
		if ($is_field == true) {
Prasad's avatar
Prasad committed
			$value = $this->getFilterComparedField($temp);
		}
Prasad's avatar
Prasad committed
		if ($comparator == "e" || $comparator == 'y') {
			if (trim($value) == "NULL") {
Prasad's avatar
Prasad committed
				$rtvalue = " is NULL";
Prasad's avatar
Prasad committed
			} elseif (trim($value) != "") {
				$rtvalue = " = " . $adb->quote($value);
			} elseif (trim($value) == "" && $datatype == "V") {
				$rtvalue = " = " . $adb->quote($value);
			} else {
Prasad's avatar
Prasad committed
				$rtvalue = " is NULL";
			}
		}
Prasad's avatar
Prasad committed
		if ($comparator == "n" || $comparator == 'ny') {
			if (trim($value) == "NULL") {
Prasad's avatar
Prasad committed
				$rtvalue = " is NOT NULL";
Prasad's avatar
Prasad committed
			} elseif (trim($value) != "") {
				if ($columnName)
					$rtvalue = " <> " . $adb->quote($value) . " OR " . $columnName . " IS NULL ";
				else
					$rtvalue = " <> " . $adb->quote($value);
			}elseif (trim($value) == "" && $datatype == "V") {
				$rtvalue = " <> " . $adb->quote($value);
			} else {
Prasad's avatar
Prasad committed
				$rtvalue = " is NOT NULL";
			}
		}
Prasad's avatar
Prasad committed
		if ($comparator == "s") {
			$rtvalue = " like '" . formatForSqlLike($value, 2, $is_field) . "'";
Prasad's avatar
Prasad committed
		}
Prasad's avatar
Prasad committed
		if ($comparator == "ew") {
			$rtvalue = " like '" . formatForSqlLike($value, 1, $is_field) . "'";
Prasad's avatar
Prasad committed
		}
Prasad's avatar
Prasad committed
		if ($comparator == "c") {
			$rtvalue = " like '" . formatForSqlLike($value, 0, $is_field) . "'";
Prasad's avatar
Prasad committed
		}
Prasad's avatar
Prasad committed
		if ($comparator == "k") {
			$rtvalue = " not like '" . formatForSqlLike($value, 0, $is_field) . "'";
Prasad's avatar
Prasad committed
		}
Prasad's avatar
Prasad committed
		if ($comparator == "l") {
			$rtvalue = " < " . $adb->quote($value);
Prasad's avatar
Prasad committed
		}
Prasad's avatar
Prasad committed
		if ($comparator == "g") {
			$rtvalue = " > " . $adb->quote($value);
Prasad's avatar
Prasad committed
		}
Prasad's avatar
Prasad committed
		if ($comparator == "m") {
			$rtvalue = " <= " . $adb->quote($value);
Prasad's avatar
Prasad committed
		}
Prasad's avatar
Prasad committed
		if ($comparator == "h") {
			$rtvalue = " >= " . $adb->quote($value);
Prasad's avatar
Prasad committed
		}
Prasad's avatar
Prasad committed
		if ($comparator == "b") {
			$rtvalue = " < " . $adb->quote($value);
Prasad's avatar
Prasad committed
		}
Prasad's avatar
Prasad committed
		if ($comparator == "a") {
			$rtvalue = " > " . $adb->quote($value);
Prasad's avatar
Prasad committed
		}
Prasad's avatar
Prasad committed
		if ($is_field == true) {
			$rtvalue = str_replace("'", "", $rtvalue);
			$rtvalue = str_replace("\\", "", $rtvalue);
Prasad's avatar
Prasad committed
		}
		$log->info("ReportRun :: Successfully returned getAdvComparator");
		return $rtvalue;
	}

	/** Function to get field that is to be compared in query form for the given Comparator and field
	 *  @ param $field : field
	 *  returns the value for the comparator
	 */
Prasad's avatar
Prasad committed
	function getFilterComparedField($field) {
		global $adb, $ogReport;
		if (!empty($this->secondarymodule)) {
			$secModules = explode(':', $this->secondarymodule);
			foreach ($secModules as $secModule) {
				$secondary = CRMEntity::getInstance($secModule);
				$this->queryPlanner->addTable($secondary->table_name);
			}
		}
Prasad's avatar
Prasad committed
		$module = $field[0];
		$fieldname = trim($field[1]);
		$tabid = getTabId($module);
		$field_query = $adb->pquery("SELECT tablename,columnname,typeofdata,fieldname,uitype FROM vtiger_field WHERE tabid = ? AND fieldname= ?", array($tabid, $fieldname));
		$fieldtablename = $adb->query_result($field_query, 0, 'tablename');
		$fieldcolname = $adb->query_result($field_query, 0, 'columnname');
		$typeofdata = $adb->query_result($field_query, 0, 'typeofdata');
		$fieldtypeofdata = ChangeTypeOfData_Filter($fieldtablename, $fieldcolname, $typeofdata[0]);
		$uitype = $adb->query_result($field_query, 0, 'uitype');
		/* if($tr[0]==$ogReport->primodule)
		  $value = $adb->query_result($field_query,0,'tablename').".".$adb->query_result($field_query,0,'columnname');
		  else
		  $value = $adb->query_result($field_query,0,'tablename').$tr[0].".".$adb->query_result($field_query,0,'columnname');
		 */
		if ($uitype == 68 || $uitype == 59) {
			$fieldtypeofdata = 'V';
		}
		if ($fieldtablename == "vtiger_crmentity" && $module != $this->primarymodule) {
			$fieldtablename = $fieldtablename . $module;
		}
		if ($fieldname == "assigned_user_id") {
			$fieldtablename = "vtiger_users" . $module;
			$fieldcolname = "user_name";
		}
		if ($fieldtablename == "vtiger_crmentity" && $fieldname == "modifiedby") {
			$fieldtablename = "vtiger_lastModifiedBy" . $module;
			$fieldcolname = "user_name";
		}
		if ($fieldname == "assigned_user_id1") {
			$fieldtablename = "vtiger_usersRel1";
			$fieldcolname = "user_name";
		}

		$value = $fieldtablename . "." . $fieldcolname;

		$this->queryPlanner->addTable($fieldtablename);
Prasad's avatar
Prasad committed
		return $value;
	}
Prasad's avatar
Prasad committed

Prasad's avatar
Prasad committed
	/** Function to get the advanced filter columns for the reportid
	 *  This function accepts the $reportid
	 *  This function returns  $columnslist Array($columnname => $tablename:$columnname:$fieldlabel:$fieldname:$typeofdata=>$tablename.$columnname filtercriteria,
Prasad's avatar
Prasad committed
	 * 					      $tablename1:$columnname1:$fieldlabel1:$fieldname1:$typeofdata1=>$tablename1.$columnname1 filtercriteria,
	 * 					      					|
	 * 					      $tablenamen:$columnnamen:$fieldlabeln:$fieldnamen:$typeofdatan=>$tablenamen.$columnnamen filtercriteria
	 * 				      	     )
Prasad's avatar
Prasad committed
	 *
	 */
Prasad's avatar
Prasad committed
	function getAdvFilterList($reportid, $forClickThrough = false) {
Prasad's avatar
Prasad committed
		global $adb, $log;

		$advft_criteria = array();

Prasad's avatar
Prasad committed
		// Not a good approach to get all the fields if not required(May leads to Performance issue)
		$sql = 'SELECT groupid,group_condition FROM vtiger_relcriteria_grouping WHERE queryid = ? ORDER BY groupid';
Prasad's avatar
Prasad committed
		$groupsresult = $adb->pquery($sql, array($reportid));

		$i = 1;
		$j = 0;
Prasad's avatar
Prasad committed
		while ($relcriteriagroup = $adb->fetch_array($groupsresult)) {
Prasad's avatar
Prasad committed
			$groupId = $relcriteriagroup["groupid"];
			$groupCondition = $relcriteriagroup["group_condition"];

			$ssql = 'select vtiger_relcriteria.* from vtiger_report
						inner join vtiger_relcriteria on vtiger_relcriteria.queryid = vtiger_report.queryid
						left join vtiger_relcriteria_grouping on vtiger_relcriteria.queryid = vtiger_relcriteria_grouping.queryid
								and vtiger_relcriteria.groupid = vtiger_relcriteria_grouping.groupid';
			$ssql.= " where vtiger_report.reportid = ? AND vtiger_relcriteria.groupid = ? order by vtiger_relcriteria.columnindex";

			$result = $adb->pquery($ssql, array($reportid, $groupId));
			$noOfColumns = $adb->num_rows($result);
Prasad's avatar
Prasad committed
			if ($noOfColumns <= 0)
				continue;
Prasad's avatar
Prasad committed

Prasad's avatar
Prasad committed
			while ($relcriteriarow = $adb->fetch_array($result)) {
Prasad's avatar
Prasad committed
				$columnIndex = $relcriteriarow["columnindex"];
				$criteria = array();
				$criteria['columnname'] = html_entity_decode($relcriteriarow["columnname"]);
				$criteria['comparator'] = $relcriteriarow["comparator"];
				$advfilterval = $relcriteriarow["value"];
				$col = explode(":",$relcriteriarow["columnname"]);
				$criteria['value'] = $advfilterval;
				$criteria['column_condition'] = $relcriteriarow["column_condition"];