Merge pull request #17719 from civicrm/5.27
[civicrm-core.git] / CRM / Contribute / Form / CancelSubscription.php
index 4cbac2cfb6cac0533e45cf399ded972a1d1be75b..3d0003796ef17921d23f333df25dc55405ba80d6 100644 (file)
@@ -9,11 +9,7 @@
  +--------------------------------------------------------------------+
  */
 
-/**
- *
- * @package CRM
- * @copyright CiviCRM LLC https://civicrm.org/licensing
- */
+use Civi\Payment\PropertyBag;
 
 /**
  * This class provides support for canceling recurring subscriptions.
@@ -24,6 +20,13 @@ class CRM_Contribute_Form_CancelSubscription extends CRM_Contribute_Form_Contrib
 
   protected $_mode = NULL;
 
+  /**
+   * The contributor email
+   *
+   * @var string
+   */
+  protected $_donorEmail = '';
+
   /**
    * Should custom data be suppressed on this form.
    *
@@ -44,15 +47,21 @@ class CRM_Contribute_Form_CancelSubscription extends CRM_Contribute_Form_Contrib
    */
   public function preProcess() {
     parent::preProcess();
-    if ($this->_crid) {
-      $this->assign('frequency_unit', $this->_subscriptionDetails->frequency_unit);
-      $this->assign('frequency_interval', $this->_subscriptionDetails->frequency_interval);
-      $this->assign('amount', $this->_subscriptionDetails->amount);
-      $this->assign('installments', $this->_subscriptionDetails->installments);
 
+    $cancelRecurTextParams = [
+      'mode' => $this->_mode,
+      'amount' => $this->getSubscriptionDetails()->amount,
+      'currency' => $this->getSubscriptionDetails()->currency,
+      'frequency_interval' => $this->getSubscriptionDetails()->frequency_interval,
+      'frequency_unit' => $this->getSubscriptionDetails()->frequency_unit,
+      'installments' => $this->getSubscriptionDetails()->installments,
+      'selfService' => $this->isSelfService(),
+    ];
+
+    if ($this->_crid) {
       // Are we cancelling a recurring contribution that is linked to an auto-renew membership?
-      if ($this->_subscriptionDetails->membership_id) {
-        $this->_mid = $this->_subscriptionDetails->membership_id;
+      if ($this->getSubscriptionDetails()->membership_id) {
+        $this->_mid = $this->getSubscriptionDetails()->membership_id;
       }
     }
 
@@ -63,7 +72,9 @@ class CRM_Contribute_Form_CancelSubscription extends CRM_Contribute_Form_Contrib
 
       $membershipTypes = CRM_Member_PseudoConstant::membershipType();
       $membershipTypeId = CRM_Core_DAO::getFieldValue('CRM_Member_DAO_Membership', $this->_mid, 'membership_type_id');
-      $this->assign('membershipType', CRM_Utils_Array::value($membershipTypeId, $membershipTypes));
+      $membershipType = $membershipTypes[$membershipTypeId] ?? '';
+      $this->assign('membershipType', $membershipType);
+      $cancelRecurTextParams['membershipType'] = $membershipType;
     }
 
     if ($this->_coid) {
@@ -71,20 +82,17 @@ class CRM_Contribute_Form_CancelSubscription extends CRM_Contribute_Form_Contrib
         CRM_Core_Error::statusBounce(ts('The recurring contribution looks to have been cancelled already.'));
       }
       $this->_paymentProcessorObj = CRM_Financial_BAO_PaymentProcessor::getProcessorForEntity($this->_coid, 'contribute', 'obj');
-
-      $this->assign('frequency_unit', $this->_subscriptionDetails->frequency_unit);
-      $this->assign('frequency_interval', $this->_subscriptionDetails->frequency_interval);
-      $this->assign('amount', $this->_subscriptionDetails->amount);
-      $this->assign('installments', $this->_subscriptionDetails->installments);
     }
 
     if (
       (!$this->_crid && !$this->_coid && !$this->_mid) ||
-      (!$this->_subscriptionDetails)
+      (!$this->getSubscriptionDetails())
     ) {
       CRM_Core_Error::statusBounce('Required information missing.');
     }
 
+    $this->assign('cancelRecurDetailText', $this->_paymentProcessorObj->getText('cancelRecurDetailText', $cancelRecurTextParams));
+
     // handle context redirection
     CRM_Contribute_BAO_ContributionRecur::setSubscriptionContext();
 
@@ -95,9 +103,9 @@ class CRM_Contribute_Form_CancelSubscription extends CRM_Contribute_Form_Contrib
       unset($this->entityFields['send_cancel_request'], $this->entityFields['is_notify']);
     }
 
