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

110 lines
3.3 KiB
PHP

<?php
/**
* Invoices List Endpoint (Role-Based, Tenant-Aware, Paginated)
*/
use App\Core\Database;
use App\Core\Encryption;
use App\Middleware\AuthMiddleware;
// 1. Auth Check
$decoded = AuthMiddleware::check();
$db = Database::getInstance();
$tenantId = $decoded['tenant_id'];
$userId = $decoded['user_id'];
$role = $decoded['role'];
try {
$pagination = paginate_params(25, 100);
// 2. Build WHERE clause based on Role
$where = '';
$params = [];
if ($role === 'super_admin') {
$where = '1=1';
} elseif ($role === 'admin') {
$where = 'i.tenant_id = ?';
$params = [$tenantId];
} else {
// Accountant/Viewer: Filter by assigned companies
$stmtUser = $db->prepare("SELECT company_id FROM user_company_assignments WHERE user_id = ? AND is_active = 1");
$stmtUser->execute([$userId]);
$assignedCompanyIds = $stmtUser->fetchAll(PDO::FETCH_COLUMN);
if (empty($assignedCompanyIds)) {
json_paginated([], 0, $pagination);
}
$placeholders = implode(',', array_fill(0, count($assignedCompanyIds), '?'));
$where = "i.company_id IN ($placeholders)";
$params = $assignedCompanyIds;
}
// Optional filters from query string
$companyFilter = $_GET['company_id'] ?? null;
$statusFilter = $_GET['status'] ?? null;
$searchFilter = $_GET['search'] ?? null;
if ($companyFilter) {
$where .= ' AND i.company_id = ?';
$params[] = $companyFilter;
}
if ($statusFilter) {
$where .= ' AND i.status = ?';
$params[] = $statusFilter;
}
if ($searchFilter) {
$where .= ' AND (i.invoice_number LIKE ? OR i.supplier_name LIKE ?)';
$params[] = "%$searchFilter%";
$params[] = "%$searchFilter%";
}
// 3. Count total
$countStmt = $db->prepare("SELECT COUNT(*) FROM invoices i WHERE $where");
$countStmt->execute($params);
$total = (int)$countStmt->fetchColumn();
// 4. Fetch page
$joinTenant = ($role === 'super_admin') ? 'LEFT JOIN tenants t ON i.tenant_id = t.id' : '';
$selectTenant = ($role === 'super_admin') ? ', t.name as tenant_name' : '';
$stmt = $db->prepare("
SELECT i.*{$selectTenant}, c.name as company_name
FROM invoices i
LEFT JOIN companies c ON i.company_id = c.id
{$joinTenant}
WHERE {$where}
ORDER BY i.created_at DESC
LIMIT {$pagination['limit']} OFFSET {$pagination['offset']}
");
$stmt->execute($params);
$invoices = $stmt->fetchAll();
// 5. Decrypt sensitive fields
$dec = function($val) {
if (empty($val)) return '';
$result = Encryption::decrypt((string)$val);
return ($result !== false && $result !== null) ? $result : (string)$val;
};
foreach ($invoices as &$inv) {
$inv['supplier_name'] = $dec($inv['supplier_name']);
$inv['supplier_tin'] = $dec($inv['supplier_tin']);
$inv['buyer_name'] = $dec($inv['buyer_name']);
if (!empty($inv['company_name'])) {
$inv['company_name'] = $dec($inv['company_name']);
}
if (!empty($inv['tenant_name'])) {
$inv['tenant_name'] = $dec($inv['tenant_name']);
}
}
json_paginated($invoices, $total, $pagination);
} catch (\Exception $e) {
safe_error($e, 'invoices/index');
}