# === URL ROUTING === # Maps URLs to view functions. Each path() connects a web address to # the Python function that handles it. from django.urls import path from . import views urlpatterns = [ # Dashboard — the home page after login path('', views.index, name='home'), # Attendance logging — where supervisors log daily work path('attendance/log/', views.attendance_log, name='attendance_log'), # Work history — table of all work logs with filters path('history/', views.work_history, name='work_history'), # CSV export — downloads filtered work logs as a spreadsheet path('history/export/', views.export_work_log_csv, name='export_work_log_csv'), # === WORK LOG PAYROLL CROSS-LINK (admin-only) === # Click a historic work log -> see who got paid and who didn't. # AJAX endpoint returns JSON (the modal builds its own DOM safely); # detail view renders the same data as a shareable full page. path('history//', views.work_log_payroll_detail, name='work_log_payroll_detail'), path('history//payroll/ajax/', views.work_log_payroll_ajax, name='work_log_payroll_ajax'), # === SITE REPORT (DAILY PROGRESS) === # Companion to attendance: log WHAT was done on site (counts, checks, # weather, free-form notes). Edit page is the redirect target after # /attendance/log/ submission. Detail page is read-only. path('site-report//edit/', views.site_report_edit, name='site_report_edit'), path('site-report//', views.site_report_detail, name='site_report_detail'), # 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///', views.toggle_active, name='toggle_active'), # === PAYROLL === # Main payroll dashboard — shows pending payments, history, loans, and charts path('payroll/', views.payroll_dashboard, name='payroll_dashboard'), # Process payment — pays a worker and links their unpaid logs + adjustments path('payroll/pay//', views.process_payment, name='process_payment'), # Batch pay — preview which workers would be paid, then process all at once path('payroll/batch-pay/preview/', views.batch_pay_preview, name='batch_pay_preview'), path('payroll/batch-pay/', views.batch_pay, name='batch_pay'), # Price overtime — creates Overtime adjustments from unpriced OT entries path('payroll/price-overtime/', views.price_overtime, name='price_overtime'), # Add a new payroll adjustment (bonus, deduction, loan, etc.) path('payroll/adjustment/add/', views.add_adjustment, name='add_adjustment'), # Edit an existing unpaid adjustment path('payroll/adjustment//edit/', views.edit_adjustment, name='edit_adjustment'), # Delete an unpaid adjustment path('payroll/adjustment//delete/', views.delete_adjustment, name='delete_adjustment'), # Bulk-delete multiple unpaid adjustments at once (Adjustments tab) path('payroll/adjustments/bulk-delete/', views.bulk_delete_adjustments, name='bulk_delete_adjustments'), # Preview a worker's payslip (AJAX — returns JSON) path('payroll/preview//', views.preview_payslip, name='preview_payslip'), # Worker lookup — AJAX report card for a single worker (returns JSON) path('payroll/worker-lookup//', views.worker_lookup_ajax, name='worker_lookup_ajax'), # Add a repayment from the payslip preview modal (AJAX — returns JSON) path('payroll/repayment//', views.add_repayment_ajax, name='add_repayment_ajax'), # View a completed payslip (print-friendly page) path('payroll/payslip//', views.payslip_detail, name='payslip_detail'), # === REPORTS === # Generate payroll reports filtered by date range, project, or team path('report/', views.generate_report, name='generate_report'), path('report/pdf/', views.generate_report_pdf, name='generate_report_pdf'), # === WORKERS === # Admin-friendly worker management UI (alternative to /admin/core/worker/) path('workers/', views.worker_list, name='worker_list'), path('workers/new/', views.worker_edit, name='worker_new'), path('workers//', views.worker_detail, name='worker_detail'), path('workers//edit/', views.worker_edit, name='worker_edit'), # Batch report (table of all workers with aggregated history) path('workers/report/', views.worker_batch_report, name='worker_batch_report'), path('workers/report/csv/', views.worker_batch_report_csv, name='worker_batch_report_csv'), path('workers/report/pdf/', views.worker_batch_report_pdf, name='worker_batch_report_pdf'), # === TEAMS === # Admin-friendly team management UI (alternative to /admin/core/team/) path('teams/', views.team_list, name='team_list'), path('teams/new/', views.team_edit, name='team_new'), path('teams/report/', views.team_batch_report, name='team_batch_report'), path('teams/report/csv/', views.team_batch_report_csv, name='team_batch_report_csv'), path('teams//', views.team_detail, name='team_detail'), path('teams//edit/', views.team_edit, name='team_edit'), # === PROJECTS === # Admin-friendly project management UI (alternative to /admin/core/project/) path('projects/', views.project_list, name='project_list'), path('projects/new/', views.project_edit, name='project_new'), path('projects/report/', views.project_batch_report, name='project_batch_report'), path('projects/report/csv/', views.project_batch_report_csv, name='project_batch_report_csv'), path('projects//', views.project_detail, name='project_detail'), path('projects//edit/', views.project_edit, name='project_edit'), # === ABSENCES === # Standalone absence logging — admins + supervisors mark workers # absent for a date or date range. Conflict flow: if any selected # (worker, date) already has a WorkLog, the form redirects to # /absences/log/confirm/ where the admin can optionally remove the # worker from those WorkLogs before creating the Absence rows. path('absences/log/', views.absence_log, name='absence_log'), path('absences/log/confirm/', views.absence_log_confirm, name='absence_log_confirm'), # Browse + manage. Admin-only export. The edit/delete pages reuse # _absence_user_queryset so supervisor scope applies consistently. path('absences/', views.absence_list, name='absence_list'), path('absences/export/', views.absence_export_csv, name='absence_export_csv'), path('absences//edit/', views.absence_edit, name='absence_edit'), path('absences//delete/', views.absence_delete, name='absence_delete'), # === EXPENSE RECEIPTS === # Create a new expense receipt — emails HTML + PDF to Spark Receipt path('receipts/create/', views.create_receipt, name='create_receipt'), # === TEMPORARY: Import production data from browser === # Visit /import-data/ once to populate the database. Remove after use. path('import-data/', views.import_data, name='import_data'), # === TEMPORARY: Run migrations from browser === # Visit /run-migrate/ to apply pending database migrations on production. path('run-migrate/', views.run_migrate, name='run_migrate'), # === BACKUP / RESTORE (admin-only, browser-accessible) === # Flatlogic has no SSH/shell — admins use these to snapshot and # restore all app data via the browser. See CLAUDE.md "Backup & # Restore" section for the full procedure. path('backup-data/', views.backup_data, name='backup_data'), path('restore-data/', views.restore_data, name='restore_data'), ]