Compare commits
21 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 3bd043bde7 | |||
| 7c8ee85b89 | |||
| aab68646e6 | |||
| e1fb74ac01 | |||
| 8d9f218280 | |||
| 9ed999f9fc | |||
| 989c06a383 | |||
| 9bd99c81a9 | |||
| 2943d93962 | |||
| 8eb309bc58 | |||
| b74f652127 | |||
| 1061914a5f | |||
| 5424726a97 | |||
| 2b3713db69 | |||
| a6b57115b6 | |||
| 12e0e49c9b | |||
| 3ffab562f8 | |||
| c05e013a5a | |||
| e282de7e08 | |||
| c14b680be4 | |||
| 7558cb6638 |
17
ROADMAP.md
17
ROADMAP.md
@@ -26,8 +26,6 @@
|
|||||||
- [ ] Тесты для регистрации документа возврата расхода
|
- [ ] Тесты для регистрации документа возврата расхода
|
||||||
- [ ] Тесты для регистрации документа коррекции расхода
|
- [ ] Тесты для регистрации документа коррекции расхода
|
||||||
- [ ] Вообще все расчёты вообще везде должны быть строго в копейках. Рубли (дроби) должны быть только в JSON-представлениях
|
- [ ] Вообще все расчёты вообще везде должны быть строго в копейках. Рубли (дроби) должны быть только в JSON-представлениях
|
||||||
- [ ] Валидатор схемы для документов прихода, возврата прихода, расхода, возврата расхода
|
|
||||||
- [ ] Валидатор схемы для документов коррекции прихода, коррекции расхода
|
|
||||||
|
|
||||||
## Поддержка методов API (регистрация документов)
|
## Поддержка методов API (регистрация документов)
|
||||||
|
|
||||||
@@ -65,3 +63,18 @@
|
|||||||
- [x] Пoддержка `correction.vats` (обязательный)
|
- [x] Пoддержка `correction.vats` (обязательный)
|
||||||
- [x] Пoддержка `correction.correction_info` (обязательный)
|
- [x] Пoддержка `correction.correction_info` (обязательный)
|
||||||
- [x] Пoддержка `correction.cashier`
|
- [x] Пoддержка `correction.cashier`
|
||||||
|
|
||||||
|
## Не будут реализовываться
|
||||||
|
|
||||||
|
### Валидация генерируемых документов согласно актуальной схемы API
|
||||||
|
|
||||||
|
- Валидатор схемы для документов прихода, возврата прихода, расхода, возврата расхода
|
||||||
|
- Валидатор схемы для документов коррекции прихода, коррекции расхода
|
||||||
|
|
||||||
|
1. Отказ обусловлен скоростью выполнения.
|
||||||
|
Базовая реализация, которая была начата, подразумевала синглтон, который кешировал однажды полученную схему.
|
||||||
|
Практика показала, что этот единичный запрос может существенно тормозить работу сервера и в течение долгого времени
|
||||||
|
не отдавать ответ клиенту.
|
||||||
|
|
||||||
|
2. Такая валидация подходит в том случае, если бы при разработке использовалась концепция IoC.
|
||||||
|
До версии пакета 2.0.0 таких серьёзных имзенений не планируется.
|
||||||
|
|||||||
@@ -40,12 +40,14 @@
|
|||||||
"autoload": {
|
"autoload": {
|
||||||
"classmap": [
|
"classmap": [
|
||||||
"src/AtolOnline/Api/",
|
"src/AtolOnline/Api/",
|
||||||
"src/AtolOnline/Api/Schemas/",
|
|
||||||
"src/AtolOnline/Exceptions/",
|
"src/AtolOnline/Exceptions/",
|
||||||
"src/AtolOnline/Entities/",
|
"src/AtolOnline/Entities/",
|
||||||
"src/AtolOnline/Traits/",
|
"src/AtolOnline/Traits/",
|
||||||
"src/AtolOnline/Constants/",
|
"src/AtolOnline/Constants/",
|
||||||
"tests/"
|
"tests/"
|
||||||
|
],
|
||||||
|
"files": [
|
||||||
|
"src/helpers.php"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,10 +46,10 @@ $customer = (new AtolOnline\Entities\Client())
|
|||||||
* `AtolEmailValidateException` (если email невалиден).
|
* `AtolEmailValidateException` (если email невалиден).
|
||||||
|
|
||||||
Метод `setInn()` чистит входную строку от всех символов, кроме цифр, и проверяет длину (либо 10, либо 12 цифр).
|
Метод `setInn()` чистит входную строку от всех символов, кроме цифр, и проверяет длину (либо 10, либо 12 цифр).
|
||||||
Выбрасывает исключение `AtolInnWrongLengthException` (если длина строка ИНН некорректна).
|
Выбрасывает исключение `AtolInnWrongLengthException` (если длина ИНН некорректна).
|
||||||
|
|
||||||
Метод `setName()` проверяет входную строку на длину (до 256 символов).
|
Метод `setName()` проверяет входную строку на длину (до 256 символов).
|
||||||
Выбрасывает исключение `AtolNameTooLongException` (если слишком длинное наименование).
|
Выбрасывает исключение `AtolNameTooLongException` (если слишком длинное имя).
|
||||||
|
|
||||||
Метод `setPhone()` чистит входную строку от всех символов, кроме цифр и знака `+`, и проверяет длину (до 64 символов).
|
Метод `setPhone()` чистит входную строку от всех символов, кроме цифр и знака `+`, и проверяет длину (до 64 символов).
|
||||||
Выбрасывает исключение `AtolPhoneTooLongException` (если слишком длинный номер телефона).
|
Выбрасывает исключение `AtolPhoneTooLongException` (если слишком длинный номер телефона).
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ $company = (new AtolOnline\Entities\Company())
|
|||||||
* `AtolEmailValidateException` (если email невалиден).
|
* `AtolEmailValidateException` (если email невалиден).
|
||||||
|
|
||||||
Метод `setInn()` чистит входную строку от всех символов, кроме цифр, и проверяет длину (либо 10, либо 12 цифр).
|
Метод `setInn()` чистит входную строку от всех символов, кроме цифр, и проверяет длину (либо 10, либо 12 цифр).
|
||||||
Выбрасывает исключение `AtolInnWrongLengthException` (если длина строка ИНН некорректна).
|
Выбрасывает исключение `AtolInnWrongLengthException` (если длина ИНН некорректна).
|
||||||
|
|
||||||
Метод `setPaymentAddress()` проверяет длину (до 256 символов).
|
Метод `setPaymentAddress()` проверяет длину (до 256 символов).
|
||||||
Выбрасывает исключение `AtolPaymentAddressTooLongException` (если слишком длинный адрес места расчётов).
|
Выбрасывает исключение `AtolPaymentAddressTooLongException` (если слишком длинный адрес места расчётов).
|
||||||
|
|||||||
@@ -164,4 +164,4 @@ $json_array = $doc->jsonSerialize();
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
[Вернуться к содержанию](readme.md)
|
[Вернуться к содержанию](readme.md)
|
||||||
|
|||||||
87
docs/kkt.md
87
docs/kkt.md
@@ -49,12 +49,18 @@ $kkt->getGroup();
|
|||||||
|
|
||||||
Эти параметры нужно задать [объекту компании](/docs/company.md), который будет передаваться в документах через эту ККТ.
|
Эти параметры нужно задать [объекту компании](/docs/company.md), который будет передаваться в документах через эту ККТ.
|
||||||
|
|
||||||
|
<a name='testmode'></a>
|
||||||
## Тестовый режим
|
## Тестовый режим
|
||||||
|
|
||||||
На самом деле, в АТОЛ Онлайн нет понятия *тестовая операция* или чего-то в этом духе.
|
На самом деле, в АТОЛ Онлайн нет понятия *тестовая операция* или чего-то в этом духе.
|
||||||
АТОЛ предоставляет нам отдельную тестовую ККТ.
|
АТОЛ предоставляет нам отдельную тестовую среду (ККТ).
|
||||||
[Её настройки](https://online.atol.ru/files/ffd/test_sreda.txt) уже указаны в коде библиотеки.
|
[Её настройки](https://online.atol.ru/files/ffd/test_sreda.txt) уже указаны в коде библиотеки.
|
||||||
*Под тестовым режимом работы подразумевается использование этой тестовой ККТ.*
|
*Под тестовым режимом работы подразумевается использование другой (тестовой) ККТ.*
|
||||||
|
|
||||||
|
При включенном тестовом режиме:
|
||||||
|
* меняется логин, пароль и группа (для обращения на тестовую ККТ)
|
||||||
|
* между авторизацией и операцией над документом, в `Company` документа переопределяется ИНН, СНО и адрес места
|
||||||
|
расчётов на те, что указаны в [параметрах тестовой среды](https://online.atol.ru/files/ffd/test_sreda.txt).
|
||||||
|
|
||||||
В библиотеке есть переключатель настроек ККТ.
|
В библиотеке есть переключатель настроек ККТ.
|
||||||
С его помощью можете поменять вашу боевую ККТ на тестовую и наоборот.
|
С его помощью можете поменять вашу боевую ККТ на тестовую и наоборот.
|
||||||
@@ -70,13 +76,43 @@ $kkt->setTestMode(false); // выключить
|
|||||||
> Если вы включили тестовый режим (как показано выше), то используются именно эта ККТ, а не ваша.
|
> Если вы включили тестовый режим (как показано выше), то используются именно эта ККТ, а не ваша.
|
||||||
> После выключения тестового режима настройки доступа к ККТ меняются на ваши (используется уже ваша ККТ).
|
> После выключения тестового режима настройки доступа к ККТ меняются на ваши (используется уже ваша ККТ).
|
||||||
|
|
||||||
Если по каким-то причинам у вас не получится использовать тестовый режим, вы можете проводить свои тесты в боевом режиме (на собственной ККТ).
|
Для включения тестового режима необязательно задавать параметры боевой ККТ.
|
||||||
|
|
||||||
|
Если по каким-то причинам у вас не получится использовать тестовый режим, вы можете проводить свои тесты в боевом
|
||||||
|
режиме (на собственной ККТ).
|
||||||
В этом случае важно понимать следующее:
|
В этом случае важно понимать следующее:
|
||||||
1. сразу после оформления документа **прихода** необходимо оформлять точно такой же документ **возврата прихода**;
|
1. сразу после оформления документа **прихода** необходимо оформлять точно такой же документ **возврата прихода**;
|
||||||
2. [вы обязательно забудете о пункте 1](http://murphy-law.net.ru/basics.html);
|
2. [вы обязательно забудете о пункте 1](http://murphy-law.net.ru/basics.html);
|
||||||
3. пп. 1 и 2 в любом случае скажутся на ваших финансовых отчётах;
|
3. пп. 1 и 2 в любом случае скажутся на ваших финансовых отчётах;
|
||||||
4. вся ответственность за пп. 1-3 и последствия ложится только на вас.
|
4. вся ответственность за пп. 1-3 и последствия ложится только на вас.
|
||||||
|
|
||||||
|
## Авторизация на ККТ
|
||||||
|
|
||||||
|
Перед первым запросом на ККТ происходит аутентификация на сервере по логину и паролю.
|
||||||
|
В ответ приходит авторизационный токен, срок жизни коего равен **24 часам**.
|
||||||
|
После первой успешной операции возможно получить этот токен следующим образом:
|
||||||
|
|
||||||
|
```php
|
||||||
|
$kkt->getAuthToken(); // вернёт строку длиной 128 символа
|
||||||
|
```
|
||||||
|
|
||||||
|
Этот токен можно сохранить и переиспользовать в течение всего срока его жизни.
|
||||||
|
Спустя это время следует получить новый токен.
|
||||||
|
|
||||||
|
Для дальнейшего использования однажды полученный токен следует указывать следующим образом:
|
||||||
|
|
||||||
|
```php
|
||||||
|
$kkt->setAuthToken($token_string);
|
||||||
|
```
|
||||||
|
|
||||||
|
Если токен был установлен перед выполнением операции, то при выполнении операции будет использоваться именно он, а новый
|
||||||
|
запрашиваться не будет. Если операция завершится ошибочно из-за истёкшего токена, следует повторить операцию без
|
||||||
|
использования метода `setAuthToken()`, либо обнулив его следующим образом:
|
||||||
|
|
||||||
|
```php
|
||||||
|
$kkt->setAuthToken(null);
|
||||||
|
```
|
||||||
|
|
||||||
## Регистрация документа
|
## Регистрация документа
|
||||||
|
|
||||||
Для регистрации документа **прихода** необходимо вызвать метод `sell()`:
|
Для регистрации документа **прихода** необходимо вызвать метод `sell()`:
|
||||||
@@ -106,29 +142,64 @@ $result = $kkt->buyRefund($document);
|
|||||||
Для операций, перечисленных выше, документы не должны содержать [данных коррекции](/docs/documents.md#correction).
|
Для операций, перечисленных выше, документы не должны содержать [данных коррекции](/docs/documents.md#correction).
|
||||||
Тогда как для операций коррекции, которые описаны ниже, эти данные должны присутствовать.
|
Тогда как для операций коррекции, которые описаны ниже, эти данные должны присутствовать.
|
||||||
|
|
||||||
Для регистрации документа **коррекции прихода** необходимо вызвать метод `sellRefund()`:
|
Для регистрации документа **коррекции прихода** необходимо вызвать метод `sellCorrection()`:
|
||||||
|
|
||||||
```php
|
```php
|
||||||
$result = $kkt->sellCorrection($document);
|
$result = $kkt->sellCorrection($document);
|
||||||
```
|
```
|
||||||
|
|
||||||
Для регистрации документа **коррекции расхода** необходимо вызвать метод `buyRefund()`:
|
Для регистрации документа **коррекции расхода** необходимо вызвать метод `buyCorrection()`:
|
||||||
|
|
||||||
```php
|
```php
|
||||||
$result = $kkt->buyCorrection($document);
|
$result = $kkt->buyCorrection($document);
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Любой из перечисленных выше шести методов может выбросить исключение `AtolAuthFailedException` при ошибке
|
||||||
|
аутентификации или авторизации.
|
||||||
|
|
||||||
|
### Собственный идентификатор документа
|
||||||
|
|
||||||
|
Каждый документ, переданный на ККТ для регистрации, всегда имеет свой идентификатор, абсолютно уникальный среди всех
|
||||||
|
документов когда-либо регистрировавшихся на ККТ, даже если при регистрации были ошибки.
|
||||||
|
По умолчанию это UUID версии 4.
|
||||||
|
|
||||||
|
Чтобы использовать собственный идентификатор, следует передать нужное строковое значение вторым параметром в любой из
|
||||||
|
шести описанных выше методов, например:
|
||||||
|
|
||||||
|
```php
|
||||||
|
$kkt->sell($document, $my_unique_id);
|
||||||
|
$kkt->sellRefund($document, $my_unique_id);
|
||||||
|
$kkt->buy($document, $my_unique_id);
|
||||||
|
$kkt->buyRefund($document, $my_unique_id);
|
||||||
|
$kkt->sellCorrection($document, $my_unique_id);
|
||||||
|
$kkt->buyCorrection($document, $my_unique_id);
|
||||||
|
```
|
||||||
|
|
||||||
|
Если `$my_unique_id` равен `null` или пустой строке, то будет сгенерирован новый UUID.
|
||||||
|
Узнать его можно будет только в ответе от ККТ.
|
||||||
|
|
||||||
### Передача callback_url
|
### Передача callback_url
|
||||||
|
|
||||||
Перед регистрацией документа можно указать `callback_url`.
|
Перед регистрацией документа можно указать `callback_url`.
|
||||||
АТОЛ отправит на указанный URL результат регистрации.
|
АТОЛ отправит на указанный URL результат регистрации.
|
||||||
Вам необходимо расположить по этому адресу скрипт, обрабатывающий этот результат.
|
По этому адресу должен располагаться код, который будет обрабатывать этот результат.
|
||||||
|
|
||||||
```php
|
```php
|
||||||
$kkt->setCallbackUrl('http://example.com/process-kkt-result');
|
$kkt->setCallbackUrl('http://example.com/process-kkt-result');
|
||||||
$kkt->getCallbackUrl();
|
$kkt->getCallbackUrl();
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Метод `setCallbackUrl()` проверяет входную строку на длину (до 256 символов) и валидность формата url по
|
||||||
|
регулярному выражению:
|
||||||
|
|
||||||
|
```
|
||||||
|
^http(s?)\:\/\/[0-9a-zA-Zа-яА-Я]([-.\w]*[0-9a-zA-Zа-яА-Я])*(:(0-9)*)*(\/?)([a-zAZ0-9а-яА-Я\-\.\?\,\'\/\\\+&=%$#_]*)?$
|
||||||
|
```
|
||||||
|
|
||||||
|
Выбрасывает исключения:
|
||||||
|
* `AtolCallbackUrlTooLongException` (если слишком длинный url);
|
||||||
|
* `AtolInvalidCallbackUrlException` (если url невалиден).
|
||||||
|
|
||||||
## Обработка результата регистрации
|
## Обработка результата регистрации
|
||||||
|
|
||||||
Методы `sell()`, `sellRefund()`, `sellCorrection()`, `buy()`, `buyRefund()` и `buyCorrection()` возвращают объект `AtolOnline\Api\KktResponse`.
|
Методы `sell()`, `sellRefund()`, `sellCorrection()`, `buy()`, `buyRefund()` и `buyCorrection()` возвращают объект `AtolOnline\Api\KktResponse`.
|
||||||
@@ -138,7 +209,7 @@ $kkt->getCallbackUrl();
|
|||||||
Этот объект содержит в себе HTTP-код ответа, массив заголовков и JSON-декодированные данные тела ответа.
|
Этот объект содержит в себе HTTP-код ответа, массив заголовков и JSON-декодированные данные тела ответа.
|
||||||
|
|
||||||
```php
|
```php
|
||||||
$result = $kkt->getLastResponse();
|
$result = $kkt->getLastResponse(); // вернёт последний ответ от API
|
||||||
$headers = $result->getHeaders(); // вернёт заголовки
|
$headers = $result->getHeaders(); // вернёт заголовки
|
||||||
$code = $result->getCode(); // вернёт код ответа
|
$code = $result->getCode(); // вернёт код ответа
|
||||||
$body = $result->getContent(); // вернёт JSON-декодированное тело ответа
|
$body = $result->getContent(); // вернёт JSON-декодированное тело ответа
|
||||||
@@ -158,7 +229,7 @@ $err_text = $result->error->text;
|
|||||||
Проверка корректности ответа (отсутствия ошибок) работает через метод `isValid()`:
|
Проверка корректности ответа (отсутствия ошибок) работает через метод `isValid()`:
|
||||||
|
|
||||||
```php
|
```php
|
||||||
$kkt->isValid(); // вернёт true, если ошибок нет
|
$kkt->getLastResponse()->isValid(); // вернёт true, если ошибок нет
|
||||||
```
|
```
|
||||||
|
|
||||||
## Проверка статуса документа
|
## Проверка статуса документа
|
||||||
|
|||||||
@@ -9,12 +9,19 @@
|
|||||||
|
|
||||||
namespace AtolOnline\Api;
|
namespace AtolOnline\Api;
|
||||||
|
|
||||||
use AtolOnline\{Entities\Document,
|
use AtolOnline\{Constants\Constraints,
|
||||||
|
Constants\TestEnvParams,
|
||||||
|
Entities\Company,
|
||||||
|
Entities\Document,
|
||||||
|
Exceptions\AtolAuthFailedException,
|
||||||
|
Exceptions\AtolCallbackUrlTooLongException,
|
||||||
Exceptions\AtolCorrectionInfoException,
|
Exceptions\AtolCorrectionInfoException,
|
||||||
|
Exceptions\AtolInvalidCallbackUrlException,
|
||||||
Exceptions\AtolInvalidUuidException,
|
Exceptions\AtolInvalidUuidException,
|
||||||
Exceptions\AtolKktLoginEmptyException,
|
Exceptions\AtolKktLoginEmptyException,
|
||||||
Exceptions\AtolKktLoginTooLongException,
|
Exceptions\AtolKktLoginTooLongException,
|
||||||
Exceptions\AtolKktPasswordEmptyException,
|
Exceptions\AtolKktPasswordEmptyException,
|
||||||
|
Exceptions\AtolKktPasswordTooLongException,
|
||||||
Exceptions\AtolWrongDocumentTypeException
|
Exceptions\AtolWrongDocumentTypeException
|
||||||
};
|
};
|
||||||
use GuzzleHttp\Client;
|
use GuzzleHttp\Client;
|
||||||
@@ -58,6 +65,7 @@ class Kkt extends Client
|
|||||||
* @throws \AtolOnline\Exceptions\AtolKktLoginEmptyException Логин ККТ не может быть пустым
|
* @throws \AtolOnline\Exceptions\AtolKktLoginEmptyException Логин ККТ не может быть пустым
|
||||||
* @throws \AtolOnline\Exceptions\AtolKktLoginTooLongException Слишком длинный логин ККТ
|
* @throws \AtolOnline\Exceptions\AtolKktLoginTooLongException Слишком длинный логин ККТ
|
||||||
* @throws \AtolOnline\Exceptions\AtolKktPasswordEmptyException Пароль ККТ не может быть пустым
|
* @throws \AtolOnline\Exceptions\AtolKktPasswordEmptyException Пароль ККТ не может быть пустым
|
||||||
|
* @throws \AtolOnline\Exceptions\AtolKktPasswordTooLongException Слишком длинный пароль ККТ
|
||||||
* @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(
|
||||||
@@ -115,12 +123,10 @@ class Kkt extends Client
|
|||||||
*/
|
*/
|
||||||
public function setLogin(string $login)
|
public function setLogin(string $login)
|
||||||
{
|
{
|
||||||
if (!$this->isTestMode()) {
|
if (empty($login)) {
|
||||||
if (empty($login)) {
|
throw new AtolKktLoginEmptyException();
|
||||||
throw new AtolKktLoginEmptyException();
|
} elseif (valid_strlen($login) > Constraints::MAX_LENGTH_LOGIN) {
|
||||||
} elseif ((function_exists('mb_strlen') ? mb_strlen($login) : strlen($login)) > 100) {
|
throw new AtolKktLoginTooLongException($login, Constraints::MAX_LENGTH_LOGIN);
|
||||||
throw new AtolKktLoginTooLongException($login, 100);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
$this->kkt_config['prod']['login'] = $login;
|
$this->kkt_config['prod']['login'] = $login;
|
||||||
return $this;
|
return $this;
|
||||||
@@ -142,13 +148,14 @@ class Kkt extends Client
|
|||||||
* @param string $password
|
* @param string $password
|
||||||
* @return $this
|
* @return $this
|
||||||
* @throws \AtolOnline\Exceptions\AtolKktPasswordEmptyException Пароль ККТ не может быть пустым
|
* @throws \AtolOnline\Exceptions\AtolKktPasswordEmptyException Пароль ККТ не может быть пустым
|
||||||
|
* @throws \AtolOnline\Exceptions\AtolKktPasswordTooLongException Слишком длинный пароль ККТ
|
||||||
*/
|
*/
|
||||||
public function setPassword(string $password)
|
public function setPassword(string $password)
|
||||||
{
|
{
|
||||||
if (!$this->isTestMode()) {
|
if (empty($password)) {
|
||||||
if (empty($password)) {
|
throw new AtolKktPasswordEmptyException();
|
||||||
throw new AtolKktPasswordEmptyException();
|
} elseif (valid_strlen($password) > Constraints::MAX_LENGTH_PASSWORD) {
|
||||||
}
|
throw new AtolKktPasswordTooLongException($password, Constraints::MAX_LENGTH_PASSWORD);
|
||||||
}
|
}
|
||||||
$this->kkt_config['prod']['pass'] = $password;
|
$this->kkt_config['prod']['pass'] = $password;
|
||||||
return $this;
|
return $this;
|
||||||
@@ -169,9 +176,16 @@ class Kkt extends Client
|
|||||||
*
|
*
|
||||||
* @param string $url
|
* @param string $url
|
||||||
* @return $this
|
* @return $this
|
||||||
|
* @throws \AtolOnline\Exceptions\AtolCallbackUrlTooLongException Слишком длинный Callback URL
|
||||||
|
* @throws \AtolOnline\Exceptions\AtolInvalidCallbackUrlException Невалидный Callback URL
|
||||||
*/
|
*/
|
||||||
public function setCallbackUrl(string $url)
|
public function setCallbackUrl(string $url)
|
||||||
{
|
{
|
||||||
|
if (valid_strlen($url) > Constraints::MAX_LENGTH_CALLBACK_URL) {
|
||||||
|
throw new AtolCallbackUrlTooLongException($url, Constraints::MAX_LENGTH_CALLBACK_URL);
|
||||||
|
} elseif (!preg_match(Constraints::PATTERN_CALLBACK_URL, $url)) {
|
||||||
|
throw new AtolInvalidCallbackUrlException('Callback URL not matches with pattern');
|
||||||
|
}
|
||||||
$this->kkt_config[$this->isTestMode() ? 'test' : 'prod']['callback_url'] = $url;
|
$this->kkt_config[$this->isTestMode() ? 'test' : 'prod']['callback_url'] = $url;
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
@@ -221,105 +235,135 @@ class Kkt extends Client
|
|||||||
/**
|
/**
|
||||||
* Регистрирует документ прихода
|
* Регистрирует документ прихода
|
||||||
*
|
*
|
||||||
* @param \AtolOnline\Entities\Document $document
|
* @param \AtolOnline\Entities\Document $document Объект документа
|
||||||
|
* @param string|null $external_id Уникальный код документа (если не указан, то будет создан UUID)
|
||||||
* @return \AtolOnline\Api\KktResponse
|
* @return \AtolOnline\Api\KktResponse
|
||||||
* @throws \AtolOnline\Exceptions\AtolWrongDocumentTypeException Некорректный тип документа
|
* @throws \AtolOnline\Exceptions\AtolAuthFailedException Ошибка авторизации
|
||||||
* @throws \AtolOnline\Exceptions\AtolCorrectionInfoException В документе есть данные коррекции
|
* @throws \AtolOnline\Exceptions\AtolCorrectionInfoException В документе есть данные коррекции
|
||||||
|
* @throws \AtolOnline\Exceptions\AtolInnWrongLengthException Некорректная длина ИНН
|
||||||
|
* @throws \AtolOnline\Exceptions\AtolPaymentAddressTooLongException Слишком длинный адрес места расчётов
|
||||||
|
* @throws \AtolOnline\Exceptions\AtolWrongDocumentTypeException Некорректный тип документа
|
||||||
|
* @throws \GuzzleHttp\Exception\GuzzleException
|
||||||
*/
|
*/
|
||||||
public function sell(Document $document)
|
public function sell(Document $document, ?string $external_id = null)
|
||||||
{
|
{
|
||||||
if ($document->getCorrectionInfo()) {
|
if ($document->getCorrectionInfo()) {
|
||||||
throw new AtolCorrectionInfoException('Некорректная операция над документом коррекции');
|
throw new AtolCorrectionInfoException('Некорректная операция над документом коррекции');
|
||||||
}
|
}
|
||||||
return $this->registerDocument('sell', 'receipt', $document);
|
return $this->registerDocument('sell', 'receipt', $document, $external_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Регистрирует документ возврата прихода
|
* Регистрирует документ возврата прихода
|
||||||
*
|
*
|
||||||
* @param \AtolOnline\Entities\Document $document
|
* @param \AtolOnline\Entities\Document $document Объект документа
|
||||||
|
* @param string|null $external_id Уникальный код документа (если не указан, то будет создан UUID)
|
||||||
* @return \AtolOnline\Api\KktResponse
|
* @return \AtolOnline\Api\KktResponse
|
||||||
|
* @throws \AtolOnline\Exceptions\AtolAuthFailedException Ошибка авторизации
|
||||||
|
* @throws \AtolOnline\Exceptions\AtolCorrectionInfoException В документе есть данные коррекции
|
||||||
|
* @throws \AtolOnline\Exceptions\AtolInnWrongLengthException Некорректная длина ИНН
|
||||||
|
* @throws \AtolOnline\Exceptions\AtolPaymentAddressTooLongException Слишком длинный адрес места расчётов
|
||||||
* @throws \AtolOnline\Exceptions\AtolPriceTooHighException Слишком большая сумма
|
* @throws \AtolOnline\Exceptions\AtolPriceTooHighException Слишком большая сумма
|
||||||
* @throws \AtolOnline\Exceptions\AtolTooManyVatsException Слишком много ставок НДС
|
* @throws \AtolOnline\Exceptions\AtolTooManyVatsException Слишком много ставок НДС
|
||||||
* @throws \AtolOnline\Exceptions\AtolWrongDocumentTypeException Некорректный тип документа
|
* @throws \AtolOnline\Exceptions\AtolWrongDocumentTypeException Некорректный тип документа
|
||||||
* @throws \AtolOnline\Exceptions\AtolCorrectionInfoException В документе есть данные коррекции
|
* @throws \GuzzleHttp\Exception\GuzzleException
|
||||||
*/
|
*/
|
||||||
public function sellRefund(Document $document)
|
public function sellRefund(Document $document, ?string $external_id = null)
|
||||||
{
|
{
|
||||||
if ($document->getCorrectionInfo()) {
|
if ($document->getCorrectionInfo()) {
|
||||||
throw new AtolCorrectionInfoException('Некорректная операция над документом коррекции');
|
throw new AtolCorrectionInfoException('Invalid operation on correction document');
|
||||||
}
|
}
|
||||||
return $this->registerDocument('sell_refund', 'receipt', $document->clearVats());
|
return $this->registerDocument('sell_refund', 'receipt', $document->clearVats(), $external_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Регистрирует документ коррекции прихода
|
* Регистрирует документ коррекции прихода
|
||||||
*
|
*
|
||||||
* @param \AtolOnline\Entities\Document $document
|
* @param \AtolOnline\Entities\Document $document Объект документа
|
||||||
|
* @param string|null $external_id Уникальный код документа (если не указан, то будет создан UUID)
|
||||||
* @return \AtolOnline\Api\KktResponse
|
* @return \AtolOnline\Api\KktResponse
|
||||||
* @throws \AtolOnline\Exceptions\AtolWrongDocumentTypeException Некорректный тип документа
|
* @throws \AtolOnline\Exceptions\AtolAuthFailedException Ошибка авторизации
|
||||||
* @throws \AtolOnline\Exceptions\AtolCorrectionInfoException В документе отсутствуют данные коррекции
|
* @throws \AtolOnline\Exceptions\AtolCorrectionInfoException В документе отсутствуют данные коррекции
|
||||||
|
* @throws \AtolOnline\Exceptions\AtolInnWrongLengthException Некорректная длина ИНН
|
||||||
|
* @throws \AtolOnline\Exceptions\AtolPaymentAddressTooLongException Слишком длинный адрес места расчётов
|
||||||
* @throws \AtolOnline\Exceptions\AtolTooManyItemsException Слишком много предметов расчёта
|
* @throws \AtolOnline\Exceptions\AtolTooManyItemsException Слишком много предметов расчёта
|
||||||
|
* @throws \AtolOnline\Exceptions\AtolWrongDocumentTypeException Некорректный тип документа
|
||||||
|
* @throws \GuzzleHttp\Exception\GuzzleException
|
||||||
*/
|
*/
|
||||||
public function sellCorrection(Document $document)
|
public function sellCorrection(Document $document, ?string $external_id = null)
|
||||||
{
|
{
|
||||||
if (!$document->getCorrectionInfo()) {
|
if (!$document->getCorrectionInfo()) {
|
||||||
throw new AtolCorrectionInfoException();
|
throw new AtolCorrectionInfoException();
|
||||||
}
|
}
|
||||||
$document->setClient(null)->setItems([]);
|
$document->setClient(null)->setItems([]);
|
||||||
return $this->registerDocument('sell_correction', 'correction', $document);
|
return $this->registerDocument('sell_correction', 'correction', $document, $external_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Регистрирует документ расхода
|
* Регистрирует документ расхода
|
||||||
*
|
*
|
||||||
* @param \AtolOnline\Entities\Document $document
|
* @param \AtolOnline\Entities\Document $document
|
||||||
|
* @param string|null $external_id Уникальный код документа (если не указан, то будет создан UUID)
|
||||||
* @return \AtolOnline\Api\KktResponse
|
* @return \AtolOnline\Api\KktResponse
|
||||||
* @throws \AtolOnline\Exceptions\AtolWrongDocumentTypeException Некорректный тип документа
|
* @throws \AtolOnline\Exceptions\AtolAuthFailedException Ошибка авторизации
|
||||||
* @throws \AtolOnline\Exceptions\AtolCorrectionInfoException В документе есть данные коррекции
|
* @throws \AtolOnline\Exceptions\AtolCorrectionInfoException В документе есть данные коррекции
|
||||||
|
* @throws \AtolOnline\Exceptions\AtolInnWrongLengthException Некорректная длина ИНН
|
||||||
|
* @throws \AtolOnline\Exceptions\AtolPaymentAddressTooLongException Слишком длинный адрес места расчётов
|
||||||
|
* @throws \AtolOnline\Exceptions\AtolWrongDocumentTypeException Некорректный тип документа
|
||||||
|
* @throws \GuzzleHttp\Exception\GuzzleException
|
||||||
*/
|
*/
|
||||||
public function buy(Document $document)
|
public function buy(Document $document, ?string $external_id = null)
|
||||||
{
|
{
|
||||||
if ($document->getCorrectionInfo()) {
|
if ($document->getCorrectionInfo()) {
|
||||||
throw new AtolCorrectionInfoException('Некорректная операция над документом коррекции');
|
throw new AtolCorrectionInfoException('Invalid operation on correction document');
|
||||||
}
|
}
|
||||||
return $this->registerDocument('buy', 'receipt', $document);
|
return $this->registerDocument('buy', 'receipt', $document, $external_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Регистрирует документ возврата расхода
|
* Регистрирует документ возврата расхода
|
||||||
*
|
*
|
||||||
* @param \AtolOnline\Entities\Document $document
|
* @param \AtolOnline\Entities\Document $document
|
||||||
|
* @param string|null $external_id Уникальный код документа (если не указан, то будет создан UUID)
|
||||||
* @return \AtolOnline\Api\KktResponse
|
* @return \AtolOnline\Api\KktResponse
|
||||||
|
* @throws \AtolOnline\Exceptions\AtolAuthFailedException Ошибка авторизации
|
||||||
|
* @throws \AtolOnline\Exceptions\AtolCorrectionInfoException В документе есть данные коррекции
|
||||||
|
* @throws \AtolOnline\Exceptions\AtolInnWrongLengthException Некорректная длина ИНН
|
||||||
|
* @throws \AtolOnline\Exceptions\AtolPaymentAddressTooLongException Слишком длинный адрес места расчётов
|
||||||
* @throws \AtolOnline\Exceptions\AtolPriceTooHighException Слишком большая сумма
|
* @throws \AtolOnline\Exceptions\AtolPriceTooHighException Слишком большая сумма
|
||||||
* @throws \AtolOnline\Exceptions\AtolTooManyVatsException Слишком много ставок НДС
|
* @throws \AtolOnline\Exceptions\AtolTooManyVatsException Слишком много ставок НДС
|
||||||
* @throws \AtolOnline\Exceptions\AtolWrongDocumentTypeException Некорректный тип документа
|
* @throws \AtolOnline\Exceptions\AtolWrongDocumentTypeException Некорректный тип документа
|
||||||
* @throws \AtolOnline\Exceptions\AtolCorrectionInfoException В документе есть данные коррекции
|
* @throws \GuzzleHttp\Exception\GuzzleException
|
||||||
*/
|
*/
|
||||||
public function buyRefund(Document $document)
|
public function buyRefund(Document $document, ?string $external_id = null)
|
||||||
{
|
{
|
||||||
if ($document->getCorrectionInfo()) {
|
if ($document->getCorrectionInfo()) {
|
||||||
throw new AtolCorrectionInfoException('Некорректная операция над документом коррекции');
|
throw new AtolCorrectionInfoException('Invalid operation on correction document');
|
||||||
}
|
}
|
||||||
return $this->registerDocument('buy_refund', 'receipt', $document->clearVats());
|
return $this->registerDocument('buy_refund', 'receipt', $document->clearVats(), $external_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Регистрирует документ коррекции расхода
|
* Регистрирует документ коррекции расхода
|
||||||
*
|
*
|
||||||
* @param Document $document
|
* @param \AtolOnline\Entities\Document $document
|
||||||
|
* @param string|null $external_id Уникальный код документа (если не указан, то будет создан UUID)
|
||||||
* @return \AtolOnline\Api\KktResponse
|
* @return \AtolOnline\Api\KktResponse
|
||||||
* @throws \AtolOnline\Exceptions\AtolWrongDocumentTypeException Некорректный тип документа
|
* @throws \AtolOnline\Exceptions\AtolAuthFailedException Ошибка авторизации
|
||||||
* @throws \AtolOnline\Exceptions\AtolCorrectionInfoException В документе отсутствуют данные коррекции
|
* @throws \AtolOnline\Exceptions\AtolCorrectionInfoException В документе отсутствуют данные коррекции
|
||||||
|
* @throws \AtolOnline\Exceptions\AtolInnWrongLengthException Некорректная длтина ИНН
|
||||||
|
* @throws \AtolOnline\Exceptions\AtolPaymentAddressTooLongException Слишком длинный адрес места расчётов
|
||||||
* @throws \AtolOnline\Exceptions\AtolTooManyItemsException Слишком много предметов расчёта
|
* @throws \AtolOnline\Exceptions\AtolTooManyItemsException Слишком много предметов расчёта
|
||||||
|
* @throws \AtolOnline\Exceptions\AtolWrongDocumentTypeException Некорректный тип документа
|
||||||
|
* @throws \GuzzleHttp\Exception\GuzzleException
|
||||||
*/
|
*/
|
||||||
public function buyCorrection(Document $document)
|
public function buyCorrection(Document $document, ?string $external_id = null)
|
||||||
{
|
{
|
||||||
if (!$document->getCorrectionInfo()) {
|
if (!$document->getCorrectionInfo()) {
|
||||||
throw new AtolCorrectionInfoException();
|
throw new AtolCorrectionInfoException();
|
||||||
}
|
}
|
||||||
$document->setClient(null)->setItems([]);
|
$document->setClient(null)->setItems([]);
|
||||||
return $this->registerDocument('buy_correction', 'correction', $document);
|
return $this->registerDocument('buy_correction', 'correction', $document, $external_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -327,7 +371,9 @@ class Kkt extends Client
|
|||||||
*
|
*
|
||||||
* @param string $uuid UUID регистрации
|
* @param string $uuid UUID регистрации
|
||||||
* @return \AtolOnline\Api\KktResponse
|
* @return \AtolOnline\Api\KktResponse
|
||||||
|
* @throws \AtolOnline\Exceptions\AtolAuthFailedException Ошибка авторизации
|
||||||
* @throws \AtolOnline\Exceptions\AtolInvalidUuidException Некорректный UUID документа
|
* @throws \AtolOnline\Exceptions\AtolInvalidUuidException Некорректный UUID документа
|
||||||
|
* @throws \GuzzleHttp\Exception\GuzzleException
|
||||||
*/
|
*/
|
||||||
public function getDocumentStatus(string $uuid)
|
public function getDocumentStatus(string $uuid)
|
||||||
{
|
{
|
||||||
@@ -347,7 +393,9 @@ class Kkt extends Client
|
|||||||
* @param int $retry_count Количество попыток
|
* @param int $retry_count Количество попыток
|
||||||
* @param int $timeout Таймаут в секундах между попытками
|
* @param int $timeout Таймаут в секундах между попытками
|
||||||
* @return \AtolOnline\Api\KktResponse
|
* @return \AtolOnline\Api\KktResponse
|
||||||
* @throws \AtolOnline\Exceptions\AtolException Некорректный UUID документа
|
* @throws \AtolOnline\Exceptions\AtolAuthFailedException Ошибка авторизации
|
||||||
|
* @throws \AtolOnline\Exceptions\AtolInvalidUuidException Некорректный UUID документа
|
||||||
|
* @throws \GuzzleHttp\Exception\GuzzleException
|
||||||
*/
|
*/
|
||||||
public function pollDocumentStatus(string $uuid, int $retry_count = 5, int $timeout = 1)
|
public function pollDocumentStatus(string $uuid, int $retry_count = 5, int $timeout = 1)
|
||||||
{
|
{
|
||||||
@@ -396,9 +444,9 @@ class Kkt extends Client
|
|||||||
$this->kkt_config['prod']['pass'] = '';
|
$this->kkt_config['prod']['pass'] = '';
|
||||||
$this->kkt_config['prod']['url'] = 'https://online.atol.ru/possystem/v4';
|
$this->kkt_config['prod']['url'] = 'https://online.atol.ru/possystem/v4';
|
||||||
$this->kkt_config['prod']['callback_url'] = '';
|
$this->kkt_config['prod']['callback_url'] = '';
|
||||||
$this->kkt_config['test']['group'] = 'v4-online-atol-ru_4179';
|
$this->kkt_config['test']['group'] = TestEnvParams::GROUP;
|
||||||
$this->kkt_config['test']['login'] = 'v4-online-atol-ru';
|
$this->kkt_config['test']['login'] = TestEnvParams::LOGIN;
|
||||||
$this->kkt_config['test']['pass'] = 'iGFFuihss';
|
$this->kkt_config['test']['pass'] = TestEnvParams::PASSWORD;
|
||||||
$this->kkt_config['test']['url'] = 'https://testonline.atol.ru/possystem/v4';
|
$this->kkt_config['test']['url'] = 'https://testonline.atol.ru/possystem/v4';
|
||||||
$this->kkt_config['test']['callback_url'] = '';
|
$this->kkt_config['test']['callback_url'] = '';
|
||||||
}
|
}
|
||||||
@@ -472,6 +520,7 @@ class Kkt extends Client
|
|||||||
* Производит авторизацию на ККТ и получает токен доступа для дальнейших HTTP-запросов
|
* Производит авторизацию на ККТ и получает токен доступа для дальнейших HTTP-запросов
|
||||||
*
|
*
|
||||||
* @return bool
|
* @return bool
|
||||||
|
* @throws \AtolOnline\Exceptions\AtolAuthFailedException Ошибка авторизации
|
||||||
* @throws \GuzzleHttp\Exception\GuzzleException
|
* @throws \GuzzleHttp\Exception\GuzzleException
|
||||||
*/
|
*/
|
||||||
protected function auth()
|
protected function auth()
|
||||||
@@ -482,7 +531,7 @@ class Kkt extends Client
|
|||||||
'pass' => $this->getPassword(),
|
'pass' => $this->getPassword(),
|
||||||
]);
|
]);
|
||||||
if (!$result->isValid() || !$result->getContent()->token) {
|
if (!$result->isValid() || !$result->getContent()->token) {
|
||||||
return false;
|
throw new AtolAuthFailedException($result);
|
||||||
}
|
}
|
||||||
$this->auth_token = $result->getContent()->token;
|
$this->auth_token = $result->getContent()->token;
|
||||||
}
|
}
|
||||||
@@ -497,7 +546,10 @@ class Kkt extends Client
|
|||||||
* @param \AtolOnline\Entities\Document $document Объект документа
|
* @param \AtolOnline\Entities\Document $document Объект документа
|
||||||
* @param string|null $external_id Уникальный код документа (если не указан, то будет создан UUID)
|
* @param string|null $external_id Уникальный код документа (если не указан, то будет создан UUID)
|
||||||
* @return \AtolOnline\Api\KktResponse
|
* @return \AtolOnline\Api\KktResponse
|
||||||
* @throws \AtolOnline\Exceptions\AtolWrongDocumentTypeException
|
* @throws \AtolOnline\Exceptions\AtolAuthFailedException Ошибка авторизации
|
||||||
|
* @throws \AtolOnline\Exceptions\AtolWrongDocumentTypeException Некорректный тип документа
|
||||||
|
* @throws \AtolOnline\Exceptions\AtolInnWrongLengthException Некорректная длина ИНН
|
||||||
|
* @throws \AtolOnline\Exceptions\AtolPaymentAddressTooLongException Слишком длинный адрес места расчётов
|
||||||
* @throws \GuzzleHttp\Exception\GuzzleException
|
* @throws \GuzzleHttp\Exception\GuzzleException
|
||||||
*/
|
*/
|
||||||
protected function registerDocument(string $api_method, string $type, Document $document, ?string $external_id = null)
|
protected function registerDocument(string $api_method, string $type, Document $document, ?string $external_id = null)
|
||||||
@@ -507,6 +559,12 @@ class Kkt extends Client
|
|||||||
throw new AtolWrongDocumentTypeException($type);
|
throw new AtolWrongDocumentTypeException($type);
|
||||||
}
|
}
|
||||||
$this->auth();
|
$this->auth();
|
||||||
|
if ($this->isTestMode()) {
|
||||||
|
$document->setCompany(($document->getCompany() ?: new Company())
|
||||||
|
->setInn(TestEnvParams::INN)
|
||||||
|
->setSno(TestEnvParams::SNO)
|
||||||
|
->setPaymentAddress(TestEnvParams::PAYMENT_ADDRESS));
|
||||||
|
}
|
||||||
$data['timestamp'] = date('d.m.y H:i:s');
|
$data['timestamp'] = date('d.m.y H:i:s');
|
||||||
$data['external_id'] = $external_id ?: Uuid::uuid4()->toString();
|
$data['external_id'] = $external_id ?: Uuid::uuid4()->toString();
|
||||||
$data[$type] = $document;
|
$data[$type] = $document;
|
||||||
|
|||||||
@@ -1,23 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace AtolOnline\Api;
|
|
||||||
|
|
||||||
abstract class AtolSchema
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @return mixed
|
|
||||||
*/
|
|
||||||
public static function get()
|
|
||||||
{
|
|
||||||
return static::$json
|
|
||||||
?? static::$json = json_decode(file_get_contents(static::$URL));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return false|string
|
|
||||||
*/
|
|
||||||
public static function json()
|
|
||||||
{
|
|
||||||
return json_encode(static::get());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace AtolOnline\Api;
|
|
||||||
|
|
||||||
class CorrectionSchema extends AtolSchema
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @var
|
|
||||||
*/
|
|
||||||
protected static $json;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Адрес схемы
|
|
||||||
*/
|
|
||||||
protected static $URL = 'https://online.atol.ru/possystem/v4/schema/correction';
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace AtolOnline\Api;
|
|
||||||
|
|
||||||
class SellSchema extends AtolSchema
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @var
|
|
||||||
*/
|
|
||||||
protected static $json;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Адрес схемы
|
|
||||||
*/
|
|
||||||
protected static $URL = 'https://online.atol.ru/possystem/v4/schema/sell';
|
|
||||||
|
|
||||||
}
|
|
||||||
76
src/AtolOnline/Constants/Constraints.php
Normal file
76
src/AtolOnline/Constants/Constraints.php
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace AtolOnline\Constants;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Класс с константами ограничений: максимальные длины, правила валидации значений
|
||||||
|
*
|
||||||
|
* @package AtolOnline\Constants
|
||||||
|
*/
|
||||||
|
class Constraints
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Максимальная длина Callback URL
|
||||||
|
*/
|
||||||
|
const MAX_LENGTH_CALLBACK_URL = 256;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Максимальная длина email
|
||||||
|
*/
|
||||||
|
const MAX_LENGTH_EMAIL = 64;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Максимальная длина логина ККТ
|
||||||
|
*/
|
||||||
|
const MAX_LENGTH_LOGIN = 100;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Максимальная длина пароля ККТ
|
||||||
|
*/
|
||||||
|
const MAX_LENGTH_PASSWORD = 100;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Максимальная длина имени покупателя
|
||||||
|
*/
|
||||||
|
const MAX_LENGTH_CLIENT_NAME = 256;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Максимальная длина телефона покупателя
|
||||||
|
*/
|
||||||
|
const MAX_LENGTH_CLIENT_PHONE = 64;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Максимальная длина адреса места расчётов
|
||||||
|
*/
|
||||||
|
const MAX_LENGTH_PAYMENT_ADDRESS = 256;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Максимальная длина имени кассира
|
||||||
|
*/
|
||||||
|
const MAX_LENGTH_CASHIER_NAME = 64;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Максимальная длина наименования предмета расчётов
|
||||||
|
*/
|
||||||
|
const MAX_LENGTH_ITEM_NAME = 128;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Максимальная длина единицы измерения предмета расчётов
|
||||||
|
*/
|
||||||
|
const MAX_LENGTH_MEASUREMENT_UNIT = 16;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Максимальная длина пользовательских данных для предмета расчётов
|
||||||
|
*/
|
||||||
|
const MAX_LENGTH_USER_DATA = 64;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Регулярное выражание для валидации строки ИНН
|
||||||
|
*/
|
||||||
|
const PATTERN_INN = "/(^[0-9]{10}$)|(^[0-9]{12}$)/";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Регулярное выражание для валидации строки Callback URL
|
||||||
|
*/
|
||||||
|
const PATTERN_CALLBACK_URL = "/^http(s?)\:\/\/[0-9a-zA-Zа-яА-Я]([-.\w]*[0-9a-zA-Zа-яА-Я])*(:(0-9)*)*(\/?)([a-zAZ0-9а-яА-Я\-\.\?\,\'\/\\\+&=%\$#_]*)?$/";
|
||||||
|
}
|
||||||
49
src/AtolOnline/Constants/TestEnvParams.php
Normal file
49
src/AtolOnline/Constants/TestEnvParams.php
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Copyright (c) Антон Аксенов (aka Anthony Axenov)
|
||||||
|
*
|
||||||
|
* This code is licensed under MIT.
|
||||||
|
* Этот код распространяется по лицензии MIT.
|
||||||
|
* https://github.com/anthonyaxenov/atol-online/blob/master/LICENSE
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace AtolOnline\Constants;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Константы, определяющие параметры тестовой среды
|
||||||
|
*
|
||||||
|
* @see https://online.atol.ru/files/ffd/test_sreda.txt
|
||||||
|
* @package AtolOnline\Constants
|
||||||
|
*/
|
||||||
|
class TestEnvParams
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Логин
|
||||||
|
*/
|
||||||
|
const LOGIN = 'v4-online-atol-ru';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Пароль
|
||||||
|
*/
|
||||||
|
const PASSWORD = 'iGFFuihss';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Группа
|
||||||
|
*/
|
||||||
|
const GROUP = 'v4-online-atol-ru_4179';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Система налогообложения
|
||||||
|
*/
|
||||||
|
const SNO = SnoTypes::OSN;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ИНН
|
||||||
|
*/
|
||||||
|
const INN = '5544332219';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Адрес места расчётов
|
||||||
|
*/
|
||||||
|
const PAYMENT_ADDRESS = 'https://v4.online.atol.ru';
|
||||||
|
}
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
namespace AtolOnline\Entities;
|
namespace AtolOnline\Entities;
|
||||||
|
|
||||||
use AtolOnline\{Exceptions\AtolNameTooLongException, Exceptions\AtolPhoneTooLongException, Traits\HasEmail, Traits\HasInn};
|
use AtolOnline\{Constants\Constraints, Exceptions\AtolNameTooLongException, Exceptions\AtolPhoneTooLongException, Traits\HasEmail, Traits\HasInn};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Класс Client, описывающий сущность покупателя
|
* Класс Client, описывающий сущность покупателя
|
||||||
@@ -46,11 +46,11 @@ class Client extends Entity
|
|||||||
* @param string|null $phone Телефон
|
* @param string|null $phone Телефон
|
||||||
* @param string|null $email Email
|
* @param string|null $email Email
|
||||||
* @param string|null $inn ИНН
|
* @param string|null $inn ИНН
|
||||||
* @throws \AtolOnline\Exceptions\AtolEmailTooLongException
|
* @throws \AtolOnline\Exceptions\AtolEmailTooLongException Слишком длинный email
|
||||||
* @throws \AtolOnline\Exceptions\AtolEmailValidateException
|
* @throws \AtolOnline\Exceptions\AtolEmailValidateException Невалидный email
|
||||||
* @throws \AtolOnline\Exceptions\AtolInnWrongLengthException
|
* @throws \AtolOnline\Exceptions\AtolInnWrongLengthException Некорректная длина ИНН
|
||||||
* @throws \AtolOnline\Exceptions\AtolNameTooLongException
|
* @throws \AtolOnline\Exceptions\AtolNameTooLongException Слишком длинное имя
|
||||||
* @throws \AtolOnline\Exceptions\AtolPhoneTooLongException
|
* @throws \AtolOnline\Exceptions\AtolPhoneTooLongException СЛишком длинный номер телефона
|
||||||
*/
|
*/
|
||||||
public function __construct(?string $name = null, ?string $phone = null, ?string $email = null, ?string $inn = null)
|
public function __construct(?string $name = null, ?string $phone = null, ?string $email = null, ?string $inn = null)
|
||||||
{
|
{
|
||||||
@@ -89,8 +89,8 @@ class Client extends Entity
|
|||||||
public function setName(string $name)
|
public function setName(string $name)
|
||||||
{
|
{
|
||||||
$name = trim($name);
|
$name = trim($name);
|
||||||
if ((function_exists('mb_strlen') ? mb_strlen($name) : strlen($name)) > 256) {
|
if (valid_strlen($name) > Constraints::MAX_LENGTH_CLIENT_NAME) {
|
||||||
throw new AtolNameTooLongException($name, 256);
|
throw new AtolNameTooLongException($name, Constraints::MAX_LENGTH_CLIENT_NAME);
|
||||||
}
|
}
|
||||||
$this->name = $name;
|
$this->name = $name;
|
||||||
return $this;
|
return $this;
|
||||||
@@ -119,8 +119,8 @@ class Client extends Entity
|
|||||||
public function setPhone(string $phone)
|
public function setPhone(string $phone)
|
||||||
{
|
{
|
||||||
$phone = preg_replace("/[^0-9+]/", '', $phone);
|
$phone = preg_replace("/[^0-9+]/", '', $phone);
|
||||||
if ((function_exists('mb_strlen') ? mb_strlen($phone) : strlen($phone)) > 64) {
|
if (valid_strlen($phone) > Constraints::MAX_LENGTH_CLIENT_PHONE) {
|
||||||
throw new AtolPhoneTooLongException($phone, 64);
|
throw new AtolPhoneTooLongException($phone, Constraints::MAX_LENGTH_CLIENT_PHONE);
|
||||||
}
|
}
|
||||||
$this->phone = $phone;
|
$this->phone = $phone;
|
||||||
return $this;
|
return $this;
|
||||||
|
|||||||
@@ -9,7 +9,8 @@
|
|||||||
|
|
||||||
namespace AtolOnline\Entities;
|
namespace AtolOnline\Entities;
|
||||||
|
|
||||||
use AtolOnline\{Exceptions\AtolEmailTooLongException,
|
use AtolOnline\{Constants\Constraints,
|
||||||
|
Exceptions\AtolEmailTooLongException,
|
||||||
Exceptions\AtolEmailValidateException,
|
Exceptions\AtolEmailValidateException,
|
||||||
Exceptions\AtolInnWrongLengthException,
|
Exceptions\AtolInnWrongLengthException,
|
||||||
Exceptions\AtolPaymentAddressTooLongException,
|
Exceptions\AtolPaymentAddressTooLongException,
|
||||||
@@ -52,10 +53,10 @@ class Company extends Entity
|
|||||||
* @param string|null $inn
|
* @param string|null $inn
|
||||||
* @param string|null $paymentAddress
|
* @param string|null $paymentAddress
|
||||||
* @param string|null $email
|
* @param string|null $email
|
||||||
* @throws AtolEmailTooLongException
|
* @throws AtolEmailTooLongException Слишком длинный email
|
||||||
* @throws AtolEmailValidateException
|
* @throws AtolEmailValidateException Невалидный email
|
||||||
* @throws AtolInnWrongLengthException
|
* @throws AtolInnWrongLengthException Некорректная длина ИНН
|
||||||
* @throws AtolPaymentAddressTooLongException
|
* @throws AtolPaymentAddressTooLongException Слишком длинный адрес места расчётов
|
||||||
*/
|
*/
|
||||||
public function __construct(string $sno = null, string $inn = null, string $paymentAddress = null, string $email = null)
|
public function __construct(string $sno = null, string $inn = null, string $paymentAddress = null, string $email = null)
|
||||||
{
|
{
|
||||||
@@ -110,13 +111,13 @@ class Company extends Entity
|
|||||||
*
|
*
|
||||||
* @param string $payment_address
|
* @param string $payment_address
|
||||||
* @return $this
|
* @return $this
|
||||||
* @throws AtolPaymentAddressTooLongException
|
* @throws AtolPaymentAddressTooLongException Слишком длинный адрес места расчётов
|
||||||
*/
|
*/
|
||||||
public function setPaymentAddress(string $payment_address)
|
public function setPaymentAddress(string $payment_address)
|
||||||
{
|
{
|
||||||
$payment_address = trim($payment_address);
|
$payment_address = trim($payment_address);
|
||||||
if ((function_exists('mb_strlen') ? mb_strlen($payment_address) : strlen($payment_address)) > 256) {
|
if (valid_strlen($payment_address) > Constraints::MAX_LENGTH_PAYMENT_ADDRESS) {
|
||||||
throw new AtolPaymentAddressTooLongException($payment_address, 256);
|
throw new AtolPaymentAddressTooLongException($payment_address, Constraints::MAX_LENGTH_PAYMENT_ADDRESS);
|
||||||
}
|
}
|
||||||
$this->payment_address = $payment_address;
|
$this->payment_address = $payment_address;
|
||||||
return $this;
|
return $this;
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
namespace AtolOnline\Entities;
|
namespace AtolOnline\Entities;
|
||||||
|
|
||||||
|
use AtolOnline\Constants\Constraints;
|
||||||
use AtolOnline\Exceptions\AtolCashierTooLongException;
|
use AtolOnline\Exceptions\AtolCashierTooLongException;
|
||||||
use AtolOnline\Exceptions\AtolException;
|
use AtolOnline\Exceptions\AtolException;
|
||||||
use AtolOnline\Exceptions\AtolInvalidJsonException;
|
use AtolOnline\Exceptions\AtolInvalidJsonException;
|
||||||
@@ -259,9 +260,11 @@ class Document extends Entity
|
|||||||
*/
|
*/
|
||||||
public function setCashier(?string $cashier)
|
public function setCashier(?string $cashier)
|
||||||
{
|
{
|
||||||
$cashier = trim($cashier);
|
if ($cashier !== null) {
|
||||||
if ((function_exists('mb_strlen') ? mb_strlen($cashier) : strlen($cashier)) > 64) {
|
$cashier = trim($cashier);
|
||||||
throw new AtolCashierTooLongException($cashier, 64);
|
if (valid_strlen($cashier) > Constraints::MAX_LENGTH_CASHIER_NAME) {
|
||||||
|
throw new AtolCashierTooLongException($cashier, Constraints::MAX_LENGTH_CASHIER_NAME);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
$this->cashier = $cashier;
|
$this->cashier = $cashier;
|
||||||
return $this;
|
return $this;
|
||||||
|
|||||||
@@ -9,12 +9,14 @@
|
|||||||
|
|
||||||
namespace AtolOnline\Entities;
|
namespace AtolOnline\Entities;
|
||||||
|
|
||||||
use AtolOnline\{Exceptions\AtolNameTooLongException,
|
use AtolOnline\{Constants\Constraints,
|
||||||
|
Exceptions\AtolNameTooLongException,
|
||||||
Exceptions\AtolPriceTooHighException,
|
Exceptions\AtolPriceTooHighException,
|
||||||
Exceptions\AtolTooManyException,
|
Exceptions\AtolTooManyException,
|
||||||
Exceptions\AtolUnitTooLongException,
|
Exceptions\AtolUnitTooLongException,
|
||||||
Exceptions\AtolUserdataTooLongException,
|
Exceptions\AtolUserdataTooLongException,
|
||||||
Traits\RublesKopeksConverter};
|
Traits\RublesKopeksConverter
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Предмет расчёта (товар, услуга)
|
* Предмет расчёта (товар, услуга)
|
||||||
@@ -137,8 +139,8 @@ class Item extends Entity
|
|||||||
public function setName(string $name)
|
public function setName(string $name)
|
||||||
{
|
{
|
||||||
$name = trim($name);
|
$name = trim($name);
|
||||||
if ((function_exists('mb_strlen') ? mb_strlen($name) : strlen($name)) > 128) {
|
if (valid_strlen($name) > Constraints::MAX_LENGTH_ITEM_NAME) {
|
||||||
throw new AtolNameTooLongException($name, 128);
|
throw new AtolNameTooLongException($name, Constraints::MAX_LENGTH_ITEM_NAME);
|
||||||
}
|
}
|
||||||
$this->name = $name;
|
$this->name = $name;
|
||||||
return $this;
|
return $this;
|
||||||
@@ -225,8 +227,8 @@ class Item extends Entity
|
|||||||
public function setMeasurementUnit(string $measurement_unit)
|
public function setMeasurementUnit(string $measurement_unit)
|
||||||
{
|
{
|
||||||
$measurement_unit = trim($measurement_unit);
|
$measurement_unit = trim($measurement_unit);
|
||||||
if ((function_exists('mb_strlen') ? mb_strlen($measurement_unit) : strlen($measurement_unit)) > 16) {
|
if (valid_strlen($measurement_unit) > Constraints::MAX_LENGTH_MEASUREMENT_UNIT) {
|
||||||
throw new AtolUnitTooLongException($measurement_unit, 16);
|
throw new AtolUnitTooLongException($measurement_unit, Constraints::MAX_LENGTH_MEASUREMENT_UNIT);
|
||||||
}
|
}
|
||||||
$this->measurement_unit = $measurement_unit;
|
$this->measurement_unit = $measurement_unit;
|
||||||
return $this;
|
return $this;
|
||||||
@@ -328,8 +330,8 @@ class Item extends Entity
|
|||||||
public function setUserData(string $user_data)
|
public function setUserData(string $user_data)
|
||||||
{
|
{
|
||||||
$user_data = trim($user_data);
|
$user_data = trim($user_data);
|
||||||
if ((function_exists('mb_strlen') ? mb_strlen($user_data) : strlen($user_data)) > 64) {
|
if (valid_strlen($user_data) > Constraints::MAX_LENGTH_USER_DATA) {
|
||||||
throw new AtolUserdataTooLongException($user_data, 64);
|
throw new AtolUserdataTooLongException($user_data, Constraints::MAX_LENGTH_USER_DATA);
|
||||||
}
|
}
|
||||||
$this->user_data = $user_data;
|
$this->user_data = $user_data;
|
||||||
return $this;
|
return $this;
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ class ItemArray extends Entity
|
|||||||
protected function validateCount(?array $items = null): bool
|
protected function validateCount(?array $items = null): bool
|
||||||
{
|
{
|
||||||
if ((!empty($items) && count($items) >= self::MAX_COUNT) || count($this->items) >= self::MAX_COUNT) {
|
if ((!empty($items) && count($items) >= self::MAX_COUNT) || count($this->items) >= self::MAX_COUNT) {
|
||||||
throw new AtolTooManyItemsException(self::MAX_COUNT);
|
throw new AtolTooManyItemsException(count($items), self::MAX_COUNT);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,6 @@
|
|||||||
|
|
||||||
namespace AtolOnline\Entities;
|
namespace AtolOnline\Entities;
|
||||||
|
|
||||||
use AtolOnline\Api\SellSchema;
|
|
||||||
use AtolOnline\Exceptions\AtolTooManyPaymentsException;
|
use AtolOnline\Exceptions\AtolTooManyPaymentsException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -19,6 +18,11 @@ use AtolOnline\Exceptions\AtolTooManyPaymentsException;
|
|||||||
*/
|
*/
|
||||||
class PaymentArray extends Entity
|
class PaymentArray extends Entity
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* Максимальное количество элементов массива
|
||||||
|
*/
|
||||||
|
public const MAX_COUNT = 10;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var Payment[] Массив оплат
|
* @var Payment[] Массив оплат
|
||||||
*/
|
*/
|
||||||
@@ -99,9 +103,8 @@ class PaymentArray extends Entity
|
|||||||
*/
|
*/
|
||||||
protected function validateCount(?array $payments = null): bool
|
protected function validateCount(?array $payments = null): bool
|
||||||
{
|
{
|
||||||
$max_items = SellSchema::get()->properties->receipt->properties->payments->maxItems;
|
if ((!empty($payments) && count($payments) >= self::MAX_COUNT) || count($this->payments) >= self::MAX_COUNT) {
|
||||||
if ((!empty($payments) && count($payments) >= $max_items) || count($this->payments) >= $max_items) {
|
throw new AtolTooManyPaymentsException(count($payments), self::MAX_COUNT);
|
||||||
throw new AtolTooManyPaymentsException($max_items);
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,6 @@
|
|||||||
|
|
||||||
namespace AtolOnline\Entities;
|
namespace AtolOnline\Entities;
|
||||||
|
|
||||||
use AtolOnline\Api\SellSchema;
|
|
||||||
use AtolOnline\Exceptions\AtolTooManyVatsException;
|
use AtolOnline\Exceptions\AtolTooManyVatsException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -19,6 +18,11 @@ use AtolOnline\Exceptions\AtolTooManyVatsException;
|
|||||||
*/
|
*/
|
||||||
class VatArray extends Entity
|
class VatArray extends Entity
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* Максимальное количество элементов массива
|
||||||
|
*/
|
||||||
|
public const MAX_COUNT = 6;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var Vat[] Массив ставок НДС
|
* @var Vat[] Массив ставок НДС
|
||||||
*/
|
*/
|
||||||
@@ -103,9 +107,8 @@ class VatArray extends Entity
|
|||||||
*/
|
*/
|
||||||
protected function validateCount(?array $vats = null): bool
|
protected function validateCount(?array $vats = null): bool
|
||||||
{
|
{
|
||||||
$max_items = SellSchema::get()->properties->receipt->properties->vats->maxItems;
|
if ((!empty($vats) && count($vats) >= self::MAX_COUNT) || count($this->vats) >= self::MAX_COUNT) {
|
||||||
if ((!empty($vats) && count($vats) >= $max_items) || count($this->vats) >= $max_items) {
|
throw new AtolTooManyVatsException(count($vats), self::MAX_COUNT);
|
||||||
throw new AtolTooManyVatsException(count($vats), $max_items);
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
41
src/AtolOnline/Exceptions/AtolAuthFailedException.php
Normal file
41
src/AtolOnline/Exceptions/AtolAuthFailedException.php
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Copyright (c) Антон Аксенов (aka Anthony Axenov)
|
||||||
|
*
|
||||||
|
* This code is licensed under MIT.
|
||||||
|
* Этот код распространяется по лицензии MIT.
|
||||||
|
* https://github.com/anthonyaxenov/atol-online/blob/master/LICENSE
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace AtolOnline\Exceptions;
|
||||||
|
|
||||||
|
use AtolOnline\Api\KktResponse;
|
||||||
|
use Exception;
|
||||||
|
use Throwable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Исключение, возникающее при работе с АТОЛ Онлайн
|
||||||
|
*
|
||||||
|
* @package AtolOnline\Exceptions
|
||||||
|
*/
|
||||||
|
class AtolAuthFailedException extends Exception
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* AtolAuthFailedException constructor.
|
||||||
|
*
|
||||||
|
* @param \AtolOnline\Api\KktResponse $last_response
|
||||||
|
* @param string $message
|
||||||
|
* @param int $code
|
||||||
|
* @param \Throwable|null $previous
|
||||||
|
*/
|
||||||
|
public function __construct(KktResponse $last_response, $message = "", $code = 0, Throwable $previous = null)
|
||||||
|
{
|
||||||
|
$message = $last_response->isValid()
|
||||||
|
? $message
|
||||||
|
: '['.$last_response->error->code.'] '.$last_response->error->text.
|
||||||
|
'. ERROR_ID: '.$last_response->error->error_ID.
|
||||||
|
'. TYPE: '.$last_response->error->type;
|
||||||
|
$code = $last_response->isValid() ? $code : $last_response->error->code;
|
||||||
|
parent::__construct($message, $code, $previous);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Copyright (c) Антон Аксенов (aka Anthony Axenov)
|
||||||
|
*
|
||||||
|
* This code is licensed under MIT.
|
||||||
|
* Этот код распространяется по лицензии MIT.
|
||||||
|
* https://github.com/anthonyaxenov/atol-online/blob/master/LICENSE
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace AtolOnline\Exceptions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Исключение, возникающее при попытке указать слишком длинный callback_url
|
||||||
|
*
|
||||||
|
* @package AtolOnline\Exceptions
|
||||||
|
*/
|
||||||
|
class AtolCallbackUrlTooLongException extends AtolTooLongException
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var string Сообщение об ошибке
|
||||||
|
*/
|
||||||
|
protected $message = 'Callback URL is too long';
|
||||||
|
}
|
||||||
@@ -27,5 +27,5 @@ class AtolEmailTooLongException extends AtolTooLongException
|
|||||||
/**
|
/**
|
||||||
* @var string Сообщение об ошибке
|
* @var string Сообщение об ошибке
|
||||||
*/
|
*/
|
||||||
protected $message = 'Email is is too long';
|
protected $message = 'Email is too long';
|
||||||
}
|
}
|
||||||
@@ -33,6 +33,7 @@ class AtolException extends Exception
|
|||||||
*/
|
*/
|
||||||
public function __construct($message = "", $code = 0, Throwable $previous = null)
|
public function __construct($message = "", $code = 0, Throwable $previous = null)
|
||||||
{
|
{
|
||||||
|
$message = $message ?: $this->message;
|
||||||
if ($this->getFfdTags()) {
|
if ($this->getFfdTags()) {
|
||||||
$message .= ' [FFD tags: '.implode(', ', $this->getFfdTags()).']';
|
$message .= ' [FFD tags: '.implode(', ', $this->getFfdTags()).']';
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,6 +39,6 @@ class AtolInnWrongLengthException extends AtolException
|
|||||||
public function __construct($inn, $message = "", $code = 0, Throwable $previous = null)
|
public function __construct($inn, $message = "", $code = 0, Throwable $previous = null)
|
||||||
{
|
{
|
||||||
parent::__construct($message ?: 'INN length must be 10 or 12 digits only, but actual is '.
|
parent::__construct($message ?: 'INN length must be 10 or 12 digits only, but actual is '.
|
||||||
(function_exists('mb_strlen') ? mb_strlen($inn) : strlen($inn)).')', $code, $previous);
|
valid_strlen($inn), $code, $previous);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Copyright (c) Антон Аксенов (aka Anthony Axenov)
|
||||||
|
*
|
||||||
|
* This code is licensed under MIT.
|
||||||
|
* Этот код распространяется по лицензии MIT.
|
||||||
|
* https://github.com/anthonyaxenov/atol-online/blob/master/LICENSE
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace AtolOnline\Exceptions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Исключение, возникающее при попытке указать невалидный callback_url
|
||||||
|
*
|
||||||
|
* @package AtolOnline\Exceptions
|
||||||
|
*/
|
||||||
|
class AtolInvalidCallbackUrlException extends AtolException
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var string Сообщение об ошибке
|
||||||
|
*/
|
||||||
|
protected $message = 'Invalid callback URL';
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Copyright (c) Антон Аксенов (aka Anthony Axenov)
|
||||||
|
*
|
||||||
|
* This code is licensed under MIT.
|
||||||
|
* Этот код распространяется по лицензии MIT.
|
||||||
|
* https://github.com/anthonyaxenov/atol-online/blob/master/LICENSE
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace AtolOnline\Exceptions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Исключение, возникающее при попытке указать слишком длинный пароль ККТ
|
||||||
|
*
|
||||||
|
* @package AtolOnline\Exceptions
|
||||||
|
*/
|
||||||
|
class AtolKktPasswordTooLongException extends AtolTooLongException
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var string Сообщение об ошибке
|
||||||
|
*/
|
||||||
|
protected $message = 'KKT password is too long';
|
||||||
|
}
|
||||||
@@ -35,6 +35,6 @@ class AtolTooLongException extends AtolException
|
|||||||
public function __construct($string, $max, $message = "", $code = 0, Throwable $previous = null)
|
public function __construct($string, $max, $message = "", $code = 0, Throwable $previous = null)
|
||||||
{
|
{
|
||||||
parent::__construct($message ?: $this->message.' (max length - '.$max.', actual length - '.
|
parent::__construct($message ?: $this->message.' (max length - '.$max.', actual length - '.
|
||||||
(function_exists('mb_strlen') ? mb_strlen($string) : strlen($string)).')', $code, $previous);
|
valid_strlen($string), $code, $previous);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
namespace AtolOnline\Traits;
|
namespace AtolOnline\Traits;
|
||||||
|
|
||||||
use AtolOnline\{Exceptions\AtolEmailTooLongException, Exceptions\AtolEmailValidateException};
|
use AtolOnline\{Constants\Constraints, Exceptions\AtolEmailTooLongException, Exceptions\AtolEmailValidateException};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Добавляет объекту функционал для работы с email
|
* Добавляет объекту функционал для работы с email
|
||||||
@@ -38,16 +38,15 @@ trait HasEmail
|
|||||||
*
|
*
|
||||||
* @param string $email
|
* @param string $email
|
||||||
* @return $this
|
* @return $this
|
||||||
* @throws AtolEmailTooLongException
|
* @throws \AtolOnline\Exceptions\AtolEmailTooLongException Слишком длинный email
|
||||||
* @throws AtolEmailValidateException
|
* @throws \AtolOnline\Exceptions\AtolEmailValidateException Невалидный email
|
||||||
*/
|
*/
|
||||||
public function setEmail(string $email)
|
public function setEmail(string $email)
|
||||||
{
|
{
|
||||||
$email = trim($email);
|
$email = trim($email);
|
||||||
if ((function_exists('mb_strlen') ? mb_strlen($email) : strlen($email)) > 64) {
|
if (valid_strlen($email) > Constraints::MAX_LENGTH_EMAIL) {
|
||||||
throw new AtolEmailTooLongException($email, 64);
|
throw new AtolEmailTooLongException($email, Constraints::MAX_LENGTH_EMAIL);
|
||||||
}
|
} elseif (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
|
||||||
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
|
|
||||||
throw new AtolEmailValidateException($email);
|
throw new AtolEmailValidateException($email);
|
||||||
}
|
}
|
||||||
$this->email = $email;
|
$this->email = $email;
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
namespace AtolOnline\Traits;
|
namespace AtolOnline\Traits;
|
||||||
|
|
||||||
|
use AtolOnline\Constants\Constraints;
|
||||||
use AtolOnline\Exceptions\AtolInnWrongLengthException;
|
use AtolOnline\Exceptions\AtolInnWrongLengthException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -39,12 +40,12 @@ trait HasInn
|
|||||||
*
|
*
|
||||||
* @param string $inn
|
* @param string $inn
|
||||||
* @return $this
|
* @return $this
|
||||||
* @throws AtolInnWrongLengthException
|
* @throws AtolInnWrongLengthException Некорректная длина ИНН
|
||||||
*/
|
*/
|
||||||
public function setInn(string $inn)
|
public function setInn(string $inn)
|
||||||
{
|
{
|
||||||
$inn = preg_replace("/[^0-9]/", '', $inn);
|
$inn = preg_replace("/[^0-9]/", '', $inn);
|
||||||
if (preg_match_all("/(^[0-9]{10}$)|(^[0-9]{12}$)/", $inn) == 0) {
|
if (preg_match_all(Constraints::PATTERN_INN, $inn) == 0) {
|
||||||
throw new AtolInnWrongLengthException($inn);
|
throw new AtolInnWrongLengthException($inn);
|
||||||
}
|
}
|
||||||
$this->inn = $inn;
|
$this->inn = $inn;
|
||||||
|
|||||||
16
src/helpers.php
Normal file
16
src/helpers.php
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
if (!function_exists('valid_strlen')) {
|
||||||
|
/**
|
||||||
|
* Возвращает корректную длину строки
|
||||||
|
*
|
||||||
|
* @param string $value
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
function valid_strlen(string $value): int
|
||||||
|
{
|
||||||
|
return function_exists('mb_strlen')
|
||||||
|
? mb_strlen($value)
|
||||||
|
: strlen($value);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Unit;
|
|
||||||
|
|
||||||
use AtolOnline\Api\CorrectionSchema;
|
|
||||||
use AtolOnline\Api\SellSchema;
|
|
||||||
use PHPUnit\Framework\TestCase;
|
|
||||||
|
|
||||||
class SchemaTest extends TestCase
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Тестирует корректность работы объекта схемы документа
|
|
||||||
* прихода, возврата прихода, расхода, возврата расхода
|
|
||||||
*/
|
|
||||||
public function testSellSchema()
|
|
||||||
{
|
|
||||||
$this->assertIsObject(SellSchema::get());
|
|
||||||
$this->assertJson(SellSchema::json());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Тестирует корректность работы объекта схемы документа
|
|
||||||
* коррекции прихода, коррекции расхода
|
|
||||||
*/
|
|
||||||
public function testCorrectionSchema()
|
|
||||||
{
|
|
||||||
$this->assertIsObject(CorrectionSchema::get());
|
|
||||||
$this->assertJson(CorrectionSchema::json());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user