From 401f654439ba97ad041017308dd75790c7b27d37 Mon Sep 17 00:00:00 2001 From: Eileen McNaughton Date: Thu, 2 Mar 2023 11:48:36 +1300 Subject: [PATCH] Fix bug in tax calculation when recurring overrides with a different value --- CRM/Contribute/BAO/Contribution.php | 19 ++++++++++++++----- tests/phpunit/api/v3/ContributionTest.php | 20 +++++++++++++++----- 2 files changed, 29 insertions(+), 10 deletions(-) diff --git a/CRM/Contribute/BAO/Contribution.php b/CRM/Contribute/BAO/Contribution.php index d1d7afe877..87784ecc73 100644 --- a/CRM/Contribute/BAO/Contribution.php +++ b/CRM/Contribute/BAO/Contribution.php @@ -2162,20 +2162,29 @@ LEFT JOIN civicrm_contribution contribution ON ( componentPayment.contribution_ * Gaps in the above ( * * @param array $input - * Keys are all optional, if not supplied the template contribution's values are used. - * The template contribution is either the actual template or the latest added contribution - * for the ContributionRecur specified in $contributionParams['contribution_recur_id']. * - total_amount * - financial_type_id * - campaign_id * + * These keys are all optional, and are combined with the values from the contribution_recur + * record to override values from the template contribution. Overrides are + * subject to the following limitations + * 1) the campaign id & is_test always apply (is_test is available on the recurring but not as input) + * 2) the total amount & financial type ID overrides ONLY apply if the contribution has + * only one line item. + * + * The template contribution is derived from a contribution linked to + * the recurring contribution record. A true template contribution is only used + * as a template and is_template is set to TRUE. If this cannot be found the latest added contribution + * is used. + * * @param array $contributionParams * * @return bool|array * @throws \CRM_Core_Exception * @throws \Civi\API\Exception\UnauthorizedException * @todo - * 1) many processors still call repeattransaction with contribution_status_id = Completed + * * 2) repeattransaction code is current munged into completeTransaction code for historical bad coding reasons * 3) Repeat transaction duplicates rather than calls Order.create * 4) Use of payment.create still limited - completetransaction is more common. @@ -2192,7 +2201,7 @@ LEFT JOIN civicrm_contribution contribution ON ( componentPayment.contribution_ $contributionParams['line_item'] = $templateContribution['line_item']; $contributionParams['status_id'] = 'Pending'; - foreach (['contact_id', 'campaign_id', 'financial_type_id', 'currency', 'source', 'amount_level', 'address_id', 'on_behalf', 'source_contact_id', 'tax_amount', 'contribution_page_id', 'total_amount'] as $fieldName) { + foreach (['contact_id', 'campaign_id', 'financial_type_id', 'currency', 'source', 'amount_level', 'address_id', 'on_behalf', 'source_contact_id', 'contribution_page_id', 'total_amount'] as $fieldName) { if (isset($templateContribution[$fieldName])) { $contributionParams[$fieldName] = $templateContribution[$fieldName]; } diff --git a/tests/phpunit/api/v3/ContributionTest.php b/tests/phpunit/api/v3/ContributionTest.php index f41051ef5f..31d78c24c4 100644 --- a/tests/phpunit/api/v3/ContributionTest.php +++ b/tests/phpunit/api/v3/ContributionTest.php @@ -4788,12 +4788,10 @@ class api_v3_ContributionTest extends CiviUnitTestCase { * Test Repeat Transaction Contribution with Tax amount. * * https://lab.civicrm.org/dev/core/issues/806 - * - * @throws \CRM_Core_Exception */ public function testRepeatContributionWithTaxAmount(): void { $this->enableTaxAndInvoicing(); - $financialType = $this->callAPISuccess('financial_type', 'create', [ + $financialType = $this->callAPISuccess('FinancialType', 'create', [ 'name' => 'Test taxable financial Type', 'is_reserved' => 0, 'is_active' => 1, @@ -4806,7 +4804,7 @@ class api_v3_ContributionTest extends CiviUnitTestCase { 'financial_type_id' => $financialType['id'], ] ); - $this->callAPISuccess('contribution', 'repeattransaction', [ + $this->callAPISuccess('Contribution', 'repeattransaction', [ 'original_contribution_id' => $contribution['id'], 'contribution_status_id' => 'Completed', 'trxn_id' => 'test', @@ -4824,9 +4822,21 @@ class api_v3_ContributionTest extends CiviUnitTestCase { $this->assertEquals($lineItem['line_total'], $taxExclusiveAmount); } $this->callAPISuccessGetCount('Contribution', [], 2); + $this->callAPISuccess('ContributionRecur', 'create', [ + 'id' => $contribution['contribution_recur_id'], + 'amount' => 200, + ]); + $this->callAPISuccess('Contribution', 'repeattransaction', [ + 'original_contribution_id' => $contribution['id'], + 'contribution_status_id' => 'Completed', + 'trxn_id' => 'test-2', + ]); + $contribution = $this->callAPISuccessGetSingle('Contribution', ['sequential' => 1, 'trxn_id' => 'test-2', 'return' => ['total_amount', 'tax_amount']]); + $this->assertEquals(200, $contribution['total_amount']); + $this->assertEquals(18.18, $contribution['tax_amount']); } - public function testGetCurrencyOptions() { + public function testGetCurrencyOptions(): void { $result = $this->callAPISuccess('Contribution', 'getoptions', [ 'field' => 'currency', ]); -- 2.25.1