354 lines
18 KiB
PHP
354 lines
18 KiB
PHP
<?php
|
|
require_once 'includes/header.php';
|
|
require_once __DIR__ . '/includes/pagination.php';
|
|
|
|
// Check Permission
|
|
if (!canView('hr_employees')) {
|
|
echo "<div class='alert alert-danger'>ليس لديك صلاحية للوصول إلى هذه الصفحة.</div>";
|
|
require_once 'includes/footer.php';
|
|
exit;
|
|
}
|
|
|
|
$error = '';
|
|
$success = '';
|
|
|
|
// Handle Form Submissions
|
|
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|
if (isset($_POST['save_employee'])) {
|
|
if (!canAdd('hr_employees') && !canEdit('hr_employees')) {
|
|
$error = "لا تملك صلاحية التعديل.";
|
|
} else {
|
|
$id = !empty($_POST['id']) ? $_POST['id'] : null;
|
|
$first_name = trim($_POST['first_name']);
|
|
$last_name = trim($_POST['last_name']);
|
|
$email = trim($_POST['email']);
|
|
$phone = trim($_POST['phone']);
|
|
$department_id = !empty($_POST['department_id']) ? $_POST['department_id'] : null;
|
|
$job_title = trim($_POST['job_title']);
|
|
$basic_salary = floatval($_POST['basic_salary']);
|
|
$join_date = $_POST['join_date'];
|
|
$status = $_POST['status'];
|
|
$gender = $_POST['gender'];
|
|
$birth_date = !empty($_POST['birth_date']) ? $_POST['birth_date'] : null;
|
|
|
|
if (empty($first_name) || empty($last_name) || empty($join_date)) {
|
|
$error = "يرجى تعبئة الحقول الإلزامية.";
|
|
} else {
|
|
try {
|
|
if ($id) {
|
|
// Update
|
|
$stmt = db()->prepare("UPDATE hr_employees SET first_name=?, last_name=?, email=?, phone=?, department_id=?, job_title=?, basic_salary=?, join_date=?, status=?, gender=?, birth_date=? WHERE id=?");
|
|
$stmt->execute([$first_name, $last_name, $email, $phone, $department_id, $job_title, $basic_salary, $join_date, $status, $gender, $birth_date, $id]);
|
|
$success = "تم تحديث بيانات الموظف بنجاح.";
|
|
} else {
|
|
// Insert
|
|
$stmt = db()->prepare("INSERT INTO hr_employees (first_name, last_name, email, phone, department_id, job_title, basic_salary, join_date, status, gender, birth_date) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
|
|
$stmt->execute([$first_name, $last_name, $email, $phone, $department_id, $job_title, $basic_salary, $join_date, $status, $gender, $birth_date]);
|
|
$success = "تم إضافة الموظف بنجاح.";
|
|
}
|
|
} catch (PDOException $e) {
|
|
$error = "خطأ في قاعدة البيانات: " . $e->getMessage();
|
|
}
|
|
}
|
|
}
|
|
} elseif (isset($_POST['delete_employee'])) {
|
|
if (!canDelete('hr_employees')) {
|
|
$error = "لا تملك صلاحية الحذف.";
|
|
} else {
|
|
$id = $_POST['id'];
|
|
try {
|
|
$stmt = db()->prepare("DELETE FROM hr_employees WHERE id = ?");
|
|
$stmt->execute([$id]);
|
|
$success = "تم حذف الموظف بنجاح.";
|
|
} catch (PDOException $e) {
|
|
$error = "لا يمكن حذف الموظف لوجود سجلات مرتبطة به.";
|
|
}
|
|
}
|
|
} elseif (isset($_POST['save_department'])) {
|
|
$dept_name = trim($_POST['name']);
|
|
if (!empty($dept_name)) {
|
|
$stmt = db()->prepare("INSERT INTO hr_departments (name) VALUES (?)");
|
|
$stmt->execute([$dept_name]);
|
|
$success = "تم إضافة القسم بنجاح.";
|
|
}
|
|
} elseif (isset($_POST['delete_department'])) {
|
|
$dept_id = $_POST['id'];
|
|
try {
|
|
$stmt = db()->prepare("DELETE FROM hr_departments WHERE id = ?");
|
|
$stmt->execute([$dept_id]);
|
|
$success = "تم حذف القسم.";
|
|
} catch (PDOException $e) {
|
|
$error = "لا يمكن حذف القسم لأنه مرتبط بموظفين.";
|
|
}
|
|
}
|
|
}
|
|
|
|
// Fetch Departments for Dropdown
|
|
$departments = db()->query("SELECT * FROM hr_departments ORDER BY name")->fetchAll();
|
|
|
|
// Pagination
|
|
$page = $_GET['page'] ?? 1;
|
|
$perPage = 10;
|
|
$totalEmployees = db()->query("SELECT COUNT(*) FROM hr_employees")->fetchColumn();
|
|
$pagination = getPagination($page, $totalEmployees, $perPage);
|
|
|
|
?>
|
|
|
|
<div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
|
|
<h1 class="h2">إدارة الموظفين</h1>
|
|
<div class="btn-toolbar mb-2 mb-md-0">
|
|
<?php if (canAdd('hr_employees')): ?>
|
|
<button type="button" class="btn btn-sm btn-outline-secondary me-2" data-bs-toggle="modal" data-bs-target="#deptModal">
|
|
<i class="fas fa-building"></i> الأقسام
|
|
</button>
|
|
<button type="button" class="btn btn-sm btn-primary" data-bs-toggle="modal" data-bs-target="#employeeModal" onclick="resetEmployeeForm()">
|
|
<i class="fas fa-plus"></i> إضافة موظف
|
|
</button>
|
|
<?php endif; ?>
|
|
</div>
|
|
</div>
|
|
|
|
<?php if ($error): ?>
|
|
<div class="alert alert-danger"><?= htmlspecialchars($error) ?></div>
|
|
<?php endif; ?>
|
|
<?php if ($success): ?>
|
|
<div class="alert alert-success"><?= htmlspecialchars($success) ?></div>
|
|
<?php endif; ?>
|
|
|
|
<!-- Departments Modal -->
|
|
<div class="modal fade" id="deptModal" tabindex="-1" aria-hidden="true">
|
|
<div class="modal-dialog">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h5 class="modal-title">إدارة الأقسام</h5>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<form method="post" class="mb-3 d-flex gap-2">
|
|
<input type="text" name="name" class="form-control" placeholder="اسم القسم الجديد" required>
|
|
<button type="submit" name="save_department" class="btn btn-primary">إضافة</button>
|
|
</form>
|
|
<ul class="list-group">
|
|
<?php foreach ($departments as $dept): ?>
|
|
<li class="list-group-item d-flex justify-content-between align-items-center">
|
|
<?= htmlspecialchars($dept['name']) ?>
|
|
<form method="post" onsubmit="return confirm('هل أنت متأكد؟');">
|
|
<input type="hidden" name="id" value="<?= $dept['id'] ?>">
|
|
<button type="submit" name="delete_department" class="btn btn-sm btn-danger"><i class="fas fa-trash"></i></button>
|
|
</form>
|
|
</li>
|
|
<?php endforeach; ?>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Employee Modal (Add/Edit) -->
|
|
<div class="modal fade" id="employeeModal" tabindex="-1" aria-hidden="true">
|
|
<div class="modal-dialog modal-lg">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h5 class="modal-title" id="employeeModalLabel">إضافة موظف جديد</h5>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
</div>
|
|
<form method="post" id="employeeForm">
|
|
<div class="modal-body">
|
|
<input type="hidden" name="id" id="empId">
|
|
|
|
<div class="row g-3">
|
|
<div class="col-md-6">
|
|
<label class="form-label">الاسم الأول <span class="text-danger">*</span></label>
|
|
<input type="text" name="first_name" id="empFirstName" class="form-control" required>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<label class="form-label">اسم العائلة <span class="text-danger">*</span></label>
|
|
<input type="text" name="last_name" id="empLastName" class="form-control" required>
|
|
</div>
|
|
|
|
<div class="col-md-6">
|
|
<label class="form-label">البريد الإلكتروني</label>
|
|
<input type="email" name="email" id="empEmail" class="form-control">
|
|
</div>
|
|
<div class="col-md-6">
|
|
<label class="form-label">رقم الهاتف</label>
|
|
<input type="text" name="phone" id="empPhone" class="form-control">
|
|
</div>
|
|
|
|
<div class="col-md-6">
|
|
<label class="form-label">الجنس</label>
|
|
<select name="gender" id="empGender" class="form-select">
|
|
<option value="male">ذكر</option>
|
|
<option value="female">أنثى</option>
|
|
</select>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<label class="form-label">تاريخ الميلاد</label>
|
|
<input type="date" name="birth_date" id="empBirthDate" class="form-control">
|
|
</div>
|
|
|
|
<div class="col-md-6">
|
|
<label class="form-label">القسم</label>
|
|
<select name="department_id" id="empDept" class="form-select">
|
|
<option value="">-- اختر القسم --</option>
|
|
<?php foreach ($departments as $dept): ?>
|
|
<option value="<?= $dept['id'] ?>"><?= htmlspecialchars($dept['name']) ?></option>
|
|
<?php endforeach; ?>
|
|
</select>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<label class="form-label">المسمى الوظيفي</label>
|
|
<input type="text" name="job_title" id="empJobTitle" class="form-control">
|
|
</div>
|
|
|
|
<div class="col-md-6">
|
|
<label class="form-label">تاريخ التعيين <span class="text-danger">*</span></label>
|
|
<input type="date" name="join_date" id="empJoinDate" class="form-control" value="<?= date('Y-m-d') ?>" required>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<label class="form-label">الراتب الأساسي</label>
|
|
<input type="number" step="0.01" name="basic_salary" id="empSalary" class="form-control">
|
|
</div>
|
|
|
|
<div class="col-md-6">
|
|
<label class="form-label">الحالة</label>
|
|
<select name="status" id="empStatus" class="form-select">
|
|
<option value="active">نشط</option>
|
|
<option value="on_leave">في إجازة</option>
|
|
<option value="resigned">مستقيل</option>
|
|
<option value="terminated">منهي خدماته</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">إلغاء</button>
|
|
<button type="submit" name="save_employee" class="btn btn-primary">حفظ البيانات</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- List View -->
|
|
<div class="card shadow-sm mb-4">
|
|
<div class="card-body">
|
|
<div class="table-responsive">
|
|
<table class="table table-hover align-middle">
|
|
<thead>
|
|
<tr>
|
|
<th>الاسم</th>
|
|
<th>القسم</th>
|
|
<th>المسمى الوظيفي</th>
|
|
<th>تاريخ التعيين</th>
|
|
<th>الحالة</th>
|
|
<th>الإجراءات</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<?php
|
|
$sql = "SELECT e.*, d.name as dept_name
|
|
FROM hr_employees e
|
|
LEFT JOIN hr_departments d ON e.department_id = d.id
|
|
ORDER BY e.first_name
|
|
LIMIT ? OFFSET ?";
|
|
$stmt = db()->prepare($sql);
|
|
$stmt->bindValue(1, $pagination['limit'], PDO::PARAM_INT);
|
|
$stmt->bindValue(2, $pagination['offset'], PDO::PARAM_INT);
|
|
$stmt->execute();
|
|
|
|
while ($row = $stmt->fetch()):
|
|
?>
|
|
<tr>
|
|
<td>
|
|
<div class="d-flex align-items-center">
|
|
<div class="bg-primary text-white rounded-circle d-flex align-items-center justify-content-center me-2" style="width: 35px; height: 35px; font-size: 0.9rem;">
|
|
<?= mb_substr($row['first_name'], 0, 1) . mb_substr($row['last_name'], 0, 1) ?>
|
|
</div>
|
|
<div>
|
|
<div class="fw-bold"><?= htmlspecialchars($row['first_name'] . ' ' . $row['last_name']) ?></div>
|
|
<div class="small text-muted"><?= htmlspecialchars($row['email']) ?></div>
|
|
</div>
|
|
</div>
|
|
</td>
|
|
<td><span class="badge bg-secondary"><?= htmlspecialchars($row['dept_name'] ?? '-') ?></span></td>
|
|
<td><?= htmlspecialchars($row['job_title']) ?></td>
|
|
<td><?= $row['join_date'] ?></td>
|
|
<td>
|
|
<?php
|
|
$status_cls = match($row['status']) {
|
|
'active' => 'success',
|
|
'terminated' => 'danger',
|
|
'resigned' => 'warning',
|
|
'on_leave' => 'info',
|
|
default => 'secondary'
|
|
};
|
|
?>
|
|
<span class="badge bg-<?= $status_cls ?>"><?= htmlspecialchars($row['status']) ?></span>
|
|
</td>
|
|
<td>
|
|
<div class="btn-group">
|
|
<?php if (canEdit('hr_employees')): ?>
|
|
<button type="button" class="btn btn-sm btn-outline-primary"
|
|
data-bs-toggle="modal"
|
|
data-bs-target="#employeeModal"
|
|
data-id="<?= $row['id'] ?>"
|
|
data-fname="<?= htmlspecialchars($row['first_name']) ?>"
|
|
data-lname="<?= htmlspecialchars($row['last_name']) ?>"
|
|
data-email="<?= htmlspecialchars($row['email']) ?>"
|
|
data-phone="<?= htmlspecialchars($row['phone']) ?>"
|
|
data-gender="<?= $row['gender'] ?>"
|
|
data-bdate="<?= $row['birth_date'] ?>"
|
|
data-dept="<?= $row['department_id'] ?>"
|
|
data-job="<?= htmlspecialchars($row['job_title']) ?>"
|
|
data-join="<?= $row['join_date'] ?>"
|
|
data-salary="<?= $row['basic_salary'] ?>"
|
|
data-status="<?= $row['status'] ?>"
|
|
onclick="editEmployee(this)">
|
|
<i class="fas fa-edit"></i>
|
|
</button>
|
|
<?php endif; ?>
|
|
<?php if (canDelete('hr_employees')): ?>
|
|
<form method="post" onsubmit="return confirm('هل أنت متأكد من حذف هذا الموظف؟');" class="d-inline">
|
|
<input type="hidden" name="id" value="<?= $row['id'] ?>">
|
|
<button type="submit" name="delete_employee" class="btn btn-sm btn-outline-danger"><i class="fas fa-trash"></i></button>
|
|
</form>
|
|
<?php endif; ?>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
<?php endwhile; ?>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="card-footer bg-white">
|
|
<?= renderPagination($pagination['current_page'], $pagination['total_pages']) ?>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
function resetEmployeeForm() {
|
|
document.getElementById('employeeForm').reset();
|
|
document.getElementById('empId').value = '';
|
|
document.getElementById('employeeModalLabel').textContent = 'إضافة موظف جديد';
|
|
}
|
|
|
|
function editEmployee(btn) {
|
|
document.getElementById('employeeModalLabel').textContent = 'تعديل بيانات موظف';
|
|
document.getElementById('empId').value = btn.dataset.id;
|
|
document.getElementById('empFirstName').value = btn.dataset.fname;
|
|
document.getElementById('empLastName').value = btn.dataset.lname;
|
|
document.getElementById('empEmail').value = btn.dataset.email;
|
|
document.getElementById('empPhone').value = btn.dataset.phone;
|
|
document.getElementById('empGender').value = btn.dataset.gender;
|
|
document.getElementById('empBirthDate').value = btn.dataset.bdate;
|
|
document.getElementById('empDept').value = btn.dataset.dept;
|
|
document.getElementById('empJobTitle').value = btn.dataset.job;
|
|
document.getElementById('empJoinDate').value = btn.dataset.join;
|
|
document.getElementById('empSalary').value = btn.dataset.salary;
|
|
document.getElementById('empStatus').value = btn.dataset.status;
|
|
}
|
|
</script>
|
|
|
|
<?php require_once 'includes/footer.php'; ?>
|