PageRenderTime 47ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/modules/Charts/code/Chart_pipeline_by_lead_source.php

https://bitbucket.org/cviolette/sugarcrm
PHP | 430 lines | 313 code | 50 blank | 67 comment | 62 complexity | ba05404a1f840ff230b153b35b912c23 MD5 | raw file
Possible License(s): LGPL-2.1, MPL-2.0-no-copyleft-exception, BSD-3-Clause
  1. <?php
  2. if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');
  3. /*********************************************************************************
  4. * SugarCRM Community Edition is a customer relationship management program developed by
  5. * SugarCRM, Inc. Copyright (C) 2004-2012 SugarCRM Inc.
  6. *
  7. * This program is free software; you can redistribute it and/or modify it under
  8. * the terms of the GNU Affero General Public License version 3 as published by the
  9. * Free Software Foundation with the addition of the following permission added
  10. * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
  11. * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
  12. * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
  13. *
  14. * This program is distributed in the hope that it will be useful, but WITHOUT
  15. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  16. * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
  17. * details.
  18. *
  19. * You should have received a copy of the GNU Affero General Public License along with
  20. * this program; if not, see http://www.gnu.org/licenses or write to the Free
  21. * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  22. * 02110-1301 USA.
  23. *
  24. * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
  25. * SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
  26. *
  27. * The interactive user interfaces in modified source and object code versions
  28. * of this program must display Appropriate Legal Notices, as required under
  29. * Section 5 of the GNU Affero General Public License version 3.
  30. *
  31. * In accordance with Section 7(b) of the GNU Affero General Public License version 3,
  32. * these Appropriate Legal Notices must retain the display of the "Powered by
  33. * SugarCRM" logo. If the display of the logo is not reasonably feasible for
  34. * technical reasons, the Appropriate Legal Notices must display the words
  35. * "Powered by SugarCRM".
  36. ********************************************************************************/
  37. /*********************************************************************************
  38. * Description: returns HTML for client-side image map.
  39. * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
  40. * All Rights Reserved.
  41. * Contributor(s): ______________________________________..
  42. ********************************************************************************/
  43. require_once('include/charts/Charts.php');
  44. class Chart_pipeline_by_lead_source
  45. {
  46. var $order = 0;
  47. var $modules = array('Opportunities');
  48. function Chart_pipeline_by_lead_source()
  49. {
  50. }
  51. function draw($extra_tools)
  52. {
  53. global $app_list_strings, $current_language, $ids, $sugar_config ,$theme;
  54. $current_module_strings = return_module_language($current_language, 'Charts');
  55. if (isset($_REQUEST['pbls_refresh'])) { $refresh = $_REQUEST['pbls_refresh']; }
  56. else { $refresh = false; }
  57. $tempx = array();
  58. $datax = array();
  59. $selected_datax = array();
  60. //get list of sales stage keys to display
  61. global $current_user;
  62. $user_tempx = $current_user->getPreference('pbls_lead_sources');
  63. if (!empty($user_tempx) && count($user_tempx) > 0 && !isset($_REQUEST['pbls_lead_sources'])) {
  64. $tempx = $user_tempx;
  65. $GLOBALS['log']->debug("USER PREFERENCES['pbls_lead_sources'] is:");
  66. $GLOBALS['log']->debug($user_tempx);
  67. }
  68. elseif (isset($_REQUEST['pbls_lead_sources']) && count($_REQUEST['pbls_lead_sources']) > 0) {
  69. $tempx = $_REQUEST['pbls_lead_sources'];
  70. $current_user->setPreference('pbls_lead_sources', $_REQUEST['pbls_lead_sources']);
  71. $GLOBALS['log']->debug("_REQUEST['pbls_lead_sources'] is:");
  72. $GLOBALS['log']->debug($_REQUEST['pbls_lead_sources']);
  73. $GLOBALS['log']->debug("USER PREFERENCES['pbls_lead_sources'] is:");
  74. $GLOBALS['log']->debug($current_user->getPreference('pbls_lead_sources'));
  75. }
  76. //set $datax using selected sales stage keys
  77. if (count($tempx) > 0) {
  78. foreach ($tempx as $key) {
  79. $datax[$key] = $app_list_strings['lead_source_dom'][$key];
  80. array_push($selected_datax,$key);
  81. }
  82. }
  83. else {
  84. $datax = $app_list_strings['lead_source_dom'];
  85. $selected_datax = array_keys($app_list_strings['lead_source_dom']);
  86. }
  87. $GLOBALS['log']->debug("datax is:");
  88. $GLOBALS['log']->debug($datax);
  89. $ids = array();
  90. $user_ids = $current_user->getPreference('pbls_ids');
  91. //get list of user ids for which to display data
  92. if (!empty($user_ids) && count($user_ids) != 0 && !isset($_REQUEST['pbls_ids'])) {
  93. if(isset($_SESSION['pbls_ids'])) {$ids = $_SESSION['pbls_ids'];}
  94. $GLOBALS['log']->debug("USER PREFERENCES['pbls_ids'] is:");
  95. $GLOBALS['log']->debug($user_ids);
  96. }
  97. elseif (isset($_REQUEST['pbls_ids']) && count($_REQUEST['pbls_ids']) > 0) {
  98. $ids = $_REQUEST['pbls_ids'];
  99. $current_user->setPreference('pbls_ids', $ids);
  100. $GLOBALS['log']->debug("_REQUEST['pbls_ids'] is:");
  101. $GLOBALS['log']->debug($_REQUEST['pbls_ids']);
  102. $GLOBALS['log']->debug("USER PREFERENCES['pbls_ids'] is:");
  103. $GLOBALS['log']->debug($current_user->getPreference('pbls_ids'));
  104. }
  105. else {
  106. $ids = get_user_array(false);
  107. $ids = array_keys($ids);
  108. }
  109. //create unique prefix based on selected users for image files
  110. $id_hash = '1';
  111. if (isset($ids) && is_array($ids)) {
  112. sort($ids);
  113. $id_hash = crc32(implode('',$ids));
  114. if($id_hash < 0)
  115. {
  116. $id_hash = $id_hash * -1;
  117. }
  118. }
  119. $GLOBALS['log']->debug("ids is:");
  120. $GLOBALS['log']->debug($ids);
  121. $id_md5 = substr(md5($current_user->id),0,9);
  122. $seps = array("-", "/");
  123. $dates = array(date($GLOBALS['timedate']->dbDayFormat), $GLOBALS['timedate']->dbDayFormat);
  124. $dateFileNameSafe = str_replace($seps, "_", $dates);
  125. $cache_file_name = sugar_cached("xml/").$current_user->getUserPrivGuid()."_pipeline_by_lead_source_".$dateFileNameSafe[0]."_".$dateFileNameSafe[1].".xml";
  126. $GLOBALS['log']->debug("cache file name is: $cache_file_name");
  127. global $currentModule,$action;
  128. $tools='<div align="right"><a href="index.php?module='.$currentModule.'&action='. $action .'&pbls_refresh=true" class="tabFormAdvLink">'.SugarThemeRegistry::current()->getImage('refresh','border="0" align="absmiddle"',null,null,'.gif',$mod_strings['LBL_REFRESH']).'&nbsp;'.$current_module_strings['LBL_REFRESH'].'</a>&nbsp;&nbsp;<a href="javascript: toggleDisplay(\'pbls_edit\');" class="tabFormAdvLink">'.SugarThemeRegistry::current()->getImage('edit','border="0" align="absmiddle"',null,null,'.gif',$mod_strings['LBL_EDIT']).'&nbsp;'. $current_module_strings['LBL_EDIT'].'</a>&nbsp;&nbsp;'.$extra_tools.'</div>';
  129. ?>
  130. <?php
  131. echo '<span onmouseover="this.style.cursor=\'move\'" id="chart_handle_' . $this->order . '">' . get_form_header($current_module_strings['LBL_LEAD_SOURCE_FORM_TITLE'],$tools,false) . '</span>';
  132. if (empty($_SESSION['pbls_lead_sources'])) $_SESSION['pbls_lead_sources'] = "";
  133. if (empty($_SESSION['pbls_ids'])) $_SESSION['pbls_ids'] = "";
  134. ?>
  135. <p>
  136. <div id='pbls_edit' style='display: none;'>
  137. <form action="index.php" method="post" >
  138. <input type="hidden" name="module" value="<?php echo $currentModule;?>">
  139. <input type="hidden" name="action" value="<?php echo $action;?>">
  140. <input type="hidden" name="pbls_refresh" value="true">
  141. <table cellpadding="0" cellspacing="0" border="0" class="edit view" align="center">
  142. <tr>
  143. <td valign='top' nowrap><b><?php echo $current_module_strings['LBL_LEAD_SOURCES'];?></b></td>
  144. <td valign='top'><select name="pbls_lead_sources[]" multiple size='3'><?php echo get_select_options_with_id($app_list_strings['lead_source_dom'],$selected_datax); ?></select></td>
  145. <td valign='top' nowrap><b><?php echo $current_module_strings['LBL_USERS'];?></b></td>
  146. <td valign='top'><select name="pbls_ids[]" multiple size='3'><?php $allUsers = get_user_array(false); echo get_select_options_with_id($allUsers,$ids); ?></select></td>
  147. <?php
  148. global $app_strings;
  149. ?>
  150. <td align="right" valign="top"><input class="button" type="submit" title="<?php echo $app_strings['LBL_SELECT_BUTTON_TITLE']; ?>" value="<?php echo $app_strings['LBL_SELECT_BUTTON_LABEL']?>" /><input class="button" onClick="javascript: toggleDisplay('pbls_edit');" type="button" title="<?php echo $app_strings['LBL_CANCEL_BUTTON_TITLE']; ?>" accessKey="<?php echo $app_strings['LBL_CANCEL_BUTTON_KEY'];?>" value="<?php echo $app_strings['LBL_CANCEL_BUTTON_LABEL']?>"/></td>
  151. </tr>
  152. </table>
  153. </form>
  154. </div>
  155. </p>
  156. <?php
  157. // draw table
  158. echo "<p align='center'>".$this->gen_xml($datax, $ids, $cache_file_name, $refresh,$current_module_strings)."</p>";
  159. echo "<P align='center'><span class='chartFootnote'>".$current_module_strings['LBL_LEAD_SOURCE_FORM_DESC']."</span></P>";
  160. if (file_exists($cache_file_name)) {
  161. global $timedate;
  162. $file_date = $timedate->asUser($timedate->fromTimestamp(filemtime($cache_file_name)));
  163. }
  164. else {
  165. $file_date = '';
  166. }
  167. ?>
  168. <span class='chartFootnote'>
  169. <p align="right"><i><?php echo $current_module_strings['LBL_CREATED_ON'].' '.$file_date; ?></i></p>
  170. </span>
  171. <?Php
  172. }
  173. /**
  174. * Creates PIE CHART image of opportunities by lead_source.
  175. * param $datax- the sales stage data to display in the x-axis
  176. * param $datay- the sum of opportunity amounts for each opportunity in each sales stage
  177. * to display in the y-axis
  178. * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc..
  179. * All Rights Reserved..
  180. * Contributor(s): ______________________________________..
  181. */
  182. function gen_xml($legends=array('foo','bar'), $user_id=array('1'), $cache_file_name='a_file', $refresh=true,$current_module_strings) {
  183. global $app_strings, $charset, $lang, $pieChartColors, $current_user;
  184. $kDelim = $current_user->getPreference('num_grp_sep');
  185. if (!file_exists($cache_file_name) || $refresh == true) {
  186. ;
  187. $GLOBALS['log']->debug("starting pipeline chart");
  188. $GLOBALS['log']->debug("legends is:");
  189. $GLOBALS['log']->debug($legends);
  190. $GLOBALS['log']->debug("user_id is: ");
  191. $GLOBALS['log']->debug($user_id);
  192. $GLOBALS['log']->debug("cache_file_name is: $cache_file_name");
  193. $opp = new Opportunity;
  194. //Now do the db queries
  195. //query for opportunity data that matches $legends and $user
  196. $where="";
  197. //build the where clause for the query that matches $user
  198. $count = count($user_id);
  199. $id = array();
  200. if ($count > 0 && !empty($user_id)) {
  201. foreach ($user_id as $the_id) {
  202. $id[] = "'".$the_id."'";
  203. }
  204. $ids = join(",",$id);
  205. $where .= "opportunities.assigned_user_id IN ($ids) ";
  206. }
  207. if(!empty($where)) $where .= 'AND';
  208. //build the where clause for the query that matches $datax
  209. $count = count($legends);
  210. $legendItem = array();
  211. if ($count > 0 && !empty($legends)) {
  212. foreach ($legends as $key=>$value) {
  213. $legendItem[] = "'".$key."'";
  214. }
  215. $legendItems = join(",",$legendItem);
  216. $where .= " opportunities.lead_source IN ($legendItems) ";
  217. }
  218. $query = "SELECT lead_source,sum(amount_usdollar/1000) as total,count(*) as opp_count FROM opportunities ";
  219. $query .= "WHERE ".$where." AND opportunities.deleted=0 ";
  220. $query .= "GROUP BY lead_source ORDER BY total DESC";
  221. //build pipeline by lead source data
  222. $total = 0;
  223. $div = 1;
  224. global $sugar_config;
  225. $symbol = $sugar_config['default_currency_symbol'];
  226. global $current_user;
  227. if($current_user->getPreference('currency') ) {
  228. $currency = new Currency();
  229. $currency->retrieve($current_user->getPreference('currency'));
  230. $div = $currency->conversion_rate;
  231. $symbol = $currency->symbol;
  232. }
  233. $subtitle = $current_module_strings['LBL_OPP_SIZE'].' '.$symbol.'1'.$current_module_strings['LBL_OPP_THOUSANDS'];
  234. $fileContents = '';
  235. $fileContents .= ' <pie defaultAltText="'.$current_module_strings['LBL_ROLLOVER_WEDGE_DETAILS'].'" legendStatus="on">'."\n";
  236. $result = $opp->db->query($query, true);
  237. $leadSourceArr = array();
  238. while($row = $opp->db->fetchByAssoc($result, false))
  239. {
  240. if($row['lead_source'] == ''){
  241. $leadSource = $current_module_strings['NTC_NO_LEGENDS'];
  242. } else {
  243. $leadSource = $row['lead_source'];
  244. }
  245. if($row['total']*$div<=100){
  246. $sum = round($row['total']*$div, 2);
  247. } else {
  248. $sum = round($row['total']*$div);
  249. }
  250. $leadSourceArr[$leadSource]['opp_count'] = $row['opp_count'];
  251. $leadSourceArr[$leadSource]['sum'] = $sum;
  252. }
  253. $i=0;
  254. foreach ($legends as $lead_source_key=>$translation) {
  255. if ($lead_source_key == '') {
  256. $lead_source_key = $current_module_strings['NTC_NO_LEGENDS'];
  257. $translation = $current_module_strings['NTC_NO_LEGENDS'];
  258. }
  259. if(!isset($leadSourceArr[$lead_source_key])) {
  260. $leadSourceArr[$lead_source_key] = $lead_source_key;
  261. $leadSourceArr[$lead_source_key]['sum'] = 0;
  262. }
  263. $color = generate_graphcolor($lead_source_key,$i);
  264. $fileContents .= ' <wedge title="'.$translation.'" kDelim="'.$kDelim.'" value="'.$leadSourceArr[$lead_source_key]['sum'].'" color="'.$color.'" labelText="'.currency_format_number($leadSourceArr[$lead_source_key]['sum'], array('currency_symbol' => true)).'" url="index.php?module=Opportunities&action=index&lead_source='.urlencode($lead_source_key).'&query=true&searchFormTab=advanced_search" altText="'.format_number($leadSourceArr[$lead_source_key]['opp_count'], 0, 0).' '.$current_module_strings['LBL_OPPS_IN_LEAD_SOURCE'].' '.$translation.'"/>'."\n";
  265. if(isset($leadSourceArr[$lead_source_key])){$total += $leadSourceArr[$lead_source_key]['sum'];}
  266. $i++;
  267. }
  268. $fileContents .= ' </pie>'."\n";
  269. $fileContents .= ' <graphInfo>'."\n";
  270. $fileContents .= ' <![CDATA[]]>'."\n";
  271. $fileContents .= ' </graphInfo>'."\n";
  272. $fileContents .= ' <chartColors ';
  273. foreach ($pieChartColors as $key => $value) {
  274. $fileContents .= ' '.$key.'='.'"'.$value.'" ';
  275. }
  276. $fileContents .= ' />'."\n";
  277. $fileContents .= '</graphData>'."\n";
  278. $total = round($total, 2);
  279. $title = $current_module_strings['LBL_TOTAL_PIPELINE'].currency_format_number($total, array('currency_symbol' => true)).$app_strings['LBL_THOUSANDS_SYMBOL'];
  280. $fileContents = '<graphData title="'.$title.'" subtitle="'.$subtitle.'">'."\n" . $fileContents;
  281. $GLOBALS['log']->debug("total is: $total");
  282. if ($total == 0) {
  283. return ($current_module_strings['ERR_NO_OPPS']);
  284. }
  285. save_xml_file($cache_file_name, $fileContents);
  286. }
  287. $return = create_chart('pieF',$cache_file_name);
  288. return $return;
  289. }
  290. function constructQuery(){
  291. global $current_user;
  292. global $app_list_strings;
  293. $tempx = array();
  294. $datax = array();
  295. $selected_datax = array();
  296. //get list of sales stage keys to display
  297. global $current_user;
  298. $user_tempx = $current_user->getPreference('pbls_lead_sources');
  299. if (!empty($user_tempx) && count($user_tempx) > 0 && !isset($_REQUEST['pbls_lead_sources'])) {
  300. $tempx = $user_tempx;
  301. $GLOBALS['log']->debug("USER PREFERENCES['pbls_lead_sources'] is:");
  302. $GLOBALS['log']->debug($user_tempx);
  303. }
  304. elseif (isset($_REQUEST['pbls_lead_sources']) && count($_REQUEST['pbls_lead_sources']) > 0) {
  305. $tempx = $_REQUEST['pbls_lead_sources'];
  306. $current_user->setPreference('pbls_lead_sources', $_REQUEST['pbls_lead_sources']);
  307. $GLOBALS['log']->debug("_REQUEST['pbls_lead_sources'] is:");
  308. $GLOBALS['log']->debug($_REQUEST['pbls_lead_sources']);
  309. $GLOBALS['log']->debug("USER PREFERENCES['pbls_lead_sources'] is:");
  310. $GLOBALS['log']->debug($current_user->getPreference('pbls_lead_sources'));
  311. }
  312. //set $datax using selected sales stage keys
  313. if (count($tempx) > 0) {
  314. foreach ($tempx as $key) {
  315. $datax[$key] = $app_list_strings['lead_source_dom'][$key];
  316. array_push($selected_datax,$key);
  317. }
  318. }
  319. else {
  320. $datax = $app_list_strings['lead_source_dom'];
  321. $selected_datax = array_keys($app_list_strings['lead_source_dom']);
  322. }
  323. $legends = $datax;
  324. $ids = array();
  325. $user_ids = $current_user->getPreference('pbls_ids');
  326. //get list of user ids for which to display data
  327. if (!empty($user_ids) && count($user_ids) != 0 && !isset($_REQUEST['pbls_ids'])) {
  328. if(isset($_SESSION['pbls_ids'])) {$ids = $_SESSION['pbls_ids'];}
  329. $GLOBALS['log']->debug("USER PREFERENCES['pbls_ids'] is:");
  330. $GLOBALS['log']->debug($user_ids);
  331. }
  332. elseif (isset($_REQUEST['pbls_ids']) && count($_REQUEST['pbls_ids']) > 0) {
  333. $ids = $_REQUEST['pbls_ids'];
  334. $current_user->setPreference('pbls_ids', $ids);
  335. $GLOBALS['log']->debug("_REQUEST['pbls_ids'] is:");
  336. $GLOBALS['log']->debug($_REQUEST['pbls_ids']);
  337. $GLOBALS['log']->debug("USER PREFERENCES['pbls_ids'] is:");
  338. $GLOBALS['log']->debug($current_user->getPreference('pbls_ids'));
  339. }
  340. else {
  341. $ids = get_user_array(false);
  342. $ids = array_keys($ids);
  343. }
  344. $user_id = $ids;
  345. $opp = new Opportunity;
  346. //Now do the db queries
  347. //query for opportunity data that matches $legends and $user
  348. $where="";
  349. //build the where clause for the query that matches $user
  350. $count = count($user_id);
  351. $id = array();
  352. if ($count > 0 && !empty($user_id)) {
  353. foreach ($user_id as $the_id) {
  354. $id[] = "'".$the_id."'";
  355. }
  356. $ids = join(",",$id);
  357. $where .= "opportunities.assigned_user_id IN ($ids) ";
  358. }
  359. if(!empty($where)) $where .= 'AND';
  360. //build the where clause for the query that matches $datax
  361. $count = count($legends);
  362. $legendItem = array();
  363. if ($count > 0 && !empty($legends)) {
  364. foreach ($legends as $key=>$value) {
  365. $legendItem[] = "'".$key."'";
  366. }
  367. $legendItems = join(",",$legendItem);
  368. $where .= " opportunities.lead_source IN ($legendItems) ";
  369. }
  370. $query = "SELECT lead_source,sum(amount_usdollar/1000) as total,count(*) as opp_count FROM opportunities ";
  371. $query .= "WHERE ".$where." AND opportunities.deleted=0 ";
  372. $query .= "GROUP BY lead_source ORDER BY total DESC";
  373. return $query;
  374. }
  375. function constructGroupBy(){
  376. return array( 'lead_source', );
  377. }
  378. }
  379. ?>