diff --git a/src/Number/Vat.php b/src/Number/Vat.php index a31b703..cd0c01b 100644 --- a/src/Number/Vat.php +++ b/src/Number/Vat.php @@ -18,7 +18,7 @@ public function diff(float $number): float public function without(float $number): float { - return Utils\Percentage::without($this->ratio, $number); + return Utils\Percentage::without($number, $this->ratio); } } diff --git a/src/Utils/Percentage.php b/src/Utils/Percentage.php index 8e56603..bab7cbf 100644 --- a/src/Utils/Percentage.php +++ b/src/Utils/Percentage.php @@ -25,6 +25,18 @@ public static function ratio(float $smallRatio): float } + public static function calculate(float $part, float $total): float + { + return self::without($part, $total) * 100; + } + + + public static function calculateRemainder(float $part, float $total): float + { + return 100 - self::calculate($part, $total); + } + + /** * N + 17.5% -> N * 1.175 */ @@ -44,11 +56,15 @@ public static function diffWith(float $ratio, float $number): float /** + * Safe division * If you have price with percentage, and you need price without percentage. * N / 1.175 */ - public static function without(float $ratio, float $number): float + public static function without(float $number, float $ratio): float { + if ($ratio === 0.0) { + return 0.0; + } return $number / $ratio; } @@ -58,7 +74,7 @@ public static function without(float $ratio, float $number): float */ public static function diffWithout(float $ratio, float $number): float { - return $number - self::without($ratio, $number); + return $number - self::without($number, $ratio); } @@ -76,6 +92,6 @@ public static function deduct(float $percentage, float $number): float */ public static function diffDeduct(float $percentage, float $number): float { - return self::smallRatio($number * $percentage); + return self::with(self::smallRatio($percentage), $number); } } diff --git a/tests/src/Utils/PercentageTest.php b/tests/src/Utils/PercentageTest.php new file mode 100644 index 0000000..c47382a --- /dev/null +++ b/tests/src/Utils/PercentageTest.php @@ -0,0 +1,172 @@ + + */ + protected function providePercentage(): array + { + return [ + [0.0, 1.0, 0.0], + [0.0, 0.0, 1.0], + [-100.0, 1.0, -1.0], + [120, 108, 90], + [120, 120, 100], + [120, -120, -100], + ]; + } + + /** + * @dataProvider provideCalculateRemainder + */ + public function testCalculateRemainder(float $result, float $part, float $total): void + { + Assert::same($result, Percentage::calculateRemainder($part, $total)); + } + + + /** + * @return array + */ + protected function provideCalculateRemainder(): array + { + return [ + [100.0, 1.0, 0.0], + [100.0, 0.0, 1.0], + [200.0, 1.0, -1.0], + [20, 80, 100], + [-20, 120, 100], + [-20, -120, -100], + ]; + } + + + /** + * @dataProvider provideSmallRatio + */ + public function testSmallRatio(float $expected, float $percentage): void + { + Assert::same($expected, Percentage::smallRatio($percentage)); + } + + + /** + * @return array + */ + protected function provideSmallRatio(): array + { + return [ + [0, 0], + [0.2, 20], + [-0.2, -20], + ]; + } + + + /** + * @dataProvider provideRatio + */ + public function testRatio(float $expected, float $percentage): void + { + Assert::same($expected, Percentage::ratio($percentage)); + } + + + /** + * @return array + */ + protected function provideRatio(): array + { + return [ + [1.2, 0.2], + [1.0, 0.0], + [0.8, -0.2], + ]; + } + + + /** + * @dataProvider provideDiffDeduct + */ + public function testDiffDeduct(float $expected, float $percentage, float $number): void + { + Assert::same($expected, Percentage::diffDeduct($percentage, $number)); + } + + + /** + * @return array + */ + protected function provideDiffDeduct(): array + { + return [ + [20, 20, 100], + [24, 20, 120], + [0, 20, 0], + ]; + } + + + /** + * @dataProvider provideDeduct + */ + public function testDeduct(float $expected, float $percentage, float $number): void + { + Assert::same($expected, Percentage::deduct($percentage, $number)); + } + + + /** + * @return array + */ + protected function provideDeduct(): array + { + return [ + [80, 20, 100], + [96, 20, 120], + [0, 20, 0], + ]; + } + + + /** + * @dataProvider provideWithout + */ + public function testWithout(float $expected, float $ratio, float $number): void + { + Assert::same($expected, Percentage::without($number, $ratio)); + } + + + /** + * @return array + */ + protected function provideWithout(): array + { + return [ + [100, 1.2, 120], + [0, 1.2, 0], + ]; + } +} + +(new PercentageTest())->run();