Added new Money provider

This commit is contained in:
Juan Pablo Vial
2025-10-24 18:35:52 -03:00
parent 6e32b1debc
commit 04a725e517
8 changed files with 178 additions and 31 deletions

View File

@ -0,0 +1,106 @@
<?php
namespace Incoviba\Service\Money;
use DateTimeInterface;
use DateTimeImmutable;
use JsonException;
use Psr\Http\Client\ClientExceptionInterface;
use Psr\Http\Client\ClientInterface;
use Incoviba\Common\Define;
use Incoviba\Common\Ideal;
use Incoviba\Common\Implement\Exception\EmptyResponse;
use Incoviba\Service\Money;
class Findic extends Ideal\Money\Provider
{
public function __construct(protected ClientInterface $client) {}
protected string $url = 'https://findic.cl/api/';
public function get(string $money_symbol, ?DateTimeInterface $dateTime = null): float
{
if (!$this->supported($money_symbol)) {
throw new EmptyResponse($money_symbol);
}
if ($dateTime === null) {
$dateTime = new DateTimeImmutable();
}
return match (strtolower($money_symbol)) {
Money::UF, Money::USD => $this->getMonth(strtolower($money_symbol), $dateTime),
Money::IPC => $this->getSum(strtolower($money_symbol), $dateTime,
DateTimeImmutable::createFromFormat('Y-m-d',
$dateTime->modify('-1 year')->format('Y-11-01'))),
default => throw new EmptyResponse($money_symbol),
};
}
protected array $supportedMap = [
Money::UF => 'uf',
Money::IPC => 'ipc',
Money::USD => 'dolar'
];
/**
* @param string $request_uri
* @return float
* @throws EmptyResponse
*/
protected function sendRequest(string $request_uri): array
{
try {
$response = $this->client->get($request_uri);
} catch (ClientExceptionInterface $exception) {
throw new EmptyResponse($request_uri, $exception);
}
if ((int) floor($response->getStatusCode() / 100) !== 2) {
throw new EmptyResponse($request_uri);
}
$body = $response->getBody();
try {
$json = json_decode($body->getContents(), true, 512, JSON_THROW_ON_ERROR);
} catch (JsonException $exception) {
throw new EmptyResponse($request_uri, $exception);
}
if (!array_key_exists('serie', $json) or count($json['serie']) === 0) {
throw new EmptyResponse($request_uri);
}
return $json['serie'];
}
/**
* @param string $symbol
* @param DateTimeInterface $dateTime
* @return float
* @throws EmptyResponse
*/
protected function getMonth(string $symbol, DateTimeInterface $dateTime): float
{
$request_uri = "{$this->supportedMap[strtolower($symbol)]}/{$dateTime->format('d-m-Y')}";
return (float) $this->sendRequest($request_uri)[0]['valor'];
}
/**
* @param string $symbol
* @param DateTimeInterface $dateTime
* @param DateTimeInterface|null $fromDateTime
* @return float
* @throws EmptyResponse
*/
protected function getSum(string $symbol, DateTimeInterface $dateTime, ?DateTimeInterface $fromDateTime = null): float
{
$requestUri = "{$this->supportedMap[strtolower($symbol)]}/{$dateTime->format('Y')})";
$json = $this->sendRequest($requestUri);
$values = array_filter($json['serie'], fn($month) => DateTimeImmutable::createFromFormat('Y-m-d', $month['fecha']) <= $dateTime);
$value = array_reduce($values, fn($value, $month) => $value + ((float) $month['valor']), 0.0);
if ($fromDateTime === null) {
$fromDateTime = $dateTime->modify('-1 year');
}
$requestUri = "{$this->supportedMap[strtolower($symbol)]}/{$fromDateTime->format('Y')})";
$json = $this->sendRequest($requestUri);
$values = array_filter($json['serie'], fn($month) => DateTimeImmutable::createFromFormat('Y-m-d', $month['fecha']) > $dateTime);
return array_reduce($values, fn($value, $month) => $value + ((float) $month['valor']), $value);
}
}

