14 Commits

Author SHA1 Message Date
93f5186b15 Перезапись компании в документе при тестовом режиме 2020-05-30 01:59:24 +08:00
f2b4952aa5 Установка адреса callback для тестового режима 2020-05-30 01:59:24 +08:00
7899daf421 Снова фикс ошибок при приведении документа к json-строке 2020-05-30 01:59:23 +08:00
4cf6e81d5f Исправлены тесты компании и клиента 2020-05-29 22:24:15 +08:00
9d7dd75cd9 Испарвлен тест на длину имени предмета расчёта 2020-05-29 22:15:47 +08:00
4d7e5dd76e Фикс возвращаемого значения KktResponse::getContent() 2020-05-29 22:06:04 +08:00
0f658d38a9 Фикс ошибок при приведении докумнета к json-строке 2020-05-29 22:05:35 +08:00
ca32fe5923 Повсюду улучшена проверка длин строк 2020-05-28 22:56:26 +08:00
9ea1c81666 Скорректирован Document::jsonSerialize() - не выдаёт пустого кассира 2020-05-28 22:55:53 +08:00
12b98dcdac Document::fromRaw() теперь парсит входящий json как массив, а не объект 2020-05-28 22:55:27 +08:00
1fec446ce0 Фикс тестов НДС 2020-05-28 01:31:37 +08:00
6256c14522 Обновления в composer.lock 2020-05-28 01:25:27 +08:00
7dff642f0a Бейджик в readme + фикс composer.json 2020-05-28 01:14:53 +08:00
670f440620 Github actions только на мастере 2020-05-28 01:13:08 +08:00
16 changed files with 327 additions and 185 deletions

View File

@@ -1,6 +1,9 @@
name: Composer and phpunit tests name: Build
on: [push] on:
push:
branches:
- master
jobs: jobs:
build: build:

View File

