CRM-16829 move form functions to form
authorEileen McNaughton <eileen@fuzion.co.nz>
Fri, 10 Jul 2015 08:49:12 +0000 (20:49 +1200)
committerEileen McNaughton <eileen@fuzion.co.nz>
Fri, 10 Jul 2015 08:49:12 +0000 (20:49 +1200)
CRM/Contribute/Form/Contribution/Confirm.php
CRM/Member/BAO/Membership.php

index 863e8ef56bf2b9f77a724e6f1cf70e4d31ce1770..dcd9cce58f6fa462359c1b5479f6f34172747e76 100644 (file)
@@ -1551,7 +1551,7 @@ class CRM_Contribute_Form_Contribution_Confirm extends CRM_Contribute_Form_Contr
         $membershipParams['contribution_source'] = $this->_params['membership_source'];
       }
 
-      CRM_Member_BAO_Membership::postProcessMembership($membershipParams, $contactID,
+      $this->postProcessMembership($membershipParams, $contactID,
         $this, $premiumParams, $customFieldsFormatted, $fieldTypes, $membershipType, $membershipTypeIDs, $isPaidMembership, $this->_membershipId, $isProcessSeparateMembershipTransaction, $financialTypeID,
         $membershipLineItems, $isPayLater, $isPending);
 
@@ -1564,6 +1564,343 @@ class CRM_Contribute_Form_Contribution_Confirm extends CRM_Contribute_Form_Contr
     }
   }
 
