CRM-14866 membership payment not creating for membership block type
authorEileen McNaughton <eileen@fuzion.co.nz>
Tue, 17 Jun 2014 01:41:28 +0000 (13:41 +1200)
committerEileen McNaughton <eileen@fuzion.co.nz>
Tue, 17 Jun 2014 01:41:28 +0000 (13:41 +1200)
CRM/Contribute/BAO/ContributionPage.php
CRM/Contribute/Form/Contribution/Confirm.php
CRM/Contribute/Form/ContributionBase.php
CRM/Member/BAO/Membership.php
api/v3/MembershipBlock.php [new file with mode: 0644]
tests/phpunit/api/v3/ContributionPageTest.php

index 00f546b306194c9248509ef7b7fb1324017983e6..9d1db36d6654cf443de74cf12d91d7aae4c3cf35 100644 (file)
@@ -887,5 +887,20 @@ LEFT JOIN  civicrm_premiums            ON ( civicrm_premiums.entity_id = civicrm
     }
     return $sctJson;
   }
+
+
+  /**
+   * helper to determine if the page supports separate membership payments
+   * @param integer id form id
+   *
+   * @return bool isSeparateMembershipPayment
+   */
+  static function getIsMembershipPayment($id) {
+    $membershipBlocks = civicrm_api3('membership_block', 'get', array('entity_table' => 'civicrm_contribution_page', 'entity_id' => $id, 'sequential' => TRUE));
+    if(!$membershipBlocks['count']) {
+      return FALSE;
+    }
+    return $membershipBlocks['values'][0]['is_separate_payment'];
+  }
 }
 
index 88d951705b23b907452370af338f2da1b029baf8..a560d3962d8047d5d099543edeeab250871ae9e7 100644 (file)
@@ -902,7 +902,7 @@ class CRM_Contribute_Form_Contribution_Confirm extends CRM_Contribute_Form_Contr
         $membershipParams['cms_contactID'] = $contactID;
       }
 
-      //inherit campaign from contirb page.
+      //inherit campaign from contribution page.
       if (!array_key_exists('campaign_id', $membershipParams)) {
         $membershipParams['campaign_id'] = CRM_Utils_Array::value('campaign_id', $this->_values);
       }
@@ -1697,11 +1697,9 @@ class CRM_Contribute_Form_Contribution_Confirm extends CRM_Contribute_Form_Contr
    * @param $fieldTypes
    * @param $premiumParams
    */
