Переработан Vat, покрыт тестами

This commit is contained in:
Anthony Axenov 2021-11-28 00:58:05 +08:00
parent e0ff5a261a
commit a7205ff754
5 changed files with 174 additions and 180 deletions

View File

@ -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
*/ */
@ -91,45 +65,7 @@ class Vat extends Entity
{ {
return $this->type; return $this->type;
} }
/**
* Устанавливает тип ставки НДС. Тег ФФД - 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
*/
public function getFinalSum(): float
{
return rubles($this->sum_final);
}
/**
* Устанавливает исходную сумму, от которой будет расчитываться итоговый размер НДС.
* Автоматически пересчитывает итоговый размер НДС от исходной суммы.
*
* @param float $rubles Сумма в рублях за предмет расчёта, из которой высчитывается размер НДС
* @return $this
*/
public function setSum(float $rubles): Vat
{
$this->sum_original = kopeks($rubles);
$this->setFinal();
return $this;
}
/** /**
* Возвращает исходную сумму, от которой расчитывается размер налога * Возвращает исходную сумму, от которой расчитывается размер налога
* *
@ -137,52 +73,64 @@ class Vat extends Entity
*/ */
public function getSum(): float public function getSum(): float
{ {
return rubles($this->sum_original); return $this->sum;
} }
/** /**
* Прибавляет указанную сумму к общей исходной сумме. * Устанавливает исходную сумму, от которой будет расчитываться итоговый размер НДС.
* Автоматически пересчитывает итоговый размер НДС от новой исходной суммы. * Автоматически пересчитывает итоговый размер НДС от исходной суммы.
*
* @param float $rubles Сумма в рублях за предмет расчёта, из которой высчитывается размер НДС
* @return $this
*/
public function setSum(float $rubles): self
{
$this->sum = $rubles;
return $this;
}
/**
* Возвращает sdрасчитанный итоговый размер ставки НДС в рублях
*
* @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 getCalculated(): float
{
$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;
}
}

View File

@ -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(), []);
} }
/** /**

View 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());
}
}

View File

@ -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);
} }

View File

@ -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],
];
}
}