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/Setup/Patch/Data/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : /home/corals/old/app/code/Cnc/Catalog/Setup/Patch/Data/ConfigureMSIStocks.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]>
 */

namespace Cnc\Catalog\Setup\Patch\Data;

use Magento\Framework\Api\DataObjectHelper;
use Magento\Framework\Api\SearchCriteriaBuilder;
use Magento\Framework\App\RequestInterface;
use Magento\Framework\Exception\CouldNotDeleteException;
use Magento\Framework\Exception\CouldNotSaveException;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Framework\Setup\Patch\DataPatchInterface;
use Magento\Framework\Validation\ValidationException;
use Magento\InventoryAdminUi\Model\Stock\StockSaveProcessor;
use Magento\InventoryApi\Api\Data\SourceInterfaceFactory;
use Magento\InventoryApi\Api\Data\StockInterface;
use Magento\InventoryApi\Api\Data\StockInterfaceFactory;
use Magento\InventoryApi\Api\Data\StockSourceLinkInterface;
use Magento\InventoryApi\Api\Data\StockSourceLinkInterfaceFactory;
use Magento\InventoryApi\Api\GetStockSourceLinksInterface;
use Magento\InventoryApi\Api\SourceRepositoryInterface;
use Magento\InventoryApi\Api\StockRepositoryInterface;
use Magento\InventoryApi\Api\StockSourceLinksDeleteInterface;
use Magento\InventoryApi\Api\StockSourceLinksSaveInterface;
use Magento\InventorySalesApi\Api\Data\SalesChannelInterface;
use Magento\InventorySalesApi\Api\Data\SalesChannelInterfaceFactory;
use Psr\Log\LoggerInterface;

class ConfigureMSIStocks implements DataPatchInterface
{
    const SOURCE_CONFIG = [
        'fr' => [
            'code' => 'cnc_fr',
            'name' => 'FR',
            'postCode' => 75001,
            'country' => 'FR'
        ],
        'us' => [
            'code' => 'cnc_usa',
            'name' => 'USA',
            'postCode' => 33101,
            'country' => 'US'
        ],
    ];

    const STOCK_CONFIG = [
        'us' => [
            'name' => 'CNC Stock Prio USA',
            'websites' => ['cnc_us'],
            'sources' => [
                0 => [
                    'position' => 1,
                    'priority' => 3,
                    'name' => 'USA',
                    'record_id' => 'cnc_usa',
                    'source_code' => 'cnc_usa'
                ],
                1 => [
                    'position' => 2,
                    'priority' => 4,
                    'name' => 'FR',
                    'record_id' => 'cnc_fr',
                    'source_code' => 'cnc_fr'
                ]
            ]
        ],
        'fr' => [
            'name' => 'CNC Stock Prio FR',
            'websites' => ['cnc_eu', 'cnc_gb'],
            'sources' => [
                0 => [
                    'position' => 1,
                    'priority' => 3,
                    'name' => 'FR',
                    'record_id' => 'cnc_fr',
                    'source_code' => 'cnc_fr'
                ],
                1 => [
                    'position' => 2,
                    'priority' => 4,
                    'name' => 'USA',
                    'record_id' => 'cnc_usa',
                    'source_code' => 'cnc_usa'
                ]
            ]
        ],
    ];
    /**
     * @var StockInterfaceFactory
     */
    private $stockFactory;
    /**
     * @var SourceInterfaceFactory
     */
    private $sourceFactory;
    /**
     * @var SourceRepositoryInterface
     */
    private $sourceRepository;
    /**
     * @var StockSaveProcessor
     */
    private $stockSaveProcessor;
    /**
     * @var SalesChannelInterfaceFactory
     */
    private $salesChannelFactory;
    /**
     * @var StockRepositoryInterface
     */
    private $stockRepository;
    /**
     * @var GetStockSourceLinksInterface
     */
    private $getStockSourceLinks;
    /**
     * @var SearchCriteriaBuilder
     */
    private $searchCriteriaBuilder;
    /**
     * @var StockSourceLinkInterfaceFactory
     */
    private $stockSourceLinkFactory;
    /**
     * @var DataObjectHelper
     */
    private $dataObjectHelper;

    /**
     * @var StockSourceLinksSaveInterface
     */
    private $stockSourceLinksSave;

    /**
     * @var StockSourceLinksDeleteInterface
     */
    private $stockSourceLinksDelete;

    /**
     * @var RequestInterface
     */
    private $request;

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