-  public function processMembership($membershipParams, $contactID, $customFieldsFormatted, $fieldTypes, $premiumParams)
-  {
+  public function processMembership($membershipParams, $contactID, $customFieldsFormatted, $fieldTypes, $premiumParams) {
     try {
-
-      $membershipTypeID = $membershipParams['selectMembership'];
+      $membershipTypeID = (array) $membershipParams['selectMembership'];
 
       $membershipDetails = CRM_Member_BAO_Membership::buildMembershipTypeValues($this);
       $this->assign('membership_name', CRM_Utils_Array::value('name', $membershipDetails));
@@ -1794,7 +1792,7 @@ class CRM_Contribute_Form_Contribution_Confirm extends CRM_Contribute_Form_Contr
       // but the circumstances are very confusing. Many of these conditions are repeated in the next conditional
       // so we should merge them together
       // the quick config seems like a red-herring - if this is about a separate membership payment then there
-      // are 2 types of line items - membership ones & non-membership ones - regardless of whether quickconfig is set
+      // are 2 types of line items - membership ones & non-membership ones - regardless of whether quick config is set
       elseif (
         CRM_Utils_Array::value('is_separate_payment', $this->_membershipBlock)
         && !empty($this->_values['fee'][$priceField->id])
@@ -1826,14 +1824,20 @@ class CRM_Contribute_Form_Contribution_Confirm extends CRM_Contribute_Form_Contr
   static function submit($params) {
     $form = new CRM_Contribute_Form_Contribution_Confirm();
     $form->_id = $params['id'];
+    CRM_Contribute_BAO_ContributionPage::setValues($form->_id, $form->_values);
+    $form->_separateMembershipPayment = CRM_Contribute_BAO_ContributionPage::getIsMembershipPayment($form->_id);
     //this way the mocked up controller ignores the session stuff
     $_SERVER['REQUEST_METHOD'] = 'GET';
     $form->controller = new CRM_Contribute_Controller_Contribution();
     $params['invoiceID'] = md5(uniqid(rand(), TRUE));
     $paramsProcessedForForm = $form->_params = self::getFormParams($params['id'], $params);
+    $form->_amount = $params['amount'];
+
 
     $priceSetID = $form->_params['priceSetId'] = $paramsProcessedForForm['price_set_id'];
     $priceFields = CRM_Price_BAO_PriceSet::getSetDetail($priceSetID);
+    $priceSetFields = reset($priceFields);
+    $form->_values['fee'] = $priceSetFields['fields'];
     $form->setFormAmountFields($priceSetID);
     $priceFields = $priceFields[$priceSetID]['fields'];
     CRM_Price_BAO_PriceSet::processAmount($priceFields, $paramsProcessedForForm, $lineItems, 'civicrm_contribution');
index 2cbd0c1575b963e257818f5a0865af993ac620b5..d60a8405bc202ca634ef1da78e8c55ae289845c3 100644 (file)
@@ -88,6 +88,11 @@ class CRM_Contribute_Form_ContributionBase extends CRM_Core_Form {
    */
   public $_membershipBlock = NULL;
 
+  /**
+   * Does this form support a separate membership payment
+   * @var bool
+   */
+  protected $_separateMembershipPayment;
   /**
    * the default values for the form
    *
index a91081a1301ccc57f7618f435e331e3d24feb903..5e338a9865b432491f2689ee04ae4fd33383b194 100644 (file)
@@ -717,7 +717,7 @@ INNER JOIN  civicrm_membership_type type ON ( type.id = membership.membership_ty
    * @param boolean $thankPage thank you page
    * @param null $isTest
    *
-   * @return bool|mixed
+   * @return bool Is this a separate membership payment
    * @internal param int $pageId contribution page id
    * @internal param bool $memContactId contact who is to be
    * checked for having a current membership for a particular membership
@@ -1304,7 +1304,7 @@ AND civicrm_membership.is_test = %2";
       if (isset($membershipParams['onbehalf']) && !empty($membershipParams['onbehalf']['member_campaign_id'])) {
         $form->_params['campaign_id'] = $membershipParams['onbehalf']['member_campaign_id'];
       }
-      //!!B
+      //@todo it should no longer be possible for it to get to this point & membership to not be an array
       if (is_array($membershipTypeID)) {
         $typesTerms = CRM_Utils_Array::value('types_terms', $membershipParams, array());
         foreach ($membershipTypeID as $memType) {
diff --git a/api/v3/MembershipBlock.php b/api/v3/MembershipBlock.php
new file mode 100644 (file)
index 0000000..8d85a14
--- /dev/null
@@ -0,0 +1,95 @@
+<?php
+
+/*
+ +--------------------------------------------------------------------+
+ | CiviCRM version 4.5                                                |
+ +--------------------------------------------------------------------+
+ | Copyright CiviCRM LLC (c) 2004-2014                                |
+ +--------------------------------------------------------------------+
+ | This file is a part of CiviCRM.                                    |
+ |                                                                    |
+ | CiviCRM is free software; you can copy, modify, and distribute it  |
+ | under the terms of the GNU Affero General Public License           |
+ | Version 3, 19 November 2007 and the CiviCRM Licensing Exception.   |
+ |                                                                    |
+ | CiviCRM is distributed in the hope that it will be useful, but     |
+ | WITHOUT ANY WARRANTY; without even the implied warranty of         |
+ | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.               |
+ | See the GNU Affero General Public License for more details.        |
+ |                                                                    |
+ | You should have received a copy of the GNU Affero General Public   |
+ | License and the CiviCRM Licensing Exception along                  |
+ | with this program; if not, contact CiviCRM LLC                     |
+ | at info[AT]civicrm[DOT]org. If you have questions about the        |
+ | GNU Affero General Public License or the licensing of CiviCRM,     |
+ | see the CiviCRM license FAQ at http://civicrm.org/licensing        |
+ +--------------------------------------------------------------------+
+*/
+
+/**
+ * File for the CiviCRM APIv3 membership type functions
+ *
+ * @package CiviCRM_APIv3
+ * @subpackage API_Membership
+ *
+ * @copyright CiviCRM LLC (c) 2004-2014
+ * @version $Id: MembershipBlock.php 30171 2010-10-14 09:11:27Z mover $
+ *
+ */
+
+/**
+ * API to Create or update a Membership Type
+ *
+ * @param array$params  an associative array of name/value property values of civicrm_membership_block
+ *
+ * @return array $result newly created or updated membership type property values.
+ * @access public
+ * {getfields MembershipBlock_get}
+ */
+function civicrm_api3_membership_block_create($params) {
+  return _civicrm_api3_basic_create(_civicrm_api3_get_BAO(__FUNCTION__), $params);
+}
+
+/**
+ * Adjust Metadata for Create action
+ *
+ * The metadata is used for setting defaults, documentation & validation
+ * @param array $params array or parameters determined by getfields
+ */
+function _civicrm_api3_membership_block_create_spec(&$params) {
+  $params['is_active']['api.default'] = TRUE;
+  $params['entity_id']['api.required'] = TRUE;
+  $params['entity_table']['api.default'] = 'civicrm_contribution_page';
+}
+
+/**
+ * Get a Membership Type.
+ *
+ * This api is used for finding an existing membership type.
+ *
+ * @param array $params  an associative array of name/value property values of civicrm_membership_block
+ * {getfields MembershipBlock_get}
+ *
+ * @return array api result array of all found membership block property values.
+ * @access public
+ */
+function civicrm_api3_membership_block_get($params) {
+  return _civicrm_api3_basic_get(_civicrm_api3_get_BAO(__FUNCTION__), $params);
+}
+
+/**
+ * Deletes an existing membership type
+ *
+ * This API is used for deleting a membership type
+ * Required parameters : id of a membership type
+ *
+ * @param  array $params
+ *
+ * @return array api result array
+ * @access public
+ * {getfields MembershipBlock_delete}
+ */
+function civicrm_api3_membership_block_delete($params) {
+  return _civicrm_api3_basic_delete(_civicrm_api3_get_BAO(__FUNCTION__), $params);
+}
+
index be86e403ac43e803d483de67c38ebf0541d8f3ec..c0a7df4936f80e64461711e591327ced3ac9bb39 100644 (file)
@@ -43,6 +43,17 @@ class api_v3_ContributionPageTest extends CiviUnitTestCase {
   protected $contactIds = array();
   protected $_entity = 'contribution_page';
   protected $contribution_result = null;
+  protected $_priceSetParams = array();
+
+  /**
+   * @var array
+   *  - contribution_page
+   *  - price_set
+   *  - price_field
+   *  - price_field_value
+   */
+  protected $_ids = array();
+
 
   public $DBResetRequired = TRUE;
   public function setUp() {
@@ -54,6 +65,14 @@ class api_v3_ContributionPageTest extends CiviUnitTestCase {
       'currency' => 'NZD',
       'goal_amount' => $this->testAmount,
       'is_pay_later' => 1,
+      'is_monetary' => TRUE,
+    );
+
+    $this->_priceSetParams = array(
+      'is_quick_config' => 1,
+      'extends' => 'CiviContribute',
+      'financial_type_id' => 'Donation',
+      'title' => 'my Page'
     );
   }
 
@@ -113,43 +132,128 @@ class api_v3_ContributionPageTest extends CiviUnitTestCase {
    * Test form submission with basic price set
    */
   public function testSubmit() {
-    $contributionPageResult = $this->callAPISuccess($this->_entity, 'create', $this->params);
-    $priceSetParams = array(
-      'is_quick_config' => 1,
-      'extends' => 'CiviContribute',
-      'financial_type_id' => 'Donation',
-      'title' => 'my Page'
+    $this->setUpContributionPage();
+    $priceFieldID = reset($this->_ids['price_field']);
+    $priceFieldValueID = reset($this->_ids['price_field_value']);
+    $submitParams = array(
+      'price_' . $priceFieldID => $priceFieldValueID,
+      'id' => (int) $this->_ids['contribution_page'],
+      'amount' => 10
     );
 
-    $priceSet = $this->callAPISuccess('price_set', 'create', $priceSetParams);
-    CRM_Price_BAO_PriceSet::addTo('civicrm_contribution_page', $contributionPageResult['id'], $priceSet['id']);
+    $this->callAPISuccess('contribution_page', 'submit', $submitParams);
+    $this->callAPISuccess('contribution', 'getsingle', array('contribution_page_id' => $this->_ids['contribution_page']));
+  }
+
+  /**
+   * Test submit with a membership block in place
+   */
+  public function testSubmitMembershipBlock() {
+    $this->_ids['price_set'][] = $this->callAPISuccess('price_set', 'getvalue', array('name'  => 'default_membership_type_amount', 'return' => 'id'));
+    $this->params['payment_processor_id'] = $this->paymentProcessorCreate(array('payment_processor_type_id' => 'Dummy',));
+    $this->setUpContributionPage();
+    $contributionPageID = $this->_ids['contribution_page'];
+    /*
+     *             [qfKey] => 6994954fc612cb500406b793d2676ebb_7820
+            [entryURL] => http://civi45/civicrm/contribute/transact?reset=1&id=5
+            [hidden_processor] => 1
+            [billing_first_name] => me
+            [billing_middle_name] =>
+            [billing_last_name] => demo
+            [billing_street_address-5] => d
+            [billing_city-5] => s
+            [billing_state_province_id-5] => 1011
+            [billing_postal_code-5] => 7070
+            [billing_country_id-5] => 1228
+            [credit_card_number] => 4111111111111111
+            [cvv2] => 123
+            [credit_card_exp_date] => Array
+                (
+                    [M] => 2
+                    [Y] => 2016
+                )
+
+            [credit_card_type] => Visa
+            [email-5] => demo@example.com
+            [payment_processor] => 13
+            [priceSetId] => 11
+            [price_18] => 30
+            [selectProduct] =>
+            [MAX_FILE_SIZE] => 2097152
+            [stripe_token] =>
+            [billing_state_province-5] => ID
+            [billing_country-5] => US
+            [year] => 2016
+            [month] => 2
+            [ip_address] => 192.168.56.1
+            [amount] => 100
+            [amount_level] =>
+            [selectMembership] => 1
+            [currencyID] => USD
+            [payment_action] => Sale
+            [is_pay_later] => 0
+            [invoiceID] => 78bc8c7ebf99c609067caac81128720d
+            [is_quick_config] => 1
+     */
+    $this->_ids['membership_type'] = $this->membershipTypeCreate();
+    $this->callAPISuccess('membership_block', 'create', array(
+      'entity_id' => $contributionPageID,
+      'entity_table' => 'civicrm_contribution_page',
+      'is_required' => TRUE,
+      'is_active' => TRUE,
+      'membership_type_default' => $this->_ids['membership_type'],
+    ));
+    $submitParams = array(
+      'price_' . reset($this->_ids['price_field']) => reset($this->_ids['price_field_value']),
+      'id' => (int) $contributionPageID,
+      'amount' => 10,
+      'billing_first_name' => 'Billy',
+      'billing_middle_name' => 'Goat',
+      'billing_last_name' => 'Gruff',
+      'selectMembership' => $this->_ids['membership_type'],
+
+    );
+
+    $this->callAPIAndDocument('contribution_page', 'submit', $submitParams, __FUNCTION__, __FILE__, 'submit contribution page', NULL, 'Submit');
+    $contribution = $this->callAPISuccess('contribution', 'getsingle', array('contribution_page_id' => $contributionPageID));
+    $this->callAPISuccess('membership_payment', 'getsingle', array('contribution_id' => $contribution['id']));
+
+  }
+
+  /**
+   * help function to set up contribution page with some defaults
+   */
+  function setUpContributionPage() {
+    $contributionPageResult = $this->callAPISuccess($this->_entity, 'create', $this->params);
+    if (empty($this->_ids['price_set'])) {
+      $priceSet = $this->callAPISuccess('price_set', 'create', $this->_priceSetParams);
+      $this->_ids['price_set'][] = $priceSet['id'];
+    }
+    $priceSetID = reset($this->_ids['price_set']);
+    CRM_Price_BAO_PriceSet::addTo('civicrm_contribution_page', $contributionPageResult['id'], $priceSetID );
     $priceField = $this->callAPISuccess('price_field', 'create', array(
-      'price_set_id' => $priceSet['id'],
+      'price_set_id' => $priceSetID ,
       'label' => 'Goat Breed',
       'html_type' => 'Radio',
     ));
     $this->callAPISuccess('price_field_value', 'create', array(
-      'price_set_id' => $priceSet['id'],
-      'price_field_id' => $priceField['id'],
-      'label' => 'Long Haired Goat',
-      'amount' => 20,
+        'price_set_id' => $priceSetID ,
+        'price_field_id' => $priceField['id'],
+        'label' => 'Long Haired Goat',
+        'amount' => 20,
       )
     );
-    $priceFieldValue2 = $this->callAPISuccess('price_field_value', 'create', array(
-      'price_set_id' => $priceSet['id'],
-      'price_field_id' => $priceField['id'],
-      'label' => 'Shoe-eating Goat',
-      'amount' => 10,
+    $priceFieldValue = $this->callAPISuccess('price_field_value', 'create', array(
+        'price_set_id' => $priceSetID ,
+        'price_field_id' => $priceField['id'],
+        'label' => 'Shoe-eating Goat',
+        'amount' => 10,
       )
     );
-    $submitParams = array(
-      'price_' . $priceField['id'] => $priceFieldValue2['id'],
-      'id' => (int) $contributionPageResult['id'],
-      'amount' => 10
+    $this->_ids['contribution_page'] = $contributionPageResult['id'];
+    $this->_ids['price_field'] = array($priceField['id']);
+    $this->_ids['price_field_value'] = array($priceFieldValue['id']
     );
-
-    $this->callAPISuccess('contribution_page', 'submit', $submitParams);
-    $this->callAPISuccess('contribution', 'getsingle', array('contribution_page_id' => $contributionPageResult['id']));
   }
 
   public static function setUpBeforeClass() {