diff --git a/CRM/Twingle/Tools.php b/CRM/Twingle/Tools.php new file mode 100644 index 0000000..6af1999 --- /dev/null +++ b/CRM/Twingle/Tools.php @@ -0,0 +1,94 @@ + 'trxn_id,contribution_status_id,payment_instrument_id', + 'id' => $recurring_contribution_id]); + + // check if this is a SEPA transaction + //if (self::isSDD($recurring_contribution['payment_instrument_id'])) return; + + // check if it's really a termination (i.e. current status is 2 or 5) + if (!in_array($recurring_contribution['contribution_status_id'], [2,5])) return; + + // check if it's a Twingle contribution + if (substr($recurring_contribution['trxn_id'], 0, strlen($prefix)) == $prefix) { + // this is a Twingle contribution that is about to be terminated + throw new Exception(E::ts("This is a Twingle recurring contribution. It should be terminated through the Twingle interface, otherwise it will still be collected.")); + } + } + + /** + * Check if the given payment instrument is SEPA + * + * @param $payment_instrument_id string payment instrument + * @return boolean + */ + public static function isSDD($payment_instrument_id) { + static $sepa_payment_instruments = NULL; + if ($sepa_payment_instruments === NULL) { + // init with instrument names + $sepa_payment_instruments = ['FRST', 'RCUR', 'OOFF']; + + // lookup and add instrument IDs + $lookup = civicrm_api3('OptionValue', 'get', [ + 'option_group_id' => 'payment_instrument', + 'name' => ['IN' => $sepa_payment_instruments], + 'return' => 'value' + ]); + foreach ($lookup['values'] as $payment_instrument) { + $sepa_payment_instruments[] = $payment_instrument['value']; + } + } + return in_array($payment_instrument_id, $sepa_payment_instruments); + } +} diff --git a/api/v3/TwingleDonation/Cancel.php b/api/v3/TwingleDonation/Cancel.php index 00fc6a8..4883217 100644 --- a/api/v3/TwingleDonation/Cancel.php +++ b/api/v3/TwingleDonation/Cancel.php @@ -122,12 +122,14 @@ function civicrm_api3_twingle_donation_Cancel($params) { )); } else { + CRM_Twingle_Tools::$protection_suspended = TRUE; $contribution = civicrm_api3($contribution_type, 'create', array( 'id' => $contribution['id'], 'cancel_date' => $params['cancelled_at'], 'contribution_status_id' => 'Cancelled', 'cancel_reason' => $params['cancel_reason'], )); + CRM_Twingle_Tools::$protection_suspended = FALSE; } $result = civicrm_api3_create_success($contribution); diff --git a/api/v3/TwingleDonation/Endrecurring.php b/api/v3/TwingleDonation/Endrecurring.php index baecb32..aa5d967 100644 --- a/api/v3/TwingleDonation/Endrecurring.php +++ b/api/v3/TwingleDonation/Endrecurring.php @@ -113,11 +113,13 @@ function civicrm_api3_twingle_donation_endrecurring($params) { )); } else { + CRM_Twingle_Tools::$protection_suspended = TRUE; $contribution = civicrm_api3('ContributionRecur', 'create', array( 'id' => $contribution['id'], 'end_date' => $params['ended_at'], 'contribution_status_id' => CRM_Twingle_Submission::CONTRIBUTION_STATUS_COMPLETED, )); + CRM_Twingle_Tools::$protection_suspended = FALSE; } $result = civicrm_api3_create_success($contribution); diff --git a/settings/twingle.setting.php b/settings/twingle.setting.php index 1df4d27..d703845 100644 --- a/settings/twingle.setting.php +++ b/settings/twingle.setting.php @@ -31,6 +31,20 @@ return array( 'is_contact' => 0, 'description' => 'Whether to provide CiviSEPA functionality for manual debit payment method. This requires the CiviSEPA (org.project60.sepa) extension be installed.', ), + 'twingle_protect_recurring' => array( + 'group_name' => 'de.systopia.twingle', + 'group' => 'de.systopia.twingle', + 'name' => 'twingle_protect_recurring', + 'type' => 'Boolean', + 'quick_form_type' => 'YesNo', + 'html_type' => 'radio', + 'title' => 'Protect Recurring Contributions', + 'default' => 0, + 'add' => '4.6', + 'is_domain' => 1, + 'is_contact' => 0, + 'description' => 'Will protect all recurring contributions created by Twingle from termination, since this does NOT terminate the Twingle collection process. Currently only works with a prefix', + ), 'twingle_prefix' => array( 'group_name' => 'de.systopia.twingle', 'group' => 'de.systopia.twingle', diff --git a/templates/CRM/Twingle/Form/Settings.hlp b/templates/CRM/Twingle/Form/Settings.hlp index b9ff9d1..8b5ef1b 100644 --- a/templates/CRM/Twingle/Form/Settings.hlp +++ b/templates/CRM/Twingle/Form/Settings.hlp @@ -16,6 +16,10 @@ {ts domain="de.systopia.twingle" 1="CiviSEPA (org.project60.sepa) extension"}When the %1 is enabled and one of its payment instruments is assigned to a Twingle payment method (practically the debit_manual payment method), submitting a Twingle donation through the API will create a SEPA mandate with the given data.{/ts} {/htxt} +{htxt id='id-twingle_protect_recurring'} + {ts domain="de.systopia.twingle"}Will protect all recurring contributions created by Twingle from termination, since this does NOT terminate the Twingle collection process{/ts} +{/htxt} + {htxt id='id-twingle_prefix'} {ts domain="de.systopia.twingle"}You can use this setting to add a prefix to the Twingle transaction ID, in order to avoid collisions with other transaction ids.{/ts} {/htxt} diff --git a/twingle.php b/twingle.php index c2a064e..214d041 100644 --- a/twingle.php +++ b/twingle.php @@ -3,6 +3,15 @@ require_once 'twingle.civix.php'; use CRM_Twingle_ExtensionUtil as E; +/** + * Implements hook_civicrm_pre(). + */ +function twingle_civicrm_pre($op, $objectName, $id, &$params) { + if ($objectName == 'ContributionRecur' && $op == 'edit') { + CRM_Twingle_Tools::checkRecurringContributionChange($id, $params); + } +} + /** * Implements hook_civicrm_config(). *