38808-vm/hr_attendance.php
2026-03-27 03:32:55 +00:00

227 lines
11 KiB
PHP

<?php
require_once 'includes/header.php';
if (!canView('hr_attendance')) {
echo "<div class='alert alert-danger'>ليس لديك صلاحية للوصول إلى هذه الصفحة.</div>";
require_once 'includes/footer.php';
exit;
}
$date = $_GET['date'] ?? date('Y-m-d');
$error = '';
$success = '';
// Handle Attendance Submission
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['save_attendance'])) {
if (!canAdd('hr_attendance') && !canEdit('hr_attendance')) {
$error = "لا تملك صلاحية التعديل.";
} else {
$emp_id = $_POST['employee_id'];
$att_date = $_POST['date'];
$status = $_POST['status'];
$check_in = !empty($_POST['check_in']) ? $_POST['check_in'] : null;
$check_out = !empty($_POST['check_out']) ? $_POST['check_out'] : null;
$notes = $_POST['notes'];
try {
// Check if exists
$stmt = db()->prepare("SELECT id FROM hr_attendance WHERE employee_id = ? AND date = ?");
$stmt->execute([$emp_id, $att_date]);
$exists = $stmt->fetch();
if ($exists) {
$stmt = db()->prepare("UPDATE hr_attendance SET status = ?, check_in = ?, check_out = ?, notes = ? WHERE id = ?");
$stmt->execute([$status, $check_in, $check_out, $notes, $exists['id']]);
$success = "تم تحديث الحضور بنجاح.";
} else {
$stmt = db()->prepare("INSERT INTO hr_attendance (employee_id, date, status, check_in, check_out, notes) VALUES (?, ?, ?, ?, ?, ?)");
$stmt->execute([$emp_id, $att_date, $status, $check_in, $check_out, $notes]);
$success = "تم تسجيل الحضور بنجاح.";
}
} catch (PDOException $e) {
$error = "خطأ: " . $e->getMessage();
}
}
}
// Fetch Employees and their attendance for the selected date
$sql = "SELECT e.id, e.first_name, e.last_name, e.job_title,
a.id as att_id, a.status, a.check_in, a.check_out, a.notes
FROM hr_employees e
LEFT JOIN hr_attendance a ON e.id = a.employee_id AND a.date = ?
WHERE e.status = 'active'
ORDER BY e.first_name";
$stmt = db()->prepare($sql);
$stmt->execute([$date]);
$records = $stmt->fetchAll();
?>
<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">
<form class="d-flex gap-2 align-items-center" method="get">
<label class="col-form-label">التاريخ:</label>
<input type="date" name="date" class="form-control" value="<?= $date ?>" onchange="this.form.submit()">
</form>
</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; ?>
<div class="card shadow-sm">
<div class="card-body">
<div class="table-responsive">
<table class="table table-hover align-middle">
<thead class="table-light">
<tr>
<th>الموظف</th>
<th>الوظيفة</th>
<th>الحالة</th>
<th>وقت الحضور</th>
<th>وقت الانصراف</th>
<th>ملاحظات</th>
<th>إجراء</th>
</tr>
</thead>
<tbody>
<?php foreach ($records as $row): ?>
<tr class="<?= !$row['att_id'] ? 'table-light text-muted' : '' ?>">
<td class="fw-bold"><?= htmlspecialchars($row['first_name'] . ' ' . $row['last_name']) ?></td>
<td class="small"><?= htmlspecialchars($row['job_title']) ?></td>
<td>
<?php if ($row['att_id']): ?>
<?php
$badge = match($row['status']) {
'present' => 'success',
'absent' => 'danger',
'late' => 'warning',
'excused' => 'info',
'holiday' => 'primary',
default => 'secondary'
};
$status_text = match($row['status']) {
'present' => 'حاضر',
'absent' => 'غائب',
'late' => 'تأخير',
'excused' => 'مأذون',
'holiday' => 'عطلة',
default => $row['status']
};
?>
<span class="badge bg-<?= $badge ?>"><?= $status_text ?></span>
<?php else: ?>
<span class="badge bg-light text-dark border">غير مسجل</span>
<?php endif; ?>
</td>
<td><?= $row['check_in'] ? date('h:i A', strtotime($row['check_in'])) : '-' ?></td>
<td><?= $row['check_out'] ? date('h:i A', strtotime($row['check_out'])) : '-' ?></td>
<td class="text-truncate" style="max-width: 150px;"><?= htmlspecialchars($row['notes'] ?? '') ?></td>
<td>
<?php if (canEdit('hr_attendance')): ?>
<?php if ($row['att_id']): ?>
<button class="btn btn-sm btn-outline-primary"
title="تعديل"
data-bs-toggle="modal"
data-bs-target="#attModal"
data-id="<?= $row['id'] ?>"
data-name="<?= htmlspecialchars($row['first_name'] . ' ' . $row['last_name']) ?>"
data-status="<?= $row['status'] ?? 'present' ?>"
data-in="<?= $row['check_in'] ?? '' ?>"
data-out="<?= $row['check_out'] ?? '' ?>"
data-notes="<?= htmlspecialchars($row['notes'] ?? '') ?>">
<i class="fas fa-edit"></i>
</button>
<?php else: ?>
<button class="btn btn-sm btn-success"
title="تسجيل حضور"
data-bs-toggle="modal"
data-bs-target="#attModal"
data-id="<?= $row['id'] ?>"
data-name="<?= htmlspecialchars($row['first_name'] . ' ' . $row['last_name']) ?>"
data-status="present"
data-in="<?= date('09:00') ?>"
data-out=""
data-notes="">
<i class="fas fa-check"></i> تسجيل
</button>
<?php endif; ?>
<?php endif; ?>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</div>
</div>
<!-- Attendance Modal -->
<div class="modal fade" id="attModal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">تسجيل/تعديل الحضور: <span id="modalEmpName" class="text-primary"></span></h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<form method="post">
<div class="modal-body">
<input type="hidden" name="employee_id" id="modalEmpId">
<input type="hidden" name="date" value="<?= $date ?>">
<div class="mb-3">
<label class="form-label">الحالة</label>
<select name="status" id="modalStatus" class="form-select" required>
<option value="present">حاضر</option>
<option value="late">تأخير</option>
<option value="excused">مأذون/إذن</option>
<option value="absent">غائب</option>
<option value="holiday">عطلة</option>
</select>
</div>
<div class="row g-2 mb-3">
<div class="col">
<label class="form-label">وقت الحضور</label>
<input type="time" name="check_in" id="modalIn" class="form-control">
</div>
<div class="col">
<label class="form-label">وقت الانصراف</label>
<input type="time" name="check_out" id="modalOut" class="form-control">
</div>
</div>
<div class="mb-3">
<label class="form-label">ملاحظات</label>
<textarea name="notes" id="modalNotes" class="form-control" rows="2"></textarea>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">إلغاء</button>
<button type="submit" name="save_attendance" class="btn btn-primary">حفظ</button>
</div>
</form>
</div>
</div>
</div>
<script>
const attModal = document.getElementById('attModal');
attModal.addEventListener('show.bs.modal', event => {
const button = event.relatedTarget;
document.getElementById('modalEmpId').value = button.getAttribute('data-id');
document.getElementById('modalEmpName').textContent = button.getAttribute('data-name');
document.getElementById('modalStatus').value = button.getAttribute('data-status');
document.getElementById('modalIn').value = button.getAttribute('data-in');
document.getElementById('modalOut').value = button.getAttribute('data-out');
document.getElementById('modalNotes').value = button.getAttribute('data-notes');
});
</script>
<?php require_once 'includes/footer.php'; ?>