HEX
Server: Microsoft-IIS/8.5
System: Windows NT YDAWBH120 6.3 build 9600 (Windows Server 2012 R2 Standard Edition) AMD64
User: tentjecom_web (0)
PHP: 7.4.14
Disabled: NONE
Upload Files
File: D:/HostingSpaces/SBogers10/helder.komma.pro/app/Komma/Shop/Vies/ViesService.php
<?php


namespace App\Komma\Shop\Vies;

use App\KommaApp\Shop\Notifications\CustomersVatChecked;
use App\KommaApp\Users\Models\Role;
use App\KommaApp\Users\Models\User;
use function foo\func;
use Illuminate\Support\Collection;

/**
 * Class viesService
 *
 *
 *
 * @package App\Komma\Kms\Core
 */
class ViesService
{
    /**
     * This method will validate if a given vat number is genuine by checking a the Vies (Vat i
     *
     * @see http://ec.europa.eu/taxation_customs/vies/?locale=nl
     * @param string  $vatCode
     * @return mixed viesResult when $vatNumber is valid. int 0 if not valid and int -1 if the var could not be checked because the vies service was unavailable
     */
    public function validateVatNumber(string $vatCode)
    {
        $vatCode = str_replace(' ', '', $vatCode);

        if(!$this->vatIsCorrectlyFormatted($vatCode)) return false;
        //The vat is correct and an VAT of the EU

        $countryCode = $this->getCountryCodeFromVatCode($vatCode);
        $vatCodeWithoutCountryCode = $this->getVatCodeWithoutCountryCode($vatCode);

        //Check the VAT with the ec.europe load the soap client
        $client = new \SoapClient("http://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl");
        if(!$client) return -1;

        $params = [
            'countryCode' => $countryCode,
            'vatNumber' => $vatCodeWithoutCountryCode
        ];

        try {
            $response = $client->checkVat($params);
        } catch (\SoapFault $e) {
            //Service may be offline
            if($e->getMessage() == "INVALID_INPUT") return 0; //The provided CountryCode is invalid or the VAT number is empty
            return -1;
        }

        if ($response->valid) {
            $result = new ViesResult();
            if(property_exists($response, 'valid')) $result->setValid($response->valid);
            if(property_exists($response, 'vatNumber')) $result->setVatNumber($response->vatNumber);
            if(property_exists($response, 'requestDate')) $result->setRequestDate($response->requestDate);
            if(property_exists($response, 'name')) $result->setName($response->name);
            if(property_exists($response, 'address')) $result->setAddress($response->address);
            if(property_exists($response, 'countryCode')) $result->setCountryCode($response->countryCode);

            return $result;
        } else {
            return 0;
        }
    }

    /**
     * Gets the country code from a vat code or an empty string if none
     *
     * @param string $vatCode
     * @return string
     */
    public function getCountryCodeFromVatCode(string $vatCode)
    {
        $result = substr($vatCode, 0, 2);
        if($result == "" || $result == false) return '';
        else return $result;
    }

    /**
     * Gets the vat code without country code or an empty string if none
     *
     * @param string $vatCode
     * @return string
     */
    public function getVatCodeWithoutCountryCode(string $vatCode)
    {
        $result = substr($vatCode, 2);
        if($result == "" || $result == false) return '';
        else return $result;
    }

    /**
     * Checks if a vat number is correctly formatted
     *
     * @param string $vatCode
     * @return bool
     */
    public function vatIsCorrectlyFormatted(string $vatCode)
    {
        $regexes = [
            '(AT)?U[0-9]{8}',
            '(BE)?0[0-9]{9}',
            '(BG)?[0-9]{9,10}',
            '(CY)?[0-9]{8}L',
            '(CY)?[0-9]{8}L',
            '(CZ)?[0-9]{8,10}',
            '(DE)?[0-9]{9}',
            '(DK)?[0-9]{8}',
            '(EE)?[0-9]{9}',
            '(EL|GR)?[0-9]{9}',
            '(ES)?[0-9A-Z][0-9]{7}[0-9A-Z]',
            '(FI)?[0-9]{8}',
            '(FR)?[0-9A-Z]{2}[0-9]{9}',
            '(GB)?([0-9]{9}([0-9]{3}))',
            '(HU)?[0-9]{8}',
            '(?:IE)(?:\d{7}[a-zA-Z]$|\d{7}[a-zA-Z]{2}$|\d[a-zA-Z]\d{6}[a-zA-Z]{1}){1}',
            '(IT)?[0-9]{11}',
            '(LT)?([0-9]{9}|[0-9]{12})',
            '(LU)?[0-9]{8}',
            '(LV)?[0-9]{11}',
            '(MT)?[0-9]{8}',
            '(NL)?[0-9]{9}B[0-9]{2}',
            '(PL)?[0-9]{10}',
            '(PT)?[0-9]{9}',
            '(RO)?[0-9]{2,10}',
            '(SE)?[0-9]{12}',
            '(SI)?[0-9]{8}',
            '(SK)?[0-9]{10}'
        ];

        $completeRegex = '/'.implode('|', $regexes).'/'; //Concatenate them using an OR operator

        //The big EU vat checker
        $valid = preg_match($completeRegex, $vatCode);
        if($valid == 1 || $valid == 0) return $valid;
        else throw new \RuntimeException("Could not use regex. Probable incorrectly formatted");
    }

    /**
     * Checks all vat numbers of customers that are not validated yet and notifies admins about the result
     */
    public function recheckUserVatNumbersAndNotifyAdmins()
    {
        $customerCollection = $this->recheckUserVatNumbersThatAreNotValidated();
        $this->notifyAdminsOfVatNumberValidationChanges($customerCollection);
    }

    /**
     * Receives a collection Users (customers) who's vat numbers are checked and sends
     * admins a mail with the validation status of those customers
     *
     * @param Collection $customers
     */
    private function notifyAdminsOfVatNumberValidationChanges(Collection $customers)
    {
        if($customers->count() == 0) return;

        User::where('role_id', '=', Role::Admin)->get()->each(function(User $admin) use ($customers) {
            $admin->notify(new CustomersVatChecked($customers));
        });
    }

    /**
     * Checks all vat numbers of customers that are not validated yet. Updates them if needed.
     * Returns a collection of users who where not validated yet and now may be validated.
     */
    private function recheckUserVatNumbersThatAreNotValidated(): Collection
    {
        return User::where([['role_id', '=', Role::Customer], ['company_vat_number_validated', '=', 0]])->get()->each(function (User $customer) {
            $result = $this->validateVatNumber($customer->company_vat_number);
            if(is_a($result, ViesResult::class)) {
                $customer->company_vat_number_validated = 1;
            }
            else if(is_int($result))
            {
                $customer->company_vat_number_validated = 0;
            }

            $customer->save();
        });
    }
}