    /**
     * ConfigureMSIStocks constructor.
     * @param SourceInterfaceFactory $sourceFactory
     * @param SourceRepositoryInterface $sourceRepository
     * @param RequestInterface $request
     * @param StockSaveProcessor $stockSaveProcessor
     * @param StockInterfaceFactory $stockFactory
     * @param SalesChannelInterfaceFactory $salesChannelFactory
     * @param StockRepositoryInterface $stockRepository
     * @param GetStockSourceLinksInterface $getStockSourceLinks
     * @param SearchCriteriaBuilder $searchCriteriaBuilder
     * @param StockSourceLinkInterfaceFactory $stockSourceLinkFactory
     * @param StockSourceLinksSaveInterface $stockSourceLinksSave
     * @param StockSourceLinksDeleteInterface $stockSourceLinksDelete
     * @param DataObjectHelper $dataObjectHelper
     * @param LoggerInterface $logger
     */
    public function __construct(
        SourceInterfaceFactory $sourceFactory,
        SourceRepositoryInterface $sourceRepository,
        RequestInterface $request,
        StockSaveProcessor $stockSaveProcessor,
        StockInterfaceFactory $stockFactory,
        SalesChannelInterfaceFactory $salesChannelFactory,
        StockRepositoryInterface $stockRepository,
        GetStockSourceLinksInterface $getStockSourceLinks,
        SearchCriteriaBuilder $searchCriteriaBuilder,
        StockSourceLinkInterfaceFactory $stockSourceLinkFactory,
        StockSourceLinksSaveInterface $stockSourceLinksSave,
        StockSourceLinksDeleteInterface $stockSourceLinksDelete,
        DataObjectHelper $dataObjectHelper,
        LoggerInterface $logger
    ) {
        $this->sourceFactory = $sourceFactory;
        $this->sourceRepository = $sourceRepository;
        $this->logger = $logger;
        $this->request = $request;
        $this->stockSaveProcessor = $stockSaveProcessor;
        $this->stockFactory = $stockFactory;
        $this->salesChannelFactory = $salesChannelFactory;
        $this->stockRepository = $stockRepository;
        $this->getStockSourceLinks = $getStockSourceLinks;
        $this->searchCriteriaBuilder = $searchCriteriaBuilder;
        $this->stockSourceLinkFactory = $stockSourceLinkFactory;
        $this->dataObjectHelper = $dataObjectHelper;
        $this->stockSourceLinksSave = $stockSourceLinksSave;
        $this->stockSourceLinksDelete = $stockSourceLinksDelete;
    }

    /**
     * @return ConfigureMSIStocks|void
     * @throws CouldNotDeleteException
     * @throws CouldNotSaveException
     * @throws ValidationException
     */
    public function apply()
    {
        //1. Add 2 new sources (FR + USA)
        foreach (self::SOURCE_CONFIG as $sourceData) {
            try {
                $source = $this->sourceRepository->get($sourceData['code']);
                if ($source->getSourceCode() == $sourceData['code']) {
                    $source->setPostcode($sourceData['postCode']);
                    $source->setName($sourceData['name']);
                    $source->setCountryId($sourceData['country']);
                }
            } catch (NoSuchEntityException $e) {
                $source = $this->sourceFactory->create();
                $source->setSourceCode($sourceData['code']);
                $source->setPostcode($sourceData['postCode']);
                $source->setName($sourceData['name']);
                $source->setCountryId($sourceData['country']);

                $this->sourceRepository->save($source);
            }
        }

        //2. Add Stocks for sources
        foreach (self::STOCK_CONFIG as $stockData) {
            $stockParams = [];
            $stockParams['general'] = [];
            $stockParams['sales_channels'] = [];
            $stockParams['sources'] = [];
            $stockParams['sources']['assigned_sources'] = [];
            $stockParams['assign_sources_grid'] = [];
            $stockParams['general']['name'] = $stockData['name'];
            $stockParams['sales_channels']['website'] = $stockData['websites'];

            foreach ($stockData['sources'] as $id => $data) {
                $stockParams['sources']['assigned_sources'][$id] = [
                    'source_code' => $data['source_code'],
                    'name' => $data['name'],
                    'position' => $data['position'],
                    'priority' => $data['priority'],
                    'record_id' => $data['record_id'],
                ];
                $stockParams['assign_sources_grid'][$id] = ['source_code' => $data['source_code']];
            }

            $stockId = $this->processStockSave($stockParams);
            $this->processStockLinkSave($stockId, $stockParams);
        }
    }

