CRM-18236 fix
authordeb.monish <monish.deb@webaccessglobal.com>
Fri, 25 Mar 2016 10:50:15 +0000 (16:20 +0530)
committerdeb.monish <monish.deb@webaccessglobal.com>
Mon, 4 Apr 2016 18:01:53 +0000 (23:31 +0530)
CRM/Utils/SQL/Select.php
Civi/ActionSchedule/RecipientBuilder.php
tests/phpunit/CRM/Core/BAO/ActionScheduleTest.php

index c416a955e205f30f53ca4522d1d200553891855d..000042776d9916305657dbe321f24cf80838e255 100644 (file)
@@ -125,6 +125,7 @@ class CRM_Utils_SQL_Select implements ArrayAccess {
   private $limit = NULL;
   private $offset = NULL;
   private $params = array();
+  private $distinct = NULL;
 
   // Public to work-around PHP 5.3 limit.
   public $strict = NULL;
@@ -256,6 +257,19 @@ class CRM_Utils_SQL_Select implements ArrayAccess {
     return $this;
   }
 
+  /**
+   * Return only distinct values
+   *
+   * @param bool $isDistinct allow DISTINCT select or not
+   * @return CRM_Utils_SQL_Select
+   */
+  public function distinct($isDistinct = TRUE) {
+    if ($isDistinct) {
+      $this->distinct = 'DISTINCT ';
+    }
+    return $this;
+  }
+
   /**
    * Limit results by adding extra condition(s) to the WHERE clause
    *
@@ -536,7 +550,7 @@ class CRM_Utils_SQL_Select implements ArrayAccess {
       $sql .= ")\n";
     }
     if ($this->selects) {
-      $sql .= 'SELECT ' . implode(', ', $this->selects) . "\n";
+      $sql .= 'SELECT ' . $this->distinct . implode(', ', $this->selects) . "\n";
     }
     else {
       $sql .= 'SELECT *' . "\n";
index 450143f36a9b6edc1383d348050c0d2dd2abc5f9..450dcfe270fc3cf70773344fdf0a17d10aab0ba8 100644 (file)
@@ -178,31 +178,57 @@ class RecipientBuilder {
 
     $startDateClauses = $this->prepareStartDateClauses();
 
-    $firstQuery = $query->copy()
-      ->merge($this->selectIntoActionLog(self::PHASE_RELATION_FIRST, $query))
-      ->merge($this->joinReminder('LEFT JOIN', 'rel', $query))
-      ->where("reminder.id IS NULL")
-      ->where($startDateClauses)
-      ->strict()
-      ->toSQL();
-    \CRM_Core_DAO::executeQuery($firstQuery);
-
     // In some cases reference_date got outdated due to many reason e.g. In Membership renewal end_date got extended
     // which means reference date mismatches with the end_date where end_date may be used as the start_action_date
     // criteria  for some schedule reminder so in order to send new reminder we INSERT new reminder with new reference_date
     // value via UNION operation
+    $referenceReminderIDs = array();
+    $referenceDate = NULL;
     if (!empty($query['casUseReferenceDate'])) {
+      // First retrieve all the action log's ids which are outdated or in other words reference_date now don't match with entity date.
+      // And the retrieve the updated entity date which will later used below to update all other outdated action log records
+      $sql = $query->copy()
+        ->select('reminder.id as id')
+        ->select($query['casDateField'] . ' as reference_date')
+        ->merge($this->joinReminder('INNER JOIN', 'rel', $query))
+        ->where("reminder.id IS NOT NULL AND reminder.reference_date IS NOT NULL AND reminder.reference_date <> !casDateField")
+        ->where($startDateClauses)
+        ->orderBy("reminder.id desc")
+        ->strict()
+        ->toSQL();
+      $dao = \CRM_Core_DAO::executeQuery($sql);
+
+      while ($dao->fetch()) {
+        $referenceReminderIDs[] = $dao->id;
+        $referenceDate = $dao->reference_date;
+      }
+    }
+
+    if (empty($referenceReminderIDs)) {
+      $firstQuery = $query->copy()
+        ->merge($this->selectIntoActionLog(self::PHASE_RELATION_FIRST, $query))
+        ->merge($this->joinReminder('LEFT JOIN', 'rel', $query))
+        ->where("reminder.id IS NULL")
+        ->where($startDateClauses)
+        ->strict()
+        ->toSQL();
+      \CRM_Core_DAO::executeQuery($firstQuery);
+    }
+    else {
+      // INSERT new log to send reminder as desired entity date got updated
       $referenceQuery = $query->copy()
         ->merge($this->selectIntoActionLog(self::PHASE_RELATION_FIRST, $query))
         ->merge($this->joinReminder('LEFT JOIN', 'rel', $query))
-        ->where("reminder.id IS NOT NULL")
+        ->where("reminder.id = !reminderID")
         ->where($startDateClauses)
-        ->where("reminder.action_date_time IS NOT NULL AND reminder.reference_date IS NOT NULL")
-        ->groupBy("reminder.id, reminder.reference_date")
-        ->having("reminder.id = MAX(reminder.id) AND reminder.reference_date <> !casDateField")
+        ->param('reminderID', $referenceReminderIDs[0])
         ->strict()
         ->toSQL();
       \CRM_Core_DAO::executeQuery($referenceQuery);
+
+      // Update all the previous outdated reference date valued, action_log rows to the latest changed entity date
+      $updateQuery = "UPDATE civicrm_action_log SET reference_date = '" . $referenceDate . "' WHERE id IN (" . implode(', ', $referenceReminderIDs) . ")";
+      \CRM_Core_DAO::executeQuery($updateQuery);
     }
   }
 
index 22a6cc30c3c91892c17770ecef77748115ebcceb..b4301f388ed1bb3f72eddc4dabd2fe2ca2b8c098 100644 (file)
@@ -1294,7 +1294,7 @@ class CRM_Core_BAO_ActionScheduleTest extends CiviUnitTestCase {
       array(
         // It should not re-send on the same day
         'time' => '2012-04-12 01:00:00',
-        'recipients' => array(array()),
+        'recipients' => array(),
       ),
     ));
   }