diff --git a/src/Entities/Receipt.php b/src/Entities/Receipt.php index 8f1326b..dd9694f 100644 --- a/src/Entities/Receipt.php +++ b/src/Entities/Receipt.php @@ -15,7 +15,10 @@ use AtolOnline\Collections\Items; use AtolOnline\Collections\Payments; use AtolOnline\Collections\Vats; use AtolOnline\Constants\Constraints; -use AtolOnline\Exceptions\TooHighPriceException; +use AtolOnline\Exceptions\EmptyItemsException; +use AtolOnline\Exceptions\EmptyPaymentsException; +use AtolOnline\Exceptions\EmptyVatsException; +use AtolOnline\Exceptions\InvalidEntityInCollectionException; use AtolOnline\Exceptions\TooLongAddCheckPropException; use AtolOnline\Exceptions\TooLongCashierException; use Exception; @@ -75,22 +78,26 @@ class Receipt extends Entity /** * @var string|null Дополнительный реквизит */ - protected ?string $add_check_props; + protected ?string $add_check_props = null; /** * @var AdditionalUserProps|null Дополнительный реквизит пользователя */ - protected ?AdditionalUserProps $add_user_props; + protected ?AdditionalUserProps $add_user_props = null; /** * Конструктор + * + * @param Client $client + * @param Company $company + * @param Items $items + * @param Payments $payments + * @throws EmptyItemsException + * @throws EmptyPaymentsException + * @throws InvalidEntityInCollectionException */ - public function __construct( - Client $client, - Company $company, - Items $items, - Payments $payments, - ) { + public function __construct(Client $client, Company $company, Items $items, Payments $payments) + { $this->setClient($client)->setCompany($company)->setItems($items)->setPayments($payments); } @@ -141,7 +148,7 @@ class Receipt extends Entity /** * Возвращает установленного агента * - * @return AgentInfo + * @return AgentInfo|null */ public function getAgentInfo(): ?AgentInfo { @@ -198,9 +205,15 @@ class Receipt extends Entity * @todo исключение при пустой коллекции * @param Items $items * @return Receipt + * @throws EmptyItemsException + * @throws InvalidEntityInCollectionException */ public function setItems(Items $items): self { + if ($items->isEmpty()) { + throw new EmptyItemsException(); + } + $items->checkItemsClasses(); $this->items = $items; return $this; } @@ -218,12 +231,15 @@ class Receipt extends Entity /** * Устанаваливает коллекцию оплат * - * @todo исключение при пустой коллекции * @param Payments $payments * @return Receipt + * @throws EmptyPaymentsException */ public function setPayments(Payments $payments): self { + if ($payments->isEmpty()) { + throw new EmptyPaymentsException(); + } $this->payments = $payments; return $this; } @@ -243,9 +259,13 @@ class Receipt extends Entity * * @param Vats|null $vats * @return Receipt + * @throws EmptyVatsException */ public function setVats(?Vats $vats): self { + if ($vats->isEmpty()) { + throw new EmptyVatsException(); + } $this->vats = $vats; return $this; } @@ -297,7 +317,7 @@ class Receipt extends Entity throw new TooLongCashierException($cashier); } } - $this->cashier = empty($cashier) ? null : $cashier; + $this->cashier = $cashier ?: null; return $this; } @@ -364,7 +384,7 @@ class Receipt extends Entity 'company' => $this->getCompany(), 'items' => $this->getItems(), 'total' => $this->getTotal(), - 'payment' => $this->getPayments(), + 'payments' => $this->getPayments(), ]; $this->getAgentInfo()?->jsonSerialize() && $json['agent_info'] = $this->getAgentInfo(); $this->getSupplier()?->jsonSerialize() && $json['vats'] = $this->getVats(); diff --git a/src/Exceptions/EmptyItemsException.php b/src/Exceptions/EmptyItemsException.php new file mode 100644 index 0000000..771aee2 --- /dev/null +++ b/src/Exceptions/EmptyItemsException.php @@ -0,0 +1,22 @@ +validReceipt(); + $this->assertIsAtolable($receipt); + } + + /** + * Тестирует установку данных агента + * + * @return void + * @covers \AtolOnline\Entities\Receipt::setAgentInfo + * @covers \AtolOnline\Entities\Receipt::getAgentInfo + * @covers \AtolOnline\Entities\Receipt::jsonSerialize + * @throws EmptyItemNameException + * @throws EmptyItemsException + * @throws EmptyPaymentsException + * @throws InvalidEntityInCollectionException + * @throws InvalidEnumValueException + * @throws NegativeItemPriceException + * @throws NegativeItemQuantityException + * @throws NegativePaymentSumException + * @throws TooHighItemPriceException + * @throws TooHighPaymentSumException + * @throws TooLongItemNameException + * @throws TooManyException + * @throws InvalidInnLengthException + * @throws InvalidPhoneException + * @throws TooLongPayingAgentOperationException + * @throws Exception + */ + public function testSetAgentInfo(): void + { + $agent_info = new AgentInfo( + AgentTypes::ANOTHER, + new PayingAgent('test', ['+79518888888']), + new ReceivePaymentsOperator(['+79519999999']), + new MoneyTransferOperator('MTO Name', '9876543210', 'London', ['+79517777777']), + ); + $receipt = $this->validReceipt()->setAgentInfo($agent_info); + $this->assertArrayHasKey('agent_info', $receipt->jsonSerialize()); + $this->assertEquals($receipt->getAgentInfo(), $receipt->jsonSerialize()['agent_info']); + } + + /** + * Тестирует выброс исключения при передаче пустой коллекции предметов расчёта + * + * @return void + * @covers \AtolOnline\Entities\Receipt + * @covers \AtolOnline\Entities\Receipt::setVats + * @covers \AtolOnline\Collections\Items::checkCount + * @covers \AtolOnline\Exceptions\EmptyItemsException + * @throws InvalidEnumValueException + * @throws NegativePaymentSumException + * @throws TooHighPaymentSumException + * @throws InvalidEntityInCollectionException + * @throws EmptyPaymentsException + */ + public function testEmptyItemsException(): void + { + $this->expectException(EmptyItemsException::class); + new Receipt( + new Client('John Doe', 'john@example.com', '+1/22/99*73s dsdas654 5s6', '+fasd3\qe3fs_=nac99013928czc'), + new Company('company@example.com', SnoTypes::OSN, '1234567890', 'https://example.com'), + new Items([]), + new Payments($this->generatePaymentObjects()) + ); + } + + /** + * Тестирует выброс исключения при передаче коллекции предметов расчёта с некорректным содержимым + * + * @return void + * @covers \AtolOnline\Entities\Receipt + * @covers \AtolOnline\Entities\Receipt::setVats + * @covers \AtolOnline\Collections\Items::checkItemsClasses + * @covers \AtolOnline\Collections\Items::checkItemClass + * @covers \AtolOnline\Exceptions\InvalidEntityInCollectionException + * @throws EmptyItemsException + * @throws EmptyPaymentsException + * @throws InvalidEntityInCollectionException + * @throws InvalidEnumValueException + * @throws NegativePaymentSumException + * @throws TooHighPaymentSumException + */ + public function testInvalidItemInCollectionException(): void + { + $this->expectException(InvalidEntityInCollectionException::class); + $this->expectErrorMessage('Коллекция AtolOnline\Collections\Items должна содержать объекты AtolOnline\Entities\Item'); + new Receipt( + new Client('John Doe', 'john@example.com', '+1/22/99*73s dsdas654 5s6', '+fasd3\qe3fs_=nac99013928czc'), + new Company('company@example.com', SnoTypes::OSN, '1234567890', 'https://example.com'), + new Items(['qwerty']), + new Payments($this->generatePaymentObjects()) + ); + } + + /** + * Тестирует выброс исключения при передаче пустой коллекции оплат + * + * @return void + * @covers \AtolOnline\Entities\Receipt + * @covers \AtolOnline\Entities\Receipt::setPayments + * @covers \AtolOnline\Collections\Payments::checkCount + * @covers \AtolOnline\Exceptions\EmptyPaymentsException + * @throws TooHighPaymentSumException + * @throws EmptyItemNameException + * @throws NegativeItemPriceException + * @throws NegativeItemQuantityException + * @throws TooHighItemPriceException + * @throws TooLongItemNameException + * @throws TooManyException + * @throws InvalidEntityInCollectionException + * @throws EmptyItemsException + */ + public function testEmptyPaymentsException(): void + { + $this->expectException(EmptyPaymentsException::class); + new Receipt( + new Client('John Doe', 'john@example.com', '+1/22/99*73s dsdas654 5s6', '+fasd3\qe3fs_=nac99013928czc'), + new Company('company@example.com', SnoTypes::OSN, '1234567890', 'https://example.com'), + new Items([new Item('test item', 2, 3)]), + new Payments([]) + ); + } + + /** + * Тестирует выброс исключения при передаче коллекции предметов расчёта с некорректным содержимым + * + * @return void + * @covers \AtolOnline\Entities\Receipt + * @covers \AtolOnline\Entities\Receipt::setVats + * @covers \AtolOnline\Collections\Items::checkItemsClasses + * @covers \AtolOnline\Collections\Items::checkItemClass + * @covers \AtolOnline\Exceptions\InvalidEntityInCollectionException + * @throws EmptyItemNameException + * @throws EmptyItemsException + * @throws EmptyPaymentsException + * @throws InvalidEntityInCollectionException + * @throws NegativeItemPriceException + * @throws NegativeItemQuantityException + * @throws TooHighItemPriceException + * @throws TooLongItemNameException + * @throws TooManyException + */ + public function testInvalidPaymentInCollectionException(): void + { + $this->expectException(InvalidEntityInCollectionException::class); + $this->expectErrorMessage('Коллекция AtolOnline\Collections\Payments должна содержать объекты AtolOnline\Entities\Payment'); + new Receipt( + new Client('John Doe', 'john@example.com', '+1/22/99*73s dsdas654 5s6', '+fasd3\qe3fs_=nac99013928czc'), + new Company('company@example.com', SnoTypes::OSN, '1234567890', 'https://example.com'), + new Items([new Item('test item', 2, 3)]), + new Payments(['qwerty']) + ); + } + + /** + * Возвращает валидный тестовый объект чека + * + * @return Receipt + * @throws EmptyItemNameException + * @throws EmptyItemsException + * @throws EmptyPaymentsException + * @throws InvalidEntityInCollectionException + * @throws InvalidEnumValueException + * @throws NegativeItemPriceException + * @throws NegativeItemQuantityException + * @throws NegativePaymentSumException + * @throws TooHighItemPriceException + * @throws TooHighPaymentSumException + * @throws TooLongItemNameException + * @throws TooManyException + */ + protected function validReceipt(): Receipt + { + return new Receipt( + new Client('John Doe', 'john@example.com', '+1/22/99*73s dsdas654 5s6', '+fasd3\qe3fs_=nac99013928czc'), + new Company('company@example.com', SnoTypes::OSN, '1234567890', 'https://example.com'), + new Items($this->generateItemObjects()), + new Payments($this->generatePaymentObjects()) + ); + } +}