Ejegg has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/313606

Change subject: Add check for stable data before running GC charges.
......................................................................

Add check for stable data before running GC charges.

When running drush recurring-globalcollect an error will be thrown if
any scheduled dates are more than 2 days away from a one month range
and it will not continue. This is a back stop against miscalculated dates

Bug: T144557

Change-Id: Icbddc60d4b45849b3b1960f47ba0d3df960a643a
---
M sites/all/modules/recurring_globalcollect/recurring_globalcollect.drush.inc
M sites/all/modules/recurring_globalcollect/recurring_globalcollect.info
M sites/all/modules/recurring_globalcollect/recurring_globalcollect.module
M sites/all/modules/recurring_globalcollect/recurring_globalcollect_common.inc
4 files changed, 88 insertions(+), 43 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/wikimedia/fundraising/crm 
refs/changes/06/313606/1

diff --git 
a/sites/all/modules/recurring_globalcollect/recurring_globalcollect.drush.inc 
b/sites/all/modules/recurring_globalcollect/recurring_globalcollect.drush.inc
index fcb9dd1..91a939f 100644
--- 
a/sites/all/modules/recurring_globalcollect/recurring_globalcollect.drush.inc
+++ 
b/sites/all/modules/recurring_globalcollect/recurring_globalcollect.drush.inc
@@ -14,7 +14,7 @@
 
   $items['recurring-globalcollect'] = array(
     'description' => 'Process recurring payments through GlobalCollect. ',
-    'examples' => array( 
+    'examples' => array(
       'drush recurring-globalcollect'       => '# Process recurring payments',
       'drush rg --batch=10'                        => '# Process up to 10 
contributions.',
       'drush rg --date=2011-12-31'                 => '# Specify a date to 
process. By default, today will be processed.',
@@ -56,17 +56,17 @@
   $date = drush_get_option('date');
   $url = drush_get_option('url');
   $batch = drush_get_option('batch');
-  
+
   $options = array();
 
   // Set the date
   $options['date'] = drush_recurring_globalcollect_parse_date($date);
- 
+
   // Set the url
   if ( !is_null($url)) {
     $options['url'] = $url;
   }
- 
+
   // Set the number of contributions to batch
   if ( !is_null( $batch ) ) {
     $options['batch'] = $batch;
@@ -91,7 +91,7 @@
 
 /**
  * drush_recurring_globalcollect_validate
- * 
+ *
  * This function is called magically from within Drush
  *
  * Numeric values for batch will be converted to an integer:
@@ -119,8 +119,16 @@
 
   $batch = drush_get_option('batch');
   $date = drush_get_option('date');
-  
+
   $batch_max = (integer) variable_get('recurring_globalcollect_batch_max', 
100);
+  if (is_found_globalcollect_invalid_next_sched_dates()) {
+    $message = 'Global Collect recurring processing aborted '
+      . 'until invalid next scheduled recurring dates resolved. The query '
+      . ' to find them is in 
https://phabricator.wikimedia.org/T144557#2673161';
+    wmf_common_failmail('Invalid data blocking global collect', $message);
+    drush_set_error('SCHED_DATE_CHECK', dt($message));
+    return false;
+  }
 
   /**
    * Validate batch:
@@ -137,18 +145,18 @@
       drush_set_error('BATCHING', dt($message));
       return false;
     }
-    
+
     // $batch is numeric, convert it to an integer for further testing.
     $batch = (integer) $batch;
-    
+
     if ($batch < 1) {
-      
+
       $message = 'Batching is disabled: $batch = "' . $batch . '"';
       $link = l('Edit recurring GlobalCollect settings', 
'admin/config/recurring_globalcollect');
       watchdog('recurring_globalcollect', $message, array(), WATCHDOG_WARNING, 
$link);
-      return false;         
+      return false;
     }
-    
+
     if ($batch < 0) {
 
       $message = 'You specified a negative number. You must specify either'
@@ -157,7 +165,7 @@
       drush_set_error('BATCHING', dt($message));
       return false;
     }
-    
+
     if ($batch > $batch_max) {
       $message = 'You are attempting to batch ' . $batch .' payments, which'
         . ' is more than the maximum allowed: ' . $batch_max .'. Either batch'
@@ -173,7 +181,7 @@
    * - failures_before_cancellation
    */
   $failures_before_cancellation = (integer) 
variable_get('recurring_globalcollect_failures_before_cancellation', 0);
-  
+
   if ( $failures_before_cancellation < 1 ) {
     $message = 'The value in settings, "Failures before subscription is'
              . ' cancelled" must be a postive integer. You specifed ['
@@ -196,7 +204,7 @@
  * @return                     Returns the date with the format: 'Y-m-d'
  */
 function drush_recurring_globalcollect_parse_date($date) {
-  
+
   if (!empty($date)) {
     $oldTimezone = date_default_timezone_get();
     date_default_timezone_set( "UTC" );
@@ -204,20 +212,20 @@
     $now_stamp = time();
     $now = date('Y-m-d', $now_stamp);
     $date_stamp = strtotime($date);
-    
+
     // Set date from stamp so we have the proper format expected by the module.
     $date = date('Y-m-d', $date_stamp);
 
     date_default_timezone_set( $oldTimezone );
-    
+
     if ($date_stamp > $now_stamp) {
       $message = 'The date you entered [' . $date . '] is being parsed as [' . 
$date . ']. The current date is: [' . $now . ']. You are not allowed to specify 
dates in the future.';
       drush_set_error('FUTURE_DATE', dt($message));
       return false;
     }
   }
-  
+
   return $date;
-       
+
 }
 
diff --git 
a/sites/all/modules/recurring_globalcollect/recurring_globalcollect.info 
b/sites/all/modules/recurring_globalcollect/recurring_globalcollect.info
index e84f1b7..2eecf8c 100644
--- a/sites/all/modules/recurring_globalcollect/recurring_globalcollect.info
+++ b/sites/all/modules/recurring_globalcollect/recurring_globalcollect.info
@@ -3,6 +3,7 @@
 core = 7.x
 dependencies[] = civicrm
 dependencies[] = wmf_common
+dependencies[] = wmf_communication
 dependencies[] = queue2civicrm
 dependencies[] = wmf_civicrm
 package = GlobalCollect
diff --git 
a/sites/all/modules/recurring_globalcollect/recurring_globalcollect.module 
b/sites/all/modules/recurring_globalcollect/recurring_globalcollect.module
index 9d946f3..9a0b843 100644
--- a/sites/all/modules/recurring_globalcollect/recurring_globalcollect.module
+++ b/sites/all/modules/recurring_globalcollect/recurring_globalcollect.module
@@ -435,3 +435,39 @@
 
   drupal_set_message($message);
 }
+
+/**
+ * Are there any recurring contributions with next_dates that are dubious.
+ *
+ * The next date, for monthly contributions, should be one month after
+ * the last payment, give or take a couple of days for month length weirdness.
+ *
+ * If there are we might not want to run the charges until we have checked 
them out.
+ *
+ * Only check 2016+ transactions (since those are currently clean) and
+ * exclude Coinbase (not currently clean).
+ *
+ * @return bool
+ */
+function is_found_globalcollect_invalid_next_sched_dates() {
+  civicrm_initialize();
+  $query = "
+  SELECT count(*) FROM (
+    SELECT
+    DATEDIFF(DATE_ADD(DATE(max(receive_date) ), INTERVAL 1 month) , 
DATE(next_sched_contribution_date)) as date_diff
+    FROM civicrm_contribution_recur cr
+    LEFT JOIN civicrm_contribution c  on c.contribution_recur_id = cr.id
+    WHERE end_date IS NULL
+    AND cr.contribution_status_id <> 3
+    AND cr.contribution_status_id <> 4
+    AND c.trxn_id LIKE 'RECURRING GLOBALCOLLECT%'
+    AND next_sched_contribution_date > '2016-01-01'
+    AND frequency_unit = 'month' AND frequency_interval = 1
+    GROUP BY cr.id DESC
+   ) as inn
+  WHERE date_diff NOT BETWEEN -3 AND 3
+ ";
+
+  $count = CRM_Core_DAO::singleValueQuery($query);
+  return !empty($count);
+}
diff --git 
a/sites/all/modules/recurring_globalcollect/recurring_globalcollect_common.inc 
b/sites/all/modules/recurring_globalcollect/recurring_globalcollect_common.inc
index 3432b12..eeaa298 100644
--- 
a/sites/all/modules/recurring_globalcollect/recurring_globalcollect_common.inc
+++ 
b/sites/all/modules/recurring_globalcollect/recurring_globalcollect_common.inc
@@ -1,12 +1,12 @@
-<?php 
+<?php
 /**
- * Common functions for recurring_globalcollect modules 
+ * Common functions for recurring_globalcollect modules
  */
 
 
 /**
  * Select one payment by the primary key.
- * 
+ *
  * @return false|object
  */
 function recurring_globalcollect_get_payment_by_id($id)
@@ -18,23 +18,23 @@
   $dbs->push( 'civicrm' );
 
   $query = 'SELECT civicrm_contribution_recur.* FROM 
civicrm_contribution_recur WHERE civicrm_contribution_recur.id = :id LIMIT 1';
-  
+
   $result = db_query( $query, array( ':id' => $id ) )->fetch();
 
   if ( empty( $result ) ) {
     throw new WmfException( 'INVALID_RECURRING', t( 'No record was found with 
the id: [!id].', array( '!id' => $id ) ) );
   }
- 
+
   return $result;
 }
 
 /**
  * Select a set of recurring payments that need to be retried today
- * 
+ *
  * NOTE: `end_date` should only be set if the end has passed.
- * 
+ *
  * Example query called with standard options and the date set to: 2012-01-01
- * 
+ *
  * SELECT `civicrm_contribution_recur`.* FROM `civicrm_contribution_recur`
  *  WHERE `civicrm_contribution_recur`.`failure_retry_date`
  *   BETWEEN '2012-01-01 00:00:00' AND '2012-04-01 23:59:59'
@@ -42,7 +42,7 @@
  *  AND ( `civicrm_contribution_recur`.`end_date` IS NULL )
  *  AND `civicrm_contribution_recur`.`contribution_status_id` = 4
  * LIMIT 1
- * 
+ *
  * @param int $limit Number of records to pull. Default is 1.
  * @param string $date End of period to look for failure retries. Start of
  *      period is this minus recurring_globalcollect_run_missed_days. Uses
@@ -50,7 +50,7 @@
  *
  * @todo The field `civicrm_payment_processor`.`payment_processor_type` should 
be set.
  * @todo Implement $contributionStatus = 
CRM_Contribute_PseudoConstant::contributionStatus( null, 'name' );
- * 
+ *
  * @return false|object
  */
 function recurring_globalcollect_get_failure_retry_batch($limit = 1, $date = 
'now', $past_days = 0) {
@@ -125,7 +125,7 @@
     return false;
   }
   $order_id = intval( $order_id );
-  
+
   // make sure we're using the default (civicrm) db
   $dbs = wmf_civicrm_get_dbs();
   $dbs->push( 'civicrm' );
@@ -141,11 +141,11 @@
     OR civicrm_contribution_recur.trxn_id LIKE CONCAT_WS( ' ', 'RECURRING 
GLOBALCOLLECT', :order_id, '%' )
 LIMIT 1
 EOS;
-  
+
   $result = db_query( $query, array( ':order_id' => $order_id ) )->fetch();
 
   $record = is_object( $result ) ? (array) $result : false;
-  
+
   return $record;
 }
 
@@ -166,7 +166,7 @@
  * - [6] => Overdue (not used by this module)
  *
  * @param integer $id     The primary key of the record.
- * 
+ *
  * @return integer  Returns the number of affected rows.
  */
 function _recurring_globalcollect_update_record_failure($id) {
@@ -176,7 +176,7 @@
 
   // Make sure all of the proper fields are set to sane values.
   _recurring_globalcollect_validate_record_for_update($record);
-  
+
   $failures_before_cancellation = (integer) variable_get( 
'recurring_globalcollect_failures_before_cancellation', 0 );
   $recurring_globalcollect_failure_retry_rate = (integer) 
abs(variable_get('recurring_globalcollect_failure_retry_rate', 1));
 
@@ -227,14 +227,14 @@
  * @todo Implement $contributionStatus = 
CRM_Contribute_PseudoConstant::contributionStatus( null, 'name' );
  *
  * @param integer $id     The primary key of the record.
- * 
+ *
  * @return integer  Returns the number of affected rows.
  */
 function _recurring_globalcollect_update_record_in_progress($id) {
- 
+
   $result = recurring_globalcollect_get_payment_by_id($id);
   $record = (array) $result;
-  
+
   $working_statuses = array(
       civicrm_api_contribution_status( 'Completed' ),
       civicrm_api_contribution_status( 'Failed' ),
@@ -255,11 +255,11 @@
       ->execute();
 
   $dbs->pop();
-  
+
   if ( !$affected_rows ) {
     throw new WmfException( 'INVALID_RECURRING', t( 'The subscription was not 
marked as in progress.' ), $record );
   }
-  
+
   return $affected_rows;
 }
 
@@ -269,17 +269,17 @@
  * Payments will be rescheduled for the following month.
  *
  * @param integer $id     The primary key of the record.
- * 
+ *
  * @return integer  Returns the number of affected rows.
  */
 function _recurring_globalcollect_update_record_success($id) {
- 
+
   $result = recurring_globalcollect_get_payment_by_id($id);
   $record = (array) $result;
-  
+
   // Make sure all of the proper fields are set to sane values.
   _recurring_globalcollect_validate_record_for_update($record);
-  
+
   $next_sched_contribution = 
wmf_civicrm_get_next_sched_contribution_date_for_month($record);
 
   $dbs = wmf_civicrm_get_dbs();
@@ -355,7 +355,7 @@
 
   $protocol = (isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) == 
'on') ? 'https' : 'http';
   $host = (isset($_SERVER['HTTP_HOST'])) ? $_SERVER['HTTP_HOST'] : 'localhost';
-  
+
   $defaultTestUrl = $protocol . '://' . $host . '/';
 
   return $defaultTestUrl;

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

Gerrit-MessageType: newchange
Gerrit-Change-Id: Icbddc60d4b45849b3b1960f47ba0d3df960a643a
Gerrit-PatchSet: 1
Gerrit-Project: wikimedia/fundraising/crm
Gerrit-Branch: deployment
Gerrit-Owner: Ejegg <eeggles...@wikimedia.org>
Gerrit-Reviewer: Eileen <emcnaugh...@wikimedia.org>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to