38086-vm/hr/views.py
Flatlogic Bot bdde0c2da9 revision 1
2026-02-06 06:32:17 +00:00

145 lines
5.6 KiB
Python

from django.views.generic import ListView, CreateView, UpdateView, TemplateView, DetailView, DeleteView
from django.contrib.auth.mixins import LoginRequiredMixin
from django.urls import reverse_lazy
from django.utils.translation import gettext_lazy as _
from .models import Employee, Department, Attendance, LeaveRequest, JobPosition, BiometricDevice
from .forms import EmployeeForm
from django.db.models import Count
from django.shortcuts import get_object_or_404, redirect
from django.contrib import messages
import socket
from django.utils import timezone
class HRDashboardView(LoginRequiredMixin, TemplateView):
template_name = 'hr/dashboard.html'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['total_employees'] = Employee.objects.count()
context['active_employees'] = Employee.objects.filter(status='active').count()
context['departments_count'] = Department.objects.count()
context['pending_leaves'] = LeaveRequest.objects.filter(status='pending').count()
return context
class EmployeeListView(LoginRequiredMixin, ListView):
model = Employee
template_name = 'hr/employee_list.html'
context_object_name = 'employees'
class EmployeeCreateView(LoginRequiredMixin, CreateView):
model = Employee
form_class = EmployeeForm
template_name = 'hr/employee_form.html'
success_url = reverse_lazy('hr:employee_list')
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['title'] = _("Add New Employee")
return context
class EmployeeUpdateView(LoginRequiredMixin, UpdateView):
model = Employee
form_class = EmployeeForm
template_name = 'hr/employee_form.html'
success_url = reverse_lazy('hr:employee_list')
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['title'] = _("Edit Employee")
return context
class EmployeeDetailView(LoginRequiredMixin, DetailView):
model = Employee
template_name = 'hr/employee_detail.html'
class DepartmentListView(LoginRequiredMixin, ListView):
model = Department
template_name = 'hr/department_list.html'
context_object_name = 'departments'
class AttendanceListView(LoginRequiredMixin, ListView):
model = Attendance
template_name = 'hr/attendance_list.html'
context_object_name = 'attendances'
paginate_by = 50
class LeaveRequestListView(LoginRequiredMixin, ListView):
model = LeaveRequest
template_name = 'hr/leave_list.html'
context_object_name = 'leaves'
class LeaveRequestCreateView(LoginRequiredMixin, CreateView):
model = LeaveRequest
fields = ['employee', 'leave_type', 'start_date', 'end_date', 'reason']
template_name = 'hr/leave_form.html'
success_url = reverse_lazy('hr:leave_list')
class BiometricDeviceListView(LoginRequiredMixin, ListView):
model = BiometricDevice
template_name = 'hr/biometric_device_list.html'
context_object_name = 'devices'
class BiometricDeviceCreateView(LoginRequiredMixin, CreateView):
model = BiometricDevice
fields = ['name', 'ip_address', 'port', 'device_type', 'status']
template_name = 'hr/biometric_device_form.html'
success_url = reverse_lazy('hr:device_list')
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['title'] = _("Add Biometric Device")
return context
class BiometricDeviceUpdateView(LoginRequiredMixin, UpdateView):
model = BiometricDevice
fields = ['name', 'ip_address', 'port', 'device_type', 'status']
template_name = 'hr/biometric_device_form.html'
success_url = reverse_lazy('hr:device_list')
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['title'] = _("Edit Biometric Device")
return context
class BiometricDeviceDeleteView(LoginRequiredMixin, DeleteView):
model = BiometricDevice
template_name = 'hr/biometric_device_confirm_delete.html'
success_url = reverse_lazy('hr:device_list')
def test_device_connection(request, pk):
device = get_object_or_404(BiometricDevice, pk=pk)
try:
# Simple socket connect to see if port is open (timeout 3s)
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(3)
result = sock.connect_ex((device.ip_address, device.port))
sock.close()
if result == 0:
messages.success(request, _("Connection successful! Device is online."))
device.status = 'active'
device.last_sync = timezone.now()
device.save()
else:
# If failed, we still report it but since this is often run in dev/cloud
# where the device isn't reachable, we warn.
messages.warning(request, _("Connection failed: Port closed or host unreachable. (Error Code: %(code)s)") % {'code': result})
device.status = 'inactive'
device.save()
except Exception as e:
messages.error(request, _("Connection Error: %(error)s") % {'error': str(e)})
return redirect('hr:device_list')
def sync_device_logs(request, pk):
device = get_object_or_404(BiometricDevice, pk=pk)
result = device.sync_data() # This method we added to the model
if result.get('error'):
messages.error(request, _("Sync Failed: %(error)s") % {'error': result['error']})
else:
messages.success(request, _("Sync Successful! Fetched %(total)s records, %(new)s new.") % {'total': result['total'], 'new': result['new']})
return redirect('hr:device_list')