2021-12-06 12:07:17 +00:00
|
|
|
<?php
|
|
|
|
/*
|
|
|
|
* Copyright (c) 2020-2021 Антон Аксенов (Anthony Axenov)
|
|
|
|
*
|
|
|
|
* This code is licensed under MIT.
|
|
|
|
* Этот код распространяется по лицензии MIT.
|
|
|
|
* https://github.com/anthonyaxenov/atol-online/blob/master/LICENSE
|
|
|
|
*/
|
|
|
|
|
|
|
|
declare(strict_types = 1);
|
|
|
|
|
|
|
|
namespace AtolOnline\Entities;
|
|
|
|
|
|
|
|
use AtolOnline\Collections\Items;
|
|
|
|
use AtolOnline\Collections\Payments;
|
|
|
|
use AtolOnline\Collections\Vats;
|
|
|
|
use AtolOnline\Constants\Constraints;
|
2021-12-07 12:09:12 +00:00
|
|
|
use AtolOnline\Exceptions\EmptyItemsException;
|
|
|
|
use AtolOnline\Exceptions\InvalidEntityInCollectionException;
|
2021-12-06 12:07:17 +00:00
|
|
|
use AtolOnline\Exceptions\TooLongAddCheckPropException;
|
|
|
|
use AtolOnline\Exceptions\TooLongCashierException;
|
|
|
|
use Exception;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Класс, описывающий документ прихода, расхода, возврата прихода, возврата расхода
|
|
|
|
*
|
|
|
|
* @see https://online.atol.ru/files/API_atol_online_v4.pdf Документация, стр 17
|
|
|
|
*/
|
2021-12-11 07:53:57 +00:00
|
|
|
final class Receipt extends Entity
|
2021-12-06 12:07:17 +00:00
|
|
|
{
|
|
|
|
/**
|
|
|
|
* @var Client Покупатель
|
|
|
|
*/
|
|
|
|
protected Client $client;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @var Company Продавец
|
2021-12-11 07:53:57 +00:00
|
|
|
* @todo вынести в трейт
|
2021-12-06 12:07:17 +00:00
|
|
|
*/
|
|
|
|
protected Company $company;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @var AgentInfo|null Агент
|
|
|
|
*/
|
|
|
|
protected ?AgentInfo $agent_info = null;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @var Supplier|null Поставщик
|
|
|
|
*/
|
|
|
|
protected ?Supplier $supplier = null;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @var Items Коллекция предметов расчёта
|
|
|
|
*/
|
|
|
|
protected Items $items;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @var Payments Коллекция оплат
|
2021-12-11 07:53:57 +00:00
|
|
|
* @todo вынести в трейт
|
2021-12-06 12:07:17 +00:00
|
|
|
*/
|
|
|
|
protected Payments $payments;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @var Vats|null Коллекция ставок НДС
|
|
|
|
*/
|
|
|
|
protected ?Vats $vats = null;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @var float Итоговая сумма чека
|
|
|
|
*/
|
|
|
|
protected float $total = 0;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @var string|null ФИО кассира
|
2021-12-11 07:53:57 +00:00
|
|
|
* @todo вынести в трейт
|
2021-12-06 12:07:17 +00:00
|
|
|
*/
|
|
|
|
protected ?string $cashier = null;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @var string|null Дополнительный реквизит
|
|
|
|
*/
|
2021-12-07 12:09:12 +00:00
|
|
|
protected ?string $add_check_props = null;
|
2021-12-06 12:07:17 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @var AdditionalUserProps|null Дополнительный реквизит пользователя
|
|
|
|
*/
|
2021-12-07 12:09:12 +00:00
|
|
|
protected ?AdditionalUserProps $add_user_props = null;
|
2021-12-06 12:07:17 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Конструктор
|
2021-12-07 12:09:12 +00:00
|
|
|
*
|
|
|
|
* @param Client $client
|
|
|
|
* @param Company $company
|
|
|
|
* @param Items $items
|
|
|
|
* @param Payments $payments
|
|
|
|
* @throws EmptyItemsException
|
|
|
|
* @throws InvalidEntityInCollectionException
|
2021-12-06 12:07:17 +00:00
|
|
|
*/
|
2021-12-07 12:09:12 +00:00
|
|
|
public function __construct(Client $client, Company $company, Items $items, Payments $payments)
|
|
|
|
{
|
2021-12-06 12:07:17 +00:00
|
|
|
$this->setClient($client)->setCompany($company)->setItems($items)->setPayments($payments);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Возвращает установленного покупателя
|
|
|
|
*
|
|
|
|
* @return Client
|
|
|
|
*/
|
|
|
|
public function getClient(): Client
|
|
|
|
{
|
|
|
|
return $this->client;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Устанаваливает покупателя
|
|
|
|
*
|
|
|
|
* @param Client $client
|
2021-12-11 07:53:57 +00:00
|
|
|
* @return $this
|
2021-12-06 12:07:17 +00:00
|
|
|
*/
|
|
|
|
public function setClient(Client $client): self
|
|
|
|
{
|
|
|
|
$this->client = $client;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Возвращает установленного продавца
|
|
|
|
*
|
|
|
|
* @return Company
|
|
|
|
*/
|
|
|
|
public function getCompany(): Company
|
|
|
|
{
|
|
|
|
return $this->company;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Устанаваливает продавца
|
|
|
|
*
|
|
|
|
* @param Company $company
|
2021-12-11 07:53:57 +00:00
|
|
|
* @return $this
|
2021-12-06 12:07:17 +00:00
|
|
|
*/
|
|
|
|
public function setCompany(Company $company): self
|
|
|
|
{
|
|
|
|
$this->company = $company;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Возвращает установленного агента
|
|
|
|
*
|
2021-12-07 12:09:12 +00:00
|
|
|
* @return AgentInfo|null
|
2021-12-06 12:07:17 +00:00
|
|
|
*/
|
|
|
|
public function getAgentInfo(): ?AgentInfo
|
|
|
|
{
|
|
|
|
return $this->agent_info;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Устанаваливает агента
|
|
|
|
*
|
|
|
|
* @param AgentInfo|null $agent_info
|
2021-12-11 07:53:57 +00:00
|
|
|
* @return $this
|
2021-12-06 12:07:17 +00:00
|
|
|
*/
|
|
|
|
public function setAgentInfo(?AgentInfo $agent_info): self
|
|
|
|
{
|
|
|
|
$this->agent_info = $agent_info;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Поставщика
|
|
|
|
*
|
|
|
|
* @return Supplier|null
|
|
|
|
*/
|
|
|
|
public function getSupplier(): ?Supplier
|
|
|
|
{
|
|
|
|
return $this->supplier;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Поставщика
|
|
|
|
*
|
|
|
|
* @param Supplier|null $supplier
|
2021-12-11 07:53:57 +00:00
|
|
|
* @return $this
|
2021-12-06 12:07:17 +00:00
|
|
|
*/
|
|
|
|
public function setSupplier(?Supplier $supplier): self
|
|
|
|
{
|
|
|
|
$this->supplier = $supplier;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Возвращает установленную коллекцию предметов расчёта
|
|
|
|
*
|
|
|
|
* @return Items
|
|
|
|
*/
|
|
|
|
public function getItems(): Items
|
|
|
|
{
|
2021-12-08 08:01:25 +00:00
|
|
|
return $this->items ?? new Items();
|
2021-12-06 12:07:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Устанаваливает коллекцию предметов расчёта
|
|
|
|
*
|
|
|
|
* @param Items $items
|
2021-12-11 07:53:57 +00:00
|
|
|
* @return $this
|
2021-12-07 12:09:12 +00:00
|
|
|
* @throws EmptyItemsException
|
|
|
|
* @throws InvalidEntityInCollectionException
|
2021-12-08 08:01:25 +00:00
|
|
|
* @throws Exception
|
2021-12-11 07:53:57 +00:00
|
|
|
* @todo исключение при пустой коллекции
|
2021-12-06 12:07:17 +00:00
|
|
|
*/
|
|
|
|
public function setItems(Items $items): self
|
|
|
|
{
|
2021-12-09 12:13:43 +00:00
|
|
|
$items->checkCount();
|
2021-12-07 12:09:12 +00:00
|
|
|
$items->checkItemsClasses();
|
2021-12-06 12:07:17 +00:00
|
|
|
$this->items = $items;
|
2021-12-09 12:13:43 +00:00
|
|
|
$this->getItems()->each(fn($item) => $this->total += $item->getSum());
|
2021-12-08 08:01:25 +00:00
|
|
|
$this->total = round($this->total, 2);
|
2021-12-06 12:07:17 +00:00
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Возвращает установленную коллекцию оплат
|
|
|
|
*
|
|
|
|
* @return Payments
|
|
|
|
*/
|
|
|
|
public function getPayments(): Payments
|
|
|
|
{
|
|
|
|
return $this->payments;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Устанаваливает коллекцию оплат
|
|
|
|
*
|
|
|
|
* @param Payments $payments
|
2021-12-11 07:53:57 +00:00
|
|
|
* @return $this
|
2021-12-09 12:13:43 +00:00
|
|
|
* @throws InvalidEntityInCollectionException
|
2021-12-06 12:07:17 +00:00
|
|
|
*/
|
|
|
|
public function setPayments(Payments $payments): self
|
|
|
|
{
|
2021-12-09 12:13:43 +00:00
|
|
|
$payments->checkCount();
|
|
|
|
$payments->checkItemsClasses();
|
2021-12-06 12:07:17 +00:00
|
|
|
$this->payments = $payments;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Возвращает установленную коллекцию ставок НДС
|
|
|
|
*
|
|
|
|
* @return Vats|null
|
|
|
|
*/
|
|
|
|
public function getVats(): ?Vats
|
|
|
|
{
|
2021-12-08 08:01:25 +00:00
|
|
|
return $this->vats ?? new Vats();
|
2021-12-06 12:07:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Устанаваливает коллекцию ставок НДС
|
|
|
|
*
|
|
|
|
* @param Vats|null $vats
|
2021-12-11 07:53:57 +00:00
|
|
|
* @return $this
|
2021-12-08 08:01:25 +00:00
|
|
|
* @throws Exception
|
2021-12-06 12:07:17 +00:00
|
|
|
*/
|
|
|
|
public function setVats(?Vats $vats): self
|
|
|
|
{
|
2021-12-09 12:13:43 +00:00
|
|
|
$vats->checkCount();
|
|
|
|
$vats->checkItemsClasses();
|
2021-12-06 12:07:17 +00:00
|
|
|
$this->vats = $vats;
|
2021-12-08 08:01:25 +00:00
|
|
|
/** @var Vat $vat */
|
2021-12-09 12:13:43 +00:00
|
|
|
$this->getVats()->each(fn($vat) => $vat->setSum($this->getTotal()));
|
2021-12-06 12:07:17 +00:00
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Возвращает полную сумму чека
|
|
|
|
*
|
|
|
|
* @return float
|
|
|
|
*/
|
|
|
|
public function getTotal(): float
|
|
|
|
{
|
|
|
|
return $this->total;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Возвращает установленного кассира
|
|
|
|
*
|
|
|
|
* @return string|null
|
|
|
|
*/
|
|
|
|
public function getCashier(): ?string
|
|
|
|
{
|
|
|
|
return $this->cashier;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Устанаваливает кассира
|
|
|
|
*
|
|
|
|
* @param string|null $cashier
|
2021-12-11 07:53:57 +00:00
|
|
|
* @return $this
|
2021-12-06 12:07:17 +00:00
|
|
|
* @throws TooLongCashierException
|
|
|
|
*/
|
|
|
|
public function setCashier(?string $cashier): self
|
|
|
|
{
|
|
|
|
if (is_string($cashier)) {
|
|
|
|
$cashier = trim($cashier);
|
|
|
|
if (mb_strlen($cashier) > Constraints::MAX_LENGTH_CASHIER_NAME) {
|
|
|
|
throw new TooLongCashierException($cashier);
|
|
|
|
}
|
|
|
|
}
|
2021-12-07 12:09:12 +00:00
|
|
|
$this->cashier = $cashier ?: null;
|
2021-12-06 12:07:17 +00:00
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Возвращает установленный дополнительный реквизит чека
|
|
|
|
*
|
|
|
|
* @return string|null
|
|
|
|
*/
|
|
|
|
public function getAddCheckProps(): ?string
|
|
|
|
{
|
|
|
|
return $this->add_check_props;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Устанаваливает дополнительный реквизит чека
|
|
|
|
*
|
|
|
|
* @param string|null $add_check_props
|
2021-12-11 07:53:57 +00:00
|
|
|
* @return $this
|
2021-12-06 12:07:17 +00:00
|
|
|
* @throws TooLongAddCheckPropException
|
|
|
|
*/
|
|
|
|
public function setAddCheckProps(?string $add_check_props): self
|
|
|
|
{
|
|
|
|
if (is_string($add_check_props)) {
|
|
|
|
$add_check_props = trim($add_check_props);
|
|
|
|
if (mb_strlen($add_check_props) > Constraints::MAX_LENGTH_ADD_CHECK_PROP) {
|
|
|
|
throw new TooLongAddCheckPropException($add_check_props);
|
|
|
|
}
|
|
|
|
}
|
2021-12-08 11:04:14 +00:00
|
|
|
$this->add_check_props = $add_check_props ?: null;
|
2021-12-06 12:07:17 +00:00
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Возвращает установленный дополнительный реквизит пользователя
|
|
|
|
*
|
|
|
|
* @return AdditionalUserProps|null
|
|
|
|
*/
|
|
|
|
public function getAddUserProps(): ?AdditionalUserProps
|
|
|
|
{
|
|
|
|
return $this->add_user_props;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Устанаваливает дополнительный реквизит пользователя
|
|
|
|
*
|
|
|
|
* @param AdditionalUserProps|null $add_user_props
|
2021-12-11 07:53:57 +00:00
|
|
|
* @return $this
|
2021-12-06 12:07:17 +00:00
|
|
|
*/
|
|
|
|
public function setAddUserProps(?AdditionalUserProps $add_user_props): self
|
|
|
|
{
|
|
|
|
$this->add_user_props = $add_user_props;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Возвращает массив для кодирования в json
|
|
|
|
*
|
|
|
|
* @throws Exception
|
|
|
|
*/
|
|
|
|
public function jsonSerialize(): array
|
|
|
|
{
|
|
|
|
$json = [
|
|
|
|
'client' => $this->getClient(),
|
|
|
|
'company' => $this->getCompany(),
|
2021-12-09 12:13:43 +00:00
|
|
|
'items' => $this->getItems()->jsonSerialize(),
|
2021-12-06 12:07:17 +00:00
|
|
|
'total' => $this->getTotal(),
|
2021-12-09 12:13:43 +00:00
|
|
|
'payments' => $this->getPayments()->jsonSerialize(),
|
2021-12-06 12:07:17 +00:00
|
|
|
];
|
|
|
|
$this->getAgentInfo()?->jsonSerialize() && $json['agent_info'] = $this->getAgentInfo();
|
2021-12-08 08:01:25 +00:00
|
|
|
$this->getSupplier()?->jsonSerialize() && $json['supplier_info'] = $this->getSupplier();
|
2021-12-09 12:13:43 +00:00
|
|
|
$this->getVats()?->isNotEmpty() && $json['vats'] = $this->getVats();
|
2021-12-06 12:07:17 +00:00
|
|
|
!is_null($this->getAddCheckProps()) && $json['additional_check_props'] = $this->getAddCheckProps();
|
|
|
|
!is_null($this->getCashier()) && $json['cashier'] = $this->getCashier();
|
|
|
|
$this->getAddUserProps()?->jsonSerialize() && $json['additional_user_props'] = $this->getAddUserProps();
|
|
|
|
return $json;
|
|
|
|
}
|
|
|
|
}
|