143 lines
5.1 KiB
PHP
143 lines
5.1 KiB
PHP
<?php
|
|
/**
|
|
* AI Company Health Report
|
|
* GET /v1/reports/company-health?company_id=xxx
|
|
*
|
|
* Generates an AI-powered financial health analysis using invoice data.
|
|
* Returns insights, warnings, and recommendations in Arabic.
|
|
*/
|
|
|
|
use App\Core\Database;
|
|
use App\Core\Encryption;
|
|
use App\Core\AI;
|
|
use App\Middleware\AuthMiddleware;
|
|
|
|
$decoded = AuthMiddleware::check();
|
|
$db = Database::getInstance();
|
|
|
|
$tenantId = $decoded['tenant_id'];
|
|
$role = $decoded['role'];
|
|
$companyId = $_GET['company_id'] ?? null;
|
|
|
|
if (!$companyId) {
|
|
json_error('معرّف الشركة مطلوب', 422);
|
|
}
|
|
|
|
// Verify access
|
|
$accessQuery = ($role === 'super_admin')
|
|
? "SELECT id, name, tax_identification_number FROM companies WHERE id = ? AND deleted_at IS NULL"
|
|
: "SELECT id, name, tax_identification_number FROM companies WHERE id = ? AND tenant_id = ? AND deleted_at IS NULL";
|
|
|
|
$accessParams = ($role === 'super_admin') ? [$companyId] : [$companyId, $tenantId];
|
|
$stmt = $db->prepare($accessQuery);
|
|
$stmt->execute($accessParams);
|
|
$company = $stmt->fetch();
|
|
|
|
if (!$company) {
|
|
json_error('الشركة غير موجودة أو ليس لديك صلاحية', 404);
|
|
}
|
|
|
|
$companyName = Encryption::decrypt($company['name']) ?: $company['name'];
|
|
|
|
try {
|
|
// 1. Gather last 3 months of data
|
|
$months = [];
|
|
for ($i = 0; $i < 3; $i++) {
|
|
$m = date('m', strtotime("-{$i} months"));
|
|
$y = date('Y', strtotime("-{$i} months"));
|
|
|
|
$stmt = $db->prepare("
|
|
SELECT
|
|
COUNT(*) as total_invoices,
|
|
COALESCE(SUM(grand_total), 0) as revenue,
|
|
COALESCE(SUM(tax_amount), 0) as tax,
|
|
COALESCE(SUM(discount_total), 0) as discounts,
|
|
COALESCE(AVG(grand_total), 0) as avg_invoice,
|
|
SUM(CASE WHEN status = 'submitted' THEN 1 ELSE 0 END) as submitted_count,
|
|
SUM(CASE WHEN status = 'extracted' THEN 1 ELSE 0 END) as pending_count
|
|
FROM invoices
|
|
WHERE company_id = ? AND MONTH(created_at) = ? AND YEAR(created_at) = ?
|
|
");
|
|
$stmt->execute([$companyId, $m, $y]);
|
|
$data = $stmt->fetch();
|
|
$data['month'] = (int)$m;
|
|
$data['year'] = (int)$y;
|
|
$months[] = $data;
|
|
}
|
|
|
|
// 2. Pending invoices count
|
|
$pendingStmt = $db->prepare("SELECT COUNT(*) FROM invoices WHERE company_id = ? AND status = 'extracted'");
|
|
$pendingStmt->execute([$companyId]);
|
|
$pendingCount = (int)$pendingStmt->fetchColumn();
|
|
|
|
// 3. Build AI prompt
|
|
$dataJson = json_encode([
|
|
'company_name' => $companyName,
|
|
'tin' => $company['tax_identification_number'],
|
|
'monthly_data' => $months,
|
|
'pending_invoices' => $pendingCount,
|
|
], JSON_UNESCAPED_UNICODE);
|
|
|
|
$prompt = <<<PROMPT
|
|
أنت محلل مالي خبير. حلل البيانات التالية لشركة وأعطِ تقريراً مختصراً بالعربية.
|
|
|
|
البيانات:
|
|
{$dataJson}
|
|
|
|
أعد الرد بصيغة JSON فقط بدون أي نص إضافي:
|
|
{
|
|
"health_score": (رقم من 1 إلى 10),
|
|
"health_label": ("ممتاز" أو "جيد" أو "متوسط" أو "يحتاج انتباه"),
|
|
"summary": "ملخص من سطرين عن الحالة المالية",
|
|
"insights": ["ملاحظة 1", "ملاحظة 2", "ملاحظة 3"],
|
|
"warnings": ["تحذير إن وجد"],
|
|
"recommendations": ["توصية 1", "توصية 2"]
|
|
}
|
|
PROMPT;
|
|
|
|
$aiResponse = AI::ask($prompt, $tenantId);
|
|
|
|
// Parse AI response
|
|
$report = null;
|
|
if ($aiResponse) {
|
|
// Extract JSON from response
|
|
$cleaned = preg_replace('/```json?\s*|```/', '', $aiResponse);
|
|
$report = json_decode(trim($cleaned), true);
|
|
}
|
|
|
|
// Fallback if AI fails
|
|
if (!$report) {
|
|
$currentMonth = $months[0] ?? [];
|
|
$prevMonth = $months[1] ?? [];
|
|
$score = 5;
|
|
|
|
if (($currentMonth['total_invoices'] ?? 0) > 0) $score += 2;
|
|
if (($currentMonth['submitted_count'] ?? 0) > 0) $score += 1;
|
|
if ($pendingCount === 0) $score += 1;
|
|
if (($currentMonth['revenue'] ?? 0) > ($prevMonth['revenue'] ?? 0)) $score += 1;
|
|
|
|
$report = [
|
|
'health_score' => min(10, $score),
|
|
'health_label' => $score >= 8 ? 'ممتاز' : ($score >= 6 ? 'جيد' : 'متوسط'),
|
|
'summary' => 'تقرير مبني على البيانات المتوفرة بدون تحليل AI.',
|
|
'insights' => ['عدد الفواتير: ' . ($currentMonth['total_invoices'] ?? 0)],
|
|
'warnings' => $pendingCount > 0 ? ["يوجد {$pendingCount} فاتورة بانتظار المراجعة"] : [],
|
|
'recommendations' => ['تأكد من إرسال جميع الفواتير المعتمدة لجوفوترا'],
|
|
];
|
|
}
|
|
|
|
json_success([
|
|
'company_id' => $companyId,
|
|
'company_name' => $companyName,
|
|
'report' => $report,
|
|
'data' => [
|
|
'monthly_summary' => $months,
|
|
'pending_count' => $pendingCount,
|
|
],
|
|
'generated_at' => date('c'),
|
|
], 'تقرير صحة الشركة');
|
|
|
|
} catch (\Exception $e) {
|
|
safe_error($e, 'reports/company-health', 'حدث خطأ في إنشاء التقرير.');
|
|
}
|