YetiForceCompany/YetiForceCRM

View on GitHub
app/RecordCollectors/VatifyEu.php

Summary

Maintainability
B
6 hrs
Test Coverage
F
0%
<?php
/**
 * Vatify API file.
 *
 * @see https://www.vatify.eu/coverage.html
 * @see https://api.vatify.eu/v1/demo/ TEST API URL
 * @see https://api.vatify.eu/v1/ PROD API URL
 *
 * @package App
 *
 * @copyright YetiForce S.A.
 * @license   YetiForce Public License 6.5 (licenses/LicenseEN.txt or yetiforce.com)
 * @author    SÅ‚awomir Rembiesa <s.rembiesa@yetiforce.com>
 * @author    Mariusz Krzaczkowski <m.krzaczkowski@yetiforce.com>
 */

namespace App\RecordCollectors;

/**
 * Vatify API class.
 */
class VatifyEu extends Base
{
    /** {@inheritdoc} */
    public $allowedModules = ['Accounts', 'Leads', 'Vendors', 'Partners', 'Competition'];

    /** {@inheritdoc} */
    public $icon = 'yfi-vatify-eu';

    /** {@inheritdoc} */
    public $label = 'LBL_VATIFY_EU';

    /** {@inheritdoc} */
    public $displayType = 'FillFields';

    /** {@inheritdoc} */
    public $description = 'LBL_VATIFY_DESC_EU';

    /** {@inheritdoc} */
    public $docUrl = 'https://www.vatify.eu/docs/api/getting-started/';

    /** {@inheritdoc} */
    public $settingsFields = [
        'client_id' => ['required' => 1, 'purifyType' => 'Text', 'label' => 'LBL_CLIENT_ID'],
        'access_key' => ['required' => 1, 'purifyType' => 'Text', 'label' => 'LBL_ACCESS_KEY'],
    ];

    /** {@inheritdoc} */
    public $formFieldsToRecordMap = [
        'Accounts' => [
            'title' => 'accountname',
            'transliteratedTitle' => 'accountname',
            'registration_number' => 'registration_number_1',
            'identifier' => 'vat_id',
            'tax_id_number' => 'vat_id',
            'sector' => 'siccode',
            'transliteratedSector' => 'siccode',
            'address' => 'addresslevel8a',
            'transliteratedAddress' => 'addresslevel8a',
            'postal_code' => 'addresslevel7a',
            'city' => 'addresslevel5a',
            'transliteratedCity' => 'addresslevel5a',
            'community' => 'addresslevel4a',
            'region' => 'addresslevel2a',
            'transliteratedRegion' => 'addresslevel2a',
            'country' => 'addresslevel1a',
            'phone_number' => 'phone',
            'fax_number' => 'fax',
            'email_address' => 'email1',
        ],
        'Leads' => [
            'title' => 'company',
            'transliteratedTitle' => 'company',
            'registration_number' => 'registration_number_1',
            'identifier' => 'vat_id',
            'tax_id_number' => 'vat_id',
            'address' => 'addresslevel8a',
            'transliteratedAddress' => 'addresslevel8a',
            'postal_code' => 'addresslevel7a',
            'city' => 'addresslevel5a',
            'transliteratedCity' => 'addresslevel5a',
            'community' => 'addresslevel4a',
            'region' => 'addresslevel2a',
            'transliteratedRegion' => 'addresslevel2a',
            'country' => 'addresslevel1a',
            'phone_number' => 'phone',
            'fax_number' => 'fax',
            'email_address' => 'email',
        ],
        'Vendors' => [
            'title' => 'vendorname',
            'transliteratedTitle' => 'vendorname',
            'registration_number' => 'registration_number_1',
            'identifier' => 'vat_id',
            'tax_id_number' => 'vat_id',
            'transliteratedSector' => 'siccode',
            'address' => 'addresslevel8a',
            'transliteratedAddress' => 'addresslevel8a',
            'postal_code' => 'addresslevel7a',
            'city' => 'addresslevel5a',
            'transliteratedCity' => 'addresslevel5a',
            'community' => 'addresslevel4a',
            'region' => 'addresslevel2a',
            'transliteratedRegion' => 'addresslevel2a',
            'country' => 'addresslevel1a',
            'phone_number' => 'phone',
            'email_address' => 'email',
        ],
        'Partners' => [
            'title' => 'subject',
            'transliteratedTitle' => 'subject',
            'identifier' => 'vat_id',
            'tax_id_number' => 'vat_id',
            'transliteratedSector' => 'siccode',
            'address' => 'addresslevel8a',
            'transliteratedAddress' => 'addresslevel8a',
            'postal_code' => 'addresslevel7a',
            'city' => 'addresslevel5a',
            'transliteratedCity' => 'addresslevel5a',
            'community' => 'addresslevel4a',
            'region' => 'addresslevel2a',
            'transliteratedRegion' => 'addresslevel2a',
            'country' => 'addresslevel1a',
            'email_address' => 'email',
        ],
        'Competition' => [
            'title' => 'subject',
            'transliteratedTitle' => 'subject',
            'identifier' => 'vat_id',
            'tax_id_number' => 'vat_id',
            'address' => 'addresslevel8a',
            'transliteratedAddress' => 'addresslevel8a',
            'postal_code' => 'addresslevel7a',
            'city' => 'addresslevel5a',
            'transliteratedCity' => 'addresslevel5a',
            'community' => 'addresslevel4a',
            'region' => 'addresslevel2a',
            'transliteratedRegion' => 'addresslevel2a',
            'country' => 'addresslevel1a',
            'email_address' => 'email',
        ],
    ];
    /** {@inheritdoc} */
    protected string $addOnName = 'YetiForceRcVatifyEu';

