CRM-16338 fix - Incorrect Contribution Summary Report when a contributions has multip...
authormonishdeb <monish.deb@webaccessglobal.com>
Thu, 30 Apr 2015 13:28:22 +0000 (18:58 +0530)
committermonishdeb <monish.deb@webaccessglobal.com>
Fri, 8 May 2015 10:11:01 +0000 (15:41 +0530)
https://issues.civicrm.org/jira/browse/CRM-16338

CRM/Report/Form/Contribute/Summary.php

index 3398bdc31d34ab2e4886da2ab7668601ce761574..7e0e24fbbd49d6c0a56dc69bc7dc0993f0e4c620 100644 (file)
@@ -336,30 +336,24 @@ class CRM_Report_Form_Contribute_Summary extends CRM_Report_Form {
           if (!empty($field['required']) ||
             !empty($this->_params['fields'][$fieldName])
           ) {
-
             // only include statistics columns if set
             if (!empty($field['statistics'])) {
               foreach ($field['statistics'] as $stat => $label) {
+                $this->_columnHeaders["{$tableName}_{$fieldName}_{$stat}"]['title'] = $label;
+                $this->_columnHeaders["{$tableName}_{$fieldName}_{$stat}"]['type'] = $field['type'];
+                $this->_statFields[] = "{$tableName}_{$fieldName}_{$stat}";
                 switch (strtolower($stat)) {
                   case 'sum':
                     $select[] = "SUM({$field['dbAlias']}) as {$tableName}_{$fieldName}_{$stat}";
-                    $this->_columnHeaders["{$tableName}_{$fieldName}_{$stat}"]['title'] = $label;
-                    $this->_columnHeaders["{$tableName}_{$fieldName}_{$stat}"]['type'] = $field['type'];
-                    $this->_statFields[] = "{$tableName}_{$fieldName}_{$stat}";
                     break;
 
                   case 'count':
                     $select[] = "COUNT({$field['dbAlias']}) as {$tableName}_{$fieldName}_{$stat}";
                     $this->_columnHeaders["{$tableName}_{$fieldName}_{$stat}"]['type'] = CRM_Utils_Type::T_INT;
-                    $this->_columnHeaders["{$tableName}_{$fieldName}_{$stat}"]['title'] = $label;
-                    $this->_statFields[] = "{$tableName}_{$fieldName}_{$stat}";
                     break;
 
                   case 'avg':
                     $select[] = "ROUND(AVG({$field['dbAlias']}),2) as {$tableName}_{$fieldName}_{$stat}";
-                    $this->_columnHeaders["{$tableName}_{$fieldName}_{$stat}"]['type'] = $field['type'];
-                    $this->_columnHeaders["{$tableName}_{$fieldName}_{$stat}"]['title'] = $label;
-                    $this->_statFields[] = "{$tableName}_{$fieldName}_{$stat}";
                     break;
                 }
               }
@@ -414,13 +408,19 @@ class CRM_Report_Form_Contribute_Summary extends CRM_Report_Form {
     return $errors;
   }
 
-  public function from() {
-    $softCreditJoin = "LEFT";
+  public function from($entity = NULL) {
+    $softCreditJoinType = "LEFT";
     if (!empty($this->_params['fields']['soft_amount']) &&
       empty($this->_params['fields']['total_amount'])
     ) {
       // if its only soft credit stats, use inner join
-      $softCreditJoin = "INNER";
+      $softCreditJoinType = "INNER";
+    }
+
+    $softCreditJoin = "{$softCreditJoinType} JOIN civicrm_contribution_soft {$this->_aliases['civicrm_contribution_soft']}
+                       ON {$this->_aliases['civicrm_contribution_soft']}.contribution_id = {$this->_aliases['civicrm_contribution']}.id";
+    if ($entity == 'contribution' || empty($this->_params['fields']['soft_amount'])) {
+      $softCreditJoin .= " AND {$this->_aliases['civicrm_contribution_soft']}.id = (SELECT MIN(id) FROM civicrm_contribution_soft cs WHERE cs.contribution_id = {$this->_aliases['civicrm_contribution']}.id) ";
     }
 
     $this->_from = "
@@ -428,8 +428,7 @@ class CRM_Report_Form_Contribute_Summary extends CRM_Report_Form {
              INNER JOIN civicrm_contribution   {$this->_aliases['civicrm_contribution']}
                      ON {$this->_aliases['civicrm_contact']}.id = {$this->_aliases['civicrm_contribution']}.contact_id AND
                         {$this->_aliases['civicrm_contribution']}.is_test = 0
-             {$softCreditJoin} JOIN civicrm_contribution_soft {$this->_aliases['civicrm_contribution_soft']}
-                       ON {$this->_aliases['civicrm_contribution_soft']}.contribution_id = {$this->_aliases['civicrm_contribution']}.id
+             {$softCreditJoin}
              LEFT  JOIN civicrm_financial_type  {$this->_aliases['civicrm_financial_type']}
                      ON {$this->_aliases['civicrm_contribution']}.financial_type_id ={$this->_aliases['civicrm_financial_type']}.id
              LEFT  JOIN civicrm_email {$this->_aliases['civicrm_email']}
@@ -523,38 +522,47 @@ class CRM_Report_Form_Contribute_Summary extends CRM_Report_Form {
     $onlySoftCredit = $softCredit &&
       !CRM_Utils_Array::value('total_amount', $this->_params['fields']);
     $totalAmount = $average = $softTotalAmount = $softAverage = array();
+    $group = "\nGROUP BY {$this->_aliases['civicrm_contribution']}.currency";
 
-    $select = "SELECT
+    $this->from('contribution');
+    $contriSQL = "SELECT
 COUNT({$this->_aliases['civicrm_contribution']}.total_amount )        as civicrm_contribution_total_amount_count,
 SUM({$this->_aliases['civicrm_contribution']}.total_amount )          as civicrm_contribution_total_amount_sum,
 ROUND(AVG({$this->_aliases['civicrm_contribution']}.total_amount), 2) as civicrm_contribution_total_amount_avg,
-{$this->_aliases['civicrm_contribution']}.currency                    as currency";
+{$this->_aliases['civicrm_contribution']}.currency                    as currency
+{$this->_from} {$this->_where} {$group} {$this->_having}";
+
 
     if ($softCredit) {
-      $select .= ",
+      $this->from();
+      $softSQL = "SELECT
 COUNT({$this->_aliases['civicrm_contribution_soft']}.amount )        as civicrm_contribution_soft_soft_amount_count,
 SUM({$this->_aliases['civicrm_contribution_soft']}.amount )          as civicrm_contribution_soft_soft_amount_sum,
-ROUND(AVG({$this->_aliases['civicrm_contribution_soft']}.amount), 2) as civicrm_contribution_soft_soft_amount_avg";
+ROUND(AVG({$this->_aliases['civicrm_contribution_soft']}.amount), 2) as civicrm_contribution_soft_soft_amount_avg,
+{$this->_aliases['civicrm_contribution']}.currency                    as currency
+{$this->_from} {$this->_where} {$group} {$this->_having}";
     }
-    $group = "\nGROUP BY {$this->_aliases['civicrm_contribution']}.currency";
-    $sql = "{$select} {$this->_from} {$this->_where} {$group} {$this->_having}";
 
-    $dao = CRM_Core_DAO::executeQuery($sql);
+    $contriDAO = CRM_Core_DAO::executeQuery($contriSQL);
+
     $totalAmount = $average = $softTotalAmount = $softAverage = array();
     $count = $softCount = 0;
-    while ($dao->fetch()) {
+    while ($contriDAO->fetch()) {
       $totalAmount[]
-        = CRM_Utils_Money::format($dao->civicrm_contribution_total_amount_sum, $dao->currency) .
-        " (" . $dao->civicrm_contribution_total_amount_count . ")";
-      $average[] = CRM_Utils_Money::format($dao->civicrm_contribution_total_amount_avg, $dao->currency);
-      $count += $dao->civicrm_contribution_total_amount_count;
+        = CRM_Utils_Money::format($contriDAO->civicrm_contribution_total_amount_sum, $contriDAO->currency) .
+        " (" . $contriDAO->civicrm_contribution_total_amount_count . ")";
+      $average[] = CRM_Utils_Money::format($contriDAO->civicrm_contribution_total_amount_avg, $contriDAO->currency);
+      $count += $contriDAO->civicrm_contribution_total_amount_count;
+    }
 
-      if ($softCredit) {
+    if ($softCredit) {
+      $softDAO = CRM_Core_DAO::executeQuery($softSQL);
+      while ($softDAO->fetch()) {
         $softTotalAmount[]
-          = CRM_Utils_Money::format($dao->civicrm_contribution_soft_soft_amount_sum, $dao->currency) .
-          " (" . $dao->civicrm_contribution_soft_soft_amount_count . ")";
-        $softAverage[] = CRM_Utils_Money::format($dao->civicrm_contribution_soft_soft_amount_avg, $dao->currency);
-        $softCount += $dao->civicrm_contribution_soft_soft_amount_count;
+          = CRM_Utils_Money::format($softDAO->civicrm_contribution_soft_soft_amount_sum, $softDAO->currency) .
+          " (" . $softDAO->civicrm_contribution_soft_soft_amount_count . ")";
+        $softAverage[] = CRM_Utils_Money::format($softDAO->civicrm_contribution_soft_soft_amount_avg, $softDAO->currency);
+        $softCount += $softDAO->civicrm_contribution_soft_soft_amount_count;
       }
     }
 
@@ -598,6 +606,63 @@ ROUND(AVG({$this->_aliases['civicrm_contribution_soft']}.amount), 2) as civicrm_
     parent::postProcess();
   }
 
+  public function buildRows($sql, &$rows) {
+    $dao = CRM_Core_DAO::executeQuery($sql);
+    if (!is_array($rows)) {
+      $rows = array();
+    }
+
+    // use this method to modify $this->_columnHeaders
+    $this->modifyColumnHeaders();
+
+    $unselectedSectionColumns = $this->unselectedSectionColumns();
+
+    //CRM-16338 if both soft-credit and contribution are enabled then process the contribution's
+    //total amount's average, count and sum separately and add it to the respective result list
+    $softCredit = (!empty($this->_params['fields']['soft_amount']) && !empty($this->_params['fields']['total_amount'])) ? TRUE : FALSE;
+    if ($softCredit) {
+      $this->from('contribution');
+      $contriSQL = "{$this->_select} {$this->_from} {$this->_where} {$this->_groupBy} {$this->_having} {$this->_orderBy} {$this->_limit}";
+      $contriDAO = CRM_Core_DAO::executeQuery($contriSQL);
+      $contriFields = array(
+        'civicrm_contribution_total_amount_sum',
+        'civicrm_contribution_total_amount_avg',
+        'civicrm_contribution_total_amount_count');
+      $contriRows = array();
+      while ($contriDAO->fetch()) {
+        $contriRow = array();
+        foreach ($contriFields as $column) {
+          $contriRow[$column] = $contriDAO->$column;
+        }
+        $contriRows[] = $contriRow;
+      }
+    }
+
+    $count = 0;
+    while ($dao->fetch()) {
+      $row = array();
+      foreach ($this->_columnHeaders as $key => $value) {
+        if ($softCredit && array_key_exists($key, $contriRows[$count])) {
+          $row[$key] = $contriRows[$count][$key];
+        }
+        elseif (property_exists($dao, $key)) {
+          $row[$key] = $dao->$key;
+        }
+      }
+
+      // section headers not selected for display need to be added to row
+      foreach ($unselectedSectionColumns as $key => $values) {
+        if (property_exists($dao, $key)) {
+          $row[$key] = $dao->$key;
+        }
+      }
+
+      $count++;
+      $rows[] = $row;
+    }
+
+  }
+
   /**
    * @param $rows
    */