From 31f5f5e4e28a3800dbac35a601d70ed3880ef13c Mon Sep 17 00:00:00 2001 From: Mathieu Lutfy Date: Tue, 15 Aug 2017 14:54:18 -0400 Subject: [PATCH] CRM-17281 Pledge payments : fix bug with miscalculation when assigning pledge payments. This PR fixes a bug where payments are miscalculated with weird results. If a payment changes the amount of future payments in such a way as to make an irregular amount e.g 10 is split over 3 payments, the payment amount needs to be recorded as .33 not .333333, assuming a currency with 2 decimal places. This commit ensures the rounding takes place & is locked in by the accompanying unit test. Note that we discussed this & agreed to use a function as a placeholder for the number of decimal places. --- CRM/Pledge/BAO/PledgePayment.php | 2 +- CRM/Utils/Money.php | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/CRM/Pledge/BAO/PledgePayment.php b/CRM/Pledge/BAO/PledgePayment.php index 6abe2225fe..a40b8efb74 100644 --- a/CRM/Pledge/BAO/PledgePayment.php +++ b/CRM/Pledge/BAO/PledgePayment.php @@ -863,7 +863,7 @@ WHERE civicrm_pledge_payment.contribution_id = {$paymentContributionId} // means we are editing payment scheduled payment. $oldestPaymentAmount = self::getOldestPledgePayment($pledgeID, 2); } - $newActualAmount = ($actualAmount - $pledgeScheduledAmount); + $newActualAmount = round(($actualAmount - $pledgeScheduledAmount), CRM_Utils_Money::getCurrencyPrecision()); $newPledgeScheduledAmount = $oldestPayment['amount']; if (!$paymentContributionId) { $newActualAmount = ($actualAmount - $pledgeScheduledAmount); diff --git a/CRM/Utils/Money.php b/CRM/Utils/Money.php index da35641306..edabc90446 100644 --- a/CRM/Utils/Money.php +++ b/CRM/Utils/Money.php @@ -125,4 +125,20 @@ class CRM_Utils_Money { return strtr($format, $replacements); } + /** + * This is a placeholder function for calculating the number of decimal places for a currency. + * + * Currently code assumes 2 decimal places but some currencies (bitcoin, middle eastern) have + * more. By using this function we can signpost the locations where the number of decimal places is + * currency specific for future enhancement. + * + * @param string $currency + * + * @return int + * Number of decimal places. + */ + public static function getCurrencyPrecision($currency = NULL) { + return 2; + } + } -- 2.25.1