    /** {@inheritdoc} */
    protected $fields = [
        'country' => [
            'labelModule' => '_Base',
            'label' => 'Country',
            'picklistModule' => 'Other.Country',
            'typeofdata' => 'V~M',
            'uitype' => 16,
            'picklistValues' => [
                'AL' => 'Albania',
                'AT' => 'Austria',
                'BY' => 'Belarus',
                'BE' => 'Belgium',
                'BA' => 'Bosnia And Herzegovina',
                'BG' => 'Bulgaria',
                'CY' => 'Cyprus',
                'CZ' => 'Czech Republic',
                'DE' => 'Germany',
                'DK' => 'Denmark',
                'EE' => 'Estonia',
                'GB' => 'United Kingdom',
                'GR' => 'Greece',
                'ES' => 'Spain',
                'FI' => 'Finland',
                'FR' => 'France',
                'GB' => 'Northern Ireland',
                'GE' => 'Georgia',
                'HR' => 'Croatia',
                'HU' => 'Hungary',
                'IS' => 'Iceland',
                'IE' => 'Ireland',
                'IL' => 'Israel',
                'IT' => 'Italy',
                'KZ' => 'Kazakstan',
                'Kosovo' => 'Kosovo',
                'LV' => 'Latvia',
                'LI' => 'Liechtenstein',
                'LT' => 'Lithuania',
                'LU' => 'Luxembourg',
                'MK' => 'Macedonia, The Former Yugoslav Republic Of',
                'MT' => 'Malta',
                'MD' => 'Moldova, Republic Of',
                'ME' => 'Montenegro',
                'NO' => 'Norway',
                'NL' => 'Netherlands',
                'PL' => 'Poland',
                'PT' => 'Portugal',
                'RO' => 'Romania',
                'RU' => 'Russian Federation',
                'SE' => 'Sweden',
                'SK' => 'Slovenia',
                'RS' => 'Serbia',
                'CH' => 'Switzerland',
                'UA' => 'Ukraine',
                'ZA' => 'South Africa',
            ]
        ],
        'vatNumber' => [
            'labelModule' => '_Base',
            'label' => 'Vat ID',
            'typeofdata' => 'V~M',
        ]
    ];

    /** {@inheritdoc} */
    protected $modulesFieldsMap = [
        'Accounts' => [
            'vatNumber' => 'vat_id',
            'country' => 'addresslevel1a'
        ],
        'Leads' => [
            'vatNumber' => 'vat_id',
            'country' => 'addresslevel1a'
        ],
        'Vendors' => [
            'vatNumber' => 'vat_id',
            'country' => 'addresslevel1a'
        ],
        'Competition' => [
            'vatNumber' => 'vat_id',
            'country' => 'addresslevel1a'
        ],
    ];

