diff --git a/lib/PayPal/Api/Amount.php b/lib/PayPal/Api/Amount.php index 877db80..5a90331 100644 --- a/lib/PayPal/Api/Amount.php +++ b/lib/PayPal/Api/Amount.php @@ -55,7 +55,7 @@ class Amount extends PPModel public function setTotal($total) { NumericValidator::validate($total, "Total"); - $total = FormatConverter::formatToTwoDecimalPlaces($total); + $total = FormatConverter::formatToPrice($total, $this->getCurrency()); $this->total = $total; return $this; } diff --git a/lib/PayPal/Api/Cost.php b/lib/PayPal/Api/Cost.php index 8813966..f6baf37 100644 --- a/lib/PayPal/Api/Cost.php +++ b/lib/PayPal/Api/Cost.php @@ -28,7 +28,7 @@ class Cost extends PPModel public function setPercent($percent) { NumericValidator::validate($percent, "Percent"); - $percent = FormatConverter::formatToTwoDecimalPlaces($percent); + $percent = FormatConverter::formatToNumber($percent); $this->percent = $percent; return $this; } diff --git a/lib/PayPal/Api/Currency.php b/lib/PayPal/Api/Currency.php index cfbe165..c4018a6 100644 --- a/lib/PayPal/Api/Currency.php +++ b/lib/PayPal/Api/Currency.php @@ -51,7 +51,7 @@ class Currency extends PPModel public function setValue($value) { NumericValidator::validate($value, "Value"); - $value = FormatConverter::formatToTwoDecimalPlaces($value); + $value = FormatConverter::formatToPrice($value, $this->getCurrency()); $this->value = $value; return $this; } diff --git a/lib/PayPal/Api/Details.php b/lib/PayPal/Api/Details.php index 5d5c627..b03449e 100644 --- a/lib/PayPal/Api/Details.php +++ b/lib/PayPal/Api/Details.php @@ -36,7 +36,7 @@ class Details extends PPModel public function setShipping($shipping) { NumericValidator::validate($shipping, "Shipping"); - $shipping = FormatConverter::formatToTwoDecimalPlaces($shipping); + $shipping = FormatConverter::formatToPrice($shipping); $this->shipping = $shipping; return $this; } @@ -62,7 +62,7 @@ class Details extends PPModel public function setSubtotal($subtotal) { NumericValidator::validate($subtotal, "SubTotal"); - $subtotal = FormatConverter::formatToTwoDecimalPlaces($subtotal); + $subtotal = FormatConverter::formatToPrice($subtotal); $this->subtotal = $subtotal; return $this; } @@ -89,7 +89,7 @@ class Details extends PPModel public function setTax($tax) { NumericValidator::validate($tax, "Tax"); - $tax = FormatConverter::formatToTwoDecimalPlaces($tax); + $tax = FormatConverter::formatToPrice($tax); $this->tax = $tax; return $this; } @@ -115,7 +115,7 @@ class Details extends PPModel public function setFee($fee) { NumericValidator::validate($fee, "Fee"); - $fee = FormatConverter::formatToTwoDecimalPlaces($fee); + $fee = FormatConverter::formatToPrice($fee); $this->fee = $fee; return $this; } @@ -141,7 +141,7 @@ class Details extends PPModel public function setShippingDiscount($shipping_discount) { NumericValidator::validate($shipping_discount, "Shipping Discount"); - $shipping_discount = FormatConverter::formatToTwoDecimalPlaces($shipping_discount); + $shipping_discount = FormatConverter::formatToPrice($shipping_discount); $this->shipping_discount = $shipping_discount; return $this; } @@ -192,7 +192,7 @@ class Details extends PPModel public function setInsurance($insurance) { NumericValidator::validate($insurance, "Insurance"); - $insurance = FormatConverter::formatToTwoDecimalPlaces($insurance); + $insurance = FormatConverter::formatToPrice($insurance); $this->insurance = $insurance; return $this; } @@ -218,7 +218,7 @@ class Details extends PPModel public function setHandlingFee($handling_fee) { NumericValidator::validate($handling_fee, "Handling Fee"); - $handling_fee = FormatConverter::formatToTwoDecimalPlaces($handling_fee); + $handling_fee = FormatConverter::formatToPrice($handling_fee); $this->handling_fee = $handling_fee; return $this; } @@ -268,7 +268,7 @@ class Details extends PPModel public function setGiftWrap($gift_wrap) { NumericValidator::validate($gift_wrap, "Gift Wrap"); - $gift_wrap = FormatConverter::formatToTwoDecimalPlaces($gift_wrap); + $gift_wrap = FormatConverter::formatToPrice($gift_wrap); $this->gift_wrap = $gift_wrap; return $this; } diff --git a/lib/PayPal/Api/Item.php b/lib/PayPal/Api/Item.php index 6814066..0faf5aa 100644 --- a/lib/PayPal/Api/Item.php +++ b/lib/PayPal/Api/Item.php @@ -113,7 +113,7 @@ class Item extends PPModel { NumericValidator::validate($price, "Price"); - $price = FormatConverter::formatToTwoDecimalPlaces($price); + $price = FormatConverter::formatToPrice($price, $this->getCurrency()); $this->price = $price; return $this; } @@ -139,7 +139,7 @@ class Item extends PPModel public function setTax($tax) { NumericValidator::validate($tax, "Tax"); - $tax = FormatConverter::formatToTwoDecimalPlaces($tax); + $tax = FormatConverter::formatToPrice($tax, $this->getCurrency()); $this->tax = $tax; return $this; } diff --git a/lib/PayPal/Common/FormatConverter.php b/lib/PayPal/Common/FormatConverter.php index d52612c..e5db4b5 100644 --- a/lib/PayPal/Common/FormatConverter.php +++ b/lib/PayPal/Common/FormatConverter.php @@ -19,14 +19,56 @@ class FormatConverter { /** * Format the input data to two decimal places * + * @deprecated Use formatToNumber instead * @param $value * @return string */ public static function formatToTwoDecimalPlaces($value) + { + return self::formatToNumber($value); + } + + /** + * Format the input data with decimal places + * + * Defaults to 2 decimal places + * + * @param $value + * @param int $decimals + * @return null|string + */ + public static function formatToNumber($value, $decimals = 2) { if (trim($value) != null) { - return number_format($value, 2, '.', ''); + return number_format($value, $decimals, '.', ''); } return null; } + + /** + * Helper method to format price values with associated currency information. + * + * It covers the cases where certain currencies does not accept decimal values. We will be adding + * any specific currency level rules as required here. + * + * @param $value + * @param null $currency + * @return null|string + */ + public static function formatToPrice($value, $currency = null) + { + $decimals = 2; + $currencyDecimals = array('JPY' => 0, 'TWD' => 0); + if ($currency && array_key_exists($currency, $currencyDecimals)) { + if (strpos($value, ".") !== false && (floor($value) != $value)) { + //throw exception if it has decimal values for JPY and TWD which does not ends with .00 + throw new \InvalidArgumentException("value cannot have decimals for $currency currency"); + } + $decimals = $currencyDecimals[$currency]; + } else if (strpos($value, ".") === false) { + // Check if value has decimal values. If not no need to assign 2 decimals with .00 at the end + $decimals = 0; + } + return self::formatToNumber($value, $decimals); + } } diff --git a/tests/PayPal/Test/Common/FormatConverterTest.php b/tests/PayPal/Test/Common/FormatConverterTest.php index b425dbc..4b8c93f 100644 --- a/tests/PayPal/Test/Common/FormatConverterTest.php +++ b/tests/PayPal/Test/Common/FormatConverterTest.php @@ -12,7 +12,8 @@ use PayPal\Test\Validation\NumericValidatorTest; class FormatConverterTest extends \PHPUnit_Framework_TestCase { - public static function classMethodListProvider(){ + public static function classMethodListProvider() + { return array( array(new Item(), 'Price'), array(new Item(), 'Tax'), @@ -29,6 +30,14 @@ class FormatConverterTest extends \PHPUnit_Framework_TestCase ); } + public static function CurrencyListWithNoDecimalsProvider() + { + return array( + array('JPY'), + array('TWD') + ); + } + public static function apiModelSettersProvider() { $provider = array(); @@ -62,6 +71,44 @@ class FormatConverterTest extends \PHPUnit_Framework_TestCase } + /** + * @dataProvider CurrencyListWithNoDecimalsProvider + */ + public function testPriceWithNoDecimalCurrencyInvalid($input) + { + try { + FormatConverter::formatToPrice("1.234", $input); + } catch (\InvalidArgumentException $ex) { + $this->assertContains("value cannot have decimals for", $ex->getMessage()); + } + } + + /** + * @dataProvider CurrencyListWithNoDecimalsProvider + */ + public function testPriceWithNoDecimalCurrencyValid($input) + { + $result = FormatConverter::formatToPrice("1.0000000", $input); + $this->assertEquals("1", $result); + } + + /** + * + * @dataProvider \PayPal\Test\Validation\NumericValidatorTest::positiveProvider + */ + public function testFormatToNumber($input, $expected) + { + $result = FormatConverter::formatToNumber($input); + $this->assertEquals($expected, $result); + } + + public function testFormatToNumberDecimals() + { + $result = FormatConverter::formatToNumber("0.0", 4); + $this->assertEquals("0.0000", $result); + } + + public function testFormat() { $result = FormatConverter::format("12.0123", "%0.2f"); diff --git a/tests/PayPal/Test/Validation/NumericValidatorTest.php b/tests/PayPal/Test/Validation/NumericValidatorTest.php index 09dcfdd..85cee40 100644 --- a/tests/PayPal/Test/Validation/NumericValidatorTest.php +++ b/tests/PayPal/Test/Validation/NumericValidatorTest.php @@ -10,6 +10,8 @@ class NumericValidatorTest extends \PHPUnit_Framework_TestCase public static function positiveProvider() { return array( + array(".5", "0.50"), + array(".55", "0.55"), array("0", "0.00"), array(null, null), array("01", "1.00"),