<commit_before><?php

/*
 * This file is part of the Sylius package.
 *
 * (c) <NAME>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Sylius\Bundle\CoreBundle\OrderProcessing;

use Sylius\Bundle\CoreBundle\Model\OrderInterface;
use Sylius\Bundle\CoreBundle\Model\VariantInterface;
use Sylius\Bundle\InventoryBundle\Factory\InventoryUnitFactoryInterface;
use Sylius\Bundle\InventoryBundle\Model\InventoryUnitInterface;
use Sylius\Bundle\InventoryBundle\Operator\InventoryOperatorInterface;

/**
 * Order inventory handler.
 *
 * @author <NAME> <<EMAIL>>
 */
class InventoryHandler implements InventoryHandlerInterface
{
    /**
     * Inventory operator.
     *
     * @var InventoryOperatorInterface
     */
    protected $inventoryOperator;

    /**
     * Inventory unit factory.
     *
     * @var InventoryUnitFactoryInterface
     */
    protected $inventoryUnitFactory;

    /**
     * Constructor.
     *
     * @param InventoryOperatorInterface    $inventoryOperator
     * @param InventoryUnitFactoryInterface $inventoryUnitFactory
     */
    public function __construct(InventoryOperatorInterface $inventoryOperator, InventoryUnitFactoryInterface $inventoryUnitFactory)
    {
        $this->inventoryOperator = $inventoryOperator;
        $this->inventoryUnitFactory = $inventoryUnitFactory;
    }

    /**
     * {@inheritdoc}
     */
    public function processInventoryUnits(OrderInterface $order)
    {
        $variants = array();
        $quantities = array();

        foreach ($order->getItems() as $item) {
            $variant = $item->getVariant();

            if (!in_array($variant, $variants)) {
                $variants[] = $variant;
            }

            $index = array_search($variant, $variants);
            $quantities[$index] = isset($quantities[$index]) ? $quantities[$index] + $item->getQuantity() : $item->getQuantity();
        }

        foreach ($variants as $variant) {
            $units = $order->getInventoryUnitsByVariant($variant);
            $quantityDifference = $quantities[array_search($variant, $variants)] - count($units);

            if (0 !== $quantityDifference) {
                $quantityDifference < 0 ? $this->removeInventoryUnits($order, $variant, abs($quantityDifference)) : $this->addInventoryUnits($order, $variant, $quantityDifference);
            }
        }

        //remove units of items that no longer exist
        foreach ($order->getInventoryUnits() as $unit) {
            if (!in_array($unit->getStockable(), $variants)) {
                $order->removeInventoryUnit($unit);
            }
        }
    }

    /**
     * {@inheritdoc}
     */<commit_msg>Refactoring code to make it easier to follow.<commit_after><?php

/*
 * This file is part of the Sylius package.
 *
 * (c) <NAME>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Sylius\Bundle\CoreBundle\OrderProcessing;

use Sylius\Bundle\CoreBundle\Model\OrderInterface;
use Sylius\Bundle\CoreBundle\Model\VariantInterface;
use Sylius\Bundle\InventoryBundle\Factory\InventoryUnitFactoryInterface;
use Sylius\Bundle\InventoryBundle\Model\InventoryUnitInterface;
use Sylius\Bundle\InventoryBundle\Operator\InventoryOperatorInterface;

/**
 * Order inventory handler.
 *
 * @author <NAME> <<EMAIL>>
 */
class InventoryHandler implements InventoryHandlerInterface
{
    /**
     * Inventory operator.
     *
     * @var InventoryOperatorInterface
     */
    protected $inventoryOperator;

    /**
     * Inventory unit factory.
     *
     * @var InventoryUnitFactoryInterface
     */
    protected $inventoryUnitFactory;

    /**
     * Constructor.
     *
     * @param InventoryOperatorInterface    $inventoryOperator
     * @param InventoryUnitFactoryInterface $inventoryUnitFactory
     */
    public function __construct(InventoryOperatorInterface $inventoryOperator, InventoryUnitFactoryInterface $inventoryUnitFactory)
    {
        $this->inventoryOperator = $inventoryOperator;
        $this->inventoryUnitFactory = $inventoryUnitFactory;
    }

    /**
     * {@inheritdoc}
     */
    public function processInventoryUnits(OrderInterface $order)
    {
        list ($variants, $quantities) = $this->getVariantQuantities($order);

        foreach ($variants as $variant) {
            $this->updateVariantUnits($order, $variant, $quantities[array_search($variant, $variants)]);
        }

        $this->removeUnusedUnits($order, $variants);
    }

    /**
     * Removes inventory units which are not linked to any of specified variants
     *
     * @param OrderInterface $order
     * @param array $variants
     */
    private function removeUnusedUnits(OrderInterface $order, array $variants)
    {
        foreach ($order->getInventoryUnits() as $unit) {
            if (!in_array($unit->getStockable(), $variants)) {
                $order->removeInventoryUnit($unit);
            }
        }
    }

    /**
     * Update inventory units related to passed variant to the specified quantity
     *
     * @param OrderInterface $order
     * @param VariantInterface $variant
     * @param int $quantity
     */
    private function updateVariantUnits(OrderInterface $order, VariantInterface $variant, $quantity)
    {
        $units = $order->getInventoryUnitsByVariant($variant);
        $quantityDifference = $quantity - count($units);

        if (0 === $quantityDifference) {
            return;
        }

        if ($quantityDifference < 0) {
            $this->removeInventoryUnits($order, $variant, abs($quantityDifference));
        } else {
            $this->addInventoryUnits($order, $variant, $quantityDifference);
        }
    }

    /**
     * Helper method that returns the quantities of each variant in cart
     * Return format: [[Variant1, Variant2], [QuantityForVariant1, QuantityForVariant2]]
     *
     * @param OrderInterface $order
     * @return array
     */
    private function getVariantQuantities(OrderInterface $order)
    {
        $variants = array();
        $quantities = array();

        foreach ($order->getItems() as $item) {
            $variant = $item->getVariant();

            if (!in_array($variant, $variants)) {
                $variants[] = $variant;
            }

            $index = array_search($variant, $variants);
            $quantities[$index] = isset($quantities[$index]) ? $quantities[$index] + $item->getQuantity() : $item->getQuantity();
        }

        return array($variants, $quantities);
    }

    /**
     * {@inheritdoc}
     */
{'fraction_non_alphanumeric': 0.11595728681004662, 'fraction_numerical': 0.0012031884493908858, 'mean_word_length': 2.824036802760207, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 38, 'https://': 0, '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': '4627034', 'n_tokens_mistral': 1837, 'n_tokens_neox': 1783, 'n_words': 387}