Spamworldpro Mini Shell
Spamworldpro


Server : Apache
System : Linux server2.corals.io 4.18.0-348.2.1.el8_5.x86_64 #1 SMP Mon Nov 15 09:17:08 EST 2021 x86_64
User : corals ( 1002)
PHP Version : 7.4.33
Disable Function : exec,passthru,shell_exec,system
Directory :  /home/corals/old/app/code/Cnc/Catalog/Console/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : /home/corals/old/app/code/Cnc/Catalog/Console/ImportProductStock.php
<?php
/**
 * Copyright (c) 2020 Kaliop Digital Commerce (https://digitalcommerce.kaliop.com) All Rights Reserved.
 * https://opensource.org/licenses/OSL-3.0  Open Software License (OSL 3.0)
 * Cnc
 * Arkadiusz Tokarczyk <[email protected]> <[email protected]>
 */

namespace Cnc\Catalog\Console;

use Cnc\Catalog\Model\ResourceModel\DataFactory as SourceDataFactory;
use Cnc\SerialNumber\Api\Data\SerialNumberInterface;
use Cnc\SerialNumber\Api\IsSerialNumberEnabledForProductInterface;
use Cnc\SerialNumber\Api\SerialNumberRepositoryInterface;
use Cnc\SerialNumber\Helper\SerialNumber;
use Cnc\SerialNumber\Model\Source\SerialNumber\Status;
use Magento\Catalog\Api\Data\ProductInterface;
use Magento\Catalog\Model\ResourceModel\Product;
use Magento\Framework\App\ResourceConnection;
use Magento\Framework\Api\SearchCriteriaBuilderFactory;
use Magento\InventoryApi\Api\Data\SourceItemInterface;
use Magento\InventoryApi\Api\SourceItemRepositoryInterface;
use Magento\InventoryImportExport\Model\Import\SourcesFactory as Importer;
use Magento\Setup\Exception;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;

class ImportProductStock extends Command
{
    const LIMIT = 'limit';
    const CLEAR_STOCKS = 'clear-stock-data';

    /**
     * @var SourceDataFactory
     */
    private $sourceDataFactory;
    /**
     * @var Importer
     */
    private $importer;
    /**
     * @var ResourceConnection
     */
    private $resource;

    /**
     * @var IsSerialNumberEnabledForProductInterface
     */
    private $isSerialNumberEnabledForProduct;

    /**
     * @var SearchCriteriaBuilderFactory
     */
    private $searchCriteriaBuilderFactory;

    /**
     * @var SourceItemRepositoryInterface
     */
    private $sourceItemRepository;

    /**
     * @var SerialNumber
     */
    private $helper;

    /**
     * @var Product
     */
    private $resourceProduct;

    /**
     * @var SerialNumberRepositoryInterface
     */
    private $serialNumberRepository;

    /**
     * ImportProductStock constructor.
     * @param SourceDataFactory $sourceDataFactory
     * @param Importer $importer
     * @param ResourceConnection $resource
     * @param IsSerialNumberEnabledForProductInterface $isSerialNumberEnabledForProduct
     * @param SearchCriteriaBuilderFactory $searchCriteriaBuilderFactory
     * @param SourceItemRepositoryInterface $sourceItemRepository
     * @param SerialNumber $helper
     * @param Product $resourceProduct
     * @param SerialNumberRepositoryInterface $serialNumberRepository
     * @param string|null $name
     */
    public function __construct(
        SourceDataFactory $sourceDataFactory,
        Importer $importer,
        ResourceConnection $resource,
        IsSerialNumberEnabledForProductInterface $isSerialNumberEnabledForProduct,
        SearchCriteriaBuilderFactory $searchCriteriaBuilderFactory,
        SourceItemRepositoryInterface $sourceItemRepository,
        SerialNumber $helper,
        Product $resourceProduct,
        SerialNumberRepositoryInterface $serialNumberRepository,
        string $name = null
    ) {
        parent::__construct($name);
        $this->sourceDataFactory = $sourceDataFactory;
        $this->importer = $importer;
        $this->resource = $resource;
        $this->isSerialNumberEnabledForProduct = $isSerialNumberEnabledForProduct;
        $this->searchCriteriaBuilderFactory = $searchCriteriaBuilderFactory;
        $this->sourceItemRepository = $sourceItemRepository;
        $this->helper = $helper;
        $this->resourceProduct = $resourceProduct;
        $this->serialNumberRepository = $serialNumberRepository;
    }

