Initial commit, v0.1.0-b
This commit is contained in:
28
src/AtolOnline/Entities/AtolEntity.php
Normal file
28
src/AtolOnline/Entities/AtolEntity.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (c) Антон Аксенов (aka Anthony Axenov)
|
||||
*
|
||||
* This code is licensed under MIT.
|
||||
* Этот код распространяется по лицензии MIT.
|
||||
* https://github.com/anthonyaxenov/atol-online/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
namespace AtolOnline\Entities;
|
||||
|
||||
use JsonSerializable;
|
||||
|
||||
/**
|
||||
* Абстрактное описание любой сущности, представляемой как JSON
|
||||
*
|
||||
* @package AtolOnline\Entities
|
||||
*/
|
||||
abstract class AtolEntity implements JsonSerializable
|
||||
{
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return json_encode($this->jsonSerialize(), JSON_UNESCAPED_UNICODE);
|
||||
}
|
||||
}
|
||||
149
src/AtolOnline/Entities/Client.php
Normal file
149
src/AtolOnline/Entities/Client.php
Normal file
@@ -0,0 +1,149 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (c) Антон Аксенов (aka Anthony Axenov)
|
||||
*
|
||||
* This code is licensed under MIT.
|
||||
* Этот код распространяется по лицензии MIT.
|
||||
* https://github.com/anthonyaxenov/atol-online/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
namespace AtolOnline\Entities;
|
||||
|
||||
use AtolOnline\{Exceptions\AtolNameTooLongException, Exceptions\AtolPhoneTooLongException, Traits\HasEmail, Traits\HasInn};
|
||||
|
||||
/**
|
||||
* Класс Client, описывающий сущность покупателя
|
||||
*
|
||||
* @package AtolOnline\Entities
|
||||
*/
|
||||
class Client extends AtolEntity
|
||||
{
|
||||
use
|
||||
/**
|
||||
* Покупатель может иметь почту. Тег ФФД - 1008.
|
||||
*/
|
||||
HasEmail,
|
||||
|
||||
/**
|
||||
* Покупатель может иметь ИНН. Тег ФФД - 1228.
|
||||
*/
|
||||
HasInn;
|
||||
|
||||
/**
|
||||
* @var string Телефон покупателя. Тег ФФД - 1008.
|
||||
*/
|
||||
protected $phone;
|
||||
|
||||
/**
|
||||
* @var string Имя покупателя. Тег ФФД - 1227.
|
||||
*/
|
||||
protected $name;
|
||||
|
||||
/**
|
||||
* Client constructor.
|
||||
*
|
||||
* @param string|null $name Наименование
|
||||
* @param string|null $phone Телефон
|
||||
* @param string|null $email Email
|
||||
* @param string|null $inn ИНН
|
||||
* @throws \AtolOnline\Exceptions\AtolEmailTooLongException
|
||||
* @throws \AtolOnline\Exceptions\AtolEmailValidateException
|
||||
* @throws \AtolOnline\Exceptions\AtolInnWrongLengthException
|
||||
* @throws \AtolOnline\Exceptions\AtolNameTooLongException
|
||||
* @throws \AtolOnline\Exceptions\AtolPhoneTooLongException
|
||||
*/
|
||||
public function __construct(?string $name = null, ?string $phone = null, ?string $email = null, ?string $inn = null)
|
||||
{
|
||||
if ($name) {
|
||||
$this->setName($name);
|
||||
}
|
||||
if ($email) {
|
||||
$this->setEmail($email);
|
||||
}
|
||||
if ($phone) {
|
||||
$this->setPhone($phone);
|
||||
}
|
||||
if ($inn) {
|
||||
$this->setInn($inn);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Возвращает имя покупателя. Тег ФФД - 1227.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Устанавливает имя покупателя
|
||||
* Тег ФФД - 1227.
|
||||
*
|
||||
* @param string $name
|
||||
* @return $this
|
||||
* @throws AtolNameTooLongException
|
||||
*/
|
||||
public function setName(string $name)
|
||||
{
|
||||
$name = trim($name);
|
||||
if (strlen($name) > 256) {
|
||||
throw new AtolNameTooLongException($name, 256);
|
||||
}
|
||||
$this->name = $name;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Возвращает телефон покупателя.
|
||||
* Тег ФФД - 1008.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getPhone()
|
||||
{
|
||||
return $this->phone ?? '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Устанавливает телефон покупателя.
|
||||
* Тег ФФД - 1008.
|
||||
* Входная строка лишается всех знаков, кроме цифр и знака '+'.
|
||||
*
|
||||
* @param string $phone
|
||||
* @return $this
|
||||
* @throws AtolPhoneTooLongException
|
||||
*/
|
||||
public function setPhone(string $phone)
|
||||
{
|
||||
$phone = preg_replace("/[^0-9+]/", '', $phone);
|
||||
if (strlen($phone) > 64) {
|
||||
throw new AtolPhoneTooLongException($phone, 64);
|
||||
}
|
||||
$this->phone = $phone;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function jsonSerialize()
|
||||
{
|
||||
$json = [];
|
||||
if ($this->getName()) {
|
||||
$json['name'] = $this->getName() ?? '';
|
||||
}
|
||||
if ($this->getEmail()) {
|
||||
$json['email'] = $this->getEmail() ?? '';
|
||||
}
|
||||
if ($this->getPhone()) {
|
||||
$json['phone'] = $this->getPhone() ?? '';
|
||||
}
|
||||
if ($this->getInn()) {
|
||||
$json['inn'] = $this->getInn() ?? '';
|
||||
}
|
||||
return $json;
|
||||
}
|
||||
}
|
||||
137
src/AtolOnline/Entities/Company.php
Normal file
137
src/AtolOnline/Entities/Company.php
Normal file
@@ -0,0 +1,137 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (c) Антон Аксенов (aka Anthony Axenov)
|
||||
*
|
||||
* This code is licensed under MIT.
|
||||
* Этот код распространяется по лицензии MIT.
|
||||
* https://github.com/anthonyaxenov/atol-online/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
namespace AtolOnline\Entities;
|
||||
|
||||
use AtolOnline\{Exceptions\AtolEmailTooLongException,
|
||||
Exceptions\AtolEmailValidateException,
|
||||
Exceptions\AtolInnWrongLengthException,
|
||||
Exceptions\AtolPaymentAddressTooLongException,
|
||||
Traits\HasEmail,
|
||||
Traits\HasInn
|
||||
};
|
||||
|
||||
/**
|
||||
* Класс, описывающий сущность компании-продавца
|
||||
*
|
||||
* @package AtolOnline\Entities
|
||||
*/
|
||||
class Company extends AtolEntity
|
||||
{
|
||||
use
|
||||
/**
|
||||
* Продавец должен иметь почту. Тег ФФД - 1117.
|
||||
*/
|
||||
HasEmail,
|
||||
|
||||
/**
|
||||
* Продавец должен иметь ИНН. Тег ФФД - 1018.
|
||||
*/
|
||||
HasInn;
|
||||
|
||||
/**
|
||||
* @var string Система налогообложения продавца. Тег ФФД - 1055.
|
||||
*/
|
||||
protected $sno;
|
||||
|
||||
/**
|
||||
* @var string Место расчётов (адрес интернет-магазина). Тег ФФД - 1187.
|
||||
*/
|
||||
protected $payment_address;
|
||||
|
||||
/**
|
||||
* Company constructor.
|
||||
*
|
||||
* @param string|null $sno
|
||||
* @param string|null $inn
|
||||
* @param string|null $paymentAddress
|
||||
* @param string|null $email
|
||||
* @throws AtolEmailTooLongException
|
||||
* @throws AtolEmailValidateException
|
||||
* @throws AtolInnWrongLengthException
|
||||
* @throws AtolPaymentAddressTooLongException
|
||||
*/
|
||||
public function __construct(string $sno = null, string $inn = null, string $paymentAddress = null, string $email = null)
|
||||
{
|
||||
if ($sno) {
|
||||
$this->setSno($sno);
|
||||
}
|
||||
if ($inn) {
|
||||
$this->setInn($inn);
|
||||
}
|
||||
if ($paymentAddress) {
|
||||
$this->setPaymentAddress($paymentAddress);
|
||||
}
|
||||
if ($email) {
|
||||
$this->setEmail($email);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Возвращает установленный тип налогообложения. Тег ФФД - 1055.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getSno()
|
||||
{
|
||||
return $this->sno;
|
||||
}
|
||||
|
||||
/**
|
||||
* Устанавливает тип налогообложения. Тег ФФД - 1055.
|
||||
*
|
||||
* @param string $sno
|
||||
* @return $this
|
||||
*/
|
||||
public function setSno(string $sno)
|
||||
{
|
||||
$this->sno = trim($sno);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Возвращает установленный адрес места расчётов. Тег ФФД - 1187.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getPaymentAddress()
|
||||
{
|
||||
return $this->payment_address;
|
||||
}
|
||||
|
||||
/**
|
||||
* Устанавливает адрес места расчётов. Тег ФФД - 1187.
|
||||
*
|
||||
* @param string $payment_address
|
||||
* @return $this
|
||||
* @throws AtolPaymentAddressTooLongException
|
||||
*/
|
||||
public function setPaymentAddress(string $payment_address)
|
||||
{
|
||||
$payment_address = trim($payment_address);
|
||||
if (strlen($payment_address) > 256) {
|
||||
throw new AtolPaymentAddressTooLongException($payment_address, 256);
|
||||
}
|
||||
$this->payment_address = $payment_address;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function jsonSerialize()
|
||||
{
|
||||
return [
|
||||
'email' => $this->getEmail(),
|
||||
'sno' => $this->getSno(),
|
||||
'inn' => $this->getInn(),
|
||||
'payment_address' => $this->getPaymentAddress(),
|
||||
];
|
||||
}
|
||||
}
|
||||
171
src/AtolOnline/Entities/CorrectionInfo.php
Normal file
171
src/AtolOnline/Entities/CorrectionInfo.php
Normal file
@@ -0,0 +1,171 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (c) Антон Аксенов (aka Anthony Axenov)
|
||||
*
|
||||
* This code is licensed under MIT.
|
||||
* Этот код распространяется по лицензии MIT.
|
||||
* https://github.com/anthonyaxenov/atol-online/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
namespace AtolOnline\Entities;
|
||||
|
||||
/**
|
||||
* Класс CorrectionInfo, описывающий данные коррекции
|
||||
*
|
||||
* @package AtolOnline\Entities
|
||||
*/
|
||||
class CorrectionInfo extends AtolEntity
|
||||
{
|
||||
/**
|
||||
* @var int Тип коррекции. Тег ФФД - 1173.
|
||||
*/
|
||||
protected $type;
|
||||
|
||||
/**
|
||||
* @var string Дата документа основания для коррекции. Тег ФФД - 1178.
|
||||
*/
|
||||
protected $base_date;
|
||||
|
||||
/**
|
||||
* @var string Номер документа основания для коррекции. Тег ФФД - 1179.
|
||||
*/
|
||||
protected $base_number;
|
||||
|
||||
/**
|
||||
* @var string Описание коррекции. Тег ФФД - 1177.
|
||||
*/
|
||||
protected $base_name;
|
||||
|
||||
/**
|
||||
* CorrectionInfo constructor.
|
||||
*
|
||||
* @param string|null $type Тип коррекции
|
||||
* @param string|null $base_date Дата документа
|
||||
* @param string|null $base_number Номер документа
|
||||
* @param string|null $base_name Описание коррекции
|
||||
*/
|
||||
public function __construct(?string $type = null, ?string $base_date = null, ?string $base_number = null, ?string $base_name = null)
|
||||
{
|
||||
if ($type) {
|
||||
$this->setType($type);
|
||||
}
|
||||
if ($base_date) {
|
||||
$this->setDate($base_date);
|
||||
}
|
||||
if ($base_number) {
|
||||
$this->setNumber($base_number);
|
||||
}
|
||||
if ($base_name) {
|
||||
$this->setName($base_name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Возвращает номер документа основания для коррекции.
|
||||
* Тег ФФД - 1179.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getNumber(): ?string
|
||||
{
|
||||
return $this->base_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Устанавливает номер документа основания для коррекции.
|
||||
* Тег ФФД - 1179.
|
||||
*
|
||||
* @param string $number
|
||||
* @return $this
|
||||
*/
|
||||
public function setNumber(string $number)
|
||||
{
|
||||
$this->base_number = trim($number);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Возвращает описание коррекции.
|
||||
* Тег ФФД - 1177.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getName(): ?string
|
||||
{
|
||||
return $this->base_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Устанавливает описание коррекции.
|
||||
* Тег ФФД - 1177.
|
||||
*
|
||||
* @param string $name
|
||||
* @return $this
|
||||
*/
|
||||
public function setName(string $name)
|
||||
{
|
||||
$this->base_name = trim($name);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Возвращает дату документа основания для коррекции.
|
||||
* Тег ФФД - 1178.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getDate(): ?string
|
||||
{
|
||||
return $this->base_date;
|
||||
}
|
||||
|
||||
/**
|
||||
* Устанавливает дату документа основания для коррекции.
|
||||
* Тег ФФД - 1178.
|
||||
*
|
||||
* @param string $date Строка в формате d.m.Y
|
||||
* @return $this
|
||||
*/
|
||||
public function setDate(string $date)
|
||||
{
|
||||
$this->base_date = $date;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Возвращает тип коррекции.
|
||||
* Тег ФФД - 1173.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getType(): ?string
|
||||
{
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Устанавливает тип коррекции.
|
||||
* Тег ФФД - 1173.
|
||||
*
|
||||
* @param string $type
|
||||
* @return $this
|
||||
*/
|
||||
public function setType(string $type)
|
||||
{
|
||||
$this->type = $type;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function jsonSerialize()
|
||||
{
|
||||
return [
|
||||
'type' => $this->getType() ?? '', // обязателен
|
||||
'base_date' => $this->getDate() ?? '', // обязателен
|
||||
'base_number' => $this->getNumber() ?? '', // обязателен
|
||||
'base_name' => $this->getName() ?? '' // обязателен
|
||||
];
|
||||
}
|
||||
}
|
||||
354
src/AtolOnline/Entities/Document.php
Normal file
354
src/AtolOnline/Entities/Document.php
Normal file
@@ -0,0 +1,354 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (c) Антон Аксенов (aka Anthony Axenov)
|
||||
*
|
||||
* This code is licensed under MIT.
|
||||
* Этот код распространяется по лицензии MIT.
|
||||
* https://github.com/anthonyaxenov/atol-online/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
namespace AtolOnline\Entities;
|
||||
|
||||
use AtolOnline\Exceptions\AtolCashierTooLongException;
|
||||
|
||||
/**
|
||||
* Класс, описывающий документ
|
||||
*
|
||||
* @package AtolOnline\Entities
|
||||
*/
|
||||
class Document extends AtolEntity
|
||||
{
|
||||
/**
|
||||
* @var \AtolOnline\Entities\ItemArray Массив предметов расчёта
|
||||
*/
|
||||
protected $items;
|
||||
|
||||
/**
|
||||
* @var \AtolOnline\Entities\VatArray Массив ставок НДС
|
||||
*/
|
||||
protected $vats;
|
||||
|
||||
/**
|
||||
* @var \AtolOnline\Entities\PaymentArray Массив оплат
|
||||
*/
|
||||
protected $payments;
|
||||
|
||||
/**
|
||||
* @var \AtolOnline\Entities\Company Объект компании (продавца)
|
||||
*/
|
||||
protected $company;
|
||||
|
||||
/**
|
||||
* @var \AtolOnline\Entities\Client Объект клиента (покупателя)
|
||||
*/
|
||||
protected $client;
|
||||
|
||||
/**
|
||||
* @var int Итоговая сумма чека. Тег ФФД - 1020.
|
||||
*/
|
||||
protected $total = 0;
|
||||
|
||||
/**
|
||||
* @var string ФИО кассира. Тег ФФД - 1021.
|
||||
*/
|
||||
protected $cashier;
|
||||
|
||||
/**
|
||||
* @var \AtolOnline\Entities\CorrectionInfo Данные коррекции
|
||||
*/
|
||||
protected $correction_info;
|
||||
|
||||
/**
|
||||
* Document constructor.
|
||||
*
|
||||
* @throws \AtolOnline\Exceptions\AtolTooManyItemsException Слишком много предметов расчёта
|
||||
* @throws \AtolOnline\Exceptions\AtolTooManyPaymentsException Слишком много оплат
|
||||
* @throws \AtolOnline\Exceptions\AtolTooManyVatsException Слишком много ставок НДС
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->vats = new VatArray();
|
||||
$this->payments = new PaymentArray();
|
||||
$this->items = new ItemArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Удаляет все налоги из документа и предметов расчёта
|
||||
*
|
||||
* @return $this
|
||||
* @throws \AtolOnline\Exceptions\AtolPriceTooHighException Слишком большая сумма
|
||||
* @throws \AtolOnline\Exceptions\AtolTooManyVatsException Слишком много ставок НДС
|
||||
*/
|
||||
public function clearVats()
|
||||
{
|
||||
$this->setVats([]);
|
||||
foreach ($this->getItems() as &$item) {
|
||||
$item->setVatType(null);
|
||||
}
|
||||
$this->calcTotal();
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Добавляет новую ставку НДС в массив ставок НДС
|
||||
*
|
||||
* @param \AtolOnline\Entities\Vat $vat Объект ставки НДС
|
||||
* @return $this
|
||||
* @throws \AtolOnline\Exceptions\AtolTooManyVatsException Слишком много ставок НДС
|
||||
*/
|
||||
public function addVat(Vat $vat)
|
||||
{
|
||||
if (count($this->getVats()) == 0 && !$vat->getSum()) {
|
||||
$vat->setSum($this->calcTotal());
|
||||
}
|
||||
$this->vats->add($vat);
|
||||
$this->calcTotal();
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Возвращает массив ставок НДС
|
||||
*
|
||||
* @return \AtolOnline\Entities\Vat[]
|
||||
*/
|
||||
public function getVats(): array
|
||||
{
|
||||
return $this->vats->get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Устанавливает массив ставок НДС
|
||||
*
|
||||
* @param \AtolOnline\Entities\Vat[] $vats Массив ставок НДС
|
||||
* @return $this
|
||||
* @throws \AtolOnline\Exceptions\AtolTooManyVatsException Слишком много ставок НДС
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function setVats(array $vats)
|
||||
{
|
||||
$this->vats->set($vats);
|
||||
$this->calcTotal();
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Добавляет новую оплату в массив оплат
|
||||
*
|
||||
* @param \AtolOnline\Entities\Payment $payment Объект оплаты
|
||||
* @return $this
|
||||
* @throws \Exception
|
||||
* @throws \AtolOnline\Exceptions\AtolTooManyPaymentsException Слишком много оплат
|
||||
*/
|
||||
public function addPayment(Payment $payment)
|
||||
{
|
||||
if (count($this->getPayments()) == 0 && !$payment->getSum()) {
|
||||
$payment->setSum($this->calcTotal());
|
||||
}
|
||||
$this->payments->add($payment);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Возвращает массив оплат
|
||||
*
|
||||
* @return \AtolOnline\Entities\Payment[]
|
||||
*/
|
||||
public function getPayments(): array
|
||||
{
|
||||
return $this->payments->get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Устанавливает массив оплат
|
||||
*
|
||||
* @param \AtolOnline\Entities\Payment[] $payments Массив оплат
|
||||
* @return $this
|
||||
* @throws \AtolOnline\Exceptions\AtolTooManyPaymentsException Слишком много оплат
|
||||
*/
|
||||
public function setPayments(array $payments)
|
||||
{
|
||||
$this->payments->set($payments);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Добавляет новый предмет расчёта в массив предметов расчёта
|
||||
*
|
||||
* @param \AtolOnline\Entities\Item $item Объект предмета расчёта
|
||||
* @return $this
|
||||
* @throws \AtolOnline\Exceptions\AtolTooManyItemsException Слишком много предметов расчёта
|
||||
*/
|
||||
public function addItem(Item $item)
|
||||
{
|
||||
$this->items->add($item);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Возвращает массив предметов расчёта
|
||||
*
|
||||
* @return \AtolOnline\Entities\Item[]
|
||||
*/
|
||||
public function getItems(): array
|
||||
{
|
||||
return $this->items->get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Устанавливает массив предметов расчёта
|
||||
*
|
||||
* @param \AtolOnline\Entities\Item[] $items Массив предметов расчёта
|
||||
* @return $this
|
||||
* @throws \AtolOnline\Exceptions\AtolTooManyItemsException Слишком много предметов расчёта
|
||||
*/
|
||||
public function setItems(array $items)
|
||||
{
|
||||
$this->items->set($items);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Возвращает заданного клиента (покупателя)
|
||||
*
|
||||
* @return Client
|
||||
*/
|
||||
public function getClient(): Client
|
||||
{
|
||||
return $this->client;
|
||||
}
|
||||
|
||||
/**
|
||||
* Устанавливает клиента (покупателя)
|
||||
*
|
||||
* @param Client|null $client
|
||||
* @return $this
|
||||
*/
|
||||
public function setClient(?Client $client)
|
||||
{
|
||||
$this->client = $client;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Возвращает заданную компанию (продавца)
|
||||
*
|
||||
* @return Company
|
||||
*/
|
||||
public function getCompany(): Company
|
||||
{
|
||||
return $this->company;
|
||||
}
|
||||
|
||||
/**
|
||||
* Устанавливает компанию (продавца)
|
||||
*
|
||||
* @param Company|null $company
|
||||
* @return $this
|
||||
*/
|
||||
public function setCompany(?Company $company)
|
||||
{
|
||||
$this->company = $company;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Возвращает ФИО кассира. Тег ФФД - 1021.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getCashier(): ?string
|
||||
{
|
||||
return $this->cashier;
|
||||
}
|
||||
|
||||
/**
|
||||
* Устанавливает ФИО кассира. Тег ФФД - 1021.
|
||||
*
|
||||
* @param string|null $cashier
|
||||
* @return $this
|
||||
* @throws \AtolOnline\Exceptions\AtolCashierTooLongException
|
||||
*/
|
||||
public function setCashier(?string $cashier)
|
||||
{
|
||||
$cashier = trim($cashier);
|
||||
if (strlen($cashier) > 64) {
|
||||
throw new AtolCashierTooLongException($cashier);
|
||||
}
|
||||
$this->cashier = $cashier;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Возвращает данные коррекции
|
||||
*
|
||||
* @return \AtolOnline\Entities\CorrectionInfo|null
|
||||
*/
|
||||
public function getCorrectionInfo(): ?CorrectionInfo
|
||||
{
|
||||
return $this->correction_info;
|
||||
}
|
||||
|
||||
/**
|
||||
* Устанавливает данные коррекции
|
||||
*
|
||||
* @param \AtolOnline\Entities\CorrectionInfo|null $correction_info
|
||||
* @return $this
|
||||
*/
|
||||
public function setCorrectionInfo(?CorrectionInfo $correction_info)
|
||||
{
|
||||
$this->correction_info = $correction_info;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Пересчитывает, сохраняет и возвращает итоговую сумму чека по всем позициям (включая НДС). Тег ФФД - 1020.
|
||||
*
|
||||
* @return float
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function calcTotal()
|
||||
{
|
||||
$sum = 0;
|
||||
foreach ($this->items->get() as $item) {
|
||||
$sum += $item->calcSum();
|
||||
}
|
||||
foreach ($this->vats->get() as $vat) {
|
||||
$vat->setSum($sum);
|
||||
}
|
||||
return $this->total = round($sum, 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Возвращает итоговую сумму чека. Тег ФФД - 1020.
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public function getTotal(): float
|
||||
{
|
||||
return $this->total;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function jsonSerialize()
|
||||
{
|
||||
$json = [
|
||||
'company' => $this->getCompany()->jsonSerialize(), // обязательно
|
||||
'payments' => $this->payments->jsonSerialize(), // обязательно
|
||||
'cashier' => $this->getCashier() ?? '',
|
||||
];
|
||||
if ($this->getCorrectionInfo()) {
|
||||
$json['correction_info'] = $this->getCorrectionInfo()->jsonSerialize(); // обязательно для коррекционных
|
||||
} else {
|
||||
$json['client'] = $this->getClient()->jsonSerialize(); // обязательно для некоррекционных
|
||||
$json['items'] = $this->items->jsonSerialize(); // обязательно для некоррекционных
|
||||
$json['total'] = $this->calcTotal(); // обязательно для некоррекционных
|
||||
}
|
||||
if ($this->getVats()) {
|
||||
$json['vats'] = $this->vats->jsonSerialize();
|
||||
}
|
||||
return $json;
|
||||
}
|
||||
}
|
||||
396
src/AtolOnline/Entities/Item.php
Normal file
396
src/AtolOnline/Entities/Item.php
Normal file
@@ -0,0 +1,396 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (c) Антон Аксенов (aka Anthony Axenov)
|
||||
*
|
||||
* This code is licensed under MIT.
|
||||
* Этот код распространяется по лицензии MIT.
|
||||
* https://github.com/anthonyaxenov/atol-online/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
namespace AtolOnline\Entities;
|
||||
|
||||
use AtolOnline\{Exceptions\AtolNameTooLongException,
|
||||
Exceptions\AtolPriceTooHighException,
|
||||
Exceptions\AtolQuantityTooHighException,
|
||||
Exceptions\AtolUnitTooLongException,
|
||||
Exceptions\AtolUserdataTooLongException,
|
||||
Traits\RublesKopeksConverter
|
||||
};
|
||||
|
||||
/**
|
||||
* Предмет расчёта (товар, услуга)
|
||||
*
|
||||
* @package AtolOnline\Entities
|
||||
*/
|
||||
class Item extends AtolEntity
|
||||
{
|
||||
use RublesKopeksConverter;
|
||||
|
||||
/**
|
||||
* @var string Наименование. Тег ФФД - 1030.
|
||||
*/
|
||||
protected $name;
|
||||
|
||||
/**
|
||||
* @var int Цена в копейках (с учётом скидок и наценок). Тег ФФД - 1079.
|
||||
*/
|
||||
protected $price = 0;
|
||||
|
||||
/**
|
||||
* @var float Количество, вес. Тег ФФД - 1023.
|
||||
*/
|
||||
protected $quantity = 0.0;
|
||||
|
||||
/**
|
||||
* @var float Сумма в копейках. Тег ФФД - 1043.
|
||||
*/
|
||||
protected $sum = 0;
|
||||
|
||||
/**
|
||||
* @var string Единица измерения количества. Тег ФФД - 1197.
|
||||
*/
|
||||
protected $measurement_unit;
|
||||
|
||||
/**
|
||||
* @var Vat Ставка НДС
|
||||
*/
|
||||
protected $vat;
|
||||
|
||||
/**
|
||||
* @var string Признак способа расчёта. Тег ФФД - 1214.
|
||||
*/
|
||||
protected $payment_method;
|
||||
|
||||
/**
|
||||
* @var string Признак объекта расчёта. Тег ФФД - 1212.
|
||||
*/
|
||||
protected $payment_object;
|
||||
|
||||
/**
|
||||
* @var string Дополнительный реквизит. Тег ФФД - 1191.
|
||||
*/
|
||||
protected $user_data;
|
||||
|
||||
/**
|
||||
* Item constructor.
|
||||
*
|
||||
* @param string|null $name Наименование
|
||||
* @param float|null $price Цена за одну единицу
|
||||
* @param float|null $quantity Количество
|
||||
* @param string|null $measurement_unit Единица измерения
|
||||
* @param string|null $vat_type Ставка НДС
|
||||
* @param string|null $payment_object Признак
|
||||
* @param string|null $payment_method Способ расчёта
|
||||
* @throws AtolNameTooLongException Слишком длинное наименование
|
||||
* @throws AtolPriceTooHighException Слишком высокая цена за одну единицу
|
||||
* @throws AtolQuantityTooHighException Слишком большое количество
|
||||
* @throws AtolUnitTooLongException Слишком длинное название единицы измерения
|
||||
*/
|
||||
public function __construct(
|
||||
?string $name = null,
|
||||
?float $price = null,
|
||||
?float $quantity = null,
|
||||
?string $measurement_unit = null,
|
||||
$vat_type = null,
|
||||
?string $payment_object = null,
|
||||
?string $payment_method = null
|
||||
) {
|
||||
if ($name) {
|
||||
$this->setName($name);
|
||||
}
|
||||
if ($price) {
|
||||
$this->setPrice($price);
|
||||
}
|
||||
if ($payment_object) {
|
||||
$this->setPaymentObject($payment_object);
|
||||
}
|
||||
if ($quantity) {
|
||||
$this->setQuantity($quantity);
|
||||
}
|
||||
if ($vat_type) {
|
||||
$this->setVatType($vat_type);
|
||||
}
|
||||
if ($measurement_unit) {
|
||||
$this->setMeasurementUnit($measurement_unit);
|
||||
}
|
||||
if ($payment_method) {
|
||||
$this->setPaymentMethod($payment_method);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Возвращает наименование. Тег ФФД - 1030.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Устаналивает наименование. Тег ФФД - 1030.
|
||||
*
|
||||
* @param string $name Наименование
|
||||
* @return $this
|
||||
* @throws AtolNameTooLongException Слишком длинное имя/наименование
|
||||
*/
|
||||
public function setName(string $name)
|
||||
{
|
||||
$name = trim($name);
|
||||
if (strlen($name) > 128) {
|
||||
throw new AtolNameTooLongException($name, 128);
|
||||
}
|
||||
$this->name = $name;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Возвращает цену в рублях. Тег ФФД - 1079.
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public function getPrice()
|
||||
{
|
||||
return self::toRub($this->price);
|
||||
}
|
||||
|
||||
/**
|
||||
* Устанавливает цену в рублях. Тег ФФД - 1079.
|
||||
*
|
||||
* @param float $rubles Цена за одну единицу в рублях
|
||||
* @return $this
|
||||
* @throws AtolPriceTooHighException Слишком высокая цена за одну единицу
|
||||
*/
|
||||
public function setPrice(float $rubles)
|
||||
{
|
||||
if ($rubles > 42949672.95) {
|
||||
throw new AtolPriceTooHighException($rubles, 42949672.95);
|
||||
}
|
||||
$this->price = self::toKop($rubles);
|
||||
$this->calcSum();
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Возвращает количество. Тег ФФД - 1023.
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public function getQuantity(): float
|
||||
{
|
||||
return $this->quantity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Устанавливает количество. Тег ФФД - 1023.
|
||||
*
|
||||
* @param float $quantity Количество
|
||||
* @param string|null $measurement_unit Единица измерения количества
|
||||
* @return $this
|
||||
* @throws AtolQuantityTooHighException Слишком большое количество
|
||||
* @throws AtolPriceTooHighException Слишком высокая общая стоимость
|
||||
* @throws AtolUnitTooLongException Слишком длинное название единицы измерения
|
||||
*/
|
||||
public function setQuantity(float $quantity, string $measurement_unit = null)
|
||||
{
|
||||
$quantity = round($quantity, 3);
|
||||
if ($quantity > 99999.999) {
|
||||
throw new AtolQuantityTooHighException($quantity, 99999.999);
|
||||
}
|
||||
$this->quantity = $quantity;
|
||||
$this->calcSum();
|
||||
if ($measurement_unit) {
|
||||
$this->setMeasurementUnit($measurement_unit);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Возвращает заданную единицу измерения количества. Тег ФФД - 1197.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getMeasurementUnit(): string
|
||||
{
|
||||
return $this->measurement_unit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Устанавливает единицу измерения количества. Тег ФФД - 1197.
|
||||
*
|
||||
* @param string $measurement_unit Единица измерения количества
|
||||
* @return $this
|
||||
* @throws AtolUnitTooLongException Слишком длинное название единицы измерения
|
||||
*/
|
||||
public function setMeasurementUnit(string $measurement_unit)
|
||||
{
|
||||
$measurement_unit = trim($measurement_unit);
|
||||
if (strlen($measurement_unit) > 16) {
|
||||
throw new AtolUnitTooLongException($measurement_unit, 16);
|
||||
}
|
||||
$this->measurement_unit = $measurement_unit;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Возвращает признак способа оплаты. Тег ФФД - 1214.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getPaymentMethod(): string
|
||||
{
|
||||
return $this->payment_method;
|
||||
}
|
||||
|
||||
/**
|
||||
* Устанавливает признак способа оплаты. Тег ФФД - 1214.
|
||||
*
|
||||
* @param string $payment_method Признак способа оплаты
|
||||
* @return $this
|
||||
* @todo Проверка допустимых значений
|
||||
*/
|
||||
public function setPaymentMethod(string $payment_method)
|
||||
{
|
||||
$this->payment_method = trim($payment_method);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Возвращает признак предмета расчёта. Тег ФФД - 1212.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getPaymentObject(): string
|
||||
{
|
||||
return $this->payment_object;
|
||||
}
|
||||
|
||||
/**
|
||||
* Устанавливает признак предмета расчёта. Тег ФФД - 1212.
|
||||
*
|
||||
* @param string $payment_object Признак предмета расчёта
|
||||
* @return $this
|
||||
* @todo Проверка допустимых значений
|
||||
*/
|
||||
public function setPaymentObject(string $payment_object)
|
||||
{
|
||||
$this->payment_object = trim($payment_object);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Возвращает ставку НДС
|
||||
*
|
||||
* @return \AtolOnline\Entities\Vat|null
|
||||
*/
|
||||
public function getVat(): ?Vat
|
||||
{
|
||||
return $this->vat;
|
||||
}
|
||||
|
||||
/**
|
||||
* Устанавливает ставку НДС
|
||||
*
|
||||
* @param string|null $vat_type Тип ставки НДС. Передать null, чтобы удалить ставку.
|
||||
* @return $this
|
||||
* @throws \AtolOnline\Exceptions\AtolPriceTooHighException
|
||||
*/
|
||||
public function setVatType(?string $vat_type)
|
||||
{
|
||||
if ($vat_type) {
|
||||
$this->vat
|
||||
? $this->vat->setType($vat_type)
|
||||
: $this->vat = new Vat($vat_type);
|
||||
} else {
|
||||
$this->vat = null;
|
||||
}
|
||||
$this->calcSum();
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Возвращает дополнительный реквизит. Тег ФФД - 1191.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getUserData(): ?string
|
||||
{
|
||||
return $this->user_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Устанавливает дополнительный реквизит. Тег ФФД - 1191.
|
||||
*
|
||||
* @param string $user_data Дополнительный реквизит. Тег ФФД - 1191.
|
||||
* @return $this
|
||||
* @throws AtolUserdataTooLongException Слишком длинный дополнительный реквизит
|
||||
*/
|
||||
public function setUserData(string $user_data)
|
||||
{
|
||||
$user_data = trim($user_data);
|
||||
if (strlen($user_data) > 64) {
|
||||
throw new AtolUserdataTooLongException($user_data, 64);
|
||||
}
|
||||
$this->user_data = $user_data;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Возвращает стоимость. Тег ФФД - 1043.
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public function getSum(): float
|
||||
{
|
||||
return self::toRub($this->sum);
|
||||
}
|
||||
|
||||
/**
|
||||
* Расчитывает стоимость и размер НДС на неё
|
||||
*
|
||||
* @return float
|
||||
* @throws AtolPriceTooHighException Слишком большая сумма
|
||||
*/
|
||||
public function calcSum()
|
||||
{
|
||||
$sum = $this->quantity * $this->price;
|
||||
if (self::toRub($sum) > 42949672.95) {
|
||||
throw new AtolPriceTooHighException($sum, 42949672.95);
|
||||
}
|
||||
$this->sum = $sum;
|
||||
if ($this->vat) {
|
||||
$this->vat->setSum(self::toRub($sum));
|
||||
}
|
||||
return $this->getSum();
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function jsonSerialize()
|
||||
{
|
||||
$json = [
|
||||
'name' => $this->getName(), // обязательно
|
||||
'price' => $this->getPrice(), // обязательно
|
||||
'quantity' => $this->getQuantity(), // обязательно
|
||||
'sum' => $this->getSum(), // обязательно
|
||||
'measurement_unit' => $this->getMeasurementUnit(),
|
||||
'payment_method' => $this->getPaymentMethod(),
|
||||
'payment_object' => $this->getPaymentObject()
|
||||
//TODO nomenclature_code
|
||||
//TODO agent_info
|
||||
//TODO supplier_info
|
||||
//TODO excise
|
||||
//TODO country_code
|
||||
//TODO declaration_number
|
||||
];
|
||||
if ($this->getVat()) {
|
||||
$json['vat'] = $this->getVat()->jsonSerialize();
|
||||
}
|
||||
if ($this->getUserData()) {
|
||||
$json['user_data'] = $this->getUserData();
|
||||
}
|
||||
return $json;
|
||||
}
|
||||
}
|
||||
111
src/AtolOnline/Entities/ItemArray.php
Normal file
111
src/AtolOnline/Entities/ItemArray.php
Normal file
@@ -0,0 +1,111 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (c) Антон Аксенов (aka Anthony Axenov)
|
||||
*
|
||||
* This code is licensed under MIT.
|
||||
* Этот код распространяется по лицензии MIT.
|
||||
* https://github.com/anthonyaxenov/atol-online/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
namespace AtolOnline\Entities;
|
||||
|
||||
use AtolOnline\Exceptions\AtolTooManyItemsException;
|
||||
|
||||
/**
|
||||
* Класс, описывающий массив предметов расчёта
|
||||
*
|
||||
* @package AtolOnline\Entities
|
||||
*/
|
||||
class ItemArray extends AtolEntity
|
||||
{
|
||||
/**
|
||||
* Максимальное количество элементов в массиве
|
||||
*/
|
||||
const MAX_COUNT = 100;
|
||||
|
||||
/**
|
||||
* @var \AtolOnline\Entities\Item[] Массив предметов расчёта
|
||||
*/
|
||||
private $items = [];
|
||||
|
||||
/**
|
||||
* ItemArray constructor.
|
||||
*
|
||||
* @param \AtolOnline\Entities\Item[]|null $items Массив предметов расчёта
|
||||
* @throws \AtolOnline\Exceptions\AtolTooManyItemsException Слишком много предметов расчёта
|
||||
*/
|
||||
public function __construct(array $items = null)
|
||||
{
|
||||
if ($items) {
|
||||
$this->set($items);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Устанавливает массив предметов расчёта
|
||||
*
|
||||
* @param \AtolOnline\Entities\Item[] $items Массив предметов расчёта
|
||||
* @return $this
|
||||
* @throws \AtolOnline\Exceptions\AtolTooManyItemsException Слишком много предметов расчёта
|
||||
*/
|
||||
public function set(array $items)
|
||||
{
|
||||
if ($this->validateCount($items)) {
|
||||
$this->items = $items;
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Добавляет предмет расчёта в массив
|
||||
*
|
||||
* @param \AtolOnline\Entities\Item $item Объект предмета расчёта
|
||||
* @return $this
|
||||
* @throws \AtolOnline\Exceptions\AtolTooManyItemsException Слишком много предметов расчёта
|
||||
*/
|
||||
public function add(Item $item)
|
||||
{
|
||||
if ($this->validateCount()) {
|
||||
$this->items[] = $item;
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Возвращает массив предметов расчёта
|
||||
*
|
||||
* @return \AtolOnline\Entities\Item[]
|
||||
*/
|
||||
public function get()
|
||||
{
|
||||
return $this->items;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function jsonSerialize()
|
||||
{
|
||||
$result = [];
|
||||
foreach ($this->get() as $item) {
|
||||
$result[] = $item->jsonSerialize();
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Проверяет количество элементов в массиве
|
||||
*
|
||||
* @param array|null $items Если передать массив, то проверит количество его элементов.
|
||||
* Иначе проверит количество уже присвоенных элементов.
|
||||
* @return bool
|
||||
* @throws \AtolOnline\Exceptions\AtolTooManyItemsException Слишком много предметов расчёта
|
||||
*/
|
||||
protected function validateCount(array $items = null)
|
||||
{
|
||||
if (($items && is_array($items) && count($items) >= self::MAX_COUNT) || count($this->items) == self::MAX_COUNT) {
|
||||
throw new AtolTooManyItemsException(self::MAX_COUNT);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
97
src/AtolOnline/Entities/Payment.php
Normal file
97
src/AtolOnline/Entities/Payment.php
Normal file
@@ -0,0 +1,97 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (c) Антон Аксенов (aka Anthony Axenov)
|
||||
*
|
||||
* This code is licensed under MIT.
|
||||
* Этот код распространяется по лицензии MIT.
|
||||
* https://github.com/anthonyaxenov/atol-online/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
namespace AtolOnline\Entities;
|
||||
|
||||
use AtolOnline\Constants\PaymentTypes;
|
||||
|
||||
/**
|
||||
* Класс, описывающий оплату. Тег ФФД - 1031, 1081, 1215, 1216, 1217.
|
||||
*
|
||||
* @package AtolOnline\Entities
|
||||
*/
|
||||
class Payment extends AtolEntity
|
||||
{
|
||||
/**
|
||||
* @var int Тип оплаты
|
||||
*/
|
||||
protected $type;
|
||||
|
||||
/**
|
||||
* @var float Сумма оплаты
|
||||
*/
|
||||
protected $sum;
|
||||
|
||||
/**
|
||||
* Payment constructor.
|
||||
*
|
||||
* @param int $payment_type Тип оплаты
|
||||
* @param float $sum Сумма оплаты
|
||||
*/
|
||||
public function __construct(int $payment_type = PaymentTypes::ELECTRON, float $sum = 0.0)
|
||||
{
|
||||
$this->setType($payment_type);
|
||||
$this->setSum($sum);
|
||||
}
|
||||
|
||||
/**
|
||||
* Возвращает тип оплаты. Тег ФФД - 1031, 1081, 1215, 1216, 1217.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getType(): int
|
||||
{
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Устанавливает тип оплаты. Тег ФФД - 1031, 1081, 1215, 1216, 1217.
|
||||
*
|
||||
* @param int $type
|
||||
* @return $this
|
||||
*/
|
||||
public function setType(int $type)
|
||||
{
|
||||
$this->type = $type;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Возвращает сумму оплаты
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public function getSum(): float
|
||||
{
|
||||
return $this->sum;
|
||||
}
|
||||
|
||||
/**
|
||||
* Устанавливает сумму оплаты
|
||||
*
|
||||
* @param float $sum
|
||||
* @return $this
|
||||
*/
|
||||
public function setSum(float $sum)
|
||||
{
|
||||
$this->sum = $sum;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function jsonSerialize()
|
||||
{
|
||||
return [
|
||||
'type' => $this->getType(),
|
||||
'sum' => $this->getSum(),
|
||||
];
|
||||
}
|
||||
}
|
||||
111
src/AtolOnline/Entities/PaymentArray.php
Normal file
111
src/AtolOnline/Entities/PaymentArray.php
Normal file
@@ -0,0 +1,111 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (c) Антон Аксенов (aka Anthony Axenov)
|
||||
*
|
||||
* This code is licensed under MIT.
|
||||
* Этот код распространяется по лицензии MIT.
|
||||
* https://github.com/anthonyaxenov/atol-online/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
namespace AtolOnline\Entities;
|
||||
|
||||
use AtolOnline\Exceptions\AtolTooManyPaymentsException;
|
||||
|
||||
/**
|
||||
* Класс, описывающий массив оплат
|
||||
*
|
||||
* @package AtolOnline\Entities
|
||||
*/
|
||||
class PaymentArray extends AtolEntity
|
||||
{
|
||||
/**
|
||||
* Максимальное количество элементов в массиве
|
||||
*/
|
||||
const MAX_COUNT = 10;
|
||||
|
||||
/**
|
||||
* @var Payment[] Массив оплат
|
||||
*/
|
||||
private $payments = [];
|
||||
|
||||
/**
|
||||
* ItemArray constructor.
|
||||
*
|
||||
* @param Payment[]|null $payments Массив оплат
|
||||
* @throws AtolTooManyPaymentsException Слишком много оплат
|
||||
*/
|
||||
public function __construct(array $payments = null)
|
||||
{
|
||||
if ($payments) {
|
||||
$this->set($payments);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Устанавливает массив оплат
|
||||
*
|
||||
* @param Payment[] $payments
|
||||
* @return $this
|
||||
* @throws AtolTooManyPaymentsException Слишком много оплат
|
||||
*/
|
||||
public function set(array $payments)
|
||||
{
|
||||
if ($this->validateCount($payments)) {
|
||||
$this->payments = $payments;
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Добавляет новую оплату к заданным
|
||||
*
|
||||
* @param Payment $payment Объект оплаты
|
||||
* @return $this
|
||||
* @throws AtolTooManyPaymentsException Слишком много оплат
|
||||
*/
|
||||
public function add(Payment $payment)
|
||||
{
|
||||
if ($this->validateCount()) {
|
||||
$this->payments[] = $payment;
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Возвращает массив оплат
|
||||
*
|
||||
* @return Payment[]
|
||||
*/
|
||||
public function get()
|
||||
{
|
||||
return $this->payments;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function jsonSerialize()
|
||||
{
|
||||
$result = [];
|
||||
foreach ($this->get() as $payment) {
|
||||
$result[] = $payment->jsonSerialize();
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Проверяет количество элементов в массиве
|
||||
*
|
||||
* @param Payment[]|null $payments Если передать массив, то проверит количество его элементов.
|
||||
* Иначе проверит количество уже присвоенных элементов.
|
||||
* @return bool
|
||||
* @throws AtolTooManyPaymentsException Слишком много оплат
|
||||
*/
|
||||
protected function validateCount(array $payments = null)
|
||||
{
|
||||
if (($payments && is_array($payments) && count($payments) >= self::MAX_COUNT) || count($this->payments) == self::MAX_COUNT) {
|
||||
throw new AtolTooManyPaymentsException(self::MAX_COUNT);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
186
src/AtolOnline/Entities/Vat.php
Normal file
186
src/AtolOnline/Entities/Vat.php
Normal file
@@ -0,0 +1,186 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (c) Антон Аксенов (aka Anthony Axenov)
|
||||
*
|
||||
* This code is licensed under MIT.
|
||||
* Этот код распространяется по лицензии MIT.
|
||||
* https://github.com/anthonyaxenov/atol-online/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
namespace AtolOnline\Entities;
|
||||
|
||||
use AtolOnline\{Constants\VatTypes, Traits\RublesKopeksConverter};
|
||||
|
||||
/**
|
||||
* Класс, описывающий ставку НДС
|
||||
*
|
||||
* @package AtolOnline\Entities
|
||||
*/
|
||||
class Vat extends AtolEntity
|
||||
{
|
||||
use RublesKopeksConverter;
|
||||
|
||||
/**
|
||||
* @var string Выбранный тип ставки НДС. Тег ФФД - 1199, 1105, 1104, 1103, 1102, 1107, 1106.
|
||||
*/
|
||||
private $type;
|
||||
|
||||
/**
|
||||
* @var int Сумма в копейках, от которой пересчитывается размер налога
|
||||
*/
|
||||
private $sum_original = 0;
|
||||
|
||||
/**
|
||||
* @var int Сумма налога в копейках
|
||||
*/
|
||||
private $sum_final = 0;
|
||||
|
||||
/**
|
||||
* Vat constructor.
|
||||
*
|
||||
* @param string $type Тип ставки НДС
|
||||
* @param float|null $rubles Исходная сумма в рублях, от которой нужно расчитать размер НДС
|
||||
*/
|
||||
public function __construct(string $type = VatTypes::NONE, float $rubles = null)
|
||||
{
|
||||
$this->type = $type;
|
||||
if ($rubles) {
|
||||
$this->setSum($rubles);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Устанавливает размер НДС от суммы в копейках
|
||||
*
|
||||
* @param string $type Тип ставки НДС
|
||||
* @param int $kopeks Копейки
|
||||
* @return float|int
|
||||
* @see https://nalog-nalog.ru/nds/nalogovaya_baza_nds/kak-schitat-nds-pravilno-vychislyaem-20-ot-summy-primer-algoritm/
|
||||
* @see https://glavkniga.ru/situations/k500734
|
||||
* @see https://www.b-kontur.ru/nds-kalkuljator-online
|
||||
*/
|
||||
protected static function calculator(string $type, int $kopeks)
|
||||
{
|
||||
switch ($type) {
|
||||
case VatTypes::NONE:
|
||||
case VatTypes::VAT0:
|
||||
return 0;
|
||||
case VatTypes::VAT10:
|
||||
return $kopeks * 10 / 100;
|
||||
case VatTypes::VAT110:
|
||||
return $kopeks * 10 / 110;
|
||||
case VatTypes::VAT18:
|
||||
return $kopeks * 18 / 100;
|
||||
case VatTypes::VAT118:
|
||||
return $kopeks * 18 / 118;
|
||||
case VatTypes::VAT20:
|
||||
return $kopeks * 20 / 100;
|
||||
case VatTypes::VAT120:
|
||||
return $kopeks * 20 / 120;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Возвращает тип ставки НДС. Тег ФФД - 1199, 1105, 1104, 1103, 1102, 1107, 1106.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getType(): string
|
||||
{
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Устанавливает тип ставки НДС. Тег ФФД - 1199, 1105, 1104, 1103, 1102, 1107, 1106.
|
||||
* Автоматически пересчитывает итоговый размер НДС от исходной суммы.
|
||||
*
|
||||
* @param string $type Тип ставки НДС
|
||||
* @return $this
|
||||
*/
|
||||
public function setType(string $type)
|
||||
{
|
||||
$this->type = $type;
|
||||
$this->setFinal();
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Возвращает расчитанный итоговый размер ставки НДС в рублях. Тег ФФД - 1200.
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public function getFinalSum()
|
||||
{
|
||||
return self::toRub($this->sum_final);
|
||||
}
|
||||
|
||||
/**
|
||||
* Устанавливает исходную сумму, от которой будет расчитываться итоговый размер НДС.
|
||||
* Автоматически пересчитывает итоговый размер НДС от исходной суммы.
|
||||
*
|
||||
* @param float $rubles Сумма в рублях за предмет расчёта, из которой высчитывается размер НДС
|
||||
* @return $this
|
||||
*/
|
||||
public function setSum(float $rubles)
|
||||
{
|
||||
$this->sum_original = self::toKop($rubles);
|
||||
$this->setFinal();
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Возвращает исходную сумму, от которой расчитывается размер налога
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public function getSum(): float
|
||||
{
|
||||
return self::toRub($this->sum_original);
|
||||
}
|
||||
|
||||
/**
|
||||
* Прибавляет указанную сумму к общей исходной сумме.
|
||||
* Автоматически пересчитывает итоговый размер НДС от новой исходной суммы.
|
||||
*
|
||||
* @param float $rubles
|
||||
* @return $this
|
||||
*/
|
||||
public function addSum(float $rubles)
|
||||
{
|
||||
$this->sum_original += self::toKop($rubles);
|
||||
$this->setFinal();
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Расчитывает и возвращает размер НДС от указанной суммы в рублях.
|
||||
* Не изменяет итоговый размер НДС.
|
||||
*
|
||||
* @param float|null $rubles
|
||||
* @return float
|
||||
*/
|
||||
public function calc(float $rubles): float
|
||||
{
|
||||
return self::toRub(self::calculator($this->type, self::toKop($rubles)));
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function jsonSerialize()
|
||||
{
|
||||
return [
|
||||
'type' => $this->getType(),
|
||||
'sum' => $this->getFinalSum(),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Расчитывает и устанавливает итоговый размер ставки от исходной суммы в копейках
|
||||
*/
|
||||
protected function setFinal()
|
||||
{
|
||||
$this->sum_final = self::calculator($this->type, $this->sum_original);
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
111
src/AtolOnline/Entities/VatArray.php
Normal file
111
src/AtolOnline/Entities/VatArray.php
Normal file
@@ -0,0 +1,111 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (c) Антон Аксенов (aka Anthony Axenov)
|
||||
*
|
||||
* This code is licensed under MIT.
|
||||
* Этот код распространяется по лицензии MIT.
|
||||
* https://github.com/anthonyaxenov/atol-online/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
namespace AtolOnline\Entities;
|
||||
|
||||
use AtolOnline\Exceptions\AtolTooManyVatsException;
|
||||
|
||||
/**
|
||||
* Класс, описывающий массив ставок НДС
|
||||
*
|
||||
* @package AtolOnline\Entities
|
||||
*/
|
||||
class VatArray extends AtolEntity
|
||||
{
|
||||
/**
|
||||
* Максимальное количество элементов в массиве
|
||||
*/
|
||||
public const MAX_COUNT = 6;
|
||||
|
||||
/**
|
||||
* @var Vat[] Массив ставок НДС
|
||||
*/
|
||||
private $vats = [];
|
||||
|
||||
/**
|
||||
* VatArray constructor.
|
||||
*
|
||||
* @param Vat[]|null $vats Массив ставок НДС
|
||||
* @throws AtolTooManyVatsException Слишком много ставок НДС
|
||||
*/
|
||||
public function __construct(array $vats = null)
|
||||
{
|
||||
if ($vats) {
|
||||
$this->set($vats);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Устанавливает массив ставок НДС
|
||||
*
|
||||
* @param Vat[] $vats Массив ставок НДС
|
||||
* @return $this
|
||||
* @throws AtolTooManyVatsException Слишком много ставок НДС
|
||||
*/
|
||||
public function set(array $vats)
|
||||
{
|
||||
if ($this->validateCount($vats)) {
|
||||
$this->vats = $vats;
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Добавляет новую ставку НДС в массив
|
||||
*
|
||||
* @param Vat $vat Объект ставки НДС
|
||||
* @return $this
|
||||
* @throws AtolTooManyVatsException Слишком много ставок НДС
|
||||
*/
|
||||
public function add(Vat $vat)
|
||||
{
|
||||
if ($this->validateCount()) {
|
||||
$this->vats[] = $vat;
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Возвращает массив ставок НДС
|
||||
*
|
||||
* @return Vat[]
|
||||
*/
|
||||
public function get()
|
||||
{
|
||||
return $this->vats;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function jsonSerialize()
|
||||
{
|
||||
$result = [];
|
||||
foreach ($this->get() as $vat) {
|
||||
$result[] = $vat->jsonSerialize();
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Проверяет количество элементов в массиве
|
||||
*
|
||||
* @param array|null $vats Если передать массив, то проверит количество его элементов.
|
||||
* Иначе проверит количество уже присвоенных элементов.
|
||||
* @return bool
|
||||
* @throws AtolTooManyVatsException Слишком много ставок НДС
|
||||
*/
|
||||
protected function validateCount(array $vats = null)
|
||||
{
|
||||
if (($vats && is_array($vats) && count($vats) >= self::MAX_COUNT) || count($this->vats) == self::MAX_COUNT) {
|
||||
throw new AtolTooManyVatsException(self::MAX_COUNT);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user