From 6dde7f043a950809895436bc7f48b17c3f5cbfdc Mon Sep 17 00:00:00 2001 From: "deb.monish" Date: Fri, 6 Oct 2017 17:27:13 +0530 Subject: [PATCH] CRM-21245: Incorrect Contribution status 'Pending Refund' and Add test of CRM-17151 ported from kainuk PR --- CRM/Event/Form/ParticipantFeeSelection.php | 2 +- CRM/Member/Form/Membership.php | 5 +- CRM/Price/BAO/LineItem.php | 52 ++++++++++--------- ...273Test.php => ChangeFeeSelectionTest.php} | 47 +++++++++++++++-- tests/phpunit/CiviTest/CiviUnitTestCase.php | 2 +- 5 files changed, 73 insertions(+), 35 deletions(-) rename tests/phpunit/CRM/Event/BAO/{CRM19273Test.php => ChangeFeeSelectionTest.php} (82%) diff --git a/CRM/Event/Form/ParticipantFeeSelection.php b/CRM/Event/Form/ParticipantFeeSelection.php index aab0a8375da3..e4ec1597137a 100644 --- a/CRM/Event/Form/ParticipantFeeSelection.php +++ b/CRM/Event/Form/ParticipantFeeSelection.php @@ -239,7 +239,7 @@ public function postProcess() { $feeBlock = $this->_values['fee']; $lineItems = $this->_values['line_items']; - CRM_Price_BAO_LineItem::changeFeeSelections($params, $this->_participantId, 'participant', $this->_contributionId, $feeBlock, $lineItems, $this->_paidAmount); + CRM_Price_BAO_LineItem::changeFeeSelections($params, $this->_participantId, 'participant', $this->_contributionId, $feeBlock, $lineItems); $this->contributionAmt = CRM_Core_DAO::getFieldValue('CRM_Contribute_BAO_Contribution', $this->_contributionId, 'total_amount'); // email sending if (!empty($params['send_receipt'])) { diff --git a/CRM/Member/Form/Membership.php b/CRM/Member/Form/Membership.php index acb14746d658..cf84532b7291 100644 --- a/CRM/Member/Form/Membership.php +++ b/CRM/Member/Form/Membership.php @@ -1730,8 +1730,7 @@ protected function updateContributionOnMembershipTypeChange($inputParams, $membe // add price field information in $inputParams self::addPriceFieldByMembershipType($inputParams, $priceSetDetails['fields'], $membership->membership_type_id); - // paid amount - $paidAmount = CRM_Utils_Array::value('paid', CRM_Contribute_BAO_Contribution::getPaymentInfo($membership->id, 'membership')); + // update related contribution and financial records CRM_Price_BAO_LineItem::changeFeeSelections( $inputParams, @@ -1739,7 +1738,7 @@ protected function updateContributionOnMembershipTypeChange($inputParams, $membe 'membership', $contributionID, $priceSetDetails['fields'], - $lineItems, $paidAmount + $lineItems ); CRM_Core_Session::setStatus(ts('Associated contribution is updated on membership type change.'), ts('Success'), 'success'); } diff --git a/CRM/Price/BAO/LineItem.php b/CRM/Price/BAO/LineItem.php index 93c6f3eb404e..d838029b0965 100644 --- a/CRM/Price/BAO/LineItem.php +++ b/CRM/Price/BAO/LineItem.php @@ -611,7 +611,6 @@ public static function getLineItemArray(&$params, $entityId = NULL, $entityTable * @param int $contributionId * @param $feeBlock * @param array $lineItems - * @param $paidAmount * */ public static function changeFeeSelections( @@ -620,8 +619,7 @@ public static function changeFeeSelections( $entity, $contributionId, $feeBlock, - $lineItems, - $paidAmount + $lineItems ) { $entityTable = "civicrm_" . $entity; CRM_Price_BAO_PriceSet::processAmount($feeBlock, @@ -694,8 +692,7 @@ public static function changeFeeSelections( if (!empty($amountLevel)) { $updateAmountLevel = CRM_Core_DAO::VALUE_SEPARATOR . implode(CRM_Core_DAO::VALUE_SEPARATOR, $amountLevel) . $displayParticipantCount . CRM_Core_DAO::VALUE_SEPARATOR; } - $trxn = $lineItemObj->recordAdjustedAmt($updatedAmount, $paidAmount, $contributionId, $taxAmount, $updateAmountLevel); - + $trxn = $lineItemObj->_recordAdjustedAmt($updatedAmount, $contributionId, $taxAmount, $updateAmountLevel); $contributionStatus = CRM_Core_PseudoConstant::getName('CRM_Contribute_DAO_Contribution', 'contribution_status_id', CRM_Core_DAO::getFieldValue('CRM_Contribute_DAO_Contribution', $contributionId, 'contribution_status_id')); if (!empty($financialItemsArray)) { @@ -1034,18 +1031,23 @@ protected function updateEntityRecordOnChangeFeeSelection($inputParams, $entityI * @return array $financialTrxn * */ - protected function getRelatedCancelFinancialTrxn($financialItemID) { - $financialTrxn = civicrm_api3('EntityFinancialTrxn', 'getsingle', array( - 'entity_table' => 'civicrm_financial_item', - 'entity_id' => $financialItemID, - 'options' => array( - 'sort' => 'id DESC', - 'limit' => 1, - ), - 'api.FinancialTrxn.getsingle' => array( - 'id' => "\$value.financial_trxn_id", - ), - )); + protected function _getRelatedCancelFinancialTrxn($financialItemID) { + try { + $financialTrxn = civicrm_api3('EntityFinancialTrxn', 'getsingle', array( + 'entity_table' => 'civicrm_financial_item', + 'entity_id' => $financialItemID, + 'options' => array( + 'sort' => 'id DESC', + 'limit' => 1, + ), + 'api.FinancialTrxn.getsingle' => array( + 'id' => "\$value.financial_trxn_id", + ), + )); + } + catch (CiviCRM_API3_Exception $e) { + return array(); + } $financialTrxn = array_merge($financialTrxn['api.FinancialTrxn.getsingle'], array( 'trxn_date' => date('YmdHis'), @@ -1063,21 +1065,15 @@ protected function getRelatedCancelFinancialTrxn($financialItemID) { * Record adjusted amount. * * @param int $updatedAmount - * @param int $paidAmount * @param int $contributionId - * * @param int $taxAmount * @param bool $updateAmountLevel * * @return bool|\CRM_Core_BAO_FinancialTrxn */ - protected function recordAdjustedAmt($updatedAmount, $paidAmount, $contributionId, $taxAmount = NULL, $updateAmountLevel = NULL) { - $pendingAmount = CRM_Core_BAO_FinancialTrxn::getBalanceTrxnAmt($contributionId); - $pendingAmount = CRM_Utils_Array::value('total_amount', $pendingAmount, 0); + protected function _recordAdjustedAmt($updatedAmount, $contributionId, $taxAmount = NULL, $updateAmountLevel = NULL) { + $paidAmount = CRM_Core_BAO_FinancialTrxn::getTotalPayments($contributionId); $balanceAmt = $updatedAmount - $paidAmount; - if ($paidAmount != $pendingAmount) { - $balanceAmt -= $pendingAmount; - } $contributionStatuses = CRM_Contribute_PseudoConstant::contributionStatus(NULL, 'name'); $partiallyPaidStatusId = array_search('Partially paid', $contributionStatuses); @@ -1132,6 +1128,12 @@ protected function recordAdjustedAmt($updatedAmount, $paidAmount, $contributionI ); $adjustedTrxn = CRM_Core_BAO_FinancialTrxn::create($adjustedTrxnValues); } + // CRM-17151: Update the contribution status to completed if balance is zero, + // because due to sucessive fee change will leave the related contribution status incorrect + else { + CRM_Core_DAO::setFieldValue('CRM_Contribute_DAO_Contribution', $contributionId, 'contribution_status_id', $completedStatusId); + } + return $adjustedTrxn; } diff --git a/tests/phpunit/CRM/Event/BAO/CRM19273Test.php b/tests/phpunit/CRM/Event/BAO/ChangeFeeSelectionTest.php similarity index 82% rename from tests/phpunit/CRM/Event/BAO/CRM19273Test.php rename to tests/phpunit/CRM/Event/BAO/ChangeFeeSelectionTest.php index 1caaa49a5a86..894c6011975c 100644 --- a/tests/phpunit/CRM/Event/BAO/CRM19273Test.php +++ b/tests/phpunit/CRM/Event/BAO/ChangeFeeSelectionTest.php @@ -3,7 +3,7 @@ * Class CRM_Event_BAO_AdditionalPaymentTest * @group headless */ -class CRM_Event_BAO_CRM19273Test extends CiviUnitTestCase { +class CRM_Event_BAO_ChangeFeeSelectionTest extends CiviUnitTestCase { protected $_priceSetID; protected $_cheapFee = 80; @@ -252,18 +252,32 @@ public function testCRM19273() { $this->balanceCheck($this->_veryExpensive); } + /** + * CRM-21245: Test that Contribution status doesn't changed to 'Pending Refund' from 'Partially Paid' if the partially paid amount is lower then newly selected fee amount + */ + public function testCRM21245() { + $this->registerParticipantAndPay(50); + $partiallyPaidContribuitonStatus = CRM_Core_PseudoConstant::getKey('CRM_Contribute_BAO_Contribution', 'contribution_status_id', 'Partially paid'); + $this->assertEquals($this->callAPISuccessGetValue('Contribution', array('id' => $this->_contributionId, 'return' => 'contribution_status_id')), $partiallyPaidContribuitonStatus); + + $priceSetParams['price_1'] = 3; + $lineItem = CRM_Price_BAO_LineItem::getLineItems($this->_participantId, 'participant'); + CRM_Price_BAO_LineItem::changeFeeSelections($priceSetParams, $this->_participantId, 'participant', $this->_contributionId, $this->_feeBlock, $lineItem); + $this->assertEquals($this->callAPISuccessGetValue('Contribution', array('id' => $this->_contributionId, 'return' => 'contribution_status_id')), $partiallyPaidContribuitonStatus); + } + /** * Test that proper financial items are recorded for cancelled line items */ public function testCRM20611() { $priceSetParams['price_1'] = 1; - $lineItem = CRM_Price_BAO_LineItem::getLineItems($this->_participantId, 'participant'); - CRM_Price_BAO_LineItem::changeFeeSelections($priceSetParams, $this->_participantId, 'participant', $this->_contributionId, $this->_feeBlock, $lineItem, $this->_expensiveFee); + $lineItem = CRM_Price_BAO_LineItem::getLineItems($this->participantID, 'participant'); + CRM_Price_BAO_LineItem::changeFeeSelections($priceSetParams, $this->_participantId, 'participant', $this->_contributionId, $this->_feeBlock, $lineItem); $this->balanceCheck($this->_expensiveFee); $priceSetParams['price_1'] = 2; - $lineItem = CRM_Price_BAO_LineItem::getLineItems($this->_participantId, 'participant'); - CRM_Price_BAO_LineItem::changeFeeSelections($priceSetParams, $this->_participantId, 'participant', $this->_contributionId, $this->_feeBlock, $lineItem, $this->_expensiveFee); + $lineItem = CRM_Price_BAO_LineItem::getLineItems($this->participantID, 'participant'); + CRM_Price_BAO_LineItem::changeFeeSelections($priceSetParams, $this->_participantId, 'participant', $this->_contributionId, $this->_feeBlock, $lineItem); $this->balanceCheck($this->_cheapFee); //Complete the refund payment. @@ -405,4 +419,27 @@ public function testCRM21513() { $this->balanceCheck(20); } + /** + * CRM-17151: Test that Contribution status change to 'Completed' if balance is zero. + */ + public function testCRM17151() { + $contributionStatuses = CRM_Contribute_PseudoConstant::contributionStatus(NULL, 'name'); + $partiallyPaidStatusId = array_search('Partially paid', $contributionStatuses); + $pendingRefundStatusId = array_search('Pending refund', $contributionStatuses); + $completedStatusId = array_search('Completed', $contributionStatuses); + $this->assertDBCompareValue('CRM_Contribute_BAO_Contribution', $this->_contributionId, 'contribution_status_id', 'id', $completedStatusId, 'Payment t be completed'); + $priceSetParams['price_1'] = 2; + $lineItem = CRM_Price_BAO_LineItem::getLineItems($this->_participantId, 'participant'); + CRM_Price_BAO_LineItem::changeFeeSelections($priceSetParams, $this->_participantId, 'participant', $this->_contributionId, $this->_feeBlock, $lineItem); + $this->assertDBCompareValue('CRM_Contribute_BAO_Contribution', $this->_contributionId, 'contribution_status_id', 'id', $pendingRefundStatusId, 'Contribution must be refunding'); + $priceSetParams['price_1'] = 1; + $lineItem = CRM_Price_BAO_LineItem::getLineItems($this->_participantId, 'participant'); + CRM_Price_BAO_LineItem::changeFeeSelections($priceSetParams, $this->_participantId, 'participant', $this->_contributionId, $this->_feeBlock, $lineItem); + $this->assertDBCompareValue('CRM_Contribute_BAO_Contribution', $this->_contributionId, 'contribution_status_id', 'id', $completedStatusId, 'Contribution must, after complete payment be in state completed'); + $priceSetParams['price_1'] = 3; + $lineItem = CRM_Price_BAO_LineItem::getLineItems($this->_participantId, 'participant'); + CRM_Price_BAO_LineItem::changeFeeSelections($priceSetParams, $this->_participantId, 'participant', $this->_contributionId, $this->_feeBlock, $lineItem); + $this->assertDBCompareValue('CRM_Contribute_BAO_Contribution', $this->_contributionId, 'contribution_status_id', 'id', $partiallyPaidStatusId, 'Partial Paid'); + } + } diff --git a/tests/phpunit/CiviTest/CiviUnitTestCase.php b/tests/phpunit/CiviTest/CiviUnitTestCase.php index be424eb7c622..6a720653c239 100644 --- a/tests/phpunit/CiviTest/CiviUnitTestCase.php +++ b/tests/phpunit/CiviTest/CiviUnitTestCase.php @@ -552,7 +552,7 @@ public function assertDBCompareValue( $expectedValue, $message ) { $value = CRM_Core_DAO::getFieldValue($daoName, $searchValue, $returnColumn, $searchColumn, TRUE); - $this->assertEquals($value, $expectedValue, $message); + $this->assertEquals($expectedValue, $value, $message); } /**