<commit_before><?php
/**
 * Shopware 4.0
 * Copyright © 2013 shopware AG
 *
 * According to our dual licensing model, this program can be used either
 * under the terms of the GNU Affero General Public License, version 3,
 * or under a proprietary license.
 *
 * The texts of the GNU Affero General Public License with an additional
 * permission and of our proprietary license can be found at and
 * in the LICENSE file you have received along with this program.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Affero General Public License for more details.
 *
 * "Shopware" is a registered trademark of shopware AG.
 * The licensing of the program under the AGPLv3 does not imply a
 * trademark license. Therefore any rights, title and interest in
 * our trademarks remain entirely with us.
 */

namespace Shopware\Bepado;
use Bepado\SDK\ProductFromShop as ProductFromShopBase,
    Bepado\SDK\Struct\Order,
    Bepado\SDK\Struct\Product,
    Bepado\SDK\Struct\Address,
    Shopware\Models\Order as OrderModel,
    Shopware\Models\Customer as CustomerModel,
    Shopware\Components\Model\ModelManager,
    Doctrine\ORM\Query;

/**
 * The interface for products exported *to* bepado *from* the local shop
 *
 * @category  Shopware
 * @package   Shopware\Plugins\SwagBepado
 */
class ProductFromShop implements ProductFromShopBase
{
    /**
     * @var Helper
     */
    private $helper;

    /**
     * @var ModelManager
     */
    private $manager;

    /**
     * @param Helper $helper
     * @param ModelManager $manager
     */
    public function __construct(Helper $helper, ModelManager $manager)
    {
        $this->helper = $helper;
        $this->manager = $manager;
    }

    /**
     * Get product data
     *
     * Get product data for all the product IDs specified in the given string
     * array.
     *
     * @param string[] $ids
     * @return Product[]
     */
    public function getProducts(array $ids)
    {
        $products = array();
        foreach($ids as $id) {
            $products[] = $this->helper->getProductById($id);
        }
        return $products;
    }

    /**
     * Get all IDs of all exported products
     *
     * @return string[]
     */
    public function getExportedProductIDs()
    {
        $repository = $this->manager->getRepository(
            'Shopware\Models\Article\Article'
        );
        $builder = $repository->createQueryBuilder('a');
        $builder->join('a.mainDetail', 'd');
        $builder->join('d.attribute', 'at');
        $builder->where("at.bepadoExportStatus IN ('online', 'update', 'insert')");
        $builder->select(array(
            'a.id as sourceId'
        ));
        $query = $builder->getQuery();
        $ids = $query->getArrayResult();
        $ids = array_map(function($id) {
            return $id['sourceId'];
        }, $ids);
        return $ids;
    }

    /**
     * Reserve a product in shop for purchase
     *
     * @param Order $order
     * @return void
     * @throws \Exception Abort reservation by throwing an exception here.
     */
    public function reserve(Order $order)
    {
    }

