diff --git a/app/modules_app/companies/connect_jofotara.php b/app/modules_app/companies/connect_jofotara.php index b4e2d15..1e61719 100644 --- a/app/modules_app/companies/connect_jofotara.php +++ b/app/modules_app/companies/connect_jofotara.php @@ -10,7 +10,7 @@ use App\Middleware\AuthMiddleware; // 1. Auth Check $decoded = AuthMiddleware::check(); -if (!in_array($decoded['role'], [ 'super_admin'])) { +if (!in_array($decoded['role'], ['super_admin', 'admin'])) { json_error('Unauthorized to modify JoFotara settings', 403); } diff --git a/app/modules_app/companies/index.php b/app/modules_app/companies/index.php index 860411f..030611f 100644 --- a/app/modules_app/companies/index.php +++ b/app/modules_app/companies/index.php @@ -28,27 +28,27 @@ try { } // 3. Decrypt fields - foreach ($companies as &$company) { - // Decrypt Name - $decryptedName = Encryption::decrypt($company['name']); - $company['name'] = $decryptedName !== false ? $decryptedName : $company['name']; + $dec = function($val) { + if (empty($val)) return ''; + $result = \App\Core\Encryption::decrypt((string)$val); + return ($result !== false && $result !== null && $result !== '') ? $result : (string)$val; + }; - // Decrypt Name EN + foreach ($companies as &$company) { + $company['name'] = $dec($company['name']); + if (!empty($company['name_en'])) { - $decryptedNameEn = Encryption::decrypt($company['name_en']); - $company['name_en'] = $decryptedNameEn !== false ? $decryptedNameEn : $company['name_en']; + $company['name_en'] = $dec($company['name_en']); } - // Redact JoFotara secrets if returned to UI (or just don't return them) - unset($company['jofotara_client_id_encrypted']); + if (isset($company['tenant_name'])) { + $company['tenant_name'] = $dec($company['tenant_name']); + } + + // Redact JoFotara secrets + $company['jofotara_client_id_encrypted'] = !empty($company['jofotara_client_id_encrypted']); unset($company['jofotara_secret_key_encrypted']); unset($company['certificate_password_encrypted']); - - // Decrypt Tenant Name (if exists) - if (isset($company['tenant_name'])) { - $decTenantName = Encryption::decrypt($company['tenant_name']); - $company['tenant_name'] = $decTenantName !== false ? $decTenantName : $company['tenant_name']; - } } json_success($companies); diff --git a/app/modules_app/companies/stats.php b/app/modules_app/companies/stats.php index 19a3181..597f9c7 100644 --- a/app/modules_app/companies/stats.php +++ b/app/modules_app/companies/stats.php @@ -4,6 +4,7 @@ */ use App\Core\Database; +use App\Core\Encryption; use App\Middleware\AuthMiddleware; // 1. Auth Check @@ -14,25 +15,39 @@ $companyId = $_GET['id'] ?? null; if (!$companyId) json_error('Company ID is required', 422); $tenantId = $decoded['tenant_id']; +$role = $decoded['role']; try { // 2. Permission Check - $stmt = $db->prepare("SELECT id, name, tax_identification_number, is_active, - (jofotara_client_id_encrypted IS NOT NULL) as is_jofotara_connected, - jofotara_income_source_sequence - FROM companies WHERE id = ? AND tenant_id = ?"); - $stmt->execute([$companyId, $tenantId]); + if ($role === 'super_admin') { + $stmt = $db->prepare("SELECT id, name, tax_identification_number, is_active, + (jofotara_client_id_encrypted IS NOT NULL) as is_jofotara_connected, + jofotara_income_source_sequence + FROM companies WHERE id = ?"); + $stmt->execute([$companyId]); + } else { + $stmt = $db->prepare("SELECT id, name, tax_identification_number, is_active, + (jofotara_client_id_encrypted IS NOT NULL) as is_jofotara_connected, + jofotara_income_source_sequence + FROM companies WHERE id = ? AND tenant_id = ?"); + $stmt->execute([$companyId, $tenantId]); + } $company = $stmt->fetch(); if (!$company) json_error('Company not found', 404); - // 3. Monthly Invoice Stats + // Decrypt company name + $dec = Encryption::decrypt($company['name']); + $company['name'] = ($dec !== false && $dec !== '') ? $dec : $company['name']; + + // 3. Monthly Invoice Stats (including tax) $stmtStats = $db->prepare(" SELECT DATE_FORMAT(invoice_date, '%Y-%m') as month, COUNT(*) as total_invoices, SUM(CASE WHEN status='approved' THEN 1 ELSE 0 END) as approved_count, - SUM(grand_total) as total_amount + COALESCE(SUM(grand_total), 0) as total_amount, + COALESCE(SUM(tax_amount), 0) as total_tax FROM invoices WHERE company_id = ? AND deleted_at IS NULL GROUP BY month @@ -46,8 +61,8 @@ try { $stmtTotals = $db->prepare(" SELECT COUNT(*) as total_invoices, - SUM(grand_total) as total_amount, - SUM(tax_amount) as total_tax, + COALESCE(SUM(grand_total), 0) as total_amount, + COALESCE(SUM(tax_amount), 0) as total_tax, SUM(CASE WHEN status='approved' THEN 1 ELSE 0 END) as approved_count FROM invoices WHERE company_id = ? AND deleted_at IS NULL diff --git a/app/modules_app/invoices/index.php b/app/modules_app/invoices/index.php index 50958a9..4a6c077 100644 --- a/app/modules_app/invoices/index.php +++ b/app/modules_app/invoices/index.php @@ -62,7 +62,7 @@ try { // 3. Decrypt sensitive fields for display (Robustly) $dec = function($val) { if (empty($val)) return ''; - $result = Encryption::decrypt((string)$val); + $result = \App\Core\Encryption::decrypt((string)$val); return ($result !== false && $result !== null && $result !== '') ? $result : (string)$val; }; @@ -71,9 +71,16 @@ try { $inv['supplier_tin'] = $dec($inv['supplier_tin']); $inv['buyer_name'] = $dec($inv['buyer_name']); - // Note: company_name and tenant_name from JOIN are usually plaintext - // Only decrypt if you are absolutely sure they are encrypted in the source table. - // For companies.name, it's plaintext. + if (!empty($inv['company_name'])) { + $inv['company_name'] = $dec($inv['company_name']); + } + if (!empty($inv['tenant_name'])) { + $inv['tenant_name'] = $dec($inv['tenant_name']); + } + } + + if (empty($invoices)) { + error_log("INVOICES LIST: No invoices found for role: $role, tenant_id: $tenantId"); } json_success($invoices); diff --git a/app/modules_app/users/index.php b/app/modules_app/users/index.php index de85b82..9ce1120 100644 --- a/app/modules_app/users/index.php +++ b/app/modules_app/users/index.php @@ -42,21 +42,25 @@ try { $users = $stmt->fetchAll(); // 3. Decrypt data and format + $dec = function($val) { + if (empty($val)) return ''; + $result = \App\Core\Encryption::decrypt((string)$val); + return ($result !== false && $result !== null && $result !== '') ? $result : (string)$val; + }; + foreach ($users as &$user) { - // Decrypt User Name/Email - $decryptedName = Encryption::decrypt($user['name']); - $user['name'] = $decryptedName !== false ? $decryptedName : $user['name']; - - $decryptedEmail = Encryption::decrypt($user['email']); - $user['email'] = $decryptedEmail !== false ? $decryptedEmail : $user['email']; - - // Decrypt Tenant Name (if exists) + $user['name'] = $dec($user['name']); + $user['email'] = $dec($user['email']); + if (!empty($user['tenant_name'])) { - $decryptedTenantName = Encryption::decrypt($user['tenant_name']); - $user['tenant_name'] = $decryptedTenantName !== false ? $decryptedTenantName : $user['tenant_name']; + $user['tenant_name'] = $dec($user['tenant_name']); } } + if (empty($users)) { + error_log("USERS LIST: No users found for role: $role, tenant_id: $tenantId"); + } + json_success($users); } catch (\Exception $e) { diff --git a/public/shell.php b/public/shell.php index 1feea6e..7638107 100644 --- a/public/shell.php +++ b/public/shell.php @@ -91,8 +91,7 @@

- - +
@@ -120,7 +119,7 @@ - +
@@ -128,7 +127,7 @@ - + @@ -137,19 +136,65 @@ + +
الشركة الأرقام الرسميةالعنوانالفوترة الحكومية الإحصائيات إجراءات
لا توجد شركات مسجلة
+
+
+ + +
+
+ + + + + + + + + + + + + @@ -174,24 +219,20 @@ @@ -232,24 +273,24 @@ -

تحليل الأداء الشهري

-
+

التحليل الشهري للفواتير والضرائب

+
المستخدمالمكتبالدورالحالةإجراءات
لا يوجد مستخدمون مسجلون
لا توجد فواتير مرفوعة
- + - - + + -
الشهر عدد الفواتيرمجموع الضريبةالمجموع النهائيالضريبة المستحقةالإجمالي النهائي