113 lines
4.0 KiB
PHP
113 lines
4.0 KiB
PHP
<?php
|
|
namespace Incoviba\Service\Money;
|
|
|
|
use DateTimeInterface;
|
|
use DateTimeImmutable;
|
|
use JsonException;
|
|
use Psr\Http\Client\ClientExceptionInterface;
|
|
use Psr\Http\Client\ClientInterface;
|
|
use Psr\Log\LoggerInterface;
|
|
use Incoviba\Common\Ideal;
|
|
use Incoviba\Common\Implement\Exception\EmptyResponse;
|
|
use Incoviba\Service\Money;
|
|
|
|
class Findic extends Ideal\Money\Provider
|
|
{
|
|
public function __construct(LoggerInterface $logger, protected ClientInterface $client)
|
|
{
|
|
parent::__construct($logger);
|
|
}
|
|
|
|
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->getDate(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 getDate(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
|
|
{
|
|
$dateTime = $dateTime->modify('last day of this month');
|
|
$requestUri = "{$this->supportedMap[strtolower($symbol)]}/{$dateTime->format('Y')}";
|
|
$serie = $this->sendRequest($requestUri);
|
|
$values = array_filter($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');
|
|
} else {
|
|
$fromDateTime = $fromDateTime->modify('last day of this month');
|
|
}
|
|
$requestUri = "{$this->supportedMap[strtolower($symbol)]}/{$fromDateTime->format('Y')}";
|
|
$serie = $this->sendRequest($requestUri);
|
|
$values = array_filter($serie, fn($month) => DateTimeImmutable::createFromFormat('Y-m-d', $month['fecha']) > $fromDateTime);
|
|
return array_reduce($values, fn($value, $month) => $value + ((float) $month['valor']), $value);
|
|
}
|
|
}
|