Remove legacy tpl assigns
[civicrm-core.git] / CRM / Member / Form / Membership.php
index 0086b47d7ef09688188f63149a376d90dccb3be0..5840a4c37a1db6587a6993c2ff81e481bc81ee90 100644 (file)
@@ -22,8 +22,6 @@ class CRM_Member_Form_Membership extends CRM_Member_Form {
 
   protected $_memType = NULL;
 
-  protected $_onlinePendingContributionId;
-
   public $_mode;
 
   public $_contributeMode = 'direct';
@@ -276,16 +274,6 @@ class CRM_Member_Form_Membership extends CRM_Member_Form {
 
     // Add custom data to form
     CRM_Custom_Form_CustomData::addToForm($this, $this->_memType);
-
-    // CRM-4395, get the online pending contribution id.
-    $this->_onlinePendingContributionId = NULL;
-    if (!$this->_mode && $this->_id && ($this->_action & CRM_Core_Action::UPDATE)) {
-      $this->_onlinePendingContributionId = CRM_Contribute_BAO_Contribution::checkOnlinePendingContribution($this->_id,
-        'Membership'
-      );
-    }
-    $this->assign('onlinePendingContributionId', $this->_onlinePendingContributionId);
-
     $this->setPageTitle(ts('Membership'));
   }
 
@@ -308,20 +296,15 @@ class CRM_Member_Form_Membership extends CRM_Member_Form {
     $defaults['num_terms'] = 1;
 
     if (!empty($defaults['id'])) {
-      if ($this->_onlinePendingContributionId) {
-        $defaults['record_contribution'] = $this->_onlinePendingContributionId;
-      }
-      else {
-        $contributionId = CRM_Core_DAO::singleValueQuery("
-  SELECT contribution_id
-  FROM civicrm_membership_payment
-  WHERE membership_id = $this->_id
-  ORDER BY contribution_id
-  DESC limit 1");
-
-        if ($contributionId) {
-          $defaults['record_contribution'] = $contributionId;
-        }
+      $contributionId = CRM_Core_DAO::singleValueQuery("
+SELECT contribution_id
+FROM civicrm_membership_payment
+WHERE membership_id = $this->_id
+ORDER BY contribution_id
+DESC limit 1");
+
+      if ($contributionId) {
+        $defaults['record_contribution'] = $contributionId;
       }
     }
     else {
@@ -627,9 +610,7 @@ class CRM_Member_Form_Membership extends CRM_Member_Form {
 
     // Retrieve the name and email of the contact - this will be the TO for receipt email
     if ($this->_contactID) {
-      list($this->_memberDisplayName,
-        $this->_memberEmail
-        ) = CRM_Contact_BAO_Contact_Location::getEmailDetails($this->_contactID);
+      [$this->_memberDisplayName, $this->_memberEmail] = CRM_Contact_BAO_Contact_Location::getEmailDetails($this->_contactID);
 
       $this->assign('emailExists', $this->_memberEmail);
       $this->assign('displayName', $this->_memberDisplayName);
@@ -668,8 +649,8 @@ class CRM_Member_Form_Membership extends CRM_Member_Form {
   public static function formRule($params, $files, $self) {
     $errors = [];
 
-    $priceSetId = self::getPriceSetID($params);
-    $priceSetDetails = self::getPriceSetDetails($params);
+    $priceSetId = $self->getPriceSetID($params);
+    $priceSetDetails = $self->getPriceSetDetails($params);
 
     $selectedMemberships = self::getSelectedMemberships($priceSetDetails[$priceSetId], $params);
 
@@ -861,15 +842,6 @@ class CRM_Member_Form_Membership extends CRM_Member_Form {
       }
     }
 
-    // validate contribution status for 'Failed'.
-    if ($self->_onlinePendingContributionId && !empty($params['record_contribution']) &&
-      (CRM_Utils_Array::value('contribution_status_id', $params) ==
-        array_search('Failed', CRM_Contribute_PseudoConstant::contributionStatus(NULL, 'name'))
-      )
-    ) {
-      $errors['contribution_status_id'] = ts('Please select a valid payment status before updating.');
-    }
-
     return empty($errors) ? TRUE : $errors;
   }
 
@@ -960,9 +932,6 @@ class CRM_Member_Form_Membership extends CRM_Member_Form {
 
       $valuesForForm = CRM_Contribute_Form_AbstractEditPayment::formatCreditCardDetails($form->_params);
       $form->assignVariables($valuesForForm, ['credit_card_exp_date', 'credit_card_type', 'credit_card_number']);
-
-      $form->assign('contributeMode', 'direct');
-      $form->assign('isAmountzero', 0);
       $form->assign('is_pay_later', 0);
       $form->assign('isPrimary', 1);
     }
@@ -975,9 +944,6 @@ class CRM_Member_Form_Membership extends CRM_Member_Form {
     if (!empty($formValues['contribution_id'])) {
       $form->assign('contributionID', $formValues['contribution_id']);
     }
-    elseif (isset($form->_onlinePendingContributionId)) {
-      $form->assign('contributionID', $form->_onlinePendingContributionId);
-    }
 
     if (!empty($formValues['contribution_status_id'])) {
       $form->assign('contributionStatusID', $formValues['contribution_status_id']);
@@ -1059,8 +1025,8 @@ class CRM_Member_Form_Membership extends CRM_Member_Form {
     $this->storeContactFields($this->_params);
     $this->beginPostProcess();
     $endDate = NULL;
-    $membershipTypes = $membership = $calcDate = [];
-    $membershipType = NULL;
+    $membership = $calcDate = [];
+
     $paymentInstrumentID = $this->_paymentProcessor['object']->getPaymentInstrumentID();
     $params = $softParams = $ids = [];
 
@@ -1213,13 +1179,8 @@ class CRM_Member_Form_Membership extends CRM_Member_Form {
         $this->_id,
         'Membership'
       );
-      $membershipTypes[$memType] = CRM_Core_DAO::getFieldValue('CRM_Member_DAO_MembershipType',
-        $memType
-      );
     }
 
-    $membershipType = implode(', ', $membershipTypes);
-
     // Retrieve the name and email of the current user - this will be the FROM for the receipt email
     list($userName) = CRM_Contact_BAO_Contact_Location::getEmailDetails(CRM_Core_Session::getLoggedInContactID());
 
@@ -1252,16 +1213,14 @@ class CRM_Member_Form_Membership extends CRM_Member_Form {
         $params[$f] = $formValues[$f] ?? NULL;
       }
 
-      if (!$this->_onlinePendingContributionId) {
-        if (empty($formValues['source'])) {
-          $params['contribution_source'] = ts('%1 Membership: Offline signup (by %2)', [
-            1 => $membershipType,
-            2 => $userName,
-          ]);
-        }
-        else {
-          $params['contribution_source'] = $formValues['source'];
-        }
+      if (empty($formValues['source'])) {
+        $params['contribution_source'] = ts('%1 Membership: Offline signup (by %2)', [
+          1 => $this->getSelectedMembershipLabels(),
+          2 => $userName,
+        ]);
+      }
+      else {
+        $params['contribution_source'] = $formValues['source'];
       }
 
       $completedContributionStatusId = CRM_Core_PseudoConstant::getKey('CRM_Contribute_BAO_Contribution', 'contribution_status_id', 'Completed');
@@ -1348,7 +1307,7 @@ class CRM_Member_Form_Membership extends CRM_Member_Form {
         $financialType->find(TRUE);
         $this->_params = $formValues;
 
-        $contribution = CRM_Contribute_Form_Contribution_Confirm::processFormContribution($this,
+        $contribution = self::processFormContribution($this,
           $paymentParams,
           NULL,
           [
@@ -1417,23 +1376,18 @@ class CRM_Member_Form_Membership extends CRM_Member_Form {
         // unset send-receipt option, since receipt will be sent when ipn is received.
         unset($formValues['send_receipt'], $formValues['send_receipt']);
         //as membership is pending set dates to null.
-        $memberDates = [
-          'join_date' => 'joinDate',
-          'start_date' => 'startDate',
-          'end_date' => 'endDate',
-        ];
-        foreach ($memberDates as $dv) {
-          $$dv = NULL;
-          foreach ($this->_memTypeSelected as $memType) {
-            $membershipTypeValues[$memType][$dv] = NULL;
-          }
+        foreach ($this->_memTypeSelected as $memType) {
+          $membershipTypeValues[$memType]['joinDate'] = NULL;
+          $membershipTypeValues[$memType]['startDate'] = NULL;
+          $membershipTypeValues[$memType]['endDate'] = NULL;
         }
+        $endDate = $startDate = NULL;
       }
       $now = date('YmdHis');
       $params['receive_date'] = date('Y-m-d H:i:s');
       $params['invoice_id'] = $formValues['invoiceID'];
       $params['contribution_source'] = ts('%1 Membership Signup: Credit card or direct debit (by %2)',
-        [1 => $membershipType, 2 => $userName]
+        [1 => $this->getSelectedMembershipLabels(), 2 => $userName]
       );
       $params['source'] = $formValues['source'] ?: $params['contribution_source'];
       $params['trxn_id'] = $result['trxn_id'] ?? NULL;
@@ -1496,94 +1450,34 @@ class CRM_Member_Form_Membership extends CRM_Member_Form {
     }
     else {
       $params['action'] = $this->_action;
-      if ($this->_onlinePendingContributionId && !empty($formValues['record_contribution'])) {
-
-        // update membership as well as contribution object, CRM-4395
-        $params['contribution_id'] = $this->_onlinePendingContributionId;
-        $params['componentId'] = $params['id'];
-        $params['componentName'] = 'contribute';
-        // Only available statuses are Pending and completed so cancel or failed is not possible here.
-        $result = CRM_Contribute_BAO_Contribution::transitionComponents($params, TRUE);
-        if (!empty($result) && !empty($params['contribution_id'])) {
-          $lineItem = [];
-          $lineItems = CRM_Price_BAO_LineItem::getLineItemsByContributionID($params['contribution_id']);
-          $itemId = key($lineItems);
-          $priceSetId = CRM_Core_DAO::getFieldValue('CRM_Price_DAO_PriceField', $lineItems[$itemId]['price_field_id'], 'price_set_id');
-
-          $lineItems[$itemId]['unit_price'] = $params['total_amount'];
-          $lineItems[$itemId]['line_total'] = $params['total_amount'];
-          $lineItems[$itemId]['id'] = $itemId;
-          $lineItem[$priceSetId] = $lineItems;
-          $contributionBAO = new CRM_Contribute_BAO_Contribution();
-          $contributionBAO->id = $params['contribution_id'];
-          $contributionBAO->contact_id = $params['contact_id'];
-          $contributionBAO->find();
-          CRM_Price_BAO_LineItem::processPriceSet($params['contribution_id'], $lineItem, $contributionBAO, 'civicrm_membership');
-
-          //create new soft-credit record, CRM-13981
-          if ($softParams) {
-            $softParams['contribution_id'] = $params['contribution_id'];
-            while ($contributionBAO->fetch()) {
-              $softParams['currency'] = $contributionBAO->currency;
-              $softParams['amount'] = $contributionBAO->total_amount;
-            }
-            CRM_Contribute_BAO_ContributionSoft::add($softParams);
-          }
+      foreach ($lineItem[$this->_priceSetId] as $id => $lineItemValues) {
+        if (empty($lineItemValues['membership_type_id'])) {
+          continue;
         }
 
-        //carry updated membership object.
-        $membership = new CRM_Member_DAO_Membership();
-        $membership->id = $this->_id;
-        $membership->find(TRUE);
-
-        $cancelled = TRUE;
-        if ($membership->end_date) {
-          //display end date w/ status message.
-          $endDate = $membership->end_date;
-
-          if (!in_array($membership->status_id, [
-            // CRM-15475
-            array_search('Cancelled', CRM_Member_PseudoConstant::membershipStatus(NULL, " name = 'Cancelled' ", 'name', FALSE, TRUE)),
-            array_search('Expired', CRM_Member_PseudoConstant::membershipStatus()),
-          ])
-          ) {
-            $cancelled = FALSE;
-          }
+        // @todo figure out why recieve_date isn't being set right here.
+        if (empty($params['receive_date'])) {
+          $params['receive_date'] = date('Y-m-d H:i:s');
         }
-        // suppress form values in template.
-        $this->assign('cancelled', $cancelled);
-
-        $createdMemberships[] = $membership;
-      }
-      else {
-        $count = 0;
-        foreach ($this->_memTypeSelected as $memType) {
-          if ($count && !empty($formValues['record_contribution']) &&
-            ($relateContribution = CRM_Member_BAO_Membership::getMembershipContributionId($membership->id))
-          ) {
-            $membershipTypeValues[$memType]['relate_contribution_id'] = $relateContribution;
-          }
-
-          // @todo figure out why recieve_date isn't being set right here.
-          if (empty($params['receive_date'])) {
-            $params['receive_date'] = date('Y-m-d H:i:s');
-          }
-          $membershipParams = array_merge($params, $membershipTypeValues[$memType]);
+        $membershipParams = array_merge($params, $membershipTypeValues[$lineItemValues['membership_type_id']]);
 
-          if (!empty($softParams)) {
-            $membershipParams['soft_credit'] = $softParams;
-          }
-          // @todo stop passing $ids (membership and userId only are set above)
-          $membership = CRM_Member_BAO_Membership::create($membershipParams, $ids);
-          $params['contribution'] = $membershipParams['contribution'] ?? NULL;
-          unset($params['lineItems']);
-          // skip line item creation for next interation since line item(s) are already created.
-          $params['skipLineItem'] = TRUE;
-
-          $this->_membershipIDs[] = $membership->id;
-          $createdMemberships[$memType] = $membership;
-          $count++;
+        if (!empty($softParams)) {
+          $membershipParams['soft_credit'] = $softParams;
         }
+        unset($membershipParams['contribution_status_id']);
+        $membershipParams['skipLineItem'] = TRUE;
+        unset($membershipParams['lineItems']);
+        // @todo stop passing $ids (membership and userId only are set above)
+        $membership = CRM_Member_BAO_Membership::create($membershipParams, $ids);
+        $lineItem[$this->_priceSetId][$id]['entity_id'] = $membership->id;
+        $lineItem[$this->_priceSetId][$id]['entity_table'] = 'civicrm_membership';
+
+        $this->_membershipIDs[] = $membership->id;
+        $createdMemberships[$membership->membership_type_id] = $membership;
+      }
+      $params['lineItems'] = $lineItem;
+      if (!empty($formValues['record_contribution'])) {
+        CRM_Member_BAO_Membership::recordMembershipContribution($params);
       }
     }
     $isRecur = $params['is_recur'] ?? NULL;
@@ -1935,4 +1829,218 @@ class CRM_Member_Form_Membership extends CRM_Member_Form {
     return $customValues;
   }
 
+  /**
+   * Get the selected memberships as a string of labels.
+   *
+   * @return string
+   */
+  protected function getSelectedMembershipLabels(): string {
+    $return = [];
+    foreach ($this->_memTypeSelected as $membershipTypeID) {
+      $return[] = $this->allMembershipTypeDetails[$membershipTypeID]['name'];
+    }
+    return implode(', ', $return);
+  }
+
+  /**
+   * Legacy contribution processing function.
+   *
+   * This is copied from a shared function in order to clean it up. Most of the
+   * stuff in it, maybe all except the ContributionRecur create is
+   * not applicable to this form & can be removed in follow up cleanup.
+   *
+   * It's like the contribution create being done here is actively bad and
+   * being fixed later.
+   *
+   * @param CRM_Core_Form $form
+   * @param array $params
+   * @param array $result
+   * @param array $contributionParams
+   *   Parameters to be passed to contribution create action.
+   *   This differs from params in that we are currently adding params to it and 1) ensuring they are being
+   *   passed consistently & 2) documenting them here.
+   *   - contact_id
+   *   - line_item
+   *   - is_test
+   *   - campaign_id
+   *   - contribution_page_id
+   *   - source
+   *   - payment_type_id
+   *   - thankyou_date (not all forms will set this)
+   *
+   * @param CRM_Financial_DAO_FinancialType $financialType
+   * @param bool $online
+   *   Is the form a front end form? If so set a bunch of unpredictable things that should be passed in from the form.
+   *
+   * @param int $billingLocationID
+   *   ID of billing location type.
+   * @param bool $isRecur
+   *   Is this recurring?
+   *
+   * @return \CRM_Contribute_DAO_Contribution
+   *
+   * @throws \CRM_Core_Exception
+   * @throws \CiviCRM_API3_Exception
+   */
+  public static function processFormContribution(
+    &$form,
+    $params,
+    $result,
+    $contributionParams,
+    $financialType,
+    $online,
+    $billingLocationID,
+    $isRecur
+  ) {
+    $transaction = new CRM_Core_Transaction();
+    $contactID = $contributionParams['contact_id'];
+
+    $isEmailReceipt = !empty($form->_values['is_email_receipt']);
+    $isSeparateMembershipPayment = !empty($params['separate_membership_payment']);
+    $pledgeID = !empty($params['pledge_id']) ? $params['pledge_id'] : $form->_values['pledge_id'] ?? NULL;
+    if (!$isSeparateMembershipPayment && !empty($form->_values['pledge_block_id']) &&
+      (!empty($params['is_pledge']) || $pledgeID)) {
+      $isPledge = TRUE;
+    }
+    else {
+      $isPledge = FALSE;
+    }
+
+    // add these values for the recurringContrib function ,CRM-10188
+    $params['financial_type_id'] = $financialType->id;
+
+    $contributionParams['address_id'] = CRM_Contribute_BAO_Contribution::createAddress($params, $billingLocationID);
+
+    //@todo - this is being set from the form to resolve CRM-10188 - an
+    // eNotice caused by it not being set @ the front end
+    // however, we then get it being over-written with null for backend contributions
+    // a better fix would be to set the values in the respective forms rather than require
+    // a function being shared by two forms to deal with their respective values
+    // moving it to the BAO & not taking the $form as a param would make sense here.
+    if (!isset($params['is_email_receipt']) && $isEmailReceipt) {
+      $params['is_email_receipt'] = $isEmailReceipt;
+    }
+    $params['is_recur'] = $isRecur;
+    $params['payment_instrument_id'] = $contributionParams['payment_instrument_id'] ?? NULL;
+    $recurringContributionID = CRM_Contribute_Form_Contribution_Confirm::processRecurringContribution($form, $params, $contactID, $financialType);
+
+    $now = date('YmdHis');
+    $receiptDate = $params['receipt_date'] ?? NULL;
+    if ($isEmailReceipt) {
+      $receiptDate = $now;
+    }
+
+    if (isset($params['amount'])) {
+      $contributionParams = array_merge(CRM_Contribute_Form_Contribution_Confirm::getContributionParams(
+        $params, $financialType->id,
+        $result, $receiptDate,
+        $recurringContributionID), $contributionParams
+      );
+      $contributionParams['non_deductible_amount'] = CRM_Contribute_Form_Contribution_Confirm::getNonDeductibleAmount($params, $financialType, $online, $form);
+      $contributionParams['skipCleanMoney'] = TRUE;
+      // @todo this is the wrong place for this - it should be done as close to form submission
+      // as possible
+      $contributionParams['total_amount'] = $params['amount'];
+
+      $contribution = CRM_Contribute_BAO_Contribution::add($contributionParams);
+
+      $invoiceSettings = Civi::settings()->get('contribution_invoice_settings');
+      $invoicing = $invoiceSettings['invoicing'] ?? NULL;
+      if ($invoicing) {
+        $dataArray = [];
+        // @todo - interrogate the line items passed in on the params array.
+        // No reason to assume line items will be set on the form.
+        foreach ($form->_lineItem as $lineItemKey => $lineItemValue) {
+          foreach ($lineItemValue as $key => $value) {
+            if (isset($value['tax_amount']) && isset($value['tax_rate'])) {
+              if (isset($dataArray[$value['tax_rate']])) {
+                $dataArray[$value['tax_rate']] = $dataArray[$value['tax_rate']] + $value['tax_amount'];
+              }
+              else {
+                $dataArray[$value['tax_rate']] = $value['tax_amount'];
+              }
+            }
+          }
+        }
+        $smarty = CRM_Core_Smarty::singleton();
+        $smarty->assign('dataArray', $dataArray);
+        $smarty->assign('totalTaxAmount', $params['tax_amount'] ?? NULL);
+      }
+
+      // lets store it in the form variable so postProcess hook can get to this and use it
+      $form->_contributionID = $contribution->id;
+    }
+
+    // process soft credit / pcp params first
+    CRM_Contribute_BAO_ContributionSoft::formatSoftCreditParams($params, $form);
+
+    //CRM-13981, processing honor contact into soft-credit contribution
+    CRM_Contribute_BAO_ContributionSoft::processSoftContribution($params, $contribution);
+
+    if ($isPledge) {
+      $form = CRM_Contribute_Form_Contribution_Confirm::handlePledge($form, $params, $contributionParams, $pledgeID, $contribution, $isEmailReceipt);
+    }
+
+    if ($online && $contribution) {
+      CRM_Core_BAO_CustomValueTable::postProcess($params,
+        'civicrm_contribution',
+        $contribution->id,
+        'Contribution'
+      );
+    }
+    elseif ($contribution) {
+      //handle custom data.
+      $params['contribution_id'] = $contribution->id;
+      if (!empty($params['custom']) &&
+        is_array($params['custom'])
+      ) {
+        CRM_Core_BAO_CustomValueTable::store($params['custom'], 'civicrm_contribution', $contribution->id);
+      }
+    }
+    // Save note
+    if ($contribution && !empty($params['contribution_note'])) {
+      $noteParams = [
+        'entity_table' => 'civicrm_contribution',
+        'note' => $params['contribution_note'],
+        'entity_id' => $contribution->id,
+        'contact_id' => $contribution->contact_id,
+      ];
+
+      CRM_Core_BAO_Note::add($noteParams, []);
+    }
+
+    if (isset($params['related_contact'])) {
+      $contactID = $params['related_contact'];
+    }
+    elseif (isset($params['cms_contactID'])) {
+      $contactID = $params['cms_contactID'];
+    }
+
+    //create contribution activity w/ individual and target
+    //activity w/ organisation contact id when onbelf, CRM-4027
+    $actParams = [];
+    $targetContactID = NULL;
+    if (!empty($params['onbehalf_contact_id'])) {
+      $actParams = [
+        'source_contact_id' => $params['onbehalf_contact_id'],
+        'on_behalf' => TRUE,
+      ];
+      $targetContactID = $contribution->contact_id;
+    }
+
+    // create an activity record
+    if ($contribution) {
+      CRM_Activity_BAO_Activity::addActivity($contribution, 'Contribution', $targetContactID, $actParams);
+    }
+
+    $transaction->commit();
+    // CRM-13074 - create the CMSUser after the transaction is completed as it
+    // is not appropriate to delete a valid contribution if a user create problem occurs
+    CRM_Contribute_BAO_Contribution_Utils::createCMSUser($params,
+      $contactID,
+      'email-' . $billingLocationID
+    );
+    return $contribution;
+  }
+
 }