    /**
     * @return array|string[]
     */
    public static function getDependencies(): array
    {
        return [];
    }

    /**
     * @return array|string[]
     */
    public function getAliases(): array
    {
        return [];
    }

    /**
     * @param $stockParams
     * @return int
     * @throws CouldNotSaveException
     * @throws ValidationException
     */
    private function processStockSave($stockParams): int
    {
        $stock = $this->stockFactory->create();
        $this->dataObjectHelper->populateWithArray($stock, $stockParams['general'], StockInterface::class);
        $extensionAttributes = $stock->getExtensionAttributes();
        $assignedSalesChannels = $extensionAttributes->getSalesChannels();

        if (null !== $assignedSalesChannels) {
            foreach ($assignedSalesChannels as $key => $assignedSalesChannel) {
                if ($assignedSalesChannel->getType() === SalesChannelInterface::TYPE_WEBSITE) {
                    unset($assignedSalesChannels[$key]);
                }
            }
        }

        if (isset($stockParams['sales_channels'][SalesChannelInterface::TYPE_WEBSITE])
            && is_array($stockParams['sales_channels'][SalesChannelInterface::TYPE_WEBSITE])
        ) {
            foreach ($stockParams['sales_channels'][SalesChannelInterface::TYPE_WEBSITE] as $websiteCode) {
                $assignedSalesChannels[] = $this->createSalesChannelByWebsiteCode($websiteCode);
            }
        }
        $extensionAttributes->setSalesChannels($assignedSalesChannels);

        return $this->stockRepository->save($stock);
    }

    /**
     * Create the sales channel by given website code
     *
     * @param string $websiteCode
     * @return SalesChannelInterface
     */
    private function createSalesChannelByWebsiteCode(string $websiteCode): SalesChannelInterface
    {
        $salesChannel = $this->salesChannelFactory->create();
        $salesChannel->setCode($websiteCode);
        $salesChannel->setType(SalesChannelInterface::TYPE_WEBSITE);
        return $salesChannel;
    }

    /**
     * @param int $stockId
     * @param $stockData
     * @throws CouldNotDeleteException
     * @throws CouldNotSaveException
     * @throws ValidationException
     */
    private function processStockLinkSave(int $stockId, $stockData)
    {
        $assignedSources =
            isset($stockData['sources']['assigned_sources'])
            && is_array($stockData['sources']['assigned_sources'])
                ? $this->prepareAssignedSources($stockData['sources']['assigned_sources'])
                : [];

        $linksForDelete = $this->getAssignedLinks($stockId);
        $linksForSave = [];

        foreach ($assignedSources as $linkData) {
            $sourceCode = $linkData[StockSourceLinkInterface::SOURCE_CODE];

            if (isset($linksForDelete[$sourceCode])) {
                $link = $linksForDelete[$sourceCode];
            } else {
                /** @var StockSourceLinkInterface $link */
                $link = $this->stockSourceLinkFactory->create();
            }

            $linkData[StockSourceLinkInterface::STOCK_ID] = $stockId;
            $this->dataObjectHelper->populateWithArray($link, $linkData, StockSourceLinkInterface::class);

            $linksForSave[] = $link;
            unset($linksForDelete[$sourceCode]);
        }

        if (count($linksForSave) > 0) {
            $this->stockSourceLinksSave->execute($linksForSave);
        }
        if (count($linksForDelete) > 0) {
            $this->stockSourceLinksDelete->execute($linksForDelete);
        }
    }

    /**
     * Convert built-in UI component property position into priority
     *
     * @param array $assignedSources
     * @return array
     */
    private function prepareAssignedSources(array $assignedSources): array
    {
        foreach ($assignedSources as $key => $source) {
            if (empty($source['priority'])) {
                $source['priority'] = (int)$source['position'];
                $assignedSources[$key] = $source;
            }
        }
        return $assignedSources;
    }

    /**
     * Retrieves links that are assigned to $stockId
     *
     * @param int $stockId
     * @return StockSourceLinkInterface[]
     */
    private function getAssignedLinks(int $stockId): array
    {
        $searchCriteria = $this->searchCriteriaBuilder
            ->addFilter(StockSourceLinkInterface::STOCK_ID, $stockId)
            ->create();

        $result = [];
        foreach ($this->getStockSourceLinks->execute($searchCriteria)->getItems() as $link) {
            $result[$link->getSourceCode()] = $link;
        }
        return $result;
    }
}

Spamworldpro Mini