<?php

use KupShop\AdminBundle\Util\StockInProductOfSupplierService;
use KupShop\CatalogBundle\Util\Product\ProductPriceWeigher;
use KupShop\KupShopBundle\Context\ContextManager;
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
use KupShop\StoresBundle\Utils\StoresInStore;
use Query\Operator;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;

$main_class = 'StockIn';

class StockIn extends Window
{
    use DatabaseCommunication;

    protected $defaults = [
        'paid' => '0',
        'vatDisplay' => '0',
        'payment_method' => 'prevodem',
        'multiplier' => '1',
        'id_index' => 'invoice',
    ];

    protected $required = [
        'number' => true,
        'code' => true,
    ];

    protected $tableName = 'stock_in';

    private $index;
    protected $index_old;

    protected ?StoresInStore $storesInStore = null;
    protected ContextManager $contextManager;
    protected StockInProductOfSupplierService $stockInProductOfSupplierService;

    public function __construct()
    {
        if (findModule(Modules::STORES)) {
            $this->storesInStore = ServiceContainer::getService(StoresInStore::class);
        }
        $this->contextManager = ServiceContainer::getService(ContextManager::class);
        $this->stockInProductOfSupplierService = ServiceContainer::getService(StockInProductOfSupplierService::class);
    }

    public function recalcTotalPrice()
    {
        sqlQuery('UPDATE '.getTableName('stock_in').' s
         SET total_price=(
            SELECT COALESCE(SUM(si.quantity*si.price), 0)+s.transport_price-s.discount
            FROM '.getTableName('stock_in_items').' si
            WHERE si.id_stock_in=s.id
         )
         WHERE s.id=:id', ['id' => $this->getID()]);
    }

    public function get_vars()
    {
        $vars = parent::get_vars();
        $pageVars = getVal('body', $vars);
        $acn = $this->getAction();
        $pageVars['paid'] = [
            '1' => translate('priceType_withVat', 'stockIn'),
            '2' => translate('priceType_withoutVat', 'stockIn'),
            '0' => translate('priceType_bothVat', 'stockIn'),
            '3' => translate('priceType_foreignCurrency', 'stockIn'),
        ];

        $sql = sqlQuery('SELECT id, name FROM '.getTableName('suppliers'));
        $pageVars['suppliers'] = ['' => '- Vyber dodavatele -'];
        foreach ($sql as $row) {
            $pageVars['suppliers'][$row['id']] = $row['name'];
        }

        if (findModule(Modules::STORES)) {
            $pageVars['stores'] = $this->storesInStore->getStoresNames();
        }

        $pageVars['paymentMethods'] = [
            'dobirka' => translate('cod', 'stockIn'),
            'prevodem' => translate('bankTransfer', 'stockIn'),
        ];

        $ID = $this->getID();
        if ($ID) {
            global $cfg;
            $id_supplier = $pageVars['data']['id_supplier'];
            $date_issued = $pageVars['data']['date_issued'];
            $fields = 'si.id, si.id_product, si.name, si.id_variation, si.quantity, 
            p.title as product_title, pv.title variation_title, si.price, COALESCE(v.vat, si.vat) as vat, p.figure,
            COALESCE(pv.price, p.price) as web_price, COALESCE(pv.in_store, p.in_store) as web_in_store, 
            p.discount as web_discount, COALESCE(pv.ean, p.ean) as ean, pos.code as code_supplier, pos.note as products_of_suppliers_note';

            if (!empty($cfg['Modules']['products_variations']['variationCode'])) {
                $fields .= ', COALESCE(pv.code, p.code) as code';
            } else {
                $fields .= ', p.code as code';
            }

            if (!empty($cfg['Modules']['products']['note'])) {
                $fields .= ', COALESCE(pv.note, p.note) as note';
            }

            if (findModule(Modules::STOCK_IN, Modules::SUB_WEIGHTED_PURCHASE_PRICE)) {
                $fields .= ', si.additional_costs';
            }

            $fields .= ', 
            (SELECT si2.price FROM stock_in_items si2 
            LEFT JOIN stock_in st2 ON si2.id_stock_in = st2.id
            WHERE st2.id_index = "invoice" AND st2.date_issued <= "'.$date_issued.'" AND st2.id != si.id_stock_in
            AND si2.id_product = si.id_product AND ((si.id_variation IS NULL AND si2.id_variation IS NULL) OR si2.id_variation = si.id_variation)
            ORDER BY st2.date_issued DESC, st2.id DESC LIMIT 1) AS prev_price';

            $orderBy = 'p.id > 0, si.id DESC';
            if ($this->getIndex() == 'future') {
                $orderBy = 'IF(products_of_suppliers_note IS NULL, 1, 0) ASC, '.$orderBy;
            }

            $SQL = sqlQuery("SELECT {$fields}
                  FROM stock_in_items si
                  LEFT JOIN products p ON p.id=si.id_product
                  LEFT JOIN products_variations pv ON pv.id=si.id_variation
                  LEFT JOIN products_of_suppliers pos ON p.id = pos.id_product AND pos.id_supplier = '".$id_supplier."' AND ((pv.id IS NULL AND pos.id_variation IS NULL) OR pos.id_variation = pv.id) 
                  LEFT JOIN vats v ON v.id=p.vat
                  WHERE si.id_stock_in='".$ID."' GROUP BY si.id ORDER BY ".$orderBy.' ');

            $vat = getAdminVat()['value'];

            $data = &$pageVars['data'];
            $data['transportVat'] = $vat;

            $data['transport_price_vat'] = $data['transport_price'] * (1 + ($vat / 100));
            $data['total_price_vat'] = $data['transport_price_vat'] - ($data['discount'] * (1 + ($vat / 100)));

            $this->unserializeCustomData($data);
            if (!empty($data['data']['parent_stock_in'])) {
                $data['data']['parent_stock_in'] = sqlQueryBuilder()
                    ->select('*')
                    ->from('stock_in')
                    ->where(Operator::equals(['id' => $data['data']['parent_stock_in']]))
                    ->execute()->fetch();
            }

            if (findModule(Modules::STORES) && ($data['data']['id_store'] ?? false)) {
                $data['isExternalStore'] = ($this->storesInStore->getStores()[$data['data']['id_store']]['type'] ?? false) == StoresInStore::TYPE_EXTERNAL_STORE;
            }

            $totalQuantity = 0;
            $items = [];
            foreach ($SQL as $row) {
                $row['web_price'] = calcPrice($row['web_price'], 0, $row['web_discount'])->asFloat();
                $row['price'] = floatval($row['price']);
                if ($row['web_price'] && $row['price']) {
                    $row['rabat'] = ($row['web_price'] - $row['price']) / $row['price'] * 100;
                    if ($row['rabat'] < 2) {
                        $row['color'] = '#9b313b';
                        $row['bg_color'] = '#FDD7DB';
                    } elseif ($row['rabat'] < 10) {
                        $row['color'] = '#9a7a2c';
                        $row['bg_color'] = '#fceecd';
                    } else {
                        $row['color'] = '#699b31';
                        $row['bg_color'] = '#E5FCCD';
                    }

                    if ($row['web_price'] > 0 && $row['web_price'] <= $row['price']) {
                        $row['bg_color'] = '#FCC479';
                    }

                    if ($row['rabat'] > 100) {
                        $row['bg_color'] = '#DADDFC';
                    }
                }

                if ($row['figure'] != 'Y') {
                    $row['bg_color'] = '#FF858D';
                }

                $row['web_price_vat'] = $row['web_price'] * (1 + $row['vat'] / 100);
                $row['price_vat'] = $row['price'] * (1 + $row['vat'] / 100);
                $row['price_all'] = $row['price'] * $row['quantity'];
                $row['price_all_vat'] = $row['price'] * $row['quantity'] * (1 + $row['vat'] / 100);
                $row['additional_costs'] = floatval($row['additional_costs'] ?? null);
                $items[$row['id']] = $row;
                $data['total_price_vat'] += ($row['price'] * $row['quantity']) * (1 + $row['vat'] / 100);

                $totalQuantity += $row['quantity'];
            }
            $data['total_price_vat'] = round($data['total_price_vat'], 4); // to fix values like -9.0949470177293E-13
            $pageVars['items'] = $items;
            $pageVars['totalQuantity'] = $totalQuantity;
            $pageVars['itemsCount'] = count($items);
        }

        // Import from file
        if (empty($pageVars['items']) && !empty($data['id_supplier'])) {
            $pageVars['import'] = new StockInImport($data);
        }

        $pageVars['paid2'] = ['1' => 'ANO', '0' => 'NE'];

        $pageVars['vatDisplay'] = getVal('vatDisplay');

        if (isset($data['data']['currency_symbol']) && !empty($data['data']['currency_symbol'])) {
            $pageVars['data']['currency_symbol'] = $data['data']['currency_symbol'];
        } else {
            $pageVars['data']['currency_symbol'] = '€';
        }

        if (is_string($pageVars['data']['data'] ?? false)) {
            $this->unserializeCustomData($pageVars['data']);
        }

        $vars['body'] = $pageVars;

        return $vars;
    }

    protected function getFields()
    {
        $index = $this->getIndex();
        if (in_array($index, ['closure', 'future', 'preorder'])) {
            $this->required = [];
        }

        parent::getFields();
    }

    public function createObject()
    {
        $data = parent::createObject();

        if (empty($data['date_created'])) {
            $data['date_created'] = date('d-m-Y H:i:s');
        }
        if (empty($data['date_issued'])) {
            if (in_array($data['id_index'], ['future', 'preorder'])) {
                $data['date_issued'] = date('d-m-Y', time() + 86400);
            } else {
                $data['date_issued'] = date('d-m-Y', time() - 86400);
            }
        }
        if (empty($data['date_expiration'])) {
            $data['date_expiration'] = date('d-m-Y', time() + (13 * 86400));
        }

        return $data;
    }

    public function getData()
    {
        $data = parent::getData();

        if (!empty($data['date_issued'])) {
            $data['date_issued'] = $this->prepareDate($data['date_issued']);
        }
        if (!empty($data['date_expiration'])) {
            $data['date_expiration'] = $this->prepareDate($data['date_expiration']);
        }

        if (isset($data['multiplier'])) {
            $this->preparePrice($data['multiplier']);
        }

        if (getVal('Submit') == 'recieved') {
            if ($this->getIndex() == 'future') {
                $this->index_old = 'future';
                $this->index = 'invoice';
            }
            $data['id_index'] = $this->index;
        }

        if (getVal('Submit')) {
            $this->serializeCustomData($data);
        }

        return $data;
    }

    public function handleUpdate()
    {
        $acn = $this->getAction();
        $data = $this->getData();
        $ID = $this->getID();

        $oldMultiplier = null;
        $multiplier = $data['multiplier'];

        if ($acn == 'edit' && !empty($ID)) {
            $closed = returnSQLResult('SELECT closed
         FROM '.getTableName('stock_in')." s
         WHERE s.id='{$ID}' ");

            if ($closed) {
                $this->returnError('Nelze upravovat uzavřenou fakturu');
            }

            // kvůli přepočtu CZK ceny při změně kurzu u naskladnění v cizí měně
            $vatDisplay = json_decode($data['data'], true)['vatDisplay'] ?? null;
            if ($vatDisplay and $vatDisplay == 3) {
                $oldMultiplier = sqlQueryBuilder()
                    ->select('multiplier')
                    ->from('stock_in')
                    ->andWhere(Operator::equals(['id' => $ID]))
                    ->execute()->fetchOne();
            }
        }
        parent::handleUpdate();
        if ($this->index_old == 'future' && $this->index == 'invoice') {
            // Naskladnění aktualizovat pouze v případě naskladnění, ne aktualizace faktury
            sqlQueryBuilder()
                ->update('stock_in')
                ->set('date_stock_in', 'NOW()')
                ->andWhere(Operator::equals(['id' => $ID]))
                ->execute();
        }
        $object = $this->getObject();
        if (empty($object['number']) && $object['id_index'] == 'invoice') {
            $number = returnSQLResult('SELECT MAX(number)+1 FROM '.getTableName('stock_in').' WHERE id_index="invoice"');
            if (empty($number)) {
                $number = 1;
            }
            $this->updateSQL('stock_in', ['number' => $number], ['id' => $this->getID()]);
        }

        $stockin = getVal('stockin', $data, []);

        if (findModule(Modules::STOCK_IN, Modules::SUB_WEIGHTED_PURCHASE_PRICE)) {
            $this->appendAdditionalCosts($stockin, $object);
        }

        if (findModule(Modules::STOCK_IN, Modules::SUB_WEIGHTED_PURCHASE_PRICE)) {
            $this->productPriceWeigher = ServiceContainer::getService(ProductPriceWeigher::class);
        }

        if (isset($oldMultiplier) && $oldMultiplier != 0 && ($oldMultiplier != $multiplier)) {
            foreach ($stockin as $id => &$item) {
                $item['price'] = ($item['price'] / $oldMultiplier) * $multiplier;
            }
        }

        krsort($stockin, SORT_NUMERIC);

        sqlGetConnection()->transactional(function () use ($stockin) {
            foreach ($stockin as $id => $item) {
                $item['id'] = intval($id);

                if (!$id) {
                    continue;
                }

                $item['quantity'] = str_replace(',', '.', $item['quantity']);

                $item = array_merge($this->getItem($item), $item);
                if ($this->index_old == 'future' && $this->index == 'invoice') {
                    // naskladneni
                    $item['recieved'] = true;
                }
                $this->recalculateWeightedPrice($item);

                if (!empty($item['delete'])) {
                    $this->handleDeleteValue($item);
                    continue;
                }

                if ($id < 0) {
                    $this->handleAddValue($item);
                } else {
                    $this->handleUpdateValue($item);
                }
            }
            $this->recalcTotalPrice();
        });

        $vatDisplay = '0';
        if (getVal('vatDisplay')) {
            $vatDisplay = getVal('vatDisplay');
        }

        $this->redirect(['vatDisplay' => $vatDisplay, 'ErrStr' => $this->getErrors()[0]]);

        return true;
    }

    public function getItem($item)
    {
        $row = sqlFetchAssoc(sqlQuery('SELECT si.id_product, si.id_variation, si.quantity as old_quantity
         FROM stock_in_items si
         WHERE si.id=:id AND si.id_product IS NOT NULL', ['id' => $item['id']]));

        return $row ? $row : [];
    }

    /** Předefinováno na Lashes **/
    public function appendAdditionalCosts(&$stockin, $stockInRow)
    {
        $additionalsCosts = toDecimal($stockInRow['transport_price']);
        $totalPrice = \DecimalConstants::zero();

        foreach ($stockin as $id => &$item) {
            $item['price'] = $this->preparePrice($item['price']);
            // fix Division by zero - convert string to float (quantity muze byt napr. "0.0000")
            $item['quantity'] = $this->preparePrice($item['quantity']);
            $item['additional_costs'] = 0;

            if (!$item['price'] || !$item['quantity']) {
                continue;
            }

            $totalPrice = $totalPrice->add(toDecimal($item['price'])->mul(toDecimal($item['quantity']))->abs());
        }

        foreach ($stockin as $id => &$item) {
            if (!$item['price'] || !$item['quantity']) {
                continue;
            }

            $itemsPrice = toDecimal($item['price'])->mul(toDecimal($item['quantity']))->abs();
            $itemsPiecesPerc = $itemsPrice->div($totalPrice);

            $item['additional_costs'] = $additionalsCosts->mul($itemsPiecesPerc)->div(toDecimal($item['quantity']))->asFloat();
        }

        return $stockin;
    }

    public function handleDelete()
    {
        if (!findRight('INSTORE_STOCKIN_ERASE')) {
            redirect('launch.php?s=error.php&id=1');
        }

        $ID = $this->getID();
        $SQL = sqlQuery('SELECT si.id_product, si.id_variation, si.quantity
         FROM '.getTableName('stock_in_items')." si
         WHERE si.id_stock_in={$ID} AND si.id_product IS NOT NULL");

        while (($row = sqlFetchAssoc($SQL)) !== false) {
            $this->storeIn($row['id_product'], $row['id_variation'], -$row['quantity']);
        }

        writeDownActivity(sprintf(translate('activityDeleted'), $ID));
        // smazat

        sqlQuery('DELETE FROM '.getTableName('stock_in')." WHERE id='{$ID}' ");

        redirect("launch.php?s={$this->getName()}.php&acn=erased");
    }

    public function handleDeleteValue($item)
    {
        if (!empty($item['id_product'])) {
            $this->storeIn($item['id_product'], $item['id_variation'], -$item['old_quantity']);
        }

        sqlQuery('DELETE FROM stock_in_items WHERE id=:id', ['id' => $item['id']]);
    }

    public function handleAddValue($item)
    {
        $data = $this->getData();
        $ID = $this->getID();
        $item['id_stock_in'] = $ID;

        $this->preparePrice($item['price']);
        $this->preparePrice($item['price_vat']);

        if (empty($item['price'])) {
            $item['price'] = 0;
        }
        if (empty($item['price_vat'])) {
            $item['price_vat'] = 0;
        }
        if (empty($item['quantity'])) {
            $item['quantity'] = 0;
        }

        $fields = ['id_stock_in', 'quantity', 'price', 'name', 'vat'];

        if (findModule(Modules::STOCK_IN, Modules::SUB_WEIGHTED_PURCHASE_PRICE)) {
            $fields[] = 'additional_costs';
        }

        if (!empty($item['id_product'])) {
            if (empty(intval($item['id_product']))) {
                return false;
            }

            $fields[] = 'id_product';
            $fields[] = 'id_variation';

            if (!empty($item['id_product_text'])) {
                $item['name'] = $item['id_product_text'];
            }

            if (empty($item['id_variation'])) {
                $item['id_variation'] = null;
            } else {
                $item['name'] = Variations::fillInProductTitle($item['id_variation'], $item['name']);
            }

            $vat = returnSQLResult('SELECT v.vat
             FROM '.getTableName('products').' p
             JOIN '.getTableName('vats')." v ON v.id=p.vat
             WHERE p.id={$item['id_product']} ");

            $item['vat'] = (float) $vat;

            if (empty($item['price'])) {
                $item['price'] = $item['price_vat'] / (1 + ($vat / 100));
            }
        } else {
            if (empty($item['product_text'])) {
                return false;
            }

            $vat = getAdminVat()['value'];

            if (empty($item['quantity'])) {
                $item['quantity'] = 1;
            }

            if (empty($price)) {
                $item['price'] = $item['price_vat'] / (1 + ($vat / 100));
            }

            $item['name'] = $item['product_text'];
            $fields[] = 'name';
            $item['vat'] = $vat;
        }

        $SQLfields = $this->getSQLFields($item, $fields);

        $this->insertSQL('stock_in_items', $SQLfields);

        if (!empty($item['id_product'])) {
            // Update store
            $this->storeIn($item['id_product'], $item['id_variation'], $item['quantity']);

            // Update suppliers code
            $item['supplier_code'] = trim($item['supplier_code']) ?: null;
            $GLOBALS['code'] = $item['supplier_code'];

            try {
                $this->stockInProductOfSupplierService->updateOrInsertProductSupplier($item, $data);
            } catch (Exception|\Doctrine\DBAL\Driver\Exception) {
                $this->addError("Nepodařilo se uložit kód dodavatele: {$item['supplier_code']}, položky: {$item['name']}");
            }
        }
    }

    public function handleUpdateValue($item)
    {
        if (empty($item['price']) && $item['id_product']) {
            $vat = returnSQLResult('SELECT v.vat
            FROM products p
            JOIN vats v ON v.id=p.vat
            WHERE p.id=:id_product', $item);
            $item['price'] = $item['price_vat'] / (1 + ($vat / 100));
        } else {
            $this->preparePrice($item['price']);
        }

        if ($item['id_product']) {
            if ($this->index_old == 'future' && $this->index == 'invoice') {
                $quantity = $item['quantity'];
                if (findModule(Modules::PRODUCTS, Modules::SUB_PRICE_BUY)
                    && findModule(Modules::PRODUCTS, Modules::SUB_PRICE_BUY) !== 'do_not_update'
                    && !findModule(Modules::STOCK_IN, Modules::SUB_WEIGHTED_PURCHASE_PRICE)
                ) {
                    $qb = sqlQueryBuilder()
                        ->update(($item['id_variation'] ?? false) ? 'products_variations' : 'products')
                        ->set('price_buy', $item['price']);
                    if ($item['id_variation'] ?? false) {
                        $qb->andWhere(Operator::equals(['id' => $item['id_variation']]));
                    } else {
                        $qb->andWhere(Operator::equals(['id' => $item['id_product']]));
                    }
                    $qb->execute();
                }
                // Naskladnění aktualizovat pouze v případě naskladnění, ne aktualizace faktury
                sqlQueryBuilder()
                    ->update('products')
                    ->set('date_stock_in', 'NOW()')
                    ->andWhere(Operator::equals(['id' => $item['id_product']]))
                    ->execute();
            } else {
                $quantity = $item['quantity'] - $item['old_quantity'];
            }

            $this->storeIn($item['id_product'], $item['id_variation'], $quantity);
        }

        $SQLFields = [
            'quantity' => $item['quantity'],
            'price' => $item['price'],
        ];

        if (findModule(Modules::STOCK_IN, Modules::SUB_WEIGHTED_PURCHASE_PRICE)) {
            $SQLFields['additional_costs'] = $item['additional_costs'];
        }

        $this->updateSQL('stock_in_items', $SQLFields, ['id' => $item['id']]);
        $this->recalcTotalPrice();
    }

    public function recalculateWeightedPrice($item)
    {
        $index = $this->getIndex();
        if (in_array($index, ['closure', 'future', 'preorder']) || empty($item['price'])) {
            return false;
        }

        if (findModule(Modules::STOCK_IN, Modules::SUB_WEIGHTED_PURCHASE_PRICE)) {
            $this->productPriceWeigher->updateWeightedPurchasePrice($item);
        }
    }

    public function handleClose()
    {
        $ID = $this->getID();
        sqlQuery('UPDATE '.getTableName('stock_in')." s
         SET s.closed=1
         WHERE s.id={$ID}");

        $ErrStr = "Záznam číslo {$ID} uzavřen.";

        // presmerovani
        redirect('launch.php?s=stockIn.php&acn=edit&refresh=parent&ID='.$ID.'&ErrStr='.$ErrStr);
    }

    public function handleImport()
    {
        $data = $this->getData();
        $data['id'] = $this->getID();

        $import = new StockInImport($data, $this->getIndex());
        try {
            $import->load_supplier_settings();
        } catch (Exception $e) {
            $this->returnError('Chyba importu: '.$e->getMessage());
        }
        if (!$import->import($_FILES['import'])) {
            $this->returnError('Chyba importu: '.join(', ', $import->errors));
        }

        $this->recalcTotalPrice();

        $this->returnOK('Import proběhl: '.join(', ', $import->errors));
    }

    public function handleCreateProduct()
    {
        $stockInID = $this->getID();
        $itemID = getVal('itemID');
        $success = false;

        if ($stockInID && $itemID) {
            try {
                sqlGetConnection()->transactional(function () use ($itemID, $stockInID, &$success) {
                    if ($item = $this->selectSQL('stock_in_items', ['id' => $itemID])->fetch()) {
                        $stockIn = $this->selectSQL('stock_in', ['id' => $stockInID])->fetch();

                        $name = $item['name'];
                        preg_match('/\(kód: (.*?)\)/', $name, $match);
                        if (!empty($match)) {
                            $name = str_replace($match[0], '', $name);
                            $code = $match[1];
                            $vatID = getAdminVat()['id'];
                            $vat = getAdminVat()['value'];

                            $insert = [
                                'title' => $name,
                                // 'code' => $code,
                                'vat' => $vatID,
                                'figure' => 'N',
                                'date_added' => date('Y-m-d H:i:s'),
                            ];

                            if ($this->getIndex() == 'invoice') {
                                $insert['in_store'] = $item['quantity'] ? $item['quantity'] : 0;
                            }

                            if (findModule(Modules::PRODUCTS, Modules::SUB_PRICE_BUY)) {
                                $insert['price_buy'] = toDecimal($item['price'])->addVat($vat);
                            }

                            $this->insertSQL('products', $insert);
                            $productID = sqlInsertId();

                            $this->updateSQL(
                                'stock_in_items',
                                [
                                    'id_product' => $productID,
                                    'vat' => $vat,
                                ],
                                ['id' => $itemID]
                            );

                            $this->insertSQL(
                                'products_of_suppliers',
                                [
                                    'id_product' => $productID,
                                    'id_supplier' => $stockIn['id_supplier'],
                                    'code' => $code,
                                ]
                            );

                            $success = true;
                        }
                    }
                });

                if ($success) {
                    $this->returnOK('Produkt byl úspěšně vytvořen');
                } else {
                    $this->returnError('Produkt se nepodařilo vytvořit');
                }
            } catch (Exception $e) {
                if (strpos($e->getMessage(), '1062 Duplicate entry')) {
                    $this->returnError('Nepodařilo se vytvořit produkt, protože produkt s takovým kódem už existuje.');
                } else {
                    $this->returnError('Při vytváření produktu se vyskytla chyba: '.$e->getMessage());
                }
            }
        }
    }

    public function getIndex()
    {
        if (is_null($this->index)) {
            try {
                $this->index = $this->getObject()['id_index'];
            } catch (NotFoundHttpException) {
                $this->index = '';
            }
        }

        return $this->index;
    }

    public function storeIn($id_product, $id_variation, $quantity)
    {
        $index = $this->getIndex();
        if (in_array($index, ['closure', 'future', 'preorder'])) {
            return false;
        }

        sqlGetConnection()->transactional(function () use ($quantity, $id_variation, $id_product) {
            $stockIn = true;

            if (findModule(Modules::STORES)) {
                $data = $this->getCustomData();
                $store_id = ($data['id_store'] ?? 1);
                $SQLfields = [
                    'id_store' => $store_id,
                    'id_product' => $id_product,
                    'id_variation' => $id_variation,
                    'quantity' => $quantity,
                ];

                ServiceContainer::getService(\KupShop\KupShopBundle\Util\LoggingContext::class)->activateStockIn($this->getID(), function () use ($SQLfields) {
                    $this->storesInStore->updateStoreItem($SQLfields);
                });

                $stores = $this->storesInStore->getStores();
                $store = $stores[$store_id];
                if ($store['type'] == StoresInStore::TYPE_EXTERNAL_STORE) {
                    $stockIn = false;
                }
            }

            if ($stockIn) {
                $prod = new Product($id_product);
                $prod->storeIn($id_variation, $quantity);
            }
        });

        return true;
    }

    public function hasRights($name = null)
    {
        switch ($name) {
            case Window::RIGHT_DUPLICATE:
                return false;
            case Window::RIGHT_DELETE:
                return findRight('INSTORE_STOCKIN_ERASE');
            default:
                return parent::hasRights($name);
        }
    }
}