-    if ($this->_subscriptionDetails->contact_id) {
+    if ($this->getSubscriptionDetails()->contact_id) {
       list($this->_donorDisplayName, $this->_donorEmail)
-        = CRM_Contact_BAO_Contact::getContactDetails($this->_subscriptionDetails->contact_id);
+        = CRM_Contact_BAO_Contact::getContactDetails($this->getSubscriptionDetails()->contact_id);
     }
   }
 
@@ -126,8 +134,7 @@ class CRM_Contribute_Form_CancelSubscription extends CRM_Contribute_Form_Contrib
   public function buildQuickForm() {
     $this->buildQuickEntityForm();
     // Determine if we can cancel recurring contribution via API with this processor
-    $cancelSupported = $this->_paymentProcessorObj->supports('CancelRecurring');
-    if ($cancelSupported) {
+    if ($this->_paymentProcessorObj->supports('CancelRecurringNotifyOptional')) {
       $searchRange = [];
       $searchRange[] = $this->createElement('radio', NULL, NULL, ts('Yes'), '1');
       $searchRange[] = $this->createElement('radio', NULL, NULL, ts('No'), '0');
@@ -136,13 +143,15 @@ class CRM_Contribute_Form_CancelSubscription extends CRM_Contribute_Form_Contrib
         $searchRange,
         'send_cancel_request',
         ts('Send cancellation request to %1 ?',
-          [1 => $this->_paymentProcessorObj->_processorName])
+          [1 => $this->_paymentProcessorObj->getTitle()])
       );
     }
-    $this->assign('cancelSupported', $cancelSupported);
+    else {
+      $this->assign('cancelRecurNotSupportedText', $this->_paymentProcessorObj->getText('cancelRecurNotSupportedText', []));
+    }
 
