Поддержка мониторинга (#8) и рефакторинг
- абстрактный класс AtolClient:
- больше не наследуется от клиента guzzle, но содержит его объект
- из Kkt вынесены методы, отвечающие за формирование запроса, отправку и получение ответа, в т.ч. авторизацию
- переименованы исключения TooLongKktLoginException, TooLongKktPasswordException, EmptyKktLoginException и EmptyKktPasswordException
- мелочи по AuthFailedException
- заготовки тестов AtolClient и KktMonitor
This commit is contained in:
298
src/Api/AtolClient.php
Normal file
298
src/Api/AtolClient.php
Normal file
@@ -0,0 +1,298 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020-2021 Антон Аксенов (Anthony Axenov)
|
||||||
|
*
|
||||||
|
* This code is licensed under MIT.
|
||||||
|
* Этот код распространяется по лицензии MIT.
|
||||||
|
* https://github.com/anthonyaxenov/atol-online/blob/master/LICENSE
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types = 1);
|
||||||
|
|
||||||
|
namespace AtolOnline\Api;
|
||||||
|
|
||||||
|
use AtolOnline\{
|
||||||
|
Constants\Constraints,
|
||||||
|
Exceptions\AuthFailedException,
|
||||||
|
Exceptions\EmptyLoginException,
|
||||||
|
Exceptions\EmptyPasswordException,
|
||||||
|
Exceptions\TooLongLoginException,
|
||||||
|
Exceptions\TooLongPasswordException};
|
||||||
|
use GuzzleHttp\Client;
|
||||||
|
use GuzzleHttp\Exception\GuzzleException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Класс для подключения АТОЛ Онлайн API
|
||||||
|
*/
|
||||||
|
abstract class AtolClient
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var bool Флаг тестового режима
|
||||||
|
*/
|
||||||
|
protected bool $test_mode = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var Client HTTP-клиент для работы с API
|
||||||
|
*/
|
||||||
|
protected Client $http;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string|null Логин доступа к API
|
||||||
|
*/
|
||||||
|
private ?string $login = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string|null Пароль доступа к API (readonly)
|
||||||
|
*/
|
||||||
|
private ?string $password = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string|null Токен авторизации
|
||||||
|
*/
|
||||||
|
private ?string $token = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var KktResponse|null Последний ответ сервера АТОЛ
|
||||||
|
*/
|
||||||
|
private ?KktResponse $response;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Конструктор
|
||||||
|
*
|
||||||
|
* @param string|null $login
|
||||||
|
* @param string|null $password
|
||||||
|
* @param array $config
|
||||||
|
* @throws EmptyLoginException
|
||||||
|
* @throws EmptyPasswordException
|
||||||
|
* @throws TooLongLoginException
|
||||||
|
* @throws TooLongPasswordException
|
||||||
|
* @see https://guzzle.readthedocs.io/en/latest/request-options.html Допустимые параметры для $config
|
||||||
|
*/
|
||||||
|
public function __construct(
|
||||||
|
?string $login = null,
|
||||||
|
?string $password = null,
|
||||||
|
array $config = []
|
||||||
|
) {
|
||||||
|
$this->http = new Client(array_merge($config, [
|
||||||
|
'http_errors' => $config['http_errors'] ?? false,
|
||||||
|
]));
|
||||||
|
$login && $this->setLogin($login);
|
||||||
|
$password && $this->setPassword($password);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Возвращает установленный флаг тестового режима
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function isTestMode(): bool
|
||||||
|
{
|
||||||
|
return $this->test_mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Устанавливает флаг тестового режима
|
||||||
|
*
|
||||||
|
* @param bool $test_mode
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function setTestMode(bool $test_mode): self
|
||||||
|
{
|
||||||
|
$this->test_mode = $test_mode;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Возвращает текущий токен авторизации
|
||||||
|
*
|
||||||
|
* @return string|null
|
||||||
|
*/
|
||||||
|
public function getToken(): ?string
|
||||||
|
{
|
||||||
|
return $this->token;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Устанавливает токен авторизации
|
||||||
|
*
|
||||||
|
* @param string|null $token
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function setToken(?string $token): AtolClient
|
||||||
|
{
|
||||||
|
$this->token = $token;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Возвращает последний ответ сервера
|
||||||
|
*
|
||||||
|
* @return KktResponse|null
|
||||||
|
*/
|
||||||
|
public function getResponse(): ?KktResponse
|
||||||
|
{
|
||||||
|
return $this->response;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Возвращает логин доступа к API
|
||||||
|
*
|
||||||
|
* @return string|null
|
||||||
|
*/
|
||||||
|
protected function getLogin(): ?string
|
||||||
|
{
|
||||||
|
return $this->login;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Устанавливает логин доступа к API
|
||||||
|
*
|
||||||
|
* @param string $login
|
||||||
|
* @return $this
|
||||||
|
* @throws EmptyLoginException
|
||||||
|
* @throws TooLongLoginException
|
||||||
|
*/
|
||||||
|
public function setLogin(string $login): self
|
||||||
|
{
|
||||||
|
$login = trim($login);
|
||||||
|
if (empty($login)) {
|
||||||
|
throw new EmptyLoginException();
|
||||||
|
} elseif (mb_strlen($login) > Constraints::MAX_LENGTH_LOGIN) {
|
||||||
|
throw new TooLongLoginException($login, Constraints::MAX_LENGTH_LOGIN);
|
||||||
|
}
|
||||||
|
$this->login = $login;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Возвращает пароль доступа к API
|
||||||
|
*
|
||||||
|
* @return string|null
|
||||||
|
*/
|
||||||
|
protected function getPassword(): ?string
|
||||||
|
{
|
||||||
|
return $this->password;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Устанавливает пароль доступа к API
|
||||||
|
*
|
||||||
|
* @param string $password
|
||||||
|
* @return $this
|
||||||
|
* @throws EmptyPasswordException Пароль ККТ не может быть пустым
|
||||||
|
* @throws TooLongPasswordException Слишком длинный пароль ККТ
|
||||||
|
*/
|
||||||
|
public function setPassword(string $password): self
|
||||||
|
{
|
||||||
|
if (empty($password)) {
|
||||||
|
throw new EmptyPasswordException();
|
||||||
|
} elseif (mb_strlen($password) > Constraints::MAX_LENGTH_PASSWORD) {
|
||||||
|
throw new TooLongPasswordException($password, Constraints::MAX_LENGTH_PASSWORD);
|
||||||
|
}
|
||||||
|
$this->password = $password;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Возвращает набор заголовков для HTTP-запроса
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
private function getHeaders(): array
|
||||||
|
{
|
||||||
|
$headers['Content-type'] = 'application/json; charset=utf-8';
|
||||||
|
if ($this->getToken()) {
|
||||||
|
$headers['Token'] = $this->getToken();
|
||||||
|
}
|
||||||
|
return $headers;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Возвращает полный URL для запроса
|
||||||
|
*
|
||||||
|
* @param string $method
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function getUrlToMethod(string $method): string
|
||||||
|
{
|
||||||
|
return $this->getMainEndpoint() . '/' . trim($method);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Отправляет авторизационный запрос на сервер АТОЛ и возвращает авторизационный токен
|
||||||
|
*
|
||||||
|
* @return string|null
|
||||||
|
* @throws AuthFailedException
|
||||||
|
* @throws EmptyPasswordException
|
||||||
|
* @throws EmptyLoginException
|
||||||
|
* @throws GuzzleException
|
||||||
|
*/
|
||||||
|
protected function doAuth(): ?string
|
||||||
|
{
|
||||||
|
$result = $this->sendRequest('POST', $this->getAuthEndpoint(), [
|
||||||
|
'login' => $this->getLogin() ?? throw new EmptyLoginException(),
|
||||||
|
'pass' => $this->getPassword() ?? throw new EmptyPasswordException(),
|
||||||
|
]);
|
||||||
|
if (!$result->isValid() || !$result->getContent()->token) {
|
||||||
|
throw new AuthFailedException($result);
|
||||||
|
}
|
||||||
|
return $result->getContent()?->token;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Отправляет запрос и возвращает декодированный ответ
|
||||||
|
*
|
||||||
|
* @param string $http_method Метод HTTP
|
||||||
|
* @param string $url URL
|
||||||
|
* @param array|null $data Данные для передачи
|
||||||
|
* @param array|null $options Параметры Guzzle
|
||||||
|
* @return KktResponse
|
||||||
|
* @throws GuzzleException
|
||||||
|
* @see https://guzzle.readthedocs.io/en/latest/request-options.html
|
||||||
|
*/
|
||||||
|
protected function sendRequest(
|
||||||
|
string $http_method,
|
||||||
|
string $url,
|
||||||
|
?array $data = null,
|
||||||
|
?array $options = null
|
||||||
|
): KktResponse {
|
||||||
|
$http_method = strtoupper(trim($http_method));
|
||||||
|
$options['headers'] = array_merge($this->getHeaders(), $options['headers'] ?? []);
|
||||||
|
if ($http_method != 'GET') {
|
||||||
|
$options['json'] = $data;
|
||||||
|
}
|
||||||
|
$response = $this->http->request($http_method, $url, $options);
|
||||||
|
return $this->response = new KktResponse($response);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Выполняет авторизацию на сервере АТОЛ
|
||||||
|
*
|
||||||
|
* Авторизация выолнится только если неизвестен токен
|
||||||
|
*
|
||||||
|
* @param string|null $login
|
||||||
|
* @param string|null $password
|
||||||
|
* @return bool
|
||||||
|
* @throws AuthFailedException
|
||||||
|
* @throws TooLongLoginException
|
||||||
|
* @throws EmptyLoginException
|
||||||
|
* @throws EmptyPasswordException
|
||||||
|
* @throws TooLongPasswordException
|
||||||
|
* @throws GuzzleException
|
||||||
|
*/
|
||||||
|
abstract public function auth(?string $login = null, ?string $password = null): bool;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Возвращает URL для запроса авторизации
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
abstract protected function getAuthEndpoint(): string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Возвращает URL для запросов
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
abstract protected function getMainEndpoint(): string;
|
||||||
|
}
|
||||||
@@ -17,15 +17,15 @@ use AtolOnline\{
|
|||||||
Entities\Document,
|
Entities\Document,
|
||||||
Exceptions\AuthFailedException,
|
Exceptions\AuthFailedException,
|
||||||
Exceptions\EmptyCorrectionInfoException,
|
Exceptions\EmptyCorrectionInfoException,
|
||||||
Exceptions\EmptyKktLoginException,
|
Exceptions\EmptyLoginException,
|
||||||
Exceptions\EmptyKktPasswordException,
|
Exceptions\EmptyPasswordException,
|
||||||
Exceptions\InvalidCallbackUrlException,
|
Exceptions\InvalidCallbackUrlException,
|
||||||
Exceptions\InvalidDocumentTypeException,
|
Exceptions\InvalidDocumentTypeException,
|
||||||
Exceptions\InvalidInnLengthException,
|
Exceptions\InvalidInnLengthException,
|
||||||
Exceptions\InvalidUuidException,
|
Exceptions\InvalidUuidException,
|
||||||
Exceptions\TooLongCallbackUrlException,
|
Exceptions\TooLongCallbackUrlException,
|
||||||
Exceptions\TooLongKktLoginException,
|
Exceptions\TooLongLoginException,
|
||||||
Exceptions\TooLongKktPasswordException,
|
Exceptions\TooLongPasswordException,
|
||||||
Exceptions\TooLongPaymentAddressException,
|
Exceptions\TooLongPaymentAddressException,
|
||||||
Exceptions\TooManyItemsException,
|
Exceptions\TooManyItemsException,
|
||||||
Exceptions\TooManyVatsException,
|
Exceptions\TooManyVatsException,
|
||||||
@@ -70,10 +70,6 @@ class Kkt extends Client
|
|||||||
* @param string|null $pass
|
* @param string|null $pass
|
||||||
* @param bool $test_mode Флаг тестового режима
|
* @param bool $test_mode Флаг тестового режима
|
||||||
* @param array $guzzle_config Конфигурация GuzzleHttp
|
* @param array $guzzle_config Конфигурация GuzzleHttp
|
||||||
* @throws EmptyKktLoginException Логин ККТ не может быть пустым
|
|
||||||
* @throws TooLongKktLoginException Слишком длинный логин ККТ
|
|
||||||
* @throws EmptyKktPasswordException Пароль ККТ не может быть пустым
|
|
||||||
* @throws TooLongKktPasswordException Слишком длинный пароль ККТ
|
|
||||||
* @see https://guzzle.readthedocs.io/en/latest/request-options.html
|
* @see https://guzzle.readthedocs.io/en/latest/request-options.html
|
||||||
*/
|
*/
|
||||||
public function __construct(
|
public function __construct(
|
||||||
@@ -126,15 +122,15 @@ class Kkt extends Client
|
|||||||
*
|
*
|
||||||
* @param string $login
|
* @param string $login
|
||||||
* @return $this
|
* @return $this
|
||||||
* @throws EmptyKktLoginException Логин ККТ не может быть пустым
|
* @throws EmptyLoginException Логин ККТ не может быть пустым
|
||||||
* @throws TooLongKktLoginException Слишком длинный логин ККТ
|
* @throws TooLongLoginException Слишком длинный логин ККТ
|
||||||
*/
|
*/
|
||||||
public function setLogin(string $login): Kkt
|
public function setLogin(string $login): Kkt
|
||||||
{
|
{
|
||||||
if (empty($login)) {
|
if (empty($login)) {
|
||||||
throw new EmptyKktLoginException();
|
throw new EmptyLoginException();
|
||||||
} elseif (mb_strlen($login) > Constraints::MAX_LENGTH_LOGIN) {
|
} elseif (mb_strlen($login) > Constraints::MAX_LENGTH_LOGIN) {
|
||||||
throw new TooLongKktLoginException($login, Constraints::MAX_LENGTH_LOGIN);
|
throw new TooLongLoginException($login, Constraints::MAX_LENGTH_LOGIN);
|
||||||
}
|
}
|
||||||
$this->kkt_config['prod']['login'] = $login;
|
$this->kkt_config['prod']['login'] = $login;
|
||||||
return $this;
|
return $this;
|
||||||
@@ -155,15 +151,15 @@ class Kkt extends Client
|
|||||||
*
|
*
|
||||||
* @param string $password
|
* @param string $password
|
||||||
* @return $this
|
* @return $this
|
||||||
* @throws EmptyKktPasswordException Пароль ККТ не может быть пустым
|
* @throws EmptyPasswordException Пароль ККТ не может быть пустым
|
||||||
* @throws TooLongKktPasswordException Слишком длинный пароль ККТ
|
* @throws TooLongPasswordException Слишком длинный пароль ККТ
|
||||||
*/
|
*/
|
||||||
public function setPassword(string $password): Kkt
|
public function setPassword(string $password): Kkt
|
||||||
{
|
{
|
||||||
if (empty($password)) {
|
if (empty($password)) {
|
||||||
throw new EmptyKktPasswordException();
|
throw new EmptyPasswordException();
|
||||||
} elseif (mb_strlen($password) > Constraints::MAX_LENGTH_PASSWORD) {
|
} elseif (mb_strlen($password) > Constraints::MAX_LENGTH_PASSWORD) {
|
||||||
throw new TooLongKktPasswordException($password, Constraints::MAX_LENGTH_PASSWORD);
|
throw new TooLongPasswordException($password, Constraints::MAX_LENGTH_PASSWORD);
|
||||||
}
|
}
|
||||||
$this->kkt_config['prod']['pass'] = $password;
|
$this->kkt_config['prod']['pass'] = $password;
|
||||||
return $this;
|
return $this;
|
||||||
@@ -208,16 +204,6 @@ class Kkt extends Client
|
|||||||
return $this->kkt_config[$this->isTestMode() ? 'test' : 'prod']['callback_url'];
|
return $this->kkt_config[$this->isTestMode() ? 'test' : 'prod']['callback_url'];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Возвращает последний ответ сервера
|
|
||||||
*
|
|
||||||
* @return KktResponse|null
|
|
||||||
*/
|
|
||||||
public function getLastResponse(): ?KktResponse
|
|
||||||
{
|
|
||||||
return $this->last_response;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Возвращает флаг тестового режима
|
* Возвращает флаг тестового режима
|
||||||
*
|
*
|
||||||
|
|||||||
124
src/Api/KktMonitor.php
Normal file
124
src/Api/KktMonitor.php
Normal file
@@ -0,0 +1,124 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020-2021 Антон Аксенов (Anthony Axenov)
|
||||||
|
*
|
||||||
|
* This code is licensed under MIT.
|
||||||
|
* Этот код распространяется по лицензии MIT.
|
||||||
|
* https://github.com/anthonyaxenov/atol-online/blob/master/LICENSE
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types = 1);
|
||||||
|
|
||||||
|
namespace AtolOnline\Api;
|
||||||
|
|
||||||
|
use GuzzleHttp\Exception\GuzzleException;
|
||||||
|
use stdClass;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Класс для мониторинга ККТ
|
||||||
|
*
|
||||||
|
* @see https://online.atol.ru/files/API_service_information.pdf Документация
|
||||||
|
*/
|
||||||
|
class KktMonitor extends AtolClient
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
protected function getAuthEndpoint(): string
|
||||||
|
{
|
||||||
|
return $this->isTestMode()
|
||||||
|
? 'https://testonline.atol.ru/api/auth/v1/gettoken'
|
||||||
|
: 'https://online.atol.ru/api/auth/v1/gettoken';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
protected function getMainEndpoint(): string
|
||||||
|
{
|
||||||
|
return $this->isTestMode()
|
||||||
|
? 'https://testonline.atol.ru/api/kkt/v1'
|
||||||
|
: 'https://online.atol.ru/api/kkt/v1';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
public function auth(?string $login = null, ?string $password = null): bool
|
||||||
|
{
|
||||||
|
if (empty($this->getToken())) {
|
||||||
|
$login && $this->setLogin($login);
|
||||||
|
$password && $this->setPassword($password);
|
||||||
|
if ($token = $this->doAuth()) {
|
||||||
|
$this->setToken($token);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return !empty($this->getToken());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Получает от API информацию обо всех ККТ и ФН в рамках группы
|
||||||
|
*
|
||||||
|
* @param int|null $limit
|
||||||
|
* @param int|null $offset
|
||||||
|
* @return KktResponse
|
||||||
|
* @throws GuzzleException
|
||||||
|
* @see https://online.atol.ru/files/API_service_information.pdf Документация, стр 9
|
||||||
|
*/
|
||||||
|
protected function fetchAll(?int $limit = null, ?int $offset = null): KktResponse
|
||||||
|
{
|
||||||
|
$params = [];
|
||||||
|
$limit && $params['limit'] = $limit;
|
||||||
|
$offset && $params['offset'] = $offset;
|
||||||
|
return $this->sendRequest('GET', self::getUrlToMethod('cash-registers'), $params);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Возвращает информацию обо всех ККТ и ФН в рамках группы
|
||||||
|
*
|
||||||
|
* @param int|null $limit
|
||||||
|
* @param int|null $offset
|
||||||
|
* @return KktResponse
|
||||||
|
* @throws GuzzleException
|
||||||
|
* @see https://online.atol.ru/files/API_service_information.pdf Документация, стр 9
|
||||||
|
*/
|
||||||
|
public function getAll(?int $limit = null, ?int $offset = null): KktResponse
|
||||||
|
{
|
||||||
|
return $this->fetchAll($limit, $offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Получает от API информацию о конкретной ККТ по её серийному номеру
|
||||||
|
*
|
||||||
|
* @param string $serial_number
|
||||||
|
* @return KktResponse
|
||||||
|
* @throws GuzzleException
|
||||||
|
* @see https://online.atol.ru/files/API_service_information.pdf Документация, стр 11
|
||||||
|
*/
|
||||||
|
protected function fetchOne(string $serial_number): KktResponse
|
||||||
|
{
|
||||||
|
return $this->sendRequest(
|
||||||
|
'GET',
|
||||||
|
self::getUrlToMethod('cash-registers') . '/' . trim($serial_number),
|
||||||
|
options: [
|
||||||
|
'headers' => [
|
||||||
|
'Accept' => 'application/hal+json',
|
||||||
|
],
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Возвращает информацию о конкретной ККТ по её серийному номеру
|
||||||
|
*
|
||||||
|
* @todo кастовать к отдельному классу со своими геттерами
|
||||||
|
* @param string $serial_number
|
||||||
|
* @return stdClass
|
||||||
|
* @throws GuzzleException
|
||||||
|
* @see https://online.atol.ru/files/API_service_information.pdf Документация, стр 11
|
||||||
|
*/
|
||||||
|
public function getOne(string $serial_number): stdClass
|
||||||
|
{
|
||||||
|
return $this->fetchOne($serial_number)->getContent()->data;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -14,6 +14,7 @@ namespace AtolOnline\Api;
|
|||||||
use JsonSerializable;
|
use JsonSerializable;
|
||||||
use Psr\Http\Message\ResponseInterface;
|
use Psr\Http\Message\ResponseInterface;
|
||||||
use stdClass;
|
use stdClass;
|
||||||
|
use Stringable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Класс AtolResponse, описывающий ответ от ККТ
|
* Класс AtolResponse, описывающий ответ от ККТ
|
||||||
@@ -21,7 +22,7 @@ use stdClass;
|
|||||||
* @property mixed $error
|
* @property mixed $error
|
||||||
* @package AtolOnline\Api
|
* @package AtolOnline\Api
|
||||||
*/
|
*/
|
||||||
class KktResponse implements JsonSerializable
|
class KktResponse implements JsonSerializable, Stringable
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @var int Код ответа сервера
|
* @var int Код ответа сервера
|
||||||
@@ -29,9 +30,9 @@ class KktResponse implements JsonSerializable
|
|||||||
protected int $code;
|
protected int $code;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var stdClass Содержимое ответа сервера
|
* @var stdClass|array|null Содержимое ответа сервера
|
||||||
*/
|
*/
|
||||||
protected $content;
|
protected stdClass|array|null $content;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var array Заголовки ответа
|
* @var array Заголовки ответа
|
||||||
@@ -66,9 +67,9 @@ class KktResponse implements JsonSerializable
|
|||||||
* @param $name
|
* @param $name
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public function __get($name)
|
public function __get($name): mixed
|
||||||
{
|
{
|
||||||
return $this->getContent()->$name;
|
return $this->getContent()?->$name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -84,9 +85,9 @@ class KktResponse implements JsonSerializable
|
|||||||
/**
|
/**
|
||||||
* Возвращает объект результата запроса
|
* Возвращает объект результата запроса
|
||||||
*
|
*
|
||||||
* @return stdClass|null
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public function getContent(): ?stdClass
|
public function getContent(): mixed
|
||||||
{
|
{
|
||||||
return $this->content;
|
return $this->content;
|
||||||
}
|
}
|
||||||
@@ -107,7 +108,7 @@ class KktResponse implements JsonSerializable
|
|||||||
/**
|
/**
|
||||||
* Возвращает текстовое представление
|
* Возвращает текстовое представление
|
||||||
*/
|
*/
|
||||||
public function __toString()
|
public function __toString(): string
|
||||||
{
|
{
|
||||||
return json_encode($this->jsonSerialize(), JSON_UNESCAPED_UNICODE);
|
return json_encode($this->jsonSerialize(), JSON_UNESCAPED_UNICODE);
|
||||||
}
|
}
|
||||||
@@ -115,7 +116,7 @@ class KktResponse implements JsonSerializable
|
|||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function jsonSerialize()
|
public function jsonSerialize(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'code' => $this->code,
|
'code' => $this->code,
|
||||||
|
|||||||
@@ -16,26 +16,26 @@ use Exception;
|
|||||||
use Throwable;
|
use Throwable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Исключение, возникающее при работе с АТОЛ Онлайн
|
* Исключение, возникающее при неудачной авторизации
|
||||||
*/
|
*/
|
||||||
class AuthFailedException extends Exception
|
class AuthFailedException extends Exception
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Конструктор
|
* Конструктор
|
||||||
*
|
*
|
||||||
* @param KktResponse $last_response
|
* @param KktResponse $response
|
||||||
* @param string $message
|
* @param string $message
|
||||||
* @param int $code
|
* @param int $code
|
||||||
* @param Throwable|null $previous
|
* @param Throwable|null $previous
|
||||||
*/
|
*/
|
||||||
public function __construct(KktResponse $last_response, $message = "", $code = 0, Throwable $previous = null)
|
public function __construct(KktResponse $response, $message = "", $code = 0, Throwable $previous = null)
|
||||||
{
|
{
|
||||||
$message = $last_response->isValid()
|
$message = $response->isValid()
|
||||||
? $message
|
? $message
|
||||||
: '[' . $last_response->error->code . '] ' . $last_response->error->text .
|
: '[' . $response->error->code . '] ' . $response->error->text .
|
||||||
'. ERROR_ID: ' . $last_response->error->error_id .
|
'. ERROR_ID: ' . $response->error->error_id .
|
||||||
'. TYPE: ' . $last_response->error->type;
|
'. TYPE: ' . $response->error->type;
|
||||||
$code = $last_response->isValid() ? $code : $last_response->error->code;
|
$code = $response->isValid() ? $code : $response->error->code;
|
||||||
parent::__construct($message, $code, $previous);
|
parent::__construct($message, $code, $previous);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ namespace AtolOnline\Exceptions;
|
|||||||
/**
|
/**
|
||||||
* Исключение, возникающее при попытке указать пустой логин ККТ
|
* Исключение, возникающее при попытке указать пустой логин ККТ
|
||||||
*/
|
*/
|
||||||
class EmptyKktLoginException extends AtolException
|
class EmptyLoginException extends AtolException
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @var string Сообщение об ошибке
|
* @var string Сообщение об ошибке
|
||||||
@@ -14,7 +14,7 @@ namespace AtolOnline\Exceptions;
|
|||||||
/**
|
/**
|
||||||
* Исключение, возникающее при попытке указать пустой пароль ККТ
|
* Исключение, возникающее при попытке указать пустой пароль ККТ
|
||||||
*/
|
*/
|
||||||
class EmptyKktPasswordException extends AtolException
|
class EmptyPasswordException extends AtolException
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @var string Сообщение об ошибке
|
* @var string Сообщение об ошибке
|
||||||
@@ -14,7 +14,7 @@ namespace AtolOnline\Exceptions;
|
|||||||
/**
|
/**
|
||||||
* Исключение, возникающее при попытке указать слишком длинный логин ККТ
|
* Исключение, возникающее при попытке указать слишком длинный логин ККТ
|
||||||
*/
|
*/
|
||||||
class TooLongKktLoginException extends BasicTooLongException
|
class TooLongLoginException extends BasicTooLongException
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @var string Сообщение об ошибке
|
* @var string Сообщение об ошибке
|
||||||
@@ -14,7 +14,7 @@ namespace AtolOnline\Exceptions;
|
|||||||
/**
|
/**
|
||||||
* Исключение, возникающее при попытке указать слишком длинный пароль ККТ
|
* Исключение, возникающее при попытке указать слишком длинный пароль ККТ
|
||||||
*/
|
*/
|
||||||
class TooLongKktPasswordException extends BasicTooLongException
|
class TooLongPasswordException extends BasicTooLongException
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @var string Сообщение об ошибке
|
* @var string Сообщение об ошибке
|
||||||
48
tests/AtolClientTest.php
Normal file
48
tests/AtolClientTest.php
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020-2021 Антон Аксенов (Anthony Axenov)
|
||||||
|
*
|
||||||
|
* This code is licensed under MIT.
|
||||||
|
* Этот код распространяется по лицензии MIT.
|
||||||
|
* https://github.com/anthonyaxenov/atol-online/blob/master/LICENSE
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace AtolOnline\Tests;
|
||||||
|
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
|
class AtolClientTest extends TestCase
|
||||||
|
{
|
||||||
|
|
||||||
|
public function testAuth()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testSetPassword()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testSetTestMode()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetToken()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testSetLogin()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testSetToken()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetResponse()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testIsTestMode()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
40
tests/KktMonitorTest.php
Normal file
40
tests/KktMonitorTest.php
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020-2021 Антон Аксенов (Anthony Axenov)
|
||||||
|
*
|
||||||
|
* This code is licensed under MIT.
|
||||||
|
* Этот код распространяется по лицензии MIT.
|
||||||
|
* https://github.com/anthonyaxenov/atol-online/blob/master/LICENSE
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace AtolOnline\Tests;
|
||||||
|
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
|
class KktMonitorTest extends TestCase
|
||||||
|
{
|
||||||
|
|
||||||
|
public function testSetToken()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetResponse()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testSetLogin()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testAuth()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetToken()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testSetPassword()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user