Add Export Workers CSV — downloads all worker data as spreadsheet

Admin-only CSV export with name, ID number, phone, salary, daily rate,
employment date, active status, and notes. Button on dashboard next to
Manage Resources header.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Konrad du Plessis 2026-02-23 00:36:57 +02:00
parent 3199e52e72
commit 2aad9ac623
3 changed files with 43 additions and 1 deletions

View File

@ -170,8 +170,11 @@
<!-- Manage Resources -->
<div class="col-lg-6 mb-4">
<div class="card shadow-sm border-0 h-100">
<div class="card-header py-3 bg-white">
<div class="card-header py-3 bg-white d-flex justify-content-between align-items-center">
<h6 class="m-0 font-weight-bold" style="color: #0f172a;">Manage Resources</h6>
<a href="{% url 'export_workers_csv' %}" class="btn btn-outline-success btn-sm">
<i class="fas fa-file-csv me-1"></i> Export Workers
</a>
</div>
<div class="card-body p-0">
<ul class="nav nav-tabs px-3 pt-3" id="resourceTabs" role="tablist">

View File

@ -18,6 +18,9 @@ urlpatterns = [
# CSV export — downloads filtered work logs as a spreadsheet
path('history/export/', views.export_work_log_csv, name='export_work_log_csv'),
# CSV export — downloads all worker data (admin only)
path('workers/export/', views.export_workers_csv, name='export_workers_csv'),
# AJAX toggle — activates/deactivates workers, projects, teams from dashboard
path('toggle/<str:model_name>/<int:item_id>/', views.toggle_active, name='toggle_active'),

View File

@ -646,6 +646,42 @@ def export_work_log_csv(request):
return response
# === EXPORT WORKERS CSV ===
# Downloads all worker data as a CSV file for use in spreadsheets.
# Admin-only — supervisors don't have access to salary/ID data.
@login_required
def export_workers_csv(request):
"""Export all workers to CSV — includes name, ID, phone, salary, daily rate, status."""
if not is_admin(request.user):
return HttpResponseForbidden("Admin access required.")
workers = Worker.objects.all().order_by('name')
response = HttpResponse(content_type='text/csv')
response['Content-Disposition'] = 'attachment; filename="workers.csv"'
writer = csv.writer(response)
writer.writerow([
'Name', 'ID Number', 'Phone Number', 'Monthly Salary',
'Daily Rate', 'Employment Date', 'Active', 'Notes'
])
for w in workers:
writer.writerow([
w.name,
w.id_number,
w.phone_number,
f'{w.monthly_salary:.2f}',
f'{w.daily_rate:.2f}',
w.employment_date.strftime('%Y-%m-%d') if w.employment_date else '',
'Yes' if w.active else 'No',
w.notes,
])
return response
# === TOGGLE RESOURCE STATUS (AJAX) ===
# Called by the toggle switches on the dashboard to activate/deactivate
# workers, projects, or teams without reloading the page.