Skip to content

Instantly share code, notes, and snippets.

@sergiy-petrov-vakoms
Created August 29, 2019 15:00
Show Gist options
  • Save sergiy-petrov-vakoms/86092c49caf37229d5f15ea36d021195 to your computer and use it in GitHub Desktop.
Save sergiy-petrov-vakoms/86092c49caf37229d5f15ea36d021195 to your computer and use it in GitHub Desktop.
Test Decimals
<?php
namespace App\Http\Controllers;
class TestTotalController extends Controller
{
private $taxRate = 8.875;
public function show()
{
$price1 = $this->getItem1Price();
$price1 = $price1 + $this->getTaxAmount($price1);
$centPrice1 = (new Money($price1, Money::MODE_DOLLAR))->getCentValue();
$price2 = $this->getItem2Price();
$price2 = $price2 + $this->getTaxAmount($price2);
$centPrice2 = (new Money($price2, Money::MODE_DOLLAR))->getCentValue();
dd('expected total: 41.9168$ (41.92$ -> 4192 cents), actual total: ' . ($centPrice1 + $centPrice2) . ' cents');
}
protected function getItem1Price()
{
// dollars
return 14.75; // with taxes it would be 16.05906
}
protected function getItem2Price()
{
// dollars
return 23.75; // with taxes it would be 25.85781
}
protected function getTaxAmount($sum)
{
return ($this->taxRate / 100) * $sum;
}
}
class Money
{
public const MODE_CENT = 1;
public const MODE_DOLLAR = 2;
/** @var int */
private $centValue;
/** @var float */
private $dollarValue;
public function __construct($amount, $mode = self::MODE_CENT)
{
$this->setAmount($amount, $mode);
}
public function setAmount($amount, $mode = self::MODE_CENT) : void
{
if ($mode === self::MODE_CENT) {
$this->setCentValue($amount);
$this->setDollarValue(round($amount / 100, 2));
} elseif ($mode === self::MODE_DOLLAR) {
$this->setCentValue(round($amount, 2) * 100);
$this->setDollarValue($amount);
} else {
throw new \Exception("Mode '$mode' is incorrect'");
}
}
public function getCentValue() : int
{
return $this->centValue;
}
public function getDollarValue() : float
{
return $this->dollarValue;
}
public function getDollarValueAsString(int $decimals = 2) : string
{
$stringCentValue = (string)$this->getCentValue();
$dollar = substr($stringCentValue, 0, strlen($stringCentValue)-2);
$cent = substr($stringCentValue, -2);
if ($decimals >= 2) {
$cent = str_pad($cent, $decimals, '0');
} else {
$cent = substr($cent, 0, $decimals);
}
$result = $dollar;
if (strlen($cent) > 0) {
$result .= ".{$cent}";
}
return $result;
}
/**
* @param mixed $centValue
*/
private function setCentValue($centValue) : void
{
$this->centValue = intval($centValue);
}
/**
* @param mixed $dollarValue
*/
private function setDollarValue($dollarValue) : void
{
$this->dollarValue = floatval($dollarValue);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment