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/SerialNumber/Console/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : /home/corals/old/app/code/Cnc/SerialNumber/Console/ImportSerialNumber.php
<?php
/**
 * Copyright (c) 2021 Kaliop Digital Commerce (https://digitalcommerce.kaliop.com) All Rights Reserved.
 * https://opensource.org/licenses/OSL-3.0  Open Software License (OSL 3.0)
 * Cnc
 * Radosław Stępień <[email protected]> <[email protected]>
 */
namespace Cnc\SerialNumber\Console;

use Cnc\Catalog\Model\Config as CncCatalogConfig;
use Cnc\SerialNumber\Helper\Config;
use Cnc\SerialNumber\Model\Import\Logger;
use Cnc\SerialNumber\Model\Source\SerialNumber\Status;
use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory;
use Magento\Framework\App\ResourceConnection;
use Magento\Framework\DB\Adapter\AdapterInterface;
use Magento\Framework\Exception\FileSystemException;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\Filesystem\Driver\File;
use Magento\Framework\Setup\SampleData\FixtureManager;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

class ImportSerialNumber extends Command
{
    /**
     * @var CollectionFactory
     */
    private $collectionFactory;

    /**
     * @var ResourceConnection
     */
    private $resourceConnection;

    /**
     * @var File
     */
    private $file;

    /**
     * @var FixtureManager
     */
    private $fixtureManager;

    /**
     * @var Logger
     */
    private $logger;

    private $adminId;
    /** @var AdapterInterface $connection */
    private $connection;
    private $soldData = [];
    private $availableData = [];

    /**
     * ImportSerialNumber constructor.
     * @param CollectionFactory $collectionFactory
     * @param ResourceConnection $resourceConnection
     * @param File $file
     * @param FixtureManager $fixtureManager
     * @param Logger $logger
     * @param string|null $name
     */
    public function __construct(
        CollectionFactory $collectionFactory,
        ResourceConnection $resourceConnection,
        File $file,
        FixtureManager $fixtureManager,
        Logger $logger,
        string $name = null
    ) {
        parent::__construct($name);
        $this->collectionFactory = $collectionFactory;
        $this->resourceConnection = $resourceConnection;
        $this->fixtureManager = $fixtureManager;
        $this->logger = $logger;
        $this->file = $file;
    }

    /**
     * @inheritDoc
     */
    protected function configure()
    {
        $this->setName('catalog:serial_number:import_serial_number');
        $this->setDescription('Import serial numbers data');
        parent::configure();
    }

    /**
     * @param InputInterface $input
     * @param OutputInterface $output
     * @throws FileSystemException
     * @throws LocalizedException
     */
    protected function execute(InputInterface $input, OutputInterface $output): void
    {
        $importedItems = 0;
        $this->clearLogFile();
        $output->writeln('START IMPORTING SERIAL NUMBERS');
        $this->initConnection();
        $this->initAdminId();
        $this->initDataFromFixture();
        $soldDataCount = count($this->soldData);
        $availableDataCount = count($this->availableData);
        $output->writeln('Data prepared:');
        $output->writeln($soldDataCount . ' sold serial numbers to be imported');
        $output->writeln($availableDataCount . ' available serial numbers to be imported');
        $groupedAvailableSerialNumbers = $this->getGroupedAvailableSerialNumbers();
        $output->writeln('Available serial numbers import in progress');
        foreach ($groupedAvailableSerialNumbers as $productId => $availableSerialNumberGroup) {
            $numberOfSerialNumbersToDelete = count($availableSerialNumberGroup);
            $productSku = $this->getProductSkuByOscomId($productId) ?: '';
            if ($productSku) {
                $this->logger->log($numberOfSerialNumbersToDelete . ' serial numbers to overwrite for product sku: '
                    . $productSku . ', oscommerce ID: ' . $productId);
                // Removing new cnc serial numbers to be replaced by old oscommerce values
                //phpcs:disable
                $this->connection->query('DELETE FROM ' . Config::CNC_SERIAL_NUMBER_TABLE_NAME
                    . ' WHERE sku = "'. $productSku .'" AND status = '. Status::AVAILABLE .' LIMIT '. $numberOfSerialNumbersToDelete .';');
                //phpcs:enable
                foreach ($availableSerialNumberGroup as $availableSerialNumber) {
                    if ($importedItems % 100 == 0) {
                        $output->write($importedItems . '/' . $availableDataCount . ' | ');
                    }
                    $this->createNewSerialNumber($availableSerialNumber, Status::AVAILABLE);
                    if (isset($availableSerialNumber['stocks_libelle'])) {
                        $this->logger->log($availableSerialNumber['stocks_libelle'] . ' serial number was added.');
                    }
                    $importedItems++;
                }
                $this->logger->log($numberOfSerialNumbersToDelete . ' serial numbers was overwritten.');
            }
        }
        $output->writeln('Available serial numbers imported correctly');
        $output->writeln('Sold serial numbers import in progress');
        $importedItems = 0;
        foreach ($this->soldData as $soldSerialNumber) {
            if ($importedItems % 100 == 0) {
                $output->write($importedItems . '/' . $soldDataCount . ' | ');
            }
            $this->createNewSerialNumber($soldSerialNumber, Status::SOLD);
            if (isset($soldSerialNumber['stocks_libelle'])) {
                $this->logger->log($soldSerialNumber['stocks_libelle'] . ' old serial number was added.');
            }
            $importedItems++;
        }
        $output->writeln('Sold serial numbers imported correctly');

        $output->writeln('[OK] FINISH');
    }

    /**
     * @param $serialNumber
     * @param $status
     */
    private function createNewSerialNumber($serialNumber, $status)
    {
        $tableName = $this->connection->getTableName(Config::CNC_SERIAL_NUMBER_TABLE_NAME);
        $productSku = isset($serialNumber['products_id'])
            ? $this->getProductSkuByOscomId($serialNumber['products_id'])
            : '';
        $this->connection->insertOnDuplicate(
            $tableName,
            [
                'serial_number' => isset($serialNumber['stocks_libelle'])
                    ? $serialNumber['stocks_libelle']
                    : '',
                'source_code' => 'cnc_fr',
                'sku' => $productSku,
                'origin' => isset($serialNumber['stocks_physique_origine'])
                    ? $serialNumber['stocks_physique_origine']
                    : '',
                'created_at' => isset($serialNumber['stocks_physique_date'])
                    ? $serialNumber['stocks_physique_date']
                    : '',
                'admin_user_id' => $this->adminId,
                'status' => $status,
                'is_exported' => 0
            ]
        );
    }

    /**
     * @param $oscomId
     * @return string
     */
    private function getProductSkuByOscomId($oscomId)
    {
        $osComAttributeId = $this->connection->fetchOne(
            $this->connection->select()
                ->from('eav_attribute')
                ->columns('attribute_id')
                ->where('attribute_code = "' . CncCatalogConfig::PRODUCT_ATTRIBUTE_CODE_OSCOMMERCE_ID . '"')
        );
        // Fetch whole row and after that retrieve entity_id because select on single column returns value_id column
        $productEntityIntRow = $this->connection->fetchRow(
            $this->connection->select()
                ->from('catalog_product_entity_int')
                ->where('attribute_id = "' . $osComAttributeId . '" AND value = "' . $oscomId . '"')
        );
        $productMagentoId = isset($productEntityIntRow['entity_id']) ? $productEntityIntRow['entity_id'] : '';
        // Fetch whole row and after that retrieve sku because select on single column returns entity_id column
        $productRow = $this->connection->fetchRow(
            $this->connection->select()
                ->from('catalog_product_entity')
                ->columns('sku')
                ->where('entity_id = "' . $productMagentoId . '"')
        );

        return isset($productRow['sku']) ? $productRow['sku'] : '';
    }

    /**
     * @return array
     */
    private function getGroupedAvailableSerialNumbers()
    {
        $groupedAvailableSerialNumbers = [];
        foreach ($this->availableData as $serialNumber) {
            if (isset($serialNumber['products_id'])) {
                $groupedAvailableSerialNumbers[$serialNumber['products_id']][]
                    = $serialNumber;
            }
        }
        return $groupedAvailableSerialNumbers;
    }

    /**
     * @throws FileSystemException
     * @throws LocalizedException
     */
    private function initDataFromFixture()
    {
        $fileToOpen = $this->fixtureManager->getFixture(Config::FIXTURE_SERIAL_NUMBER_DATA_FILE_PATH);
        $file = $this->file->fileOpen($fileToOpen, "r");
        $header = $this->file->fileGetCsv($file, 0, ";");
        while ($row = $this->file->fileGetCsv($file, 0, ";")) {
            //Set headers on new row to call array elements by names
            $rowWithHeaders = array_filter(array_combine($header, $row));
            if (isset($rowWithHeaders['stocks_quantity']) && $rowWithHeaders['stocks_quantity'] > 0) {
                $this->availableData[] = array_filter(array_combine($header, $row));
            } else {
                $this->soldData[] = array_filter(array_combine($header, $row));
            }
        }
    }

    /**
     * Initialize admin user ID used in serial numbers data
     */
    private function initAdminId()
    {
        $this->adminId = $this->connection->fetchOne(
            $this->connection->select()
                ->from('admin_user')
                ->columns('user_id')
                ->where('username = "'.Config::ADMIN_USER_USERNAME.'"')
        );
        if (!$this->adminId) {
            //Fetch any admin ID in case of removed native admin user
            $this->adminId = $this->connection->fetchOne(
                $this->connection->select()->from('admin_user')->columns('user_id')
            );
        }
    }

    /**
     * Initialize connection used to fetch data from db / save new data
     */
    private function initConnection()
    {
        $this->connection = $this->resourceConnection->getConnection();
    }

    /**
     * No need to keep previous imports unnecessary data, because it is one time import
     * @throws FileSystemException
     */
    private function clearLogFile()
    {
        if ($this->file->isExists(BP . '/var/log/' . Logger::LOG_FILE)) {
            $this->file->filePutContents(BP . '/var/log/' . Logger::LOG_FILE, '');
        }
    }
}

Spamworldpro Mini