+  /**
+   * Process the Memberships.
+   *
+   * @param array $membershipParams
+   *   Array of membership fields.
+   * @param int $contactID
+   *   Contact id.
+   * @param CRM_Contribute_Form_Contribution_Confirm $form
+   *   Confirmation form object.
+   *
+   * @param array $premiumParams
+   * @param null $customFieldsFormatted
+   * @param null $includeFieldTypes
+   *
+   * @param array $membershipDetails
+   *
+   * @param array $membershipTypeIDs
+   *
+   * @param bool $isPaidMembership
+   * @param array $membershipID
+   *
+   * @param bool $isProcessSeparateMembershipTransaction
+   *
+   * @param int $financialTypeID
+   * @param array $membershipLineItems
+   *   Line items specific to membership payment that is separate to contribution.
+   * @param bool $isPayLater
+   * @param bool $isPending
+   *
+   * @throws \CRM_Core_Exception
+   */
+  protected function postProcessMembership(
+    $membershipParams, $contactID, &$form, $premiumParams,
+    $customFieldsFormatted = NULL, $includeFieldTypes = NULL, $membershipDetails, $membershipTypeIDs, $isPaidMembership, $membershipID,
+    $isProcessSeparateMembershipTransaction, $financialTypeID, $membershipLineItems, $isPayLater, $isPending) {
+    $result = $membershipContribution = NULL;
+    $isTest = CRM_Utils_Array::value('is_test', $membershipParams, FALSE);
+    $errors = $createdMemberships = $paymentResult = array();
+
+    if ($isPaidMembership) {
+      if ($isProcessSeparateMembershipTransaction) {
+        // If we have 2 transactions only one can use the invoice id.
+        $membershipParams['invoiceID'] .= '-2';
+      }
+
+      $paymentResult = CRM_Contribute_BAO_Contribution_Utils::processConfirm($form, $membershipParams,
+        $premiumParams, $contactID,
+        $financialTypeID,
+        'membership',
+        array(),
+        $isTest,
+        $isPayLater
+      );
+      if (is_a($result[1], 'CRM_Core_Error')) {
+        $errors[1] = CRM_Core_Error::getMessages($paymentResult[1]);
+      }
+
+      if (is_a($paymentResult, 'CRM_Core_Error')) {
+        $errors[1] = CRM_Core_Error::getMessages($paymentResult);
+      }
+      elseif (!empty($paymentResult['contribution'])) {
+        //note that this will be over-written if we are using a separate membership transaction. Otherwise there is only one
+        $membershipContribution = $paymentResult['contribution'];
+        // Save the contribution ID so that I can be used in email receipts
+        // For example, if you need to generate a tax receipt for the donation only.
+        $form->_values['contribution_other_id'] = $membershipContribution->id;
+      }
+    }
+
+    if ($isProcessSeparateMembershipTransaction) {
+      try {
+        $form->_lineItem = $membershipLineItems;
+        if (empty($form->_params['auto_renew']) && !empty($membershipParams['is_recur'])) {
+          unset($membershipParams['is_recur']);
+        }
+        $membershipContribution = $this->processSecondaryFinancialTransaction($contactID, $form, $membershipParams,
+          $isTest, $membershipLineItems, CRM_Utils_Array::value('minimum_fee', $membershipDetails, 0), CRM_Utils_Array::value('financial_type_id', $membershipDetails));
+      }
+      catch (CRM_Core_Exception $e) {
+        $errors[2] = $e->getMessage();
+        $membershipContribution = NULL;
+      }
+    }
+
+    $membership = NULL;
+    if (!empty($membershipContribution) && !is_a($membershipContribution, 'CRM_Core_Error')) {
+      $membershipContributionID = $membershipContribution->id;
+    }
+
+    //@todo - why is this nested so deep? it seems like it could be just set on the calling function on the form layer
+    if (isset($membershipParams['onbehalf']) && !empty($membershipParams['onbehalf']['member_campaign_id'])) {
+      $form->_params['campaign_id'] = $membershipParams['onbehalf']['member_campaign_id'];
+    }
+    //@todo it should no longer be possible for it to get to this point & membership to not be an array
+    if (is_array($membershipTypeIDs) && !empty($membershipContributionID)) {
+      $typesTerms = CRM_Utils_Array::value('types_terms', $membershipParams, array());
+      foreach ($membershipTypeIDs as $memType) {
+        $numTerms = CRM_Utils_Array::value($memType, $typesTerms, 1);
+        if (!empty($membershipContribution)) {
+          $pendingStatus = CRM_Core_OptionGroup::getValue('contribution_status', 'Pending', 'name');
+          $pending = ($membershipContribution->contribution_status_id == $pendingStatus) ? TRUE : FALSE;
+        }
+        else {
+          $pending = $isPending;
+        }
+        $contributionRecurID = isset($form->_params['contributionRecurID']) ? $form->_params['contributionRecurID'] : NULL;
+
+        $membershipSource = NULL;
+        if (!empty($form->_params['membership_source'])) {
+          $membershipSource = $form->_params['membership_source'];
+        }
+        elseif (isset($form->_values['title']) && !empty($form->_values['title'])) {
+          $membershipSource = ts('Online Contribution:') . ' ' . $form->_values['title'];
+        }
+        $isPayLater = NULL;
+        if (isset($form->_params)) {
+          $isPayLater = CRM_Utils_Array::value('is_pay_later', $form->_params);
+        }
+        $campaignId = NULL;
+        if (isset($form->_values) && is_array($form->_values) && !empty($form->_values)) {
+          $campaignId = CRM_Utils_Array::value('campaign_id', $form->_params);
+          if (!array_key_exists('campaign_id', $form->_params)) {
+            $campaignId = CRM_Utils_Array::value('campaign_id', $form->_values);
+          }
+        }
+
+        list($membership, $renewalMode, $dates) = CRM_Member_BAO_Membership::renewMembership(
+          $contactID, $memType, $isTest,
+          date('YmdHis'), CRM_Utils_Array::value('cms_contactID', $membershipParams),
+          $customFieldsFormatted,
+          $numTerms, $membershipID, $pending,
+          $contributionRecurID, $membershipSource, $isPayLater, $campaignId
+        );
+        $form->set('renewal_mode', $renewalMode);
+        if (!empty($dates)) {
+          $form->assign('mem_start_date',
+            CRM_Utils_Date::customFormat($dates['start_date'], '%Y%m%d')
+          );
+          $form->assign('mem_end_date',
+            CRM_Utils_Date::customFormat($dates['end_date'], '%Y%m%d')
+          );
+        }
+
+        if (!empty($membershipContribution)) {
+          // update recurring id for membership record
+          CRM_Member_BAO_Membership::updateRecurMembership($membership, $membershipContribution);
+          CRM_Member_BAO_Membership::linkMembershipPayment($membership, $membershipContribution);
+        }
+      }
+      if ($form->_priceSetId && !empty($form->_useForMember) && !empty($form->_lineItem)) {
+        foreach ($form->_lineItem[$form->_priceSetId] as & $priceFieldOp) {
+          if (!empty($priceFieldOp['membership_type_id']) &&
+            isset($createdMemberships[$priceFieldOp['membership_type_id']])
+          ) {
+            $membershipOb = $createdMemberships[$priceFieldOp['membership_type_id']];
+            $priceFieldOp['start_date'] = $membershipOb->start_date ? CRM_Utils_Date::customFormat($membershipOb->start_date, '%B %E%f, %Y') : '-';
+            $priceFieldOp['end_date'] = $membershipOb->end_date ? CRM_Utils_Date::customFormat($membershipOb->end_date, '%B %E%f, %Y') : '-';
+          }
+          else {
+            $priceFieldOp['start_date'] = $priceFieldOp['end_date'] = 'N/A';
+          }
+        }
+        $form->_values['lineItem'] = $form->_lineItem;
+        $form->assign('lineItem', $form->_lineItem);
+      }
+    }
+
+    if (!empty($errors)) {
+      $message = $this->compileErrorMessage($errors);
+      throw new CRM_Core_Exception($message);
+    }
+    $form->_params['createdMembershipIDs'] = array();
+
+    // CRM-7851 - Moved after processing Payment Errors
+    //@todo - the reasoning for this being here seems a little outdated
+    foreach ($createdMemberships as $createdMembership) {
+      CRM_Core_BAO_CustomValueTable::postProcess(
+        $form->_params,
+        'civicrm_membership',
+        $createdMembership->id,
+        'Membership'
+      );
+      $form->_params['createdMembershipIDs'][] = $createdMembership->id;
+    }
+    if (count($createdMemberships) == 1) {
+      //presumably this is only relevant for exactly 1 membership
+      $form->_params['membershipID'] = $createdMembership->id;
+    }
+
+    //CRM-15232: Check if membership is created and on the basis of it use
+    //membership receipt template to send payment receipt
+    if (count($createdMemberships)) {
+      $form->_values['isMembership'] = TRUE;
+    }
+    if ($form->_contributeMode == 'notify') {
+      if ($form->_values['is_monetary'] && $form->_amount > 0.0 && !$form->_params['is_pay_later']) {
+        // call postProcess hook before leaving
+        $form->postProcessHook();
+        // this does not return
+        $payment = CRM_Core_Payment::singleton($form->_mode, $form->_paymentProcessor, $form);
+        $payment->doTransferCheckout($form->_params, 'contribute');
+      }
+    }
+
+    if (isset($membershipContributionID)) {
+      $form->_values['contribution_id'] = $membershipContributionID;
+    }
+
+    if ($form->_contributeMode == 'direct') {
+      if (CRM_Utils_Array::value('payment_status_id', $paymentResult) == 1) {
+        // Refer to CRM-16737. Payment processors 'should' return payment_status_id
+        // to denote the outcome of the transaction.
+        try {
+          civicrm_api3('contribution', 'completetransaction', array(
+            'id' => $paymentResult['contribution']->id,
+            'trxn_id' => $paymentResult['contribution']->trxn_id,
+            'is_transactional' => FALSE,
+          ));
+        }
+        catch (CiviCRM_API3_Exception $e) {
+          // if for any reason it is already completed this will fail - e.g extensions hacking around core not completing transactions prior to CRM-15296
+          // so let's be gentle here
+          CRM_Core_Error::debug_log_message('contribution ' . $membershipContribution->id . ' not completed with trxn_id ' . $membershipContribution->trxn_id . ' and message ' . $e->getMessage());
+        }
+      }
+      // Do not send an email if Recurring transaction is done via Direct Mode
+      // Email will we sent when the IPN is received.
+      return;
+    }
+
+    //finally send an email receipt
+    CRM_Contribute_BAO_ContributionPage::sendMail($contactID,
+      $form->_values,
+      $isTest, FALSE,
+      $includeFieldTypes
+    );
+  }
+
+  /**
+   * Turn array of errors into message string.
+   *
+   * @param array $errors
+   *
+   * @return string
+   */
+  protected function compileErrorMessage($errors) {
+    foreach ($errors as $error) {
+      if (is_string($error)) {
+        $message[] = $error;
+      }
+    }
+    return ts('Payment Processor Error message') . ': ' . implode('<br/>', $message);
+  }
+
+  /**
+   * Where a second separate financial transaction is supported we will process it here.
+   *
+   * @param int $contactID
+   * @param CRM_Contribute_Form_Contribution_Confirm $form
+   * @param array $tempParams
+   * @param bool $isTest
+   * @param array $lineItems
+   * @param $minimumFee
+   * @param int $financialTypeID
+   *
+   * @throws CRM_Core_Exception
+   * @throws Exception
+   * @return CRM_Contribute_BAO_Contribution
+   */
+  protected function processSecondaryFinancialTransaction($contactID, &$form, $tempParams, $isTest, $lineItems, $minimumFee,
+                                                   $financialTypeID) {
+    $financialType = new CRM_Financial_DAO_FinancialType();
+    $financialType->id = $financialTypeID;
+    $financialType->find(TRUE);
+    $tempParams['amount'] = $minimumFee;
+    $tempParams['invoiceID'] = md5(uniqid(rand(), TRUE));
+
+    $result = NULL;
+    if ($form->_values['is_monetary'] && !$form->_params['is_pay_later'] && $minimumFee > 0.0) {
+      $payment = CRM_Core_Payment::singleton($form->_mode, $form->_paymentProcessor, $form);
+
+      if ($form->_contributeMode == 'express') {
+        $result = $payment->doExpressCheckout($tempParams);
+        if (is_a($result, 'CRM_Core_Error')) {
+          throw new CRM_Core_Exception(CRM_Core_Error::getMessages($result));
+        }
+      }
+      else {
+        $result = $payment->doPayment($tempParams, 'contribute');
+      }
+    }
+
+    //assign receive date when separate membership payment
+    //and contribution amount not selected.
+    if ($form->_amount == 0) {
+      $now = date('YmdHis');
+      $form->_params['receive_date'] = $now;
+      $receiveDate = CRM_Utils_Date::mysqlToIso($now);
+      $form->set('params', $form->_params);
+      $form->assign('receive_date', $receiveDate);
+    }
+
+    $form->set('membership_trx_id', $result['trxn_id']);
+    $form->set('membership_amount', $minimumFee);
+
+    $form->assign('membership_trx_id', $result['trxn_id']);
+    $form->assign('membership_amount', $minimumFee);
+
+    // we don't need to create the user twice, so lets disable cms_create_account
+    // irrespective of the value, CRM-2888
+    $tempParams['cms_create_account'] = 0;
+
+    //CRM-16165, scenarios are
+    // 1) If contribution is_pay_later and if contribution amount is > 0.0 we set pending = TRUE, vice-versa FALSE
+    // 2) If not pay later but auto-renewal membership is chosen then pending = TRUE as it later triggers
+    //   pending recurring contribution, vice-versa FALSE
+    $pending = $form->_params['is_pay_later'] ? (($minimumFee > 0.0) ? TRUE : FALSE) : (!empty($form->_params['auto_renew']) ? TRUE : FALSE);
+
+    //set this variable as we are not creating pledge for
+    //separate membership payment contribution.
+    //so for differentiating membership contribution from
+    //main contribution.
+    $form->_params['separate_membership_payment'] = 1;
+    $membershipContribution = CRM_Contribute_Form_Contribution_Confirm::processFormContribution($form,
+      $tempParams,
+      $result,
+      $contactID,
+      $financialType,
+      $pending,
+      TRUE,
+      $isTest,
+      $lineItems,
+      $form->_bltID
+    );
+    return $membershipContribution;
+  }
+
   /**
    * Is the payment a pending payment.
    *
index bc4b216bdaee5d068c9ef4e720dc8bd454d37c88..7cec76f1cbf0946b7dde9da5f72c25c27b50dc8e 100644 (file)
@@ -1998,88 +1998,6 @@ INNER JOIN  civicrm_contact contact ON ( contact.id = membership.contact_id AND
     return (int) $memberCount;
   }
 
-  /**
-   * Where a second separate financial transaction is supported we will process it here.
-   *
-   * @param int $contactID
-   * @param CRM_Contribute_Form_Contribution_Confirm $form
-   * @param array $tempParams
-   * @param bool $isTest
-   * @param array $lineItems
-   * @param $minimumFee
-   * @param int $financialTypeID
-   *
-   * @throws CRM_Core_Exception
-   * @throws Exception
-   * @return CRM_Contribute_BAO_Contribution
-   */
-  public static function processSecondaryFinancialTransaction($contactID, &$form, $tempParams, $isTest, $lineItems, $minimumFee, $financialTypeID) {
-    $financialType = new CRM_Financial_DAO_FinancialType();
-    $financialType->id = $financialTypeID;
-    $financialType->find(TRUE);
-    $tempParams['amount'] = $minimumFee;
-    $tempParams['invoiceID'] = md5(uniqid(rand(), TRUE));
-
-    $result = NULL;
-    if ($form->_values['is_monetary'] && !$form->_params['is_pay_later'] && $minimumFee > 0.0) {
-      $payment = CRM_Core_Payment::singleton($form->_mode, $form->_paymentProcessor, $form);
-
-      if ($form->_contributeMode == 'express') {
-        $result = $payment->doExpressCheckout($tempParams);
-        if (is_a($result, 'CRM_Core_Error')) {
-          throw new CRM_Core_Exception(CRM_Core_Error::getMessages($result));
-        }
-      }
-      else {
-        $result = $payment->doPayment($tempParams, 'contribute');
-      }
-    }
-
-    //assign receive date when separate membership payment
-    //and contribution amount not selected.
-    if ($form->_amount == 0) {
-      $now = date('YmdHis');
-      $form->_params['receive_date'] = $now;
-      $receiveDate = CRM_Utils_Date::mysqlToIso($now);
-      $form->set('params', $form->_params);
-      $form->assign('receive_date', $receiveDate);
-    }
-
-    $form->set('membership_trx_id', $result['trxn_id']);
-    $form->set('membership_amount', $minimumFee);
-
-    $form->assign('membership_trx_id', $result['trxn_id']);
-    $form->assign('membership_amount', $minimumFee);
-
-    // we don't need to create the user twice, so lets disable cms_create_account
-    // irrespective of the value, CRM-2888
-    $tempParams['cms_create_account'] = 0;
-
-    //CRM-16165, scenarios are
-    // 1) If contribution is_pay_later and if contribution amount is > 0.0 we set pending = TRUE, vice-versa FALSE
-    // 2) If not pay later but auto-renewal membership is chosen then pending = TRUE as it later triggers
-    //   pending recurring contribution, vice-versa FALSE
-    $pending = $form->_params['is_pay_later'] ? (($minimumFee > 0.0) ? TRUE : FALSE) : (!empty($form->_params['auto_renew']) ? TRUE : FALSE);
-
-    //set this variable as we are not creating pledge for
-    //separate membership payment contribution.
-    //so for differentiating membership contribution from
-    //main contribution.
-    $form->_params['separate_membership_payment'] = 1;
-    $membershipContribution = CRM_Contribute_Form_Contribution_Confirm::processFormContribution($form,
-      $tempParams,
-      $result,
-      $contactID,
-      $financialType,
-      $pending,
-      TRUE,
-      $isTest,
-      $lineItems,
-      $form->_bltID
-    );
-    return $membershipContribution;
-  }
-
   /**
    * Create linkages between membership & contribution - note this is the wrong place for this code but this is a
    * refactoring step. This should be BAO functionality
@@ -2093,22 +2011,6 @@ INNER JOIN  civicrm_contact contact ON ( contact.id = membership.contact_id AND
     ));
   }
 
-  /**
-   * Turn array of errors into message string.
-   *
-   * @param array $errors
-   *
-   * @return string
-   */
-  public static function compileErrorMessage($errors) {
-    foreach ($errors as $error) {
-      if (is_string($error)) {
-        $message[] = $error;
-      }
-    }
-    return ts('Payment Processor Error message') . ': ' . implode('<br/>', $message);
-  }
-
   /**
    * @param int $contactID
    * @param int $membershipTypeID