YetiForceCompany/YetiForceCRM

View on GitHub
app/Integrations/Wapro.php

Summary

Maintainability
B
4 hrs
Test Coverage
F
0%
<?php
/**
 * WAPRO ERP main integration file.
 *
 * @package App
 *
 * @copyright YetiForce S.A.
 * @license   YetiForce Public License 6.5 (licenses/LicenseEN.txt or yetiforce.com)
 * @author    Mariusz Krzaczkowski <m.krzaczkowski@yetiforce.com>
 */

namespace App\Integrations;

/**
 * WAPRO ERP main integration class.
 */
class Wapro
{
    /** @var string Basic table name */
    public const TABLE_NAME = 'i_#__wapro';

    /** @var string Basic table name */
    public const LOG_TABLE_NAME = 'l_#__wapro';

    /** @var string Map relation table name */
    public const RECORDS_MAP_TABLE_NAME = 'u_#__wapro_records_map';

    /** @var array Database config. */
    public $config;

    /** @var array Custom configuration, enables extension of mappings for synchronization. */
    public $customConfig;

    /** @var \App\CronHandler The cron task object available when the timing is called by CRON. */
    public $cron;

    /** @var \App\Db Database instance. */
    private $db;

    /**
     * Wapro instance constructor.
     *
     * @param int                   $serverId
     * @param \App\CronHandler|null $cron
     */
    public function __construct(int $serverId, ?\App\CronHandler $cron = null)
    {
        $this->config = self::getById($serverId);
        $this->config['synchronizer'] = $this->config['synchronizer'] ? (\App\Json::decode($this->config['synchronizer']) ?? []) : [];
        $this->customConfig = \App\Config::component('IntegrationWapro', 'config', []);
        $this->db = self::connectToDatabase($this->config['server'], $this->config['database'], $this->config['username'], $this->config['password'], $this->config['port']);
        if ($cron) {
            $this->cron = $cron;
        }
    }

    /**
     * Get WAPRO ERP configuration by id.
     *
     * @param int $id
     *
     * @return array
     */
    public static function getById(int $id): array
    {
        if (\App\Cache::has(__METHOD__, $id)) {
            return \App\Cache::get(__METHOD__, $id);
        }
        $row = (new \App\Db\Query())->from(self::TABLE_NAME)->where(['id' => $id])->one(\App\Db::getInstance('admin')) ?: [];
        if ($row) {
            $row['password'] = \App\Encryption::getInstance()->decrypt($row['password']);
        }
        \App\Cache::save(__METHOD__, $id, $row);
        return $row;
    }

    /**
     * Connect to WAPRO ERP SQL Server through PDO.
     *
     * @param string $server
     * @param string $database
     * @param string $user
     * @param string $password
     * @param int    $port
     *
     * @return \App\Db
     */
    public static function connectToDatabase(string $server, string $database, string $user, string $password, int $port): \App\Db
    {
        $port = $port ?: 1433;
        \App\Db::setConfig([
            'driverName' => 'sqlsrv',
            'dsn' => "sqlsrv:Server={$server},{$port};Database={$database};",
            'username' => $user,
            'password' => $password,
            'port' => $port,
            'charset' => 'utf8',
        ], 'wapro');
        $db = \App\Db::getInstance('wapro');
        $db->open();
        return $db;
    }

    /**
     * Verify access to the WAPRO ERP system database.
     *
     * @param string $server
     * @param string $database
     * @param string $user
     * @param string $password
     * @param int    $port
     *
     * @return array
     */
    public static function verifyDatabaseAccess(string $server, string $database, string $user, string $password, int $port): array
    {
        try {
            $db = self::connectToDatabase($server, $database, $user, $password, $port);
            if (0 === \count($db->getSchema()->getSchemaNames())) {
                $response = [
                    'status' => false,
                    'message' => 'There are no schemas in the database',
                ];
            } else {
                $row = (new \App\Db\Query())->from('dbo.WAPRODBSTATE')->one($db);
                $response = [
                    'status' => !empty($row),
                    'message' => empty($row) ? 'No data' : '',
                ];
            }
        } catch (\yii\db\Exception $th) {
            $message = $th->getMessage();
            if ($th->errorInfo) {
                foreach ($th->errorInfo as $value) {
                    if ($value && !is_numeric($value) && false === strpos($message, $value)) {
                        $message .= PHP_EOL . $value;
                    }
                }
            }
            $response = [
                'status' => false,
                'message' => $message,
                'code' => $th->getCode(),
            ];
        }
        return $response;
    }

    /**
     * Get information about WAPRO ERP.
     *
     * @return string
     */
    public function getInfo(): string
    {
        $info = '';
        $pdo = $this->db->getSlavePdo();
        $info .= "dbo.WAPRODBSTATE:\n";
        foreach ((new \App\Db\Query())->from('dbo.WAPRODBSTATE')->all($this->db) as $row) {
            $info .= " {$row['PRGNAZWA']}, {$row['PRGWER']}, {$row['DBWER']}, {$row['WARIANT']}\n";
        }
        $info .= "dbo.FIRMA:\n";
        foreach ((new \App\Db\Query())->from('dbo.FIRMA')->all($this->db) as $row) {
            $info .= " {$row['NAZWA_PELNA']}, NIP: {$row['NIP']}, REGON: {$row['REGON']}\n";
        }
        foreach (array_merge($pdo->getAttribute(\PDO::ATTR_SERVER_INFO), $pdo->getAttribute(\PDO::ATTR_CLIENT_VERSION)) as $key => $value) {
            $info .= "$key: $value \n";
        }
        return trim($info);
    }

    /**
     * Get synchronizers.
     *
     * @return Wapro\Synchronizer[]
     */
    public function getAllSynchronizers(): array
    {
        $synchronizers = [];
        $iterator = new \DirectoryIterator(__DIR__ . '/Wapro/Synchronizer');
        foreach ($iterator as $item) {
            if ($item->isFile() && 'php' === $item->getExtension() && $synchronizer = self::getSynchronizer($item->getBasename('.php'))) {
                $synchronizers[$synchronizer::SEQUENCE] = $synchronizer;
            }
        }
        ksort($synchronizers);
        return $synchronizers;
    }

    /**
     * Get synchronizer by name.
     *
     * @param string $name
     *
     * @return Wapro\Synchronizer|null
     */
    public function getSynchronizer(string $name): ?Wapro\Synchronizer
    {
        $className = "\\App\\Integrations\\Wapro\\Synchronizer\\{$name}";
        return class_exists($className) ? new $className($this) : null;
    }

    /**
     * Get synchronizers.
     *
     * @return Wapro\Synchronizer[]
     */
    public function getSynchronizers(): array
    {
        $synchronizers = [];
        foreach ($this->config['synchronizer'] as $name) {
            $synchronizer = $this->getSynchronizer($name);
            $synchronizers[$synchronizer::SEQUENCE] = $synchronizer;
        }
        ksort($synchronizers);
        return $synchronizers;
    }

    /**
     * Database connection instance.
     *
     * @return \App\Db
     */
    public function getDb(): \App\Db
    {
        return $this->db;
    }
}