    /**
     * Buy products mentioned in order
     *
     * Should return the internal order ID.
     *
     * @param Order $order
     * @return string
     *
     * @throws \Exception Abort buy by throwing an exception,
     *                    but only in very important cases.
     *                    Do validation in {@see reserve} instead.
     */
    public function buy(Order $order)
    {
        $detailStatus = $this->manager->find('Shopware\Models\Order\DetailStatus', 0);
        $status = $this->manager->find('Shopware\Models\Order\Status', 0);
        $shop = $this->manager->find('Shopware\Models\Shop\Shop', 1);
        $number = 'BP-' . $order->orderShop . '-' . $order->localOrderId;

        $repository = $this->manager->getRepository('Shopware\Models\Payment\Payment');
        $payment = $repository->findOneBy(array(
            'name' => 'invoice',
        ));

        // todo: Create the OrderModel without previous plain SQL
        //$model = new OrderModel\Order();
        $sql = 'INSERT INTO `s_order` (`ordernumber`, `cleared`) VALUES (?, 17);';
        Shopware()->Db()->query($sql, array($number));
        $modelId = Shopware()->Db()->lastInsertId();
        /** @var $model \Shopware\Models\Order\Order */
        $model = $this->manager->find('Shopware\Models\Order\Order', $modelId);

        $attribute = new \Shopware\Models\Attribute\Order;
        $attribute->setBepadoOrderId($order->localOrderId);
        $attribute->setBepadoShopId($order->orderShop);
        $model->setAttribute($attribute);

        $model->fromArray(array(
            'number' => $number,
            'invoiceShipping' => $order->grossShippingCosts,
            'invoiceShippingNet' => $order->shippingCosts,
            'currencyFactor' => 1,
            'orderStatus' => $status,
            'shop' => $shop,
            'languageSubShop' => $shop,
            'payment' => $payment,
            'currency' => 'EUR',
            'orderTime' => 'now'
        ));
        $items = array();
        foreach($order->products as $product) {
            /** @var $productModel \Shopware\Models\Article\Article */
            $productModel = $this->manager->find(
                '\Shopware\Models\Article\Article',
                $product->product->sourceId
            );
            $productDetail = $productModel->getMainDetail();
            $item = new OrderModel\Detail();
            $item->fromArray(array(
                'articleId' => $product->product->sourceId,
                'quantity' => $product->count,
                'orderId' => $model->getId(),
                'number' => $model->getNumber(),
                'articleNumber' => $productDetail->getNumber(),
                'articleName' => $product->product->title,
                'price' => $this->calculatePrice($product->product),
                'taxRate' => $product->product->vat * 100,
                'status' => $detailStatus
            ));
            $items[] = $item;
        }
        $model->setDetails($items);

        $hash = md5(serialize($order->deliveryAddress));
        $email = substr($hash, 0, 8) . '@bepado.de';

        $repository = $this->manager->getRepository('Shopware\Models\Customer\Customer');
        $customer = $repository->findOneBy(array(
            'email' => $email,
            'hashPassword' => $<PASSWORD>
        ));
        if($customer === null) {
            $customer = new CustomerModel\Customer();
            $customer->fromArray(array(
                'active' => true,
                'email' => $email,
                'rawPassword' => <PASSWORD>,
                'accountMode' => 1,
                'shop' => $shop,
                'paymentId' => $payment->getId(),
            ));
        }
        if($customer->getBilling() === null) {
            $billing = new CustomerModel\Billing();
            $customer->setBilling($billing);
        } else {
            $billing = $customer->getBilling();
        }
        $billing->fromArray($this->getAddressData(<commit_msg>BEP-478 - mail + phone<commit_after><?php
/**
 * Shopware 4.0
 * Copyright © 2013 shopware AG
 *
 * According to our dual licensing model, this program can be used either
 * under the terms of the GNU Affero General Public License, version 3,
 * or under a proprietary license.
 *
 * The texts of the GNU Affero General Public License with an additional
 * permission and of our proprietary license can be found at and
 * in the LICENSE file you have received along with this program.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Affero General Public License for more details.
 *
 * "Shopware" is a registered trademark of shopware AG.
 * The licensing of the program under the AGPLv3 does not imply a
 * trademark license. Therefore any rights, title and interest in
 * our trademarks remain entirely with us.
 */

namespace Shopware\Bepado;
use Bepado\SDK\ProductFromShop as ProductFromShopBase,
    Bepado\SDK\Struct\Order,
    Bepado\SDK\Struct\Product,
    Bepado\SDK\Struct\Address,
    Shopware\Models\Order as OrderModel,
    Shopware\Models\Customer as CustomerModel,
    Shopware\Components\Model\ModelManager,
    Doctrine\ORM\Query;

/**
 * The interface for products exported *to* bepado *from* the local shop
 *
 * @category  Shopware
 * @package   Shopware\Plugins\SwagBepado
 */
class ProductFromShop implements ProductFromShopBase
{
    /**
     * @var Helper
     */
    private $helper;

    /**
     * @var ModelManager
     */
    private $manager;

    /**
     * @param Helper $helper
     * @param ModelManager $manager
     */
    public function __construct(Helper $helper, ModelManager $manager)
    {
        $this->helper = $helper;
        $this->manager = $manager;
    }

    /**
     * Get product data
     *
     * Get product data for all the product IDs specified in the given string
     * array.
     *
     * @param string[] $ids
     * @return Product[]
     */
    public function getProducts(array $ids)
    {
        $products = array();
        foreach($ids as $id) {
            $products[] = $this->helper->getProductById($id);
        }
        return $products;
    }

    /**
     * Get all IDs of all exported products
     *
     * @return string[]
     */
    public function getExportedProductIDs()
    {
        $repository = $this->manager->getRepository(
            'Shopware\Models\Article\Article'
        );
        $builder = $repository->createQueryBuilder('a');
        $builder->join('a.mainDetail', 'd');
        $builder->join('d.attribute', 'at');
        $builder->where("at.bepadoExportStatus IN ('online', 'update', 'insert')");
        $builder->select(array(
            'a.id as sourceId'
        ));
        $query = $builder->getQuery();
        $ids = $query->getArrayResult();
        $ids = array_map(function($id) {
            return $id['sourceId'];
        }, $ids);
        return $ids;
    }

    /**
     * Reserve a product in shop for purchase
     *
     * @param Order $order
     * @return void
     * @throws \Exception Abort reservation by throwing an exception here.
     */
    public function reserve(Order $order)
    {
    }

    /**
     * Buy products mentioned in order
     *
     * Should return the internal order ID.
     *
     * @param Order $order
     * @return string
     *
     * @throws \Exception Abort buy by throwing an exception,
     *                    but only in very important cases.
     *                    Do validation in {@see reserve} instead.
     */
    public function buy(Order $order)
    {
        $detailStatus = $this->manager->find('Shopware\Models\Order\DetailStatus', 0);
        $status = $this->manager->find('Shopware\Models\Order\Status', 0);
        $shop = $this->manager->find('Shopware\Models\Shop\Shop', 1);
        $number = 'BP-' . $order->orderShop . '-' . $order->localOrderId;

        $repository = $this->manager->getRepository('Shopware\Models\Payment\Payment');
        $payment = $repository->findOneBy(array(
            'name' => 'invoice',
        ));

        // todo: Create the OrderModel without previous plain SQL
        //$model = new OrderModel\Order();
        $sql = 'INSERT INTO `s_order` (`ordernumber`, `cleared`) VALUES (?, 17);';
        Shopware()->Db()->query($sql, array($number));
        $modelId = Shopware()->Db()->lastInsertId();
        /** @var $model \Shopware\Models\Order\Order */
        $model = $this->manager->find('Shopware\Models\Order\Order', $modelId);

        $attribute = new \Shopware\Models\Attribute\Order;
        $attribute->setBepadoOrderId($order->localOrderId);
        $attribute->setBepadoShopId($order->orderShop);
        $model->setAttribute($attribute);

        $model->fromArray(array(
            'number' => $number,
            'invoiceShipping' => $order->grossShippingCosts,
            'invoiceShippingNet' => $order->shippingCosts,
            'currencyFactor' => 1,
            'orderStatus' => $status,
            'shop' => $shop,
            'languageSubShop' => $shop,
            'payment' => $payment,
            'currency' => 'EUR',
            'orderTime' => 'now'
        ));
        $items = array();
        foreach($order->products as $product) {
            /** @var $productModel \Shopware\Models\Article\Article */
            $productModel = $this->manager->find(
                '\Shopware\Models\Article\Article',
                $product->product->sourceId
            );
            $productDetail = $productModel->getMainDetail();
            $item = new OrderModel\Detail();
            $item->fromArray(array(
                'articleId' => $product->product->sourceId,
                'quantity' => $product->count,
                'orderId' => $model->getId(),
                'number' => $model->getNumber(),
                'articleNumber' => $productDetail->getNumber(),
                'articleName' => $product->product->title,
                'price' => $this->calculatePrice($product->product),
                'taxRate' => $product->product->vat * 100,
                'status' => $detailStatus
            ));
            $items[] = $item;
        }
        $model->setDetails($items);

        $email = $order->deliveryAddress->email;

        if (!$email) {
            $hash = md5(serialize($order->deliveryAddress));
            // todo@dn: Use real mail address here.600
            $email = substr($hash, 0, 8) . '@bepado.de';
        }


        $repository = $this->manager->getRepository('Shopware\Models\Customer\Customer');
        $customer = $repository->findOneBy(array(
            'email' => $email,
            'hashPassword' => <PASSWORD>
        ));
        if($customer === null) {
            $customer = new CustomerModel\Customer();
            $customer->fromArray(array(
                'active' => true,
                'email' => $email,
                'rawPassword' => <PASSWORD>,
                'accountMode' => 1,
                'shop' => $shop,
                'paymentId' => $payment->getId(),
            ));
        }
        if($customer->getBilling() === null) {
            $billing = new CustomerModel\Billing();
            $customer->setBilling($billing);
        } else {
            $billing = $customer->getBilling();
        }
        $billing->fromArray($this->getAddressData(
{'fraction_non_alphanumeric': 0.13682925174682858, 'fraction_numerical': 0.0032562241367614137, 'mean_word_length': 2.1286078098471988, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 203, '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': '3737353', 'n_tokens_mistral': 4151, 'n_tokens_neox': 3993, 'n_words': 1019}