<commit_before><?php
namespace Ayeo\Price;

/**
 * Price model
 */
class Price
{
    /**
     * todo: Add map symbol => precision
     * There exists currencies with different precision
     * but those are extremely uncommon
     *
     * Full list:
     * https://pl.wikipedia.org/wiki/Jen
     * https://pl.wikipedia.org/wiki/Funt_cypryjski
     * https://pl.wikipedia.org/wiki/Dinar_iracki
     * https://pl.wikipedia.org/wiki/Dinar_jordański
     * https://pl.wikipedia.org/wiki/Dinar_kuwejcki
     * https://pl.wikipedia.org/wiki/Dinar_Bahrajnu
     */
    const PRECISION = 2;

    /**
     * @var float
     */
	private $nett;

    /**
     * @var float
     */
	private $gross;

    /**
     * @var null|string ISO 4217 (3 uppercase chars)
     */
	private $currencySymbol;

    /**
     * @param float $nett
     * @param float $gross
     * @param null|string $currencySymbol
     */
    public function __construct($nett = 0.00, $gross = null, $currencySymbol) //fixme: param order!
    {
        if (is_null($gross))
        {
            $gross = $nett;
        }

        $this->validateValues($nett, $gross);

        $this->currencySymbol = $this->processCurrencySymbol($currencySymbol);
        $this->nett = $nett;
        $this->gross = $gross;
    }

    /**
     * @param float $nett
     * @param integer $tax
     * @param null|string $currencySymbol
     * @return Price
     */
    public static function buildByNett($nett, $tax, $currencySymbol = null)
    {
        return new Price($nett, $nett * (100 + Price::processTax($tax)) / 100, $currencySymbol);
    }

    /**
     * @param float $gross
     * @param integer $tax
     * @param null|string $currencySymbol
     * @return Price
     */
    public static function buildByGross($gross, $tax, $currencySymbol = null)
    {
        return new Price(Price::calculateNett($gross, Price::processTax($tax)), $gross, $currencySymbol);
    }

    /**
     * @return float
     */
    public function getNett()
    {
        return round($this->nett, Price::PRECISION);
    }

    /**
     * @return float
     */
    public function getGross()
    {
        return round($this->gross, Price::PRECISION);
    }

    /**
     * @return int
     */
    public function getTax()
    {
        if ($this->nett > 0) {
            return (int) round($this->gross / $this->nett * 100 - 100, 0);
        }

        return 0;
    }

    /**
     * @param Price $price
     * @return bool
     */
    public function isLowerThan(Price $price)
    {
        return $this->getGross() < $price->getGross();
    }

    /**
     * @param Price $price
     * @return bool
     */
    public function isGreaterThan(Price $price)
    {
        return $this->getGross() > $price->getGross();
    }

    /**
     * @param Price $price
     * @return bool
     */
    public function isEqual(Price $price)
    {
        $isGrossEqual = $this->getGross() === $price->getGross();
        $isNettEqual = $this->getNett() === $price->getNett();

        return ($isGrossEqual  && $isNettEqual);
    }

    /**
     * @param Price $priceToAdd
     * @return Price
     */
    public function add(Price $priceToAdd)
    {
        $this->checkCurrencies($this, $priceToAdd);

        $newGross = $this->getGross() + $priceToAdd->getGross();
        $newNett = $this->getNett() + $priceToAdd->getNett();

        return new Price($newNett, $newGross, $this->currencySymbol);
    }

    /**
     * @param Price $priceToSubtract
     * @return Price
     */
    public function subtract(Price $priceToSubtract)
    {
        $this->checkCurrencies($this, $priceToSubtract);

        if ($this->isGreaterThan($priceToSubtract)) {
            $newGross = $this->getGross() - $priceToSubtract->getGross();
            $newNett = $this->getNett() - $priceToSubtract->getNett();

            return new Price($newNett, $newGross, $this->currencySymbol);
        }

        return new Price(0, 0, $this->getCurrencySymbol()); //zero
    }

    /**
     * @param float $times
     * @return Price
     */
    public function multiply($times)
    {
        //fixme: do we really need this constraint?
        //fixme: numeric
//        if (is_integer($times) === false) {
//            throw new \LogicException('Multiply param must be integer');
//        }

        if ($times <= 0) {
            throw new \LogicException('Multiply param must greater than 0');
        }

        $nett = $this->getNett() * $times;
        $gross = $this->getGross() * $times;

        return new Price($nett, $gross, $this->currencySymbol);
    }

    /**
     * @return bool
     */<commit_msg>Add divide method<commit_after><?php
namespace Ayeo\Price;

/**
 * Price model
 */
class Price
{
    /**
     * todo: Add map symbol => precision
     * There exists currencies with different precision
     * but those are extremely uncommon
     *
     * Full list:
     * https://pl.wikipedia.org/wiki/Jen
     * https://pl.wikipedia.org/wiki/Funt_cypryjski
     * https://pl.wikipedia.org/wiki/Dinar_iracki
     * https://pl.wikipedia.org/wiki/Dinar_jordański
     * https://pl.wikipedia.org/wiki/Dinar_kuwejcki
     * https://pl.wikipedia.org/wiki/Dinar_Bahrajnu
     */
    const PRECISION = 2;

