Skip to content

Commit

Permalink
use Decimal for prices instead of money
Browse files Browse the repository at this point in the history
- money doesn't suite best because it uses currencies that don't occur in the domain
- the implementation is more straightforward
- had to fix PriceTest, because the library always produces numbers with the same scale
  • Loading branch information
Svaťa Šimara committed Jan 28, 2019
1 parent 3f9dc5d commit 9316b95
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 37 deletions.
2 changes: 1 addition & 1 deletion composer.json
Expand Up @@ -11,7 +11,7 @@
"require": {
"php": "^7.1",
"doctrine/orm": "^2.5",
"moneyphp/money": "~3.2"
"litipk/php-bignumbers": "^0.8"
},
"require-dev": {
"phpunit/phpunit": "~7.0",
Expand Down
44 changes: 12 additions & 32 deletions src/Domain/Price.php
Expand Up @@ -2,23 +2,22 @@

namespace Simara\Cart\Domain;

use Money\Money;
use Money\Number;
use Litipk\BigNumbers\Decimal;

class Price
{
private const EURO_TO_CENTS_CONVERTING_BASE = -2;
private const CENTS_TO_EURO_CONVERTING_BASE = 2;
private const DECIMALS = 2;

/**
* @var Money
* @var Decimal
*/
private $withVat;

public function __construct(string $withVat)
{
$cents = $this->eurToCents($withVat);
$this->withVat = Money::EUR($cents);
$withHigherPrecision = Decimal::fromString($withVat, self::DECIMALS + 1);
$truncated = $withHigherPrecision->floor(self::DECIMALS);
$this->withVat = $truncated;
}

/**
Expand All @@ -34,42 +33,23 @@ public static function sum(array $prices): self

public function getWithVat(): string
{
return $this->centsToEurs($this->withVat->getAmount());
return (string) $this->withVat->floor(self::DECIMALS);
}

public function add(self $adder): self
{
$withVat = $this->withVat->add($adder->withVat);
return self::fromMoney($withVat);
return self::fromDecimal($withVat);
}

public function multiply(int $multiplier): self
{
$withVat = $this->withVat->multiply($multiplier);
return self::fromMoney($withVat);
$withVat = $this->withVat->mul(Decimal::fromInteger($multiplier));
return self::fromDecimal($withVat);
}

private static function fromMoney(Money $withVat): self
private static function fromDecimal(Decimal $withVat): self
{
$price = new self('0');
$price->withVat = $withVat;
return $price;
}

private function eurToCents(string $euros): string
{
$number = Number::fromString($euros);
return $number->base10(self::EURO_TO_CENTS_CONVERTING_BASE)->getIntegerPart();
}

private function centsToEurs(string $cents): string
{
$number = new Number($cents);
$inEuro = $number->base10(self::CENTS_TO_EURO_CONVERTING_BASE);
if ($inEuro->isInteger()) {
return $inEuro->getIntegerPart();
} else {
return $inEuro->getIntegerPart() . '.' . $inEuro->getFractionalPart();
}
return new self($withVat->floor(self::DECIMALS));
}
}
8 changes: 4 additions & 4 deletions tests/Domain/PriceTest.php
Expand Up @@ -52,11 +52,11 @@ public function testGetter(string $converted, string $expected)
public function getterTestCases(): array
{
return [
["0.005", "0"],
["0.005", "0.00"],
["0.05" , "0.05"],
["0.5" , "0.5"],
["0" , "0"],
["5" , "5"],
["0.5" , "0.50"],
["0" , "0.00"],
["5" , "5.00"],
["5.555", "5.55"],
];
}
Expand Down

0 comments on commit 9316b95

Please sign in to comment.