CRM-17238, Dedupe for Individual Birth Date Results in Error
authorPradeep Nayak <pradpnayak@gmail.com>
Thu, 15 Nov 2018 18:20:35 +0000 (23:50 +0530)
committereileen <emcnaughton@wikimedia.org>
Tue, 12 Feb 2019 19:41:38 +0000 (08:41 +1300)
dev/core#397 fix fatal error on birth_date dedupe

CRM/Dedupe/BAO/Rule.php
tests/phpunit/CRM/Dedupe/DedupeFinderTest.php

index 4a3bbade67b111a6ff8ab776ef14628576c2490a..40c6a7444805ff55f43b454988d7b5a17ea09df9 100644 (file)
@@ -72,7 +72,22 @@ class CRM_Dedupe_BAO_Rule extends CRM_Dedupe_DAO_Rule {
     // full matches, respectively)
     $where = array();
     $on = array("SUBSTR(t1.{$this->rule_field}, 1, {$this->rule_length}) = SUBSTR(t2.{$this->rule_field}, 1, {$this->rule_length})");
-    $using = array($this->rule_field);
+    $entity = CRM_Core_DAO_AllCoreTables::getBriefName(CRM_Core_DAO_AllCoreTables::getClassForTable($this->rule_table));
+    $fields = civicrm_api3($entity, 'getfields', ['action' => 'create'])['values'];
+
+    $innerJoinClauses = [
+      "t1.{$this->rule_field} IS NOT NULL",
+      "t2.{$this->rule_field} IS NOT NULL",
+      "t1.{$this->rule_field} = t2.{$this->rule_field}"
+    ];
+    if ($fields[$this->rule_field]['type'] === CRM_Utils_Type::T_DATE) {
+      $innerJoinClauses[] = "t1.{$this->rule_field} > '1000-01-01'";
+      $innerJoinClauses[] = "t2.{$this->rule_field} > '1000-01-01'";
+    }
+    else {
+      $innerJoinClauses[] = "t1.{$this->rule_field} <> ''";
+      $innerJoinClauses[] = "t2.{$this->rule_field} <> ''";
+    }
 
     switch ($this->rule_table) {
       case 'civicrm_contact':
@@ -92,7 +107,7 @@ class CRM_Dedupe_BAO_Rule extends CRM_Dedupe_DAO_Rule {
       case 'civicrm_address':
         $id = 'contact_id';
         $on[] = 't1.location_type_id = t2.location_type_id';
-        $using[] = 'location_type_id';
+        $innerJoinClauses[] = ['t1.location_type_id = t2.location_type_id'];
         if ($this->params['civicrm_address']['location_type_id']) {
           $locTypeId = CRM_Utils_Type::escape($this->params['civicrm_address']['location_type_id'], 'Integer', FALSE);
           if ($locTypeId) {
@@ -152,7 +167,6 @@ class CRM_Dedupe_BAO_Rule extends CRM_Dedupe_DAO_Rule {
       if ($this->rule_length) {
         $where[] = "SUBSTR(t1.{$this->rule_field}, 1, {$this->rule_length}) = SUBSTR('$str', 1, {$this->rule_length})";
         $where[] = "t1.{$this->rule_field} IS NOT NULL";
-        $where[] = "t1.{$this->rule_field} <> ''";
       }
       else {
         $where[] = "t1.{$this->rule_field} = '$str'";
@@ -163,15 +177,13 @@ class CRM_Dedupe_BAO_Rule extends CRM_Dedupe_DAO_Rule {
         $from = "{$this->rule_table} t1 JOIN {$this->rule_table} t2 ON (" . implode(' AND ', $on) . ")";
       }
       else {
-        $from = "{$this->rule_table} t1 JOIN {$this->rule_table} t2 USING (" . implode(', ', $using) . ")";
+        $from = "{$this->rule_table} t1 INNER JOIN {$this->rule_table} t2 ON (" . implode(' AND ', $innerJoinClauses) . ")";
       }
     }
 
     // finish building WHERE, also limit the results if requested
     if (!$this->params) {
       $where[] = "t1.$id < t2.$id";
-      $where[] = "t1.{$this->rule_field} IS NOT NULL";
-      $where[] = "t1.{$this->rule_field} <> ''";
     }
     $query = "SELECT $select FROM $from WHERE " . implode(' AND ', $where);
     if ($this->contactIds) {
index 947e52f831bbb53103a46c4a454674baff86971f..00382553ea67d6550a640fb174fa1e118c228efe 100644 (file)
@@ -85,7 +85,6 @@ class CRM_Dedupe_DedupeFinderTest extends CiviUnitTestCase {
     }
     $foundDupes = CRM_Dedupe_Finder::dupesInGroup($ruleGroup['id'], $this->groupID);
     $this->assertEquals(count($foundDupes), 4);
-    $this->markTestIncomplete('This currenctly fails - see https://lab.civicrm.org/dev/core/issues/397');
     CRM_Dedupe_Finder::dupes($ruleGroup['id']);
 
   }