From ebe31a3d3d574a089ec414fdc6017fbbbd7cd75f Mon Sep 17 00:00:00 2001 From: Juan Pablo Vial Date: Mon, 5 May 2025 15:40:55 -0400 Subject: [PATCH] Guardar UF en DB --- app/src/Model/UF.php | 19 ++++++++++ app/src/Repository/UF.php | 49 ++++++++++++++++++++++++++ app/src/Service/UF.php | 74 +++++++++++++++++++++++++++++++++------ 3 files changed, 132 insertions(+), 10 deletions(-) create mode 100644 app/src/Model/UF.php create mode 100644 app/src/Repository/UF.php diff --git a/app/src/Model/UF.php b/app/src/Model/UF.php new file mode 100644 index 0000000..de4f20f --- /dev/null +++ b/app/src/Model/UF.php @@ -0,0 +1,19 @@ + $this->fecha, + 'valor' => $this->valor + ]; + } +} diff --git a/app/src/Repository/UF.php b/app/src/Repository/UF.php new file mode 100644 index 0000000..6b73b3b --- /dev/null +++ b/app/src/Repository/UF.php @@ -0,0 +1,49 @@ +register('fecha', new Implement\Repository\Mapper\DateTime('fecha')); + return $this->parseData(new Model\UF(), $data, $map); + } + public function save(Define\Model $model): Model\UF + { + $this->saveNew(['fecha', 'valor'], [ + $model->fecha->format('Y-m-d'), + $model->valor + ]); + return $model; + } + public function edit(Define\Model $model, array $new_data): Model\UF + { + return $this->update($model, ['fecha', 'valor'], $new_data); + } + + /** + * @param DateTimeInterface $dateTime + * @return Model\UF + * @throws Implement\Exception\EmptyResult + */ + public function fetchByFecha(DateTimeInterface $dateTime): Model\UF + { + $query = $this->connection->getQueryBuilder() + ->select() + ->from($this->getTable()) + ->where('fecha = :fecha'); + return $this->fetchOne($query, ['fecha' => $dateTime->format('Y-m-d')]); + } +} diff --git a/app/src/Service/UF.php b/app/src/Service/UF.php index ebc2cec..13d109a 100644 --- a/app/src/Service/UF.php +++ b/app/src/Service/UF.php @@ -3,14 +3,17 @@ namespace Incoviba\Service; use DateTimeInterface; use DateTimeImmutable; -use Incoviba\Common\Implement\Exception\EmptyRedis; +use PDOException; use Psr\Log\LoggerInterface; +use Incoviba\Common\Implement\Exception\{EmptyRedis, EmptyResult}; +use Incoviba\Repository; class UF { protected string $redisKey = 'uf'; public function __construct(protected Redis $redisService, protected Money $moneyService, + protected Repository\UF $ufRepository, protected LoggerInterface $logger) {} public function get(?DateTimeInterface $date = null): float @@ -18,21 +21,30 @@ class UF if ($date === null) { $date = new DateTimeImmutable(); } - $ufs = []; + /** + * 1 - Redis + * 2 - DB + * 3 - Fetch from web + */ try { - $ufs = json_decode($this->redisService->get($this->redisKey), JSON_OBJECT_AS_ARRAY); + $ufs = $this->getRedisUFs(); if (!isset($ufs[$date->format('Y-m-d')])) { throw new EmptyRedis($this->redisKey); } - $uf = $ufs[$date->format('Y-m-d')]; + return $ufs[$date->format('Y-m-d')]; } catch (EmptyRedis) { - $uf = $this->moneyService->getUF($date); - if ($uf === 0.0) { - return 0.0; + try { + $model = $this->ufRepository->fetchByFecha($date); + return $model->valor; + } catch (EmptyResult) { + $uf = $this->moneyService->getUF($date); + + if ($uf === 0.0) { + return 0.0; + } + + $this->saveUF($date, $uf); } - $ufs[$date->format('Y-m-d')] = $uf; - ksort($ufs); - $this->redisService->set($this->redisKey, json_encode($ufs), 60 * 60 * 24 * 30); } return $uf; } @@ -49,6 +61,7 @@ class UF if ($uf === 0.0) { continue; } + $this->saveUF($date, $uf); $updated[$date->format('Y-m-d')] = $uf; $ufs[$date->format('Y-m-d')] = $this->moneyService->getUF($date); } @@ -63,4 +76,45 @@ class UF $uf = $this->get($date); return $input * (($from === 'uf') ? $uf : 1/$uf); } + + protected array $redisUFs; + public function getRedisUFs(): array + { + if (!isset($this->redisUFs)) { + try { + $this->redisUFs = json_decode($this->redisService->get($this->redisKey), JSON_OBJECT_AS_ARRAY); + } catch (EmptyRedis) { + $this->redisUFs = []; + } + } + return $this->redisUFs; + } + protected function saveUF(DateTimeInterface $date, float $value): void + { + $this->saveUFinRedis($date, $value); + $this->saveUFinDB($date, $value); + } + protected function saveUFinRedis(DateTimeInterface $date, float $value): void + { + $ufs = $this->redisUFs; + + $ufs[$date->format('Y-m-d')] = $value; + if (count($ufs) > 1) { + ksort($ufs); + } + + $this->redisUFs = $ufs; + $this->redisService->set($this->redisKey, json_encode($ufs), 60 * 60 * 24 * 30); + } + protected function saveUFinDB(DateTimeInterface $date, float $value): void + { + try { + $this->ufRepository->fetchByFecha($date); + } catch (EmptyResult) { + try { + $model = $this->ufRepository->create(['fecha' => $date->format('Y-m-d'), 'valor' => $value]); + $this->ufRepository->save($model); + } catch (PDOException) {} + } + } }