CRM-17539 fix "C:/Program Files (x86)/Git/bin/sh.exe" receipts & more fixes on CRM...
[civicrm-core.git] / CRM / Contribute / Form / Contribution / Confirm.php
index 6e003253967756de1cbc1678b028c20c616ebddb..db1bf2686dbcefda88d8d07c406539ca97330c5c 100644 (file)
@@ -108,7 +108,7 @@ class CRM_Contribute_Form_Contribution_Confirm extends CRM_Contribute_Form_Contr
       $contributionParams['contribution_recur_id'] = $recurringContributionID;
     }
 
-    $contributionParams['contribution_status_id'] = ($pending && $contributionParams['total_amount'] != 0) ? 2 : 1;
+    $contributionParams['contribution_status_id'] = $pending ? 2 : 1;
     if (isset($contributionParams['invoice_id'])) {
       $contributionParams['id'] = CRM_Core_DAO::getFieldValue(
         'CRM_Contribute_DAO_Contribution',
@@ -405,7 +405,7 @@ class CRM_Contribute_Form_Contribution_Confirm extends CRM_Contribute_Form_Contr
     $amount_block_is_active = $this->get('amount_block_is_active');
     $this->assign('amount_block_is_active', $amount_block_is_active);
 
-    $invoiceSettings = CRM_Core_BAO_Setting::getItem(CRM_Core_BAO_Setting::CONTRIBUTE_PREFERENCES_NAME, 'contribution_invoice_settings');
+    $invoiceSettings = Civi::settings()->get('contribution_invoice_settings');
     $invoicing = CRM_Utils_Array::value('invoicing', $invoiceSettings);
     if ($invoicing) {
       $getTaxDetails = FALSE;
@@ -807,14 +807,15 @@ class CRM_Contribute_Form_Contribution_Confirm extends CRM_Contribute_Form_Contr
     $contributionParams,
     $financialType,
     $online,
-    $billingLocationID
+    $billingLocationID,
+    $isRecur
   ) {
     $transaction = new CRM_Core_Transaction();
     $contactID = $contributionParams['contact_id'];
 
     $isEmailReceipt = !empty($form->_values['is_email_receipt']);
     $isSeparateMembershipPayment = empty($params['separate_membership_payment']) ? FALSE : TRUE;
-    $pledgeID = empty($params['pledge_id']) ? NULL : $params['pledge_id'];
+    $pledgeID = !empty($params['pledge_id']) ? $params['pledge_id'] : CRM_Utils_Array::value('pledge_id', $form->_values);
     if (!$isSeparateMembershipPayment && !empty($form->_values['pledge_block_id']) &&
       (!empty($params['is_pledge']) || $pledgeID)) {
       $isPledge = TRUE;
@@ -837,7 +838,8 @@ class CRM_Contribute_Form_Contribution_Confirm extends CRM_Contribute_Form_Contr
     if (!isset($params['is_email_receipt']) && $isEmailReceipt) {
       $params['is_email_receipt'] = $isEmailReceipt;
     }
-    $recurringContributionID = self::processRecurringContribution($form, $params, $contactID, $financialType, $online);
+    $params['is_recur'] = $isRecur;
+    $recurringContributionID = self::processRecurringContribution($form, $params, $contactID, $financialType);
     $nonDeductibleAmount = self::getNonDeductibleAmount($params, $financialType, $online);
 
     $now = date('YmdHis');
@@ -854,7 +856,7 @@ class CRM_Contribute_Form_Contribution_Confirm extends CRM_Contribute_Form_Contr
       );
       $contribution = CRM_Contribute_BAO_Contribution::add($contributionParams);
 
-      $invoiceSettings = CRM_Core_BAO_Setting::getItem(CRM_Core_BAO_Setting::CONTRIBUTE_PREFERENCES_NAME, 'contribution_invoice_settings');
+      $invoiceSettings = Civi::settings()->get('contribution_invoice_settings');
       $invoicing = CRM_Utils_Array::value('invoicing', $invoiceSettings);
       if ($invoicing) {
         $dataArray = array();
@@ -896,6 +898,8 @@ class CRM_Contribute_Form_Contribution_Confirm extends CRM_Contribute_Form_Contr
       if ($pledgeID) {
         //when user doing pledge payments.
         //update the schedule when payment(s) are made
+        $amount = $params['amount'];
+        $pledgePaymentParams = array();
         foreach ($params['pledge_amount'] as $paymentId => $dontCare) {
           $scheduledAmount = CRM_Core_DAO::getFieldValue(
             'CRM_Pledge_DAO_PledgePayment',
@@ -904,14 +908,22 @@ class CRM_Contribute_Form_Contribution_Confirm extends CRM_Contribute_Form_Contr
             'id'
           );
 
-          $pledgePaymentParams = array(
-            'id' => $paymentId,
-            'contribution_id' => $contribution->id,
-            'status_id' => $contribution->contribution_status_id,
-            'actual_amount' => $scheduledAmount,
-          );
-
-          CRM_Pledge_BAO_PledgePayment::add($pledgePaymentParams);
+          $pledgePayment = ($amount >= $scheduledAmount) ? $scheduledAmount : $amount;
+          if ($pledgePayment > 0) {
+            $pledgePaymentParams[] = array(
+              'id' => $paymentId,
+              'contribution_id' => $contribution->id,
+              'status_id' => $contribution->contribution_status_id,
+              'actual_amount' => $pledgePayment,
+            );
+            $amount -= $pledgePayment;
+          }
+        }
+        if ($amount > 0 && count($pledgePaymentParams)) {
+          $pledgePaymentParams[count($pledgePaymentParams) - 1]['actual_amount'] += $amount;
+        }
+        foreach ($pledgePaymentParams as $p) {
+          CRM_Pledge_BAO_PledgePayment::add($p);
         }
 
         //update pledge status according to the new payment statuses
@@ -1035,16 +1047,12 @@ class CRM_Contribute_Form_Contribution_Confirm extends CRM_Contribute_Form_Contr
    * @param array $params
    * @param int $contactID
    * @param string $contributionType
-   * @param bool $online
    *
-   * @return mixed
+   * @return int|null
    */
-  public static function processRecurringContribution(&$form, &$params, $contactID, $contributionType, $online = TRUE) {
-    // return if this page is not set for recurring
-    // or the user has not chosen the recurring option
+  public static function processRecurringContribution(&$form, &$params, $contactID, $contributionType) {
 
-    //this is online case validation.
-    if ((empty($form->_values['is_recur']) && $online) || empty($params['is_recur'])) {
+    if (empty($params['is_recur'])) {
       return NULL;
     }
 
@@ -1090,16 +1098,11 @@ class CRM_Contribute_Form_Contribution_Confirm extends CRM_Contribute_Form_Contr
     $recurParams['trxn_id'] = CRM_Utils_Array::value('trxn_id', $params, $params['invoiceID']);
     $recurParams['financial_type_id'] = $contributionType->id;
 
-    if (!$online || $form->_values['is_monetary']) {
+    if ($form->_values['is_monetary']) {
       $recurParams['payment_instrument_id'] = 1;
     }
 
-    $campaignId = CRM_Utils_Array::value('campaign_id', $params);
-    if ($online) {
-      if (!array_key_exists('campaign_id', $params)) {
-        $campaignId = CRM_Utils_Array::value('campaign_id', $form->_values);
-      }
-    }
+    $campaignId = CRM_Utils_Array::value('campaign_id', $params, CRM_Utils_Array::value('campaign_id', $form->_values));
     $recurParams['campaign_id'] = $campaignId;
 
     $recurring = CRM_Contribute_BAO_ContributionRecur::add($recurParams);
@@ -1415,19 +1418,26 @@ class CRM_Contribute_Form_Contribution_Confirm extends CRM_Contribute_Form_Contr
     $isProcessSeparateMembershipTransaction, $financialTypeID, $membershipLineItems, $isPayLater, $isPending) {
     $membershipContribution = NULL;
     $isTest = CRM_Utils_Array::value('is_test', $membershipParams, FALSE);
-    $errors = $createdMemberships = $paymentResult = array();
+    $errors = $createdMemberships = $paymentResults = array();
+    $form->_values['isMembership'] = TRUE;
+    $isRecurForFirstTransaction = CRM_Utils_Array::value('is_recur', $form->_values, CRM_Utils_Array::value('is_recur', $membershipParams));
+    $totalAmount = $membershipParams['amount'];
 
     if ($isPaidMembership) {
       if ($isProcessSeparateMembershipTransaction) {
         // If we have 2 transactions only one can use the invoice id.
         $membershipParams['invoiceID'] .= '-2';
+        if (!empty($membershipParams['auto_renew'])) {
+          $isRecurForFirstTransaction = FALSE;
+        }
       }
 
       $paymentResult = CRM_Contribute_BAO_Contribution_Utils::processConfirm($form, $membershipParams,
         $contactID,
         $financialTypeID,
         'membership',
-        $isTest
+        $isTest,
+        $isRecurForFirstTransaction
       );
 
       if (!empty($paymentResult['contribution'])) {
@@ -1446,8 +1456,9 @@ class CRM_Contribute_Form_Contribution_Confirm extends CRM_Contribute_Form_Contr
         if (empty($form->_params['auto_renew']) && !empty($membershipParams['is_recur'])) {
           unset($membershipParams['is_recur']);
         }
-        $membershipContribution = $this->processSecondaryFinancialTransaction($contactID, $form, $membershipParams,
+        list($membershipContribution, $secondPaymentResult) = $this->processSecondaryFinancialTransaction($contactID, $form, $membershipParams,
           $isTest, $membershipLineItems, CRM_Utils_Array::value('minimum_fee', $membershipDetails, 0), CRM_Utils_Array::value('financial_type_id', $membershipDetails));
+        $paymentResults[] = array('contribution_id' => $membershipContribution->id, 'result' => $secondPaymentResult);
       }
       catch (CRM_Core_Exception $e) {
         $errors[2] = $e->getMessage();
@@ -1578,16 +1589,30 @@ class CRM_Contribute_Form_Contribution_Confirm extends CRM_Contribute_Form_Contr
       }
 
       $payment = Civi\Payment\System::singleton()->getByProcessor($form->_paymentProcessor);
-      $paymentActionResult = $payment->doPayment($form->_params, 'contribute');
-      $this->completeTransaction($paymentActionResult, $paymentResult['contribution']->id);
+      // The contribution_other_id is effectively the ID for the only contribution or the non-membership contribution.
+      // Since we have called the membership contribution (in a 2 contribution scenario) this is out
+      // primary-contribution compared to that - but let's face it - it's all just too hard & confusing at the moment!
+      $paymentParams = array_merge($form->_params, array('contributionID' => $form->_values['contribution_other_id']));
+      $paymentActionResult = $payment->doPayment($paymentParams, 'contribute');
+      $paymentResults[] = array('contribution_id' => $paymentResult['contribution']->id, 'result' => $paymentActionResult);
       // Do not send an email if Recurring transaction is done via Direct Mode
       // Email will we sent when the IPN is received.
+      foreach ($paymentResults as $result) {
+        $this->completeTransaction($result['result'], $result['contribution_id']);
+      }
       return;
     }
 
-    //finally send an email receipt
+    $emailValues = $form->_values;
+    // Finally send an email receipt for pay-later scenario (although it might sometimes be caught above!)
+    if ($totalAmount == 0) {
+      // This feels like a bizarre hack as the variable name doesn't seem to be directly connected to it's use in the template.
+      $emailValues['useForMember'] = 0;
+      $emailValues['membership_assign'] = 1;
+      $emailValues['amount'] = 0;
+    }
     CRM_Contribute_BAO_ContributionPage::sendMail($contactID,
-      $form->_values,
+      $emailValues,
       $isTest, FALSE,
       $includeFieldTypes
     );
@@ -1631,6 +1656,7 @@ class CRM_Contribute_Form_Contribution_Confirm extends CRM_Contribute_Form_Contr
     $financialType->find(TRUE);
     $tempParams['amount'] = $minimumFee;
     $tempParams['invoiceID'] = md5(uniqid(rand(), TRUE));
+    $isRecur = CRM_Utils_Array::value('is_recur', $tempParams);
 
     //assign receive date when separate membership payment
     //and contribution amount not selected.
@@ -1675,9 +1701,11 @@ class CRM_Contribute_Form_Contribution_Confirm extends CRM_Contribute_Form_Contr
       $contributionParams,
       $financialType,
       TRUE,
-      $form->_bltID
+      $form->_bltID,
+      $isRecur
     );
 
+    $result = array();
     if ($form->_values['is_monetary'] && !$form->_params['is_pay_later'] && $minimumFee > 0.0) {
       // At the moment our tests are calling this form in a way that leaves 'object' empty. For
       // now we compensate here.
@@ -1690,10 +1718,9 @@ class CRM_Contribute_Form_Contribution_Confirm extends CRM_Contribute_Form_Contr
       $result = $payment->doPayment($tempParams, 'contribute');
       $form->set('membership_trx_id', $result['trxn_id']);
       $form->assign('membership_trx_id', $result['trxn_id']);
-      $this->completeTransaction($result, $membershipContribution->id);
     }
 
-    return $membershipContribution;
+    return array($membershipContribution, $result);
   }
 
   /**
@@ -1895,6 +1922,11 @@ class CRM_Contribute_Form_Contribution_Confirm extends CRM_Contribute_Form_Contr
    */
   protected function processFormSubmission($contactID) {
     $isPayLater = $this->_params['is_pay_later'];
+    if (!isset($this->_params['payment_processor_id'])) {
+      // If there is no processor we are using the pay-later manual pseudo-processor.
+      // (note it might make sense to make this a row in the processor table in the db).
+      $this->_params['payment_processor_id'] = 0;
+    }
     if (isset($this->_params['payment_processor_id']) && $this->_params['payment_processor_id'] == 0) {
       $this->_params['is_pay_later'] = $isPayLater = TRUE;
     }
@@ -2139,12 +2171,13 @@ class CRM_Contribute_Form_Contribution_Confirm extends CRM_Contribute_Form_Contr
           }
         }
       }
-
+      $isRecur = CRM_Utils_Array::value('is_recur', $this->_values, CRM_Utils_Array::value('is_recur', $paymentParams));
       $result = CRM_Contribute_BAO_Contribution_Utils::processConfirm($this, $paymentParams,
         $contactID,
         $this->wrangleFinancialTypeID($this->_values['financial_type_id']),
         'contribution',
-        ($this->_mode == 'test') ? 1 : 0
+        ($this->_mode == 'test') ? 1 : 0,
+        $isRecur
       );
 
       if (empty($result['is_payment_failure'])) {