Your IP : 127.0.0.1


Current Path : /home/dev2.destoffenstraat.com/app/code/Geissweb/Euvat/Console/Command/
Upload File :
Current File : /home/dev2.destoffenstraat.com/app/code/Geissweb/Euvat/Console/Command/CleanVatNumbers.php

<?php
/**
 * ||GEISSWEB| EU VAT Enhanced
 *
 * NOTICE OF LICENSE
 *
 * This source file is subject to the GEISSWEB End User License Agreement
 * that is available through the world-wide-web at this URL: https://www.geissweb.de/legal-information/eula
 *
 * DISCLAIMER
 *
 * Do not edit this file if you wish to update the extension in the future. If you wish to customize the extension
 * for your needs please refer to our support for more information.
 *
 * @copyright   Copyright (c) 2015 GEISS Weblösungen (https://www.geissweb.de)
 * @license     https://www.geissweb.de/legal-information/eula GEISSWEB End User License Agreement
 */
declare(strict_types=1);

namespace Geissweb\Euvat\Console\Command;

use Geissweb\Euvat\Api\ValidationRepositoryInterface;
use Geissweb\Euvat\Logger\Logger;
use Geissweb\Euvat\Validator\Syntax;
use Geissweb\Euvat\Model\ValidationRepository;
use Geissweb\Euvat\Helper\VatNumber\Formatter;
use Magento\Customer\Api\AddressRepositoryInterface;
use Magento\Framework\Api\FilterBuilder;
use Magento\Framework\Api\SearchCriteriaBuilder;
use Magento\Framework\Exception\LocalizedException;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Helper\ProgressBar;
use Symfony\Component\Console\Helper\Table;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

/**
 * Class CleanVatNumbers can help clean up old and invalid entries from existing customer addresses
 */
class CleanVatNumbers extends Command
{
    public const ARG_EXECUTE = "execute";
    public Formatter $formatter;
    private AddressRepositoryInterface $addressRepository;
    private FilterBuilder $filterBuilder;
    private SearchCriteriaBuilder $searchCriteriaBuilder;
    private ValidationRepositoryInterface $validationRepository;
    private Logger $logger;
    private Syntax $syntaxValidator;

    /**
     * CleanVatNumbers constructor.
     *
     * @param Formatter                  $vatNumberFormatter
     * @param ValidationRepository       $validationRepository
     * @param Syntax                     $syntaxValidator
     * @param Logger                     $logger
     * @param SearchCriteriaBuilder      $searchCriteriaBuilder
     * @param FilterBuilder              $filterBuilder
     * @param AddressRepositoryInterface $addressRepository
     */
    public function __construct(
        Formatter $vatNumberFormatter,
        ValidationRepository $validationRepository,
        Syntax $syntaxValidator,
        Logger $logger,
        SearchCriteriaBuilder $searchCriteriaBuilder,
        FilterBuilder $filterBuilder,
        AddressRepositoryInterface $addressRepository
    ) {
        parent::__construct('geissweb:clean:vatnumbers');
        $this->formatter = $vatNumberFormatter;
        $this->addressRepository = $addressRepository;
        $this->filterBuilder = $filterBuilder;
        $this->searchCriteriaBuilder = $searchCriteriaBuilder;
        $this->validationRepository = $validationRepository;
        $this->logger = $logger;
        $this->syntaxValidator = $syntaxValidator;
    }

    /**
     * @inheritdoc
     */
    protected function execute(
        InputInterface $input,
        OutputInterface $output
    ): int {
        $doExecute = $input->getArgument(self::ARG_EXECUTE) === 'execute';
        $output->writeln("\nThis command will remove invalid VAT numbers from customer addresses.
Either if the syntax is invalid or if it has been validated already and the result is invalid.
It will also clean up valid numbers and removing whitespaces and special chars from the number.\n");
        if (!$doExecute) {
            $output->writeln(
                "<comment>DRY RUN</comment> - use `geissweb:clean:vatnumbers execute` to actually do changes.\n"
            );
        }
        $vatNumberFilter = $this->filterBuilder->setField('vat_id')
            ->setValue('')
            ->setConditionType('neq')
            ->create();
        $searchCriteria = $this->searchCriteriaBuilder->addFilters([$vatNumberFilter])->create();
        $list = $this->addressRepository->getList($searchCriteria);

        $output->writeln("Found " . $list->getTotalCount() . " VAT numbers in the database.");
        $progressBar = new ProgressBar($output, $list->getTotalCount());
        $progressBar->start();

        $table = new Table($output);
        $table->setHeaders(['Address ID', 'Country', 'VAT Number', 'VAT Number cleaned', 'Message']);
        $rows = [];

        foreach ($list->getItems() as $address) {
            $rowData = [$address->getId()];
            $rowData[] = $address->getCountryId();
            $rowData[] = $address->getVatId();
            $changes = false;

            $cleanedNumber = $this->formatter->formatVatNumber($address->getVatId(), $address->getCountryId());
            $rowData[] = $cleanedNumber;

            $vatInfo = $this->formatter->splitVatNumber($cleanedNumber);
            $vatValidation = $this->validationRepository->getByVatId($cleanedNumber);

            if (!$this->syntaxValidator->isValid($vatInfo['number'], $vatInfo['cc'])
                || (
                    $vatValidation !== false
                    && !$vatValidation->getVatIsValid()
                    && $vatValidation->getVatRequestSuccess()
                )
            ) {
                $rowData[] =
                    '<error>Number invalid and being removed from the address with ID: '.$address->getId().'</error>';
                $address->setVatId('');
                $changes = true;
            } elseif ($cleanedNumber !== $address->getVatId()) {
                $rowData[] =
                    '<info>Updating cleaned number: ' . $cleanedNumber . ' (was ' . $address->getVatId() . ')</info>';
                $address->setVatId($cleanedNumber);
                $changes = true;
            } elseif ($vatValidation !== false
                && $vatValidation->getVatIsValid()
                && $vatValidation->getVatRequestSuccess()
            ) {
                $rowData[] = '<info>Number is valid</info>';
            } elseif ($vatValidation === false) {
                $rowData[] = '<comment>Number is not validated yet.</comment>';
            } else {
                $rowData[] = '';
            }

            if ($doExecute && $changes) {
                try {
                    $this->addressRepository->save($address);
                } catch (LocalizedException $exc) {
                    $output->writeln("Unable to save address: " . $exc->getMessage());
                    $this->logger->critical($exc);
                }
            }
            $rows[] = $rowData;
            $progressBar->advance();
        }
        $progressBar->finish();
        $output->writeln("\n");
        $table->setRows($rows)->render();

        return 1;
    }

    /**
     * @inheritdoc
     */
    protected function configure(): void
    {
        $this->setDescription("
            Cleans up or fixes VAT numbers from the customer addresses. Use with 'execute' to do changes.
        ");
        $this->setDefinition([
            new InputArgument(
                self::ARG_EXECUTE,
                InputArgument::OPTIONAL,
                "Without this parameter, no changes to the database are made"
            )
        ]);
        parent::configure();
    }
}