From d97c96dc977611e6ae5674b7e9bcec7b60257f44 Mon Sep 17 00:00:00 2001 From: Eileen McNaughton Date: Sun, 22 Feb 2015 08:27:52 +1300 Subject: [PATCH] CRM-15966 add repeattransaction api + test making sure line items created Conflicts: tests/phpunit/api/v3/ContributionTest.php --- CRM/Contribute/BAO/Contribution.php | 4 ++ CRM/Core/Payment/BaseIPN.php | 2 +- api/v3/Contribution.php | 36 ++++++++++++--- tests/phpunit/api/v3/ContributionTest.php | 54 +++++++++++++++++++++++ 4 files changed, 89 insertions(+), 7 deletions(-) diff --git a/CRM/Contribute/BAO/Contribution.php b/CRM/Contribute/BAO/Contribution.php index fcbdacecb8..93a7fda429 100644 --- a/CRM/Contribute/BAO/Contribution.php +++ b/CRM/Contribute/BAO/Contribution.php @@ -1776,6 +1776,7 @@ LEFT JOIN civicrm_contribution contribution ON ( componentPayment.contribution_ $query = " SELECT c.id as contribution_id, c.contact_id as contact_id, + c.contribution_recur_id, mp.membership_id as membership_id, m.membership_type_id as membership_type_id, pp.participant_id as participant_id, @@ -1811,6 +1812,9 @@ LEFT JOIN civicrm_contribution contribution ON ( componentPayment.contribution_ if ($dao->pledge_payment_id) { $pledgePayment[] = $dao->pledge_payment_id; } + if ($dao->contribution_recur_id) { + $componentDetails['contributionRecur'] = $dao->contribution_recur_id; + } } if ($pledgePayment) { diff --git a/CRM/Core/Payment/BaseIPN.php b/CRM/Core/Payment/BaseIPN.php index e5354f0cd8..41e34ad1b2 100644 --- a/CRM/Core/Payment/BaseIPN.php +++ b/CRM/Core/Payment/BaseIPN.php @@ -619,7 +619,7 @@ LIMIT 1;"; $contribution->payment_instrument_id = $input['payment_instrument_id']; } - if ($contribution->id) { + if (!empty($contribution->id)) { $contributionId['id'] = $contribution->id; $input['prevContribution'] = CRM_Contribute_BAO_Contribution::getValues($contributionId, CRM_Core_DAO::$_nullArray, CRM_Core_DAO::$_nullArray); } diff --git a/api/v3/Contribution.php b/api/v3/Contribution.php index 609e38bceb..b53d24fc2d 100644 --- a/api/v3/Contribution.php +++ b/api/v3/Contribution.php @@ -414,7 +414,8 @@ function civicrm_api3_contribution_completetransaction(&$params) { elseif ($contribution->contribution_status_id == CRM_Core_OptionGroup::getValue('contribution_status', 'Completed', 'name')) { throw new API_Exception(ts('Contribution already completed')); } - $params = _ipn_complete_transaction($params, $contribution, $input, $ids); + $input['trxn_id'] = !empty($params['trxn_id']) ? $params['trxn_id'] : $contribution->trxn_id; + $params = _ipn_process_transaction($params, $contribution, $input, $ids); } catch(Exception $e) { throw new API_Exception('failed to load related objects' . $e->getMessage() . "\n" . $e->getTraceAsString()); @@ -465,14 +466,19 @@ function civicrm_api3_contribution_repeattransaction(&$params) { throw new API_Exception( 'A valid original contribution ID is required', 'invalid_data'); } + $original_contribution = clone $contribution; try { if (!$contribution->loadRelatedObjects($input, $ids, FALSE, TRUE)) { throw new API_Exception('failed to load related objects'); } - unset($contribution->id, $contribution->trxn_id, $contribution->receive_date, $contribution->invoice_id); - $contribution->contribution_status_id = $params->contribution_status_id; + + unset($contribution->id, $contribution->receive_date, $contribution->invoice_id); + $contribution->contribution_status_id = $params['contribution_status_id']; $contribution->receive_date = $params['receive_date']; - $params = _ipn_complete_transaction($params, $contribution, $input, $ids); + // Have not set trxn_id to required but an e-notice if not provided seems appropriate. + $input['trxn_id'] = $params['trxn_id']; + + $params = _ipn_process_transaction($params, $contribution, $input, $ids, $original_contribution); } catch(Exception $e) { throw new API_Exception('failed to load related objects' . $e->getMessage() . "\n" . $e->getTraceAsString()); @@ -491,14 +497,19 @@ function civicrm_api3_contribution_repeattransaction(&$params) { * * @param array $ids * + * @param CRM_Contribute_BAO_Contribution $firstContribution + * * @return mixed */ -function _ipn_complete_transaction(&$params, $contribution, $input, $ids) { +function _ipn_process_transaction(&$params, $contribution, $input, $ids, $firstContribution = NULL) { $objects = $contribution->_relatedObjects; $objects['contribution'] = &$contribution; + + if ($firstContribution) { + $objects['first_contribution'] = $firstContribution; + } $input['component'] = $contribution->_component; $input['is_test'] = $contribution->is_test; - $input['trxn_id'] = !empty($params['trxn_id']) ? $params['trxn_id'] : $contribution->trxn_id; $input['amount'] = $contribution->total_amount; if (isset($params['is_email_receipt'])) { $input['is_email_receipt'] = $params['is_email_receipt']; @@ -531,6 +542,7 @@ function _civicrm_api3_contribution_repeattransaction_spec(&$params) { ); $params['contribution_status_id'] = array( 'title' => 'Contribution Status ID', + 'name' => 'contribution_status_id', 'type' => CRM_Utils_Type::T_INT, 'pseudoconstant' => array( 'optionGroupName' => 'contribution_status', @@ -539,7 +551,19 @@ function _civicrm_api3_contribution_repeattransaction_spec(&$params) { ); $params['receive_date'] = array( 'title' => 'Contribution Receive Date', + 'name' => 'receive_date', 'type' => CRM_Utils_Type::T_DATE, 'api.default' => 'now', ); + $params['trxn_id'] = array( + 'title' => 'Transaction ID', + 'name' => 'trxn_id', + 'type' => CRM_Utils_Type::T_STRING, + ); + $params['payment_processor_id'] = array( + 'description' => ts('Payment processor ID, will be loaded from contribution_recur if not provided'), + 'title' => 'Payment processor ID', + 'name' => 'payment_processor_id', + 'type' => CRM_Utils_Type::T_INT, + ); } diff --git a/tests/phpunit/api/v3/ContributionTest.php b/tests/phpunit/api/v3/ContributionTest.php index 9ee82f1aed..c2d267f6d7 100644 --- a/tests/phpunit/api/v3/ContributionTest.php +++ b/tests/phpunit/api/v3/ContributionTest.php @@ -1323,6 +1323,60 @@ class api_v3_ContributionTest extends CiviUnitTestCase { $mut->stop(); } + /** + * Test repeat contribution successfully creates line items. + */ + function testRepeatTransaction() { + $paymentProcessorID = $this->paymentProcessorCreate(); + $contributionRecur = $this->callAPISuccess('contribution_recur', 'create', array( + 'contact_id' => $this->_individualId, + 'installments' => '12', + 'frequency_interval' => '1', + 'amount' => '500', + 'contribution_status_id' => 1, + 'start_date' => '2012-01-01 00:00:00', + 'currency' => 'USD', + 'frequency_unit' => 'month', + 'payment_processor_id' => $paymentProcessorID, + )); + $originalContribution = $this->callAPISuccess('contribution', 'create', array_merge( + $this->_params, + array('contribution_recur_id' => $contributionRecur['id'])) + ); + + $this->callAPISuccess('contribution', 'repeattransaction', array( + 'original_contribution_id' => $originalContribution['id'], + 'contribution_status_id' => 'Completed', + 'trxn_id' => uniqid(), + )); + $lineItemParams = array( + 'entity_id' => $originalContribution['id'], + 'sequential' => 1, + 'return' => array( + 'entity_table', + 'qty', + 'unit_price', + 'line_total', + 'label', + 'financial_type_id', + 'deductible_amount', + 'price_field_value_id', + 'price_field_id', + ), + ); + $lineItem1 = $this->callAPISuccess('line_item', 'get', array_merge($lineItemParams, array( + 'entity_id' => $originalContribution['id'], + ))); + $lineItem2 = $this->callAPISuccess('line_item', 'get', array_merge($lineItemParams, array( + 'entity_id' => $originalContribution['id'] + 1, + ))); + unset($lineItem1['values'][0]['id'], $lineItem1['values'][0]['entity_id']); + unset($lineItem2['values'][0]['id'], $lineItem2['values'][0]['entity_id']); + $this->assertEquals($lineItem1['values'][0], $lineItem2['values'][0]); + + $this->quickCleanUpFinancialEntities(); + } + /** * Test completing a transaction does not 'mess' with net amount (CRM-15960). */ -- 2.25.1