    /** {@inheritdoc} */
    private $url = 'https://api.vatify.eu/v1/';
    /** @var string Access Key. */
    private $accessKey;

    /** @var string Client ID. */
    private $clientId;

    /** @var string Bearer Token. */
    private $bearerToken;

    /** {@inheritdoc} */
    public function isActive(): bool
    {
        return parent::isActive() && ($params = $this->getParams()) && !empty($params['access_key'] && !empty($params['client_id']));
    }

    /** {@inheritdoc} */
    public function search(): array
    {
        $country = $this->request->getByType('country', 'Text');
        $vatNumber = str_replace([' ', ',', '.', '-'], '', $this->request->getByType('vatNumber', 'Text'));

        if (!$this->isActive() || empty($country) || empty($vatNumber)) {
            return [];
        }
        $this->loadCredentials();
        $this->getBearerToken();
        $this->getDataFromApi([
            'country' => $country,
            'identifier' => $vatNumber,
        ]);
        $this->parseData();
        $this->loadData();
        return $this->response;
    }

    /**
     * Function fetching company data by VAT ID and Country.
     *
     * @param array $params
     *
     * @return void
     */
    private function getDataFromApi(array $params): void
    {
        try {
            $client = \App\RequestHttp::getClient(['headers' => ['Authorization' => 'Bearer ' . $this->bearerToken]]);
            $response = $client->post($this->url . 'query', ['json' => $params]);
            $link = $response->getHeaderLine('location');
        } catch (\GuzzleHttp\Exception\GuzzleException $e) {
            \App\Log::warning($e->getMessage(), 'RecordCollectors');
            $this->response['error'] = $e->getResponse()->getReasonPhrase();
            return;
        }
        if (empty($link)) {
            return;
        }
        $response = null;
        $delay = $counter = 0;
        while (!$response && $counter < 5) {
            if ($delay < 10000000) {
                $delay += 500000;
            }
            usleep($delay);
            try {
                $response = $client->get($link);
                $body = \App\Json::decode($response->getBody()->getContents());
                if (202 === $response->getStatusCode() || 'FINISHED' !== $body['query']['status']) {
                    $response = null;
                } else {
                    $this->data = $body['result']['items'];
                }
            } catch (\GuzzleHttp\Exception\GuzzleException $e) {
                \App\Log::warning($e->getMessage(), 'RecordCollectors');
                $this->response['error'] = $e->getResponse()->getReasonPhrase();
                $response = true;
            }
            ++$counter;
        }
    }

    /**
     * Function parsing data to fields from API.
     *
     * @return void
     */
    private function parseData(): void
    {
        if (empty($this->data)) {
            return;
        }
        foreach ($this->data as $key => $data) {
            $this->data[$key] = \App\Utils::flattenKeys($data['data'], 'ucfirst');
        }
    }

    /**
     * Function setup Api Key.
     *
     * @return void
     */
    private function loadCredentials(): void
    {
        if (($params = $this->getParams()) && !empty($params['client_id'] && !empty($params['access_key']))) {
            $this->clientId = $params['client_id'];
            $this->accessKey = $params['access_key'];
        }
    }

    /**
     * Function fetching Bearer Token.
     *
     * @return void
     */
    private function getBearerToken(): void
    {
        try {
            $response = \App\RequestHttp::getClient()->post($this->url . 'oauth2/token', [
                'headers' => [
                    'Authorization' => 'Basic ' . base64_encode($this->clientId . ':' . $this->accessKey)
                ],
                \GuzzleHttp\RequestOptions::JSON => [
                    'grant_type' => 'client_credentials'
                ]
            ]);
            $response = \App\Json::decode($response->getBody()->getContents());
            $this->bearerToken = $response['access_token'];
        } catch (\GuzzleHttp\Exception\GuzzleException $e) {
            \App\Log::warning($e->getMessage(), 'RecordCollectors');
            $this->response['error'] = $e->getResponse()->getReasonPhrase();
            return;
        }
        if (empty($this->bearerToken)) {
            $this->response['error'] = \App\Language::translate('LBL_VATIFY_EU_NO_AUTH', 'Other.RecordCollector');
        }
    }
}