Files
fuel-price/app/Services/BrentPriceSources/EiaBrentPriceSource.php
Ovidiu U 1a0381265e refactor: extract Brent price sources into dedicated classes
OilPriceService no longer inlines per-provider fetch/transform/error logic.
EIA and FRED are now their own classes with a common shape; the service
just iterates and upserts the first successful result.
2026-04-14 16:29:52 +01:00

61 lines
1.8 KiB
PHP

<?php
namespace App\Services\BrentPriceSources;
use App\Services\ApiLogger;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
use Throwable;
final class EiaBrentPriceSource
{
private const string URL = 'https://api.eia.gov/v2/petroleum/pri/spt/data/';
public function __construct(private readonly ApiLogger $apiLogger) {}
/**
* @return array{date: string, price_usd: float}[]|null
*/
public function fetch(): ?array
{
try {
$response = $this->apiLogger->send('eia', 'GET', self::URL, fn () => Http::timeout(10)
->get(self::URL, [
'api_key' => config('services.eia.api_key'),
'frequency' => 'daily',
'data[0]' => 'value',
'facets[series][]' => 'RBRTE',
'sort[0][column]' => 'period',
'sort[0][direction]' => 'desc',
'length' => 30,
]));
if (! $response->successful()) {
Log::error('EiaBrentPriceSource: request failed', ['status' => $response->status()]);
return null;
}
$rows = collect($response->json('response.data') ?? [])
->filter(fn (array $row) => ($row['value'] ?? '.') !== '.')
->map(fn (array $row) => [
'date' => $row['period'],
'price_usd' => (float) $row['value'],
])
->all();
if ($rows === []) {
Log::warning('EiaBrentPriceSource: no valid observations returned');
return null;
}
return $rows;
} catch (Throwable $e) {
Log::error('EiaBrentPriceSource: fetch failed', ['error' => $e->getMessage()]);
return null;
}
}
}