public function allocate(array $ratios, $roundToPrecision = self::ROUND_TO_DEFAULT) { $total = array_sum($ratios); if (!count($ratios) || !$total) { throw new InvalidArgumentException('Invalid ratios specified: at least one ore more positive ratios must be provided.'); } if (is_integer($roundToPrecision)) { $precision = $roundToPrecision; } else { $precision = self::ROUND_TO_DEFAULT === $roundToPrecision ? $this->currency->getPrecision() : $this->currency->getDisplayPrecision(); } $currency = clone $this->currency; $currency->setPrecision($precision); $currency->setDisplayPrecision($this->currency->getDisplayPrecision()); $amount = new Money($currency); $amount->setAmountFloat($this->getAmountFloat()); $remainder = clone $amount; $results = array(); $increment = $amount->getScale() / pow(10, $currency->getPrecision()); foreach ($ratios as $ratio) { if ($ratio < 0) { throw new InvalidArgumentException("Invalid share ratio '" . $ratio . "' supplied: ratios may not be negative amounts."); } $share = $amount->multiply($ratio)->divide($total); $results[] = $share; $remainder = $remainder->subtract($share); } for ($i = 0; $remainder->isPositive(); $i++) { $amountInteger = $results[$i]->getAmountInteger(); $results[$i]->setAmountInteger($amountInteger + $increment); $increment = $amount->getScale() / pow(10, $amount->currency->getPrecision()); $remainderAmountInteger = $remainder->getAmountInteger(); $remainder->setAmountInteger($remainderAmountInteger - $increment); } $convertedResults = array(); foreach ($results as $result) { /** * @var $result Money */ $converted = new Money($this->currency); $converted->setAmountFloat($result->getAmountFloat()); $convertedResults[] = $converted; } return $convertedResults; }
/** * {inheritDoc} */ public function equals(CurrencyInterface $currency) { return $this->currencyCode === $currency->getCurrencyCode() && $this->precision === $currency->getPrecision() && $this->displayPrecision === $currency->getDisplayPrecision(); }