CRM-18439 - Report Fixes to include Full Group by clause
[civicrm-core.git] / CRM / Report / Form / Mailing / Bounce.php
index 7d44bbc77e56dad38d2da8352e9a406142208ef0..6aa4b8dd555ef99bc8a3b3177ccb4f5e79d19ab4 100644 (file)
@@ -3,7 +3,7 @@
  +--------------------------------------------------------------------+
  | CiviCRM version 4.7                                                |
  +--------------------------------------------------------------------+
- | Copyright CiviCRM LLC (c) 2004-2015                                |
+ | Copyright CiviCRM LLC (c) 2004-2016                                |
  +--------------------------------------------------------------------+
  | This file is a part of CiviCRM.                                    |
  |                                                                    |
@@ -28,9 +28,7 @@
 /**
  *
  * @package CRM
- * @copyright CiviCRM LLC (c) 2004-2015
- * $Id$
- *
+ * @copyright CiviCRM LLC (c) 2004-2016
  */
 class CRM_Report_Form_Mailing_Bounce extends CRM_Report_Form {
 
@@ -40,9 +38,6 @@ class CRM_Report_Form_Mailing_Bounce extends CRM_Report_Form {
 
   protected $_phoneField = FALSE;
 
-  // just a toggle we use to build the from
-  protected $_mailingidField = FALSE;
-
   protected $_customGroupExtends = array(
     'Contact',
     'Individual',
@@ -56,8 +51,6 @@ class CRM_Report_Form_Mailing_Bounce extends CRM_Report_Form {
     'pieChart' => 'Pie Chart',
   );
 
-  /**
-   */
   /**
    */
   public function __construct() {
@@ -137,9 +130,28 @@ class CRM_Report_Form_Mailing_Bounce extends CRM_Report_Form {
         'bounce_reason' => array(
           'title' => ts('Bounce Reason'),
         ),
+        'time_stamp' => array(
+          'title' => ts('Bounce Date'),
+        ),
+      ),
+      'filters' => array(
+        'bounce_reason' => array(
+          'title' => ts('Bounce Reason'),
+          'type' => CRM_Utils_Type::T_STRING,
+        ),
+        'time_stamp' => array(
+          'title' => ts('Bounce Date'),
+          'operatorType' => CRM_Report_Form::OP_DATE,
+          'type' => CRM_Utils_Type::T_DATE,
+        ),
       ),
       'order_bys' => array(
-        'bounce_reason' => array('title' => ts('Bounce Reason')),
+        'bounce_reason' => array(
+          'title' => ts('Bounce Reason'),
+        ),
+        'time_stamp' => array(
+          'title' => ts('Bounce Date'),
+        ),
       ),
       'grouping' => 'mailing-fields',
     );
@@ -177,7 +189,30 @@ class CRM_Report_Form_Mailing_Bounce extends CRM_Report_Form {
         'email' => array(
           'title' => ts('Email'),
           'no_repeat' => TRUE,
-          'required' => TRUE,
+        ),
+        'on_hold' => array(
+          'title' => ts('On hold'),
+        ),
+        'hold_date' => array(
+          'title' => ts('Hold date'),
+        ),
+        'reset_date' => array(
+          'title' => ts('Hold reset date'),
+        ),
+      ),
+      'filters' => array(
+        'on_hold' => array(
+          'title' => ts('On hold'),
+        ),
+        'hold_date' => array(
+          'title' => ts('Hold date'),
+          'operatorType' => CRM_Report_Form::OP_DATE,
+          'type' => CRM_Utils_Type::T_DATE,
+        ),
+        'reset_date' => array(
+          'title' => ts('Hold reset date'),
+          'operatorType' => CRM_Report_Form::OP_DATE,
+          'type' => CRM_Utils_Type::T_DATE,
         ),
       ),
       'order_bys' => array(
@@ -233,6 +268,7 @@ class CRM_Report_Form_Mailing_Bounce extends CRM_Report_Form {
       $this->_columnHeaders["civicrm_mailing_bounce_count"]['title'] = ts('Bounce Count');
     }
 
+    $this->_selectClauses = $select;
     $this->_select = "SELECT " . implode(', ', $select) . " ";
   }
 
@@ -258,7 +294,7 @@ class CRM_Report_Form_Mailing_Bounce extends CRM_Report_Form {
     $this->_from .= "
         INNER JOIN civicrm_mailing_event_queue
           ON civicrm_mailing_event_queue.contact_id = {$this->_aliases['civicrm_contact']}.id
-        INNER JOIN civicrm_email {$this->_aliases['civicrm_email']}
+        LEFT JOIN civicrm_email {$this->_aliases['civicrm_email']}
           ON civicrm_mailing_event_queue.email_id = {$this->_aliases['civicrm_email']}.id
         INNER JOIN civicrm_mailing_event_bounce {$this->_aliases['civicrm_mailing_event_bounce']}
           ON {$this->_aliases['civicrm_mailing_event_bounce']}.event_queue_id = civicrm_mailing_event_queue.id
@@ -279,17 +315,57 @@ class CRM_Report_Form_Mailing_Bounce extends CRM_Report_Form {
   }
 
   public function where() {
-    parent::where();
-    $this->_where .= " AND {$this->_aliases['civicrm_mailing']}.sms_provider_id IS NULL";
+
+    $clauses = array();
+
+    // Exclude SMS mailing type
+    $clauses[] = "{$this->_aliases['civicrm_mailing']}.sms_provider_id IS NULL";
+
+    // Build date filter clauses
+    foreach ($this->_columns as $tableName => $table) {
+      if (array_key_exists('filters', $table)) {
+        foreach ($table['filters'] as $fieldName => $field) {
+          $clause = NULL;
+          if (CRM_Utils_Array::value('type', $field) & CRM_Utils_Type::T_DATE) {
+            $relative = CRM_Utils_Array::value("{$fieldName}_relative", $this->_params);
+            $from = CRM_Utils_Array::value("{$fieldName}_from", $this->_params);
+            $to = CRM_Utils_Array::value("{$fieldName}_to", $this->_params);
+
+            $clause = $this->dateClause($this->_aliases[$tableName] . '.' . $field['name'], $relative, $from, $to, $field['type']);
+          }
+          else {
+            $op = CRM_Utils_Array::value("{$fieldName}_op", $this->_params);
+
+            if ($op) {
+              $clause = $this->whereClause($field,
+                $op,
+                CRM_Utils_Array::value("{$fieldName}_value", $this->_params),
+                CRM_Utils_Array::value("{$fieldName}_min", $this->_params),
+                CRM_Utils_Array::value("{$fieldName}_max", $this->_params)
+              );
+            }
+
+          }
+
+          if (!empty($clause)) {
+            $clauses[] = $clause;
+          }
+        }
+      }
+    }
+
+    $this->_where = "WHERE " . implode(' AND ', $clauses);
   }
 
   public function groupBy() {
     if (!empty($this->_params['charts'])) {
-      $this->_groupBy = " GROUP BY {$this->_aliases['civicrm_mailing']}.id";
+      $groupBy = "{$this->_aliases['civicrm_mailing']}.id";
     }
     else {
-      $this->_groupBy = " GROUP BY {$this->_aliases['civicrm_mailing_event_bounce']}.id";
+      $groupBy = "{$this->_aliases['civicrm_mailing_event_bounce']}.id";
     }
+    $this->_groupBy = " GROUP BY {$groupBy}";
+    $this->_groupBy .= CRM_Contact_BAO_Query::getGroupByFromSelectColumns($this->_selectClauses, $groupBy);
   }
 
   public function postProcess() {
@@ -360,8 +436,20 @@ class CRM_Report_Form_Mailing_Bounce extends CRM_Report_Form {
    *   Rows generated by SQL, with an array for each row.
    */
   public function alterDisplay(&$rows) {
+
+    $config = CRM_Core_Config::Singleton();
+
     $entryFound = FALSE;
     foreach ($rows as $rowNum => $row) {
+
+      // If the email address has been deleted
+      if (array_key_exists('civicrm_email_email', $row)) {
+        if (empty($rows[$rowNum]['civicrm_email_email'])) {
+          $rows[$rowNum]['civicrm_email_email'] = '<del>Email address deleted</del>';
+        }
+        $entryFound = TRUE;
+      }
+
       // make count columns point to detail report
       // convert display name to links
       if (array_key_exists('civicrm_contact_sort_name', $row) &&
@@ -376,6 +464,28 @@ class CRM_Report_Form_Mailing_Bounce extends CRM_Report_Form {
         $entryFound = TRUE;
       }
 
+      // Handle on_hold boolean display
+      if (array_key_exists('civicrm_email_on_hold', $row)) {
+        $rows[$rowNum]['civicrm_email_on_hold'] = (!empty($row['civicrm_email_on_hold'])) ? 'Yes' : 'No';
+        $entryFound = TRUE;
+      }
+
+      // Convert datetime values to custom date and time format
+      $dateFields = array(
+        'civicrm_mailing_event_bounce_time_stamp',
+        'civicrm_email_hold_date',
+        'civicrm_email_reset_date',
+      );
+
+      foreach ($dateFields as $dateField) {
+        if (array_key_exists($dateField, $row)) {
+          if (!empty($rows[$rowNum][$dateField])) {
+            $rows[$rowNum][$dateField] = CRM_Utils_Date::customFormat($row[$dateField], $config->dateformatDatetime);
+          }
+          $entryFound = TRUE;
+        }
+      }
+
       // skip looking further in rows, if first row itself doesn't
       // have the column we need
       if (!$entryFound) {