mirror of
https://github.com/anthonyaxenov/atol-online.git
synced 2024-11-22 09:14:34 +00:00
Переработан Vat
, покрыт тестами
This commit is contained in:
parent
e0ff5a261a
commit
a7205ff754
@ -12,78 +12,52 @@ declare(strict_types = 1);
|
|||||||
namespace AtolOnline\Entities;
|
namespace AtolOnline\Entities;
|
||||||
|
|
||||||
use AtolOnline\Enums\VatTypes;
|
use AtolOnline\Enums\VatTypes;
|
||||||
|
use AtolOnline\Helpers;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Класс, описывающий ставку НДС
|
* Класс, описывающий ставку НДС
|
||||||
*
|
*
|
||||||
* @package AtolOnline\Entities
|
* @see https://online.atol.ru/files/API_atol_online_v4.pdf Документация, стр 25, 31
|
||||||
*/
|
*/
|
||||||
class Vat extends Entity
|
class Vat extends Entity
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @var string Выбранный тип ставки НДС. Тег ФФД - 1199, 1105, 1104, 1103, 1102, 1107, 1106.
|
* @var string Тип ставки НДС (1199, 1105, 1104, 1103, 1102, 1107, 1106)
|
||||||
*/
|
*/
|
||||||
private string $type;
|
private string $type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var int Сумма в копейках, от которой пересчитывается размер НДС
|
* @var float Сумма в рублях, от которой пересчитывается размер НДС
|
||||||
*/
|
*/
|
||||||
private int $sum_original = 0;
|
private float $sum;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var int Сумма НДС в копейках
|
* Конструктор
|
||||||
*/
|
|
||||||
private int $sum_final = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Vat constructor.
|
|
||||||
*
|
*
|
||||||
* @param string $type Тип ставки НДС
|
* @param string $type Тип ставки НДС (1199, 1105, 1104, 1103, 1102, 1107, 1106)
|
||||||
* @param float|null $rubles Исходная сумма в рублях, от которой нужно расчитать размер НДС
|
* @param float $rubles Исходная сумма в рублях, от которой нужно расчитать размер НДС
|
||||||
*/
|
*/
|
||||||
public function __construct(string $type = VatTypes::NONE, float $rubles = null)
|
public function __construct(string $type, float $rubles)
|
||||||
{
|
{
|
||||||
$this->type = $type;
|
$this->setType($type)->setSum($rubles);
|
||||||
if ($rubles) {
|
|
||||||
$this->setSum($rubles);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Устанавливает:
|
* Устанавливает тип ставки НДС
|
||||||
* размер НДС от суммы в копейках
|
* Автоматически пересчитывает итоговый размер НДС от исходной суммы.
|
||||||
*
|
*
|
||||||
* @param string $type Тип ставки НДС
|
* @param string $type Тип ставки НДС
|
||||||
* @param int $kopeks Копейки
|
* @return $this
|
||||||
* @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)
|
public function setType(string $type): self
|
||||||
{
|
{
|
||||||
switch ($type) {
|
$type = trim($type);
|
||||||
case VatTypes::NONE:
|
VatTypes::isValid($type) && $this->type = $type;
|
||||||
case VatTypes::VAT0:
|
return $this;
|
||||||
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;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Возвращает тип ставки НДС. Тег ФФД - 1199, 1105, 1104, 1103, 1102, 1107, 1106.
|
* Возвращает тип ставки НДС
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
@ -93,27 +67,13 @@ class Vat extends Entity
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Устанавливает тип ставки НДС. Тег ФФД - 1199, 1105, 1104, 1103, 1102, 1107, 1106.
|
* Возвращает исходную сумму, от которой расчитывается размер налога
|
||||||
* Автоматически пересчитывает итоговый размер НДС от исходной суммы.
|
|
||||||
*
|
|
||||||
* @param string $type Тип ставки НДС
|
|
||||||
* @return $this
|
|
||||||
*/
|
|
||||||
public function setType(string $type): Vat
|
|
||||||
{
|
|
||||||
$this->type = $type;
|
|
||||||
$this->setFinal();
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Возвращает расчитанный итоговый размер ставки НДС в рублях. Тег ФФД - 1200.
|
|
||||||
*
|
*
|
||||||
* @return float
|
* @return float
|
||||||
*/
|
*/
|
||||||
public function getFinalSum(): float
|
public function getSum(): float
|
||||||
{
|
{
|
||||||
return rubles($this->sum_final);
|
return $this->sum;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -123,66 +83,54 @@ class Vat extends Entity
|
|||||||
* @param float $rubles Сумма в рублях за предмет расчёта, из которой высчитывается размер НДС
|
* @param float $rubles Сумма в рублях за предмет расчёта, из которой высчитывается размер НДС
|
||||||
* @return $this
|
* @return $this
|
||||||
*/
|
*/
|
||||||
public function setSum(float $rubles): Vat
|
public function setSum(float $rubles): self
|
||||||
{
|
{
|
||||||
$this->sum_original = kopeks($rubles);
|
$this->sum = $rubles;
|
||||||
$this->setFinal();
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Возвращает исходную сумму, от которой расчитывается размер налога
|
* Возвращает sdрасчитанный итоговый размер ставки НДС в рублях
|
||||||
*
|
*
|
||||||
* @return float
|
* @return float
|
||||||
|
* @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
|
||||||
*/
|
*/
|
||||||
public function getSum(): float
|
public function getCalculated(): float
|
||||||
{
|
{
|
||||||
return rubles($this->sum_original);
|
$kopeks = Helpers::toKop($this->sum);
|
||||||
|
return Helpers::toRub(match ($this->getType()) {
|
||||||
|
VatTypes::VAT10 => $kopeks * 10 / 100,
|
||||||
|
VatTypes::VAT18 => $kopeks * 18 / 100,
|
||||||
|
VatTypes::VAT20 => $kopeks * 20 / 100,
|
||||||
|
VatTypes::VAT110 => $kopeks * 10 / 110,
|
||||||
|
VatTypes::VAT118 => $kopeks * 18 / 118,
|
||||||
|
VatTypes::VAT120 => $kopeks * 20 / 120,
|
||||||
|
default => 0,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Прибавляет указанную сумму к общей исходной сумме.
|
* Прибавляет указанную сумму к исходной
|
||||||
* Автоматически пересчитывает итоговый размер НДС от новой исходной суммы.
|
|
||||||
*
|
*
|
||||||
* @param float $rubles
|
* @param float $rubles
|
||||||
* @return $this
|
* @return $this
|
||||||
*/
|
*/
|
||||||
public function addSum(float $rubles): Vat
|
public function addSum(float $rubles): self
|
||||||
{
|
{
|
||||||
$this->sum_original += kopeks($rubles);
|
$this->sum += $rubles;
|
||||||
$this->setFinal();
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Расчитывает и возвращает размер НДС от указанной суммы в рублях.
|
|
||||||
* Не изменяет итоговый размер НДС.
|
|
||||||
*
|
|
||||||
* @param float|null $rubles
|
|
||||||
* @return float
|
|
||||||
*/
|
|
||||||
public function calc(float $rubles): float
|
|
||||||
{
|
|
||||||
return rubles(self::calculator($this->type, kopeks($rubles)));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function jsonSerialize()
|
public function jsonSerialize(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'type' => $this->getType(),
|
'type' => $this->getType(),
|
||||||
'sum' => $this->getFinalSum(),
|
'sum' => $this->getCalculated(),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Расчитывает и устанавливает итоговый размер ставки от исходной суммы в копейках
|
|
||||||
*/
|
|
||||||
protected function setFinal(): Vat
|
|
||||||
{
|
|
||||||
$this->sum_final = self::calculator($this->type, $this->sum_original);
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -32,7 +32,7 @@ class ClientTest extends BasicTestCase
|
|||||||
*/
|
*/
|
||||||
public function testConstructorWithoutArgs(): void
|
public function testConstructorWithoutArgs(): void
|
||||||
{
|
{
|
||||||
$this->assertEquals('[]', (string)(new Client()));
|
$this->assertAtolable(new Client(), []);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
101
tests/AtolOnline/Tests/Entities/VatTest.php
Normal file
101
tests/AtolOnline/Tests/Entities/VatTest.php
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020-2021 Антон Аксенов (Anthony Axenov)
|
||||||
|
*
|
||||||
|
* This code is licensed under MIT.
|
||||||
|
* Этот код распространяется по лицензии MIT.
|
||||||
|
* https://github.com/anthonyaxenov/atol-online/blob/master/LICENSE
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace AtolOnline\Tests\Entities;
|
||||||
|
|
||||||
|
use AtolOnline\{
|
||||||
|
Entities\Vat,
|
||||||
|
Enums\VatTypes,
|
||||||
|
Tests\BasicTestCase
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Набор тестов для проверки работы класса ставки НДС
|
||||||
|
*/
|
||||||
|
class VatTest extends BasicTestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Провайдер данных для тестирования разных типов ставок НДС
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function providerVatsSet(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
[VatTypes::NONE, 0],
|
||||||
|
[VatTypes::VAT0, 0],
|
||||||
|
[VatTypes::VAT10, 10],
|
||||||
|
[VatTypes::VAT18, 18],
|
||||||
|
[VatTypes::VAT20, 20],
|
||||||
|
[VatTypes::VAT110, 9.09],
|
||||||
|
[VatTypes::VAT118, 15.25],
|
||||||
|
[VatTypes::VAT120, 16.67],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Провайдер данных для тестирования разных типов ставок НДС
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function providerVatsAdd(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
[VatTypes::VAT10, 12, 10],
|
||||||
|
[VatTypes::VAT18, 21.6, 18],
|
||||||
|
[VatTypes::VAT20, 24, 20],
|
||||||
|
[VatTypes::VAT110, 10.91, 9.09],
|
||||||
|
[VatTypes::VAT118, 18.31, 15.25],
|
||||||
|
[VatTypes::VAT120, 20, 16.67],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Тестирует конструктор без передачи значений и приведение к json
|
||||||
|
*
|
||||||
|
* @param string $type Тип НДС
|
||||||
|
* @param float $sum Исходная сумма
|
||||||
|
* @dataProvider providerVatsSet
|
||||||
|
* @covers \AtolOnline\Entities\Vat
|
||||||
|
* @covers \AtolOnline\Entities\Vat::setType
|
||||||
|
* @covers \AtolOnline\Entities\Vat::getType
|
||||||
|
* @covers \AtolOnline\Entities\Vat::setSum
|
||||||
|
* @covers \AtolOnline\Entities\Vat::getSum
|
||||||
|
* @covers \AtolOnline\Entities\Vat::getCalculated
|
||||||
|
* @covers \AtolOnline\Entities\Vat::jsonSerialize
|
||||||
|
*/
|
||||||
|
public function testConstructor(string $type, float $sum): void
|
||||||
|
{
|
||||||
|
$vat = new Vat($type, $sum);
|
||||||
|
$this->assertAtolable($vat, [
|
||||||
|
'type' => $vat->getType(),
|
||||||
|
'sum' => $vat->getCalculated(),
|
||||||
|
]);
|
||||||
|
$this->assertEquals($type, $vat->getType());
|
||||||
|
$this->assertEquals($sum, $vat->getSum());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Тестирует расчёт суммы НДС от исходной суммы 100+20р и 100-20р
|
||||||
|
*
|
||||||
|
* @dataProvider providerVatsAdd
|
||||||
|
* @param string $type Тип НДС
|
||||||
|
* @param float $after_plus Результат после +20р
|
||||||
|
* @param float $after_minus Результат после -20р
|
||||||
|
* @covers \AtolOnline\Entities\Vat::addSum
|
||||||
|
* @covers \AtolOnline\Entities\Vat::getCalculated
|
||||||
|
*/
|
||||||
|
public function testVatAdd(string $type, float $after_plus, float $after_minus)
|
||||||
|
{
|
||||||
|
$vat = (new Vat($type, 100))->addSum(20); // 120р
|
||||||
|
$this->assertEquals($after_plus, $vat->getCalculated());
|
||||||
|
$vat->addSum(-20); // 100р
|
||||||
|
$this->assertEquals($after_minus, $vat->getCalculated());
|
||||||
|
}
|
||||||
|
}
|
@ -84,11 +84,11 @@ class HelpersTest extends BasicTestCase
|
|||||||
* Тестирует перевод копеек в рубли
|
* Тестирует перевод копеек в рубли
|
||||||
*
|
*
|
||||||
* @dataProvider providerKopeksToRubles
|
* @dataProvider providerKopeksToRubles
|
||||||
* @covers \AtolOnline\Helpers::KopToRub
|
* @covers \AtolOnline\Helpers::toRub
|
||||||
*/
|
*/
|
||||||
public function testKopeksToRubles(?int $kopeks, float $rubles): void
|
public function testKopeksToRubles(?int $kopeks, float $rubles): void
|
||||||
{
|
{
|
||||||
$result = Helpers::KopToRub($kopeks);
|
$result = Helpers::toRub($kopeks);
|
||||||
$this->assertIsFloat($result);
|
$this->assertIsFloat($result);
|
||||||
$this->assertEquals($result, $rubles);
|
$this->assertEquals($result, $rubles);
|
||||||
}
|
}
|
||||||
@ -97,11 +97,11 @@ class HelpersTest extends BasicTestCase
|
|||||||
* Тестирует перевод копеек в рубли
|
* Тестирует перевод копеек в рубли
|
||||||
*
|
*
|
||||||
* @dataProvider providerRublesToKopeks
|
* @dataProvider providerRublesToKopeks
|
||||||
* @covers \AtolOnline\Helpers::RubToKop
|
* @covers \AtolOnline\Helpers::toKop
|
||||||
*/
|
*/
|
||||||
public function testRublesToKopeks(?float $rubles, int $kopeks): void
|
public function testRublesToKopeks(?float $rubles, int $kopeks): void
|
||||||
{
|
{
|
||||||
$result = Helpers::RubToKop($rubles);
|
$result = Helpers::toKop($rubles);
|
||||||
$this->assertIsInt($result);
|
$this->assertIsInt($result);
|
||||||
$this->assertEquals($result, $kopeks);
|
$this->assertEquals($result, $kopeks);
|
||||||
}
|
}
|
||||||
|
@ -1,55 +0,0 @@
|
|||||||
<?php
|
|
||||||
/*
|
|
||||||
* Copyright (c) 2020-2021 Антон Аксенов (Anthony Axenov)
|
|
||||||
*
|
|
||||||
* This code is licensed under MIT.
|
|
||||||
* Этот код распространяется по лицензии MIT.
|
|
||||||
* https://github.com/anthonyaxenov/atol-online/blob/master/LICENSE
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace AtolOnlineTests;
|
|
||||||
|
|
||||||
use AtolOnline\{
|
|
||||||
Entities\Vat,
|
|
||||||
Enums\VatTypes};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class VatTest
|
|
||||||
*/
|
|
||||||
class VatTestTodo extends BasicTestCase
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Тестирует каждый тип ставки НДС
|
|
||||||
*
|
|
||||||
* @dataProvider vatProvider
|
|
||||||
* @param string $vat_type Тип НДС
|
|
||||||
* @param float $sum Исходная сумма
|
|
||||||
* @param float $expected_set Ожидаемый результат после установки суммы
|
|
||||||
* @param float $expected_add Ожидаемый результат после прибавления 20р
|
|
||||||
*/
|
|
||||||
public function testVat(string $vat_type, float $sum, float $expected_set, float $expected_add)
|
|
||||||
{
|
|
||||||
$vat = new Vat($vat_type);
|
|
||||||
$this->assertEquals(0, $vat->getFinalSum(), 'Test ' . $vat_type . ' | 1 step');
|
|
||||||
$vat->setSum($sum);
|
|
||||||
$this->assertEquals($expected_set, $vat->getFinalSum(), 'Test ' . $vat_type . ' | 2 step');
|
|
||||||
$vat->addSum(20);
|
|
||||||
$this->assertEquals($expected_add, $vat->getFinalSum(), 'Test ' . $vat_type . ' | 3 step');
|
|
||||||
$vat->addSum(-20);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Провайдер данных для тестирования разных типов ставок НДС
|
|
||||||
*
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function vatProvider()
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
[VatTypes::NONE, 100, 0, 0],
|
|
||||||
[VatTypes::VAT0, 100, 0, 0],
|
|
||||||
[VatTypes::VAT10, 100, 9.09, 10.9],
|
|
||||||
[VatTypes::VAT18, 100, 15.25, 18.3],
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user