CRM-16996 instead of requiring a financial_type_id when a priceset is selected use...
[civicrm-core.git] / CRM / Member / Form / Membership.php
index 4eacaa0b770f3dde8c5a68ae7934b248d5e89aa4..80ed553a0f326de29d2e86e7a0604623d6ab6ff8 100644 (file)
@@ -114,15 +114,15 @@ class CRM_Member_Form_Membership extends CRM_Member_Form {
   /**
    * Get selected membership type from the form values.
    *
-   * @param int $priceSetID
+   * @param array $priceSet
    * @param array $params
    *
    * @return array
    */
-  public static function getSelectedMemberships($priceSetID, $params) {
+  public static function getSelectedMemberships($priceSet, $params) {
     $memTypeSelected = array();
-    $priceFieldIDS = self::getPriceFieldIDs($params);
-    if ($priceSetID && is_array($priceFieldIDS)) {
+    $priceFieldIDS = self::getPriceFieldIDs($params, $priceSet);
+    if (!empty($priceSet) && is_array($priceFieldIDS)) {
       foreach ($priceFieldIDS as $priceFieldId) {
         if ($id = CRM_Core_DAO::getFieldValue('CRM_Price_DAO_PriceFieldValue', $priceFieldId, 'membership_type_id')) {
           $memTypeSelected[$id] = $id;
@@ -139,28 +139,26 @@ class CRM_Member_Form_Membership extends CRM_Member_Form {
    * Extract price set fields and values from $params.
    *
    * @param array $params
+   * @param array $priceSet
    *
    * @return array
    */
-  public static function getPriceFieldIDs($params) {
-    $priceFieldIDS = $priceSet = $fieldIds = array();
-    if (isset(self::$priceSet) && is_array(self::$priceSet)) {
-      $priceSet = self::$_priceSet;
-      if (isset($priceSet['fields']) && is_array($priceSet['fields'])) {
-        $fieldIds = array_keys($priceSet['fields']);
-      }
-    }
-    foreach ($fieldIds as $fieldId) {
-      if (!empty($params['price_' . $fieldId])) {
-        if (is_array($params['price_' . $fieldId])) {
-          foreach ($params['price_' . $fieldId] as $priceFldVal => $isSet) {
-            if ($isSet) {
-              $priceFieldIDS[] = $priceFldVal;
+  public static function getPriceFieldIDs($params, $priceSet) {
+    $priceFieldIDS = $fieldIds = array();
+    if (isset($priceSet['fields']) && is_array($priceSet['fields'])) {
+      $fieldIds = array_keys($priceSet['fields']);
+      foreach ($fieldIds as $fieldId) {
+        if (!empty($params['price_' . $fieldId])) {
+          if (is_array($params['price_' . $fieldId])) {
+            foreach ($params['price_' . $fieldId] as $priceFldVal => $isSet) {
+              if ($isSet) {
+                $priceFieldIDS[] = $priceFldVal;
+              }
             }
           }
-        }
-        else {
-          $priceFieldIDS[] = $params['price_' . $fieldId];
+          else {
+            $priceFieldIDS[] = $params['price_' . $fieldId];
+          }
         }
       }
     }
@@ -630,7 +628,7 @@ class CRM_Member_Form_Membership extends CRM_Member_Form {
       $this->addDate('receive_date', ts('Received'), FALSE, array('formatType' => 'activityDateTime'));
 
       $this->add('select', 'payment_instrument_id',
-        ts('Paid By'),
+        ts('Payment Method'),
         array('' => ts('- select -')) + CRM_Contribute_PseudoConstant::paymentInstrument(),
         FALSE, array('onChange' => "return showHideByValue('payment_instrument_id','4','checkNumber','table-row','select',false);")
       );
@@ -723,10 +721,8 @@ class CRM_Member_Form_Membership extends CRM_Member_Form {
 
     $this->addFormRule(array('CRM_Member_Form_Membership', 'formRule'), $this);
 
-    $mailingInfo = CRM_Core_BAO_Setting::getItem(CRM_Core_BAO_Setting::MAILING_PREFERENCES_NAME,
-      'mailing_backend'
-    );
-    $this->assign('outBound_option', $mailingInfo['outBound_option']);
+    $this->assign('outBound_option', CRM_Core_BAO_Setting::getItem(CRM_Core_BAO_Setting::MAILING_PREFERENCES_NAME,
+      'mailing_backend'));
 
     parent::buildQuickForm();
   }
@@ -748,13 +744,13 @@ class CRM_Member_Form_Membership extends CRM_Member_Form {
     $errors = array();
 
     $priceSetId = CRM_Utils_Array::value('price_set_id', $params);
+    $priceSetDetails = CRM_Price_BAO_PriceSet::getSetDetail($priceSetId);
 
-    $selectedMemberships = self::getSelectedMemberships($priceSetId, $params);
-
+    $selectedMemberships = self::getSelectedMemberships($priceSetDetails[$priceSetId], $params);
     if ($priceSetId) {
       CRM_Price_BAO_PriceField::priceSetValidation($priceSetId, $params, $errors);
 
-      $priceFieldIDS = self::getPriceFieldIDs($params, $self);
+      $priceFieldIDS = self::getPriceFieldIDs($params, $priceSetDetails);
 
       if (!empty($priceFieldIDS)) {
         $ids = implode(',', $priceFieldIDS);
@@ -766,21 +762,26 @@ class CRM_Member_Form_Membership extends CRM_Member_Form {
           }
         }
       }
+      // Return error if empty $self->_memTypeSelected
+      if (empty($errors) && empty($selectedMemberships)) {
+        $errors['_qf_default'] = ts('Select at least one membership option.');
+      }
+      if (!$self->_mode && empty($params['record_contribution'])) {
+        $errors['record_contribution'] = ts('Record Membership Payment is required when you use a price set.');
+      }
     }
-    elseif (empty($params['membership_type_id'][1])) {
-      $errors['membership_type_id'] = ts('Please select a membership type.');
-    }
-
-    if (!$priceSetId) {
+    else {
+      if (empty($params['membership_type_id'][1])) {
+        $errors['membership_type_id'] = ts('Please select a membership type.');
+      }
       $numterms = CRM_Utils_Array::value('num_terms', $params);
       if ($numterms && intval($numterms) != $numterms) {
         $errors['num_terms'] = ts('Please enter an integer for the number of terms.');
       }
-    }
 
-    // Return error if empty $self->_memTypeSelected
-    if ($priceSetId && empty($errors) && empty($selectedMemberships)) {
-      $errors['_qf_default'] = ts('Select at least one membership option.');
+      if ($self->_mode || isset($params['record_contribution']) && empty($params['financial_type_id'])) {
+        $errors['financial_type_id'] = ts('Please enter the financial Type.');
+      }
     }
 
     if (!empty($errors) && (count($selectedMemberships) > 1)) {
@@ -797,16 +798,9 @@ class CRM_Member_Form_Membership extends CRM_Member_Form {
       return $errors;
     }
 
-    if ($priceSetId && !$self->_mode && empty($params['record_contribution'])) {
-      $errors['record_contribution'] = ts('Record Membership Payment is required when you using price set.');
-    }
-
-    if (!$priceSetId && $self->_mode && empty($params['financial_type_id'])) {
-      $errors['financial_type_id'] = ts('Please enter the financial Type.');
-    }
 
     if (!empty($params['record_contribution']) && empty($params['payment_instrument_id'])) {
-      $errors['payment_instrument_id'] = ts('Paid By is a required field.');
+      $errors['payment_instrument_id'] = ts('Payment Method is a required field.');
     }
 
     if (!empty($params['is_different_contribution_contact'])) {
@@ -930,9 +924,6 @@ class CRM_Member_Form_Membership extends CRM_Member_Form {
     //total amount condition arise when membership type having no
     //minimum fee
     if (isset($params['record_contribution'])) {
-      if (!$params['financial_type_id']) {
-        $errors['financial_type_id'] = ts('Please enter the financial Type.');
-      }
       if (CRM_Utils_System::isNull($params['total_amount'])) {
         $errors['total_amount'] = ts('Please enter the contribution.');
       }
@@ -1010,6 +1001,7 @@ class CRM_Member_Form_Membership extends CRM_Member_Form {
     }
 
     CRM_Core_BAO_UFGroup::getValues($formValues['contact_id'], $customFields, $customValues, FALSE, $members);
+    $form->assign('customValues', $customValues);
 
     if ($form->_mode) {
       $name = '';
@@ -1091,7 +1083,6 @@ class CRM_Member_Form_Membership extends CRM_Member_Form {
       $form->assign('membership_name', CRM_Member_PseudoConstant::membershipType($membership->membership_type_id));
     }
 
-    $form->assign('customValues', $customValues);
     $isBatchProcess = is_a($form, 'CRM_Batch_Form_Entry');
     if ((empty($form->_contributorDisplayName) || empty($form->_contributorEmail)) || $isBatchProcess) {
       // in this case the form is being called statically from the batch editing screen
@@ -1159,11 +1150,6 @@ class CRM_Member_Form_Membership extends CRM_Member_Form {
     $allMemberStatus = CRM_Member_PseudoConstant::membershipStatus();
     $allContributionStatus = CRM_Contribute_PseudoConstant::contributionStatus();
 
-    $lineItems = NULL;
-    if (!empty($this->_lineItem)) {
-      $lineItems = $this->_lineItem;
-    }
-
     if ($this->_id) {
       $ids['membership'] = $params['id'] = $this->_id;
     }
@@ -1173,7 +1159,14 @@ class CRM_Member_Form_Membership extends CRM_Member_Form {
     // In form mode these are set in preProcess.
     //TODO: set memberships, fixme
     $this->setContextVariables($formValues);
-    $this->_memTypeSelected = self::getSelectedMemberships($priceSetID, $formValues);
+    $priceSetDetails = CRM_Price_BAO_PriceSet::getSetDetail($priceSetID);
+    $this->_memTypeSelected = self::getSelectedMemberships(
+      $priceSetDetails[$priceSetID],
+      $formValues
+    );
+    if (empty($formValues['financial_type_id'])) {
+      $formValues['financial_type_id'] = $priceSetDetails[$priceSetID]['financial_type_id'];
+    }
 
     $config = CRM_Core_Config::singleton();
 
@@ -1438,8 +1431,6 @@ class CRM_Member_Form_Membership extends CRM_Member_Form {
         $fields["email-{$this->_bltID}"] = 1;
       }
 
-      $ctype = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $this->_contactID, 'contact_type');
-
       $nameFields = array('first_name', 'middle_name', 'last_name');
 
       foreach ($nameFields as $name) {
@@ -1452,7 +1443,8 @@ class CRM_Member_Form_Membership extends CRM_Member_Form {
       if ($this->_contributorContactID == $this->_contactID) {
         //see CRM-12869 for discussion of why we don't do this for separate payee payments
         CRM_Contact_BAO_Contact::createProfileContact($formValues, $fields,
-          $this->_contributorContactID, NULL, NULL, $ctype
+          $this->_contributorContactID, NULL, NULL,
+          CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $this->_contactID, 'contact_type')
         );
       }
 
@@ -1466,7 +1458,7 @@ class CRM_Member_Form_Membership extends CRM_Member_Form {
       $this->_params['ip_address'] = CRM_Utils_System::ipAddress();
       $this->_params['amount'] = $params['total_amount'];
       $this->_params['currencyID'] = $config->defaultCurrency;
-      $this->_params['description'] = ts('Office Credit Card Membership Signup Contribution');
+      $this->_params['description'] = ts("Contribution submitted by a staff person using member's credit card for signup");
       $this->_params['invoiceID'] = md5(uniqid(rand(), TRUE));
       $this->_params['financial_type_id'] = $params['financial_type_id'];
 
@@ -1493,19 +1485,26 @@ class CRM_Member_Form_Membership extends CRM_Member_Form {
       // we do need contribution and recurring records.
       $result = NULL;
       if (!empty($paymentParams['is_recur'])) {
-        $contributionType = new CRM_Financial_DAO_FinancialType();
-        $contributionType->id = $params['financial_type_id'];
-        $contributionType->find(TRUE);
+        $financialType = new CRM_Financial_DAO_FinancialType();
+        $financialType->id = $params['financial_type_id'];
+        $financialType->find(TRUE);
 
         $contribution = CRM_Contribute_Form_Contribution_Confirm::processFormContribution($this,
           $paymentParams,
-          $result,
-          $this->_contributorContactID,
-          $contributionType,
+          NULL,
+          array(
+            'contact_id' => $this->_contributorContactID,
+            'line_item' => $lineItem,
+            'is_test' => $isTest,
+            'campaign_id' => CRM_Utils_Array::value('campaign_id', $paymentParams),
+            'contribution_page_id' => CRM_Utils_Array::value('contribution_page_id', $this->_params),
+            'source' => CRM_Utils_Array::value('source', $paymentParams, CRM_Utils_Array::value('description', $paymentParams)),
+            'thankyou_date' => CRM_Utils_Array::value('thankyou_date', $paymentParams),
+            'payment_instrument_id' => $this->_paymentProcessor['payment_instrument_id'],
+          ),
+          $financialType,
           TRUE,
           FALSE,
-          $isTest,
-          $lineItems,
           $this->_bltID
         );
 
@@ -1551,26 +1550,7 @@ class CRM_Member_Form_Membership extends CRM_Member_Form {
         }
       }
 
-      if ($result) {
-        $this->_params = array_merge($this->_params, $result);
-        //assign amount to template if payment was successful
-        $this->assign('amount', $params['total_amount']);
-      }
-
-      // if the payment processor returns a payment_status_id -we assume this
-      // applies to the whole contribution.
-      // At this stage this form is not processing separate payments.
-      if (isset($result['payment_status_id'])) {
-        // CRM-16737 $result['contribution_status_id'] is deprecated in favour
-        // of payment_status_id as the payment processor only knows whether the payment is complete
-        // not whether payment completes the contribution
-        $params['contribution_status_id'] = $params['payment_status_id'];
-      }
-      // do what used to happen previously
-      else {
-        $params['contribution_status_id'] = !empty($paymentParams['is_recur']) ? 2 : 1;
-      }
-      if ($params['contribution_status_id'] != array_search('Completed', $allContributionStatus)) {
+      if ($this->_params['payment_status_id'] != array_search('Completed', $allContributionStatus)) {
         $params['status_id'] = array_search('Pending', $allMemberStatus);
         $params['skipStatusCal'] = TRUE;
         // unset send-receipt option, since receipt will be sent when ipn is received.
@@ -1627,6 +1607,13 @@ class CRM_Member_Form_Membership extends CRM_Member_Form {
         if (!empty($softParams) && empty($paymentParams['is_recur'])) {
           $membershipParams['soft_credit'] = $softParams;
         }
+        // This is required to trigger the recording of the membership contribution in the
+        // CRM_Member_BAO_Membership::Create function.
+        // @todo stop setting this & 'teach' the create function to respond to something
+        // appropriate as part of our 2-step always create the pending contribution & then finally add the payment
+        // process -
+        // @see http://wiki.civicrm.org/confluence/pages/viewpage.action?pageId=261062657#Payments&AccountsRoadmap-Movetowardsalwaysusinga2-steppaymentprocess
+        $membershipParams['contribution_status_id'] = CRM_Utils_Array::value('payment_status_id', $result);
         $membership = CRM_Member_BAO_Membership::create($membershipParams, $ids);
         $params['contribution'] = CRM_Utils_Array::value('contribution', $membershipParams);
         unset($params['lineItems']);
@@ -1800,7 +1787,6 @@ class CRM_Member_Form_Membership extends CRM_Member_Form {
     $statusMsg = '';
     if (($this->_action & CRM_Core_Action::UPDATE)) {
       $statusMsg = $this->getStatusMessageForUpdate($membership, $endDate, $receiptSend);
-
     }
     elseif (($this->_action & CRM_Core_Action::ADD)) {
       $statusMsg = $this->getStatusMessageForCreate($endDate, $receiptSend, $membershipTypes, $createdMemberships,
@@ -1808,7 +1794,18 @@ class CRM_Member_Form_Membership extends CRM_Member_Form {
     }
 
     CRM_Core_Session::setStatus($statusMsg, ts('Complete'), 'success');
-
+    //CRM-15187
+    // dusplay message when membership type is changed
+    if (($this->_action & CRM_Core_Action::UPDATE) && $this->_id && !in_array($this->_memType, $this->_memTypeSelected)) {
+      CRM_Core_Session::setStatus(
+        ts('The financial types associated with the old and new membership types are different. You may want to edit the contribution associated with this membership to adjust its financial type.'),
+        ts('Warning')
+      );
+      CRM_Core_Session::setStatus(
+        ts('The cost of the old and new membership types are different. You may want to edit the contribution associated with this membership to adjust its amount.'),
+        ts('Warning')
+      );
+    }
     return $createdMemberships;
   }
 
@@ -1901,7 +1898,7 @@ class CRM_Member_Form_Membership extends CRM_Member_Form {
       }
     }
     $statusMsg = implode('<br/>', $statusMsg);
-    if ($receiptSend && $mailSent) {
+    if ($receiptSend && !empty($mailSent)) {
       $statusMsg .= ' ' . ts('A membership confirmation and receipt has been sent to %1.', array(1 => $this->_contributorEmail));
     }
     return $statusMsg;