I need to show data from a search and display some statistics on a Google chart.
i have this structure:
Model: "Results" and "ResultsSearch"
Controller: "ResultsController"
Action: "actionConsulta"
View: "consulta" and the search form "_buscador"
The query returns the list of "Results" and the view show it in a GridView with the following fields:
Code - Type - Date - Status.
Additionally I need to show the total statistics of the "Results" with Status=1 (success) and with Status=0 (Failure) and also need to show statistics grouped by months, ie:
Example 1: Search "Results" of "Type = A" from "Start Date = January 1" to "End Date = March 1"
Total: 12 Success - 10 Failure
January: 1 Success - 5 Failure
February: 3 Success - 1 Failure
March 8 Success - 4 Failure
Example 2: Search for "Results" of "Type = A" from "Start Date = February 20" to "End Date= March 15"
Total: 15 Success - 10 Failure
February: 3 Success - 1 Failure
March 12 Success - 9 Failure
etc....
I have implemented with a global search to display data in the GridView:
Example 1
Code - Type - Date - Status.
01 - A - 01-01-2015 - Success
02 - A - 02-01-2015 - Failure
03 - A - 03-01-2015 - Failure
04 - A - 04-01-2015 - Failure
05 - A - 05-01-2015 - Failure
06 - A - 06-01-2015 - Failure
07 - A - 01-02-2015 - Success
08 - A - 02-02-2015 - Success
09 - A - 02-02-2015 - Success
10 - A - 03-02-2015 - Failure
etc....
To show the total stats I have made the same query for each Status (Status Success and [size="2"]Status[/size][size="2"] Failure) to then use ->[/size]getTotalCount, As the query is the same i use a function for the global query and another for the global DataProvider and then i use $query->andFilterWhere with the status param.
class ResultsSearch extends Results
{
public function consultaQuery($params)
{
$query = Resultados::find();
$this->load($params);
if (!$this->validate()) {
$query->where('0=1');
return $query;
}
$query->andFilterWhere([
'type' => $this->type,
'date' => $this->date,
]);
$query->andFilterWhere(['between', 'results.date', $this->dateStart, $this->dateEnd]);
return $query;
}
public function consultaDataProvider($query)
{
$dataProvider = new ActiveDataProvider([
'query' => $query,
]);
$dataProvider->setSort([
'attributes' => [
'id',
'type',
'date',
'status',
]
]);
return $dataProvider;
}
public function consulta($params)
{
$query = $this->consultaQuery($params);
$dataProvider = $this->consultaDataProvider($query);
$queryAptos = $this->consultaQuery($params);
$queryAptos->andFilterWhere(['status' => 1]);
$dataProviderAptos = $this->consultaDataProvider($queryAptos);
$queryNoAptos = $this->consultaQuery($params);
$queryNoAptos->andFilterWhere(['status' => 0]);
$dataProviderNoAptos = $this->consultaDataProvider($queryNoAptos);
$dataResult['dataProvider']=$dataProvider;
$dataResult['aptos']=$dataProviderAptos->getTotalCount();
$dataResult['noAptos']=$dataProviderNoAptos->getTotalCount();
return $dataResult;
}
}
To show the statistics by month I try to made a query for each Status (Status Success and [size="2"]Status[/size][size="2"] Failure) and for each month:[/size]
[size="2"]
public function consulta($params)
{
$query = $this->consultaQuery($params);
$dataProvider = $this->consultaDataProvider($query);
$queryAptos = $this->consultaQuery($params);
$queryAptos->andFilterWhere(['status' => 1]);
$dataProviderAptos = $this->consultaDataProvider($queryAptos);
$queryNoAptos = $this->consultaQuery($params);
$queryNoAptos->andFilterWhere(['status' => 0]);
$dataProviderNoAptos = $this->consultaDataProvider($queryNoAptos);
$dataResult['dataProvider']=$dataProvider;
$dataResult['aptos']=$dataProviderAptos->getTotalCount();
$dataResult['noAptos']=$dataProviderNoAptos->getTotalCount();
$queryAptosEne = $this->consultaQuery($params);
$queryAptosEne->andFilterWhere(['status' => 1]);
$queryAptosEne->andFilterWhere(['between', 'results.date, date("2015-01-01"), date("2015-01-31")]);
$dataProviderAptosEne = $this->consultaDataProvider($queryAptos);
$queryNoAptosEne = $this->consultaQuery($params);
$queryNoAptosEne->andFilterWhere(['status' => 0]);
$queryNoAptosEne->andFilterWhere(['between', 'results.date', date("2015-01-01"), date("2015-01-31")]);
$dataProviderNoAptosEne = $this->consultaDataProvider($queryNoAptos);
$ene['aptos']=$dataProviderAptosEne->getTotalCount();
$ene['noAptos']=$dataProviderNoAptosEne->getTotalCount();
$months['ene']=$ene;
$dataResult['months']=$months;
return $dataResult;
}
[/size]
This is my view "consulta"
<div id="results-lista">
//Show total stats
<?=Html::encode('Total: '$results['dataProvider']->getTotalCount().' - Aptos: '.$results['aptos'].' - No Aptos: '.$results['noAptos'])?>
//Show January stats
<?=Html::encode('Enero - Aptos: '.$results['month']['ene']['aptos'].' - No Aptos: '.$results['month']['ene']['noAptos'])?>
//Search Form
<?php echo $this->render('_buscador', ['model' => $resultsSearchModel]); ?>
//GridView
<?= GridView::widget([
'dataProvider' => $resultsDataProvider,
'filterModel' => $resultsSearchModel,
'columns' => [
'id',
'type',
'date',
'status',
],
]);
?>
</div>
[size="2"]I have no idea if this is the way to do it, or if there are some other ways.[/size]
With the following query in MySQL I get statistical data for months but i don’t know how to include it in the query and then how to use the stats on the view:
select code, type, date, status,
sum(case when (status = '1' AND orders.date_order BETWEEN '2015-01-01 00:00:00' AND '2015-01-31 00:00:00') then 1 else 0 end) AptoEne,
sum(case when (status = '1' AND orders.date_order BETWEEN '2015-02-01 00:00:00' AND '2015-02-29 00:00:00') then 1 else 0 end) AptoFeb,
sum(case when (status = '1' AND orders.date_order BETWEEN '2015-03-01 00:00:00' AND '2015-03-31 00:00:00') then 1 else 0 end) AptoMar,
sum(case when (status = '1' AND orders.date_order BETWEEN '2015-04-01 00:00:00' AND '2015-04-30 00:00:00') then 1 else 0 end) AptoAbr,
sum(case when (status = '1' AND orders.date_order BETWEEN '2015-05-01 00:00:00' AND '2015-05-31 00:00:00') then 1 else 0 end) AptoMay,
sum(case when (status = '1' AND orders.date_order BETWEEN '2015-06-01 00:00:00' AND '2015-06-30 00:00:00') then 1 else 0 end) AptoJun,
sum(case when (status = '1' AND orders.date_order BETWEEN '2015-07-01 00:00:00' AND '2015-07-31 00:00:00') then 1 else 0 end) AptoJul,
sum(case when (status = '1' AND orders.date_order BETWEEN '2015-08-01 00:00:00' AND '2015-08-31 00:00:00') then 1 else 0 end) AptoAgo,
sum(case when (status = '1' AND orders.date_order BETWEEN '2015-09-01 00:00:00' AND '2015-09-30 00:00:00') then 1 else 0 end) AptoSep,
sum(case when (status = '1' AND orders.date_order BETWEEN '2015-10-01 00:00:00' AND '2015-10-31 00:00:00') then 1 else 0 end) AptoOct,
sum(case when (status = '1' AND orders.date_order BETWEEN '2015-11-01 00:00:00' AND '2015-11-30 00:00:00') then 1 else 0 end) AptoNov,
sum(case when (status = '1' AND orders.date_order BETWEEN '2015-12-01 00:00:00' AND '2015-12-31 00:00:00') then 1 else 0 end) AptoDic,
sum(case when (status = '0' AND orders.date_order BETWEEN '2015-01-01 00:00:00' AND '2015-01-31 00:00:00') then 1 else 0 end) NoAptoEne,
sum(case when (status = '0' AND orders.date_order BETWEEN '2015-02-01 00:00:00' AND '2015-02-29 00:00:00') then 1 else 0 end) NoAptoFeb,
sum(case when (status = '0' AND orders.date_order BETWEEN '2015-03-01 00:00:00' AND '2015-03-31 00:00:00') then 1 else 0 end) NoAptoMar,
sum(case when (status = '0' AND orders.date_order BETWEEN '2015-04-01 00:00:00' AND '2015-04-30 00:00:00') then 1 else 0 end) NoAptoAbr,
sum(case when (status = '0' AND orders.date_order BETWEEN '2015-05-01 00:00:00' AND '2015-05-31 00:00:00') then 1 else 0 end) NoAptoMay,
sum(case when (status = '0' AND orders.date_order BETWEEN '2015-06-01 00:00:00' AND '2015-06-30 00:00:00') then 1 else 0 end) NoAptoJun,
sum(case when (status = '0' AND orders.date_order BETWEEN '2015-07-01 00:00:00' AND '2015-07-31 00:00:00') then 1 else 0 end) NoAptoJul,
sum(case when (status = '0' AND orders.date_order BETWEEN '2015-08-01 00:00:00' AND '2015-08-31 00:00:00') then 1 else 0 end) NoAptoAgo,
sum(case when (status = '0' AND orders.date_order BETWEEN '2015-09-01 00:00:00' AND '2015-09-30 00:00:00') then 1 else 0 end) NoAptoSep,
sum(case when (status = '0' AND orders.date_order BETWEEN '2015-10-01 00:00:00' AND '2015-10-31 00:00:00') then 1 else 0 end) NoAptoOct,
sum(case when (status = '0' AND orders.date_order BETWEEN '2015-11-01 00:00:00' AND '2015-11-30 00:00:00') then 1 else 0 end) NoAptoNov,
sum(case when (status = '0' AND orders.date_order BETWEEN '2015-12-01 00:00:00' AND '2015-12-31 00:00:00') then 1 else 0 end) NoAptoDic,
count(*) total,
sum(case when status = '1' then 1 else 0 end) Apto,
sum(case when status = '0' then 1 else 0 end) NoApto
from results
where results.cliente=28
I have also thought about the possibility of a only one global query and then filter data based on dates.