From 61feab9ba170813158217db1e9ea328e3dcbcc82 Mon Sep 17 00:00:00 2001 From: Monish Deb Date: Mon, 19 Nov 2018 19:11:06 +0530 Subject: [PATCH] fix partial payment scenario --- CRM/Contribute/BAO/Contribution.php | 23 +++-- .../CRM/Contribute/BAO/ContributionTest.php | 93 ++++++++++++------- .../CRM/Event/Form/ParticipantTest.php | 29 +++++- tests/phpunit/api/v3/PaymentTest.php | 2 +- 4 files changed, 100 insertions(+), 47 deletions(-) diff --git a/CRM/Contribute/BAO/Contribution.php b/CRM/Contribute/BAO/Contribution.php index fa19c6f01b9..24f0efec9b2 100644 --- a/CRM/Contribute/BAO/Contribution.php +++ b/CRM/Contribute/BAO/Contribution.php @@ -4931,7 +4931,7 @@ public static function assignProportionalLineItems($trxnParams, $trxnId, $contri if (!empty($lineItems)) { // get financial item list($financialItems, $taxItems) = self::getLastFinancialItems($trxnParams['contribution_id']); - self::createProportionalFinancialEntries($trxnId, $lineItems, $financialItems, $taxItems); + self::createProportionalFinancialEntries($trxnId, $contributionTotalAmount, $lineItems, $financialItems, $taxItems); } } @@ -5761,32 +5761,39 @@ public static function getLastFinancialItems($contributionId) { * Create proportional entries in civicrm_entity_financial_trxn. * * @param int $trxnID - * + * @param float $trxnID$contributionTotalAmount * @param array $lineItems - * * @param array $financialItems - * * @param array $taxItems * */ - public static function createProportionalFinancialEntries($trxnID, $lineItems, $financialItems, $taxItems) { + public static function createProportionalFinancialEntries($trxnID, $contributionTotalAmount, $lineItems, $financialItems, $taxItems) { $eftParams = array( 'entity_table' => 'civicrm_financial_item', 'financial_trxn_id' => $trxnID, ); + $financialTxnAmount = CRM_Core_DAO::getFieldValue('CRM_Financial_DAO_FinancialTrxn', $trxnID, 'total_amount'); foreach ($lineItems as $key => $value) { if ($value['qty'] == 0) { continue; } $eftParams['entity_id'] = $financialItems[$value['price_field_value_id']]['financial_item_id']; - $eftParams['amount'] = $financialItems[$value['price_field_value_id']]['amount']; - if (0 == civicrm_api3('EntityFinancialTrxn', 'getcount', ['entity_table' => 'civicrm_financial_item', 'entity_id' => $eftParams['entity_id']])) { + + // In case of partial payment, calculate proportional amount for each line-item and created respective EFT records + if ($value['line_total'] == $financialItems[$value['price_field_value_id']]['amount']) { + $eftParams['amount'] = CRM_Contribute_BAO_Contribution_Utils::formatAmount($financialItems[$value['price_field_value_id']]['amount'] * ($financialTxnAmount / $contributionTotalAmount)); + } + // Else for price change, allocate financial item amount as EFT amount + else { + $eftParams['amount'] = $financialItems[$value['price_field_value_id']]['amount']; + } + if (0 == civicrm_api3('EntityFinancialTrxn', 'getcount', ['entity_table' => 'civicrm_financial_item', 'entity_id' => $eftParams['entity_id'], 'financial_trxn_id' => $trxnID])) { civicrm_api3('EntityFinancialTrxn', 'create', $eftParams); } if (array_key_exists($value['price_field_value_id'], $taxItems)) { $eftParams['entity_id'] = $taxItems[$value['price_field_value_id']]['financial_item_id']; $eftParams['amount'] = $taxItems[$value['price_field_value_id']]['amount']; - if (0 == civicrm_api3('EntityFinancialTrxn', 'getcount', ['entity_table' => 'civicrm_financial_item', 'entity_id' => $eftParams['entity_id']])) { + if (0 == civicrm_api3('EntityFinancialTrxn', 'getcount', ['entity_table' => 'civicrm_financial_item', 'entity_id' => $eftParams['entity_id'], 'financial_trxn_id' => $trxnID])) { civicrm_api3('EntityFinancialTrxn', 'create', $eftParams); } } diff --git a/tests/phpunit/CRM/Contribute/BAO/ContributionTest.php b/tests/phpunit/CRM/Contribute/BAO/ContributionTest.php index fa9d7ef73d2..4e2d4327d66 100644 --- a/tests/phpunit/CRM/Contribute/BAO/ContributionTest.php +++ b/tests/phpunit/CRM/Contribute/BAO/ContributionTest.php @@ -1189,19 +1189,30 @@ public function testgetSalesTaxFinancialAccounts() { public function testCreateProportionalFinancialEntries($thousandSeparator) { $this->setCurrencySeparators($thousandSeparator); list($contribution, $financialAccount) = $this->createContributionWithTax(); - $params = array( - 'total_amount' => 55, - 'to_financial_account_id' => $financialAccount->financial_account_id, - 'payment_instrument_id' => 1, - 'trxn_date' => date('Ymd'), - 'status_id' => 1, + + $this->callAPISuccess('Contribution', 'create', [ + 'id' => $contribution['id'], + 'total_amount' => 150, + ]); + // Retrieve the created financial trxn ID from EntityFinancialTrxn mapping + $financialTrxnID = $this->callAPISuccess('EntityFinancialTrxn', 'getvalue', [ + 'entity_table' => 'civicrm_contribution', 'entity_id' => $contribution['id'], - ); - $financialTrxn = $this->callAPISuccess('FinancialTrxn', 'create', $params); + 'return' => 'financial_trxn_id', + 'options' => [ + 'sort' => 'id desc', + 'limit' => 1 + ], + ]); $lineItems = CRM_Price_BAO_LineItem::getLineItemsByContributionID($contribution['id']); list($financialItems, $taxItems) = CRM_Contribute_BAO_Contribution::getLastFinancialItems($contribution['id']); - CRM_Contribute_BAO_Contribution::createProportionalFinancialEntries($financialTrxn['id'], $lineItems, $financialItems, $taxItems); + CRM_Contribute_BAO_Contribution::createProportionalFinancialEntries($financialTrxnID, $contribution['total_amount'], $lineItems, $financialItems, $taxItems); + $eftParams = array( + 'entity_table' => 'civicrm_financial_item', + 'entity_id' => $financialItems[1]['financial_item_id'], + 'financial_trxn_id' => $financialTrxnID, + ); $trxnTestArray = array_merge($eftParams, array( 'amount' => '50.00', )); @@ -1218,22 +1229,32 @@ public function testCreateProportionalFinancialEntries($thousandSeparator) { */ public function testCreateProportionalFinancialEntriesZeroAmount($thousandSeparator) { $this->setCurrencySeparators($thousandSeparator); - list($contribution, $financialAccount) = $this->createContributionWithTax(array('total_amount' => 0)); - $params = array( + list($contribution, $financialAccount) = $this->createContributionWithTax(); + $this->callAPISuccess('Contribution', 'create', [ + 'id' => $contribution['id'], 'total_amount' => 0, - 'to_financial_account_id' => $financialAccount->financial_account_id, - 'payment_instrument_id' => 1, - 'trxn_date' => date('Ymd'), - 'status_id' => 1, + ]); + // Retrieve the created financial trxn ID from EntityFinancialTrxn mapping + $financialTrxnID = $this->callAPISuccess('EntityFinancialTrxn', 'getvalue', [ + 'entity_table' => 'civicrm_contribution', 'entity_id' => $contribution['id'], - ); - $financialTrxn = $this->callAPISuccess('FinancialTrxn', 'create', $params); + 'return' => 'financial_trxn_id', + 'options' => [ + 'sort' => 'id desc', + 'limit' => 1 + ], + ]); $lineItems = CRM_Price_BAO_LineItem::getLineItemsByContributionID($contribution['id']); list($financialItems, $taxItems) = CRM_Contribute_BAO_Contribution::getLastFinancialItems($contribution['id']); - CRM_Contribute_BAO_Contribution::createProportionalFinancialEntries($financialTrxn['id'], $lineItems, $financialItems, $taxItems); + CRM_Contribute_BAO_Contribution::createProportionalFinancialEntries($financialTrxnID, $contribution['total_amount'], $lineItems, $financialItems, $taxItems); + $eftParams = array( + 'entity_table' => 'civicrm_financial_item', + 'entity_id' => $financialItems[1]['financial_item_id'], + 'financial_trxn_id' => $financialTrxnID, + ); $trxnTestArray = array_merge($eftParams, array( - 'amount' => '0.00', + 'amount' => '-100.00', )); $this->callAPISuccessGetSingle('EntityFinancialTrxn', $eftParams, $trxnTestArray); } @@ -1255,28 +1276,32 @@ public function testgetLastFinancialItems() { * Test for function createProportionalFinancialEntries(). */ public function testCreateProportionalEntityFinancialEntries() { + // create a contribution with $100 and with 10% tax which is $10 list($contribution, $financialAccount) = $this->createContributionWithTax(); - $params = array( - 'total_amount' => 50, - 'to_financial_account_id' => $financialAccount->financial_account_id, - 'payment_instrument_id' => 1, - 'trxn_date' => date('Ymd'), - 'status_id' => 1, + + // Update the contribution to $150 to ensure that a new financialTrxn of $55 (that includes tax amount) is created + // linked with two financial items of amount $50 and $5 respectively + $this->callAPISuccess('Contribution', 'create', [ + 'id' => $contribution['id'], + 'total_amount' => 150, + ]); + // Retrieve the created financial trxn ID from EntityFinancialTrxn mapping + $financialTrxnID = $this->callAPISuccess('EntityFinancialTrxn', 'getvalue', [ + 'entity_table' => 'civicrm_contribution', 'entity_id' => $contribution['id'], - ); - $financialTrxn = $this->callAPISuccess('FinancialTrxn', 'create', $params); - $entityParams = array( - 'contribution_total_amount' => $contribution['total_amount'], - 'trxn_total_amount' => 55, - 'trxn_id' => $financialTrxn['id'], - ); + 'return' => 'financial_trxn_id', + 'options' => [ + 'sort' => 'id desc', + 'limit' => 1 + ], + ]); $lineItems = CRM_Price_BAO_LineItem::getLineItemsByContributionID($contribution['id']); list($financialItems, $taxItems) = CRM_Contribute_BAO_Contribution::getLastFinancialItems($contribution['id']); - CRM_Contribute_BAO_Contribution::createProportionalFinancialEntries($financialTrxn['id'], $lineItems, $financialItems, $taxItems); + CRM_Contribute_BAO_Contribution::createProportionalFinancialEntries($financialTrxnID, $contribution['total_amount'], $lineItems, $financialItems, $taxItems); $eftParams = array( 'entity_table' => 'civicrm_financial_item', - 'financial_trxn_id' => $financialTrxn['id'], + 'financial_trxn_id' => $financialTrxnID, ); $entityFinancialTrxn = $this->callAPISuccess('EntityFinancialTrxn', 'Get', $eftParams); $this->assertEquals($entityFinancialTrxn['count'], 2, 'Invalid count.'); diff --git a/tests/phpunit/CRM/Event/Form/ParticipantTest.php b/tests/phpunit/CRM/Event/Form/ParticipantTest.php index 90ac98f2dfd..9af89679584 100644 --- a/tests/phpunit/CRM/Event/Form/ParticipantTest.php +++ b/tests/phpunit/CRM/Event/Form/ParticipantTest.php @@ -128,7 +128,7 @@ public function testPaymentAllocationOnMultiLineItemEvent() { // Create financial type - Event Fee 2 $form = $this->getForm(array('is_monetary' => 1, 'financial_type_id' => 1)); - $newFinancialTypeID = $this->createFinancialType('Event Fee 2')['id']; + CRM_Financial_BAO_FinancialType::getAvailableFinancialTypes($financialTypes); $paramsField = array( 'label' => 'Price Field 2', 'name' => CRM_Utils_String::titleToVar('Price Field 2'), @@ -145,7 +145,7 @@ public function testPaymentAllocationOnMultiLineItemEvent() { 'is_active' => array('1' => 1), 'price_set_id' => $this->_ids['price_set'], 'is_enter_qty' => 1, - 'financial_type_id' => $newFinancialTypeID, + 'financial_type_id' => array_search('Campaign Contribution', $financialTypes), ); // Create price set and its price fields $this->_ids['price_field'][] = CRM_Price_BAO_PriceField::create($paramsField)->id; @@ -194,9 +194,30 @@ public function testPaymentAllocationOnMultiLineItemEvent() { ), ); $form->setAction(CRM_Core_Action::ADD); + print_r(array( + 'register_date' => date('Ymd'), + 'status_id' => 5, + 'role_id' => 1, + 'event_id' => $form->_eventId, + 'priceSetId' => $this->_ids['price_set'], + 'price_' . $this->_ids['price_field'][0] => array( + $this->_ids['price_field_value'][0] => 1, + ), + 'price_' . $this->_ids['price_field'][1] => array( + $this->_ids['price_field_value'][1] => 1, + ), + 'amount_level' => 'Too much', + 'fee_amount' => 65, + 'total_amount' => 65, + 'payment_processor_id' => 0, + 'record_contribution' => TRUE, + 'financial_type_id' => 1, + 'contribution_status_id' => CRM_Core_PseudoConstant::getKey('CRM_Contribute_BAO_Contribution', 'contribution_status_id', 'Completed'), + 'payment_instrument_id' => CRM_Core_PseudoConstant::getKey('CRM_Contribute_BAO_Contribution', 'payment_instrument_id', 'Check'), + )); + $form->submit(array( - 'register_date' => 'now', - 'register_date_time' => '00:00:00', + 'register_date' => date('Ymd'), 'status_id' => 5, 'role_id' => 1, 'event_id' => $form->_eventId, diff --git a/tests/phpunit/api/v3/PaymentTest.php b/tests/phpunit/api/v3/PaymentTest.php index 025c1166b14..780c6b80309 100644 --- a/tests/phpunit/api/v3/PaymentTest.php +++ b/tests/phpunit/api/v3/PaymentTest.php @@ -426,7 +426,7 @@ public function testUpdatePayment() { 'financial_trxn_id' => $payment['id'], ); $eft = $this->callAPISuccess('EntityFinancialTrxn', 'get', $params); - $amounts = array(66.67, 33.33); + $amounts = array(-33.33, -16.67); foreach ($eft['values'] as $value) { $this->assertEquals($value['amount'], array_pop($amounts)); }