78 lines
2.8 KiB
PHP
78 lines
2.8 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Services\AI;
|
|
|
|
use App\Services\AI\Contracts\{AIProviderInterface, ExtractionResultDTO};
|
|
use GuzzleHttp\Client;
|
|
use Exception;
|
|
|
|
final class GeminiProvider implements AIProviderInterface
|
|
{
|
|
private Client $client;
|
|
private string $apiKey;
|
|
private string $model;
|
|
|
|
public function __construct()
|
|
{
|
|
$this->client = new Client();
|
|
$this->apiKey = $_ENV['GEMINI_API_KEY'] ?? '';
|
|
$this->model = $_ENV['GEMINI_MODEL'] ?? 'gemini-2.0-flash';
|
|
}
|
|
|
|
public function extractFromFile(string $filePath, string $mimeType): ExtractionResultDTO
|
|
{
|
|
$fileData = base64_encode(file_get_contents($filePath));
|
|
|
|
$prompt = "Extract invoice data from this file. Return ONLY valid JSON (no markdown). " .
|
|
"Fields: invoice_number, invoice_date (YYYY-MM-DD), supplier_name, supplier_tin, supplier_address, " .
|
|
"buyer_name, buyer_tin, lines (description, quantity, unit_price, line_total, tax_rate), " .
|
|
"subtotal, tax_amount, grand_total, currency (JOD), confidence (0-1).";
|
|
|
|
$response = $this->client->post("https://generativelanguage.googleapis.com/v1beta/models/{$this->model}:generateContent?key={$this->apiKey}", [
|
|
'json' => [
|
|
'contents' => [
|
|
[
|
|
'parts' => [
|
|
['text' => $prompt],
|
|
[
|
|
'inline_data' => [
|
|
'mime_type' => $mimeType,
|
|
'data' => $fileData
|
|
]
|
|
]
|
|
]
|
|
]
|
|
],
|
|
'generationConfig' => [
|
|
'response_mime_type' => 'application/json'
|
|
]
|
|
]
|
|
]);
|
|
|
|
$data = json_decode($response->getBody()->getContents(), true);
|
|
$jsonStr = $data['candidates'][0]['content']['parts'][0]['text'] ?? '{}';
|
|
$result = json_decode($jsonStr, true);
|
|
|
|
return new ExtractionResultDTO(
|
|
$result['invoice_number'] ?? '',
|
|
$result['invoice_date'] ?? '',
|
|
$result['supplier_name'] ?? '',
|
|
$result['supplier_tin'] ?? null,
|
|
$result['supplier_address'] ?? '',
|
|
$result['buyer_name'] ?? null,
|
|
$result['buyer_tin'] ?? null,
|
|
$result['lines'] ?? [],
|
|
(float)($result['subtotal'] ?? 0),
|
|
(float)($result['tax_amount'] ?? 0),
|
|
(float)($result['grand_total'] ?? 0),
|
|
$result['currency'] ?? 'JOD',
|
|
(float)($result['confidence'] ?? 0),
|
|
$data['usageMetadata'] ?? []
|
|
);
|
|
}
|
|
|
|
public function getProviderName(): string { return 'gemini'; }
|
|
}
|