diff --git a/core/__pycache__/views.cpython-311.pyc b/core/__pycache__/views.cpython-311.pyc index 5c00a4e..dcd3c6c 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/payroll_dashboard.html b/core/templates/core/payroll_dashboard.html index b0b2d6b..6156722 100644 --- a/core/templates/core/payroll_dashboard.html +++ b/core/templates/core/payroll_dashboard.html @@ -177,6 +177,7 @@ data-adj-description="{{ adj.description }}" data-adj-date="{{ adj.date|date:'Y-m-d' }}" data-adj-worker="{{ item.worker.name }}" + data-adj-project="{% if adj.work_log %}{{ adj.work_log.project_id }}{% endif %}" title="{% if adj.type == 'ADVANCE' %}Click to delete (cannot edit){% else %}Click to edit{% endif %}"> {{ adj.get_type_display }}: R {{ adj.amount }} {% if adj.type != 'ADVANCE' %}✎{% endif %} @@ -487,6 +488,15 @@ {% endfor %} +
+ + +
@@ -530,6 +540,15 @@
+
+ + +
@@ -760,6 +779,7 @@ document.addEventListener('DOMContentLoaded', function() { } document.getElementById('editAdjWorkerName').textContent = this.dataset.adjWorker; + document.getElementById("editAdjProject").value = this.dataset.adjProject || ""; document.getElementById('editAdjAmount').value = this.dataset.adjAmount; document.getElementById('editAdjDescription').value = this.dataset.adjDescription; document.getElementById('editAdjDate').value = this.dataset.adjDate; diff --git a/core/views.py b/core/views.py index ac897e0..3510020 100644 --- a/core/views.py +++ b/core/views.py @@ -994,6 +994,7 @@ def payroll_dashboard(request): 'active_tab': status_filter, 'all_workers': all_workers, 'all_teams': all_teams, + 'all_projects': Project.objects.filter(is_active=True).order_by('name'), 'team_workers_map_json': json.dumps(team_workers_map), 'adjustment_types': PayrollAdjustment.ADJUSTMENT_TYPES, 'loans': loans, @@ -1283,6 +1284,7 @@ def add_adjustment(request): description = request.POST.get('description') date = request.POST.get('date') or timezone.now().date() loan_id = request.POST.get('loan_id') # Optional, for repayments + project_id = request.POST.get('project_id') # Optional, for linking to a project try: amount = Decimal(amount_str) if amount_str else None @@ -1329,12 +1331,22 @@ def add_adjustment(request): # Create ADVANCE adjustment + PayrollRecord atomically with transaction.atomic(): + work_log_link = None + if project_id: + # Try to find a worklog for this worker and project to link the adjustment to the project + work_log_link = worker.work_logs.filter(project_id=project_id).order_by('-date').first() + if not work_log_link: + # Fallback: any worklog for project + from .models import WorkLog + work_log_link = WorkLog.objects.filter(project_id=project_id).order_by('-date').first() + PayrollAdjustment.objects.create( worker=worker, type='ADVANCE', amount=advance_amount, description=description or 'Advance payment', date=date, + work_log=work_log_link, ) advance_date = date if isinstance(date, datetime.date) else timezone.now().date() @@ -1342,6 +1354,8 @@ def add_adjustment(request): worker=worker, amount=advance_amount, date=advance_date, + type='ADVANCE', + notes=description or 'Advance payment' ) # Send advance payslip to Spark (outside transaction) @@ -1398,13 +1412,23 @@ def add_adjustment(request): reason=description ) + work_log_link = None + if project_id: + # Try to find a worklog for this worker and project to link the adjustment to the project + work_log_link = worker.work_logs.filter(project_id=project_id).order_by('-date').first() + if not work_log_link: + # Fallback: any worklog for project + from .models import WorkLog + work_log_link = WorkLog.objects.filter(project_id=project_id).order_by("-date").first() + PayrollAdjustment.objects.create( worker=worker, type=adj_type, amount=amount, description=description, date=date, - loan=loan + loan=loan, + work_log=work_log_link ) success_names.append(worker.name) @@ -1445,6 +1469,7 @@ def edit_adjustment(request, pk): description = request.POST.get('description') date = request.POST.get('date') new_type = request.POST.get('type') + project_id = request.POST.get('project_id') if amount: adj.amount = Decimal(amount) @@ -1453,6 +1478,15 @@ def edit_adjustment(request, pk): if date: adj.date = date + if project_id: + work_log_link = adj.worker.work_logs.filter(project_id=project_id).order_by('-date').first() + if not work_log_link: + from .models import WorkLog + work_log_link = WorkLog.objects.filter(project_id=project_id).order_by('-date').first() + adj.work_log = work_log_link + elif project_id == '': + adj.work_log = None + # Only allow type change for BONUS/DEDUCTION (others have linked objects) if new_type and adj.type in ('BONUS', 'DEDUCTION') and new_type in ('BONUS', 'DEDUCTION'): adj.type = new_type