3 +--------------------------------------------------------------------+
4 | Copyright CiviCRM LLC. All rights reserved. |
6 | This work is published under the GNU AGPLv3 license with some |
7 | permitted exceptions and without any warranty. For full license |
8 | and copyright information, see https://civicrm.org/licensing |
9 +--------------------------------------------------------------------+
15 * @copyright CiviCRM LLC https://civicrm.org/licensing
17 class CRM_Report_Form_Contribute_PCP
extends CRM_Report_Form
{
22 public function __construct() {
24 'civicrm_contact' => [
25 'dao' => 'CRM_Contact_DAO_Contact',
28 'title' => ts('Supporter'),
37 'title' => ts('Supporter Contact Type'),
39 'contact_sub_type' => [
40 'title' => ts('Supporter Contact Subtype'),
45 'title' => ts('Supporter Name'),
46 'type' => CRM_Utils_Type
::T_STRING
,
50 'title' => ts('Contact ID'),
54 'grouping' => 'pcp-fields',
56 'civicrm_contribution_page' => [
57 'dao' => 'CRM_Contribute_DAO_ContributionPage',
61 'title' => ts('Page Title'),
63 'dbAlias' => 'coalesce(cp_civireport.title, e_civireport.title)',
69 'title' => ts('Contribution Page Title'),
71 'type' => CRM_Utils_Type
::T_STRING
,
74 'grouping' => 'pcp-fields',
80 'title' => ts('Event Title'),
82 'type' => CRM_Utils_Type
::T_STRING
,
85 'grouping' => 'pcp-fields',
88 'dao' => 'CRM_PCP_DAO_PCP',
91 'title' => ts('Personal Campaign Title'),
95 'title' => ts('Page Type'),
99 'title' => ts('Goal Amount'),
100 'type' => CRM_Utils_Type
::T_MONEY
,
106 'title' => ts('Personal Campaign Title'),
107 'type' => CRM_Utils_Type
::T_STRING
,
115 'title' => ts('Personal Campaign Page'),
118 'grouping' => 'pcp-fields',
120 'civicrm_contribution_soft' => [
121 'dao' => 'CRM_Contribute_DAO_ContributionSoft',
124 'title' => ts('Committed Amount'),
126 'type' => CRM_Utils_Type
::T_MONEY
,
129 'sum' => ts('Committed Amount'),
133 'title' => ts('Amount Received'),
135 'type' => CRM_Utils_Type
::T_MONEY
,
137 // nice trick with dbAlias
138 'dbAlias' => 'SUM(IF( contribution_civireport.contribution_status_id > 1, 0, contribution_soft_civireport.amount))',
141 'title' => ts('Number of Donors'),
145 'count' => ts('Number of Donors'),
151 'title' => ts('Amount Received'),
152 'type' => CRM_Utils_Type
::T_MONEY
,
153 'dbAlias' => 'SUM(IF( contribution_civireport.contribution_status_id > 1, 0, contribution_soft_civireport.amount))',
156 'grouping' => 'pcp-fields',
158 'civicrm_contribution' => [
159 'dao' => 'CRM_Contribute_DAO_Contribution',
161 'contribution_id' => [
163 'no_display' => TRUE,
167 'title' => ts('Most Recent Contribution'),
170 'max' => ts('Most Recent Contribution'),
175 'contribution_status_id' => [
176 'title' => ts('Contribution Status'),
177 'operatorType' => CRM_Report_Form
::OP_MULTISELECT
,
178 'options' => CRM_Contribute_PseudoConstant
::contributionStatus(),
182 'grouping' => 'pcp-fields',
184 'civicrm_financial_trxn' => [
185 'dao' => 'CRM_Financial_DAO_FinancialTrxn',
188 'title' => ts('Credit Card Type'),
189 'dbAlias' => 'GROUP_CONCAT(financial_trxn_civireport.card_type_id SEPARATOR ",")',
194 'title' => ts('Credit Card Type'),
195 'operatorType' => CRM_Report_Form
::OP_MULTISELECT
,
196 'options' => CRM_Financial_DAO_FinancialTrxn
::buildOptions('card_type_id'),
198 'type' => CRM_Utils_Type
::T_STRING
,
204 parent
::__construct();
205 $this->optimisedForOnlyFullGroupBy
= FALSE;
208 public function from() {
210 FROM civicrm_pcp {$this->_aliases['civicrm_pcp']}
212 LEFT JOIN civicrm_contribution_soft {$this->_aliases['civicrm_contribution_soft']}
213 ON {$this->_aliases['civicrm_pcp']}.id =
214 {$this->_aliases['civicrm_contribution_soft']}.pcp_id
216 LEFT JOIN civicrm_contribution {$this->_aliases['civicrm_contribution']}
217 ON {$this->_aliases['civicrm_contribution_soft']}.contribution_id =
218 {$this->_aliases['civicrm_contribution']}.id
220 LEFT JOIN civicrm_contact {$this->_aliases['civicrm_contact']}
221 ON {$this->_aliases['civicrm_pcp']}.contact_id =
222 {$this->_aliases['civicrm_contact']}.id
224 LEFT JOIN civicrm_contribution_page {$this->_aliases['civicrm_contribution_page']}
225 ON {$this->_aliases['civicrm_pcp']}.page_id =
226 {$this->_aliases['civicrm_contribution_page']}.id
227 AND {$this->_aliases['civicrm_pcp']}.page_type = 'contribute'
229 LEFT JOIN civicrm_event {$this->_aliases['civicrm_event']}
230 ON {$this->_aliases['civicrm_pcp']}.page_id =
231 {$this->_aliases['civicrm_event']}.id
232 AND {$this->_aliases['civicrm_pcp']}.page_type = 'event'";
234 // for credit card type
235 $this->addFinancialTrxnFromClause();
238 public function orderBy() {
239 $this->_orderBy
= " ORDER BY {$this->_aliases['civicrm_contact']}.sort_name ";
242 public function where() {
243 $whereClauses = $havingClauses = [];
245 foreach ($this->_columns
as $tableName => $table) {
246 if (array_key_exists('filters', $table)) {
247 foreach ($table['filters'] as $fieldName => $field) {
250 if (CRM_Utils_Array
::value('type', $field) & CRM_Utils_Type
::T_DATE
) {
251 $relative = $this->_params
["{$fieldName}_relative"] ??
NULL;
252 $from = $this->_params
["{$fieldName}_from"] ??
NULL;
253 $to = $this->_params
["{$fieldName}_to"] ??
NULL;
254 $clause = $this->dateClause($field['name'], $relative, $from, $to, $field['type']);
257 $op = $this->_params
["{$fieldName}_op"] ??
NULL;
260 $clause = $this->whereClause($field,
262 CRM_Utils_Array
::value("{$fieldName}_value", $this->_params
),
263 CRM_Utils_Array
::value("{$fieldName}_min", $this->_params
),
264 CRM_Utils_Array
::value("{$fieldName}_max", $this->_params
)
269 if (!empty($clause)) {
270 if ($tableName == 'civicrm_contribution_soft' &&
271 $fieldName == 'amount_2'
273 $havingClauses[] = $clause;
276 $whereClauses[] = $clause;
282 if (empty($whereClauses)) {
283 $this->_where
= "WHERE ( 1 ) ";
286 $this->_where
= "WHERE " . implode(' AND ', $whereClauses);
288 if ($this->_aclWhere
) {
289 $this->_where
.= " AND {$this->_aclWhere} ";
292 if (!empty($havingClauses)) {
293 // use this clause to construct group by clause.
294 $this->_having
= "HAVING " . implode(' AND ', $havingClauses);
303 public function statistics(&$rows) {
304 $statistics = parent
::statistics($rows);
306 // Calculate totals from the civicrm_contribution_soft table.
307 $select = "SELECT SUM({$this->_aliases['civicrm_contribution_soft']}.amount) "
308 . "as committed_total, COUNT({$this->_aliases['civicrm_contribution_soft']}.id) "
309 . "as donors_total, SUM(IF( contribution_civireport.contribution_status_id > 1, 0, "
310 . "contribution_soft_civireport.amount)) AS received_total ";
311 $sql = "{$select} {$this->_from} {$this->_where}";
312 $dao = CRM_Core_DAO
::executeQuery($sql);
314 $committed_total = $dao->committed_total
;
315 $received_total = $dao->received_total
;
316 $donors_total = $dao->donors_total
;
318 // Calculate goal total goal from the PCP table (we only want one result per
319 // PCP page - the query above produces one result per contribution made).
320 $sql = "SELECT SUM(goal_amount) as goal_total FROM civicrm_pcp WHERE "
321 . "goal_amount IS NOT NULL AND id IN ("
322 . "SELECT DISTINCT {$this->_aliases['civicrm_pcp']}.id {$this->_from} "
325 $dao = CRM_Core_DAO
::executeQuery($sql);
327 $goal_total = $dao->goal_total
;
329 $statistics['counts']['goal_total'] = [
330 'title' => ts('Goal Total'),
331 'value' => $goal_total,
332 'type' => CRM_Utils_Type
::T_MONEY
,
334 $statistics['counts']['committed_total'] = [
335 'title' => ts('Total Committed'),
336 'value' => $committed_total,
337 'type' => CRM_Utils_Type
::T_MONEY
,
339 $statistics['counts']['received_total'] = [
340 'title' => ts('Total Received'),
341 'value' => $received_total,
342 'type' => CRM_Utils_Type
::T_MONEY
,
344 $statistics['counts']['donors_total'] = [
345 'title' => ts('Total Donors'),
346 'value' => $donors_total,
347 'type' => CRM_Utils_Type
::T_INT
,
353 * Alter display of rows.
355 * Iterate through the rows retrieved via SQL and make changes for display purposes,
356 * such as rendering contacts as links.
359 * Rows generated by SQL, with an array for each row.
361 public function alterDisplay(&$rows) {
364 foreach ($rows as $rowNum => $row) {
365 if (!empty($this->_noRepeats
) && $this->_outputMode
!= 'csv') {
366 // not repeat contact sort names if it matches with the one
368 $repeatFound = FALSE;
370 foreach ($row as $colName => $colVal) {
371 if (!empty($checkList[$colName]) &&
372 is_array($checkList[$colName]) &&
373 in_array($colVal, $checkList[$colName])
375 $rows[$rowNum][$colName] = "";
378 if (in_array($colName, $this->_noRepeats
)) {
379 $checkList[$colName][] = $colVal;
384 if (array_key_exists('civicrm_contact_sort_name', $row) &&
385 $rows[$rowNum]['civicrm_contact_sort_name'] &&
386 array_key_exists('civicrm_contact_id', $row)
388 $url = CRM_Utils_System
::url("civicrm/contact/view",
389 'reset=1&cid=' . $row['civicrm_contact_id'],
392 $rows[$rowNum]['civicrm_contact_sort_name_link'] = $url;
393 $rows[$rowNum]['civicrm_contact_sort_name_hover'] = ts("View Contact Summary for this Contact.");
397 if (!empty($row['civicrm_financial_trxn_card_type_id'])) {
398 $rows[$rowNum]['civicrm_financial_trxn_card_type_id'] = $this->getLabels($row['civicrm_financial_trxn_card_type_id'], 'CRM_Financial_DAO_FinancialTrxn', 'card_type_id');
402 if (!empty($row['civicrm_pcp_page_type'])) {
403 $rows[$rowNum]['civicrm_pcp_page_type'] = ucfirst($rows[$rowNum]['civicrm_pcp_page_type']);