@@ -1,5 +1,7 @@
# АТОЛ Онлайн # АТОЛ Онлайн
![Build](https://github.com/anthonyaxenov/atol-online/workflows/Build/badge.svg?branch=master)
Библиотека для фискализации чеков по 54-ФЗ через [облачную ККТ АТОЛ](https://online.atol.ru/). Библиотека для фискализации чеков по 54-ФЗ через [облачную ККТ АТОЛ](https://online.atol.ru/).
Текущая поддерживаемая версия API: **5.1** Текущая поддерживаемая версия API: **5.1**

View File

@@ -3,7 +3,6 @@
"description": "Library to use cloud cash register in e-commerce according to Russian Federal Law #54", "description": "Library to use cloud cash register in e-commerce according to Russian Federal Law #54",
"license": "MIT", "license": "MIT",
"type": "library", "type": "library",
"version": "0.2.1-b",
"keywords": [ "keywords": [
"54-fz", "54-fz",
"kkt", "kkt",

239
composer.lock generated
View File

@@ -4,27 +4,28 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "dae801b00d2c80c28d290f676970945b", "content-hash": "20b642fe60192cf1e67c9aa8dca27440",
"packages": [ "packages": [
{ {
"name": "guzzlehttp/guzzle", "name": "guzzlehttp/guzzle",
"version": "6.5.2", "version": "6.5.4",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/guzzle/guzzle.git", "url": "https://github.com/guzzle/guzzle.git",
"reference": "43ece0e75098b7ecd8d13918293029e555a50f82" "reference": "a4a1b6930528a8f7ee03518e6442ec7a44155d9d"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/guzzle/guzzle/zipball/43ece0e75098b7ecd8d13918293029e555a50f82", "url": "https://api.github.com/repos/guzzle/guzzle/zipball/a4a1b6930528a8f7ee03518e6442ec7a44155d9d",
"reference": "43ece0e75098b7ecd8d13918293029e555a50f82", "reference": "a4a1b6930528a8f7ee03518e6442ec7a44155d9d",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"ext-json": "*", "ext-json": "*",
"guzzlehttp/promises": "^1.0", "guzzlehttp/promises": "^1.0",
"guzzlehttp/psr7": "^1.6.1", "guzzlehttp/psr7": "^1.6.1",
"php": ">=5.5" "php": ">=5.5",
"symfony/polyfill-intl-idn": "1.17.0"
}, },
"require-dev": { "require-dev": {
"ext-curl": "*", "ext-curl": "*",
@@ -32,7 +33,6 @@
"psr/log": "^1.1" "psr/log": "^1.1"
}, },
"suggest": { "suggest": {
"ext-intl": "Required for Internationalized Domain Name (IDN) support",
"psr/log": "Required for using the Log middleware" "psr/log": "Required for using the Log middleware"
}, },
"type": "library", "type": "library",
@@ -71,7 +71,7 @@
"rest", "rest",
"web service" "web service"
], ],
"time": "2019-12-23T11:57:10+00:00" "time": "2020-05-25T19:35:05+00:00"
}, },
{ {
"name": "guzzlehttp/promises", "name": "guzzlehttp/promises",
@@ -466,16 +466,16 @@
}, },
{ {
"name": "symfony/polyfill-ctype", "name": "symfony/polyfill-ctype",
"version": "v1.15.0", "version": "v1.17.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/polyfill-ctype.git", "url": "https://github.com/symfony/polyfill-ctype.git",
"reference": "4719fa9c18b0464d399f1a63bf624b42b6fa8d14" "reference": "e94c8b1bbe2bc77507a1056cdb06451c75b427f9"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/4719fa9c18b0464d399f1a63bf624b42b6fa8d14", "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/e94c8b1bbe2bc77507a1056cdb06451c75b427f9",
"reference": "4719fa9c18b0464d399f1a63bf624b42b6fa8d14", "reference": "e94c8b1bbe2bc77507a1056cdb06451c75b427f9",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -487,7 +487,7 @@
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-master": "1.15-dev" "dev-master": "1.17-dev"
} }
}, },
"autoload": { "autoload": {
@@ -520,7 +520,183 @@
"polyfill", "polyfill",
"portable" "portable"
], ],
"time": "2020-02-27T09:26:54+00:00" "time": "2020-05-12T16:14:59+00:00"
},
{
"name": "symfony/polyfill-intl-idn",
"version": "v1.17.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-intl-idn.git",
"reference": "3bff59ea7047e925be6b7f2059d60af31bb46d6a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/3bff59ea7047e925be6b7f2059d60af31bb46d6a",
"reference": "3bff59ea7047e925be6b7f2059d60af31bb46d6a",
"shasum": ""
},
"require": {
"php": ">=5.3.3",
"symfony/polyfill-mbstring": "^1.3",
"symfony/polyfill-php72": "^1.10"
},
"suggest": {
"ext-intl": "For best performance"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.17-dev"
}
},
"autoload": {
"psr-4": {
"Symfony\\Polyfill\\Intl\\Idn\\": ""
},
"files": [
"bootstrap.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Laurent Bassin",
"email": "laurent@bassin.info"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony polyfill for intl's idn_to_ascii and idn_to_utf8 functions",
"homepage": "https://symfony.com",
"keywords": [
"compatibility",
"idn",
"intl",
"polyfill",
"portable",
"shim"
],
"time": "2020-05-12T16:47:27+00:00"
},
{
"name": "symfony/polyfill-mbstring",
"version": "v1.17.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-mbstring.git",
"reference": "fa79b11539418b02fc5e1897267673ba2c19419c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/fa79b11539418b02fc5e1897267673ba2c19419c",
"reference": "fa79b11539418b02fc5e1897267673ba2c19419c",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"suggest": {
"ext-mbstring": "For best performance"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.17-dev"
}
},
"autoload": {
"psr-4": {
"Symfony\\Polyfill\\Mbstring\\": ""
},
"files": [
"bootstrap.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony polyfill for the Mbstring extension",
"homepage": "https://symfony.com",
"keywords": [
"compatibility",
"mbstring",
"polyfill",
"portable",
"shim"
],
"time": "2020-05-12T16:47:27+00:00"
},
{
"name": "symfony/polyfill-php72",
"version": "v1.17.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php72.git",
"reference": "f048e612a3905f34931127360bdd2def19a5e582"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/f048e612a3905f34931127360bdd2def19a5e582",
"reference": "f048e612a3905f34931127360bdd2def19a5e582",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.17-dev"
}
},
"autoload": {
"psr-4": {
"Symfony\\Polyfill\\Php72\\": ""
},
"files": [
"bootstrap.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions",
"homepage": "https://symfony.com",
"keywords": [
"compatibility",
"polyfill",
"portable",
"shim"
],
"time": "2020-05-12T16:47:27+00:00"
} }
], ],
"packages-dev": [ "packages-dev": [
@@ -732,24 +908,21 @@
}, },
{ {
"name": "phpdocumentor/reflection-common", "name": "phpdocumentor/reflection-common",
"version": "2.0.0", "version": "2.1.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/phpDocumentor/ReflectionCommon.git", "url": "https://github.com/phpDocumentor/ReflectionCommon.git",
"reference": "63a995caa1ca9e5590304cd845c15ad6d482a62a" "reference": "6568f4687e5b41b054365f9ae03fcb1ed5f2069b"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/63a995caa1ca9e5590304cd845c15ad6d482a62a", "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/6568f4687e5b41b054365f9ae03fcb1ed5f2069b",
"reference": "63a995caa1ca9e5590304cd845c15ad6d482a62a", "reference": "6568f4687e5b41b054365f9ae03fcb1ed5f2069b",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"php": ">=7.1" "php": ">=7.1"
}, },
"require-dev": {
"phpunit/phpunit": "~6"
},
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
@@ -780,7 +953,7 @@
"reflection", "reflection",
"static analysis" "static analysis"
], ],
"time": "2018-08-07T13:53:10+00:00" "time": "2020-04-27T09:25:28+00:00"
}, },
{ {
"name": "phpdocumentor/reflection-docblock", "name": "phpdocumentor/reflection-docblock",
@@ -1198,16 +1371,16 @@
}, },
{ {
"name": "phpunit/phpunit", "name": "phpunit/phpunit",
"version": "8.5.3", "version": "8.5.5",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git", "url": "https://github.com/sebastianbergmann/phpunit.git",
"reference": "67750516bc02f300e2742fed2f50177f8f37bedf" "reference": "63dda3b212a0025d380a745f91bdb4d8c985adb7"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/67750516bc02f300e2742fed2f50177f8f37bedf", "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/63dda3b212a0025d380a745f91bdb4d8c985adb7",
"reference": "67750516bc02f300e2742fed2f50177f8f37bedf", "reference": "63dda3b212a0025d380a745f91bdb4d8c985adb7",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -1277,7 +1450,7 @@
"testing", "testing",
"xunit" "xunit"
], ],
"time": "2020-03-31T08:52:04+00:00" "time": "2020-05-22T13:51:52+00:00"
}, },
{ {
"name": "sebastian/code-unit-reverse-lookup", "name": "sebastian/code-unit-reverse-lookup",
@@ -1936,16 +2109,16 @@
}, },
{ {
"name": "webmozart/assert", "name": "webmozart/assert",
"version": "1.7.0", "version": "1.8.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/webmozart/assert.git", "url": "https://github.com/webmozart/assert.git",
"reference": "aed98a490f9a8f78468232db345ab9cf606cf598" "reference": "ab2cb0b3b559010b75981b1bdce728da3ee90ad6"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/webmozart/assert/zipball/aed98a490f9a8f78468232db345ab9cf606cf598", "url": "https://api.github.com/repos/webmozart/assert/zipball/ab2cb0b3b559010b75981b1bdce728da3ee90ad6",
"reference": "aed98a490f9a8f78468232db345ab9cf606cf598", "reference": "ab2cb0b3b559010b75981b1bdce728da3ee90ad6",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -1953,7 +2126,7 @@
"symfony/polyfill-ctype": "^1.8" "symfony/polyfill-ctype": "^1.8"
}, },
"conflict": { "conflict": {
"vimeo/psalm": "<3.6.0" "vimeo/psalm": "<3.9.1"
}, },
"require-dev": { "require-dev": {
"phpunit/phpunit": "^4.8.36 || ^7.5.13" "phpunit/phpunit": "^4.8.36 || ^7.5.13"
@@ -1980,7 +2153,7 @@
"check", "check",
"validate" "validate"
], ],
"time": "2020-02-14T12:15:55+00:00" "time": "2020-04-18T12:12:48+00:00"
} }
], ],
"aliases": [], "aliases": [],

