* @return string
*/
protected static function formatLocaleNumericRounded($amount, $numberOfPlaces) {
- return self::formatLocaleNumeric(round($amount, $numberOfPlaces));
+ return self::formatNumericByFormat($amount, '%!.' . $numberOfPlaces . 'i');
}
/**
* Formatted amount.
*/
public static function formatLocaleNumericRoundedByCurrency($amount, $currency) {
- $amount = self::formatLocaleNumericRounded($amount, self::getCurrencyPrecision($currency));
+ return self::formatLocaleNumericRoundedByPrecision($amount, self::getCurrencyPrecision($currency));
+ }
+
+ /**
+ * Format money for display (just numeric part) according to the current locale with rounding to the supplied precision.
+ *
+ * This handles both rounding & replacement of the currency separators for the locale.
+ *
+ * @param string $amount
+ * @param int $precision
+ *
+ * @return string
+ * Formatted amount.
+ */
+ public static function formatLocaleNumericRoundedByPrecision($amount, $precision) {
+ $amount = self::formatLocaleNumericRounded($amount, $precision);
+ return self::replaceCurrencySeparators($amount);
+ }
+
+ /**
+ * Format money for display with rounding to the supplied precision but without padding.
+ *
+ * If the string is shorter than the precision trailing zeros are not added to reach the precision
+ * beyond the 2 required for normally currency formatting.
+ *
+ * This handles both rounding & replacement of the currency separators for the locale.
+ *
+ * @param string $amount
+ * @param int $precision
+ *
+ * @return string
+ * Formatted amount.
+ */
+ public static function formatLocaleNumericRoundedByOptionalPrecision($amount, $precision) {
+ $decimalPlaces = strlen(substr($amount, strpos($amount, '.') + 1));
+ $amount = self::formatLocaleNumericRounded($amount, $precision > $decimalPlaces ? $decimalPlaces : $precision);
return self::replaceCurrencySeparators($amount);
}
$this->setCurrencySeparators(',');
}
+ /**
+ * Test rounded by currency function with specified precision.
+ *
+ * @param string $thousandSeparator
+ *
+ * @dataProvider getThousandSeparators
+ */
+ public function testFormatLocaleNumericRoundedByPrecision($thousandSeparator) {
+ $this->setCurrencySeparators($thousandSeparator);
+ $result = CRM_Utils_Money::formatLocaleNumericRoundedByPrecision(8950.3678, 3);
+ $expected = ($thousandSeparator === ',') ? '8,950.368' : '8.950,368';
+ $this->assertEquals($expected, $result);
+ }
+
+ /**
+ * Test rounded by currency function with specified precision but without padding to reach it.
+ *
+ * @param string $thousandSeparator
+ *
+ * @dataProvider getThousandSeparators
+ */
+ public function testFormatLocaleNumericRoundedByOptionalPrecision($thousandSeparator) {
+ $this->setCurrencySeparators($thousandSeparator);
+ $result = CRM_Utils_Money::formatLocaleNumericRoundedByOptionalPrecision(8950.3678, 8);
+ $expected = ($thousandSeparator === ',') ? '8,950.3678' : '8.950,3678';
+ $this->assertEquals($expected, $result);
+
+ $result = CRM_Utils_Money::formatLocaleNumericRoundedByOptionalPrecision(123456789.987654321, 9);
+ $expected = ($thousandSeparator === ',') ? '123,456,789.98765' : '123.456.789,98765';
+ $this->assertEquals($result, $expected);
+ }
+
/**
* Test that using the space character as a currency works
*/