{% extends 'base.html' %} {% load static %} {% block title %}Payroll Dashboard | Fox Fitt{% endblock %} {% block content %}
{# === PAGE HEADER === #}

Payroll Dashboard

{# === ANALYTICS CARDS === #} {# Left side: 3 single-value stat cards (2 on top + 1 below) #} {# Right side: Project breakdown card spanning full height — no scroll #}
{# --- Left column: stat cards --- #}
{# Outstanding Total — with breakdown of wages vs adjustments #}
Outstanding Payments
R {{ outstanding_total|floatformat:2 }}
{# === BREAKDOWN — only shown when there are pending adjustments === #} {% if pending_adj_add_total or pending_adj_sub_total %}
Unpaid wages R {{ unpaid_wages_total|floatformat:2 }}
{% if pending_adj_add_total %}
+ Additions R {{ pending_adj_add_total|floatformat:2 }}
{% endif %} {% if pending_adj_sub_total %}
- Deductions -R {{ pending_adj_sub_total|floatformat:2 }}
{% endif %}
{% endif %}
Loan repayments deducted at payment time
{# Recent Payments #}
Paid (Last 60 Days)
R {{ recent_payments_total|floatformat:2 }}
{# Active Loans — spans full width below the first two #}
Active Loans & Advances ({{ active_loans_count }})
R {{ active_loans_balance|floatformat:2 }}
{# --- Right column: project breakdown (grows to fit all projects) --- #}
Outstanding by Project
{% if outstanding_project_costs %}
{% for pc in outstanding_project_costs %}
{{ pc.name }} R {{ pc.cost|floatformat:2 }}
{% endfor %}
{% else %}
No outstanding amounts
{% endif %}
{# === CHARTS === #}
{# === CHART TOGGLE: Overall vs By Worker === #} {# Two small buttons to switch between the total line chart #} {# and a per-worker stacked bar chart breakdown. #}
Monthly Payroll
{# --- Overall view (default): the existing line chart --- #}
{# --- By Worker view (hidden): worker dropdown + stacked bar --- #}
Cost by Project (Monthly)
{# === TAB NAVIGATION === #} {# =============================================== #} {# === PENDING PAYMENTS TAB === #} {# =============================================== #} {% if active_tab == 'pending' %} {# === PENDING PAYMENTS FILTER BAR === #} {# Lets admin filter by team, show only overdue workers, or exclude workers with loans #}
{% for wd in workers_data %} {% empty %} {% endfor %}
Worker Days Day Rate Log Amount Adjustments Net Adj Total Actions
{{ wd.worker.name }} {% if wd.is_overdue %} Overdue {% endif %} {% if wd.has_loan %} Loan {% endif %} {{ wd.unpaid_count }} R {{ wd.day_rate }} R {{ wd.unpaid_amount|floatformat:2 }} {# Show each pending adjustment as a badge #} {% for adj in wd.adjustments %} {% if adj.type == 'Bonus' or adj.type == 'Overtime' or adj.type == 'New Loan' or adj.type == 'Advance Payment' %}+{% else %}-{% endif %}R{{ adj.amount|floatformat:2 }} {{ adj.type }} {% if adj.project %}({{ adj.project.name }}){% endif %} {% endfor %} {% if not wd.adjustments %} - {% endif %} {% if wd.adj_amount >= 0 %}+{% endif %}R {{ wd.adj_amount|floatformat:2 }} R {{ wd.total_payable|floatformat:2 }}
{% csrf_token %}
No pending payments. All workers are paid up!
{% endif %} {# =============================================== #} {# === PAYMENT HISTORY TAB === #} {# =============================================== #} {% if active_tab == 'paid' %}
{% for record in paid_records %} {% empty %} {% endfor %}
Date Worker Amount Paid Work Logs Adjustments Payslip
{{ record.date }} {{ record.worker.name }} R {{ record.amount_paid|floatformat:2 }} {{ record.work_logs.count }} day{{ record.work_logs.count|pluralize }} {% for adj in record.adjustments.all %} {{ adj.type }}: R {{ adj.amount|floatformat:2 }} {% empty %} - {% endfor %} View
No payment history yet.
{% endif %} {# =============================================== #} {# === LOANS TAB === #} {# =============================================== #} {% if active_tab == 'loans' %}
Active History
{% for loan in loans %} {% empty %} {% endfor %}
Worker Type Principal Balance Date Reason Status
{{ loan.worker.name }} {% if loan.loan_type == 'advance' %} Advance {% else %} Loan {% endif %} R {{ loan.principal_amount|floatformat:2 }} R {{ loan.remaining_balance|floatformat:2 }} {{ loan.date }} {{ loan.reason|default:"-" }} {% if loan.active %} Active {% else %} Paid Off {% endif %}
{% if loan_filter == 'active' %}No active loans or advances.{% else %}No loan/advance history.{% endif %}
{% endif %}
{# ================================================================== #} {# === MODALS === #} {# ================================================================== #} {# --- ADD ADJUSTMENT MODAL --- #} {# --- EDIT ADJUSTMENT MODAL --- #} {# --- DELETE CONFIRMATION MODAL --- #} {# --- PRICE OVERTIME MODAL --- #} {# --- PREVIEW PAYSLIP MODAL --- #} {# === BATCH PAY MODAL === #} {# Shows a preview of which workers will be paid (based on team pay schedules), #} {# then lets the admin confirm to process all payments at once. #} {# === WORKER LOOKUP MODAL === #} {# Shows a comprehensive financial report card for any active worker. #} {# Triggered by clicking a worker name or the "Worker Lookup" button. #} {# ================================================================== #} {# === JAVASCRIPT === #} {# ================================================================== #} {# Django's json_script filter safely outputs JSON without XSS risk #} {{ overtime_data_json|json_script:"otDataJson" }} {{ team_workers_map_json|json_script:"teamWorkersJson" }} {{ chart_labels_json|json_script:"chartLabelsJson" }} {{ chart_totals_json|json_script:"chartTotalsJson" }} {{ project_chart_json|json_script:"projectChartJson" }} {{ worker_chart_json|json_script:"workerChartJson" }} {% endblock %}