View File

@@ -9,7 +9,8 @@
namespace AtolOnline\Api; namespace AtolOnline\Api;
use AtolOnline\{Entities\Document, use AtolOnline\{Entities\Company,
Entities\Document,
Exceptions\AtolCorrectionInfoException, Exceptions\AtolCorrectionInfoException,
Exceptions\AtolInvalidUuidException, Exceptions\AtolInvalidUuidException,
Exceptions\AtolKktLoginEmptyException, Exceptions\AtolKktLoginEmptyException,
@@ -118,7 +119,7 @@ class Kkt extends Client
if (!$this->isTestMode()) { if (!$this->isTestMode()) {
if (empty($login)) { if (empty($login)) {
throw new AtolKktLoginEmptyException(); throw new AtolKktLoginEmptyException();
} elseif (strlen($login) > 100) { } elseif ((function_exists('mb_strlen') ? mb_strlen($login) : strlen($login)) > 100) {
throw new AtolKktLoginTooLongException($login, 100); throw new AtolKktLoginTooLongException($login, 100);
} }
} }
@@ -172,7 +173,7 @@ class Kkt extends Client
*/ */
public function setCallbackUrl(string $url) public function setCallbackUrl(string $url)
{ {
$this->kkt_config['prod']['callback_url'] = $url; $this->kkt_config[$this->isTestMode() ? 'test' : 'prod']['callback_url'] = $url;
return $this; return $this;
} }
@@ -390,7 +391,7 @@ class Kkt extends Client
{ {
$headers['Content-type'] = 'application/json; charset=utf-8'; $headers['Content-type'] = 'application/json; charset=utf-8';
if ($this->getAuthToken()) { if ($this->getAuthToken()) {
$headers['Token'] = $this->auth_token; $headers['Token'] = $this->getAuthToken();
} }
return $headers; return $headers;
} }
@@ -429,6 +430,7 @@ class Kkt extends Client
* @param mixed $data Данные для передачи * @param mixed $data Данные для передачи
* @param array|null $options Параметры Guzzle * @param array|null $options Параметры Guzzle
* @return \AtolOnline\Api\KktResponse * @return \AtolOnline\Api\KktResponse
* @throws \GuzzleHttp\Exception\GuzzleException
* @see https://guzzle.readthedocs.io/en/latest/request-options.html * @see https://guzzle.readthedocs.io/en/latest/request-options.html
*/ */
protected function sendAtolRequest(string $http_method, string $api_method, $data = null, array $options = null) protected function sendAtolRequest(string $http_method, string $api_method, $data = null, array $options = null)
@@ -449,6 +451,7 @@ class Kkt extends Client
* Производит авторизацию на ККТ и получает токен доступа для дальнейших HTTP-запросов * Производит авторизацию на ККТ и получает токен доступа для дальнейших HTTP-запросов
* *
* @return bool * @return bool
* @throws \GuzzleHttp\Exception\GuzzleException
*/ */
protected function auth() protected function auth()
{ {
@@ -482,6 +485,12 @@ class Kkt extends Client
throw new AtolWrongDocumentTypeException($type); throw new AtolWrongDocumentTypeException($type);
} }
$this->auth(); $this->auth();
if ($this->isTestMode()) {
$document->setCompany((new Company())
->setInn('5544332219')
->setPaymentAddress('https://v4.online.atol.ru')
);
}
$data = [ $data = [
'timestamp' => date('d.m.y H:i:s'), 'timestamp' => date('d.m.y H:i:s'),
'external_id' => Uuid::uuid4()->toString(), 'external_id' => Uuid::uuid4()->toString(),

View File

@@ -81,9 +81,9 @@ class KktResponse implements JsonSerializable
/** /**
* Возвращает объект результата запроса * Возвращает объект результата запроса
* *
* @return \stdClass * @return stdClass|null
*/ */
public function getContent(): stdClass public function getContent(): ?stdClass
{ {
return $this->content; return $this->content;
} }

View File

@@ -89,7 +89,7 @@ class Client extends Entity
public function setName(string $name) public function setName(string $name)
{ {
$name = trim($name); $name = trim($name);
if (strlen($name) > 256) { if ((function_exists('mb_strlen') ? mb_strlen($name) : strlen($name)) > 256) {
throw new AtolNameTooLongException($name, 256); throw new AtolNameTooLongException($name, 256);
} }
$this->name = $name; $this->name = $name;
@@ -119,7 +119,7 @@ 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 (strlen($phone) > 64) { if ((function_exists('mb_strlen') ? mb_strlen($phone) : strlen($phone)) > 64) {
throw new AtolPhoneTooLongException($phone, 64); throw new AtolPhoneTooLongException($phone, 64);
} }
$this->phone = $phone; $this->phone = $phone;

View File

@@ -115,7 +115,7 @@ class Company extends Entity
public function setPaymentAddress(string $payment_address) public function setPaymentAddress(string $payment_address)
{ {
$payment_address = trim($payment_address); $payment_address = trim($payment_address);
if (strlen($payment_address) > 256) { if ((function_exists('mb_strlen') ? mb_strlen($payment_address) : strlen($payment_address)) > 256) {
throw new AtolPaymentAddressTooLongException($payment_address, 256); throw new AtolPaymentAddressTooLongException($payment_address, 256);
} }
$this->payment_address = $payment_address; $this->payment_address = $payment_address;

View File

@@ -199,9 +199,9 @@ class Document extends Entity
/** /**
* Возвращает заданного клиента (покупателя) * Возвращает заданного клиента (покупателя)
* *
* @return Client * @return Client|null
*/ */
public function getClient(): Client public function getClient(): ?Client
{ {
return $this->client; return $this->client;
} }
@@ -221,9 +221,9 @@ class Document extends Entity
/** /**
* Возвращает заданную компанию (продавца) * Возвращает заданную компанию (продавца)
* *
* @return Company * @return Company|null
*/ */
public function getCompany(): Company public function getCompany(): ?Company
{ {
return $this->company; return $this->company;
} }
@@ -338,60 +338,57 @@ class Document extends Entity
*/ */
public static function fromRaw(string $json) public static function fromRaw(string $json)
{ {
$object = json_decode($json); $array = json_decode($json, true);
if (json_last_error() !== JSON_ERROR_NONE) { if (json_last_error() !== JSON_ERROR_NONE) {
throw new AtolInvalidJsonException(); throw new AtolInvalidJsonException();
} }
$doc = new self(); $doc = new self();
if ($object->company) { if (isset($array['company'])) {
$doc->setCompany(new Company( $doc->setCompany(new Company(
$object->company->sno ?? null, $array['company']['sno'] ?? null,
$object->company->inn ?? null, $array['company']['inn'] ?? null,
$object->company->payment_address ?? null, $array['company']['payment_address'] ?? null,
$object->company->email ?? null $array['company']['email'] ?? null
)); ));
} }
if ($object->client) { if (isset($array['client'])) {
$doc->setClient(new Client( $doc->setClient(new Client(
$object->client->name ?? null, $array['client']['name'] ?? null,
$object->client->phone ?? null, $array['client']['phone'] ?? null,
$object->client->email ?? null, $array['client']['email'] ?? null,
$object->client->inn ?? null $array['client']['inn'] ?? null
)); ));
} }
if ($object->items) { if (isset($array['items'])) {
foreach ($object->items as $obj_item) { foreach ($array['items'] as $ar_item) {
$item = new Item( $item = new Item(
$obj_item->name ?? null, $ar_item['name'] ?? null,
$obj_item->price ?? null, $ar_item['price'] ?? null,
$obj_item->quantity ?? null, $ar_item['quantity'] ?? null,
$obj_item->measurement_unit ?? null, $ar_item['measurement_unit'] ?? null,
$obj_item->vat->type ?? null, $ar_item['vat']['type'] ?? null,
$obj_item->payment_object ?? null, $ar_item['payment_object'] ?? null,
$obj_item->payment_method ?? null $ar_item['payment_method'] ?? null
); );
if (!empty($obj_item->user_data)) { if (!empty($ar_item['user_data'])) {
$item->setUserData($obj_item->user_data ?? null); $item->setUserData($ar_item['user_data'] ?? null);
} }
$doc->addItem($item); $doc->addItem($item);
} }
} }
if ($object->payments) { if (isset($array['payments'])) {
foreach ($object->payments as $obj_payment) { foreach ($array['payments'] as $ar_payment) {
$doc->payments->add(new Payment( $payment = new Payment();
$obj_payment->type, if (isset($ar_payment['type'])) {
$obj_payment->sum $payment->setType($ar_payment['type']);
)); }
if (isset($ar_payment['sum'])) {
$payment->setSum($ar_payment['sum']);
}
$doc->payments->add($payment);
} }
} }
//if ($object->vats) { if (isset($array['total']) && $array['total'] != $doc->calcTotal()) {
// foreach ($object->vats as $obj_vat) {
// $doc->vats->add(new Vat(
// $obj_vat->type
// ));
// }
//}
if ($object->total != $doc->calcTotal()) {
throw new AtolException('Real total sum not equals to provided in JSON one'); throw new AtolException('Real total sum not equals to provided in JSON one');
} }
return $doc; return $doc;
@@ -404,16 +401,24 @@ class Document extends Entity
*/ */
public function jsonSerialize() public function jsonSerialize()
{ {
$json = [ if ($this->getCompany()) {
'company' => $this->getCompany()->jsonSerialize(), // обязательно $json['company'] = $this->getCompany()->jsonSerialize(); // обязательно
'payments' => $this->payments->jsonSerialize(), // обязательно }
'cashier' => $this->getCashier() ?? '', if ($this->getPayments()) {
]; $json['payments'] = $this->payments->jsonSerialize(); // обязательно
}
if ($this->getCashier()) {
$json['cashier'] = $this->getCashier();
}
if ($this->getCorrectionInfo()) { if ($this->getCorrectionInfo()) {
$json['correction_info'] = $this->getCorrectionInfo()->jsonSerialize(); // обязательно для коррекционных $json['correction_info'] = $this->getCorrectionInfo()->jsonSerialize(); // обязательно для коррекционных
} else { } else {
$json['client'] = $this->getClient()->jsonSerialize(); // обязательно для некоррекционных if ($this->getClient()) {
$json['items'] = $this->items->jsonSerialize(); // обязательно для некоррекционных $json['client'] = $this->getClient()->jsonSerialize(); // обязательно для некоррекционных
}
if ($this->getItems()) {
$json['items'] = $this->items->jsonSerialize(); // обязательно для некоррекционных
}
$json['total'] = $this->calcTotal(); // обязательно для некоррекционных $json['total'] = $this->calcTotal(); // обязательно для некоррекционных
} }
if ($this->getVats()) { if ($this->getVats()) {
@@ -421,4 +426,4 @@ class Document extends Entity
} }
return $json; return $json;
} }
} }

View File

@@ -137,7 +137,7 @@ class Item extends Entity
public function setName(string $name) public function setName(string $name)
{ {
$name = trim($name); $name = trim($name);
if (strlen($name) > 128) { if ((function_exists('mb_strlen') ? mb_strlen($name) : strlen($name)) > 128) {
throw new AtolNameTooLongException($name, 128); throw new AtolNameTooLongException($name, 128);
} }
$this->name = $name; $this->name = $name;
@@ -328,7 +328,7 @@ 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 (strlen($user_data) > 64) { if ((function_exists('mb_strlen') ? mb_strlen($user_data) : strlen($user_data)) > 64) {
throw new AtolUserdataTooLongException($user_data, 64); throw new AtolUserdataTooLongException($user_data, 64);
} }
$this->user_data = $user_data; $this->user_data = $user_data;

View File

@@ -44,7 +44,7 @@ trait HasEmail
public function setEmail(string $email) public function setEmail(string $email)
{ {
$email = trim($email); $email = trim($email);
if (strlen($email) > 64) { if ((function_exists('mb_strlen') ? mb_strlen($email) : strlen($email)) > 64) {
throw new AtolEmailTooLongException($email, 64); throw new AtolEmailTooLongException($email, 64);
} }
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) { if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {

View File

@@ -42,7 +42,22 @@ class BasicTestCase extends TestCase
*/ */
public function tearDown(): void public function tearDown(): void
{ {
//parent::tearDown(); //parent::tearDown();
} }
/**
* Возвращает случайную строку указанной длины
*
* @param int $length
* @return string
*/
protected static function randomString($length = 8)
{
$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$string = '';
for ($i = 0; $i < $length; $i++) {
$string .= $characters[mt_rand(0, strlen($characters) - 1)];
}
return $string;
}
} }

View File

@@ -85,10 +85,7 @@ class ItemTest extends BasicTestCase
/** /**
* Тестирует установку ставки НДС разными путями * Тестирует установку ставки НДС разными путями
* *
* @throws AtolOnline\Exceptions\AtolNameTooLongException * @throws \AtolOnline\Exceptions\AtolPriceTooHighException
* @throws AtolOnline\Exceptions\AtolPriceTooHighException
* @throws AtolOnline\Exceptions\AtolTooManyException
* @throws AtolOnline\Exceptions\AtolUnitTooLongException
*/ */
public function testSetVat() public function testSetVat()
{ {
@@ -102,25 +99,21 @@ class ItemTest extends BasicTestCase
/** /**
* Тестирует исключение о слишком длинном наименовании * Тестирует исключение о слишком длинном наименовании
* *
* @throws AtolOnline\Exceptions\AtolNameTooLongException * @throws \AtolOnline\Exceptions\AtolNameTooLongException
* @throws AtolOnline\Exceptions\AtolPriceTooHighException
* @throws AtolOnline\Exceptions\AtolTooManyException
* @throws AtolOnline\Exceptions\AtolUnitTooLongException
*/ */
public function testAtolNameTooLongException() public function testAtolNameTooLongException()
{ {
$item = new Item(); $item = new Item();
$this->expectException(AtolNameTooLongException::class); $this->expectException(AtolNameTooLongException::class);
$item->setName('Банан Банан Банан Банан Банан Банан Банан Банан Банан Банан Банан Банан'); $item->setName(self::randomString(130));
} }
/** /**
* Тестирует исключение о слишком высоком количестве * Тестирует исключение о слишком высоком количестве
* *
* @throws AtolOnline\Exceptions\AtolNameTooLongException * @throws \AtolOnline\Exceptions\AtolPriceTooHighException
* @throws AtolOnline\Exceptions\AtolTooManyException * @throws \AtolOnline\Exceptions\AtolTooManyException
* @throws AtolOnline\Exceptions\AtolPriceTooHighException * @throws \AtolOnline\Exceptions\AtolUnitTooLongException
* @throws AtolOnline\Exceptions\AtolUnitTooLongException
*/ */
public function testAtolQuantityTooHighException() public function testAtolQuantityTooHighException()
{ {
@@ -132,10 +125,7 @@ class ItemTest extends BasicTestCase
/** /**
* Тестирует исключение о слишком высокой цене * Тестирует исключение о слишком высокой цене
* *
* @throws AtolOnline\Exceptions\AtolPriceTooHighException * @throws \AtolOnline\Exceptions\AtolPriceTooHighException
* @throws AtolOnline\Exceptions\AtolNameTooLongException
* @throws AtolOnline\Exceptions\AtolTooManyException
* @throws AtolOnline\Exceptions\AtolUnitTooLongException
*/ */
public function testAtolPriceTooHighException() public function testAtolPriceTooHighException()
{ {
@@ -147,11 +137,7 @@ class ItemTest extends BasicTestCase
/** /**
* Тестирует исключение о слишком длинных польз. данных * Тестирует исключение о слишком длинных польз. данных
* *
* @throws AtolOnline\Exceptions\AtolUserdataTooLongException * @throws \AtolOnline\Exceptions\AtolUserdataTooLongException
* @throws AtolOnline\Exceptions\AtolPriceTooHighException
* @throws AtolOnline\Exceptions\AtolNameTooLongException
* @throws AtolOnline\Exceptions\AtolTooManyException
* @throws AtolOnline\Exceptions\AtolUnitTooLongException
*/ */
public function testAtolUserdataTooLongException() public function testAtolUserdataTooLongException()
{ {
@@ -163,10 +149,7 @@ class ItemTest extends BasicTestCase
/** /**
* Тестирует исключение о слишком длинной единице измерения * Тестирует исключение о слишком длинной единице измерения
* *
* @throws AtolOnline\Exceptions\AtolNameTooLongException * @throws \AtolOnline\Exceptions\AtolUnitTooLongException
* @throws AtolOnline\Exceptions\AtolPriceTooHighException
* @throws AtolOnline\Exceptions\AtolTooManyException
* @throws AtolOnline\Exceptions\AtolUnitTooLongException
*/ */
public function testAtolUnitTooLongException() public function testAtolUnitTooLongException()
{ {

View File

@@ -22,12 +22,6 @@ class ClientTest extends BasicTestCase
{ {
/** /**
* Тестирует установку параметров * Тестирует установку параметров
*
* @throws \AtolOnline\Exceptions\AtolEmailTooLongException
* @throws \AtolOnline\Exceptions\AtolEmailValidateException
* @throws \AtolOnline\Exceptions\AtolNameTooLongException
* @throws \AtolOnline\Exceptions\AtolPhoneTooLongException
* @throws \AtolOnline\Exceptions\AtolInnWrongLengthException
*/ */
public function testConstructor() public function testConstructor()
{ {
@@ -48,30 +42,18 @@ class ClientTest extends BasicTestCase
* Тестирует исключение о слишком длинном имени * Тестирует исключение о слишком длинном имени
* *
* @throws \AtolOnline\Exceptions\AtolNameTooLongException * @throws \AtolOnline\Exceptions\AtolNameTooLongException
* @throws \AtolOnline\Exceptions\AtolEmailTooLongException
* @throws \AtolOnline\Exceptions\AtolEmailValidateException
* @throws \AtolOnline\Exceptions\AtolPhoneTooLongException
* @throws \AtolOnline\Exceptions\AtolInnWrongLengthException
*/ */
public function testAtolNameTooLongException() public function testAtolNameTooLongException()
{ {
$customer = new Client(); $customer = new Client();
$this->expectException(AtolNameTooLongException::class); $this->expectException(AtolNameTooLongException::class);
$customer->setName('John Doe John Doe John Doe John Doe John Doe '. $customer->setName(self::randomString(257));
'John Doe John Doe John Doe John Doe John Doe John Doe John Doe John '.
'Doe John Doe John Doe John Doe John DoeJohn Doe John Doe John Doe '.
'John Doe John Doe John Doe John Doe John Doe John Doe John Doe John '.
'Doe John Doe John Doe John Doe John Doe John Doe John Doe');
} }
/** /**
* Тестирует исключение о слишком длинном телефоне * Тестирует исключение о слишком длинном телефоне
* *
* @throws \AtolOnline\Exceptions\AtolPhoneTooLongException * @throws \AtolOnline\Exceptions\AtolPhoneTooLongException
* @throws \AtolOnline\Exceptions\AtolNameTooLongException
* @throws \AtolOnline\Exceptions\AtolEmailTooLongException
* @throws \AtolOnline\Exceptions\AtolEmailValidateException
* @throws \AtolOnline\Exceptions\AtolInnWrongLengthException
*/ */
public function testAtolPhoneTooLongException() public function testAtolPhoneTooLongException()
{ {
@@ -84,42 +66,32 @@ class ClientTest extends BasicTestCase
* Тестирует исключение о слишком длинной почте * Тестирует исключение о слишком длинной почте
* *
* @throws \AtolOnline\Exceptions\AtolEmailTooLongException * @throws \AtolOnline\Exceptions\AtolEmailTooLongException
* @throws \AtolOnline\Exceptions\AtolPhoneTooLongException
* @throws \AtolOnline\Exceptions\AtolNameTooLongException
* @throws \AtolOnline\Exceptions\AtolEmailValidateException * @throws \AtolOnline\Exceptions\AtolEmailValidateException
* @throws \AtolOnline\Exceptions\AtolInnWrongLengthException
*/ */
public function testAtolEmailTooLongException() public function testAtolEmailTooLongException()
{ {
$customer = new Client(); $customer = new Client();
$this->expectException(AtolEmailTooLongException::class); $this->expectException(AtolEmailTooLongException::class);
$customer->setEmail('johnjohnjohnjohnjohnjohndoedoedoedoe@exampleexampleexampleexample.com'); $customer->setEmail(self::randomString(65));
} }
/** /**
* Тестирует исключение о некорректной почте * Тестирует исключение о некорректной почте
* *
* @throws \AtolOnline\Exceptions\AtolEmailValidateException
* @throws \AtolOnline\Exceptions\AtolEmailTooLongException * @throws \AtolOnline\Exceptions\AtolEmailTooLongException
* @throws \AtolOnline\Exceptions\AtolPhoneTooLongException * @throws \AtolOnline\Exceptions\AtolEmailValidateException
* @throws \AtolOnline\Exceptions\AtolNameTooLongException
* @throws \AtolOnline\Exceptions\AtolInnWrongLengthException
*/ */
public function testAtolEmailValidateException() public function testAtolEmailValidateException()
{ {
$customer = new Client(); $customer = new Client();
$this->expectException(AtolEmailValidateException::class); $this->expectException(AtolEmailValidateException::class);
$customer->setEmail('John Doe'); $customer->setEmail(self::randomString(15));
} }
/** /**
* Тестирует исключение о некорректной длине ИНН * Тестирует исключение о некорректной длине ИНН
* *
* @throws \AtolOnline\Exceptions\AtolInnWrongLengthException * @throws \AtolOnline\Exceptions\AtolInnWrongLengthException
* @throws \AtolOnline\Exceptions\AtolEmailTooLongException
* @throws \AtolOnline\Exceptions\AtolEmailValidateException
* @throws \AtolOnline\Exceptions\AtolNameTooLongException
* @throws \AtolOnline\Exceptions\AtolPhoneTooLongException
*/ */
public function testAtolInnWrongLengthException() public function testAtolInnWrongLengthException()
{ {

View File

@@ -22,11 +22,6 @@ class CompanyTest extends BasicTestCase
{ {
/** /**
* Тестирует установку параметров через конструктор * Тестирует установку параметров через конструктор
*
* @throws AtolOnline\Exceptions\AtolEmailTooLongException
* @throws AtolOnline\Exceptions\AtolEmailValidateException
* @throws AtolOnline\Exceptions\AtolInnWrongLengthException
* @throws AtolOnline\Exceptions\AtolPaymentAddressTooLongException
*/ */
public function testConstructor() public function testConstructor()
{ {
@@ -46,10 +41,7 @@ class CompanyTest extends BasicTestCase
/** /**
* Тестирует исключение о некорректной длине ИНН * Тестирует исключение о некорректной длине ИНН
* *
* @throws AtolOnline\Exceptions\AtolInnWrongLengthException * @throws \AtolOnline\Exceptions\AtolInnWrongLengthException
* @throws AtolOnline\Exceptions\AtolEmailTooLongException
* @throws AtolOnline\Exceptions\AtolEmailValidateException
* @throws AtolOnline\Exceptions\AtolPaymentAddressTooLongException
*/ */
public function testAtolInnWrongLengthException() public function testAtolInnWrongLengthException()
{ {
@@ -62,49 +54,38 @@ class CompanyTest extends BasicTestCase
/** /**
* Тестирует исключение о слишком длинном платёжном адресе * Тестирует исключение о слишком длинном платёжном адресе
* *
* @throws AtolOnline\Exceptions\AtolPaymentAddressTooLongException * @throws \AtolOnline\Exceptions\AtolPaymentAddressTooLongException
* @throws AtolOnline\Exceptions\AtolEmailTooLongException
* @throws AtolOnline\Exceptions\AtolEmailValidateException
* @throws AtolOnline\Exceptions\AtolInnWrongLengthException
*/ */
public function testAtolPaymentAddressTooLongException() public function testAtolPaymentAddressTooLongException()
{ {
$company = new Company(); $company = new Company();
$this->expectException(AtolPaymentAddressTooLongException::class); $this->expectException(AtolPaymentAddressTooLongException::class);
$company->setPaymentAddress('John Doe John Doe John Doe John Doe '. $company->setPaymentAddress(self::randomString(257));
'John Doe John Doe John Doe John Doe John Doe John Doe John Doe John Doe John '.
'Doe John Doe John Doe John Doe John DoeJohn Doe John Doe John Doe John Doe '.
'John Doe John Doe John Doe John Doe John Doe John Doe John Doe John Doe John '.
'Doe John Doe John Doe John Doe John Doe');
} }
/** /**
* Тестирует исключение о слишком длинной почте * Тестирует исключение о слишком длинной почте
* *
* @throws AtolOnline\Exceptions\AtolEmailTooLongException * @throws \AtolOnline\Exceptions\AtolEmailTooLongException
* @throws AtolOnline\Exceptions\AtolEmailValidateException * @throws \AtolOnline\Exceptions\AtolEmailValidateException
* @throws AtolOnline\Exceptions\AtolInnWrongLengthException
* @throws AtolOnline\Exceptions\AtolPaymentAddressTooLongException
*/ */
public function testAtolEmailTooLongException() public function testAtolEmailTooLongException()
{ {
$company = new Company(); $company = new Company();
$this->expectException(AtolEmailTooLongException::class); $this->expectException(AtolEmailTooLongException::class);
$company->setEmail('johnjohnjohnjohnjohnjohndoedoedoedoe@exampleexampleexampleexample.com'); $company->setEmail(self::randomString(65));
} }
/** /**
* Тестирует исключение о некорректной почте * Тестирует исключение о некорректной почте
* *
* @throws AtolOnline\Exceptions\AtolEmailValidateException * @throws \AtolOnline\Exceptions\AtolEmailTooLongException
* @throws AtolOnline\Exceptions\AtolEmailTooLongException * @throws \AtolOnline\Exceptions\AtolEmailValidateException
* @throws AtolOnline\Exceptions\AtolInnWrongLengthException
* @throws AtolOnline\Exceptions\AtolPaymentAddressTooLongException
*/ */
public function testAtolEmailValidateException() public function testAtolEmailValidateException()
{ {
$company = new Company(); $company = new Company();
$this->expectException(AtolEmailValidateException::class); $this->expectException(AtolEmailValidateException::class);
$company->setEmail('John Doe'); $company->setEmail(self::randomString(15));
} }
} }

View File

@@ -44,8 +44,8 @@ class VatTest extends BasicTestCase
return [ return [
[VatTypes::NONE, 100, 0, 0], [VatTypes::NONE, 100, 0, 0],
[VatTypes::VAT0, 100, 0, 0], [VatTypes::VAT0, 100, 0, 0],
[VatTypes::VAT10, 100, 10, 12], [VatTypes::VAT10, 100, 9.09, 10.9],
[VatTypes::VAT18, 100, 18, 21.6], [VatTypes::VAT18, 100, 15.25, 18.3],
]; ];
} }
} }