Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP]CRM-19585, Sales tax fixes #9340

Closed
wants to merge 13 commits into from

Conversation

pradpnayak
Copy link
Contributor

@pradpnayak pradpnayak commented Oct 31, 2016

@pradpnayak pradpnayak force-pushed the CRM-19585 branch 2 times, most recently from 17443f8 to 857fd8a Compare November 2, 2016 09:21
@omarabuhussein
Copy link
Member

omarabuhussein commented Nov 15, 2016

hi @pradpnayak ... I've been assigned to review this ticket so hopefully we can get it to be merged to the next release together .

So first thing caught my eye is the lack documentation .. it appear that you have fixed multiple issues with sales tax so can you please describe the issues you fixed in this PR in more details inside the PR description and copy it to the ticket on jira , otherwise no one will now what is going on and why you made these changes in case something break later .

another thing is the lack of unit tests ... I know it probably not required for civicrm-core PRs to have unit tests and actually some parts of civi are very hard or even impossible to test but I think your changes are testable so can you please add some tests .

I will leave the rest of my notes on the code itself during this week .

@@ -374,7 +374,8 @@ public static function calculateMissingAmountParams(&$params, $contributionID) {
$params['fee_amount'] = 0;
}
}
if (!isset($params['net_amount'])) {
// recalculate net amount if tax amount is set
Copy link
Member

@omarabuhussein omarabuhussein Nov 15, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this IF condition will be true if ( tax amount is set OR net amount is not set ) .. but this inline comment only talk about tax amount ... so can you please amend this comment to say that . maybe something like :

// recalculate net amount if it is not set or if tax amount is set

@@ -3268,7 +3269,15 @@ public static function recordFinancialAccounts(&$params, $financialTrxnValues =
self::updateFinancialAccounts($params, 'changeFinancialType');
/* $params['trxnParams']['to_financial_account_id'] = $trxnParams['to_financial_account_id']; */
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since you are working on this file can you remove this commented out line

@@ -3268,7 +3269,15 @@ public static function recordFinancialAccounts(&$params, $financialTrxnValues =
self::updateFinancialAccounts($params, 'changeFinancialType');
/* $params['trxnParams']['to_financial_account_id'] = $trxnParams['to_financial_account_id']; */
$params['financial_account_id'] = $newFinancialAccount;
$params['total_amount'] = $params['trxnParams']['total_amount'] = $params['trxnParams']['net_amount'] = $trxnParams['total_amount'];
$changeFTAmount = $trxnParams['total_amount'];
Copy link
Member

@omarabuhussein omarabuhussein Nov 15, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this newly added code can be moved to a new private method called calcluateFTChangeAmount() and rewritten like that , methods should not be big and we should stop adding more lines to them.

list($changeFTAmount, $ignoreChangeAmount) = $this->calcluateFTChangeAmount($params, $trxnParams['total_amount']);


private function calcluateFTChangeAmount($params, $totalAmount) {
    $changeFTAmount = $totalAmount;

    if (isset($params['prevContribution']->total_amount) || isset($params['tax_amount'])) {
      $taxAmount = CRM_Utils_Array::value('tax_amount', $params, 0);
      $changesinTaxAmount = $totalAmount - $params['prevContribution']->total_amount + $params['prevContribution']->tax_amount - $taxAmount;

      if ($changesinTaxAmount == 0) {
        $ignoreChangeAmount = TRUE;
        $changeFTAmount = $totalAmount;
      }
    }

  return array($changeFTAmount, $ignoreChangeAmount);
}

also you could probably rewrite it in better way but the key point is to separate the code into more short logical units to improve readability .. also please do not forget to add a doc block for this new private method in case you implemented it .

@@ -3447,6 +3456,12 @@ public static function updateFinancialAccounts(&$params, $context = NULL, $skipT
}
if ($context == 'changedAmount' || $context == 'changeFinancialType') {
$itemAmount = $params['trxnParams']['total_amount'] = $params['trxnParams']['net_amount'] = $params['total_amount'] - $params['prevContribution']->total_amount;
if (isset($params['prevContribution']->tax_amount)) {
Copy link
Member

@omarabuhussein omarabuhussein Nov 15, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure about the logic here since I don't have enough context .. but shouldn't this be :

if (isset($params['tax_amount'])) {

Copy link
Contributor

@JoeMurray JoeMurray Feb 2, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@pradpnayak @Edzelopez could you reply to each comment explaining how it is addressed or why you don't think it should be? It appears the same changes have been resubmitted as a new PR but the commented code may still appear, eg https://github.com/civicrm/civicrm-core/pull/9682/files#diff-7a5b0e2d131dabc49178460fc63328c0R3453

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @omarabuhussein

The logic here (and below) is intentional. This code here handles the case where a contribution with a taxable financial type is edited to change the financial type to another taxable/non-taxable one. In such a case, previously, the taxes were not subtracted/added to the total amount. The reason why the conditions look reversed is that the taxes usually have reversed mathematical signs. So for example, if the previous total amount was $110 with a contribution of $100 and $10 tax, on changing this to a non-taxable financial type, we would need to subtract the $10. For this reason, we have checked if there was a previous tax applied to a contribution and subtracted it from the new total amount. Similarly, for the next condition, if we have changed the financial type to a new taxable financial type, say amounting to 20% tax, we will need to first subtract the previous tax amount from the contribution to avoid calculating 20% on $110 rather than $100.

HTH,
Edsel

if (isset($params['prevContribution']->tax_amount)) {
$itemAmount -= CRM_Utils_Array::value('tax_amount', $params, 0);
}
if (isset($params['tax_amount'])) {
Copy link
Member

@omarabuhussein omarabuhussein Nov 15, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here .. shouldn't this be

if (isset($params['prevContribution']->tax_amount))

so basically flip the if condition with the one above it ... or am I missing something ?

@@ -3549,6 +3564,7 @@ public static function updateFinancialAccounts(&$params, $context = NULL, $skipT
}
}
$trxn = CRM_Core_BAO_FinancialTrxn::create($params['trxnParams']);
$previousLineItem = CRM_Price_BAO_LineItem::getLineItemsByContributionID($params['contribution']->id);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so the variable name is $previousLineItem but you are passing current contribution id .. should you pass $params['prevContribution']->id instead .. so

previousLineItem = CRM_Price_BAO_LineItem::getLineItemsByContributionID($params['prevContribution']->id);

in case is what you want is the current contribution line item then I think you should rename the variable name to reflect that .. or maybe I am missing something again ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

$params['contribution']->id and $params['prevContribution']->id hold the same id for contribution.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

then I think it would be more clear to use $params['prevContribution']->id

}
}
else {
$amount = $diff * $fieldValues['line_total'];
if ($context == 'changedAmount') {
$itemParams['amount'] = $diff * ($fieldValues['line_total'] - $previousLineItem[$fieldValues['id']]['line_total']);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so if this condition evaluated to true .. then the variable $amount will be undefined but it is still used when creating $itemParams array below .. I don't know what are you trying to do but this will cause issues so I think you need to rethink about what you are doing here

Copy link
Member

@omarabuhussein omarabuhussein Nov 15, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also I think this whole logic :

          if (!empty($params['is_quick_config'])) {
            $amount = $itemAmount;
            if (!$amount) {
              $amount = $params['total_amount'];
              if ($context === NULL) {
                $amount -= CRM_Utils_Array::value('tax_amount', $params, 0);
              }
            }
          }
          else {
            if ($context == 'changedAmount') {
              $itemParams['amount'] = $diff * ($fieldValues['line_total'] - $previousLineItem[$fieldValues['id']]['line_total']);
            }
            else {
              $amount = $diff * $fieldValues['line_total'];
            }
          }

could be moved to a new private method that calculate the amount based on passed parameters .. but it depends on what this line $itemParams['amount'] = $diff * ($fieldValues['line'] ... etc is for .

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As an aside - this is_quick_config should really not be this deep in the BAO method. Not sure if you can change it here but it's something to always be conscious of. Quick Config was introduced to allow a simplified display but has unfortunately been spaghettified into all sorts of places

@@ -3596,13 +3620,25 @@ public static function updateFinancialAccounts(&$params, $context = NULL, $skipT
$params['line_item'][$fieldId][$fieldValueId]['deferred_line_total'] = $amount;
$params['line_item'][$fieldId][$fieldValueId]['financial_item_id'] = $financialItem->id;

if ($fieldValues['tax_amount']) {
$taxAmount = $fieldValues['tax_amount'];
Copy link
Member

@omarabuhussein omarabuhussein Nov 15, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what if $fieldValues['tax_amount'] is not exists .. is that possible ... you may need check it first?

Copy link
Member

@omarabuhussein omarabuhussein left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for now I reviewed these two files :

CRM/Contribute/BAO/Contribution.php
CRM/Contribute/Form/Contribution.php

and left some notes .. I will revisit the rest of files whenever I have some time during this week and continue reviewing them .

THEN 0
ELSE 1
END
GROUP BY cfi.id ORDER BY cfi.id DESC LIMIT 1';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since there is "LIMIT 1" and I don't see that you are using any aggreate function in the select colomuns then I see that there is no need for the "GROUP BY" part .

INNER JOIN civicrm_financial_trxn cft ON cft.id = ceft.financial_trxn_id
INNER JOIN civicrm_financial_account cfa ON cfa.id = cfi.financial_account_id
WHERE cfi.entity_table = %2 AND cfi.entity_id = %1 AND
CASE
Copy link
Member

@omarabuhussein omarabuhussein Nov 20, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this query complete ? , because I don't see any meaning for this case statement .. whenever any case get satisfied it will end up either as ( AND 1 ) or (AND 0) and either way it has no meaning since you are not comparing or using it in anything .

@omarabuhussein
Copy link
Member

omarabuhussein commented Nov 20, 2016

okay I am done reviewing , since this is still marked as [WIP] and there are many notes I left on it which are still unresolved , So this is not ready for the coming release . cc @eileenmcnaughton

@eileenmcnaughton
Copy link
Contributor

Thanks for the review @omarabuhussein

I agree it is absolutely essential to add unit tests when making changes to financial or sales tax issues because they are easy to break & hard to QA and important. The sales tax code is woefully under-tested

@JoeMurray
Copy link
Contributor

jenkins please test this

@agileware
Copy link
Contributor

We've cloned this to test manually on our dev systems. Aiming to add some unit tests too.

@pradpnayak pradpnayak force-pushed the CRM-19585 branch 3 times, most recently from e1e3c3a to ebf8a32 Compare December 20, 2016 12:49
@@ -374,7 +374,8 @@ public static function calculateMissingAmountParams(&$params, $contributionID) {
$params['fee_amount'] = 0;
}
}
if (!isset($params['net_amount'])) {
// recalculate net amount if it is not set or if tax amount is set
if (!isset($params['net_amount']) || isset($params['tax_amount'])) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we torture our poor users by asking them to enter net_amount rather than always calculating it from fee amount, tax amount etc - has anyone else felt the love of altering total & then failing to save because net amount fails validation.

Erm that was a tangent

…rectly

----------------------------------------
* CRM-19585: Sales tax issue
  https://issues.civicrm.org/jira/browse/CRM-19585
…ribution amount is changed having tax

----------------------------------------
* CRM-19585: Sales tax issue
  https://issues.civicrm.org/jira/browse/CRM-19585
pradpnayak and others added 6 commits December 22, 2016 18:41
----------------------------------------
* CRM-19585: Sales tax issue
  https://issues.civicrm.org/jira/browse/CRM-19585
----------------------------------------
* CRM-19585: Sales tax issue
  https://issues.civicrm.org/jira/browse/CRM-19585
----------------------------------------
* CRM-19585: Sales tax issue
  https://issues.civicrm.org/jira/browse/CRM-19585
----------------------------------------
* CRM-19585: Sales tax issue
  https://issues.civicrm.org/jira/browse/CRM-19585
----------------------------------------
* CRM-19585: Sales tax issue
  https://issues.civicrm.org/jira/browse/CRM-19585
@omarabuhussein
Copy link
Member

hey guys .. please ping me in case all issues where sorted out so I can review again

@pradpnayak
Copy link
Contributor Author

closing this in favour of
#9574
#9576
#9588
#9589
#9590

@pradpnayak pradpnayak closed this Dec 28, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants