src/Money.php
public function allocate(int ...$ratios) : array
    {
        if (! $ratios) {
            throw new \InvalidArgumentException('Cannot allocate() an empty list of ratios.');
        }

        foreach ($ratios as $ratio) {
            if ($ratio < 0) {
                throw new \InvalidArgumentException('Cannot allocate() negative ratios.');
            }
        }

        $total = array_sum($ratios);

        if ($total === 0) {
            throw new \InvalidArgumentException('Cannot allocate() to zero ratios only.');
        }

        $step = $this->context->getStep();

        $monies = [];

        $unit = BigDecimal::ofUnscaledValue($step, $this->amount->getScale());
        $unit = new Money($unit, $this->currency, $this->context);

        if ($this->isNegative()) {
            $unit = $unit->negated();
        }

        $remainder = $this;

        foreach ($ratios as $ratio) {
            $money = $this->multipliedBy($ratio)->quotient($total);
            $remainder = $remainder->minus($money);
            $monies[] = $money;
        }

        foreach ($monies as $key => $money) {
            if ($remainder->isZero()) {
                break;
            }

            $monies[$key] = $money->plus($unit);
            $remainder = $remainder->minus($unit);
        }

        return $monies;
    }
public function allocate(int ...$ratios) : array
    {
        if (! $ratios) {
            throw new \InvalidArgumentException('Cannot allocate() an empty list of ratios.');
        }

        foreach ($ratios as $ratio) {
            if ($ratio < 0) {
                throw new \InvalidArgumentException('Cannot allocate() negative ratios.');
            }
        }

        $total = array_sum($ratios);

        if ($total === 0) {
            throw new \InvalidArgumentException('Cannot allocate() to zero ratios only.');
        }

        $step = $this->context->getStep();

        $monies = [];

        $unit = BigDecimal::ofUnscaledValue($step, $this->amount->getScale());
        $unit = new Money($unit, $this->currency, $this->context);

        if ($this->isNegative()) {
            $unit = $unit->negated();
        }

        $remainder = $this;

        foreach ($ratios as $ratio) {
            $money = $this->multipliedBy($ratio)->quotient($total);
            $remainder = $remainder->minus($money);
            $monies[] = $money;
        }

        foreach ($monies as $key => $money) {
            if ($remainder->isZero()) {
                break;
            }

            $monies[$key] = $money->plus($unit);
            $remainder = $remainder->minus($unit);
        }

        return $monies;
    }
public function allocate ( int ... $ ratios ) : array { if ( ! $ ratios ) { throw new \ InvalidArgumentException ( 'Cannot allocate() an empty list of ratios.' ) ; } foreach ( $ ratios as $ ratio ) { if ( $ ratio < 0 ) { throw new \ InvalidArgumentException ( 'Cannot allocate() negative ratios.' ) ; } } $ total = array_sum ( $ ratios ) ; if ( $ total === 0 ) { throw new \ InvalidArgumentException ( 'Cannot allocate() to zero ratios only.' ) ; } $ step = $ this -> context -> getStep ( ) ; $ monies = [ ] ; $ unit = BigDecimal :: ofUnscaledValue ( $ step , $ this -> amount -> getScale ( ) ) ; $ unit = new Money ( $ unit , $ this -> currency , $ this -> context ) ; if ( $ this -> isNegative ( ) ) { $ unit = $ unit -> negated ( ) ; } $ remainder = $ this ; foreach ( $ ratios as $ ratio ) { $ money = $ this -> multipliedBy ( $ ratio ) -> quotient ( $ total ) ; $ remainder = $ remainder -> minus ( $ money ) ; $ monies [ ] = $ money ; } foreach ( $ monies as $ key => $ money ) { if ( $ remainder -> isZero ( ) ) { break ; } $ monies [ $ key ] = $ money -> plus ( $ unit ) ; $ remainder = $ remainder -> minus ( $ unit ) ; } return $ monies ; }
Allocates this Money according to a list of ratios.

If the allocation yields a remainder, its amount is split over the first monies in the list,
so that the total of the resulting monies is always equal to this Money.

For example, given a `USD 49.99` money in the default context,
`allocate(1, 2, 3, 4)` returns [`USD 5.00`, `USD 10.00`, `USD 15.00`, `USD 19.99`]

The resulting monies have the same context as this Money.

@param int[] $ratios The ratios.

@return Money[]

@throws \InvalidArgumentException If called with invalid parameters.
Allocates this Money according to a list of ratios .