[REF] Cleanup code to determine financial_type_id
[civicrm-core.git] / CRM / Member / Form / Membership.php
index 7be3212c33e191b29cb2be1cb6ff0818cb9463bc..8d094b27b88fbedc6e237b4bb440b3c84818348c 100644 (file)
@@ -479,18 +479,15 @@ DESC limit 1");
         }
       }
       $totalAmount = $values['minimum_fee'] ?? NULL;
-      //CRM-18827 - override the default value if total_amount is submitted
-      if (!empty($this->_submitValues['total_amount'])) {
-        $totalAmount = CRM_Utils_Rule::cleanMoney($this->_submitValues['total_amount']);
-      }
       // build membership info array, which is used when membership type is selected to:
       // - set the payment information block
       // - set the max related block
       $allMembershipInfo[$key] = [
         'financial_type_id' => $values['financial_type_id'] ?? NULL,
-        'total_amount' => CRM_Utils_Money::format($totalAmount, NULL, '%a'),
+        'total_amount' => CRM_Utils_Money::formatLocaleNumericRoundedForDefaultCurrency($totalAmount),
         'total_amount_numeric' => $totalAmount,
         'auto_renew' => $values['auto_renew'] ?? NULL,
+        'tax_rate' => $values['tax_rate'],
         'has_related' => isset($values['relationship_type_id']),
         'max_related' => $values['max_related'] ?? NULL,
       ];
@@ -920,19 +917,6 @@ DESC limit 1");
       $formValues['paidBy'] = $paymentInstrument[$formValues['payment_instrument_id']];
     }
 
-    if ($form->_mode) {
-      // @todo move this outside shared code as Batch entry just doesn't
-      $form->assign('address', CRM_Utils_Address::getFormattedBillingAddressFieldsFromParameters(
-        $form->_params,
-        $form->_bltID
-      ));
-
-      $valuesForForm = CRM_Contribute_Form_AbstractEditPayment::formatCreditCardDetails($form->_params);
-      $form->assignVariables($valuesForForm, ['credit_card_exp_date', 'credit_card_type', 'credit_card_number']);
-      $form->assign('is_pay_later', 0);
-      $form->assign('isPrimary', 1);
-    }
-
     $form->assign('module', 'Membership');
     $form->assign('contactID', $formValues['contact_id']);
 
@@ -986,7 +970,7 @@ DESC limit 1");
         'toName' => $form->_contributorDisplayName,
         'toEmail' => $form->_contributorEmail,
         'PDFFilename' => ts('receipt') . '.pdf',
-        'isEmailPdf' => Civi::settings()->get('invoicing') && Civi::settings()->get('is_email_pdf'),
+        'isEmailPdf' => Civi::settings()->get('invoicing') && Civi::settings()->get('invoice_is_email_pdf'),
         'contributionId' => $formValues['contribution_id'],
         'isTest' => (bool) ($form->_action & CRM_Core_Action::PREVIEW),
       ]
@@ -1030,10 +1014,7 @@ DESC limit 1");
       $this->_priceSet,
       $formValues
     );
