diff --git a/core/__pycache__/views.cpython-311.pyc b/core/__pycache__/views.cpython-311.pyc index 39f3760..366ef82 100644 Binary files a/core/__pycache__/views.cpython-311.pyc and b/core/__pycache__/views.cpython-311.pyc differ diff --git a/core/templates/core/manage_resources.html b/core/templates/core/manage_resources.html index b79cd4c..025f0c5 100644 --- a/core/templates/core/manage_resources.html +++ b/core/templates/core/manage_resources.html @@ -49,14 +49,22 @@ Name ID Number + Teams Active Status {% for worker in workers %} - {{ worker.name }} + {{ worker.name }} {{ worker.id_no }} + + {% for team in worker.teams.all %} + {{ team.name }} + {% empty %} + No Team + {% endfor %} +
{% empty %} - No workers found. + No workers found. {% endfor %} @@ -93,7 +101,7 @@ {% for project in projects %} - {{ project.name }} + {{ project.name }} {{ project.description|truncatechars:50 }}
@@ -132,7 +140,7 @@ {% for team in teams %} - {{ team.name }} + {{ team.name }} {{ team.supervisor.username|default:"-" }} {{ team.workers.count }} @@ -210,4 +218,4 @@ }); }); -{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/core/templates/core/work_log_list.html b/core/templates/core/work_log_list.html index d15e9e7..a6954d6 100644 --- a/core/templates/core/work_log_list.html +++ b/core/templates/core/work_log_list.html @@ -4,61 +4,176 @@ {% block title %}Work Log History | LabourFlow{% endblock %} {% block content %} -
+
-
+

Work Log History

-

View and filter historical daily work logs.

+

Filter and review historical daily work logs.

+ New Entry
+ + +
+
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ +
+
+ {% if selected_worker or selected_team or selected_project or selected_payment_status and selected_payment_status != 'all' %} + + {% endif %} +
+
-
- {% if logs %} -
- - - - - - - - - - - - - {% for log in logs %} - - - - - - - - - {% endfor %} - -
DateProjectSupervisorLabourersNotesAction
{{ log.date }}{{ log.project.name }}{{ log.supervisor.username|default:"System" }} - - {{ log.workers.count }} Workers - - {{ log.notes|truncatechars:30 }} - Edit -
+
+
+ {% if logs %} +
+ + + + + + + + + + + + + {% for log in logs %} + + + + + + + + + {% endfor %} + +
DateProjectLabourersStatus / PayslipSupervisorAction
+ {{ log.date|date:"D, d M Y" }} + + + {{ log.project.name }} + + + {% if selected_worker %} + + {% for w in log.workers.all %} + {% if w.id == selected_worker %} + {{ w.name }} + {% endif %} + {% endfor %} + + {% if log.workers.count > 1 %} + (+{{ log.workers.count|add:"-1" }} others) + {% endif %} + {% else %} +
+ {% for w in log.workers.all|slice:":3" %} + {{ w.name|truncatechars:12 }} + {% endfor %} + {% if log.workers.count > 3 %} + +{{ log.workers.count|add:"-3" }} + {% endif %} +
+ {% endif %} +
+ {% with payslip=log.paid_in.first %} + {% if payslip %} + + + Paid (Slip #{{ payslip.id }}) + + + {% else %} + + Pending + + {% endif %} + {% endwith %} + + {{ log.supervisor.username|default:"System" }} + + +
+
+ {% else %} +
+ +

No logs found matching filters.

+

Try adjusting your filters or record a new entry.

+ Log Attendance +
+ {% endif %}
- {% else %} -
-

No work logs recorded yet.

- Log First Attendance -
- {% endif %}
-{% endblock %} + + +{% endblock %} \ No newline at end of file diff --git a/core/views.py b/core/views.py index 241de5c..956a7db 100644 --- a/core/views.py +++ b/core/views.py @@ -4,7 +4,7 @@ import json from django.shortcuts import render, redirect, get_object_or_404 from django.utils import timezone from django.contrib.auth.decorators import login_required -from django.db.models import Sum, Q +from django.db.models import Sum, Q, Prefetch from django.core.mail import send_mail from django.conf import settings from django.contrib import messages @@ -148,14 +148,58 @@ def log_attendance(request): return render(request, 'core/log_attendance.html', context) def work_log_list(request): - logs = WorkLog.objects.all().order_by('-date') - return render(request, 'core/work_log_list.html', {'logs': logs}) + """View work log history with advanced filtering.""" + worker_id = request.GET.get('worker') + team_id = request.GET.get('team') + project_id = request.GET.get('project') + payment_status = request.GET.get('payment_status') # 'paid', 'unpaid', 'all' + + logs = WorkLog.objects.all().prefetch_related('workers', 'project', 'supervisor', 'paid_in').order_by('-date', '-id') + + if worker_id: + logs = logs.filter(workers__id=worker_id) + + if team_id: + # Find workers in this team and filter logs containing them + team_workers = Worker.objects.filter(teams__id=team_id) + logs = logs.filter(workers__in=team_workers).distinct() + + if project_id: + logs = logs.filter(project_id=project_id) + + if payment_status == 'paid': + # Logs that are linked to at least one PayrollRecord + logs = logs.filter(paid_in__isnull=False).distinct() + elif payment_status == 'unpaid': + # This is tricky because a log can have multiple workers, some paid some not. + # But usually a WorkLog is marked paid when its workers are paid. + # If we filtered by worker, we can check if THAT worker is paid in that log. + if worker_id: + worker = get_object_or_404(Worker, pk=worker_id) + logs = logs.exclude(paid_in__worker=worker) + else: + logs = logs.filter(paid_in__isnull=True) + + # Context for filters + context = { + 'logs': logs, + 'workers': Worker.objects.filter(is_active=True).order_by('name'), + 'teams': Team.objects.filter(is_active=True).order_by('name'), + 'projects': Project.objects.filter(is_active=True).order_by('name'), + 'selected_worker': int(worker_id) if worker_id else None, + 'selected_team': int(team_id) if team_id else None, + 'selected_project': int(project_id) if project_id else None, + 'selected_payment_status': payment_status, + } + + return render(request, 'core/work_log_list.html', context) def manage_resources(request): """View to manage active status of resources.""" - workers = Worker.objects.all().order_by('name') + # Prefetch teams for workers to avoid N+1 in template + workers = Worker.objects.all().prefetch_related('teams').order_by('name') projects = Project.objects.all().order_by('name') - teams = Team.objects.all().order_by('name') + teams = Team.objects.all().prefetch_related('workers').order_by('name') context = { 'workers': workers, @@ -302,4 +346,4 @@ def payslip_detail(request, pk): 'record': record, 'logs': logs, } - return render(request, 'core/payslip.html', context) + return render(request, 'core/payslip.html', context) \ No newline at end of file