diff --git a/src/Api/AtolClient.php b/src/Api/AtolClient.php index 51254e1..ca3bf78 100644 --- a/src/Api/AtolClient.php +++ b/src/Api/AtolClient.php @@ -161,7 +161,7 @@ abstract class AtolClient if (empty($login)) { throw new EmptyLoginException(); } elseif (mb_strlen($login) > Constraints::MAX_LENGTH_LOGIN) { - throw new TooLongLoginException($login, Constraints::MAX_LENGTH_LOGIN); + throw new TooLongLoginException($login); } $this->login = $login; return $this; @@ -190,7 +190,7 @@ abstract class AtolClient if (empty($password)) { throw new EmptyPasswordException(); } elseif (mb_strlen($password) > Constraints::MAX_LENGTH_PASSWORD) { - throw new TooLongPasswordException($password, Constraints::MAX_LENGTH_PASSWORD); + throw new TooLongPasswordException($password); } $this->password = $password; return $this; diff --git a/src/Constants/Constraints.php b/src/Constants/Constraints.php index 5ca70b7..44ad74a 100644 --- a/src/Constants/Constraints.php +++ b/src/Constants/Constraints.php @@ -36,40 +36,89 @@ final class Constraints */ const MAX_LENGTH_PASSWORD = 100; - /** - * Максимальная длина имени покупателя - */ - const MAX_LENGTH_CLIENT_NAME = 256; - - /** - * Максимальная длина телефона покупателя - */ - const MAX_LENGTH_CLIENT_PHONE = 64; - /** * Максимальная длина адреса места расчётов */ const MAX_LENGTH_PAYMENT_ADDRESS = 256; - + /** - * Максимальная длина имени кассира + * Максимальная длина наименования покупателя (1227) + * @see https://online.atol.ru/files/API_atol_online_v4.pdf Документация, стр 17 */ - const MAX_LENGTH_CASHIER_NAME = 64; - + const MAX_LENGTH_CLIENT_NAME = 256; + /** - * Максимальная длина наименования предмета расчётов + * Максимальная длина наименования предмета расчёта (1030) + * @see https://online.atol.ru/files/API_atol_online_v4.pdf Документация, стр 21 */ const MAX_LENGTH_ITEM_NAME = 128; - + + /** + * Максимальная цена за единицу предмета расчёта (1079) + * @see https://online.atol.ru/files/API_atol_online_v4.pdf Документация, стр 21 + */ + const MAX_COUNT_ITEM_PRICE = 42949672.95; + + /** + * Максимальное количество (вес) единицы предмета расчёта (1023) + * @see https://online.atol.ru/files/API_atol_online_v4.pdf Документация, стр 21 + */ + const MAX_COUNT_ITEM_QUANTITY = 99999.999; + + /** + * Максимальная стоимость всех предметов расчёта в документе прихода, расхода, + * возврата прихода, возврата расхода (1043) + * @see https://online.atol.ru/files/API_atol_online_v4.pdf Документация, стр 21 + */ + const MAX_COUNT_ITEM_SUM = 42949672.95; + + /** + * Максимальная длина телефона или email покупателя (1008) + * @see https://online.atol.ru/files/API_atol_online_v4.pdf Документация, стр 17 + */ + const MAX_LENGTH_CLIENT_CONTACT = 64; + + /** + * Длина операции для платёжного агента (1044) + * @see https://online.atol.ru/files/API_atol_online_v4.pdf Документация, стр 19 + */ + const MAX_LENGTH_PAYING_AGENT_OPERATION = 24; + + /** + * Максимальное количество предметов расчёта в документе прихода, расхода, возврата прихода, возврата расхода + * @see https://online.atol.ru/files/API_atol_online_v4.pdf Документация, стр 21 + */ + const MAX_COUNT_DOC_ITEMS = 100; + /** * Максимальная длина единицы измерения предмета расчётов + * @see https://online.atol.ru/files/API_atol_online_v4.pdf Документация, стр 21 */ const MAX_LENGTH_MEASUREMENT_UNIT = 16; - + /** - * Максимальная длина пользовательских данных для предмета расчётов + * Максимальная длина пользовательских данных для предмета расчётов (1191) + * @see https://online.atol.ru/files/API_atol_online_v4.pdf Документация, стр 29 */ const MAX_LENGTH_USER_DATA = 64; + + /** + * Максимальное количество платежей в любом документе + * @see https://online.atol.ru/files/API_atol_online_v4.pdf Документация, стр 30 и 35 + */ + const MAX_COUNT_DOC_PAYMENTS = 10; + + /** + * Максимальное количество ставок НДС в любом документе + * @see https://online.atol.ru/files/API_atol_online_v4.pdf Документация, стр 31 и 36 + */ + const MAX_COUNT_DOC_VATS = 6; + + /** + * Максимальная длина имени кассира (1021) + * @see https://online.atol.ru/files/API_atol_online_v4.pdf Документация, стр 32 + */ + const MAX_LENGTH_CASHIER_NAME = 64; /** * Регулярное выражание для валидации строки ИНН diff --git a/src/Entities/Client.php b/src/Entities/Client.php index 6b13421..89ca0fe 100644 --- a/src/Entities/Client.php +++ b/src/Entities/Client.php @@ -15,9 +15,10 @@ use AtolOnline\{ Constants\Constraints, Exceptions\InvalidEmailException, Exceptions\InvalidInnLengthException, + Exceptions\TooLongClientContactException, + Exceptions\TooLongClientNameException, Exceptions\TooLongEmailException, - Exceptions\TooLongNameException, - Exceptions\TooLongPhoneException}; + Exceptions\TooLongItemNameException}; /** * Класс Client, описывающий сущность покупателя @@ -53,8 +54,8 @@ class Client extends Entity * @param string|null $phone Email. Тег ФФД - 1008. * @param string|null $email Телефон покупателя. Тег ФФД - 1008. * @param string|null $inn ИНН. Тег ФФД - 1228. - * @throws TooLongNameException - * @throws TooLongPhoneException + * @throws TooLongItemNameException + * @throws TooLongClientContactException * @throws TooLongEmailException * @throws InvalidEmailException * @throws InvalidInnLengthException @@ -91,14 +92,14 @@ class Client extends Entity * * @param string|null $name * @return $this - * @throws TooLongNameException + * @throws TooLongClientNameException */ public function setName(?string $name): self { if (is_string($name)) { $name = preg_replace('/[\n\r\t]/', '', trim($name)); if (mb_strlen($name) > Constraints::MAX_LENGTH_CLIENT_NAME) { - throw new TooLongNameException($name, Constraints::MAX_LENGTH_CLIENT_NAME); + throw new TooLongClientNameException($name); } } $this->name = empty($name) ? null : $name; @@ -128,7 +129,7 @@ class Client extends Entity if (is_string($email)) { $email = preg_replace('/[\n\r\t]/', '', trim($email)); if (mb_strlen($email) > Constraints::MAX_LENGTH_EMAIL) { - throw new TooLongEmailException($email, Constraints::MAX_LENGTH_EMAIL); + throw new TooLongEmailException($email); } elseif (filter_var($email, FILTER_VALIDATE_EMAIL) === false) { throw new InvalidEmailException($email); } @@ -156,14 +157,14 @@ class Client extends Entity * * @param string|null $phone Номер телефона * @return $this - * @throws TooLongPhoneException + * @throws TooLongClientContactException */ public function setPhone(?string $phone): self { if (is_string($phone)) { $phone = preg_replace('/[^\d]/', '', trim($phone)); - if (mb_strlen($phone) > Constraints::MAX_LENGTH_CLIENT_PHONE) { - throw new TooLongPhoneException($phone, Constraints::MAX_LENGTH_CLIENT_PHONE); + if (mb_strlen($phone) > Constraints::MAX_LENGTH_CLIENT_CONTACT) { + throw new TooLongClientContactException($phone); } } $this->phone = empty($phone) ? null : "+$phone"; diff --git a/src/Entities/Company.php b/src/Entities/Company.php index 485bd0a..df3f8f2 100644 --- a/src/Entities/Company.php +++ b/src/Entities/Company.php @@ -15,9 +15,9 @@ use AtolOnline\{ Constants\Constraints, Enums\SnoTypes, Exceptions\InvalidEmailException, + Exceptions\InvalidEnumValueException, Exceptions\InvalidInnLengthException, Exceptions\InvalidPaymentAddressException, - Exceptions\InvalidSnoException, Exceptions\TooLongEmailException, Exceptions\TooLongPaymentAddressException}; @@ -58,7 +58,7 @@ class Company extends Entity * @throws InvalidEmailException * @throws InvalidInnLengthException * @throws InvalidPaymentAddressException - * @throws InvalidSnoException + * @throws InvalidEnumValueException * @throws TooLongEmailException * @throws TooLongPaymentAddressException */ @@ -96,7 +96,7 @@ class Company extends Entity { $email = preg_replace('/[\n\r\t]/', '', trim($email)); if (mb_strlen($email) > Constraints::MAX_LENGTH_EMAIL) { - throw new TooLongEmailException($email, Constraints::MAX_LENGTH_EMAIL); + throw new TooLongEmailException($email); } elseif (empty($email) || filter_var($email, FILTER_VALIDATE_EMAIL) === false) { throw new InvalidEmailException($email); } @@ -123,14 +123,12 @@ class Company extends Entity * * @param string $sno * @return $this - * @throws InvalidSnoException + * @throws InvalidEnumValueException */ public function setSno(string $sno): self { $sno = trim($sno); - if (empty($sno) || !in_array($sno, SnoTypes::toArray())) { - throw new InvalidSnoException($sno); - } + SnoTypes::isValid($sno); $this->sno = $sno; return $this; } @@ -194,7 +192,7 @@ class Company extends Entity if (empty($payment_address)) { throw new InvalidPaymentAddressException(); } elseif (mb_strlen($payment_address) > Constraints::MAX_LENGTH_PAYMENT_ADDRESS) { - throw new TooLongPaymentAddressException($payment_address, Constraints::MAX_LENGTH_PAYMENT_ADDRESS); + throw new TooLongPaymentAddressException($payment_address); } $this->payment_address = $payment_address; return $this; @@ -203,7 +201,7 @@ class Company extends Entity /** * @inheritDoc * @throws InvalidEmailException - * @throws InvalidSnoException + * @throws InvalidEnumValueException * @throws InvalidInnLengthException * @throws InvalidPaymentAddressException */ @@ -215,7 +213,7 @@ class Company extends Entity : throw new InvalidEmailException(), 'sno' => $this->sno ? $this->getSno() - : throw new InvalidSnoException(), + : throw new InvalidEnumValueException(SnoTypes::class, 'null'), 'inn' => $this->inn ? $this->getInn() : throw new InvalidInnLengthException(), diff --git a/src/Entities/Document.php b/src/Entities/Document.php index af72077..4bc4e7c 100644 --- a/src/Entities/Document.php +++ b/src/Entities/Document.php @@ -13,18 +13,18 @@ namespace AtolOnline\Entities; use AtolOnline\Constants\Constraints; use AtolOnline\Exceptions\AtolException; -use AtolOnline\Exceptions\BasicTooManyException; use AtolOnline\Exceptions\InvalidEmailException; use AtolOnline\Exceptions\InvalidInnLengthException; use AtolOnline\Exceptions\InvalidJsonException; use AtolOnline\Exceptions\TooHighPriceException; use AtolOnline\Exceptions\TooLongCashierException; +use AtolOnline\Exceptions\TooLongClientContactException; use AtolOnline\Exceptions\TooLongEmailException; -use AtolOnline\Exceptions\TooLongNameException; +use AtolOnline\Exceptions\TooLongItemNameException; use AtolOnline\Exceptions\TooLongPaymentAddressException; -use AtolOnline\Exceptions\TooLongPhoneException; use AtolOnline\Exceptions\TooLongUnitException; use AtolOnline\Exceptions\TooLongUserdataException; +use AtolOnline\Exceptions\TooManyException; use AtolOnline\Exceptions\TooManyItemsException; use AtolOnline\Exceptions\TooManyPaymentsException; use AtolOnline\Exceptions\TooManyVatsException; @@ -66,7 +66,7 @@ class Document extends Entity * @var float Итоговая сумма чека. Тег ФФД - 1020. */ protected float $total = 0; - + /** * @var string ФИО кассира. Тег ФФД - 1021. */ @@ -76,7 +76,7 @@ class Document extends Entity * @var CorrectionInfo Данные коррекции */ protected CorrectionInfo $correction_info; - + /** * Document constructor. */ @@ -211,7 +211,7 @@ class Document extends Entity $this->items->set($items); return $this; } - + /** * Возвращает заданного клиента (покупателя) * @@ -221,7 +221,7 @@ class Document extends Entity { return $this->client; } - + /** * Устанавливает клиента (покупателя) * @@ -233,7 +233,7 @@ class Document extends Entity $this->client = $client; return $this; } - + /** * Возвращает заданную компанию (продавца) * @@ -243,7 +243,7 @@ class Document extends Entity { return $this->company; } - + /** * Устанавливает компанию (продавца) * @@ -255,7 +255,7 @@ class Document extends Entity $this->company = $company; return $this; } - + /** * Возвращает ФИО кассира. Тег ФФД - 1021. * @@ -323,7 +323,7 @@ class Document extends Entity } return $this->total = round($sum, 2); } - + /** * Возвращает итоговую сумму чека. Тег ФФД - 1020. * @@ -344,11 +344,11 @@ class Document extends Entity * @throws AtolException * @throws InvalidInnLengthException * @throws InvalidJsonException - * @throws TooLongNameException + * @throws TooLongItemNameException * @throws TooLongPaymentAddressException - * @throws TooLongPhoneException + * @throws TooLongClientContactException * @throws TooHighPriceException - * @throws BasicTooManyException + * @throws TooManyException * @throws TooManyItemsException * @throws TooManyPaymentsException * @throws TooLongUnitException diff --git a/src/Entities/Item.php b/src/Entities/Item.php index 64e11f3..1d0c95b 100644 --- a/src/Entities/Item.php +++ b/src/Entities/Item.php @@ -13,11 +13,11 @@ namespace AtolOnline\Entities; use AtolOnline\{ Constants\Constraints, - Exceptions\BasicTooManyException, Exceptions\TooHighPriceException, - Exceptions\TooLongNameException, + Exceptions\TooLongItemNameException, Exceptions\TooLongUnitException, - Exceptions\TooLongUserdataException}; + Exceptions\TooLongUserdataException, + Exceptions\TooManyException}; /** * Предмет расчёта (товар, услуга) @@ -30,22 +30,22 @@ class Item extends Entity * @var string Наименование. Тег ФФД - 1030. */ protected string $name; - + /** * @var int Цена в копейках (с учётом скидок и наценок). Тег ФФД - 1079. */ protected int $price = 0; - + /** * @var float Количество, вес. Тег ФФД - 1023. */ protected float $quantity = 0.0; - + /** * @var float Сумма в копейках. Тег ФФД - 1043. */ protected float $sum = 0; - + /** * @var string Единица измерения количества. Тег ФФД - 1197. */ @@ -55,17 +55,17 @@ class Item extends Entity * @var Vat|null Ставка НДС */ protected ?Vat $vat; - + /** * @var string Признак способа расчёта. Тег ФФД - 1214. */ protected string $payment_method; - + /** * @var string Признак объекта расчёта. Тег ФФД - 1212. */ protected string $payment_object; - + /** * @var string Дополнительный реквизит. Тег ФФД - 1191. */ @@ -81,9 +81,9 @@ class Item extends Entity * @param string|null $vat_type Ставка НДС * @param string|null $payment_object Признак * @param string|null $payment_method Способ расчёта - * @throws TooLongNameException Слишком длинное наименование + * @throws TooLongItemNameException Слишком длинное наименование * @throws TooHighPriceException Слишком высокая цена за одну единицу - * @throws BasicTooManyException Слишком большое количество + * @throws TooManyException Слишком большое количество * @throws TooLongUnitException Слишком длинное название единицы измерения */ public function __construct( @@ -117,7 +117,7 @@ class Item extends Entity $this->setPaymentMethod($payment_method); } } - + /** * Возвращает наименование. Тег ФФД - 1030. * @@ -133,18 +133,18 @@ class Item extends Entity * * @param string $name Наименование * @return $this - * @throws TooLongNameException Слишком длинное имя/наименование + * @throws TooLongItemNameException Слишком длинное имя/наименование */ public function setName(string $name): self { $name = trim($name); if (mb_strlen($name) > Constraints::MAX_LENGTH_ITEM_NAME) { - throw new TooLongNameException($name, Constraints::MAX_LENGTH_ITEM_NAME); + throw new TooLongItemNameException($name, Constraints::MAX_LENGTH_ITEM_NAME); } $this->name = $name; return $this; } - + /** * Возвращает цену в рублях. Тег ФФД - 1079. * @@ -171,7 +171,7 @@ class Item extends Entity $this->calcSum(); return $this; } - + /** * Возвращает количество. Тег ФФД - 1023. * @@ -188,7 +188,7 @@ class Item extends Entity * @param float $quantity Количество * @param string|null $measurement_unit Единица измерения количества * @return $this - * @throws BasicTooManyException Слишком большое количество + * @throws TooManyException Слишком большое количество * @throws TooHighPriceException Слишком высокая общая стоимость * @throws TooLongUnitException Слишком длинное название единицы измерения */ @@ -196,7 +196,7 @@ class Item extends Entity { $quantity = round($quantity, 3); if ($quantity > 99999.999) { - throw new BasicTooManyException($quantity, 99999.999); + throw new TooManyException($quantity, 99999.999); } $this->quantity = $quantity; $this->calcSum(); @@ -205,7 +205,7 @@ class Item extends Entity } return $this; } - + /** * Возвращает заданную единицу измерения количества. Тег ФФД - 1197. * @@ -232,7 +232,7 @@ class Item extends Entity $this->measurement_unit = $measurement_unit; return $this; } - + /** * Возвращает признак способа оплаты. Тег ФФД - 1214. * @@ -242,7 +242,7 @@ class Item extends Entity { return $this->payment_method; } - + /** * Устанавливает признак способа оплаты. Тег ФФД - 1214. * @@ -255,7 +255,7 @@ class Item extends Entity $this->payment_method = trim($payment_method); return $this; } - + /** * Возвращает признак предмета расчёта. Тег ФФД - 1212. * @@ -265,7 +265,7 @@ class Item extends Entity { return $this->payment_object; } - + /** * Устанавливает признак предмета расчёта. Тег ФФД - 1212. * @@ -308,7 +308,7 @@ class Item extends Entity $this->calcSum(); return $this; } - + /** * Возвращает дополнительный реквизит. Тег ФФД - 1191. * @@ -335,7 +335,7 @@ class Item extends Entity $this->user_data = $user_data; return $this; } - + /** * Возвращает стоимость. Тег ФФД - 1043. * @@ -364,7 +364,7 @@ class Item extends Entity } return $this->getSum(); } - + /** * @inheritDoc */ diff --git a/src/Enums/SnoTypes.php b/src/Enums/SnoTypes.php index 0892fc6..0e9e851 100644 --- a/src/Enums/SnoTypes.php +++ b/src/Enums/SnoTypes.php @@ -11,7 +11,7 @@ declare(strict_types = 1); namespace AtolOnline\Enums; -use MyCLabs\Enum\Enum; +use AtolOnline\Enum; /** * Константы, определяющие типы налогообложения @@ -49,4 +49,12 @@ final class SnoTypes extends Enum * Патентная СН */ const PATENT = 'patent'; + + /** + * @return int[] Возвращает массив тегов ФФД + */ + public static function getFfdTags(): array + { + return [1055]; + } } \ No newline at end of file diff --git a/src/Exceptions/AtolException.php b/src/Exceptions/AtolException.php index b548ab6..d3e9237 100644 --- a/src/Exceptions/AtolException.php +++ b/src/Exceptions/AtolException.php @@ -12,7 +12,6 @@ declare(strict_types = 1); namespace AtolOnline\Exceptions; use Exception; -use Throwable; /** * Исключение, возникающее при работе с АТОЛ Онлайн @@ -25,28 +24,15 @@ class AtolException extends Exception protected array $ffd_tags = []; /** - * AtolException constructor. + * Конструктор * - * @param string $message - * @param int $code - * @param Throwable|null $previous + * @param string $message Сообщение + * @param int[] $ffd_tags Переопредление тегов ФФД */ - public function __construct($message = "", $code = 0, Throwable $previous = null) + public function __construct(string $message = '', array $ffd_tags = []) { - $message = $message ?: $this->message; - if ($this->getFfdTags()) { - $message .= ' [FFD tags: '.implode(', ', $this->getFfdTags()).']'; - } - parent::__construct($message, $code, $previous); + parent::__construct( + ($message ?: $this->message) . ' [Теги ФФД: ' . implode(', ', $ffd_tags ?: $this->ffd_tags) . ']' + ); } - - /** - * Возвращает теги ФФД, с которыми связано исключение - * - * @return array - */ - protected function getFfdTags(): array - { - return $this->ffd_tags; - } -} \ No newline at end of file +} diff --git a/src/Exceptions/AuthFailedException.php b/src/Exceptions/AuthFailedException.php index e213f6b..0d379b0 100644 --- a/src/Exceptions/AuthFailedException.php +++ b/src/Exceptions/AuthFailedException.php @@ -13,7 +13,6 @@ namespace AtolOnline\Exceptions; use AtolOnline\Api\KktResponse; use Exception; -use Throwable; /** * Исключение, возникающее при неудачной авторизации @@ -25,17 +24,9 @@ class AuthFailedException extends Exception * * @param KktResponse $response * @param string $message - * @param int $code - * @param Throwable|null $previous */ - public function __construct(KktResponse $response, $message = "", $code = 0, Throwable $previous = null) + public function __construct(KktResponse $response, string $message = '') { - $message = $response->isValid() - ? $message - : '[' . $response->error->code . '] ' . $response->error->text . - '. ERROR_ID: ' . $response->error->error_id . - '. TYPE: ' . $response->error->type; - $code = $response->isValid() ? $code : $response->error->code; - parent::__construct($message, $code, $previous); + parent::__construct(($message ?: 'Ошибка авторизации: ') . ': ' . $response); } } diff --git a/src/Exceptions/BasicTooLongException.php b/src/Exceptions/BasicTooLongException.php deleted file mode 100644 index d27905b..0000000 --- a/src/Exceptions/BasicTooLongException.php +++ /dev/null @@ -1,40 +0,0 @@ -message . ' (max length - ' . $max . ', actual length - ' . - mb_strlen($string), $code, $previous); - } -} \ No newline at end of file diff --git a/src/Exceptions/EmptyCorrectionInfoException.php b/src/Exceptions/EmptyCorrectionInfoException.php index f0b2f1f..172108a 100644 --- a/src/Exceptions/EmptyCorrectionInfoException.php +++ b/src/Exceptions/EmptyCorrectionInfoException.php @@ -11,13 +11,12 @@ declare(strict_types = 1); namespace AtolOnline\Exceptions; +use AtolOnline\Entities\CorrectionInfo; + /** - * Исключение, возникающее при попытке зарегистрировать документ без данных коррекции + * Исключение, возникающее при попытке зарегистрировать документ коррекции без соотв. данных */ class EmptyCorrectionInfoException extends AtolException { - /** - * @var string Сообщение об ошибке - */ - protected $message = 'Document must have correction info'; -} \ No newline at end of file + protected $message = 'Документ должен содержать объект ' . CorrectionInfo::class; +} diff --git a/src/Exceptions/EmptyEmailException.php b/src/Exceptions/EmptyEmailException.php index 52ce4ad..bb4200b 100644 --- a/src/Exceptions/EmptyEmailException.php +++ b/src/Exceptions/EmptyEmailException.php @@ -13,19 +13,10 @@ namespace AtolOnline\Exceptions; /** * Исключение, возникающее при попытке указать пустой email + * @see https://online.atol.ru/files/API_atol_online_v4.pdf Документация, стр 17 */ class EmptyEmailException extends AtolException { - /** - * @inheritDoc - */ - protected array $ffd_tags = [ - 1008, - 1117, - ]; - - /** - * @var string Сообщение об ошибке - */ - protected $message = 'Email cannot be empty'; -} \ No newline at end of file + protected $message = 'Email не может быть пустым'; + protected array $ffd_tags = [1008, 1117]; +} diff --git a/src/Exceptions/EmptyLoginException.php b/src/Exceptions/EmptyLoginException.php index fbd4b5e..5e78966 100644 --- a/src/Exceptions/EmptyLoginException.php +++ b/src/Exceptions/EmptyLoginException.php @@ -12,12 +12,10 @@ declare(strict_types = 1); namespace AtolOnline\Exceptions; /** - * Исключение, возникающее при попытке указать пустой логин ККТ + * Исключение, возникающее при попытке указать пустой логин + * @see https://online.atol.ru/files/API_atol_online_v4.pdf Документация, стр 12 */ class EmptyLoginException extends AtolException { - /** - * @var string Сообщение об ошибке - */ - protected $message = 'KKT login cannot be empty'; -} \ No newline at end of file + protected $message = 'Логин не может быть пустым'; +} diff --git a/src/Exceptions/EmptyMonitorDataException.php b/src/Exceptions/EmptyMonitorDataException.php index 7aad529..32902d6 100644 --- a/src/Exceptions/EmptyMonitorDataException.php +++ b/src/Exceptions/EmptyMonitorDataException.php @@ -16,8 +16,5 @@ namespace AtolOnline\Exceptions; */ class EmptyMonitorDataException extends AtolException { - /** - * @var string Сообщение об ошибке - */ - protected $message = 'Cannot create KKT entity without data from monitor'; -} \ No newline at end of file + protected $message = 'Не возможно создать объект ККт без данных от мониторинга'; +} diff --git a/src/Exceptions/EmptyPasswordException.php b/src/Exceptions/EmptyPasswordException.php index d3370b8..76f4a9d 100644 --- a/src/Exceptions/EmptyPasswordException.php +++ b/src/Exceptions/EmptyPasswordException.php @@ -12,12 +12,10 @@ declare(strict_types = 1); namespace AtolOnline\Exceptions; /** - * Исключение, возникающее при попытке указать пустой пароль ККТ + * Исключение, возникающее при попытке указать пустой пароль + * @see https://online.atol.ru/files/API_atol_online_v4.pdf Документация, стр 12 */ class EmptyPasswordException extends AtolException { - /** - * @var string Сообщение об ошибке - */ - protected $message = 'KKT password cannot be empty'; -} \ No newline at end of file + protected $message = 'Пароль не может быть пустым'; +} diff --git a/src/Exceptions/InvalidCallbackUrlException.php b/src/Exceptions/InvalidCallbackUrlException.php index e8240f3..daeb446 100644 --- a/src/Exceptions/InvalidCallbackUrlException.php +++ b/src/Exceptions/InvalidCallbackUrlException.php @@ -16,8 +16,5 @@ namespace AtolOnline\Exceptions; */ class InvalidCallbackUrlException extends AtolException { - /** - * @var string Сообщение об ошибке - */ - protected $message = 'Invalid callback URL'; -} \ No newline at end of file + protected $message = 'Невалидный callback_url'; +} diff --git a/src/Exceptions/InvalidDocumentTypeException.php b/src/Exceptions/InvalidDocumentTypeException.php deleted file mode 100644 index c7aca45..0000000 --- a/src/Exceptions/InvalidDocumentTypeException.php +++ /dev/null @@ -1,38 +0,0 @@ -message . implode(', ', $props_diff), $code, $previous); + parent::__construct($message ?: $this->message . implode(', ', $props_diff)); } -} \ No newline at end of file +} diff --git a/src/Exceptions/TooHighPriceException.php b/src/Exceptions/TooHighPriceException.php index 1f523bf..0760cc0 100644 --- a/src/Exceptions/TooHighPriceException.php +++ b/src/Exceptions/TooHighPriceException.php @@ -14,7 +14,7 @@ namespace AtolOnline\Exceptions; /** * Исключение, возникающее при попытке указать слишком высокую цену (сумму) */ -class TooHighPriceException extends BasicTooManyException +class TooHighPriceException extends TooManyException { /** * @inheritDoc diff --git a/src/Exceptions/TooLongCallbackUrlException.php b/src/Exceptions/TooLongCallbackUrlException.php index ed08899..efb1775 100644 --- a/src/Exceptions/TooLongCallbackUrlException.php +++ b/src/Exceptions/TooLongCallbackUrlException.php @@ -11,13 +11,13 @@ declare(strict_types = 1); namespace AtolOnline\Exceptions; +use AtolOnline\Constants\Constraints; + /** * Исключение, возникающее при попытке указать слишком длинный callback_url */ -class TooLongCallbackUrlException extends BasicTooLongException +class TooLongCallbackUrlException extends TooLongException { - /** - * @var string Сообщение об ошибке - */ - protected $message = 'Callback URL is too long'; -} \ No newline at end of file + protected $message = 'Слишком длинный адрес колбека'; + protected int $max = Constraints::MAX_LENGTH_CALLBACK_URL; +} diff --git a/src/Exceptions/TooLongCashierException.php b/src/Exceptions/TooLongCashierException.php index 056ffd7..762d1a9 100644 --- a/src/Exceptions/TooLongCashierException.php +++ b/src/Exceptions/TooLongCashierException.php @@ -11,20 +11,14 @@ declare(strict_types = 1); namespace AtolOnline\Exceptions; +use AtolOnline\Constants\Constraints; + /** * Исключение, возникающее при попытке указать слишком длинное имя кассира */ -class TooLongCashierException extends BasicTooLongException +class TooLongCashierException extends TooLongException { - /** - * @inheritDoc - */ - protected array $ffd_tags = [ - 1021, - ]; - - /** - * @var string Сообщение об ошибке - */ - protected $message = 'Cashier name is too long'; -} \ No newline at end of file + protected $message = 'Слишком длинное имя кассира'; + protected int $max = Constraints::MAX_LENGTH_CASHIER_NAME; + protected array $ffd_tags = [1021]; +} diff --git a/src/Exceptions/TooLongPhoneException.php b/src/Exceptions/TooLongClientContactException.php similarity index 57% rename from src/Exceptions/TooLongPhoneException.php rename to src/Exceptions/TooLongClientContactException.php index 9cedc3e..183e34e 100644 --- a/src/Exceptions/TooLongPhoneException.php +++ b/src/Exceptions/TooLongClientContactException.php @@ -11,24 +11,14 @@ declare(strict_types = 1); namespace AtolOnline\Exceptions; +use AtolOnline\Constants\Constraints; + /** - * Исключение, возникающее при попытке указать слишком длинный телефон + * Исключение, возникающее при попытке указать слишком длинный телефон или email покупателя */ -class TooLongPhoneException extends BasicTooLongException +class TooLongClientContactException extends TooLongException { - /** - * @inheritDoc - */ - protected array $ffd_tags = [ - 1008, - 1073, - 1074, - 1075, - 1171, - ]; - - /** - * @var string Сообщение об ошибке - */ - protected $message = 'Phone is too long'; -} \ No newline at end of file + protected $message = 'Cлишком длинный телефон или email покупателя'; + protected int $max = Constraints::MAX_LENGTH_CLIENT_CONTACT; + protected array $ffd_tags = [1008]; +} diff --git a/src/Exceptions/TooLongClientNameException.php b/src/Exceptions/TooLongClientNameException.php new file mode 100644 index 0000000..30bf22e --- /dev/null +++ b/src/Exceptions/TooLongClientNameException.php @@ -0,0 +1,24 @@ +message) . ': '. $value; + if ($max > 0 || $this->max > 0) { + $message .= ' (макс. = ' . ($max ?? $this->max) . ', фактически = ' . mb_strlen($value) . ')'; + } + parent::__construct($message); + } +} diff --git a/src/Exceptions/TooLongNameException.php b/src/Exceptions/TooLongItemNameException.php similarity index 58% rename from src/Exceptions/TooLongNameException.php rename to src/Exceptions/TooLongItemNameException.php index d26a32c..eb3a3b7 100644 --- a/src/Exceptions/TooLongNameException.php +++ b/src/Exceptions/TooLongItemNameException.php @@ -11,24 +11,14 @@ declare(strict_types = 1); namespace AtolOnline\Exceptions; +use AtolOnline\Constants\Constraints; + /** * Исключение, возникающее при попытке указать слишком длинное имя */ -class TooLongNameException extends BasicTooLongException +class TooLongItemNameException extends TooLongException { - /** - * @inheritDoc - */ - protected array $ffd_tags = [ - 1026, - 1030, - 1085, - 1225, - 1227, - ]; - - /** - * @var string Сообщение об ошибке - */ - protected $message = 'Name is too long'; -} \ No newline at end of file + protected $message = 'Слишком длинное наименование предмета расчёта'; + protected int $max = Constraints::MAX_LENGTH_ITEM_NAME; + protected array $ffd_tags = [1030]; +} diff --git a/src/Exceptions/TooLongLoginException.php b/src/Exceptions/TooLongLoginException.php index 51170e9..a9fe073 100644 --- a/src/Exceptions/TooLongLoginException.php +++ b/src/Exceptions/TooLongLoginException.php @@ -11,13 +11,13 @@ declare(strict_types = 1); namespace AtolOnline\Exceptions; +use AtolOnline\Constants\Constraints; + /** * Исключение, возникающее при попытке указать слишком длинный логин ККТ */ -class TooLongLoginException extends BasicTooLongException +class TooLongLoginException extends TooLongException { - /** - * @var string Сообщение об ошибке - */ - protected $message = 'KKT login is too long'; -} \ No newline at end of file + protected $message = 'Слишком длинный логин'; + protected int $max = Constraints::MAX_LENGTH_LOGIN; +} diff --git a/src/Exceptions/TooLongPasswordException.php b/src/Exceptions/TooLongPasswordException.php index c9fb51e..c21477a 100644 --- a/src/Exceptions/TooLongPasswordException.php +++ b/src/Exceptions/TooLongPasswordException.php @@ -11,13 +11,13 @@ declare(strict_types = 1); namespace AtolOnline\Exceptions; +use AtolOnline\Constants\Constraints; + /** * Исключение, возникающее при попытке указать слишком длинный пароль ККТ */ -class TooLongPasswordException extends BasicTooLongException +class TooLongPasswordException extends TooLongException { - /** - * @var string Сообщение об ошибке - */ - protected $message = 'KKT password is too long'; -} \ No newline at end of file + protected $message = 'Слишком длинный пароль'; + protected int $max = Constraints::MAX_LENGTH_PASSWORD; +} diff --git a/src/Exceptions/TooLongPayingAgentOperationException.php b/src/Exceptions/TooLongPayingAgentOperationException.php new file mode 100644 index 0000000..c5079ea --- /dev/null +++ b/src/Exceptions/TooLongPayingAgentOperationException.php @@ -0,0 +1,24 @@ +message . ' (max - ' . $max . ', actual - ' . $quantity . ')', - $code, - $previous - ); + $message = ($message ?: $this->message) . ': ' . $value; + if ($max > 0 || $this->max > 0) { + $message .= ' (макс. = ' . ($max ?? $this->max) . ', фактически = ' . $value . ')'; + } + parent::__construct($message); } -} \ No newline at end of file +} diff --git a/src/Exceptions/TooManyItemsException.php b/src/Exceptions/TooManyItemsException.php index 22ce54b..f154a73 100644 --- a/src/Exceptions/TooManyItemsException.php +++ b/src/Exceptions/TooManyItemsException.php @@ -11,13 +11,13 @@ declare(strict_types = 1); namespace AtolOnline\Exceptions; +use AtolOnline\Constants\Constraints; + /** * Исключение, возникающее при попытке добавить слишком много предметов расчёта в массив */ -class TooManyItemsException extends BasicTooManyException +class TooManyItemsException extends TooManyException { - /** - * @var string Сообщение об ошибке - */ - protected $message = 'Too many items'; -} \ No newline at end of file + protected $message = 'Слишком много предметов расчёта в документе'; + protected int $max = Constraints::MAX_COUNT_DOC_ITEMS; +} diff --git a/src/Exceptions/TooManyPaymentsException.php b/src/Exceptions/TooManyPaymentsException.php index 48f5426..0e7e532 100644 --- a/src/Exceptions/TooManyPaymentsException.php +++ b/src/Exceptions/TooManyPaymentsException.php @@ -11,23 +11,13 @@ declare(strict_types = 1); namespace AtolOnline\Exceptions; +use AtolOnline\Constants\Constraints; + /** * Исключение, возникающее при попытке добавить слишком много платежей в массив */ -class TooManyPaymentsException extends BasicTooManyException +class TooManyPaymentsException extends TooManyException { - /** - * @inheritDoc - */ - protected array $ffd_tags = [ - 1031, - 1081, - 1215, - 1217, - ]; - - /** - * @var string Сообщение об ошибке - */ - protected $message = 'Too many payments'; -} \ No newline at end of file + protected $message = 'Слишком много платежей в документе'; + protected int $max = Constraints::MAX_COUNT_DOC_PAYMENTS; +} diff --git a/src/Exceptions/TooManyVatsException.php b/src/Exceptions/TooManyVatsException.php index 7ee4200..b39b38e 100644 --- a/src/Exceptions/TooManyVatsException.php +++ b/src/Exceptions/TooManyVatsException.php @@ -11,25 +11,13 @@ declare(strict_types = 1); namespace AtolOnline\Exceptions; +use AtolOnline\Constants\Constraints; + /** * Исключение, возникающее при попытке добавить слишком много ставок НДС в массив */ -class TooManyVatsException extends BasicTooManyException +class TooManyVatsException extends TooManyException { - /** - * @inheritDoc - */ - protected array $ffd_tags = [ - 1102, - 1103, - 1104, - 1105, - 1106, - 1107, - ]; - - /** - * @var string Сообщение об ошибке - */ - protected $message = 'Too many vats'; -} \ No newline at end of file + protected $message = 'Слишком много ставок НДС в документе'; + protected int $max = Constraints::MAX_COUNT_DOC_VATS; +} diff --git a/tests/BasicTestCase.php b/tests/BasicTestCase.php index 4bd5c23..aa63b9f 100644 --- a/tests/BasicTestCase.php +++ b/tests/BasicTestCase.php @@ -12,6 +12,7 @@ declare(strict_types = 1); namespace AtolOnlineTests; use AtolOnline\Entities\Entity; +use AtolOnline\Helpers; use GuzzleHttp\Client; use GuzzleHttp\Exception\GuzzleException; use Illuminate\Support\Collection; @@ -89,57 +90,40 @@ class BasicTestCase extends TestCase */ public function assertIsSameClass(object|string $expected, object|string $actual): void { - $this->assertEquals( - is_object($expected) ? $expected::class : $expected, - is_object($actual) ? $actual::class : $actual - ); + $this->assertTrue(Helpers::isSameClass($expected, $actual)); } /** * Тестирует наследование класса (объекта) от указанных классов * + * @param object|string $class * @param string[] $parents - * @param object|string $actual */ - public function assertExtendsClasses(array $parents, object|string $actual): void + public function assertExtendsClasses(object|string $class, array $parents): void { - $this->checkClassesIntersection($parents, $actual, 'class_parents'); + $this->assertTrue(Helpers::checkExtendsClasses($class, $parents)); } /** * Тестирует имплементацию классом (объектом) указанных интерфейсов * - * @param string[] $parents - * @param object|string $actual + * @param object|string $class + * @param string[] $interfaces */ - public function assertImplementsInterfaces(array $parents, object|string $actual): void + public function assertImplementsInterfaces(object|string $class, array $interfaces): void { - $this->checkClassesIntersection($parents, $actual, 'class_implements'); + $this->assertTrue(Helpers::checkImplementsInterfaces($class, $interfaces)); } /** * Тестирует использование классом (объектом) указанных трейтов * - * @param string[] $parents - * @param object|string $actual + * @param object|string $class + * @param string[] $traits */ - public function assertUsesTraits(array $parents, object|string $actual): void + public function assertUsesTraits(object|string $class, array $traits): void { - $this->checkClassesIntersection($parents, $actual, 'class_uses'); - } - - /** - * Проверяет пересечение классов указанной функцией SPL - * - * @param object|string $class Класс для проверки на вхождение, или объект, класс коего нужно проверить - * @param array $classes Массив классов, вхождение в который нужно проверить - * @param string $function class_parents|class_implements|class_uses - */ - protected function checkClassesIntersection(array $classes, object|string $class, string $function): void - { - $actual_classes = is_object($class) ? $function($class) : [$class::class]; - $this->assertIsArray($actual_classes); - $this->assertNotEmpty(array_intersect($classes, $actual_classes)); + $this->assertTrue(Helpers::checkUsesTraits($traits, $class)); } /** diff --git a/tests/ClientTest.php b/tests/ClientTest.php index be2ce7a..0442646 100644 --- a/tests/ClientTest.php +++ b/tests/ClientTest.php @@ -13,11 +13,11 @@ use AtolOnline\{ Entities\Client, Exceptions\InvalidEmailException, Exceptions\InvalidInnLengthException, + Exceptions\TooLongClientContactException, + Exceptions\TooLongClientNameException, Exceptions\TooLongEmailException, - Exceptions\TooLongNameException, - Exceptions\TooLongPhoneException, - Helpers -}; + Exceptions\TooLongItemNameException, + Helpers}; /** * Набор тестов для проверки работы класс покупателя @@ -135,7 +135,7 @@ class ClientTest extends BasicTestCase * @covers \AtolOnline\Entities\Client * @covers \AtolOnline\Entities\Client::setName * @covers \AtolOnline\Entities\Client::getName - * @throws TooLongNameException + * @throws TooLongClientNameException */ public function testNullableNames(mixed $name): void { @@ -149,7 +149,7 @@ class ClientTest extends BasicTestCase * @covers \AtolOnline\Entities\Client * @covers \AtolOnline\Entities\Client::setName * @covers \AtolOnline\Entities\Client::getName - * @throws TooLongNameException + * @throws TooLongItemNameException */ public function testValidName(): void { @@ -163,12 +163,11 @@ class ClientTest extends BasicTestCase * * @covers \AtolOnline\Entities\Client * @covers \AtolOnline\Entities\Client::setName - * @covers \AtolOnline\Exceptions\TooLongNameException - * @throws TooLongNameException + * @covers \AtolOnline\Exceptions\TooLongClientNameException */ public function testInvalidName(): void { - $this->expectException(TooLongNameException::class); + $this->expectException(TooLongClientNameException::class); (new Client())->setName(Helpers::randomStr(400)); } @@ -182,7 +181,7 @@ class ClientTest extends BasicTestCase * @covers \AtolOnline\Entities\Client * @covers \AtolOnline\Entities\Client::setPhone * @covers \AtolOnline\Entities\Client::getPhone - * @throws TooLongPhoneException + * @throws TooLongClientContactException */ public function testNullablePhones(mixed $phone): void { @@ -197,7 +196,7 @@ class ClientTest extends BasicTestCase * @covers \AtolOnline\Entities\Client * @covers \AtolOnline\Entities\Client::setPhone * @covers \AtolOnline\Entities\Client::getPhone - * @throws TooLongPhoneException + * @throws TooLongClientContactException */ public function testValidPhone(string $input, string $output): void { @@ -210,12 +209,12 @@ class ClientTest extends BasicTestCase * * @covers \AtolOnline\Entities\Client * @covers \AtolOnline\Entities\Client::setPhone - * @covers \AtolOnline\Exceptions\TooLongPhoneException - * @throws TooLongPhoneException + * @covers \AtolOnline\Exceptions\TooLongClientContactException + * @throws TooLongClientContactException */ - public function testInvalidPhone(): void + public function testTooLongClientPhone(): void { - $this->expectException(TooLongPhoneException::class); + $this->expectException(TooLongClientContactException::class); (new Client())->setPhone('99999999999999999999999999999999999999999999999999999999999999999999999999'); } @@ -315,4 +314,4 @@ class ClientTest extends BasicTestCase $this->expectException(InvalidInnLengthException::class); (new Client())->setInn('1234567890123'); } -} \ No newline at end of file +} diff --git a/tests/CompanyTest.php b/tests/CompanyTest.php index 82961af..93fa09c 100644 --- a/tests/CompanyTest.php +++ b/tests/CompanyTest.php @@ -13,9 +13,9 @@ use AtolOnline\{ Entities\Company, Enums\SnoTypes, Exceptions\InvalidEmailException, + Exceptions\InvalidEnumValueException, Exceptions\InvalidInnLengthException, Exceptions\InvalidPaymentAddressException, - Exceptions\InvalidSnoException, Exceptions\TooLongEmailException, Exceptions\TooLongPaymentAddressException, Helpers}; @@ -85,11 +85,11 @@ class CompanyTest extends BasicTestCase * * @covers \AtolOnline\Entities\Company * @covers \AtolOnline\Entities\Company::setSno - * @covers \AtolOnline\Exceptions\InvalidSnoException + * @covers \AtolOnline\Exceptions\InvalidEnumValueException */ public function testInvalidSnoException() { - $this->expectException(InvalidSnoException::class); + $this->expectException(InvalidEnumValueException::class); new Company('company@example.com', 'test', '1234567890', 'https://example.com'); } diff --git a/tests/ItemTest_todo.php b/tests/ItemTest_todo.php index 2e3b492..97d3f3f 100644 --- a/tests/ItemTest_todo.php +++ b/tests/ItemTest_todo.php @@ -14,11 +14,11 @@ use AtolOnline\{ Enums\PaymentMethods, Enums\PaymentObjects, Enums\VatTypes, - Exceptions\BasicTooManyException, Exceptions\TooHighPriceException, - Exceptions\TooLongNameException, + Exceptions\TooLongItemNameException, Exceptions\TooLongUnitException, - Exceptions\TooLongUserdataException,}; + Exceptions\TooLongUserdataException, + Exceptions\TooManyException,}; /** * Class ItemTest @@ -102,12 +102,12 @@ class ItemTestTodo extends BasicTestCase /** * Тестирует исключение о слишком длинном наименовании * - * @throws TooLongNameException + * @throws TooLongItemNameException */ public function testAtolNameTooLongException() { $item = new Item(); - $this->expectException(TooLongNameException::class); + $this->expectException(TooLongItemNameException::class); $item->setName(Helpers::randomStr(130)); } @@ -115,13 +115,13 @@ class ItemTestTodo extends BasicTestCase * Тестирует исключение о слишком высоком количестве * * @throws TooHighPriceException - * @throws BasicTooManyException + * @throws TooManyException * @throws TooLongUnitException */ public function testAtolQuantityTooHighException() { $item = new Item(); - $this->expectException(BasicTooManyException::class); + $this->expectException(TooManyException::class); $item->setQuantity(100000.1); } @@ -160,4 +160,4 @@ class ItemTestTodo extends BasicTestCase $this->expectException(TooLongUnitException::class); $item->setMeasurementUnit('кг кг кг кг кг кг кг кг кг '); } -} \ No newline at end of file +} diff --git a/tests/KktMonitorTest.php b/tests/KktMonitorTest.php index 88d9ad5..c8d53fd 100644 --- a/tests/KktMonitorTest.php +++ b/tests/KktMonitorTest.php @@ -56,7 +56,7 @@ class KktMonitorTest extends BasicTestCase $client = new KktMonitor(); $this->assertIsObject($client); $this->assertIsSameClass(KktMonitor::class, $client); - $this->assertExtendsClasses([AtolClient::class], $client); + $this->assertExtendsClasses($client, [AtolClient::class]); } /** @@ -76,8 +76,8 @@ class KktMonitorTest extends BasicTestCase { $client = new KktMonitor(false, 'login', 'password', []); $this->assertIsObject($client); - $this->assertIsSameClass(KktMonitor::class, $client); - $this->assertExtendsClasses([AtolClient::class], $client); + $this->assertIsSameClass($client, KktMonitor::class); + $this->assertExtendsClasses($client, [AtolClient::class]); } /**