-    if (empty($formValues['financial_type_id'])) {
-      $formValues['financial_type_id'] = $this->_priceSet['financial_type_id'];
-    }
-
+    $formValues['financial_type_id'] = $this->getFinancialTypeID();
     $membershipTypeValues = [];
     foreach ($this->_memTypeSelected as $memType) {
       $membershipTypeValues[$memType]['membership_type_id'] = $memType;
@@ -1071,20 +1052,10 @@ DESC limit 1");
 
     $termsByType = [];
 
-    $lineItem = [$this->_priceSetId => []];
-
-    // BEGIN Fix for dev/core/issues/860
-    // Prepare fee block and call buildAmount hook - based on CRM_Price_BAO_PriceSet::buildPriceSet().
-    CRM_Utils_Hook::buildAmount('membership', $this, $this->_priceSet['fields']);
-    // END Fix for dev/core/issues/860
+    $lineItem = [$this->order->getPriceSetID() => $this->order->getLineItems()];
 
-    CRM_Price_BAO_PriceSet::processAmount($this->_priceSet['fields'],
-      $formValues, $lineItem[$this->_priceSetId], $this->_priceSetId);
-
-    if (!empty($formValues['tax_amount'])) {
-      $params['tax_amount'] = $formValues['tax_amount'];
-    }
-    $params['total_amount'] = $formValues['amount'] ?? NULL;
+    $params['tax_amount'] = $this->order->getTotalTaxAmount();
+    $params['total_amount'] = $this->order->getTotalAmount();
     if (!empty($lineItem[$this->_priceSetId])) {
       foreach ($lineItem[$this->_priceSetId] as &$li) {
         if (!empty($li['membership_type_id'])) {
@@ -1180,7 +1151,6 @@ DESC limit 1");
     if (!empty($formValues['record_contribution'])) {
       $recordContribution = [
         'total_amount',
-        'financial_type_id',
         'payment_instrument_id',
         'trxn_id',
         'contribution_status_id',
@@ -1194,6 +1164,7 @@ DESC limit 1");
       foreach ($recordContribution as $f) {
         $params[$f] = $formValues[$f] ?? NULL;
       }
+      $params['financial_type_id'] = $this->getFinancialTypeID();
 
       if (empty($formValues['source'])) {
         $params['contribution_source'] = ts('%1 Membership: Offline signup (by %2)', [
@@ -1221,7 +1192,7 @@ DESC limit 1");
 
       //insert financial type name in receipt.
       $formValues['contributionType_name'] = CRM_Core_DAO::getFieldValue('CRM_Financial_DAO_FinancialType',
-        $formValues['financial_type_id']
+        $this->getFinancialTypeID()
       );
     }
 
@@ -1237,16 +1208,7 @@ DESC limit 1");
       //CRM-20264 : Store CC type and number (last 4 digit) during backoffice or online payment
       $params['card_type_id'] = $this->_params['card_type_id'] ?? NULL;
       $params['pan_truncation'] = $this->_params['pan_truncation'] ?? NULL;
-
-      if (!$isQuickConfig) {
-        $params['financial_type_id'] = CRM_Core_DAO::getFieldValue('CRM_Price_DAO_PriceSet',
-          $this->_priceSetId,
-          'financial_type_id'
-        );
-      }
-      else {
-        $params['financial_type_id'] = $formValues['financial_type_id'] ?? NULL;
-      }
+      $params['financial_type_id'] = $this->getFinancialTypeID();
 
       //get the payment processor id as per mode. Try removing in favour of beginPostProcess.
       $params['payment_processor_id'] = $formValues['payment_processor_id'] = $this->_paymentProcessor['id'];
@@ -1254,11 +1216,10 @@ DESC limit 1");
 
       // add all the additional payment params we need
       $formValues['amount'] = $params['total_amount'];
-      // @todo this is a candidate for beginPostProcessFunction.
-      $formValues['currencyID'] = CRM_Core_Config::singleton()->defaultCurrency;
+      $formValues['currencyID'] = $this->getCurrency();
       $formValues['description'] = ts("Contribution submitted by a staff person using member's credit card for signup");
-      $formValues['invoiceID'] = md5(uniqid(rand(), TRUE));
-      $formValues['financial_type_id'] = $params['financial_type_id'];
+      $formValues['invoiceID'] = $this->getInvoiceID();
+      $formValues['financial_type_id'] = $this->getFinancialTypeID();
 
       // at this point we've created a contact and stored its address etc
       // all the payment processors expect the name and address to be in the
@@ -1295,7 +1256,13 @@ DESC limit 1");
             'campaign_id' => $paymentParams['campaign_id'] ?? NULL,
             'source' => CRM_Utils_Array::value('source', $paymentParams, CRM_Utils_Array::value('description', $paymentParams)),
             'payment_instrument_id' => $paymentInstrumentID,
-            'financial_type_id' => $params['financial_type_id'],
+            'financial_type_id' => $this->getFinancialTypeID(),
+            'receive_date' => CRM_Utils_Time::date('YmdHis'),
+            'tax_amount' => $params['tax_amount'] ?? NULL,
+            'invoice_id' => $this->getInvoiceID(),
+            'currency' => $this->getCurrency(),
+            'is_pay_later' => $params['is_pay_later'] ?? 0,
+            'skipLineItem' => $params['skipLineItem'] ?? 0,
           ]
         );
 
@@ -1354,7 +1321,7 @@ DESC limit 1");
       }
       $now = CRM_Utils_Time::date('YmdHis');
       $params['receive_date'] = CRM_Utils_Time::date('Y-m-d H:i:s');
-      $params['invoice_id'] = $formValues['invoiceID'];
+      $params['invoice_id'] = $this->getInvoiceID();
       $params['contribution_source'] = ts('%1 Membership Signup: Credit card or direct debit (by %2)',
         [1 => $this->getSelectedMembershipLabels(), 2 => $userName]
       );
@@ -1763,6 +1730,18 @@ DESC limit 1");
     $customValues = $this->getCustomValuesForReceipt($formValues, $membership);
     $this->assign('customValues', $customValues);
 
+    if ($this->_mode) {
+      // @todo move this outside shared code as Batch entry just doesn't
+      $this->assign('address', CRM_Utils_Address::getFormattedBillingAddressFieldsFromParameters(
+        $this->_params,
+        $this->_bltID
+      ));
+
+      $valuesForForm = CRM_Contribute_Form_AbstractEditPayment::formatCreditCardDetails($this->_params);
+      $this->assignVariables($valuesForForm, ['credit_card_exp_date', 'credit_card_type', 'credit_card_number']);
+      $this->assign('is_pay_later', 0);
+      $this->assign('isPrimary', 1);
+    }
     return self::emailReceipt($this, $formValues, $membership);
   }
 
@@ -1850,56 +1829,30 @@ DESC limit 1");
     $contactID = $contributionParams['contact_id'];
 
     // add these values for the recurringContrib function ,CRM-10188
-    $params['financial_type_id'] = $contributionParams['financial_type_id'];
-
-    $params['is_email_receipt'] = (bool) $this->getSubmittedValue('send_receipt');
+    $params['financial_type_id'] = $this->getFinancialTypeID();
     $params['is_recur'] = TRUE;
     $params['payment_instrument_id'] = $contributionParams['payment_instrument_id'] ?? NULL;
     $recurringContributionID = $this->legacyProcessRecurringContribution($params, $contactID);
 
-    $now = CRM_Utils_Time::date('YmdHis');
-    $receiptDate = $params['receipt_date'] ?? NULL;
-    if ($params['is_email_receipt']) {
-      $receiptDate = $now;
+    if ($this->getSubmittedValue('send_receipt')) {
+      $contributionParams += [
+        'receipt_date' => CRM_Utils_Time::date('YmdHis'),
+      ];
     }
 
-    if (isset($params['amount'])) {
-      $contributionParams = array_merge([
-        'receive_date' => !empty($params['receive_date']) ? CRM_Utils_Date::processDate($params['receive_date']) : CRM_Utils_Time::date('YmdHis'),
-        'tax_amount' => $params['tax_amount'] ?? NULL,
-        'invoice_id' => $params['invoiceID'],
-        'currency' => $params['currencyID'],
-        'is_pay_later' => $params['is_pay_later'] ?? 0,
-        //setting to make available to hook - although seems wrong to set on form for BAO hook availability
-        'skipLineItem' => $params['skipLineItem'] ?? 0,
-      ], $contributionParams);
-
-      if ($this->getSubmittedValue('send_receipt')) {
-        $contributionParams += [
-          'receipt_date' => $receiptDate,
-        ];
-      }
-
-      if ($recurringContributionID) {
-        $contributionParams['contribution_recur_id'] = $recurringContributionID;
-      }
-
-      $contributionParams['contribution_status_id'] = CRM_Core_PseudoConstant::getKey('CRM_Contribute_BAO_Contribution', 'contribution_status_id', 'Pending');
-
-      // @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);
-
-      // lets store it in the form variable so postProcess hook can get to this and use it
-      $form->_contributionID = $contribution->id;
+    if ($recurringContributionID) {
+      $contributionParams['contribution_recur_id'] = $recurringContributionID;
     }
 
-    // process soft credit / pcp params first
-    CRM_Contribute_BAO_ContributionSoft::formatSoftCreditParams($params, $form);
+    $contributionParams['contribution_status_id'] = CRM_Core_PseudoConstant::getKey('CRM_Contribute_BAO_Contribution', 'contribution_status_id', 'Pending');
+
+    // @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);
 
-    //CRM-13981, processing honor contact into soft-credit contribution
-    CRM_Contribute_BAO_ContributionSoft::processSoftContribution($params, $contribution);
+    // lets store it in the form variable so postProcess hook can get to this and use it
+    $form->_contributionID = $contribution->id;
 
     $transaction->commit();
     return $contribution;
@@ -1923,7 +1876,7 @@ DESC limit 1");
     $recurParams['frequency_unit'] = $params['frequency_unit'] ?? NULL;
     $recurParams['frequency_interval'] = $params['frequency_interval'] ?? NULL;
     $recurParams['installments'] = $params['installments'] ?? NULL;
-    $recurParams['financial_type_id'] = $params['financial_type_id'];
+    $recurParams['financial_type_id'] = $this->getFinancialTypeID();
     $recurParams['currency'] = $params['currency'] ?? NULL;
     $recurParams['payment_instrument_id'] = $params['payment_instrument_id'];
 
@@ -1933,13 +1886,13 @@ DESC limit 1");
     if (!empty($params['receive_date'])) {
       $recurParams['start_date'] = date('YmdHis', CRM_Utils_Time::strtotime($params['receive_date']));
     }
-    $recurParams['invoice_id'] = $params['invoiceID'] ?? NULL;
+    $recurParams['invoice_id'] = $this->getInvoiceID();
     $recurParams['contribution_status_id'] = CRM_Core_PseudoConstant::getKey('CRM_Contribute_BAO_Contribution', 'contribution_status_id', 'Pending');
     $recurParams['payment_processor_id'] = $params['payment_processor_id'] ?? NULL;
     $recurParams['is_email_receipt'] = (bool) $this->getSubmittedValue('send_receipt');
     // we need to add a unique trxn_id to avoid a unique key error
     // in paypal IPN we reset this when paypal sends us the real trxn id, CRM-2991
-    $recurParams['trxn_id'] = $params['trxn_id'] ?? $params['invoiceID'];
+    $recurParams['trxn_id'] = $params['trxn_id'] ?? $this->getInvoiceID();
 
     $campaignId = $params['campaign_id'] ?? $this->_values['campaign_id'] ?? NULL;
     $recurParams['campaign_id'] = $campaignId;
@@ -1955,4 +1908,16 @@ DESC limit 1");
     return ($this->_mode === 'test') ? TRUE : FALSE;
   }
 
+  /**
+   * Get the financial type id relevant to the contribution.
+   *
+   * Financial type id is optional when price sets are in use.
+   * Otherwise they are required for the form to submit.
+   *
+   * @return int
+   */
+  protected function getFinancialTypeID(): int {
+    return (int) $this->getSubmittedValue('financial_type_id') ?: $this->order->getFinancialTypeID();
+  }
+
 }