CRM-18439 - Report Fixes to include Full Group by clause
[civicrm-core.git] / CRM / Report / Form / Event / IncomeCountSummary.php
CommitLineData
6a488035 1<?php
6a488035
TO
2/*
3 +--------------------------------------------------------------------+
7e9e8871 4 | CiviCRM version 4.7 |
6a488035 5 +--------------------------------------------------------------------+
fa938177 6 | Copyright CiviCRM LLC (c) 2004-2016 |
6a488035
TO
7 +--------------------------------------------------------------------+
8 | This file is a part of CiviCRM. |
9 | |
10 | CiviCRM is free software; you can copy, modify, and distribute it |
11 | under the terms of the GNU Affero General Public License |
c73475ea 12 | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
6a488035
TO
13 | |
14 | CiviCRM is distributed in the hope that it will be useful, but |
15 | WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
17 | See the GNU Affero General Public License for more details. |
18 | |
19 | You should have received a copy of the GNU Affero General Public |
c73475ea
WA
20 | License and the CiviCRM Licensing Exception along |
21 | with this program; if not, contact CiviCRM LLC |
6a488035
TO
22 | at info[AT]civicrm[DOT]org. If you have questions about the |
23 | GNU Affero General Public License or the licensing of CiviCRM, |
24 | see the CiviCRM license FAQ at http://civicrm.org/licensing |
25 +--------------------------------------------------------------------+
d25dd0ee 26 */
6a488035
TO
27
28/**
29 *
30 * @package CRM
fa938177 31 * @copyright CiviCRM LLC (c) 2004-2016
6a488035
TO
32 * $Id$
33 *
34 */
35class CRM_Report_Form_Event_IncomeCountSummary extends CRM_Report_Form_Event {
36
37 protected $_summary = NULL;
38
39 protected $_charts = array(
40 '' => 'Tabular',
41 'barChart' => 'Bar Chart',
42 'pieChart' => 'Pie Chart',
43 );
44
45 protected $_add2groupSupported = FALSE;
46
47 protected $_customGroupExtends = array(
21dfd5f5 48 'Event',
feebd4ea 49 );
6a488035
TO
50
51 public $_drilldownReport = array('event/participantlist' => 'Link to Detail Report');
52
74cf4551 53 /**
74cf4551
EM
54 */
55 /**
74cf4551 56 */
00be9182 57 public function __construct() {
6a488035
TO
58
59 $this->_columns = array(
feebd4ea 60 'civicrm_event' => array(
6a488035 61 'dao' => 'CRM_Event_DAO_Event',
feebd4ea
EM
62 'fields' => array(
63 'title' => array(
64 'title' => ts('Event'),
6a488035
TO
65 'required' => TRUE,
66 ),
67 'id' => array(
1d0d5aff 68 'title' => 'Event ID',
6a488035
TO
69 'no_display' => TRUE,
70 'required' => TRUE,
71 ),
feebd4ea
EM
72 'event_type_id' => array(
73 'title' => ts('Event Type'),
74 ),
75 'fee_label' => array(
21dfd5f5 76 'title' => ts('Fee Label'),
6a488035 77 ),
feebd4ea
EM
78 'event_start_date' => array(
79 'title' => ts('Event Start Date'),
6a488035 80 ),
feebd4ea
EM
81 'event_end_date' => array(
82 'title' => ts('Event End Date'),
6a488035 83 ),
feebd4ea
EM
84 'max_participants' => array(
85 'title' => ts('Capacity'),
6a488035
TO
86 'type' => CRM_Utils_Type::T_INT,
87 ),
88 ),
feebd4ea 89 'filters' => array(
2107cde9
CW
90 'id' => array(
91 'title' => ts('Event'),
92 'operatorType' => CRM_Report_Form::OP_ENTITYREF,
93 'type' => CRM_Utils_Type::T_INT,
94 'attributes' => array('select' => array('minimumInputLength' => 0)),
6a488035
TO
95 ),
96 'event_type_id' => array(
97 'name' => 'event_type_id',
98 'title' => ts('Event Type'),
525ae77a 99 'type' => CRM_Utils_Type::T_INT,
6a488035
TO
100 'operatorType' => CRM_Report_Form::OP_MULTISELECT,
101 'options' => CRM_Core_OptionGroup::values('event_type'),
102 ),
feebd4ea
EM
103 'event_start_date' => array(
104 'title' => ts('Event Start Date'),
6a488035
TO
105 'operatorType' => CRM_Report_Form::OP_DATE,
106 ),
feebd4ea
EM
107 'event_end_date' => array(
108 'title' => ts('Event End Date'),
6a488035
TO
109 'operatorType' => CRM_Report_Form::OP_DATE,
110 ),
111 ),
112 ),
feebd4ea 113 'civicrm_line_item' => array(
6a488035 114 'dao' => 'CRM_Price_DAO_LineItem',
feebd4ea 115 'fields' => array(
6a488035
TO
116 'participant_count' => array(
117 'title' => ts('Participants'),
118 'default' => TRUE,
9d72cede
EM
119 'statistics' => array(
120 'count' => ts('Participants'),
121 ),
6a488035
TO
122 ),
123 'line_total' => array(
124 'title' => ts('Income Statistics'),
125 'type' => CRM_Utils_Type::T_MONEY,
126 'default' => TRUE,
9d72cede
EM
127 'statistics' => array(
128 'sum' => ts('Income'),
129 'avg' => ts('Average'),
130 ),
6a488035
TO
131 ),
132 ),
133 ),
feebd4ea 134 'civicrm_participant' => array(
6a488035 135 'dao' => 'CRM_Event_DAO_Participant',
feebd4ea
EM
136 'filters' => array(
137 'sid' => array(
138 'name' => 'status_id',
6a488035 139 'title' => ts('Participant Status'),
525ae77a 140 'type' => CRM_Utils_Type::T_INT,
6a488035
TO
141 'operatorType' => CRM_Report_Form::OP_MULTISELECT,
142 'options' => CRM_Event_PseudoConstant::participantStatus(),
143 ),
144 'rid' => array(
145 'name' => 'role_id',
146 'title' => ts('Participant Role'),
525ae77a 147 'type' => CRM_Utils_Type::T_INT,
6a488035
TO
148 'operatorType' => CRM_Report_Form::OP_MULTISELECT,
149 'options' => CRM_Event_PseudoConstant::participantRole(),
150 ),
feebd4ea
EM
151 'participant_register_date' => array(
152 'title' => ts('Registration Date'),
6a488035
TO
153 'operatorType' => CRM_Report_Form::OP_DATE,
154 ),
155 ),
156 ),
157 );
158 parent::__construct();
159 }
160
00be9182 161 public function preProcess() {
6a488035
TO
162 parent::preProcess();
163 }
164
00be9182 165 public function select() {
6a488035
TO
166 $select = array();
167 foreach ($this->_columns as $tableName => $table) {
168 if (array_key_exists('fields', $table)) {
169 foreach ($table['fields'] as $fieldName => $field) {
9d72cede
EM
170 if (!empty($field['required']) ||
171 !empty($this->_params['fields'][$fieldName])
172 ) {
a7488080 173 if (!empty($field['statistics'])) {
6a488035
TO
174 foreach ($field['statistics'] as $stat => $label) {
175 switch (strtolower($stat)) {
176 case 'count':
177 $select[] = "SUM({$field['dbAlias']}) as {$tableName}_{$fieldName}_{$stat}";
178 $this->_columnHeaders["{$tableName}_{$fieldName}_{$stat}"]['type'] = CRM_Utils_Type::T_INT;
179 $this->_columnHeaders["{$tableName}_{$fieldName}_{$stat}"]['title'] = $label;
180 $this->_statFields[] = "{$tableName}_{$fieldName}_{$stat}";
181 break;
182
183 case 'sum':
184 $select[] = "SUM({$field['dbAlias']}) as {$tableName}_{$fieldName}_{$stat}";
185 $this->_columnHeaders["{$tableName}_{$fieldName}_{$stat}"]['type'] = CRM_Utils_Type::T_MONEY;
186
187 $this->_columnHeaders["{$tableName}_{$fieldName}_{$stat}"]['title'] = $label;
188 $this->_statFields[] = "{$tableName}_{$fieldName}_{$stat}";
189 break;
190
191 case 'avg':
192 $this->_columnHeaders["{$tableName}_{$fieldName}_{$stat}"]['title'] = $label;
193
194 $this->_columnHeaders["{$tableName}_{$fieldName}_{$stat}"]['type'] = CRM_Utils_Type::T_MONEY;
195 $this->_statFields[] = "{$tableName}_{$fieldName}_{$stat}";
196 }
197 }
198 }
199 else {
200 $select[] = "{$field['dbAlias']} as {$tableName}_{$fieldName}";
201 $this->_columnHeaders["{$tableName}_{$fieldName}"]['type'] = CRM_Utils_Array::value('type', $field);
202 $this->_columnHeaders["{$tableName}_{$fieldName}"]['title'] = $field['title'];
203 }
204 }
205 }
206 }
207 }
d1641c51 208 $this->_selectClauses = $select;
6a488035
TO
209
210 $this->_select = "SELECT " . implode(', ', $select);
211 }
212
00be9182 213 public function from() {
2f4c2f5d 214 $this->_from = "
6a488035 215 FROM civicrm_event {$this->_aliases['civicrm_event']}
2f4c2f5d 216 LEFT JOIN civicrm_participant {$this->_aliases['civicrm_participant']}
217 ON {$this->_aliases['civicrm_event']}.id = {$this->_aliases['civicrm_participant']}.event_id AND
218 {$this->_aliases['civicrm_participant']}.is_test = 0
6a488035 219 LEFT JOIN civicrm_line_item {$this->_aliases['civicrm_line_item']}
2f4c2f5d 220 ON {$this->_aliases['civicrm_participant']}.id ={$this->_aliases['civicrm_line_item']}.entity_id AND
6a488035
TO
221 {$this->_aliases['civicrm_line_item']}.entity_table = 'civicrm_participant' ";
222 }
223
00be9182 224 public function where() {
6a488035
TO
225 $clauses = array();
226 $this->_participantWhere = "";
227 foreach ($this->_columns as $tableName => $table) {
228 if (array_key_exists('filters', $table)) {
229 foreach ($table['filters'] as $fieldName => $field) {
230 $clause = NULL;
231 if (CRM_Utils_Array::value('type', $field) & CRM_Utils_Type::T_DATE) {
232 $relative = CRM_Utils_Array::value("{$fieldName}_relative", $this->_params);
feebd4ea
EM
233 $from = CRM_Utils_Array::value("{$fieldName}_from", $this->_params);
234 $to = CRM_Utils_Array::value("{$fieldName}_to", $this->_params);
6a488035
TO
235
236 if ($relative || $from || $to) {
237 $clause = $this->dateClause($field['name'], $relative, $from, $to, $field['type']);
238 }
239 }
240 else {
241 $op = CRM_Utils_Array::value("{$fieldName}_op", $this->_params);
242 if ($op) {
243 $clause = $this->whereClause($field,
244 $op,
245 CRM_Utils_Array::value("{$fieldName}_value", $this->_params),
246 CRM_Utils_Array::value("{$fieldName}_min", $this->_params),
247 CRM_Utils_Array::value("{$fieldName}_max", $this->_params)
248 );
249 }
250 }
251 if (!empty($this->_params['id_value'])) {
9e1d5fcb
CW
252 $idValue = is_array($this->_params['id_value']) ? implode(',', $this->_params['id_value']) : $this->_params['id_value'];
253 $this->_participantWhere = " AND civicrm_participant.event_id IN ( $idValue ) ";
6a488035
TO
254 }
255
256 if (!empty($clause)) {
257 $clauses[] = $clause;
258 }
259 }
260 }
261 }
99f13d8d 262 $clauses[] = "{$this->_aliases['civicrm_event']}.is_template = 0";
6a488035
TO
263 $this->_where = "WHERE " . implode(' AND ', $clauses);
264 }
265
74cf4551
EM
266 /**
267 * @param $rows
268 *
269 * @return array
270 */
00be9182 271 public function statistics(&$rows) {
6a488035
TO
272 $statistics = parent::statistics($rows);
273 $select = "
274 SELECT SUM( {$this->_aliases['civicrm_line_item']}.participant_count ) as count,
275 SUM( {$this->_aliases['civicrm_line_item']}.line_total ) as amount";
276
277 $sql = "{$select} {$this->_from} {$this->_where}";
278
279 $dao = CRM_Core_DAO::executeQuery($sql);
280
281 if ($dao->fetch()) {
1d0d5aff 282 $avg = 0;
6a488035
TO
283 if ($dao->count && $dao->amount) {
284 $avg = $dao->amount / $dao->count;
285 }
286 $statistics['counts']['count'] = array(
287 'value' => $dao->count,
288 'title' => 'Total Participants',
289 'type' => CRM_Utils_Type::T_INT,
290 );
291 $statistics['counts']['amount'] = array(
292 'value' => $dao->amount,
293 'title' => 'Total Income',
294 'type' => CRM_Utils_Type::T_MONEY,
295 );
1d0d5aff 296 $statistics['counts']['avg'] = array(
6a488035
TO
297 'value' => $avg,
298 'title' => 'Average',
299 'type' => CRM_Utils_Type::T_MONEY,
300 );
301 }
302 return $statistics;
303 }
304
00be9182 305 public function groupBy() {
6a488035
TO
306 $this->assign('chartSupported', TRUE);
307 $this->_rollup = " WITH ROLLUP";
d1641c51 308 $groupFromSelect = CRM_Contact_BAO_Query::getGroupByFromSelectColumns($this->_selectClauses, "{$this->_aliases['civicrm_event']}.id");
309 $this->_groupBy = " GROUP BY {$this->_aliases['civicrm_event']}.id {$groupFromSelect} {$this->_rollup}";
6a488035
TO
310 }
311
00be9182 312 public function postProcess() {
6a488035
TO
313
314 $this->beginPostProcess();
315
316 $sql = $this->buildQuery(TRUE);
317
318 $dao = CRM_Core_DAO::executeQuery($sql);
319
320 //set pager before execution of query in function participantInfo()
321 $this->setPager();
322
323 $rows = $graphRows = array();
324 $count = 0;
325
326 while ($dao->fetch()) {
327 $row = array();
328 foreach ($this->_columnHeaders as $key => $value) {
9d72cede
EM
329 if (($key == 'civicrm_event_start_date') ||
330 ($key == 'civicrm_event_end_date')
331 ) {
6a488035
TO
332 //get event start date and end date in custom datetime format
333 $row[$key] = CRM_Utils_Date::customFormat($dao->$key);
334 }
335 elseif ($key == 'civicrm_participant_fee_amount_avg') {
9d72cede
EM
336 if ($dao->civicrm_participant_fee_amount_sum &&
337 $dao->civicrm_line_item_participant_count_count
338 ) {
339 $row[$key] = $dao->civicrm_participant_fee_amount_sum /
340 $dao->civicrm_line_item_participant_count_count;
6a488035
TO
341 }
342 }
343 elseif ($key == 'civicrm_line_item_line_total_avg') {
9d72cede
EM
344 if ($dao->civicrm_line_item_line_total_sum &&
345 $dao->civicrm_line_item_participant_count_count
346 ) {
347 $row[$key] = $dao->civicrm_line_item_line_total_sum /
348 $dao->civicrm_line_item_participant_count_count;
6a488035
TO
349 }
350 }
351 else {
352 if (isset($dao->$key)) {
353 $row[$key] = $dao->$key;
354 }
355 }
356 }
357 $rows[] = $row;
358 }
359
360 // do not call pager here
361 $this->formatDisplay($rows, FALSE);
362 unset($this->_columnHeaders['civicrm_event_id']);
363
364 $this->doTemplateAssignment($rows);
365
366 $this->endPostProcess($rows);
367 }
368
74cf4551
EM
369 /**
370 * @param $rows
371 */
00be9182 372 public function buildChart(&$rows) {
6a488035
TO
373
374 $this->_interval = 'events';
375 $countEvent = NULL;
a7488080 376 if (!empty($this->_params['charts'])) {
6a488035
TO
377 foreach ($rows as $key => $value) {
378 if ($value['civicrm_event_id']) {
379 $graphRows['totalParticipants'][] = ($rows[$key]['civicrm_line_item_participant_count_count']);
795492f3 380 $graphRows[$this->_interval][] = substr($rows[$key]['civicrm_event_title'], 0, 12) . "..(" .
9d72cede 381 $rows[$key]['civicrm_event_id'] . ") ";
6a488035
TO
382 $graphRows['value'][] = ($rows[$key]['civicrm_line_item_participant_count_count']);
383 }
384 }
385
386 if (($rows[$key]['civicrm_line_item_participant_count_count']) == 0) {
387 $countEvent = count($rows);
388 }
389
390 if ((!empty($rows)) && $countEvent != 1) {
391 $chartInfo = array(
392 'legend' => 'Participants Summary',
393 'xname' => 'Event',
394 'yname' => 'Total Participants',
395 );
396 if (!empty($graphRows)) {
397 foreach ($graphRows[$this->_interval] as $key => $val) {
398 $graph[$val] = $graphRows['value'][$key];
399 }
400 $chartInfo['values'] = $graph;
401 $chartInfo['tip'] = 'Participants : #val#';
402 $chartInfo['xLabelAngle'] = 20;
403
404 // build the chart.
405 CRM_Utils_OpenFlashChart::buildChart($chartInfo, $this->_params['charts']);
406 }
407 }
408 }
409 }
410
74cf4551 411 /**
ced9bfed
EM
412 * Alter display of rows.
413 *
414 * Iterate through the rows retrieved via SQL and make changes for display purposes,
415 * such as rendering contacts as links.
416 *
417 * @param array $rows
418 * Rows generated by SQL, with an array for each row.
74cf4551 419 */
00be9182 420 public function alterDisplay(&$rows) {
6a488035
TO
421
422 if (is_array($rows)) {
423 $eventType = CRM_Core_OptionGroup::values('event_type');
424
425 foreach ($rows as $rowNum => $row) {
426 if (array_key_exists('civicrm_event_title', $row)) {
427 if ($value = $row['civicrm_event_id']) {
428 CRM_Event_PseudoConstant::event($value, FALSE);
429 $url = CRM_Report_Utils_Report::getNextUrl('event/participantlist',
430 'reset=1&force=1&event_id_op=eq&event_id_value=' . $value,
431 $this->_absoluteUrl, $this->_id, $this->_drilldownReport
432 );
433 $rows[$rowNum]['civicrm_event_title_link'] = $url;
434 $rows[$rowNum]['civicrm_event_title_hover'] = ts("View Event Participants For this Event");
435 }
436 }
437
438 //handle event type
439 if (array_key_exists('civicrm_event_event_type_id', $row)) {
440 if ($value = $row['civicrm_event_event_type_id']) {
441 $rows[$rowNum]['civicrm_event_event_type_id'] = $eventType[$value];
442 }
443 }
444 }
445 }
446 }
96025800 447
6a488035 448}