Fix duplicate households on 'Merge same household' exports
authoreileen <emcnaughton@wikimedia.org>
Thu, 6 Jun 2019 00:48:15 +0000 (12:48 +1200)
committereileen <emcnaughton@wikimedia.org>
Thu, 6 Jun 2019 01:02:16 +0000 (13:02 +1200)
Add test

CRM/Export/BAO/Export.php
CRM/Export/BAO/ExportProcessor.php
tests/phpunit/CRM/Export/BAO/ExportTest.php
tests/phpunit/CiviTest/CiviUnitTestCase.php

index eb1e98a5c8d265856185f71de36c0332715eb238..ee43a570e7c16ba68de6969d119f4887cdd618a4 100644 (file)
@@ -334,6 +334,7 @@ INSERT INTO {$componentTable} SELECT distinct gc.contact_id FROM civicrm_group_c
       $processor->setHouseholdMergeReturnProperties(array_diff_key($returnProperties, array_fill_keys(['location_type', 'im_provider'], 1)));
     }
 
+    // This perhaps only needs calling when $mergeSameHousehold == 1
     self::buildRelatedContactArray($selectAll, $ids, $processor, $componentTable);
 
     // make sure the groups stuff is included only if specifically specified
index 8e2489172aa469a297f281c5eae4af0ec68e31b0..25e61c07c3c181e9fe8f561f80b6a8d8328ac9bd 100644 (file)
@@ -111,6 +111,13 @@ class CRM_Export_BAO_ExportProcessor {
    */
   protected $exportedHouseholds = [];
 
+  /**
+   * Households to skip during export as they will be exported via their relationships anyway.
+   *
+   * @var array
+   */
+  protected $householdsToSkip = [];
+
   /**
    * Get return properties by relationship.
    * @return array
@@ -233,6 +240,9 @@ class CRM_Export_BAO_ExportProcessor {
    */
   public function setRelationshipValue($relationshipType, $contactID, $field, $value) {
     $this->relatedContactValues[$relationshipType][$contactID][$field] = $value;
+    if ($field === 'id') {
+      $this->householdsToSkip[] = $value;
+    }
   }
 
   /**
@@ -640,6 +650,9 @@ class CRM_Export_BAO_ExportProcessor {
    * @return array|bool
    */
   public function buildRow($query, $iterationDAO, $outputColumns, $metadata, $paymentDetails, $addPaymentHeader, $paymentTableId) {
+    if ($this->isHouseholdToSkip($iterationDAO->contact_id)) {
+      return FALSE;
+    }
     $phoneTypes = CRM_Core_PseudoConstant::get('CRM_Core_DAO_Phone', 'phone_type_id');
     $imProviders = CRM_Core_PseudoConstant::get('CRM_Core_DAO_IM', 'provider_id');
 
@@ -1356,4 +1369,15 @@ class CRM_Export_BAO_ExportProcessor {
     }
   }
 
+  /**
+   * Is this contact a household that is already set to be exported by virtue of it's household members.
+   *
+   * @param int $contactID
+   *
+   * @return bool
+   */
+  protected function isHouseholdToSkip($contactID) {
+    return in_array($contactID, $this->householdsToSkip);
+  }
+
 }
index 156cc1d2951862cc1190a35d651385f5f3b88ad2..f2307b0bb28ac0c21e2e844c47a86298a24ed9d0 100644 (file)
@@ -365,7 +365,8 @@ class CRM_Export_BAO_ExportTest extends CiviUnitTestCase {
    *
    * @param int $isPrimaryOnly
    *
-   * @dataProvider getPrimarySearchOptions
+   * @dataProvider getBooleanDataProvider
+   * @throws \CRM_Core_Exception
    */
   public function testExportPrimaryAddress($isPrimaryOnly) {
     \Civi::settings()->set('searchPrimaryDetailsOnly', $isPrimaryOnly);
@@ -399,14 +400,6 @@ class CRM_Export_BAO_ExportTest extends CiviUnitTestCase {
     \Civi::settings()->set('searchPrimaryDetailsOnly', FALSE);
   }
 
-  /**
-   * Get the options for the primary search setting field.
-   * @return array
-   */
-  public function getPrimarySearchOptions() {
-    return [[TRUE], [FALSE]];
-  }
-
   /**
    * Test that when exporting a pseudoField it is reset for NULL entries.
    *
@@ -506,10 +499,19 @@ class CRM_Export_BAO_ExportTest extends CiviUnitTestCase {
    * Test exporting relationships.
    *
    * This is to ensure that CRM-13995 remains fixed.
+   *
+   * @dataProvider getBooleanDataProvider
+   *
+   * @param bool $includeHouseHold
+   *
+   * @throws \CRM_Core_Exception
    */
-  public function testExportRelationshipsMergeToHousehold() {
+  public function testExportRelationshipsMergeToHousehold($includeHouseHold) {
     list($householdID, $houseHoldTypeID) = $this->setUpHousehold();
 
+    if ($includeHouseHold) {
+      $this->contactIDs[] = $householdID;
+    }
     $selectedFields = [
       ['Individual', $houseHoldTypeID . '_a_b', 'state_province', ''],
       ['Individual', $houseHoldTypeID . '_a_b', 'city', ''],
@@ -536,6 +538,7 @@ class CRM_Export_BAO_ExportTest extends CiviUnitTestCase {
     );
     $dao = CRM_Core_DAO::executeQuery("SELECT * FROM {$tableName}");
     while ($dao->fetch()) {
+      $this->assertEquals(1, $dao->N);
       $this->assertEquals('Portland', $dao->city);
       $this->assertEquals('ME', $dao->state_province);
       $this->assertEquals($householdID, $dao->civicrm_primary_id);
index 32fb9e3ea9c964de122a45adbb03711e1929854e..83c7f1d51fea043ebe8db3fd3b28d40030a4a196 100644 (file)
@@ -3166,6 +3166,15 @@ AND    ( TABLE_NAME LIKE 'civicrm_value_%' )
     return array(array('.'), array(','));
   }
 
+  /**
+   * Get the boolean options as a provider.
+   *
+   * @return array
+   */
+  public function getBooleanDataProvider() {
+    return [[TRUE], [FALSE]];
+  }
+
   /**
    * Set the separators for thousands and decimal points.
    *