Replace the green accent with a warm orange/amber palette and switch to a dark-first design. Add a fixed sidebar for desktop navigation and a bottom tab bar for mobile, replacing the top navbar. Cards now use glass-morphism with left accent bars, buttons use orange gradients, and decorative glow effects add depth. All 8 page templates updated, both light and dark modes tested across desktop and mobile viewports. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
235 lines
12 KiB
HTML
235 lines
12 KiB
HTML
{% extends 'base.html' %}
|
|
|
|
{% block title %}Payslip #{{ record.id }} | FoxFitt{% endblock %}
|
|
|
|
{% block content %}
|
|
<!-- === PAYSLIP DETAIL PAGE ===
|
|
Shows a completed payment with work logs, adjustments, and totals.
|
|
Print-friendly layout. -->
|
|
|
|
<div class="container py-4">
|
|
<!-- Action buttons (hidden when printing) -->
|
|
<div class="d-print-none mb-4 d-flex gap-2 flex-wrap">
|
|
<a href="{% url 'payroll_dashboard' %}?status=paid" class="btn btn-outline-secondary">
|
|
<i class="fas fa-arrow-left me-1"></i> Back to Payment History
|
|
</a>
|
|
<button onclick="window.print()" class="btn btn-accent">
|
|
<i class="fas fa-print me-1"></i> Print Payslip
|
|
</button>
|
|
</div>
|
|
|
|
<!-- Payslip card -->
|
|
<div class="card" id="payslip-card">
|
|
<div class="card-body p-4 p-md-5">
|
|
|
|
<!-- === HEADER === -->
|
|
<div class="row mb-5 pb-4 align-items-center" style="border-bottom: 2px solid var(--border-default);">
|
|
<div class="col-md-6">
|
|
<div class="stat-label mb-1">Payment To Beneficiary:</div>
|
|
<h2 class="fw-bold mb-0 text-uppercase">{{ record.worker.name }}</h2>
|
|
<p class="mb-0" style="color: var(--text-tertiary); font-size: 0.85rem;">
|
|
{% if is_advance %}Advance{% elif is_loan %}Loan{% endif %} Payslip No. #{{ record.id|stringformat:"06d" }}
|
|
</p>
|
|
</div>
|
|
<div class="col-md-6 text-md-end mt-3 mt-md-0">
|
|
<h3 class="fw-bold text-uppercase" style="color: var(--text-secondary);">
|
|
{% if is_advance %}Advance{% elif is_loan %}Loan{% endif %} Payslip
|
|
</h3>
|
|
<div class="fw-bold">{{ record.date|date:"F j, Y" }}</div>
|
|
<div style="color: var(--text-tertiary); font-size: 0.85rem;">Payer: Fox Fitt</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- === WORKER DETAILS + NET PAY === -->
|
|
<div class="row mb-5">
|
|
<div class="col-md-6">
|
|
<div class="stat-label mb-2">Beneficiary Details:</div>
|
|
<h4 class="fw-bold">{{ record.worker.name }}</h4>
|
|
<p class="mb-0">ID Number: <strong>{{ record.worker.id_number }}</strong></p>
|
|
<p class="mb-0" style="color: var(--text-secondary);">Phone: {{ record.worker.phone_number|default:"—" }}</p>
|
|
</div>
|
|
<div class="col-md-6 text-md-end mt-4 mt-md-0">
|
|
<div class="stat-label mb-2">Net Payable Amount:</div>
|
|
<div style="font-size: 2.5rem; font-weight: 700; font-family: 'Poppins', sans-serif;">
|
|
R {{ record.amount_paid|floatformat:2 }}
|
|
</div>
|
|
<p class="fw-bold mt-2" style="color: var(--color-success); font-size: 0.85rem;">
|
|
<i class="fas fa-check-circle me-1"></i> PAID
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
{% if is_advance %}
|
|
<!-- === ADVANCE PAYMENT DETAIL === -->
|
|
<div class="stat-label mb-3">Advance Details</div>
|
|
<div class="table-responsive mb-4">
|
|
<table class="table table-hover mb-0">
|
|
<thead>
|
|
<tr>
|
|
<th>Date</th>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
<th class="text-end">Amount</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td>{{ advance_adj.date|date:"M d, Y" }}</td>
|
|
<td><span class="badge" style="background: var(--color-info-bg); color: var(--color-info);">ADVANCE PAYMENT</span></td>
|
|
<td>{{ advance_adj.description|default:"Salary advance" }}</td>
|
|
<td class="text-end fw-bold" style="color: var(--color-success);">R {{ advance_adj.amount|floatformat:2 }}</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<div class="row justify-content-end mt-4">
|
|
<div class="col-md-5">
|
|
<table class="table table-sm border-0">
|
|
<tr style="border-top: 2px solid var(--text-primary);">
|
|
<td class="text-end border-0 fw-bold fs-5">Amount Advanced:</td>
|
|
<td class="text-end border-0 fw-bold fs-5">R {{ advance_adj.amount|floatformat:2 }}</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
{% elif is_loan %}
|
|
<!-- === LOAN PAYMENT DETAIL === -->
|
|
<div class="stat-label mb-3">Loan Details</div>
|
|
<div class="table-responsive mb-4">
|
|
<table class="table table-hover mb-0">
|
|
<thead>
|
|
<tr>
|
|
<th>Date</th>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
<th class="text-end">Amount</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td>{{ loan_adj.date|date:"M d, Y" }}</td>
|
|
<td><span class="badge" style="background: var(--color-warning-bg); color: var(--color-warning);">LOAN PAYMENT</span></td>
|
|
<td>{{ loan_adj.description|default:"Worker loan" }}</td>
|
|
<td class="text-end fw-bold" style="color: var(--color-success);">R {{ loan_adj.amount|floatformat:2 }}</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<div class="row justify-content-end mt-4">
|
|
<div class="col-md-5">
|
|
<table class="table table-sm border-0">
|
|
<tr style="border-top: 2px solid var(--text-primary);">
|
|
<td class="text-end border-0 fw-bold fs-5">Loan Amount:</td>
|
|
<td class="text-end border-0 fw-bold fs-5">R {{ loan_adj.amount|floatformat:2 }}</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
{% else %}
|
|
<!-- === WORK LOG TABLE === -->
|
|
<div class="stat-label mb-3">Work Log Details (Attendance)</div>
|
|
<div class="table-responsive mb-4">
|
|
<table class="table table-hover mb-0">
|
|
<thead>
|
|
<tr>
|
|
<th>Date</th>
|
|
<th>Project</th>
|
|
<th>Notes</th>
|
|
<th class="text-end">Amount</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for log in logs %}
|
|
<tr>
|
|
<td>{{ log.date|date:"M d, Y" }}</td>
|
|
<td>{{ log.project.name }}</td>
|
|
<td style="color: var(--text-secondary);">{{ log.notes|default:"—"|truncatechars:50 }}</td>
|
|
<td class="text-end">R {{ record.worker.daily_rate|floatformat:2 }}</td>
|
|
</tr>
|
|
{% empty %}
|
|
<tr>
|
|
<td colspan="4" class="text-center py-3" style="color: var(--text-tertiary);">
|
|
<i class="fas fa-info-circle me-1"></i> No work logs in this period.
|
|
</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
<tfoot>
|
|
<tr style="background: var(--bg-inset);">
|
|
<td colspan="3" class="text-end fw-bold">Base Pay Subtotal</td>
|
|
<td class="text-end fw-bold">R {{ base_pay|floatformat:2 }}</td>
|
|
</tr>
|
|
</tfoot>
|
|
</table>
|
|
</div>
|
|
|
|
<!-- === ADJUSTMENTS TABLE === -->
|
|
{% if adjustments %}
|
|
<div class="stat-label mb-3 mt-4">Adjustments (Bonuses, Deductions, Loans)</div>
|
|
<div class="table-responsive mb-4">
|
|
<table class="table table-hover mb-0">
|
|
<thead>
|
|
<tr>
|
|
<th>Date</th>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
<th class="text-end">Amount</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for adj in adjustments %}
|
|
<tr>
|
|
<td>{{ adj.date|date:"M d, Y" }}</td>
|
|
<td>
|
|
<span class="badge" style="background: var(--bg-inset); color: var(--text-secondary); border: 1px solid var(--border-default);">
|
|
{{ adj.get_type_display|upper }}
|
|
</span>
|
|
</td>
|
|
<td>{{ adj.description }}</td>
|
|
<td class="text-end fw-semibold {% if adj.type in deductive_types %}{% else %}{% endif %}" style="color: {% if adj.type in deductive_types %}var(--color-danger){% else %}var(--color-success){% endif %};">
|
|
{% if adj.type in deductive_types %}- R {{ adj.amount|floatformat:2 }}{% else %}+ R {{ adj.amount|floatformat:2 }}{% endif %}
|
|
</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
{% endif %}
|
|
|
|
<!-- === GRAND TOTAL === -->
|
|
<div class="row justify-content-end mt-4">
|
|
<div class="col-md-5">
|
|
<table class="table table-sm border-0">
|
|
<tr>
|
|
<td class="text-end border-0" style="color: var(--text-secondary);">Base Pay:</td>
|
|
<td class="text-end border-0" width="140">R {{ base_pay|floatformat:2 }}</td>
|
|
</tr>
|
|
{% if adjustments %}
|
|
<tr>
|
|
<td class="text-end border-0" style="color: var(--text-secondary);">Adjustments Net:</td>
|
|
<td class="text-end border-0">
|
|
{% if adjustments_net >= 0 %}+ R {{ adjustments_net|floatformat:2 }}{% else %}- R {{ adjustments_net_abs|floatformat:2 }}{% endif %}
|
|
</td>
|
|
</tr>
|
|
{% endif %}
|
|
<tr style="border-top: 2px solid var(--text-primary);">
|
|
<td class="text-end border-0 fw-bold fs-5">Net Payable:</td>
|
|
<td class="text-end border-0 fw-bold fs-5">R {{ record.amount_paid|floatformat:2 }}</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
|
|
<!-- === FOOTER === -->
|
|
<div class="text-center mt-5 pt-4" style="border-top: 1px solid var(--border-default); color: var(--text-tertiary); font-size: 0.85rem;">
|
|
<p>This is a computer-generated document and does not require a signature.</p>
|
|
<p>Payer: Fox Fitt © {% now "Y" %}</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endblock %}
|