Files
oficial/app/src/Service/UF.php

124 lines
3.8 KiB
PHP
Raw Normal View History

2023-11-29 20:09:08 -03:00
<?php
namespace Incoviba\Service;
use DateTimeInterface;
2023-12-21 18:45:47 -03:00
use DateTimeImmutable;
2025-05-05 15:40:55 -04:00
use PDOException;
2024-07-26 23:15:48 -04:00
use Psr\Log\LoggerInterface;
2025-05-05 15:40:55 -04:00
use Incoviba\Common\Implement\Exception\{EmptyRedis, EmptyResult};
use Incoviba\Repository;
2023-11-29 20:09:08 -03:00
class UF
{
protected string $redisKey = 'uf';
2024-07-26 23:15:48 -04:00
public function __construct(protected Redis $redisService, protected Money $moneyService,
2025-05-05 15:40:55 -04:00
protected Repository\UF $ufRepository,
2024-07-26 23:15:48 -04:00
protected LoggerInterface $logger) {}
2023-11-29 20:09:08 -03:00
2023-12-21 18:45:47 -03:00
public function get(?DateTimeInterface $date = null): float
2023-11-29 20:09:08 -03:00
{
$today = new DateTimeImmutable();
2023-12-21 18:45:47 -03:00
if ($date === null) {
$date = new DateTimeImmutable();
}
if ($date->diff($today)->days < 0) {
return 0.0;
}
2025-05-05 15:40:55 -04:00
/**
* 1 - Redis
* 2 - DB
* 3 - Fetch from web
*/
2023-11-29 20:09:08 -03:00
try {
2025-05-05 15:40:55 -04:00
$ufs = $this->getRedisUFs();
2023-11-29 20:09:08 -03:00
if (!isset($ufs[$date->format('Y-m-d')])) {
throw new EmptyRedis($this->redisKey);
}
2025-05-05 15:40:55 -04:00
return $ufs[$date->format('Y-m-d')];
2023-11-29 20:09:08 -03:00
} catch (EmptyRedis) {
2025-05-05 15:40:55 -04:00
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);
2024-07-26 23:15:48 -04:00
}
2023-11-29 20:09:08 -03:00
}
return $uf;
}
2024-07-26 23:15:48 -04:00
public function updateMany(array $dates): array
{
$ufs = [];
try {
$ufs = json_decode($this->redisService->get($this->redisKey), JSON_OBJECT_AS_ARRAY);
} catch (EmptyRedis) {}
$updated = [];
foreach ($dates as $date) {
if (!isset($ufs[$date->format('Y-m-d')]) or $ufs[$date->format('Y-m-d')] === 0) {
$uf = $this->moneyService->getUF($date);
if ($uf === 0.0) {
continue;
}
2025-05-05 15:40:55 -04:00
$this->saveUF($date, $uf);
2024-07-26 23:15:48 -04:00
$updated[$date->format('Y-m-d')] = $uf;
$ufs[$date->format('Y-m-d')] = $this->moneyService->getUF($date);
}
}
ksort($ufs);
$this->redisService->set($this->redisKey, json_encode($ufs), 60 * 60 * 24 * 30);
return $updated;
}
2023-11-29 20:09:08 -03:00
public function transform(DateTimeInterface $date, float $input, string $from = 'uf'): float
{
$uf = $this->get($date);
return $input * (($from === 'uf') ? $uf : 1/$uf);
}
2025-05-05 15:40:55 -04:00
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) {}
}
}
2023-11-29 20:09:08 -03:00
}