I’m trying add some new dashlets on SuiteCRM, they work fine, but my popup for filtering options doesn’t work.
I select the options I want to be shown and when I click on save nothing happens. It’s a graph dashlet.
Other dashlets work fine when I filter the options, but none of the ones I created work.
I think it must be something obvious but I’ve already tried everything i could.
I’m guessing it is because it isn’t registering the options I selected, but I have no idea how to fix this, and I don’t really know if this is really the issue.
My log shows “[2947][1][FATAL] Exception in Controller: String could not be parsed as XML”, but I tried to work on that with things I saw suggested here, but it didn’t have any effect.
MyDashlet.php
require_once('include/Dashlets/DashletGenericChart.php');
class MyDashlet extends DashletGenericChart
{
public $pbss_date_start;
public $pbss_date_end;
public $sales_stage = array();
/**
* @see DashletGenericChart::$_seedName
*/
protected $_seedName = 'Opportunities';
/**
* @see DashletGenericChart::__construct()
*/
public function __construct(
$id,
array $options = null
)
{
global $timedate;
if(empty($options['pbss_date_start']))
$options['pbss_date_start'] = $timedate->nowDbDate();
if(empty($options['pbss_date_end']))
$options['pbss_date_end'] = $timedate->asDbDate($timedate->getNow()->modify("+6 months"));
//if(empty($options['title']))
$options['title'] = '<a href="http://crmpesa.wikiconsultoria.com.br/index.php?module=AOR_Reports&action=DetailView&record=d6e1923d-a5de-53fe-7202-576bd580630b" target="_blank">Funil de Oportunidades</a>';
$options['autoRefresh'] = 60;
parent::__construct($id,$options);
}
/**
* @see DashletGenericChart::displayOptions()
*/
public function displayOptions()
{
global $app_list_strings;
if (!empty($this->sales_stage) && count($this->sales_stage) > 0)
foreach ($this->sales_stage as $key)
$selected_datax[] = $key;
else
$selected_datax = array_keys($app_list_strings['sales_stage']);
$this->_searchFields['sales_stage']['options'] = $app_list_strings['sales_stage'];
$this->_searchFields['sales_stage']['input_name0'] = $selected_datax;
$GLOBALS['log']->fatal("----------------------------- Tipo: ".count($this->sales_stage));
return parent::displayOptions();
}
/**
* @see DashletGenericChart::display()
*/
public function display()
{
global $current_user, $sugar_config, $app_list_strings;
$is_currency = true;
$thousands_symbol = translate('LBL_OPP_THOUSANDS', 'Charts');
$currency_symbol = $sugar_config['default_currency_symbol'];
if ($current_user->getPreference('currency')){
$currency = new Currency();
$currency->retrieve($current_user->getPreference('currency'));
$currency_symbol = $currency->symbol;
}else{
$currency_symbol = 'R$ ';
}
$data = $this->getChartData($this->constructQuery());
//$chartReadyData = $this->prepareChartData($data, $currency_symbol, $thousands_symbol);
//$jsonData = json_encode($chartReadyData['data']);
// $jsonLabels = json_encode($chartReadyData['labels']);
// $jsonLabelsAndValues = json_encode($chartReadyData['labelsAndValues']);
$i = 0;
$dados = '';
//Montando o Json
/*foreach($chartReadyData['data'] as $value){
$chave = $chartReadyData['labels'][$i];
$label = $app_list_strings['sales_stage_dom'][$chave];
$dados= $dados."['".$label."',".$value."],";
$i++;
}*/
//echo $dados;
//$total = $chartReadyData['total'];
$startDate = $this->pbss_date_start;
$endDate = $this->pbss_date_end;
//TODO find a better way of doing this
$canvasId = 'rGraphFunnel'.uniqid();
//These are taken in the same fashion as the hard-coded array above
$module = 'Opportunities';
$action = 'index';
$query ='true';
$searchFormTab ='advanced_search';
$chartWidth = 900;
$chartHeight = 500;
$autoRefresh = $this->processAutoRefresh();//$autoRefresh
$colours = "['#a6cee3','#1f78b4','#b2df8a','#33a02c','#fb9a99','#e31a1c','#fdbf6f','#ff7f00','#cab2d6','#6a3d9a','#ffff99','#b15928']";
//<canvas id='$canvasId' width='$chartWidth' height='$chartHeight'>[No canvas support]</canvas>
//<canvas id='test123' width='$chartWidth' height='$chartHeight'>[No canvas support]</canvas>
//There is always an ending anchor value, hence this check is that the data array is less than 2
/*if(!is_array($chartReadyData['data'])||count($chartReadyData['data']) < 2)
{
return "<h3 class='noGraphDataPoints'>$this->noDataMessage</h3>";
}*/
$notChart = ' <div class="oddListRowS1">
<div class="footable-visible footable-last-column footable-first-column" style="padding-top: 10px;
padding-bottom: 10px; padding-left: 5px;"><em>Sem Dados</em></div>
</div> ';
$chart = "<div id='$canvasId' class='resizableCanvas' style='auto; height:auto; margin:auto;'></div>
<input type='hidden' class='startDate' value='$startDate' />
<input type='hidden' class='endDate' value='$endDate' />
<input type='hidden' class='module' value='$module' />
<input type='hidden' class='action' value='$action' />
<input type='hidden' class='query' value='$query' />
<input type='hidden' class='searchFormTab' value='$searchFormTab' />
<script>
$(function () {
$('#$canvasId').highcharts({
chart: {
type: 'funnel',
marginRight: 150
},
title: {
text: '',
x: 50
},
plotOptions: {
series: {
dataLabels: {
enabled: true,
format: '<b>{point.name}</b> ({point.y:,.0f})',
color: (Highcharts.theme && Highcharts.theme.contrastTextColor) || 'black',
softConnector: true
}
}
},
legend: {
enabled: false
},
series: [{
name: 'Quantidade',
data: [$data]
}]
});
});
</script>
";
$result = ($data == null) ? $notChart : $chart;
return $result;
}
function getChartData($query)
{
global $db;
$result = $db->query($query);
while($row = $db->fetchByAssoc($result, false)) {
$estagio = str_replace("_", " ", $row['sales_stage']);
$data = $data."['".utf8_encode($estagio)."', ".$row['qtde']."], ";
}
$data = ltrim($data, ", ");
return $data;
}
/**
* awu: Bug 16794 - this function is a hack to get the correct sales stage order until
* i can clean it up later
*
* @param $query string
* @return array
*/
/*function getChartData(
$query
)
{
global $app_list_strings, $db;
$data = array();
$temp_data = array();
$selected_datax = array();
$user_sales_stage = $this->pbss_sales_stages;
$tempx = $user_sales_stage;
//set $datax using selected sales stage keys
if (count($tempx) > 0) {
foreach ($tempx as $key) {
$datax[$key] = $app_list_strings['sales_stage_dom'][$key];
$selected_datax[] = $key;
}
}
else {
$datax = $app_list_strings['sales_stage_dom'];
$selected_datax = array_keys($app_list_strings['sales_stage_dom']);
}
$result = $db->query($query);
while($row = $db->fetchByAssoc($result, false))
$temp_data[] = $row;
// reorder and set the array based on the order of selected_datax
foreach($selected_datax as $sales_stage){
foreach($temp_data as $key => $value){
if ($value['sales_stage'] == $sales_stage){
$value['sales_stage'] = $app_list_strings['sales_stage_dom'][$value['sales_stage']];
$value['key'] = $sales_stage;
$value['value'] = $value['sales_stage'];
$data[] = $value;
unset($temp_data[$key]);
}
}
}
return $data;
}*/
/**
* @see DashletGenericChart::constructQuery()
*/
protected function constructQuery()
{
global $current_user;
$id_user = $current_user->id;
$query = " SELECT O.sales_stage, count(*) AS qtde
FROM opportunities O
JOIN
opportunities_cstm OC ON OC.id_c = O.id";
$query .= " WHERE O.assigned_user_id = '".$id_user."'
AND O.date_entered >= ". db_convert("'".$this->pbss_date_start."'",'date').
" AND O.date_entered <= ".db_convert("'".$this->pbss_date_end."'",'date') .
" AND O.deleted = 0 ";
if (count($this->sales_stage) > 0)
$query .= " AND O.sales_stage IN ('" . implode("','",$this->sales_stage) . "') ";
$query .= " GROUP BY O.sales_stage ORDER BY O.sales_stage DESC ";
return $query;
}
/*protected function constructQuery()
{
$query = " SELECT opportunities.sales_stage,
users.user_name,
opportunities.assigned_user_id,
count(*) AS opp_count,
sum(amount_usdollar/1000) AS total
FROM users,opportunities ";
$query .= " WHERE opportunities.date_closed >= ". db_convert("'".$this->pbss_date_start."'",'date').
" AND opportunities.date_closed <= ".db_convert("'".$this->pbss_date_end."'",'date') .
" AND opportunities.assigned_user_id = users.id AND opportunities.deleted=0 ";
if ( count($this->pbss_sales_stages) > 0 )
$query .= " AND opportunities.sales_stage IN ('" . implode("','",$this->pbss_sales_stages) . "') ";
$query .= " GROUP BY opportunities.sales_stage ,users.user_name,opportunities.assigned_user_id";
return $query;
}*/
/*
protected function constructQuery()
{
$query = " SELECT opportunities.sales_stage,
count(*) AS opp_count,
sum(amount_usdollar/1000) AS total
FROM users,opportunities ";
$query .= " WHERE opportunities.date_closed >= ". db_convert("'".$this->pbss_date_start."'",'date').
" AND opportunities.date_closed <= ".db_convert("'".$this->pbss_date_end."'",'date') .
" AND opportunities.assigned_user_id = users.id AND opportunities.deleted=0 ";
$query .= " GROUP BY opportunities.sales_stage";
return $query;
}*/
protected function prepareChartData($data,$currency_symbol, $thousands_symbol)
{
//return $data;
$chart['labels']=array();
$chart['data']=array();
$total = 0;
foreach($data as $i)
{
//$chart['labelsAndValues'][]=$i['key'].' ('.$currency.(int)$i['total'].')';
$chart['labelsAndValues'][]=$i['key'].' ('.$currency_symbol.(int)$i['total'].$thousands_symbol.')';
$chart['labels'][]=$i['key'];
$chart['data'][]=(int)$i['total'];
$total+=(int)$i['total'];
}
//The funnel needs n+1 elements (to bind the shape to as per http://www.rgraph.net/demos/funnel-interactive-key.html)
//$chart['data'][]=1;
$chart['total']=$total;
return $chart;
}
}
MyDashletConfigure.tpl
<div style='width: 400px'>
<form name='configure_{$id}' action="index.php" method="post" onSubmit='return SUGAR.dashlets.postForm("configure_{$id}", SUGAR.mySugar.uncoverPage);'>
<input type='hidden' name='id' value='{$id}'>
<input type='hidden' name='module' value='Opportunities'>
<input type='hidden' name='action' value='DynamicAction'>
<input type='hidden' name='DynamicAction' value='configureDashlet'>
<input type='hidden' name='to_pdf' value='true'>
<input type='hidden' name='configure' value='true'>
<input type='hidden' id='dashletType' name='dashletType' value='{$dashletType}' />
<table width="400" cellpadding="0" cellspacing="0" border="0" class="edit view" align="center">
<tr>
<td valign='top' class='dataLabel' nowrap>{$LBL_TITLE} <br /></td>
<td valign='top' class='dataField'>
<input type="text" value="{$dashlet_title}" size="30" name="mypbss_dashlet_title"/>
</td>
</tr>
<tr>
<td valign='top' nowrap class='dataLabel'>{$LBL_DATE_START} <br><i>{$user_date_format}</i></td>
<td valign='top' class='dataField'>
<input onblur="parseDate(this, '{$cal_dateformat}');" class="text" name="mypbss_date_start" size='12' maxlength='10' id='date_start' value='{$date_start}'>
{sugar_getimage name="jscalendar" ext=".gif" alt=$LBL_ENTER_DATE other_attributes='align="absmiddle" id="date_start_trigger" '}
</td>
</tr>
<tr>
<td valign='top' nowrap class='dataLabel'>{$LBL_DATE_END}<br><i>{$user_date_format}</i></td>
<td valign='top' class='dataField'>
<input onblur="parseDate(this, '{$cal_dateformat}');" class="text" name="mypbss_date_end" size='12' maxlength='10' id='date_end' value='{$date_end}'>
{sugar_getimage name="jscalendar" ext=".gif" alt=$LBL_ENTER_DATE other_attributes='align="absmiddle" id="date_end_trigger" '}
</td>
</tr>
<tr>
<td valign='top' class='dataLabel' nowrap>{$LBL_SALES_STAGES}</td>
<td valign='top' class='dataField'>
<select name="sales_stage[]" multiple size='3'>
{$selected_datax}
</select></td>
</tr>
<tr>
<td align="right" colspan="2">
<input type='submit' onclick="" class='button' value='{$LBL_SUBMIT_BUTTON_LABEL}'>
</td>
</tr>
</table>
</form>
{literal}
<script type="text/javascript">
Calendar.setup ({
inputField : "date_start", ifFormat : "{/literal}{$cal_dateformat}{literal}", showsTime : false, button : "date_start_trigger", singleClick : true, step : 1, weekNumbers:false
});
Calendar.setup ({
inputField : "date_end", ifFormat : "{/literal}{$cal_dateformat}{literal}", showsTime : false, button : "date_end_trigger", singleClick : true, step : 1, weekNumbers:false
});
{/literal}
</script>
</div>
MyDashlet.data.php
$dashletData['MyDashlet']['searchFields'] = array(
'pbss_date_start' => array(
'name' => 'pbss_date_start',
'vname' => 'Data de:',
'type' => 'datepicker',
),
'pbss_date_end' => array(
'name' => 'pbss_date_end',
'vname' => utf8_encode('Data à:'),
'type' => 'datepicker',
),
'sales_stage' => array(
'name' => 'sales_stage',
'vname' => 'LBL_SALES_STAGES',
'type' => 'enum',
),
);
?>
MyDashlet.meta.php
global $app_strings, $current_language;
$dashletMeta['MyDashlet'] = array('title' => 'LBL_TITLE',
'description' => 'LBL_TITLE',
'icon' => 'themes/default/images/icon_Charts_Funnel_32.gif',
'module' => 'Opportunities',
'category' => 'Charts');