    /**
     * @inheritDoc
     */
    protected function configure()
    {
        $this->setName('catalog:products:stock-import');
        $this->setDescription('Stock import for source');
        $this->addOption(
            self::LIMIT,
            null,
            InputOption::VALUE_OPTIONAL,
            'Use limit in case of too many data'
        );
        $this->addOption(
            self::CLEAR_STOCKS,
            null,
            InputOption::VALUE_OPTIONAL,
            'Clear stocks temp table and stock info. WARNING! This will remove all stock info for Available sources.'
        );
        parent::configure();
    }

    /**
     * @param InputInterface $input
     * @param OutputInterface $output
     * @return int|void
     */
    protected function execute(InputInterface $input, OutputInterface $output)
    {
        if ($input->getOption(self::CLEAR_STOCKS)) {
            $this->clearImportTable();
            $this->clearStockItems();
        } else {
            $output->writeln("Preparing stock data for import...");
            $connection = $this->resource->getConnection();

            $select = $connection->select()
                ->from($connection->getTableName('cnc_stock_import'))
                ->where('is_imported = 0');

            if ($input->getOption(self::LIMIT) > 0) {
                $select->limit($input->getOption('limit'));
            }
            $data = $connection->fetchAssoc($select);

            $importData = [];
            $stockIdToUpdate = [];
            if (!empty($data)) {
                foreach ($data as $stockItem) {
                    $importData[] = [
                        'source_code' => $stockItem['source_code'],
                        'sku' => $stockItem['sku'],
                        'quantity' => $stockItem['qty']
                    ];
                    $stockIdToUpdate[] = $stockItem['cnc_stock_id'];
                }
                try {
                    $sourceModel = $this->sourceDataFactory->create(['data' => [$importData]]);
                    $stock = $this->importer->create(['importData' => $sourceModel]);
                    $stock->importData();

                    $output->writeln('Import S/N: ' . count($importData));
                    $i = 0;
                    foreach ($importData as $data) {
                        try {
                            $i++;
                            $output->write($i % 100 == 0 ? $i : '.');
                            $sku = $data['sku'];
                            $sourceCode = $data['source_code'];
                            if ($this->isSerialNumberEnabledForProduct->execute($sku)) {
                                $serialNumbers = $this->getSerialNumbers($sku, $sourceCode);
                                $currentQty = count($serialNumbers);
                                $newQty = $data['quantity'];

                                $diffQty = $newQty - $currentQty;
                                if ($diffQty > 0) {
                                    $this->helper->createSerialNumbers(
                                        (int)$this->resourceProduct->getIdBySku($sku),
                                        (string)$sku,
                                        (string)$sourceCode,
                                        (int)$diffQty
                                    );
                                } elseif ($diffQty < 0) {
                                    $this->helper->blockSerialNumbers((string)$sku, $sourceCode, (int)abs($diffQty));
                                }
                            }
                        } catch (\Exception $e) {
                            $output->writeln($e->getMessage());
                        }
                    }

                    $connection->update(
                        $connection->getTableName('cnc_stock_import'),
                        ['is_imported' => 1, 'import_date' => date('Y-m-d H:i:s')],
                        sprintf('cnc_stock_id IN (%s)', implode(',', $stockIdToUpdate))
                    );
                } catch (Exception $exception) {
                    $output->writeln($exception->getMessage());
                }
            } else {
                $output->writeln('Nothing to import.');
            }
        }
    }

    /**
     * Truncate import table.
     */
    private function clearImportTable()
    {
        $connection = $this->resource->getConnection();
        $connection->truncateTable($connection->getTableName('cnc_stock_import'));
    }

    /**
     * Truncate inventory table
     */
    private function clearStockItems()
    {
        $connection = $this->resource->getConnection();
        $connection->truncateTable($connection->getTableName('inventory_source_item'));
    }

    /**
     * @param string $sku
     * @return array
     */
    private function getSerialNumbers(string $sku, string $sourceCode): array
    {
        $searchCriteriaBuilder = $this->searchCriteriaBuilderFactory->create();
        $searchCriteria = $searchCriteriaBuilder
            ->addFilter(SerialNumberInterface::SKU, $sku)
            ->addFilter(SerialNumberInterface::SOURCE_CODE, $sourceCode)
            ->create();

        return $this->serialNumberRepository->getList($searchCriteria)->getItems();
    }
}

Spamworldpro Mini