Stock/Prioritizer/StockPrioritizer.php
protected function prioritizeAssignment(Stock\StockAssignmentInterface $assignment)
    {
        if ($assignment->isFullyShipped() || $assignment->isFullyShippable()) {
            return false;
        }

        // Get the non shippable quantity
        if (0 >= $quantity = $assignment->getSoldQuantity() - $assignment->getShippableQuantity()) {
            return false;
        }

        // Options are:
        // - Splitting non shippable quantity to other stock unit(s)
        // - Moving the whole assignment to other stock unit(s) (TODO)
        // - Moving other assignment(s) to other stock unit(s) (TODO)

        $changed = false;

        $helper = new PrioritizeHelper($this->unitResolver);

        $sourceUnit = $assignment->getStockUnit();

        $candidates = $helper->getUnitCandidates($assignment, $quantity);

        foreach ($candidates as $candidate) {
            $targetUnit = $candidate->unit;

            // If not enough reservable quantity
            if ((0 < $quantity - $targetUnit->getReservableQuantity()) && ($combination = $candidate->combination)) {
                // Use combination to release quantity
                foreach ($combination->map as $id => $qty) {
                    if (null === $a = $candidate->getAssignmentById($id)) {
                        throw new StockLogicException("Assignment not found.");
                    }

                    // Move assignment to the source unit
                    $this->moveAssignment($a, $sourceUnit, min($qty, $quantity));
                }
            }

            // Move assignment to the target unit.
            $delta = min($quantity, $targetUnit->getReservableQuantity());
            $quantity -= $this->moveAssignment($assignment, $targetUnit, $delta);

            // TODO Validate units ?

            $changed = true;

            if (0 >= $quantity) {
                break;
            }
        }

        return $changed;
    }
protected function prioritizeAssignment(Stock\StockAssignmentInterface $assignment)
    {
        if ($assignment->isFullyShipped() || $assignment->isFullyShippable()) {
            return false;
        }

        // Get the non shippable quantity
        if (0 >= $quantity = $assignment->getSoldQuantity() - $assignment->getShippableQuantity()) {
            return false;
        }

        // Options are:
        // - Splitting non shippable quantity to other stock unit(s)
        // - Moving the whole assignment to other stock unit(s) (TODO)
        // - Moving other assignment(s) to other stock unit(s) (TODO)

        $changed = false;

        $helper = new PrioritizeHelper($this->unitResolver);

        $sourceUnit = $assignment->getStockUnit();

        $candidates = $helper->getUnitCandidates($assignment, $quantity);

        foreach ($candidates as $candidate) {
            $targetUnit = $candidate->unit;

            // If not enough reservable quantity
            if ((0 < $quantity - $targetUnit->getReservableQuantity()) && ($combination = $candidate->combination)) {
                // Use combination to release quantity
                foreach ($combination->map as $id => $qty) {
                    if (null === $a = $candidate->getAssignmentById($id)) {
                        throw new StockLogicException("Assignment not found.");
                    }

                    // Move assignment to the source unit
                    $this->moveAssignment($a, $sourceUnit, min($qty, $quantity));
                }
            }

            // Move assignment to the target unit.
            $delta = min($quantity, $targetUnit->getReservableQuantity());
            $quantity -= $this->moveAssignment($assignment, $targetUnit, $delta);

            // TODO Validate units ?

            $changed = true;

            if (0 >= $quantity) {
                break;
            }
        }

        return $changed;
    }
Prioritize the stock assignment.

@param Stock\StockAssignmentInterface $assignment

@return bool Whether the assignment has been prioritized.