Update: 2026-05-07 02:01:59
This commit is contained in:
@@ -30,7 +30,7 @@ class AI
|
||||
"contents" => [
|
||||
[
|
||||
"parts" => [
|
||||
["text" => $prompt],
|
||||
["text" => $prompt . " If the image is not an invoice, is blank, or is completely unreadable, return ONLY: {\"error\": \"invalid_invoice\"}. DO NOT guess or invent data."],
|
||||
[
|
||||
"inline_data" => [
|
||||
"mime_type" => $mimeType,
|
||||
@@ -65,6 +65,11 @@ class AI
|
||||
|
||||
if (!$textResponse) return null;
|
||||
|
||||
return json_decode($textResponse, true);
|
||||
$data = json_decode($textResponse, true);
|
||||
if (isset($data['error']) && $data['error'] === 'invalid_invoice') {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,10 +64,37 @@ class NotificationService
|
||||
return $successCount > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a data-only (silent) notification to update background state (e.g., progress)
|
||||
*/
|
||||
public function sendDataNotification(string $userId, array $data, ?string $deviceId = null): bool
|
||||
{
|
||||
$db = Database::getInstance();
|
||||
if ($deviceId) {
|
||||
$stmt = $db->prepare("SELECT push_token FROM user_devices WHERE user_id = ? AND device_fingerprint = ? AND push_token IS NOT NULL");
|
||||
$stmt->execute([$userId, $deviceId]);
|
||||
} else {
|
||||
$stmt = $db->prepare("SELECT push_token FROM user_devices WHERE user_id = ? AND push_token IS NOT NULL AND is_active = 1");
|
||||
$stmt->execute([$userId]);
|
||||
}
|
||||
|
||||
$tokens = $stmt->fetchAll(\PDO::FETCH_COLUMN);
|
||||
if (empty($tokens)) return false;
|
||||
|
||||
$successCount = 0;
|
||||
foreach ($tokens as $token) {
|
||||
if ($this->dispatchToFcm($token, null, null, $data)) {
|
||||
$successCount++;
|
||||
}
|
||||
}
|
||||
|
||||
return $successCount > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatch notification to Firebase via HTTP v1 API
|
||||
*/
|
||||
private function dispatchToFcm(string $token, string $title, string $body, array $data): bool
|
||||
private function dispatchToFcm(string $token, ?string $title, ?string $body, array $data): bool
|
||||
{
|
||||
if (!file_exists($this->serviceAccountPath)) {
|
||||
error_log("[NotificationService] Firebase service account file missing: {$this->serviceAccountPath}");
|
||||
@@ -79,30 +106,34 @@ class NotificationService
|
||||
|
||||
$url = "https://fcm.googleapis.com/v1/projects/{$this->projectId}/messages:send";
|
||||
|
||||
$payload = [
|
||||
'message' => [
|
||||
'token' => $token,
|
||||
$message = [
|
||||
'token' => $token,
|
||||
'data' => array_map('strval', $data),
|
||||
];
|
||||
|
||||
if ($title || $body) {
|
||||
$message['notification'] = [
|
||||
'title' => $title,
|
||||
'body' => $body,
|
||||
];
|
||||
$message['android'] = [
|
||||
'priority' => 'high',
|
||||
'notification' => [
|
||||
'title' => $title,
|
||||
'body' => $body,
|
||||
],
|
||||
'data' => array_map('strval', $data), // FCM data values must be strings
|
||||
'android' => [
|
||||
'priority' => 'high',
|
||||
'notification' => [
|
||||
'sound' => 'default',
|
||||
'channel_id' => 'high_importance_channel'
|
||||
]
|
||||
];
|
||||
$message['apns'] = [
|
||||
'payload' => [
|
||||
'aps' => [
|
||||
'sound' => 'default',
|
||||
'channel_id' => 'high_importance_channel'
|
||||
]
|
||||
],
|
||||
'apns' => [
|
||||
'payload' => [
|
||||
'aps' => [
|
||||
'sound' => 'default',
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
];
|
||||
}
|
||||
|
||||
$payload = ['message' => $message];
|
||||
|
||||
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
|
||||
@@ -122,16 +122,31 @@ try {
|
||||
|
||||
// Mark queue item done
|
||||
$db->prepare("UPDATE invoice_processing_queue SET status = 'done', invoice_id = ?, processed_at = NOW() WHERE id = ?")->execute([$invoiceId, $queueId]);
|
||||
|
||||
|
||||
// Update batch progress
|
||||
$db->prepare("UPDATE invoice_batches SET processed_images = processed_images + 1 WHERE id = ?")->execute([$batchId]);
|
||||
|
||||
$db->commit();
|
||||
echo "Success: Created Invoice $invoiceId\n";
|
||||
|
||||
// Send silent push update for progress
|
||||
$stmt = $db->prepare("SELECT total_images, processed_images, uploaded_by FROM invoice_batches WHERE id = ?");
|
||||
$stmt->execute([$batchId]);
|
||||
$currentBatch = $stmt->fetch();
|
||||
if ($currentBatch) {
|
||||
$notifier = new NotificationService();
|
||||
$notifier->sendDataNotification($currentBatch['uploaded_by'], [
|
||||
'type' => 'batch_progress',
|
||||
'batch_id' => $batchId,
|
||||
'processed' => $currentBatch['processed_images'],
|
||||
'total' => $currentBatch['total_images']
|
||||
]);
|
||||
}
|
||||
|
||||
// Increment Quota
|
||||
QuotaMiddleware::incrementInvoiceUsage($tenantId);
|
||||
|
||||
|
||||
} catch (Exception $e) {
|
||||
$db->rollBack();
|
||||
echo "DB Error: " . $e->getMessage() . "\n";
|
||||
|
||||
Reference in New Issue
Block a user