From 5d939f970b6e2dad1ed55e3d9d828dc605af5753 Mon Sep 17 00:00:00 2001 From: Juan Pablo Vial Date: Mon, 28 Apr 2025 20:20:43 -0400 Subject: [PATCH] Valor con pruebas --- app/phpunit.xml | 8 +-- app/src/Service/Valor.php | 70 ++++++++++++++++++++++-- app/tests/unit/src/Service/ValorTest.php | 69 +++++++++++++++++++++++ 3 files changed, 139 insertions(+), 8 deletions(-) create mode 100644 app/tests/unit/src/Service/ValorTest.php diff --git a/app/phpunit.xml b/app/phpunit.xml index aa76082..e1780ab 100644 --- a/app/phpunit.xml +++ b/app/phpunit.xml @@ -2,7 +2,7 @@ - + - + diff --git a/app/src/Service/Valor.php b/app/src/Service/Valor.php index 573d275..a094895 100644 --- a/app/src/Service/Valor.php +++ b/app/src/Service/Valor.php @@ -4,6 +4,7 @@ namespace Incoviba\Service; use DateTimeInterface; use DateTimeImmutable; use DateMalformedStringException; +use function PHPUnit\Framework\countOf; class Valor { @@ -11,15 +12,22 @@ class Valor public function clean(string|float|int $value): float { - if ((float) $value == $value) { + if (!is_string($value)) { return (float) $value; } - return (float) str_replace(['.', ','], ['', '.'], $value); + if ((int) $value == $value) { + return (float) $value; + } + + if ($this->isUS($value)) { + return $this->formatUS($value); + } + return $this->formatCL($value); } public function toPesos(string $value, null|string|DateTimeInterface $date = null, bool $force = false): int { $date = $this->getDateTime($date); - if (abs((float) $value - (int) $value) > 0 or $force) { + if ($this->isFloat($value) or $force) { return round($value * $this->ufService->get($date)); } return (int) $value; @@ -27,7 +35,7 @@ class Valor public function toUF(string $value, null|string|DateTimeInterface $date = null, bool $force = false): float { $date = $this->getDateTime($date); - if (abs((float) $value - (int) $value) > 0 and !$force) { + if ($this->isFloat($value) and !$force) { return (float) $value; } return $value / $this->ufService->get($date); @@ -47,4 +55,58 @@ class Valor } return $date; } + + protected function isUS(string $value): bool + { + /* + * Chile + * 1.000.000,00 + * 10000,000 + * 10,53 + * 1.000,00 + * 1.000 imposible! se asume US si # antes de . < 10 + * + * 1,000,000.00 + * 10000.00 + * 1,000.000 + * 10.53 + * 1,000 imposible! se asume CL + */ + if (str_contains($value, '.')) { + $parts = explode('.', $value); + if (count($parts) > 2) { // 1.000.000 || 1.000.000,00 + return false; + } + if (strlen($parts[0]) > 3) { // 1000.000 || 1,000.000 + return true; + } + if (str_contains($value, ',')) { + if (strpos($value, ',') > strpos($value, '.')) { // 1.000,000 + return false; + } + return true; // 1,000.000 + } + if ((int) $parts[0] < 10) { + return true; + } + return false; + } + return true; + } + protected function formatCL(string $value): float + { + return (float) str_replace(',', '.', (str_replace('.', '', $value))); + } + protected function formatUS(string $value): float + { + return (float) str_replace(',', '', $value); + } + protected function isFloat(string|int|float $value): bool + { + if (!is_string($value)) { + return is_float($value); + } + $cleaned = $this->clean($value); + return round($cleaned) !== $cleaned; + } } diff --git a/app/tests/unit/src/Service/ValorTest.php b/app/tests/unit/src/Service/ValorTest.php new file mode 100644 index 0000000..0697f08 --- /dev/null +++ b/app/tests/unit/src/Service/ValorTest.php @@ -0,0 +1,69 @@ +ufService = $this->getMockBuilder(Service\UF::class) + ->disableOriginalConstructor() + ->getMock(); + $this->ufService->method('get')->willReturn(35000.0); + } + + public static function cleanDataProvider(): array + { + return [ + ['1.003.000,01', 1003000.01], + ['4,273.84', 4273.84], + ]; + } + + #[DataProvider('cleanDataProvider')] + public function testClean($input, $expected): void + { + $valorService = new Valor($this->ufService); + + $result = $valorService->clean($input); + + $this->assertIsFloat($result); + $this->assertEquals($expected, $result); + } + + public function testToUF() + { + $date = '2025-01-01'; + $valorService = new Valor($this->ufService); + + $input = '1000000'; + $result = $valorService->toUF($input, $date); + + $this->assertIsFloat($result); + $this->assertEquals($input / 35000, $result); + } + + public static function pesosDataProvider(): array + { + return [ + [1000.01, 1000.01*35000, false], + [1000, 1000*35000, true], + ['1000', 1000, false], + ]; + } + + #[DataProvider('pesosDataProvider')] + public function testToPesos($input, $expected, $force) + { + $date = '2025-01-01'; + $valorService = new Valor($this->ufService); + + $result = $valorService->toPesos($input, $date, $force); + + $this->assertIsInt($result); + $this->assertEquals($expected, $result); + } +}