jenkins-bot has submitted this change and it was merged.

Change subject: Alter logic for calculating wmf_donor fields
......................................................................


Alter logic for calculating wmf_donor fields

This change causes is to be calculated prior to the main contact merge, which 
means there
is only one mysql transaction. This will potentially have speed benefits but it 
will also keep
 the mysql log more readable.

The only potential gotcha I can see is that is assumes the contributions will 
be merged.
It's possible in the UI to choose NOT to merge the contributions but I can't 
think of a valid WMF use
for not merging contributions.

Bug: T133625

Change-Id: I18f2a72b0b6c351a34b3956f00ce3f81c9ce6570
---
M sites/all/modules/wmf_civicrm/tests/phpunit/MergeTest.php
M sites/all/modules/wmf_civicrm/wmf_civicrm.module
2 files changed, 136 insertions(+), 14 deletions(-)

Approvals:
  Ejegg: Looks good to me, approved
  jenkins-bot: Verified



diff --git a/sites/all/modules/wmf_civicrm/tests/phpunit/MergeTest.php 
b/sites/all/modules/wmf_civicrm/tests/phpunit/MergeTest.php
index a67e318..0907668 100644
--- a/sites/all/modules/wmf_civicrm/tests/phpunit/MergeTest.php
+++ b/sites/all/modules/wmf_civicrm/tests/phpunit/MergeTest.php
@@ -63,13 +63,27 @@
       'contact_id' => $this->contactID,
       'financial_type_id' => 'Cash',
       'total_amount' => 10,
