Files
musadaq-saas/app/modules_app/reports/company_health.php
2026-05-08 04:58:23 +03:00

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', 'حدث خطأ في إنشاء التقرير.');
}