license changes
This commit is contained in:
parent
7863ad8c93
commit
d9e9da2d7b
@ -79,8 +79,10 @@ body {
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
[dir="ltr"] .sidebar { left: 0; }
|
||||
[dir="rtl"] .sidebar { right: 0; }
|
||||
@media (min-width: 1200px) {
|
||||
[dir="ltr"] .sidebar { left: 0; }
|
||||
[dir="rtl"] .sidebar { right: 0; }
|
||||
}
|
||||
|
||||
.sidebar-header {
|
||||
padding: 1rem;
|
||||
@ -255,12 +257,13 @@ body {
|
||||
margin-right: var(--sidebar-width);
|
||||
}
|
||||
|
||||
@media (max-width: 991.98px) {
|
||||
.sidebar {
|
||||
@media (max-width: 1199.98px) {
|
||||
[dir="ltr"] .sidebar {
|
||||
left: calc(-1 * var(--sidebar-width));
|
||||
}
|
||||
.sidebar.show {
|
||||
[dir="ltr"] .sidebar.show {
|
||||
left: 0;
|
||||
box-shadow: 0 0 50px rgba(0,0,0,0.3);
|
||||
}
|
||||
[dir="rtl"] .sidebar {
|
||||
right: calc(-1 * var(--sidebar-width));
|
||||
@ -268,11 +271,12 @@ body {
|
||||
}
|
||||
[dir="rtl"] .sidebar.show {
|
||||
right: 0;
|
||||
box-shadow: 0 0 50px rgba(0,0,0,0.3);
|
||||
}
|
||||
.main-content {
|
||||
margin-left: 0 !important;
|
||||
margin-right: 0 !important;
|
||||
width: 100%;
|
||||
width: 100% !important;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -31,6 +31,17 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
overlay.classList.remove('show');
|
||||
});
|
||||
|
||||
// Close sidebar when a link is clicked on mobile
|
||||
const sidebarLinks = document.querySelectorAll('.sidebar .nav-link');
|
||||
sidebarLinks.forEach(link => {
|
||||
link.addEventListener('click', function() {
|
||||
if (window.innerWidth <= 1199.98) {
|
||||
sidebar.classList.remove('show');
|
||||
overlay.classList.remove('show');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Sidebar Accordion logic: Close other collapses when one is opened
|
||||
const sidebarCollapses = document.querySelectorAll('.sidebar .collapse');
|
||||
sidebarCollapses.forEach(collapseEl => {
|
||||
|
||||
10
get_schema.php
Normal file
10
get_schema.php
Normal file
@ -0,0 +1,10 @@
|
||||
<?php
|
||||
require_once 'db/config.php';
|
||||
$tables = db()->query("SHOW TABLES")->fetchAll(PDO::FETCH_COLUMN);
|
||||
foreach ($tables as $t) {
|
||||
echo "TABLE: $t\n";
|
||||
$cols = db()->query("SHOW COLUMNS FROM $t")->fetchAll(PDO::FETCH_ASSOC);
|
||||
foreach ($cols as $c) {
|
||||
echo " - {$c['Field']} ({$c['Type']})\n";
|
||||
}
|
||||
}
|
||||
@ -34,6 +34,7 @@ $translations = [
|
||||
'cashflow_report' => 'Cashflow Report',
|
||||
'expiry_report' => 'Expiry Report',
|
||||
'low_stock_report' => 'Low Stock Report',
|
||||
'expense_report' => 'Expense Report',
|
||||
'loyalty_history' => 'Loyalty History',
|
||||
'management' => 'Management',
|
||||
'payment_methods' => 'Payment Methods',
|
||||
@ -128,6 +129,7 @@ $translations = [
|
||||
'cashflow_report' => 'تقرير التدفق النقدي',
|
||||
'expiry_report' => 'تقرير الصلاحية',
|
||||
'low_stock_report' => 'تقرير انخفاض المخزون',
|
||||
'expense_report' => 'تقرير المصاريف',
|
||||
'loyalty_history' => 'سجل الولاء',
|
||||
'management' => 'الإدارة',
|
||||
'payment_methods' => 'طرق الدفع',
|
||||
|
||||
536
index.php
536
index.php
@ -1871,15 +1871,28 @@ if (isset($_POST['add_hr_department'])) {
|
||||
}
|
||||
|
||||
if (isset($_POST['save_backup_settings'])) {
|
||||
if (can('users_view')) {
|
||||
$limit = (int)($_POST['backup_limit'] ?? 5);
|
||||
$auto = $_POST['backup_auto_enabled'] ?? '0';
|
||||
$time = $_POST['backup_time'] ?? '00:00';
|
||||
|
||||
$db = db();
|
||||
$stmt = $db->prepare("INSERT INTO settings (`key`, `value`) VALUES ('backup_limit', ?), ('backup_auto_enabled', ?), ('backup_time', ?) ON DUPLICATE KEY UPDATE `value` = VALUES(`value`)");
|
||||
$stmt->execute([$limit, $auto, $time]);
|
||||
$message = "Backup settings saved successfully!";
|
||||
$message = "Backup settings updated.";
|
||||
}
|
||||
|
||||
if (isset($_GET['download_backup'])) {
|
||||
$filename = basename($_GET['download_backup']);
|
||||
$filepath = __DIR__ . '/backups/' . $filename;
|
||||
if (file_exists($filepath)) {
|
||||
header('Content-Description: File Transfer');
|
||||
header('Content-Type: application/octet-stream');
|
||||
header('Content-Disposition: attachment; filename="' . $filename . '"');
|
||||
header('Expires: 0');
|
||||
header('Cache-Control: must-revalidate');
|
||||
header('Pragma: public');
|
||||
header('Content-Length: ' . filesize($filepath));
|
||||
readfile($filepath);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1983,6 +1996,7 @@ $page_permissions = [
|
||||
'accounting' => 'accounting_view',
|
||||
'expense_categories' => 'expense_categories_view',
|
||||
'expenses' => 'expenses_view',
|
||||
'expense_report' => 'expenses_view',
|
||||
'items' => 'items_view',
|
||||
'categories' => 'categories_view',
|
||||
'units' => 'units_view',
|
||||
@ -2085,6 +2099,7 @@ $permission_groups = [
|
||||
'Reports' => [
|
||||
'customer_statement' => 'Customer Statement',
|
||||
'supplier_statement' => 'Supplier Statement',
|
||||
'expense_report' => 'Expense Report',
|
||||
'cashflow_report' => 'Cashflow Report',
|
||||
'expiry_report' => 'Expiry Report',
|
||||
'low_stock_report' => 'Low Stock Report',
|
||||
@ -2107,19 +2122,31 @@ $permission_groups = [
|
||||
|
||||
if ($page === 'export') {
|
||||
$type = $_GET['type'] ?? 'sales';
|
||||
$filename = $type . "_export_" . date('Y-m-d') . ".csv";
|
||||
$format = $_GET['format'] ?? 'csv';
|
||||
$filename = $type . "_export_" . date('Y-m-d') . ($format === 'excel' ? ".xls" : ".csv");
|
||||
|
||||
header('Content-Type: text/csv; charset=utf-8');
|
||||
header('Content-Disposition: attachment; filename=' . $filename);
|
||||
$output = fopen('php://output', 'w');
|
||||
|
||||
// Add UTF-8 BOM for Excel
|
||||
fprintf($output, chr(0xEF).chr(0xBB).chr(0xBF));
|
||||
if ($format === 'excel') {
|
||||
header('Content-Type: application/vnd.ms-excel; charset=utf-8');
|
||||
header('Content-Disposition: attachment; filename=' . $filename);
|
||||
echo "<table border='1'>";
|
||||
} else {
|
||||
header('Content-Type: text/csv; charset=utf-8');
|
||||
header('Content-Disposition: attachment; filename=' . $filename);
|
||||
$output = fopen('php://output', 'w');
|
||||
// Add UTF-8 BOM for Excel
|
||||
fprintf($output, chr(0xEF).chr(0xBB).chr(0xBF));
|
||||
}
|
||||
|
||||
$headers = [];
|
||||
$rows = [];
|
||||
|
||||
if ($type === 'sales' || $type === 'purchases') {
|
||||
$invType = ($type === 'sales') ? 'sale' : 'purchase';
|
||||
$where = ["v.type = ?"];
|
||||
$params = [$invType];
|
||||
$table = ($type === 'sales') ? 'invoices' : 'purchases';
|
||||
$cust_table = ($type === 'sales') ? 'customers' : 'suppliers';
|
||||
$cust_col = ($type === 'sales') ? 'customer_id' : 'supplier_id';
|
||||
|
||||
$where = ["1=1"];
|
||||
$params = [];
|
||||
if (!empty($_GET['search'])) {
|
||||
$s = $_GET['search'];
|
||||
$clean_id = preg_replace('/[^0-9]/', '', $s);
|
||||
@ -2134,16 +2161,17 @@ if ($page === 'export') {
|
||||
$params[] = "%$s%";
|
||||
}
|
||||
}
|
||||
if (!empty($_GET['customer_id'])) { $where[] = "v.customer_id = ?"; $params[] = $_GET['customer_id']; }
|
||||
if (!empty($_GET['customer_id'])) { $where[] = "v.$cust_col = ?"; $params[] = $_GET['customer_id']; }
|
||||
if (!empty($_GET['start_date'])) { $where[] = "v.invoice_date >= ?"; $params[] = $_GET['start_date']; }
|
||||
if (!empty($_GET['end_date'])) { $where[] = "v.invoice_date <= ?"; $params[] = $_GET['end_date']; }
|
||||
$whereSql = implode(" AND ", $where);
|
||||
|
||||
$stmt = db()->prepare("SELECT v.id, c.name as customer_name, v.invoice_date, v.payment_type, v.status, v.total_with_vat, v.paid_amount, (v.total_with_vat - v.paid_amount) as balance
|
||||
FROM invoices v LEFT JOIN customers c ON v.customer_id = c.id
|
||||
FROM $table v LEFT JOIN $cust_table c ON v.$cust_col = c.id
|
||||
WHERE $whereSql ORDER BY v.id DESC");
|
||||
$stmt->execute($params);
|
||||
fputcsv($output, ['Invoice ID', 'Customer/Supplier', 'Date', 'Payment', 'Status', 'Total', 'Paid', 'Balance']);
|
||||
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) fputcsv($output, $row);
|
||||
$headers = ['Invoice ID', 'Customer/Supplier', 'Date', 'Payment', 'Status', 'Total', 'Paid', 'Balance'];
|
||||
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) $rows[] = $row;
|
||||
} elseif ($type === 'customers' || $type === 'suppliers') {
|
||||
$table = ($type === 'suppliers') ? 'suppliers' : 'customers';
|
||||
$where = ["1=1"];
|
||||
@ -2154,8 +2182,8 @@ if ($page === 'export') {
|
||||
$whereSql = implode(" AND ", $where);
|
||||
$stmt = db()->prepare("SELECT id, name, email, phone, tax_id, balance, created_at FROM $table WHERE $whereSql ORDER BY id DESC");
|
||||
$stmt->execute($params);
|
||||
fputcsv($output, ['ID', 'Name', 'Email', 'Phone', 'Tax ID', 'Balance', 'Created At']);
|
||||
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) fputcsv($output, $row);
|
||||
$headers = ['ID', 'Name', 'Email', 'Phone', 'Tax ID', 'Balance', 'Created At'];
|
||||
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) $rows[] = $row;
|
||||
} elseif ($type === 'items') {
|
||||
$where = ["1=1"];
|
||||
$params = [];
|
||||
@ -2165,10 +2193,84 @@ if ($page === 'export') {
|
||||
FROM stock_items i LEFT JOIN stock_categories c ON i.category_id = c.id
|
||||
WHERE $whereSql ORDER BY i.id DESC");
|
||||
$stmt->execute($params);
|
||||
fputcsv($output, ['SKU', 'Name (EN)', 'Name (AR)', 'Category', 'Purchase Price', 'Sale Price', 'Quantity', 'VAT %']);
|
||||
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) fputcsv($output, $row);
|
||||
$headers = ['SKU', 'Name (EN)', 'Name (AR)', 'Category', 'Purchase Price', 'Sale Price', 'Quantity', 'VAT %'];
|
||||
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) $rows[] = $row;
|
||||
} elseif ($type === 'expenses') {
|
||||
$where = ["1=1"];
|
||||
$params = [];
|
||||
$stmt = db()->prepare("SELECT e.id, c.name_en as category, e.amount, e.expense_date, e.reference_no, e.description
|
||||
FROM expenses e JOIN expense_categories c ON e.category_id = c.id
|
||||
ORDER BY e.expense_date DESC");
|
||||
$stmt->execute();
|
||||
$headers = ['ID', 'Category', 'Amount', 'Date', 'Reference', 'Description'];
|
||||
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) $rows[] = $row;
|
||||
} elseif ($type === 'quotations') {
|
||||
$stmt = db()->prepare("SELECT q.id, c.name as customer_name, q.quotation_date, q.total_with_vat, q.status
|
||||
FROM quotations q JOIN customers c ON q.customer_id = c.id
|
||||
ORDER BY q.id DESC");
|
||||
$stmt->execute();
|
||||
$headers = ['Quotation #', 'Customer', 'Date', 'Total', 'Status'];
|
||||
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) $rows[] = $row;
|
||||
} elseif ($type === 'lpos') {
|
||||
$stmt = db()->prepare("SELECT q.id, s.name as supplier_name, q.lpo_date, q.total_with_vat, q.status
|
||||
FROM lpos q JOIN suppliers s ON q.supplier_id = s.id
|
||||
ORDER BY q.id DESC");
|
||||
$stmt->execute();
|
||||
$headers = ['LPO #', 'Supplier', 'Date', 'Total', 'Status'];
|
||||
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) $rows[] = $row;
|
||||
} elseif ($type === 'categories') {
|
||||
$stmt = db()->query("SELECT id, name_en, name_ar FROM stock_categories ORDER BY id DESC");
|
||||
$headers = ['ID', 'Name (EN)', 'Name (AR)'];
|
||||
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) $rows[] = $row;
|
||||
} elseif ($type === 'units') {
|
||||
$stmt = db()->query("SELECT id, name_en, name_ar, short_name_en, short_name_ar FROM stock_units ORDER BY id DESC");
|
||||
$headers = ['ID', 'Name (EN)', 'Name (AR)', 'Short (EN)', 'Short (AR)'];
|
||||
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) $rows[] = $row;
|
||||
} elseif ($type === 'sales_returns') {
|
||||
$stmt = db()->query("SELECT sr.id, sr.invoice_id, c.name as customer, sr.return_date, sr.total_amount FROM sales_returns sr LEFT JOIN customers c ON sr.customer_id = c.id ORDER BY sr.id DESC");
|
||||
$headers = ['Return ID', 'Invoice ID', 'Customer', 'Date', 'Amount'];
|
||||
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) $rows[] = $row;
|
||||
} elseif ($type === 'purchase_returns') {
|
||||
$stmt = db()->query("SELECT pr.id, pr.purchase_id, s.name as supplier, pr.return_date, pr.total_amount FROM purchase_returns pr LEFT JOIN suppliers s ON pr.supplier_id = s.id ORDER BY pr.id DESC");
|
||||
$headers = ['Return ID', 'Purchase ID', 'Supplier', 'Date', 'Amount'];
|
||||
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) $rows[] = $row;
|
||||
} elseif ($type === 'hr_employees') {
|
||||
$stmt = db()->query("SELECT e.id, e.name, d.name as department, e.position, e.salary, e.status FROM hr_employees e LEFT JOIN hr_departments d ON e.department_id = d.id ORDER BY e.id DESC");
|
||||
$headers = ['ID', 'Name', 'Department', 'Position', 'Salary', 'Status'];
|
||||
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) $rows[] = $row;
|
||||
} elseif ($type === 'hr_departments') {
|
||||
$stmt = db()->query("SELECT id, name FROM hr_departments ORDER BY id DESC");
|
||||
$headers = ['ID', 'Name'];
|
||||
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) $rows[] = $row;
|
||||
} elseif ($type === 'hr_attendance') {
|
||||
$stmt = db()->query("SELECT a.attendance_date, e.name, a.status, a.clock_in, a.clock_out FROM hr_attendance a JOIN hr_employees e ON a.employee_id = e.id ORDER BY a.attendance_date DESC, e.name ASC");
|
||||
$headers = ['Date', 'Employee', 'Status', 'In', 'Out'];
|
||||
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) $rows[] = $row;
|
||||
} elseif ($type === 'hr_payroll') {
|
||||
$stmt = db()->query("SELECT p.payroll_month, p.payroll_year, e.name, p.basic_salary, p.bonus, p.deductions, p.net_salary, p.status FROM hr_payroll p JOIN hr_employees e ON p.employee_id = e.id ORDER BY p.payroll_year DESC, p.payroll_month DESC");
|
||||
$headers = ['Month', 'Year', 'Employee', 'Salary', 'Bonus', 'Deductions', 'Net', 'Status'];
|
||||
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) $rows[] = $row;
|
||||
} elseif ($type === 'users') {
|
||||
$stmt = db()->query("SELECT u.id, u.username, u.email, g.name as role, u.status FROM users u LEFT JOIN role_groups g ON u.group_id = g.id ORDER BY u.id DESC");
|
||||
$headers = ['ID', 'Username', 'Email', 'Role', 'Status'];
|
||||
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) $rows[] = $row;
|
||||
}
|
||||
|
||||
if ($format === 'excel') {
|
||||
echo "<tr>";
|
||||
foreach ($headers as $h) echo "<th>" . htmlspecialchars($h) . "</th>";
|
||||
echo "</tr>";
|
||||
foreach ($rows as $row) {
|
||||
echo "<tr>";
|
||||
foreach ($row as $val) echo "<td>" . htmlspecialchars((string)$val) . "</td>";
|
||||
echo "</tr>";
|
||||
}
|
||||
echo "</table>";
|
||||
} else {
|
||||
fputcsv($output, $headers);
|
||||
foreach ($rows as $row) fputcsv($output, $row);
|
||||
fclose($output);
|
||||
}
|
||||
fclose($output);
|
||||
exit;
|
||||
}
|
||||
|
||||
@ -2396,6 +2498,15 @@ switch ($page) {
|
||||
$data['invoices'] = $stmt->fetchAll();
|
||||
foreach ($data['invoices'] as &$inv) {
|
||||
$inv['total_in_words'] = numberToWordsOMR($inv['total_with_vat']);
|
||||
if ($type === 'sale') {
|
||||
$item_stmt = db()->prepare("SELECT ii.*, i.name_en, i.name_ar, i.vat_rate FROM invoice_items ii LEFT JOIN stock_items i ON ii.item_id = i.id WHERE ii.invoice_id = ?");
|
||||
$item_stmt->execute([$inv['id']]);
|
||||
$inv['items'] = $item_stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
} else {
|
||||
$item_stmt = db()->prepare("SELECT pi.*, i.name_en, i.name_ar, i.vat_rate FROM purchase_items pi LEFT JOIN stock_items i ON pi.item_id = i.id WHERE pi.purchase_id = ?");
|
||||
$item_stmt->execute([$inv['id']]);
|
||||
$inv['items'] = $item_stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
}
|
||||
}
|
||||
unset($inv);
|
||||
|
||||
@ -2609,19 +2720,30 @@ switch ($page) {
|
||||
case 'expense_report':
|
||||
$start_date = $_GET['start_date'] ?? date('Y-m-01');
|
||||
$end_date = $_GET['end_date'] ?? date('Y-m-d');
|
||||
$category_id = $_GET['category_id'] ?? '';
|
||||
|
||||
$where = "WHERE e.expense_date BETWEEN ? AND ?";
|
||||
$params = [$start_date, $end_date];
|
||||
|
||||
if ($category_id !== '') {
|
||||
$where .= " AND e.category_id = ?";
|
||||
$params[] = $category_id;
|
||||
}
|
||||
|
||||
$stmt = db()->prepare("SELECT c.name_en, c.name_ar, SUM(e.amount) as total
|
||||
FROM expenses e
|
||||
JOIN expense_categories c ON e.category_id = c.id
|
||||
WHERE e.expense_date BETWEEN ? AND ?
|
||||
$where
|
||||
GROUP BY c.id
|
||||
ORDER BY total DESC");
|
||||
$stmt->execute([$start_date, $end_date]);
|
||||
$stmt->execute($params);
|
||||
$data['report_by_category'] = $stmt->fetchAll();
|
||||
|
||||
$stmt = db()->prepare("SELECT SUM(amount) FROM expenses WHERE expense_date BETWEEN ? AND ?");
|
||||
$stmt->execute([$start_date, $end_date]);
|
||||
$stmt = db()->prepare("SELECT SUM(amount) FROM expenses e $where");
|
||||
$stmt->execute($params);
|
||||
$data['total_expenses'] = $stmt->fetchColumn() ?: 0;
|
||||
|
||||
$data['expense_categories'] = db()->query("SELECT * FROM expense_categories ORDER BY name_en ASC")->fetchAll();
|
||||
break;
|
||||
case 'expiry_report':
|
||||
$where = ["expiry_date IS NOT NULL"];
|
||||
@ -2830,9 +2952,19 @@ $projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? 'Accounting System';
|
||||
<link rel="stylesheet" href="assets/css/custom.css?v=<?php echo time(); ?>">
|
||||
<style>
|
||||
@media print {
|
||||
.sidebar, .topbar, .d-print-none, .no-print { display: none !important; }
|
||||
.main-content { margin: 0 !important; padding: 0 !important; }
|
||||
.sidebar, .topbar, .d-print-none, .no-print, .btn-group, .btn, .badge i { display: none !important; }
|
||||
.main-content { margin: 0 !important; padding: 0 !important; background: white !important; width: 100% !important; }
|
||||
.card { border: none !important; box-shadow: none !important; padding: 0 !important; margin: 0 !important; }
|
||||
.table { border-collapse: collapse !important; width: 100% !important; margin-top: 20px !important; }
|
||||
.table th, .table td { border: 1px solid #000 !important; padding: 8px !important; font-size: 11px !important; color: #000 !important; }
|
||||
.table thead th { background-color: #eee !important; color: #000 !important; font-weight: bold !important; text-transform: uppercase; }
|
||||
.print-only { display: block !important; }
|
||||
.text-success, .text-danger, .text-primary, .text-warning { color: #000 !important; }
|
||||
.badge { border: none !important; padding: 0 !important; color: #000 !important; background: transparent !important; font-weight: normal !important; }
|
||||
body { font-size: 12px !important; color: #000 !important; background: #fff !important; }
|
||||
@page { margin: 1cm; }
|
||||
}
|
||||
.print-only { display: none; }
|
||||
[dir="rtl"] { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; }
|
||||
</style>
|
||||
</head>
|
||||
@ -3029,16 +3161,18 @@ $projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? 'Accounting System';
|
||||
|
||||
<!-- Reports Section -->
|
||||
<?php if (can('sales_view') || can('purchases_view') || can('items_view') || can('customers_view') || can('suppliers_view')): ?>
|
||||
<div class="nav-section-title px-4 mt-3 mb-1 text-uppercase text-muted <?= !in_array($page, ['customer_statement', 'supplier_statement', 'cashflow_report', 'expiry_report', 'low_stock_report']) ? 'collapsed' : '' ?>" data-bs-toggle="collapse" data-bs-target="#reports-collapse">
|
||||
<div class="nav-section-title px-4 mt-3 mb-1 text-uppercase text-muted <?= !in_array($page, ['customer_statement', 'supplier_statement', 'cashflow_report', 'expense_report', 'expiry_report', 'low_stock_report']) ? 'collapsed' : '' ?>" data-bs-toggle="collapse" data-bs-target="#reports-collapse">
|
||||
<span><i class="fas fa-chart-line group-icon"></i><span><?= __('reports') ?></span></span>
|
||||
<i class="fas fa-chevron-down chevron"></i>
|
||||
</div>
|
||||
<div class="collapse <?= in_array($page, ['customer_statement', 'supplier_statement', 'cashflow_report', 'expiry_report', 'low_stock_report', 'loyalty_history']) ? 'show' : '' ?>" id="reports-collapse">
|
||||
<?php if (can('customers_view')): ?>
|
||||
<div class="collapse <?= in_array($page, ['customer_statement', 'supplier_statement', 'cashflow_report', 'expense_report', 'expiry_report', 'low_stock_report', 'loyalty_history']) ? 'show' : '' ?>" id="reports-collapse">
|
||||
<?php if (can('expenses_view')): ?>
|
||||
<a href="index.php?page=expense_report" class="nav-link <?= isset($_GET['page']) && $_GET['page'] === 'expense_report' ? 'active' : '' ?>">
|
||||
<i class="fas fa-file-invoice-dollar"></i> <span><?= __('expense_report') ?></span>
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
<a href="index.php?page=customer_statement" class="nav-link <?= isset($_GET['page']) && $_GET['page'] === 'customer_statement' ? 'active' : '' ?>">
|
||||
<i class="fas fa-file-invoice"></i> <span><?= __('customer_statement') ?></span>
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
<?php if (can('suppliers_view')): ?>
|
||||
<a href="index.php?page=supplier_statement" class="nav-link <?= isset($_GET['page']) && $_GET['page'] === 'supplier_statement' ? 'active' : '' ?>">
|
||||
<i class="fas fa-file-lines"></i> <span><?= __('supplier_statement') ?></span>
|
||||
@ -3472,6 +3606,9 @@ $projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? 'Accounting System';
|
||||
<h5 class="m-0" data-en="<?= $currTitle['en'] ?> Management" data-ar="إدارة <?= $currTitle['ar'] ?>"><?= $currTitle['en'] ?> Management</h5>
|
||||
<div>
|
||||
<?php if (can('customers_add') || can('suppliers_add')): ?>
|
||||
<a href="index.php?<?= http_build_query(array_merge($_GET, ['page' => 'export', 'type' => $page, 'format' => 'excel'])) ?>" class="btn btn-outline-success me-2">
|
||||
<i class="bi bi-file-earmark-excel"></i> <span data-en="Export to Excel" data-ar="تصدير إلى اكسل">Export to Excel</span>
|
||||
</a>
|
||||
<button class="btn btn-outline-success me-2" data-bs-toggle="modal" data-bs-target="<?= $page === 'suppliers' ? '#importSuppliersModal' : '#importCustomersModal' ?>">
|
||||
<i class="bi bi-file-earmark-excel"></i> <span data-en="Import Excel" data-ar="استيراد من اكسل">Import Excel</span>
|
||||
</button>
|
||||
@ -3502,9 +3639,15 @@ $projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? 'Accounting System';
|
||||
<button type="submit" class="btn btn-primary flex-grow-1">
|
||||
<i class="bi bi-filter"></i> <span data-en="Filter" data-ar="تصفية">Filter</span>
|
||||
</button>
|
||||
<a href="index.php?<?= http_build_query(array_merge($_GET, ['page' => 'export', 'type' => $page])) ?>" class="btn btn-outline-success">
|
||||
<i class="bi bi-download"></i> <span data-en="Export" data-ar="تصدير">Export</span>
|
||||
</a>
|
||||
<div class="dropdown d-inline-block">
|
||||
<button class="btn btn-outline-success dropdown-toggle" type="button" data-bs-toggle="dropdown">
|
||||
<i class="bi bi-download"></i> <span data-en="Export" data-ar="تصدير">Export</span>
|
||||
</button>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a class="dropdown-item" href="index.php?<?= http_build_query(array_merge($_GET, ['page' => 'export', 'type' => $page, 'format' => 'csv'])) ?>"><i class="bi bi-filetype-csv me-2"></i> CSV</a></li>
|
||||
<li><a class="dropdown-item" href="index.php?<?= http_build_query(array_merge($_GET, ['page' => 'export', 'type' => $page, 'format' => 'excel'])) ?>"><i class="bi bi-file-earmark-excel me-2"></i> Excel</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<?php if (!empty($_GET['search']) || !empty($_GET['start_date']) || !empty($_GET['end_date'])): ?>
|
||||
<a href="index.php?page=<?= $page ?>" class="btn btn-outline-secondary">
|
||||
<i class="bi bi-x-lg"></i>
|
||||
@ -3601,6 +3744,9 @@ $projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? 'Accounting System';
|
||||
<h5 class="m-0" data-en="Stock Categories Management" data-ar="إدارة فئات المخزون">Stock Categories Management</h5>
|
||||
<div>
|
||||
<?php if (can('categories_add')): ?>
|
||||
<a href="index.php?page=export&type=categories&format=excel" class="btn btn-outline-success me-2">
|
||||
<i class="bi bi-download"></i> <span data-en="Export" data-ar="تصدير">Export</span>
|
||||
</a>
|
||||
<button class="btn btn-outline-success me-2" data-bs-toggle="modal" data-bs-target="#importCategoriesModal">
|
||||
<i class="bi bi-file-earmark-excel"></i> <span data-en="Import Excel" data-ar="استيراد من اكسل">Import Excel</span>
|
||||
</button>
|
||||
@ -3691,6 +3837,9 @@ $projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? 'Accounting System';
|
||||
<h5 class="m-0" data-en="Stock Units Management" data-ar="إدارة وحدات المخزون">Stock Units Management</h5>
|
||||
<div>
|
||||
<?php if (can('units_add')): ?>
|
||||
<a href="index.php?page=export&type=units&format=excel" class="btn btn-outline-success me-2">
|
||||
<i class="bi bi-download"></i> <span data-en="Export" data-ar="تصدير">Export</span>
|
||||
</a>
|
||||
<button class="btn btn-outline-success me-2" data-bs-toggle="modal" data-bs-target="#importUnitsModal">
|
||||
<i class="bi bi-file-earmark-excel"></i> <span data-en="Import Excel" data-ar="استيراد من اكسل">Import Excel</span>
|
||||
</button>
|
||||
@ -3804,6 +3953,9 @@ $projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? 'Accounting System';
|
||||
<button class="btn btn-outline-success me-2" data-bs-toggle="modal" data-bs-target="#importItemsModal">
|
||||
<i class="bi bi-file-earmark-excel"></i> <span data-en="Import Excel" data-ar="استيراد من اكسل">Import Excel</span>
|
||||
</button>
|
||||
<a href="index.php?<?= http_build_query(array_merge($_GET, ['page' => 'export', 'type' => 'items', 'format' => 'excel'])) ?>" class="btn btn-outline-success me-2">
|
||||
<i class="bi bi-file-earmark-excel"></i> <span data-en="Export to Excel" data-ar="تصدير إلى اكسل">Export to Excel</span>
|
||||
</a>
|
||||
<button class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#addItemModal">
|
||||
<i class="bi bi-plus-lg"></i> <span data-en="Add Item" data-ar="إضافة صنف">Add Item</span>
|
||||
</button>
|
||||
@ -3822,9 +3974,15 @@ $projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? 'Accounting System';
|
||||
<button type="submit" class="btn btn-primary flex-grow-1">
|
||||
<i class="bi bi-search"></i> <span data-en="Search" data-ar="بحث">Search</span>
|
||||
</button>
|
||||
<a href="index.php?<?= http_build_query(array_merge($_GET, ['page' => 'export', 'type' => 'items'])) ?>" class="btn btn-outline-success">
|
||||
<i class="bi bi-download"></i> <span data-en="Export" data-ar="تصدير">Export</span>
|
||||
</a>
|
||||
<div class="dropdown d-inline-block">
|
||||
<button class="btn btn-outline-success dropdown-toggle" type="button" data-bs-toggle="dropdown">
|
||||
<i class="bi bi-download"></i> <span data-en="Export" data-ar="تصدير">Export</span>
|
||||
</button>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a class="dropdown-item" href="index.php?<?= http_build_query(array_merge($_GET, ['page' => 'export', 'type' => 'items', 'format' => 'csv'])) ?>"><i class="bi bi-filetype-csv me-2"></i> CSV</a></li>
|
||||
<li><a class="dropdown-item" href="index.php?<?= http_build_query(array_merge($_GET, ['page' => 'export', 'type' => 'items', 'format' => 'excel'])) ?>"><i class="bi bi-file-earmark-excel me-2"></i> Excel</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<?php if (!empty($_GET['search'])): ?>
|
||||
<a href="index.php?page=items" class="btn btn-outline-secondary">
|
||||
<i class="bi bi-x-lg"></i>
|
||||
@ -4064,10 +4222,21 @@ $projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? 'Accounting System';
|
||||
<div class="card p-4">
|
||||
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||
<h5 class="m-0" data-en="Expiry Report" data-ar="تقرير انتهاء الصلاحية">Expiry Report</h5>
|
||||
<div class="d-flex gap-2">
|
||||
<a href="index.php?page=expiry_report&filter=all" class="btn btn-sm <?= !isset($_GET['filter']) || $_GET['filter'] === 'all' ? 'btn-primary' : 'btn-outline-primary' ?>" data-en="All" data-ar="الكل">All</a>
|
||||
<a href="index.php?page=expiry_report&filter=expired" class="btn btn-sm <?= isset($_GET['filter']) && $_GET['filter'] === 'expired' ? 'btn-danger' : 'btn-outline-danger' ?>" data-en="Expired" data-ar="منتهي">Expired</a>
|
||||
<a href="index.php?page=expiry_report&filter=near_expiry" class="btn btn-sm <?= isset($_GET['filter']) && $_GET['filter'] === 'near_expiry' ? 'btn-warning' : 'btn-outline-warning' ?>" data-en="Near Expiry" data-ar="قريب الانتهاء">Near Expiry</a>
|
||||
<div class="d-flex align-items-center gap-2">
|
||||
<div class="dropdown d-inline-block">
|
||||
<button class="btn btn-outline-success btn-sm dropdown-toggle" type="button" data-bs-toggle="dropdown">
|
||||
<i class="bi bi-download"></i> <span data-en="Export" data-ar="تصدير">Export</span>
|
||||
</button>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a class="dropdown-item" href="index.php?<?= http_build_query(array_merge($_GET, ['page' => 'export', 'type' => 'expiry_report', 'format' => 'csv'])) ?>"><i class="bi bi-filetype-csv me-2"></i> CSV</a></li>
|
||||
<li><a class="dropdown-item" href="index.php?<?= http_build_query(array_merge($_GET, ['page' => 'export', 'type' => 'expiry_report', 'format' => 'excel'])) ?>"><i class="bi bi-file-earmark-excel me-2"></i> Excel</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="d-flex gap-2">
|
||||
<a href="index.php?page=expiry_report&filter=all" class="btn btn-sm <?= !isset($_GET['filter']) || $_GET['filter'] === 'all' ? 'btn-primary' : 'btn-outline-primary' ?>" data-en="All" data-ar="الكل">All</a>
|
||||
<a href="index.php?page=expiry_report&filter=expired" class="btn btn-sm <?= isset($_GET['filter']) && $_GET['filter'] === 'expired' ? 'btn-danger' : 'btn-outline-danger' ?>" data-en="Expired" data-ar="منتهي">Expired</a>
|
||||
<a href="index.php?page=expiry_report&filter=near_expiry" class="btn btn-sm <?= isset($_GET['filter']) && $_GET['filter'] === 'near_expiry' ? 'btn-warning' : 'btn-outline-warning' ?>" data-en="Near Expiry" data-ar="قريب الانتهاء">Near Expiry</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="table-responsive">
|
||||
@ -5394,6 +5563,15 @@ $projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? 'Accounting System';
|
||||
<button type="submit" class="btn btn-primary btn-sm flex-grow-1">
|
||||
<i class="bi bi-filter"></i> <span data-en="Filter" data-ar="تصفية">Filter</span>
|
||||
</button>
|
||||
<div class="dropdown d-inline-block">
|
||||
<button class="btn btn-outline-success btn-sm dropdown-toggle" type="button" data-bs-toggle="dropdown">
|
||||
<i class="bi bi-download"></i> <span data-en="Export" data-ar="تصدير">Export</span>
|
||||
</button>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a class="dropdown-item" href="index.php?<?= http_build_query(array_merge($_GET, ['page' => 'export', 'type' => 'quotations', 'format' => 'csv'])) ?>"><i class="bi bi-filetype-csv me-2"></i> CSV</a></li>
|
||||
<li><a class="dropdown-item" href="index.php?<?= http_build_query(array_merge($_GET, ['page' => 'export', 'type' => 'quotations', 'format' => 'excel'])) ?>"><i class="bi bi-file-earmark-excel me-2"></i> Excel</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<a href="index.php?page=quotations" class="btn btn-outline-secondary btn-sm flex-grow-1">
|
||||
<i class="bi bi-x-circle"></i> <span data-en="Clear" data-ar="مسح">Clear</span>
|
||||
</a>
|
||||
@ -5497,6 +5675,15 @@ $projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? 'Accounting System';
|
||||
<button type="submit" class="btn btn-primary btn-sm flex-grow-1">
|
||||
<i class="bi bi-filter"></i> <span data-en="Filter" data-ar="تصفية">Filter</span>
|
||||
</button>
|
||||
<div class="dropdown d-inline-block">
|
||||
<button class="btn btn-outline-success btn-sm dropdown-toggle" type="button" data-bs-toggle="dropdown">
|
||||
<i class="bi bi-download"></i> <span data-en="Export" data-ar="تصدير">Export</span>
|
||||
</button>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a class="dropdown-item" href="index.php?<?= http_build_query(array_merge($_GET, ['page' => 'export', 'type' => 'lpos', 'format' => 'csv'])) ?>"><i class="bi bi-filetype-csv me-2"></i> CSV</a></li>
|
||||
<li><a class="dropdown-item" href="index.php?<?= http_build_query(array_merge($_GET, ['page' => 'export', 'type' => 'lpos', 'format' => 'excel'])) ?>"><i class="bi bi-file-earmark-excel me-2"></i> Excel</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<a href="index.php?page=lpos" class="btn btn-outline-secondary btn-sm flex-grow-1">
|
||||
<i class="bi bi-x-circle"></i> <span data-en="Clear" data-ar="مسح">Clear</span>
|
||||
</a>
|
||||
@ -5563,17 +5750,57 @@ $projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? 'Accounting System';
|
||||
|
||||
<?php elseif ($page === 'sales' || $page === 'purchases'): ?>
|
||||
<div class="card p-4">
|
||||
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||
<!-- Print Header -->
|
||||
<div class="print-only mb-4">
|
||||
<div class="row align-items-center">
|
||||
<div class="col-6">
|
||||
<?php if (!empty($data['settings']['company_logo'])): ?>
|
||||
<img src="<?= htmlspecialchars($data['settings']['company_logo']) ?>" alt="Logo" style="max-height: 80px;" class="mb-2">
|
||||
<?php endif; ?>
|
||||
<h3 class="mb-1 fw-bold"><?= htmlspecialchars($data['settings']['company_name'] ?? 'Accounting System') ?></h3>
|
||||
<p class="text-muted small mb-0"><?= nl2br(htmlspecialchars($data['settings']['company_address'] ?? '')) ?></p>
|
||||
<p class="text-muted small mb-0">VAT: <?= htmlspecialchars($data['settings']['vat_number'] ?? '') ?></p>
|
||||
</div>
|
||||
<div class="col-6 text-end">
|
||||
<h2 class="text-uppercase text-muted"><?= $currTitle['en'] ?> Report</h2>
|
||||
<p class="mb-0">Date: <?= date('Y-m-d') ?></p>
|
||||
<?php if (!empty($_GET['start_date']) || !empty($_GET['end_date']) || !empty($_GET['customer_id'])): ?>
|
||||
<p class="small text-muted mb-0">
|
||||
<?php if (!empty($_GET['customer_id'])): ?>
|
||||
<strong><?= $page === 'sales' ? 'Customer' : 'Supplier' ?>:</strong>
|
||||
<?php
|
||||
foreach ($data['customers_list'] as $c) {
|
||||
if ($c['id'] == $_GET['customer_id']) {
|
||||
echo htmlspecialchars($c['name']);
|
||||
break;
|
||||
}
|
||||
}
|
||||
?> |
|
||||
<?php endif; ?>
|
||||
<strong>Period:</strong> <?= !empty($_GET['start_date']) ? $_GET['start_date'] : 'All' ?> to <?= !empty($_GET['end_date']) ? $_GET['end_date'] : 'All' ?>
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
</div>
|
||||
|
||||
<div class="d-flex justify-content-between align-items-center mb-4 d-print-none">
|
||||
<h5 class="m-0" data-en="<?= $currTitle['en'] ?>" data-ar="<?= $currTitle['ar'] ?>"><?= $currTitle['en'] ?></h5>
|
||||
<?php if (can($page . '_add')): ?>
|
||||
<button class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#addInvoiceModal">
|
||||
<i class="bi bi-plus-lg"></i> <span data-en="Create New Tax Invoice" data-ar="إنشاء فاتورة ضريبية جديدة">Create New Tax Invoice</span>
|
||||
</button>
|
||||
<?php endif; ?>
|
||||
<div class="d-flex gap-2">
|
||||
<a href="index.php?<?= http_build_query(array_merge($_GET, ['page' => 'export', 'type' => $page, 'format' => 'excel'])) ?>" class="btn btn-outline-success">
|
||||
<i class="bi bi-file-earmark-excel"></i> <span data-en="Export to Excel" data-ar="تصدير إلى اكسل">Export to Excel</span>
|
||||
</a>
|
||||
<?php if (can($page . '_add')): ?>
|
||||
<button class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#addInvoiceModal">
|
||||
<i class="bi bi-plus-lg"></i> <span data-en="Create New Tax Invoice" data-ar="إنشاء فاتورة ضريبية جديدة">Create New Tax Invoice</span>
|
||||
</button>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Filters Section -->
|
||||
<div class="bg-light p-3 rounded mb-4">
|
||||
<div class="bg-light p-3 rounded mb-4 d-print-none">
|
||||
<form method="GET" class="row g-3">
|
||||
<input type="hidden" name="page" value="<?= $page ?>">
|
||||
<div class="col-md-3">
|
||||
@ -5601,9 +5828,15 @@ $projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? 'Accounting System';
|
||||
<button type="submit" class="btn btn-primary btn-sm flex-grow-1">
|
||||
<i class="bi bi-filter"></i> <span data-en="Filter" data-ar="تصفية">Filter</span>
|
||||
</button>
|
||||
<a href="index.php?<?= http_build_query(array_merge($_GET, ['page' => 'export', 'type' => $page])) ?>" class="btn btn-success btn-sm">
|
||||
<i class="bi bi-download"></i> <span data-en="Export" data-ar="تصدير">Export</span>
|
||||
</a>
|
||||
<div class="dropdown d-inline-block">
|
||||
<button class="btn btn-success btn-sm dropdown-toggle" type="button" data-bs-toggle="dropdown">
|
||||
<i class="bi bi-download"></i> <span data-en="Export" data-ar="تصدير">Export</span>
|
||||
</button>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a class="dropdown-item" href="index.php?<?= http_build_query(array_merge($_GET, ['page' => 'export', 'type' => $page, 'format' => 'csv'])) ?>"><i class="bi bi-filetype-csv me-2"></i> CSV</a></li>
|
||||
<li><a class="dropdown-item" href="index.php?<?= http_build_query(array_merge($_GET, ['page' => 'export', 'type' => $page, 'format' => 'excel'])) ?>"><i class="bi bi-file-earmark-excel me-2"></i> Excel</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<button type="button" class="btn btn-outline-primary btn-sm" onclick="window.print()">
|
||||
<i class="bi bi-printer"></i> <span data-en="Print" data-ar="طباعة">Print</span>
|
||||
</button>
|
||||
@ -5754,7 +5987,7 @@ $projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? 'Accounting System';
|
||||
<div class="col-6 text-end">
|
||||
<h2 class="text-uppercase text-muted" data-en="Statement of Account" data-ar="كشف حساب">Statement of Account</h2>
|
||||
<p class="mb-0"><strong><?= htmlspecialchars($data['selected_entity']['name']) ?></strong></p>
|
||||
<p class="text-muted small"><?= htmlspecialchars($data['selected_entity']['email']) ?> | <?= htmlspecialchars($data['selected_entity']['phone']) ?><br>Period: <?= $_GET['start_date'] ?> to <?= $_GET['end_date'] ?></p>
|
||||
<p class="text-muted small"><?= htmlspecialchars($data['selected_entity']['email']) ?> | <?= htmlspecialchars($data['selected_entity']['phone']) ?><br><span data-en="Period" data-ar="الفترة">Period</span>: <?= $_GET['start_date'] ?> <span data-en="to" data-ar="إلى">to</span> <?= $_GET['end_date'] ?></p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="table-responsive">
|
||||
@ -5784,7 +6017,13 @@ $projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? 'Accounting System';
|
||||
<tr>
|
||||
<td><?= $t['trans_date'] ?></td>
|
||||
<td><?= $t['trans_type'] === 'invoice' ? ($page === 'supplier_statement' ? 'PUR-' : 'INV-').str_pad((string)$t['ref_no'], 5, '0', STR_PAD_LEFT) : 'RCP-'.str_pad((string)$t['id'], 5, '0', STR_PAD_LEFT) ?></td>
|
||||
<td><?= $t['trans_type'] === 'invoice' ? 'Tax Invoice' : 'Payment - '.$t['payment_method'] ?></td>
|
||||
<td>
|
||||
<?php if ($t['trans_type'] === 'invoice'): ?>
|
||||
<span data-en="Tax Invoice" data-ar="فاتورة ضريبية">Tax Invoice</span>
|
||||
<?php else: ?>
|
||||
<span data-en="Payment" data-ar="دفع">Payment</span> - <span data-en="<?= $t['payment_method'] ?>" data-ar="<?= $t['payment_method'] === 'cash' ? 'نقد' : ($t['payment_method'] === 'card' ? 'بطاقة ائتمان' : 'آجل') ?>"><?= $t['payment_method'] ?></span>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td class="text-end"><?= $debit > 0 ? number_format($debit, 3) : '' ?></td>
|
||||
<td class="text-end"><?= $credit > 0 ? number_format($credit, 3) : '' ?></td>
|
||||
<td class="text-end fw-bold"><?= number_format($running_balance, 3) ?></td>
|
||||
@ -5793,15 +6032,33 @@ $projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? 'Accounting System';
|
||||
</tbody>
|
||||
<tfoot class="bg-light fw-bold">
|
||||
<tr>
|
||||
<td colspan="5" class="text-end">Closing Balance</td>
|
||||
<td colspan="5" class="text-end" data-en="Closing Balance" data-ar="رصيد الإقفال">Closing Balance</td>
|
||||
<td class="text-end">OMR <?= number_format($running_balance, 3) ?></td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<!-- Print Footer / Signatures -->
|
||||
<div class="print-only mt-5">
|
||||
<div class="row text-center mt-5">
|
||||
<div class="col-4">
|
||||
<div class="border-top pt-2" data-en="Prepared By" data-ar="أعد بواسطة">Prepared By</div>
|
||||
</div>
|
||||
<div class="col-4">
|
||||
<div class="border-top pt-2" data-en="Checked By" data-ar="روجع بواسطة">Checked By</div>
|
||||
</div>
|
||||
<div class="col-4">
|
||||
<div class="border-top pt-2" data-en="Authorized Signature" data-ar="التوقيع المعتمد">Authorized Signature</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-4 text-center text-muted small">
|
||||
<span data-en="Printed on" data-ar="طبع في">Printed on</span> <?= date('Y-m-d H:i:s') ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="text-center py-5 text-muted"><p>Please select an entity and date range to generate the statement.</p></div>
|
||||
<div class="text-center py-5 text-muted"><p data-en="Please select an entity and date range to generate the statement." data-ar="يرجى اختيار جهة ونطاق تاريخي لتوليد كشف الحساب.">Please select an entity and date range to generate the statement.</p></div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
@ -6499,8 +6756,17 @@ $projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? 'Accounting System';
|
||||
<label class="form-label small">End Date</label>
|
||||
<input type="date" name="end_date" class="form-control" value="<?= htmlspecialchars($_GET['end_date'] ?? '') ?>">
|
||||
</div>
|
||||
<div class="col-md-3 d-flex align-items-end">
|
||||
<button type="submit" class="btn btn-primary w-100">Filter</button>
|
||||
<div class="col-md-3 d-flex align-items-end gap-1">
|
||||
<button type="submit" class="btn btn-primary flex-grow-1">Filter</button>
|
||||
<div class="dropdown d-inline-block">
|
||||
<button class="btn btn-outline-success dropdown-toggle" type="button" data-bs-toggle="dropdown">
|
||||
<i class="bi bi-download"></i> <span data-en="Export" data-ar="تصدير">Export</span>
|
||||
</button>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a class="dropdown-item" href="index.php?<?= http_build_query(array_merge($_GET, ['page' => 'export', 'type' => 'expenses', 'format' => 'csv'])) ?>"><i class="bi bi-filetype-csv me-2"></i> CSV</a></li>
|
||||
<li><a class="dropdown-item" href="index.php?<?= http_build_query(array_merge($_GET, ['page' => 'export', 'type' => 'expenses', 'format' => 'excel'])) ?>"><i class="bi bi-file-earmark-excel me-2"></i> Excel</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
@ -6633,80 +6899,154 @@ $projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? 'Accounting System';
|
||||
|
||||
<?php elseif ($page === 'expense_report'): ?>
|
||||
<div class="card p-4">
|
||||
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||
<!-- Formal Print Header -->
|
||||
<div class="print-only mb-4">
|
||||
<div class="row align-items-center">
|
||||
<div class="col-6">
|
||||
<?php if (!empty($data['settings']['company_logo'])): ?>
|
||||
<img src="<?= htmlspecialchars($data['settings']['company_logo']) ?>" alt="Logo" style="max-height: 80px;" class="mb-2">
|
||||
<?php endif; ?>
|
||||
<h3 class="mb-1 fw-bold"><?= htmlspecialchars($data['settings']['company_name'] ?? 'Accounting System') ?></h3>
|
||||
<p class="text-muted small mb-0"><?= nl2br(htmlspecialchars($data['settings']['company_address'] ?? '')) ?></p>
|
||||
<p class="text-muted small mb-0">VAT: <?= htmlspecialchars($data['settings']['vat_number'] ?? '') ?></p>
|
||||
</div>
|
||||
<div class="col-6 text-end">
|
||||
<h2 class="text-uppercase text-muted" data-en="Expense Report" data-ar="تقرير المصروفات">Expense Report</h2>
|
||||
<p class="mb-0">Date: <?= date('Y-m-d') ?></p>
|
||||
<p class="mb-0">Period: <?= htmlspecialchars($_GET['start_date'] ?? date('Y-m-01')) ?> - <?= htmlspecialchars($_GET['end_date'] ?? date('Y-m-d')) ?></p>
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
</div>
|
||||
|
||||
<div class="d-flex justify-content-between align-items-center mb-4 d-print-none">
|
||||
<h5 class="m-0" data-en="Expense Report" data-ar="تقرير المصروفات">Expense Report</h5>
|
||||
<button class="btn btn-outline-secondary d-print-none" onclick="window.print()">
|
||||
<i class="bi bi-printer"></i> Print
|
||||
<button class="btn btn-outline-secondary" onclick="window.print()">
|
||||
<i class="bi bi-printer"></i> <span data-en="Print" data-ar="طباعة">Print</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="bg-light p-3 rounded mb-4 d-print-none">
|
||||
<form method="GET" class="row g-3">
|
||||
<input type="hidden" name="page" value="expense_report">
|
||||
<div class="col-md-4">
|
||||
<label class="form-label small">From Date</label>
|
||||
<input type="date" name="start_date" class="form-control" value="<?= htmlspecialchars($_GET['start_date'] ?? date('Y-m-01')) ?>">
|
||||
<div class="col-md-3">
|
||||
<label class="form-label small fw-bold" data-en="From Date" data-ar="من تاريخ">From Date</label>
|
||||
<input type="date" name="start_date" class="form-control form-control-sm" value="<?= htmlspecialchars($_GET['start_date'] ?? date('Y-m-01')) ?>">
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label small">To Date</label>
|
||||
<input type="date" name="end_date" class="form-control" value="<?= htmlspecialchars($_GET['end_date'] ?? date('Y-m-d')) ?>">
|
||||
<div class="col-md-3">
|
||||
<label class="form-label small fw-bold" data-en="To Date" data-ar="إلى تاريخ">To Date</label>
|
||||
<input type="date" name="end_date" class="form-control form-control-sm" value="<?= htmlspecialchars($_GET['end_date'] ?? date('Y-m-d')) ?>">
|
||||
</div>
|
||||
<div class="col-md-4 d-flex align-items-end">
|
||||
<button type="submit" class="btn btn-primary w-100">Generate Report</button>
|
||||
<div class="col-md-3">
|
||||
<label class="form-label small fw-bold" data-en="Category" data-ar="الفئة">Category</label>
|
||||
<select name="category_id" class="form-select form-select-sm">
|
||||
<option value="" data-en="All Categories" data-ar="كل الفئات">All Categories</option>
|
||||
<?php foreach ($data['expense_categories'] as $cat): ?>
|
||||
<option value="<?= $cat['id'] ?>" <?= (isset($_GET['category_id']) && $_GET['category_id'] == $cat['id']) ? 'selected' : '' ?>>
|
||||
<?= htmlspecialchars($cat['name_en']) ?> / <?= htmlspecialchars($cat['name_ar']) ?>
|
||||
</option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-3 d-flex align-items-end">
|
||||
<button type="submit" class="btn btn-primary btn-sm w-100" data-en="Generate Report" data-ar="توليد التقرير">Generate Report</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="row mb-4">
|
||||
<div class="col-md-12">
|
||||
<div class="card bg-light border-0">
|
||||
<div class="card bg-light border-0 shadow-sm">
|
||||
<div class="card-body text-center">
|
||||
<h6 class="text-muted text-uppercase mb-2">Total Expenses</h6>
|
||||
<h6 class="text-muted text-uppercase mb-2" data-en="Total Expenses" data-ar="إجمالي المصروفات">Total Expenses</h6>
|
||||
<h2 class="text-danger mb-0">OMR <?= number_format((float)$data['total_expenses'], 3) ?></h2>
|
||||
<small class="text-muted">Period: <?= htmlspecialchars($_GET['start_date'] ?? date('Y-m-01')) ?> to <?= htmlspecialchars($_GET['end_date'] ?? date('Y-m-d')) ?></small>
|
||||
<small class="text-muted" data-en="For the selected period" data-ar="للفترة المختارة">For the selected period</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="table-responsive">
|
||||
<table class="table table-bordered">
|
||||
<table class="table table-bordered table-striped">
|
||||
<thead class="bg-light">
|
||||
<tr>
|
||||
<th>Category</th>
|
||||
<th class="text-end">Total Amount</th>
|
||||
<th class="text-end">% of Total</th>
|
||||
<th data-en="Category" data-ar="الفئة">Category</th>
|
||||
<th class="text-end" data-en="Total Amount" data-ar="إجمالي المبلغ">Total Amount</th>
|
||||
<th class="text-end" data-en="% of Total" data-ar="نسبة الإجمالي">% of Total</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php if (empty($data['report_by_category'])): ?>
|
||||
<tr><td colspan="3" class="text-center text-muted">No expenses found for this period.</td></tr>
|
||||
<tr><td colspan="3" class="text-center text-muted" data-en="No expenses found for this period." data-ar="لم يتم العثور على مصروفات لهذه الفترة.">No expenses found for this period.</td></tr>
|
||||
<?php else: ?>
|
||||
<?php foreach ($data['report_by_category'] as $row):
|
||||
$percent = $data['total_expenses'] > 0 ? ($row['total'] / $data['total_expenses'] * 100) : 0;
|
||||
?>
|
||||
<tr>
|
||||
<td>
|
||||
<div><?= htmlspecialchars($row['name_en']) ?></div>
|
||||
<small class="text-muted"><?= htmlspecialchars($row['name_ar']) ?></small>
|
||||
<div class="fw-bold"><?= htmlspecialchars($row['name_en']) ?></div>
|
||||
<div class="text-muted small"><?= htmlspecialchars($row['name_ar']) ?></div>
|
||||
</td>
|
||||
<td class="text-end fw-bold text-dark">OMR <?= number_format((float)$row['total'], 3) ?></td>
|
||||
<td class="text-end">
|
||||
<div class="progress" style="height: 5px;">
|
||||
<div class="progress-bar bg-danger" role="progressbar" style="width: <?= $percent ?>%"></div>
|
||||
</div>
|
||||
<small><?= number_format($percent, 1) ?>%</small>
|
||||
</td>
|
||||
<td class="text-end fw-bold">OMR <?= number_format((float)$row['total'], 3) ?></td>
|
||||
<td class="text-end"><?= number_format($percent, 1) ?>%</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<?php endif; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="print-only mt-5">
|
||||
<div class="row">
|
||||
<div class="col-4 text-center">
|
||||
<hr class="mx-4">
|
||||
<p data-en="Prepared By" data-ar="أعد بواسطة">Prepared By</p>
|
||||
</div>
|
||||
<div class="col-4 text-center">
|
||||
</div>
|
||||
<div class="col-4 text-center">
|
||||
<hr class="mx-4">
|
||||
<p data-en="Approved By" data-ar="اعتمد بواسطة">Approved By</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php elseif ($page === 'sales_returns'): ?>
|
||||
<div class="card p-4">
|
||||
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||
<!-- Print Header -->
|
||||
<div class="print-only mb-4">
|
||||
<div class="row align-items-center">
|
||||
<div class="col-6">
|
||||
<?php if (!empty($data['settings']['company_logo'])): ?>
|
||||
<img src="<?= htmlspecialchars($data['settings']['company_logo']) ?>" alt="Logo" style="max-height: 80px;" class="mb-2">
|
||||
<?php endif; ?>
|
||||
<h3 class="mb-1 fw-bold"><?= htmlspecialchars($data['settings']['company_name'] ?? 'Accounting System') ?></h3>
|
||||
<p class="text-muted small mb-0"><?= nl2br(htmlspecialchars($data['settings']['company_address'] ?? '')) ?></p>
|
||||
<p class="text-muted small mb-0">VAT: <?= htmlspecialchars($data['settings']['vat_number'] ?? '') ?></p>
|
||||
</div>
|
||||
<div class="col-6 text-end">
|
||||
<h2 class="text-uppercase text-muted">Sales Returns Report</h2>
|
||||
<p class="mb-0">Date: <?= date('Y-m-d') ?></p>
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
</div>
|
||||
<div class="d-flex justify-content-between align-items-center mb-4 d-print-none">
|
||||
<h5 class="m-0" data-en="Sales Returns" data-ar="مرتجع المبيعات">Sales Returns</h5>
|
||||
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#addSalesReturnModal" id="createSalesReturnBtn">
|
||||
<i class="bi bi-plus-lg"></i> <span data-en="Create New Return" data-ar="إنشاء مرتجع جديد">Create New Return</span>
|
||||
</button>
|
||||
<div class="d-flex gap-2">
|
||||
<a href="index.php?page=export&type=sales_returns&format=excel" class="btn btn-outline-success">
|
||||
<i class="bi bi-download"></i> <span data-en="Export" data-ar="تصدير">Export</span>
|
||||
</a>
|
||||
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#addSalesReturnModal" id="createSalesReturnBtn">
|
||||
<i class="bi bi-plus-lg"></i> <span data-en="Create New Return" data-ar="إنشاء مرتجع جديد">Create New Return</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bg-light p-3 rounded mb-4">
|
||||
@ -6760,9 +7100,14 @@ $projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? 'Accounting System';
|
||||
<div class="card p-4">
|
||||
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||
<h5 class="m-0" data-en="Purchase Returns" data-ar="مرتجع المشتريات">Purchase Returns</h5>
|
||||
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#addPurchaseReturnModal">
|
||||
<i class="bi bi-plus-lg"></i> <span data-en="Create New Return" data-ar="إنشاء مرتجع جديد">Create New Return</span>
|
||||
</button>
|
||||
<div class="d-flex gap-2">
|
||||
<a href="index.php?page=export&type=purchase_returns&format=excel" class="btn btn-outline-success">
|
||||
<i class="bi bi-download"></i> <span data-en="Export" data-ar="تصدير">Export</span>
|
||||
</a>
|
||||
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#addPurchaseReturnModal">
|
||||
<i class="bi bi-plus-lg"></i> <span data-en="Create New Return" data-ar="إنشاء مرتجع جديد">Create New Return</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bg-light p-3 rounded mb-4">
|
||||
@ -8029,13 +8374,14 @@ $projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? 'Accounting System';
|
||||
<td class="ps-4 fw-medium"><?= htmlspecialchars($b['name']) ?></td>
|
||||
<td><?= htmlspecialchars($b['size']) ?></td>
|
||||
<td><?= htmlspecialchars($b['date']) ?></td>
|
||||
<td class="text-end pe-4">
|
||||
<div class="btn-group">
|
||||
<form method="POST" class="d-inline" onsubmit="return confirm('Restore this backup? Current data will be overwritten!');">
|
||||
<td class="text-end pe-4">
|
||||
<div class="btn-group">
|
||||
<a href="index.php?download_backup=<?= urlencode($b['name']) ?>" class="btn btn-sm btn-outline-primary" title="Local Download" data-en="Local Download" data-ar="تحميل محلي"><i class="fas fa-download"></i></a>
|
||||
<form method="POST" class="d-inline" onsubmit="return confirm(document.documentElement.lang === 'ar' ? 'هل تريد استعادة هذه النسخة؟ سيتم الكتابة فوق البيانات الحالية!' : 'Restore this backup? Current data will be overwritten!');">
|
||||
<input type="hidden" name="filename" value="<?= htmlspecialchars($b['name']) ?>">
|
||||
<button type="submit" name="restore_backup" class="btn btn-sm btn-outline-success" title="Restore" data-en="Restore" data-ar="استعادة"><i class="bi bi-arrow-counterclockwise"></i></button>
|
||||
<button type="submit" name="restore_backup" class="btn btn-sm btn-outline-success ms-1" title="Restore" data-en="Restore" data-ar="استعادة"><i class="bi bi-arrow-counterclockwise"></i></button>
|
||||
</form>
|
||||
<form method="POST" class="d-inline" onsubmit="return confirm('Permanently delete this backup?');">
|
||||
<form method="POST" class="d-inline" onsubmit="return confirm(document.documentElement.lang === 'ar' ? 'هل تريد حذف هذه النسخة نهائياً؟' : 'Permanently delete this backup?');">
|
||||
<input type="hidden" name="filename" value="<?= htmlspecialchars($b['name']) ?>">
|
||||
<button type="submit" name="delete_backup" class="btn btn-sm btn-outline-danger ms-1" title="Delete" data-en="Delete" data-ar="حذف"><i class="bi bi-trash"></i></button>
|
||||
</form>
|
||||
|
||||
@ -277,8 +277,8 @@ try {
|
||||
</td>
|
||||
<td class="text-end">
|
||||
<div class="d-flex justify-content-end gap-2">
|
||||
<button class="action-btn" title="Edit Limits" data-bs-toggle="modal" data-bs-target="#editModal-<?= $l['id'] ?>">
|
||||
<i class="bi bi-pencil"></i>
|
||||
<button class="btn btn-sm btn-outline-primary action-btn" title="Edit License" data-bs-toggle="modal" data-bs-target="#editModal-<?= $l['id'] ?>">
|
||||
<i class="bi bi-pencil-square"></i>
|
||||
</button>
|
||||
<button class="action-btn" title="View Activations" data-bs-toggle="modal" data-bs-target="#modal-<?= $l['id'] ?>">
|
||||
<i class="bi bi-laptop"></i>
|
||||
@ -301,98 +301,6 @@ try {
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- Edit Modal -->
|
||||
<div class="modal fade" id="editModal-<?= $l['id'] ?>" tabindex="-1">
|
||||
<div class="modal-dialog modal-dialog-centered">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title fw-bold">Edit License: <?= htmlspecialchars($l['license_key']) ?></h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
||||
</div>
|
||||
<form method="POST">
|
||||
<div class="modal-body">
|
||||
<input type="hidden" name="action" value="update_limits">
|
||||
<input type="hidden" name="id" value="<?= $l['id'] ?>">
|
||||
<div class="row g-3">
|
||||
<div class="col-6">
|
||||
<label class="form-label">Machines Limit</label>
|
||||
<input type="number" name="max_activations" class="form-control" value="<?= $l['max_activations'] ?>" min="1">
|
||||
<div class="extra-small text-muted">Number of allowed PCs</div>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<label class="form-label">Counters Limit</label>
|
||||
<input type="number" name="max_counters" class="form-control" value="<?= $l['max_counters'] ?>" min="1">
|
||||
<div class="extra-small text-muted">Internal software limit</div>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<label class="form-label">Owner Name</label>
|
||||
<input type="text" name="owner" class="form-control" value="<?= htmlspecialchars($l['owner'] ?? '') ?>">
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<label class="form-label">Address / Notes</label>
|
||||
<textarea name="address" class="form-control" rows="2"><?= htmlspecialchars($l['address'] ?? '') ?></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer border-0">
|
||||
<button type="button" class="btn btn-light rounded-pill px-4" data-bs-dismiss="modal">Cancel</button>
|
||||
<button type="submit" class="btn btn-primary rounded-pill px-4">Save Changes</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Activations Modal -->
|
||||
<div class="modal fade" id="modal-<?= $l['id'] ?>" tabindex="-1">
|
||||
<div class="modal-dialog modal-dialog-centered modal-lg">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title fw-bold">Activations: <?= htmlspecialchars($l['license_key']) ?></h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
||||
</div>
|
||||
<div class="modal-body p-0">
|
||||
<?php
|
||||
try {
|
||||
$stmt = $pdo->prepare("SELECT * FROM activations WHERE license_id = ? ORDER BY activated_at DESC");
|
||||
$stmt->execute([$l['id']]);
|
||||
$acts = $stmt->fetchAll();
|
||||
} catch (Exception $e) { $acts = []; }
|
||||
|
||||
if ($acts):
|
||||
?>
|
||||
<table class="table table-sm mb-0">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="ps-4">Fingerprint</th>
|
||||
<th>Domain / Product</th>
|
||||
<th class="pe-4">Activated Date</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($acts as $a): ?>
|
||||
<tr>
|
||||
<td class="ps-4"><code><?= htmlspecialchars($a['fingerprint']) ?></code></td>
|
||||
<td>
|
||||
<div class="small fw-semibold"><?= htmlspecialchars($a['domain'] ?: '-') ?></div>
|
||||
<div class="text-muted extra-small"><?= htmlspecialchars($a['product'] ?: '-') ?></div>
|
||||
</td>
|
||||
<td class="pe-4 small text-muted"><?= $a['activated_at'] ?></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
<?php else: ?>
|
||||
<div class="text-center py-5">
|
||||
<i class="bi bi-display text-light fs-1"></i>
|
||||
<p class="text-muted mt-2">No machines currently activated.</p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
<?php if (empty($licenses)): ?>
|
||||
<tr><td colspan="7" class="text-center py-5 text-muted">No licenses found in the database.</td></tr>
|
||||
@ -403,6 +311,101 @@ try {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Modals Section -->
|
||||
<?php foreach ($licenses as $l): ?>
|
||||
<!-- Edit Modal -->
|
||||
<div class="modal fade" id="editModal-<?= $l['id'] ?>" tabindex="-1">
|
||||
<div class="modal-dialog modal-dialog-centered">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title fw-bold">Edit License: <?= htmlspecialchars($l['license_key']) ?></h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
||||
</div>
|
||||
<form method="POST">
|
||||
<div class="modal-body">
|
||||
<input type="hidden" name="action" value="update_limits">
|
||||
<input type="hidden" name="id" value="<?= $l['id'] ?>">
|
||||
<div class="row g-3">
|
||||
<div class="col-6">
|
||||
<label class="form-label">Machines Limit</label>
|
||||
<input type="number" name="max_activations" class="form-control" value="<?= $l['max_activations'] ?>" min="1">
|
||||
<div class="extra-small text-muted">Number of allowed PCs</div>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<label class="form-label">Counters Limit</label>
|
||||
<input type="number" name="max_counters" class="form-control" value="<?= $l['max_counters'] ?>" min="1">
|
||||
<div class="extra-small text-muted">Internal software limit</div>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<label class="form-label">Owner Name</label>
|
||||
<input type="text" name="owner" class="form-control" value="<?= htmlspecialchars($l['owner'] ?? '') ?>">
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<label class="form-label">Address / Notes</label>
|
||||
<textarea name="address" class="form-control" rows="2"><?= htmlspecialchars($l['address'] ?? '') ?></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer border-0">
|
||||
<button type="button" class="btn btn-light rounded-pill px-4" data-bs-dismiss="modal">Cancel</button>
|
||||
<button type="submit" class="btn btn-primary rounded-pill px-4">Save Changes</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Activations Modal -->
|
||||
<div class="modal fade" id="modal-<?= $l['id'] ?>" tabindex="-1">
|
||||
<div class="modal-dialog modal-dialog-centered modal-lg">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title fw-bold">Activations: <?= htmlspecialchars($l['license_key']) ?></h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
||||
</div>
|
||||
<div class="modal-body p-0">
|
||||
<?php
|
||||
try {
|
||||
$stmt = $pdo->prepare("SELECT * FROM activations WHERE license_id = ? ORDER BY activated_at DESC");
|
||||
$stmt->execute([$l['id']]);
|
||||
$acts = $stmt->fetchAll();
|
||||
} catch (Exception $e) { $acts = []; }
|
||||
|
||||
if ($acts):
|
||||
?>
|
||||
<table class="table table-sm mb-0">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="ps-4">Fingerprint</th>
|
||||
<th>Domain / Product</th>
|
||||
<th class="pe-4">Activated Date</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($acts as $a): ?>
|
||||
<tr>
|
||||
<td class="ps-4"><code><?= htmlspecialchars($a['fingerprint']) ?></code></td>
|
||||
<td>
|
||||
<div class="small fw-semibold"><?= htmlspecialchars($a['domain'] ?: '-') ?></div>
|
||||
<div class="text-muted extra-small"><?= htmlspecialchars($a['product'] ?: '-') ?></div>
|
||||
</td>
|
||||
<td class="pe-4 small text-muted"><?= $a['activated_at'] ?></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
<?php else: ?>
|
||||
<div class="text-center py-5">
|
||||
<i class="bi bi-display text-light fs-1"></i>
|
||||
<p class="text-muted mt-2">No machines currently activated.</p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
|
||||
<!-- Issue Key Modal -->
|
||||
<div class="modal fade" id="issueModal" tabindex="-1">
|
||||
<div class="modal-dialog modal-dialog-centered">
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user