diff --git a/src/Entities/Company.php b/src/Entities/Company.php index c0259a4..7061d8f 100644 --- a/src/Entities/Company.php +++ b/src/Entities/Company.php @@ -24,37 +24,37 @@ use AtolOnline\{ /** * Класс, описывающий сущность компании-продавца * - * @package AtolOnline\Entities + * @see https://online.atol.ru/files/API_atol_online_v4.pdf Документация, стр 17 */ class Company extends Entity { /** - * @var string|null Почта. Тег ФФД - 1117. + * @var string|null Почта (1117) */ protected ?string $email; /** - * @var string|null Система налогообложения продавца. Тег ФФД - 1055. + * @var string|null Система налогообложения продавца (1055) */ protected ?string $sno; /** - * @var string|null ИНН. Тег ФФД - 1018. + * @var string|null ИНН (1018) */ protected ?string $inn; /** - * @var string|null Место расчётов (адрес интернет-магазина). Тег ФФД - 1187. + * @var string|null Место расчётов (адрес интернет-магазина) (1187) */ protected ?string $payment_address; /** * Company constructor. * - * @param string $sno - * @param string $inn - * @param string $payment_address - * @param string $email + * @param string $sno Система налогообложения продавца (1055) + * @param string $inn ИНН (1018) + * @param string $payment_address Место расчётов (адрес интернет-магазина) (1187) + * @param string $email Почта (1117) * @throws InvalidEmailException * @throws InvalidInnLengthException * @throws InvalidPaymentAddressException diff --git a/src/Entities/MoneyTransferOperator.php b/src/Entities/MoneyTransferOperator.php new file mode 100644 index 0000000..198bab8 --- /dev/null +++ b/src/Entities/MoneyTransferOperator.php @@ -0,0 +1,189 @@ +setName($name); + $this->setInn($inn); + $this->setAddress($address); + $this->setPhones($phones); + } + + /** + * Возвращает установленное наименование поставщика + * + * @return string|null + */ + public function getName(): ?string + { + return $this->name; + } + + /** + * Устанавливает наименование поставщика + * + * @param string|null $name + * @return $this + */ + public function setName(?string $name): self + { + // критерии валидной строки не описаны ни в схеме, ни в документации + $this->name = trim((string)$name) ?: null; + return $this; + } + + /** + * Возвращает установленный адрес места расчётов + * + * @return string|null + */ + public function getAddress(): ?string + { + return $this->address; + } + + /** + * Устанавливает адрес места расчётов + * + * @param string|null $address + * @return $this + */ + public function setAddress(?string $address): self + { + // критерии валидной строки не описаны ни в схеме, ни в документации + $this->address = trim((string)$address) ?: null; + return $this; + } + + /** + * Возвращает установленные номера телефонов + * + * @todo вытащить в трейт + * @return Collection + */ + public function getPhones(): Collection + { + return $this->phones; + } + + /** + * Устанавливает массив номеров телефонов + * + * @todo вытащить в трейт + * @param array|Collection|null $phones + * @return $this + * @throws InvalidPhoneException + */ + public function setPhones(array|Collection|null $phones): self + { + if (!is_null($phones)) { + $phones = is_array($phones) ? collect($phones) : $phones; + $phones->each(function ($phone) { + $phone = preg_replace('/[^\d]/', '', trim($phone)); + if (preg_match(Constraints::PATTERN_PHONE, $phone) != 1) { + throw new InvalidPhoneException($phone); + } + }); + } + $this->phones = $phones ?? collect(); + return $this; + } + + /** + * Возвращает установленный ИНН + * + * @return string|null + */ + public function getInn(): ?string + { + return $this->inn; + } + + /** + * Устанавливает ИНН + * + * @param string|null $inn + * @return $this + * @throws InvalidInnLengthException Некорректная длина ИНН + */ + public function setInn(?string $inn): self + { + if (is_string($inn)) { + $inn = preg_replace('/[^\d]/', '', trim($inn)); + if (preg_match_all(Constraints::PATTERN_INN, $inn) === 0) { + throw new InvalidInnLengthException($inn); + } + } + $this->inn = $inn ?: null; + return $this; + } + + /** + * @inheritDoc + */ + public function jsonSerialize(): array + { + $json = []; + $this->getName() && $json['name'] = $this->getName(); + $this->getInn() && $json['inn'] = $this->getInn(); + $this->getAddress() && $json['address'] = $this->getAddress(); + !$this->getPhones()->isEmpty() && $json['phones'] = $this->getPhones()->toArray(); + return $json; + } +} diff --git a/src/Entities/Supplier.php b/src/Entities/Supplier.php index 3852885..8ddcc40 100644 --- a/src/Entities/Supplier.php +++ b/src/Entities/Supplier.php @@ -19,7 +19,7 @@ use Illuminate\Support\Collection; /** * Класс, описывающий поставшика * - * @see https://online.atol.ru/files/API_atol_online_v4.pdf Документация, стр 20-21 + * @see https://online.atol.ru/files/API_atol_online_v4.pdf Документация, стр 29 */ class Supplier extends Entity { diff --git a/tests/AtolOnline/Tests/Entities/MoneyTransferOperatorTest.php b/tests/AtolOnline/Tests/Entities/MoneyTransferOperatorTest.php new file mode 100644 index 0000000..0be356d --- /dev/null +++ b/tests/AtolOnline/Tests/Entities/MoneyTransferOperatorTest.php @@ -0,0 +1,177 @@ +assertEquals('[]', (string)(new MoneyTransferOperator())); + } + + /** + * Тестирует конструктор с передачей значений и корректное приведение к json + * + * @covers \AtolOnline\Entities\MoneyTransferOperator + * @covers \AtolOnline\Entities\MoneyTransferOperator::jsonSerialize + * @covers \AtolOnline\Entities\MoneyTransferOperator::setName + * @covers \AtolOnline\Entities\MoneyTransferOperator::getName + * @covers \AtolOnline\Entities\MoneyTransferOperator::setPhones + * @covers \AtolOnline\Entities\MoneyTransferOperator::getPhones + * @covers \AtolOnline\Entities\MoneyTransferOperator::setInn + * @covers \AtolOnline\Entities\MoneyTransferOperator::getInn + * @covers \AtolOnline\Entities\MoneyTransferOperator::setAddress + * @covers \AtolOnline\Entities\MoneyTransferOperator::getAddress + * @throws InvalidPhoneException + * @throws InvalidInnLengthException + */ + public function testConstructorWithArgs(): void + { + $this->assertAtolable(new MoneyTransferOperator('some name'), ['name' => 'some name']); + $this->assertAtolable(new MoneyTransferOperator(inn: '+fasd3\qe3fs_=nac99013928czc'), ['inn' => '3399013928']); + $this->assertAtolable(new MoneyTransferOperator(address: 'London'), ['address' => 'London']); + $this->assertAtolable(new MoneyTransferOperator(phones: ['+122997365456']), ['phones' => ['+122997365456']]); + $this->assertAtolable(new MoneyTransferOperator( + 'some name', + '+fasd3\qe3fs_=nac99013928czc', + 'London', + ['+122997365456'], + ), [ + 'name' => 'some name', + 'inn' => '3399013928', + 'address' => 'London', + 'phones' => ['+122997365456'], + ]); + } + + /** + * Тестирует установку имён, которые приводятся к null + * + * @param mixed $name + * @dataProvider providerNullableStrings + * @covers \AtolOnline\Entities\MoneyTransferOperator + * @covers \AtolOnline\Entities\MoneyTransferOperator::setName + * @covers \AtolOnline\Entities\MoneyTransferOperator::getName + * @throws InvalidPhoneException + * @throws InvalidInnLengthException + */ + public function testNullableOperations(mixed $name): void + { + $this->assertNull((new MoneyTransferOperator($name))->getName()); + } + + /** + * Провайдер массивов телефонов, которые приводятся к null + * + * @return array + */ + public function providerNullablePhonesArrays(): array + { + return [ + [[]], + [null], + [collect()], + ]; + } + + /** + * Тестирует установку пустых телефонов + * + * @dataProvider providerNullablePhonesArrays + * @covers \AtolOnline\Entities\MoneyTransferOperator + * @covers \AtolOnline\Entities\MoneyTransferOperator::setPhones + * @covers \AtolOnline\Entities\MoneyTransferOperator::getPhones + * @throws InvalidPhoneException + * @throws InvalidInnLengthException + */ + public function testNullablePhones(mixed $phones): void + { + $agent = new MoneyTransferOperator(phones: $phones); + $this->assertIsCollection($agent->getPhones()); + $this->assertTrue($agent->getPhones()->isEmpty()); + } + + /** + * Тестирует установку невалидных телефонов + * + * @covers \AtolOnline\Entities\MoneyTransferOperator + * @covers \AtolOnline\Entities\MoneyTransferOperator::setPhones + * @covers \AtolOnline\Exceptions\InvalidPhoneException + * @throws InvalidPhoneException + * @throws InvalidInnLengthException + */ + public function testInvalidPhoneException(): void + { + $this->expectException(InvalidPhoneException::class); + (new MoneyTransferOperator(phones: [ + '12345678901234567', // good + '+123456789012345678', // good + '12345678901234567890', // bad + '+12345678901234567890', // bad + ])); + } + + /** + * Тестирует исключение о корректной длине ИНН + * + * @covers \AtolOnline\Entities\MoneyTransferOperator + * @covers \AtolOnline\Entities\MoneyTransferOperator::setInn + * @covers \AtolOnline\Entities\MoneyTransferOperator::getInn + * @throws InvalidInnLengthException + */ + public function testValidInn(): void + { + $this->assertEquals('1234567890', (new MoneyTransferOperator())->setInn('1234567890')->getInn()); + $this->assertEquals('123456789012', (new MoneyTransferOperator())->setInn('123456789012')->getInn()); + } + + /** + * Тестирует исключение о некорректной длине ИНН (10 цифр) + * + * @covers \AtolOnline\Entities\MoneyTransferOperator + * @covers \AtolOnline\Entities\MoneyTransferOperator::setInn + * @covers \AtolOnline\Exceptions\InvalidInnLengthException + * @throws InvalidInnLengthException + */ + public function testInvalidInn10(): void + { + $this->expectException(InvalidInnLengthException::class); + (new MoneyTransferOperator())->setInn('12345678901'); + } + + /** + * Тестирует исключение о некорректной длине ИНН (12 цифр) + * + * @covers \AtolOnline\Entities\MoneyTransferOperator + * @covers \AtolOnline\Entities\MoneyTransferOperator::setInn + * @covers \AtolOnline\Exceptions\InvalidInnLengthException + * @throws InvalidInnLengthException + */ + public function testInvalidInn12(): void + { + $this->expectException(InvalidInnLengthException::class); + (new MoneyTransferOperator())->setInn('1234567890123'); + } +}