143 lines
4.3 KiB
PHP
143 lines
4.3 KiB
PHP
<?php
|
|
|
|
namespace KupShop\KupShopBundle\Util\Price;
|
|
|
|
use KupShop\I18nBundle\Entity\Currency;
|
|
|
|
class PriceCalculator
|
|
{
|
|
/**
|
|
* Price + Price2.
|
|
*/
|
|
public static function add(Price $price, Price $price2): Price
|
|
{
|
|
self::makeCompatible($price, $price2);
|
|
|
|
return new Price($price->getValue()->add($price2->getValue()), $price->getCurrency(), $price->getVat());
|
|
}
|
|
|
|
/**
|
|
* Price - Price2.
|
|
*/
|
|
public static function sub(Price $price, Price $price2): Price
|
|
{
|
|
self::makeCompatible($price, $price2);
|
|
|
|
return new Price($price->getValue()->sub($price2->getValue()), $price->getCurrency(), $price->getVat());
|
|
}
|
|
|
|
/**
|
|
* Price < Price2.
|
|
*/
|
|
public static function firstLower(Price $price, Price $price2): bool
|
|
{
|
|
self::makeCompatible($price, $price2, false);
|
|
|
|
if ($price->getPriceWithVat()->lowerThan($price2->getPriceWithVat())) {
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Price > Price2.
|
|
*/
|
|
public static function firstGreater(Price $price, Price $price2): bool
|
|
{
|
|
self::makeCompatible($price, $price2, false);
|
|
|
|
if ($price->getPriceWithVat()->comp($price2->getPriceWithVat()) == 1) {
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Price * Constant.
|
|
*/
|
|
public static function mul(Price $price, \Decimal $constant): Price
|
|
{
|
|
return new Price($price->getValue()->mul($constant), $price->getCurrency(), $price->getVat());
|
|
}
|
|
|
|
public static function addDiscount(Price $price, \Decimal $discount): Price
|
|
{
|
|
$discount_decimal = $price->getValue()->mul($discount)->div(\DecimalConstants::hundred());
|
|
|
|
return new Price($price->getValue()->sub($discount_decimal), $price->getCurrency(), $price->getVat());
|
|
}
|
|
|
|
public static function makeCompatible(Price &$price, Price &$price2, bool $priceInstanceCheck = true)
|
|
{
|
|
if ($priceInstanceCheck && isDevelopment() && $price instanceof ProductPrice) {
|
|
throw new \InvalidArgumentException(
|
|
sprintf('Cannot use "%s" with "%s"! Convert it into price using "%s::toPrice".', self::class, ProductPrice::class, self::class)
|
|
);
|
|
}
|
|
|
|
// if currency is not same
|
|
if ($price->getCurrency()->getId() != $price2->getCurrency()->getId()) {
|
|
$price2 = self::convert($price2, $price->getCurrency());
|
|
}
|
|
|
|
// if vat is not same
|
|
if ($price->getVat() != $price2->getVat()) {
|
|
self::makeSameVat($price, $price2);
|
|
}
|
|
}
|
|
|
|
public static function toPrice(Price $price): Price
|
|
{
|
|
return new Price(
|
|
$price->getPriceWithoutVat(false),
|
|
$price->getCurrency(),
|
|
$price->getVat()
|
|
);
|
|
}
|
|
|
|
protected static function makeSameVat(Price &$price, Price &$price2)
|
|
{
|
|
$vat = $price->getVat();
|
|
|
|
$price2WithVat = $price2->getValue()->addVat($price2->getVat());
|
|
|
|
if ($price2 instanceof ProductPrice) {
|
|
$price2 = new ProductPrice(
|
|
$price2WithVat->removeVat($vat),
|
|
$price2->getCurrency(),
|
|
$vat,
|
|
$price2->getDiscount()
|
|
);
|
|
} else {
|
|
$price2 = new Price($price2WithVat->removeVat($vat), $price2->getCurrency(), $vat);
|
|
}
|
|
}
|
|
|
|
public static function convert(Price $price, Currency $currency): Price
|
|
{
|
|
if ($price->getCurrency()->getId() === $currency->getId()) {
|
|
return $price;
|
|
}
|
|
|
|
// to czk
|
|
$converted = $price->getValue()->mul($price->getCurrency()->getRate());
|
|
// div by given currency rate
|
|
$converted = $converted->div($currency->getRate());
|
|
|
|
if ($price instanceof ProductPrice) {
|
|
return (new ProductPrice($converted, $currency, $price->getVat(), $price->getDiscount()))->setSource($price->getSource());
|
|
} elseif ($price instanceof PriceLevelPrice) {
|
|
$newPrice = new PriceLevelPrice(
|
|
new ProductPrice($converted, $currency, $price->getVat(), $price->getDiscount())
|
|
);
|
|
$newPrice->setPricelevelDiscount($price->getPricelevelDiscount());
|
|
|
|
return $newPrice->setSource($price->getSource());
|
|
}
|
|
|
|
return (new Price($converted, $currency, $price->getVat()))->setSource($price->getSource());
|
|
}
|
|
}
|