-      'currencty' => 'USD',
+      'currency' => 'USD',
+      // Should cause 'is_2014 to be true.
+      'receive_date' => '2014-08-04',
+      wmf_civicrm_get_custom_field_name('original_currency') => 'NZD',
+      wmf_civicrm_get_custom_field_name('original_amount') => 8,
     ));
     $this->callAPISuccess('Contribution', 'create', array(
       'contact_id' => $this->contactID2,
       'financial_type_id' => 'Cash',
       'total_amount' => 5,
-      'currencty' => 'USD',
+      'currency' => 'USD',
+      // Should cause 'is_2012_donor to be true.
+      'receive_date' => '2013-01-04',
+    ));
+    $this->callAPISuccess('Contribution', 'create', array(
+      'contact_id' => $this->contactID2,
+      'financial_type_id' => 'Cash',
+      'total_amount' => 9,
+      'currency' => 'NZD',
+      // Should cause 'is_2015_donor to be true.
+      'receive_date' => '2016-04-04',
     ));
     $contact = $this->callAPISuccess('Contact', 'get', array(
       'id' => $this->contactID,
@@ -84,10 +98,33 @@
     $contact = $this->callAPISuccess('Contact', 'get', array(
       'id' => $this->contactID,
       'sequential' => 1,
-      'return' => 
array(wmf_civicrm_get_custom_field_name('lifetime_usd_total'), 
wmf_civicrm_get_custom_field_name('do_not_solicit')),
+      'return' => array(
+        wmf_civicrm_get_custom_field_name('lifetime_usd_total'),
+        wmf_civicrm_get_custom_field_name('do_not_solicit'),
+        wmf_civicrm_get_custom_field_name('last_donation_amount'),
+        wmf_civicrm_get_custom_field_name('last_donation_currency'),
+        wmf_civicrm_get_custom_field_name('last_donation_usd'),
+        wmf_civicrm_get_custom_field_name('last_donation_date'),
+        wmf_civicrm_get_custom_field_name('is_2011_donor'),
+        wmf_civicrm_get_custom_field_name('is_2012_donor'),
+        wmf_civicrm_get_custom_field_name('is_2013_donor'),
+        wmf_civicrm_get_custom_field_name('is_2014_donor'),
+        wmf_civicrm_get_custom_field_name('is_2015_donor'),
+        wmf_civicrm_get_custom_field_name('is_2016_donor'),
+      ),
     ));
-    $this->assertEquals(15, 
$contact['values'][0][wmf_civicrm_get_custom_field_name('lifetime_usd_total')]);
+    $this->assertEquals(24, 
$contact['values'][0][wmf_civicrm_get_custom_field_name('lifetime_usd_total')]);
     $this->assertEquals(1, 
$contact['values'][0][wmf_civicrm_get_custom_field_name('do_not_solicit')]);
+    $this->assertEquals(0, 
$contact['values'][0][wmf_civicrm_get_custom_field_name('is_2011_donor')]);
+    $this->assertEquals(1, 
$contact['values'][0][wmf_civicrm_get_custom_field_name('is_2012_donor')]);
+    $this->assertEquals(0, 
$contact['values'][0][wmf_civicrm_get_custom_field_name('is_2013_donor')]);
+    $this->assertEquals(1, 
$contact['values'][0][wmf_civicrm_get_custom_field_name('is_2014_donor')]);
+    $this->assertEquals(1, 
$contact['values'][0][wmf_civicrm_get_custom_field_name('is_2015_donor')]);
+    $this->assertEquals(0, 
$contact['values'][0][wmf_civicrm_get_custom_field_name('is_2016_donor')]);
+    $this->assertEquals(9, 
$contact['values'][0][wmf_civicrm_get_custom_field_name('last_donation_amount')]);
+    $this->assertEquals(9, 
$contact['values'][0][wmf_civicrm_get_custom_field_name('last_donation_usd')]);
+    $this->assertEquals('2016-04-04 00:00:00', 
$contact['values'][0][wmf_civicrm_get_custom_field_name('last_donation_date')]);
+    $this->assertEquals('NZD', 
$contact['values'][0][wmf_civicrm_get_custom_field_name('last_donation_currency')]);
 
     // Now lets check the one to be deleted has a do_not_solicit = 0.
     $this->callAPISuccess('Contact', 'create', array(
diff --git a/sites/all/modules/wmf_civicrm/wmf_civicrm.module 
b/sites/all/modules/wmf_civicrm/wmf_civicrm.module
index e46d9df..b7829f7 100644
--- a/sites/all/modules/wmf_civicrm/wmf_civicrm.module
+++ b/sites/all/modules/wmf_civicrm/wmf_civicrm.module
@@ -2008,7 +2008,12 @@
 }
 
 /**
- * Implementation of hook_civicrm_merge
+ * Implementation of hook_civicrm_merge().
+ * @param string $type
+ * @param array $refs
+ * @param int $mainId
+ * @param int $otherId
+ * @param array $tables
  */
 function wmf_civicrm_civicrm_merge( $type, &$refs, $mainId, $otherId, $tables 
) {
     switch ( $type ) {
@@ -2027,9 +2032,82 @@
             }
           }
         }
+
+        // Only bother to calculate the totals if we are already starting to 
merge.
+        if (empty($refs['fields_in_conflict'])) {
+          
wmf_civicrm_add_calculated_fields_to_migration_info($refs['migration_info'], 
$mainId, $otherId);
+        }
         break;
 
     }
+}
+
+/**
+ * Add the calculated fields to the migration info when merging.
+ *
+ * The contributions have already been merged so we can query the DB for this 
info. We
+ * are safeguarded against change by the test in our mergeTest although it 
makes sense to add
+ * a similar test upstream too.
+ *
+ * Doing this here rather than post merge means there are less changes to 
these values, meaning it
+ * is easier to revert.
+ *
+ * @param array $migrationInfo
+ * @param int $contactID
+ * @params int $otherID
+ *   ID of the contact to be deleted.
+ */
+function wmf_civicrm_add_calculated_fields_to_migration_info(&$migrationInfo, 
$contactID, $otherID) {
+  $select = "
+    SELECT
+      SUM(total_amount) AS lifetime_usd_total,
+      MAX(receive_date) AS last_donation_date,
+      SUM(COALESCE(total_amount, 0)) as total_usd_amount
+   ";
+  for ($year = WMF_MIN_ROLLUP_YEAR; $year <= WMF_MAX_ROLLUP_YEAR; $year++) {
+    $nextYear = $year + 1;
+    $select .= ", MAX(IF(receive_date BETWEEN '{$year}-07-01' AND 
'{$nextYear}-06-30 23:59:59', 1, 0)) as is_{$year}_donor";
+  }
+  $query = $select . "
+    FROM
+      civicrm_contribution c
+      LEFT JOIN wmf_contribution_extra x ON x.entity_id = c.contact_id
+      WHERE contact_id  IN ($contactID, $otherID)
+  ";
+  $result = CRM_Core_DAO::executeQuery($query);
+  $migrationInfo = 
_wmf_civicrm_add_result_fields_to_migration_info($migrationInfo, $result);
+  $query = "
+    SELECT
+      COALESCE(x.original_currency, currency) as last_donation_currency,
+      COALESCE(x.original_amount, total_amount) as last_donation_amount,
+      total_amount as last_donation_usd
+
+    FROM
+      civicrm_contribution c
+      LEFT JOIN wmf_contribution_extra x ON x.entity_id = c.id
+      WHERE contact_id  IN ($contactID, $otherID) AND receive_date = %1 LIMIT 
1";
+
+  $lastDate = $migrationInfo['move_' . 
wmf_civicrm_get_custom_field_name('last_donation_date')];
+  $result = CRM_Core_DAO::executeQuery($query, array(
+    1 => array($lastDate,
+    'String'
+  )));
+  $migrationInfo = 
_wmf_civicrm_add_result_fields_to_migration_info($migrationInfo, $result);
+}
+
+/**
+ * @param $migrationInfo
+ * @param $result
+ * @return mixed
+ */
+function _wmf_civicrm_add_result_fields_to_migration_info($migrationInfo, 
$result) {
+  $result->fetch();
+  foreach (wmf_get_calculated_field_names() as $field) {
+    if (isset($result->$field)) {
+      $migrationInfo['move_' . wmf_civicrm_get_custom_field_name($field)] = 
$result->$field;
+    }
+  }
+  return $migrationInfo;
 }
 
 /**
@@ -2044,22 +2122,32 @@
  *   - custom_2
  */
 function wmf_civicrm_get_calculated_fields() {
+  $fieldNames = wmf_get_calculated_field_names();
+  $fieldNames[] = 'do_not_solicit';
+  $customFields = array();
+  foreach ($fieldNames as $fieldName) {
+    $customFields[] = wmf_civicrm_get_custom_field_name($fieldName);
+  }
+  return $customFields;
+}
+
+/**
+ * Get the names of the calculated fields.
+ *
+ * @return array
+ */
+function wmf_get_calculated_field_names() {
   $fieldNames = array(
     'last_donation_date',
     'last_donation_currency',
     'last_donation_amount',
     'last_donation_usd',
     'lifetime_usd_total',
-    'do_not_solicit',
   );
   for ($year = WMF_MIN_ROLLUP_YEAR; $year <= WMF_MAX_ROLLUP_YEAR; $year++) {
     $fieldNames[] = 'is_' . $year . '_donor';
   }
-  $customFields = array();
-  foreach ($fieldNames as $fieldName) {
-    $customFields[] = wmf_civicrm_get_custom_field_name($fieldName);
-  }
-  return $customFields;
+  return $fieldNames;
 }
 
 /**
@@ -2070,9 +2158,6 @@
        if ( $type === 'Contribution' ) {
                wmf_civicrm_civicrm_post_Contribution( $op, $id, $entity );
        }
-  if ($op == 'merge') {
-    wmf_civicrm_calculate_donor_fields($id);
-  }
 }
 
 /**

-- 
To view, visit https://gerrit.wikimedia.org/r/294661
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: I18f2a72b0b6c351a34b3956f00ce3f81c9ce6570
Gerrit-PatchSet: 4
Gerrit-Project: wikimedia/fundraising/crm
Gerrit-Branch: master
Gerrit-Owner: Eileen <[email protected]>
Gerrit-Reviewer: Awight <[email protected]>
Gerrit-Reviewer: Cdentinger <[email protected]>
Gerrit-Reviewer: Eileen <[email protected]>
Gerrit-Reviewer: Ejegg <[email protected]>
Gerrit-Reviewer: jenkins-bot <>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to