From: Eileen McNaughton Date: Thu, 7 May 2015 04:35:01 +0000 (+1200) Subject: CRM-16397 handle changes to contribution amount in repeattransaction api X-Git-Url: https://vcs.fsf.org/?a=commitdiff_plain;h=96f0fe0db19599ff445f4287e2b47fe3fed88f04;p=civicrm-core.git CRM-16397 handle changes to contribution amount in repeattransaction api --- diff --git a/CRM/Core/Payment/BaseIPN.php b/CRM/Core/Payment/BaseIPN.php index b9c52bfd59..162d3043c2 100644 --- a/CRM/Core/Payment/BaseIPN.php +++ b/CRM/Core/Payment/BaseIPN.php @@ -634,7 +634,20 @@ LIMIT 1;"; $isNewContribution = FALSE; if (empty($contribution->id)) { $isNewContribution = TRUE; + if (!empty($input['amount']) && $input['amount'] != $contribution->total_amount) { + $contribution->total_amount = $input['amount']; + // The BAO does this stuff but we are actually kinda bypassing it here (bad code! go sit in the corner) + // so we have to handle net_amount in this (naughty) code. + if (isset($input['fee_amount']) && is_numeric($input['fee_amount'])) { + $contribution->fee_amount = $input['fee_amount']; + } + $contribution->net_amount = $contribution->total_amount - $contribution->fee_amount; + } + if (!empty($input['campaign_id'])) { + $contribution->campaign_id = $input['campaign_id']; + } } + $contributionStatuses = CRM_Core_PseudoConstant::get('CRM_Contribute_DAO_Contribution', 'contribution_status_id', array( 'labelColumn' => 'name', 'flip' => 1, @@ -672,6 +685,7 @@ LIMIT 1;"; $contributionId['id'] = $contribution->id; $input['prevContribution'] = CRM_Contribute_BAO_Contribution::getValues($contributionId, CRM_Core_DAO::$_nullArray, CRM_Core_DAO::$_nullArray); } + $contribution->save(); // Add new soft credit against current $contribution. @@ -1073,12 +1087,23 @@ LIMIT 1;"; $originalContributionID = CRM_Core_DAO::getFieldValue('CRM_Contribute_DAO_Contribution', $recurId, 'id', 'contribution_recur_id'); $lineItems = CRM_Price_BAO_LineItem::getLineItemsByContributionID($originalContributionID); + if (count($lineItems) == 1) { + foreach ($lineItems as $index => $lineItem) { + if ($lineItem['line_total'] != $contribution->total_amount) { + // We are dealing with a changed amount! Per CRM-16397 we can work out what to do with these + // if there is only one line item, and the UI should prevent this situation for those with more than one. + $lineItems[$index]['line_total'] = $contribution->total_amount; + $lineItems[$index]['unit_price'] = round($contribution->total_amount / $lineItems[$index]['qty'], 2); + } + } + } if (!empty($lineItems)) { foreach ($lineItems as $key => $value) { $priceField = new CRM_Price_DAO_PriceField(); $priceField->id = $value['price_field_id']; $priceField->find(TRUE); $lineSets[$priceField->price_set_id][] = $value; + if ($value['entity_table'] == 'civicrm_membership') { try { civicrm_api3('membership_payment', 'create', array( diff --git a/api/v3/Contribution.php b/api/v3/Contribution.php index 136a4ea83c..b19302837e 100644 --- a/api/v3/Contribution.php +++ b/api/v3/Contribution.php @@ -501,8 +501,9 @@ function civicrm_api3_contribution_repeattransaction(&$params) { unset($contribution->id, $contribution->receive_date, $contribution->invoice_id); $contribution->contribution_status_id = $params['contribution_status_id']; $contribution->receive_date = $params['receive_date']; - // Have not set trxn_id to required but an e-notice if not provided seems appropriate. - $input['trxn_id'] = $params['trxn_id']; + + $passThroughParams = array('trxn_id', 'total_amount', 'campaign_id', 'fee_amount'); + $input = array_intersect_key($params, array_fill_keys($passThroughParams, NULL)); $params = _ipn_process_transaction($params, $contribution, $input, $ids, $original_contribution); } @@ -536,7 +537,8 @@ function _ipn_process_transaction(&$params, $contribution, $input, $ids, $firstC } $input['component'] = $contribution->_component; $input['is_test'] = $contribution->is_test; - $input['amount'] = $contribution->total_amount; + $input['amount'] = empty($input['total_amount']) ? $contribution->total_amount : $input['total_amount']; + if (isset($params['is_email_receipt'])) { $input['is_email_receipt'] = $params['is_email_receipt']; }