* @param int $contributionTypeId
* Financial type id.
* @param int|string $component component id
- * @param $isTest
+ * @param bool $isTest
+ * @param bool $isRecur
*
* @throws CRM_Core_Exception
* @throws Exception
$contactID,
$contributionTypeId,
$component = 'contribution',
- $isTest
+ $isTest,
+ $isRecur
) {
CRM_Core_Payment_Form::mapParams($form->_bltID, $form->_params, $paymentParams, TRUE);
$lineItems = $form->_lineItem;
CRM_Utils_Date::mysqlToIso($form->_params['receive_date'])
);
if ($isPaymentTransaction) {
- // Fix for CRM-14354. If the membership is recurring, don't create a
- // civicrm_contribution_recur record for the additional contribution
- // (i.e., the amount NOT associated with the membership). Temporarily
- // cache the is_recur values so we can process the additional gift as a
- // one-off payment.
- if (!empty($form->_values['is_recur'])) {
- if ($form->_membershipBlock['is_separate_payment'] && !empty($form->_params['auto_renew'])) {
- $cachedFormValue = CRM_Utils_Array::value('is_recur', $form->_values);
- $cachedParamValue = CRM_Utils_Array::value('is_recur', $paymentParams);
- unset($form->_values['is_recur']);
- unset($paymentParams['is_recur']);
- }
- }
$contributionParams = array(
'contact_id' => $contactID,
$contributionParams,
$financialType,
TRUE,
- $form->_bltID
+ $form->_bltID,
+ $isRecur
);
$paymentParams['contributionTypeID'] = $contributionTypeId;
return array('contribution' => $contribution);
}
- // restore cached values (part of fix for CRM-14354)
- if (!empty($cachedFormValue)) {
- $form->_values['is_recur'] = $cachedFormValue;
- $paymentParams['is_recur'] = $cachedParamValue;
- }
-
$paymentParams['contributionID'] = $contribution->id;
//CRM-15297 deprecate contributionTypeID
$paymentParams['financialTypeID'] = $paymentParams['contributionTypeID'] = $contribution->financial_type_id;
$contributionParams,
$financialType,
FALSE,
- $this->_bltID
+ $this->_bltID,
+ CRM_Utils_Array::value('is_recur', $this->_params)
);
$paymentParams['contributionID'] = $contribution->id;
$contributionParams,
$financialType,
$online,
- $billingLocationID
+ $billingLocationID,
+ $isRecur
) {
$transaction = new CRM_Core_Transaction();
$contactID = $contributionParams['contact_id'];
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');
* @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;
}
$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);
$isTest = CRM_Utils_Array::value('is_test', $membershipParams, FALSE);
$errors = $createdMemberships = $paymentResults = array();
+ $isRecurForFirstTransaction = CRM_Utils_Array::value('is_recur', $form->_values, CRM_Utils_Array::value('is_recur', $membershipParams));
+
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'])) {
$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.
$contributionParams,
$financialType,
TRUE,
- $form->_bltID
+ $form->_bltID,
+ $isRecur
);
$result = array();
}
}
}
-
+ $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'])) {
),
$financialType,
FALSE,
- $this->_bltID
+ $this->_bltID,
+ TRUE
);
//create new soft-credit record, CRM-13981
$this->assertEquals(2, $recurringContribution['contribution_status_id']);
}
+ /**
+ * Test submit recurring membership with immediate confirmation (IATS style).
+ *
+ * - we process 2 membership transactions against with a recurring contribution against a contribution page with an immediate
+ * processor (IATS style - denoted by returning trxn_id)
+ * - the first creates a new membership, completed contribution, in progress recurring. Check these
+ * - create another - end date should be extended
+ */
+ public function testSubmitMembershipPriceSetPaymentPaymentProcessorSeparatePaymentRecurInstantPayment() {
+
+ $this->setUpMembershipContributionPage(TRUE);
+ $dummyPP = Civi\Payment\System::singleton()->getByProcessor($this->_paymentProcessor);
+ $dummyPP->setDoDirectPaymentResult(array('payment_status_id' => 1, 'trxn_id' => 'create_first_success'));
+
+ $submitParams = array(
+ 'price_' . $this->_ids['price_field'][0] => reset($this->_ids['price_field_value']),
+ 'id' => (int) $this->_ids['contribution_page'],
+ 'amount' => 10,
+ 'billing_first_name' => 'Billy',
+ 'billing_middle_name' => 'Goat',
+ 'billing_last_name' => 'Gruff',
+ 'email' => 'billy@goat.gruff',
+ 'selectMembership' => $this->_ids['membership_type'],
+ 'payment_processor_id' => 1,
+ 'credit_card_number' => '4111111111111111',
+ 'credit_card_type' => 'Visa',
+ 'credit_card_exp_date' => array('M' => 9, 'Y' => 2040),
+ 'cvv2' => 123,
+ 'is_recur' => 1,
+ 'auto_renew' => TRUE,
+ 'frequency_interval' => 1,
+ 'frequency_unit' => 'month',
+ );
+
+ $this->callAPIAndDocument('contribution_page', 'submit', $submitParams, __FUNCTION__, __FILE__, 'submit contribution page', NULL);
+ $contribution = $this->callAPISuccess('contribution', 'get', array(
+ 'contribution_page_id' => $this->_ids['contribution_page'],
+ 'contribution_status_id' => 1,
+ ));
+
+ $this->assertEquals(2, $contribution['count']);
+ $membershipPayment = $this->callAPISuccess('membership_payment', 'getsingle', array());
+ $this->callAPISuccessGetSingle('membership', array('id' => $membershipPayment['membership_id']));
+ $this->assertNotEmpty($contribution['values'][$membershipPayment['contribution_id']]['contribution_recur_id']);
+ $this->callAPISuccess('contribution_recur', 'getsingle', array());
+ }
+
/**
* Test submit recurring membership with delayed confirmation (Authorize.net style)
* - we process 2 membership transactions against with a recurring contribution against a contribution page with a delayed