    /**
     * @var float
     */
	private $nett;

    /**
     * @var float
     */
	private $gross;

    /**
     * @var null|string ISO 4217 (3 uppercase chars)
     */
	private $currencySymbol;

    /**
     * @param float $nett
     * @param float $gross
     * @param null|string $currencySymbol
     */
    public function __construct($nett = 0.00, $gross = null, $currencySymbol) //fixme: param order!
    {
        if (is_null($gross))
        {
            $gross = $nett;
        }

        $this->validateValues($nett, $gross);

        $this->currencySymbol = $this->processCurrencySymbol($currencySymbol);
        $this->nett = $nett;
        $this->gross = $gross;
    }

    /**
     * @param float $nett
     * @param integer $tax
     * @param null|string $currencySymbol
     * @return Price
     */
    public static function buildByNett($nett, $tax, $currencySymbol = null)
    {
        return new Price($nett, $nett * (100 + Price::processTax($tax)) / 100, $currencySymbol);
    }

    /**
     * @param float $gross
     * @param integer $tax
     * @param null|string $currencySymbol
     * @return Price
     */
    public static function buildByGross($gross, $tax, $currencySymbol = null)
    {
        return new Price(Price::calculateNett($gross, Price::processTax($tax)), $gross, $currencySymbol);
    }

    /**
     * @return float
     */
    public function getNett()
    {
        return round($this->nett, Price::PRECISION);
    }

    /**
     * @return float
     */
    public function getGross()
    {
        return round($this->gross, Price::PRECISION);
    }

    /**
     * @return int
     */
    public function getTax()
    {
        if ($this->nett > 0) {
            return (int) round($this->gross / $this->nett * 100 - 100, 0);
        }

        return 0;
    }

    /**
     * @param Price $price
     * @return bool
     */
    public function isLowerThan(Price $price)
    {
        return $this->getGross() < $price->getGross();
    }

    /**
     * @param Price $price
     * @return bool
     */
    public function isGreaterThan(Price $price)
    {
        return $this->getGross() > $price->getGross();
    }

    /**
     * @param Price $price
     * @return bool
     */
    public function isEqual(Price $price)
    {
        $isGrossEqual = $this->getGross() === $price->getGross();
        $isNettEqual = $this->getNett() === $price->getNett();

        return ($isGrossEqual  && $isNettEqual);
    }

    /**
     * @param Price $priceToAdd
     * @return Price
     */
    public function add(Price $priceToAdd)
    {
        $this->checkCurrencies($this, $priceToAdd);

        $newGross = $this->getGross() + $priceToAdd->getGross();
        $newNett = $this->getNett() + $priceToAdd->getNett();

        return new Price($newNett, $newGross, $this->currencySymbol);
    }

    /**
     * @param Price $priceToSubtract
     * @return Price
     */
    public function subtract(Price $priceToSubtract)
    {
        $this->checkCurrencies($this, $priceToSubtract);

        if ($this->isGreaterThan($priceToSubtract)) {
            $newGross = $this->getGross() - $priceToSubtract->getGross();
            $newNett = $this->getNett() - $priceToSubtract->getNett();

            return new Price($newNett, $newGross, $this->currencySymbol);
        }

        return new Price(0, 0, $this->getCurrencySymbol()); //zero
    }

    /**
     * @param float $times
     * @return Price
     */
    public function multiply($times)
    {
        //fixme: do we really need this constraint?
        //fixme: numeric
//        if (is_integer($times) === false) {
//            throw new \LogicException('Multiply param must be integer');
//        }

        if ($times <= 0) {
            throw new \LogicException('Multiply param must greater than 0');
        }

        $nett = $this->getNett() * $times;
        $gross = $this->getGross() * $times;

        return new Price($nett, $gross, $this->getCurrencySymbol());
    }

    public function divide($times)
    {
        if ($times <= 0) {
            throw new \LogicException('Divide factor must be positive and greater than zero');
        }

        $nett = $this->getNett() / $times;
        $gross = $this->getGross() / $times;

        return new Price($nett, $gross, $this->getCurrencySymbol());
    }

    /**
     * @return bool
     */
{'fraction_non_alphanumeric': 0.15042770707281453, 'fraction_numerical': 0.005946171500104319, 'mean_word_length': 2.0737415838409747, 'pattern_counts': {'":': 0, '<': 10, '<?xml version=': 0, '>': 82, 'https://': 12, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1916940', 'n_tokens_mistral': 3130, 'n_tokens_neox': 2996, 'n_words': 650}