View File

@ -8,9 +8,10 @@ use DateInterval;
use Psr\Http\Client\ClientInterface;
use GuzzleHttp\Exception\GuzzleException;
use Incoviba\Common\Implement\Exception\EmptyResponse;
use Incoviba\Common\Define\Money\Provider;
use Incoviba\Common\Ideal;
use Incoviba\Service\Money;
class Ine implements Provider
class Ine extends Ideal\Money\Provider
{
protected string $uri = 'https://api-calculadora.ine.cl/ServiciosCalculadoraVariacion';
public function __construct(protected ClientInterface $client) {}
@ -21,6 +22,9 @@ class Ine implements Provider
*/
public function get(string $money_symbol, ?DateTimeInterface $dateTime = null): float
{
if (!$this->supported($money_symbol)) {
throw new EmptyResponse($money_symbol);
}
if ($dateTime === null) {
$dateTime = new DateTimeImmutable();
}
@ -29,6 +33,10 @@ class Ine implements Provider
return $this->getVar($start, $end);
}
protected array $supportedMap = [
Money::IPC => 'ipc'
];
/**
* @throws EmptyResponse
*/

View File

@ -4,10 +4,11 @@ namespace Incoviba\Service\Money;
use DateTimeInterface;
use Psr\Http\Client\ClientInterface;
use GuzzleHttp\Exception\GuzzleException;
use Incoviba\Common\Define\Money\Provider;
use Incoviba\Common\Ideal;
use Incoviba\Common\Implement\Exception\EmptyResponse;
use Incoviba\Service\Money;
class MiIndicador implements Provider
class MiIndicador extends Ideal\Money\Provider
{
public function __construct(protected ClientInterface $client) {}
@ -19,9 +20,12 @@ class MiIndicador implements Provider
*/
public function get(string $money_symbol, ?DateTimeInterface $dateTime = null): float
{
$request_uri = "{$money_symbol}";
if (!$this->supported($money_symbol)) {
throw new EmptyResponse($money_symbol);
}
$request_uri = "{$this->supportedMap[strtolower($money_symbol)]}";
if ($dateTime !== null) {
$request_uri = "{$money_symbol}/{$dateTime->format('d-m-Y')}";
$request_uri = "{$request_uri}/{$dateTime->format('d-m-Y')}";
}
try {
$response = $this->client->get($request_uri);
@ -41,4 +45,9 @@ class MiIndicador implements Provider
}
return $json->serie[0]->valor;
}
protected array $supportedMap = [
Money::UF => 'uf',
Money::IPC => 'ipc',
Money::USD => 'dolar'
];
}

View File

@ -9,24 +9,31 @@ use Psr\Http\Client\ClientInterface;
use Dom\HTMLDocument;
use GuzzleHttp\Exception\GuzzleException;
use Incoviba\Common\Implement\Exception\EmptyResponse;
use Incoviba\Common\Define;
use Incoviba\Common\Ideal;
use Incoviba\Repository;
use Incoviba\Service;
class SII implements Define\Money\Provider
class SII extends Ideal\Money\Provider
{
public function __construct(protected ClientInterface $client,
protected Repository\UF $ufRepository) {}
public function get(string $money_symbol, ?DateTimeInterface $dateTime = null): float
{
if ($money_symbol === Service\Money::UF) {
if (!$this->supported($money_symbol)) {
throw new EmptyResponse("{$money_symbol} not found in " . __CLASS__);
}
if (strtolower($money_symbol) === Service\Money::UF) {
return $this->getUF($dateTime);
}
$class = __CLASS__;
throw new EmptyResponse("{$money_symbol} not found in {$class}");
}
protected array $supportedMap = [
Service\Money::UF => 'uf'
];
/**
* @param DateTimeInterface|null $dateTime
* @return float