-    if ($this->_donorEmail) {
-      $this->add('checkbox', 'is_notify', ts('Notify Contributor?'));
+    if (!empty($this->_donorEmail)) {
+      $this->add('checkbox', 'is_notify', ts('Notify Contributor?') . " ({$this->_donorEmail})");
     }
     if ($this->_mid) {
       $cancelButton = ts('Cancel Automatic Membership Renewal');
@@ -185,9 +194,11 @@ class CRM_Contribute_Form_CancelSubscription extends CRM_Contribute_Form_Contrib
 
   /**
    * Process the form submission.
+   *
+   * @throws \CRM_Core_Exception
    */
   public function postProcess() {
-    $status = $message = NULL;
+    $message = NULL;
     $cancelSubscription = TRUE;
     $params = $this->controller->exportValues($this->_name);
 
@@ -197,30 +208,28 @@ class CRM_Contribute_Form_CancelSubscription extends CRM_Contribute_Form_Contrib
         $params['send_cancel_request'] = 1;
       }
 
-      if ($this->_donorEmail) {
+      if (!empty($this->_donorEmail)) {
         $params['is_notify'] = 1;
       }
     }
 
-    if (CRM_Utils_Array::value('send_cancel_request', $params) == 1) {
-      // Note the 'subscriptionId' here is the value stored in
-      // civicrm_contribution_recur.processor_id
-      $cancelParams = ['subscriptionId' => $this->_subscriptionDetails->subscription_id];
-      try {
-        $cancelSubscription = $this->_paymentProcessorObj->cancelSubscription($message, $cancelParams);
-      }
-      catch (\Civi\Payment\Exception\PaymentProcessorException $e) {
-        CRM_Core_Error::statusBounce($e->getMessage());
+    try {
+      $propertyBag = new PropertyBag();
+      if (isset($params['send_cancel_request'])) {
+        $propertyBag->setIsNotifyProcessorOnCancelRecur(!empty($params['send_cancel_request']));
       }
+      $propertyBag->setContributionRecurID($this->getSubscriptionDetails()->recur_id);
+      $propertyBag->setRecurProcessorID($this->getSubscriptionDetails()->processor_id);
+      $message = $this->_paymentProcessorObj->doCancelRecurring($propertyBag)['message'];
     }
-
-    if (is_a($cancelSubscription, 'CRM_Core_Error')) {
-      CRM_Core_Error::displaySessionError($cancelSubscription);
+    catch (\Civi\Payment\Exception\PaymentProcessorException $e) {
+      CRM_Core_Error::statusBounce($e->getMessage());
     }
-    elseif ($cancelSubscription) {
+
+    if ($cancelSubscription) {
       try {
         civicrm_api3('ContributionRecur', 'cancel', [
-          'id' => $this->_subscriptionDetails->recur_id,
+          'id' => $this->getSubscriptionDetails()->recur_id,
           'membership_id' => $this->_mid,
           'processor_message' => $message,
           'cancel_reason' => $params['cancel_reason'],
@@ -240,15 +249,15 @@ class CRM_Contribute_Form_CancelSubscription extends CRM_Contribute_Form_Contrib
           $msgType = 'info';
         }
         else {
-          $tplParams['recur_frequency_interval'] = $this->_subscriptionDetails->frequency_interval;
-          $tplParams['recur_frequency_unit'] = $this->_subscriptionDetails->frequency_unit;
-          $tplParams['amount'] = $this->_subscriptionDetails->amount;
+          $tplParams['recur_frequency_interval'] = $this->getSubscriptionDetails()->frequency_interval;
+          $tplParams['recur_frequency_unit'] = $this->getSubscriptionDetails()->frequency_unit;
+          $tplParams['amount'] = CRM_Utils_Money::format($this->getSubscriptionDetails()->amount, $this->getSubscriptionDetails()->currency);
           $tplParams['contact'] = ['display_name' => $this->_donorDisplayName];
           $status = ts('The recurring contribution of %1, every %2 %3 has been cancelled.',
             [
-              1 => $this->_subscriptionDetails->amount,
-              2 => $this->_subscriptionDetails->frequency_interval,
-              3 => $this->_subscriptionDetails->frequency_unit,
+              1 => $tplParams['amount'],
+              2 => $tplParams['recur_frequency_interval'],
+              3 => $tplParams['recur_frequency_unit'],
             ]
           );
           $msgTitle = 'Contribution Cancelled';
@@ -256,18 +265,18 @@ class CRM_Contribute_Form_CancelSubscription extends CRM_Contribute_Form_Contrib
         }
 
         if (CRM_Utils_Array::value('is_notify', $params) == 1) {
-          if ($this->_subscriptionDetails->contribution_page_id) {
+          if ($this->getSubscriptionDetails()->contribution_page_id) {
             CRM_Core_DAO::commonRetrieveAll(
               'CRM_Contribute_DAO_ContributionPage',
               'id',
-              $this->_subscriptionDetails->contribution_page_id,
+              $this->getSubscriptionDetails()->contribution_page_id,
               $value,
               ['title', 'receipt_from_name', 'receipt_from_email']
             );
             $receiptFrom
-              = '"' . CRM_Utils_Array::value('receipt_from_name', $value[$this->_subscriptionDetails->contribution_page_id]) .
+              = '"' . CRM_Utils_Array::value('receipt_from_name', $value[$this->getSubscriptionDetails()->contribution_page_id]) .
               '" <' .
-              $value[$this->_subscriptionDetails->contribution_page_id]['receipt_from_email'] .
+              $value[$this->getSubscriptionDetails()->contribution_page_id]['receipt_from_email'] .
               '>';
           }
           else {
@@ -280,7 +289,7 @@ class CRM_Contribute_Form_CancelSubscription extends CRM_Contribute_Form_Contrib
             = [
               'groupName' => $this->_mode == 'auto_renew' ? 'msg_tpl_workflow_membership' : 'msg_tpl_workflow_contribution',
               'valueName' => $this->_mode == 'auto_renew' ? 'membership_autorenew_cancelled' : 'contribution_recurring_cancelled',
-              'contactId' => $this->_subscriptionDetails->contact_id,
+              'contactId' => $this->getSubscriptionDetails()->contact_id,
               'tplParams' => $tplParams,
               //'isTest'    => $isTest, set this from _objects
               'PDFFilename' => 'receipt.pdf',