Files
kupshop/bundles/KupShop/KupShopBundle/Util/Price/PriceCalculator.php
2025-08-02 16:30:27 +02:00

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());
}
}