@extends('layouts.app') @section('title', 'Staff Profile — ' . $staff->full_name) @section('content')
Staff Register / {{ $staff->full_name }}

{{ $staff->full_name }}

{{ $staff->employee_number }} · {{ $staff->designation ?? 'No designation' }} · {{ $staff->department->name ?? 'No department' }}

@php $statusBadge = match($staff->status) { 'active' => 'badge-success', 'on_leave' => 'badge-warning', 'suspended' => 'badge-warning', 'inactive' => 'badge-gray', 'terminated' => 'badge-danger', default => 'badge-gray', }; @endphp {{ ucfirst(str_replace('_', ' ', $staff->status)) }} Edit @if($staff->status === 'active') {{-- Demote-to-locum is rare, so we keep it as a small secondary action in the header. Clicking opens a modal that collects the locum-specific bits the staff record doesn't have (rate, payment mode). --}} @endif
@if(session('success'))
{{ session('success') }}
@endif @if(session('error'))
{{ session('error') }}
@endif {{-- ─── Demote to Locum modal ────────────────────────────────────── Triggered by the "Demote to Locum" button in the header. Hidden by default — only the small header button is visible until the admin chooses to demote. The original StaffRecord stays in the database (status=converted) so payroll, leave, and roster history aren't orphaned. A fresh Locum row is created against the same User row. The admin supplies rate / payment info because staff salary (monthly) and locum rate (per-shift or %) are structurally different — we cannot infer one from the other. --}} @if($staff->status === 'active') @endif
{{-- Personal --}}

Personal Details

Full Name
{{ $staff->full_name }}
ID Number
{{ $staff->id_number ?? '—' }}
Phone
{{ $staff->phone ?? '—' }}
Email
{{ $staff->email ?? '—' }}
Gender
{{ $staff->gender ? ucfirst($staff->gender) : '—' }}
Date of Birth
{{ optional($staff->date_of_birth)->format('d M Y') ?? '—' }}
{{-- Employment --}}

Employment

Employee #
{{ $staff->employee_number }}
Department
{{ $staff->department->name ?? '—' }}
Designation
{{ $staff->designation ?? '—' }}
@if($staff->license_no)
License #
{{ $staff->license_no }}
License Expiry
{{ optional($staff->license_expiry)->format('d M Y') ?? '—' }}
@endif
Employment Type
{{ $staff->employment_type ? ucfirst(str_replace('_', ' ', $staff->employment_type)) : '—' }}
Contract Type
{{ $staff->contract_type ? ucfirst($staff->contract_type) : '—' }}
Employment Date
{{ optional($staff->employment_date)->format('d M Y') ?? '—' }}
@if($staff->end_date)
End Date
{{ $staff->end_date->format('d M Y') }}
@endif
{{-- Compensation --}}

Compensation

@if(Route::has('payroll.staff.profile')) Payroll Profile → @endif
Basic Salary
KES {{ number_format($staff->salary ?? 0, 2) }}
Taxable Allowances
KES {{ number_format($staff->taxable_allowances ?? 0, 2) }}
Non-taxable Allowances
KES {{ number_format($staff->non_taxable_allowances ?? 0, 2) }}
Benefits in Kind
KES {{ number_format($staff->benefits_in_kind ?? 0, 2) }}
Pension
KES {{ number_format($staff->pension_contribution ?? 0, 2) }}
Insurance Relief
KES {{ number_format($staff->insurance_relief ?? 0, 2) }}
Gross (basic + allowances)
KES {{ number_format(($staff->salary ?? 0) + ($staff->taxable_allowances ?? 0) + ($staff->non_taxable_allowances ?? 0), 2) }}
{{-- Statutory + Payment --}}

Statutory & Payment

KRA PIN
{{ $staff->kra_pin ?? '—' }}
NSSF Number
{{ $staff->nssf_number ?? '—' }}
SHA Number
{{ $staff->sha_number ?? '—' }}
Payment Method
{{ $staff->payment_method ? ucfirst($staff->payment_method) : '—' }}
@if($staff->payment_method === 'bank' || $staff->bank_account)
Bank
{{ $staff->bank_name ?? '—' }}
Account
{{ $staff->bank_account ?? '—' }}
@endif @if($staff->payment_method === 'mpesa' || $staff->mobile_payment_number)
M-Pesa
{{ $staff->mobile_payment_number ?? '—' }}
@endif
{{-- ═════ Payroll Snapshot ═════════════════════════════════════════════ Live calculation from PayrollCalculator. Read-only here — to edit the underlying figures (basic salary, allowances, etc.) use the "Payroll Profile →" link inside the Compensation card above. Spans both columns so the breakdown tables read cleanly. ═════════════════════════════════════════════════════════════════════ --}} @php $hrEarnings = [ 'basic_salary' => (float) ($staff->salary ?? 0), 'taxable_allowances' => (float) ($staff->taxable_allowances ?? 0), 'non_taxable_allowances' => (float) ($staff->non_taxable_allowances ?? 0), 'overtime' => 0, 'bonus' => 0, 'benefits_in_kind' => (float) ($staff->benefits_in_kind ?? 0), 'pension_contribution' => (float) ($staff->pension_contribution ?? 0), 'insurance_relief' => (float) ($staff->insurance_relief ?? 0), 'other_deductions' => 0, ]; $hrPreview = null; try { $hrPreview = \App\Services\PayrollCalculator::calculate($hrEarnings); } catch (\Throwable $e) { $hrPreview = null; } if ($hrPreview) { $hrKraTotal = $hrPreview['paye'] + $hrPreview['ahl_employee'] + $hrPreview['ahl_employer']; $hrShaTotal = $hrPreview['shif']; $hrNssfTotal = $hrPreview['nssf_employee'] + $hrPreview['nssf_employer']; $hrTotalRemit = $hrKraTotal + $hrShaTotal + $hrNssfTotal; } @endphp @if($hrPreview && ($staff->salary ?? 0) > 0)
{{-- Net Pay (Take-home) --}}

Net Pay (Take-home)

What hits the staff member's account

KES

{{ number_format($hrPreview['net_pay'], 2) }}

Gross {{ number_format($hrPreview['gross_pay']) }} − Deductions {{ number_format($hrPreview['total_deductions']) }}

{{-- Total Cost to Hospital --}}

Total Cost to Hospital

Gross + employer-side contributions

Gross Pay{{ number_format($hrPreview['gross_pay'], 2) }}
+ NSSF (employer){{ number_format($hrPreview['nssf_employer'], 2) }}
+ Housing Levy (employer){{ number_format($hrPreview['ahl_employer'], 2) }}
Total Employer Cost{{ number_format($hrPreview['employer_cost'], 2) }}
{{-- Monthly Remittances — by authority --}}

Monthly Remittances

Grouped by who you pay · {{ now()->format('M Y') }} rates

KRA (iTax)
PAYE{{ number_format($hrPreview['paye'], 2) }}
Housing Levy (employee){{ number_format($hrPreview['ahl_employee'], 2) }}
Housing Levy (employer){{ number_format($hrPreview['ahl_employer'], 2) }}
Subtotal to KRA{{ number_format($hrKraTotal, 2) }}
SHA (Social Health Authority)
SHIF (employee){{ number_format($hrPreview['shif'], 2) }}
Subtotal to SHA{{ number_format($hrShaTotal, 2) }}
NSSF
NSSF (employee){{ number_format($hrPreview['nssf_employee'], 2) }}
NSSF (employer){{ number_format($hrPreview['nssf_employer'], 2) }}
Subtotal to NSSF{{ number_format($hrNssfTotal, 2) }}
Total Monthly Remittance{{ number_format($hrTotalRemit, 2) }}
{{-- PAYE Workings — collapsible --}}

PAYE Workings

click to expand ▾
@if(($hrPreview['insurance_relief'] ?? 0) > 0) @endif
Gross Pay (cash + BIK){{ number_format($hrPreview['gross_pay'], 2) }}
− Pension contribution (allowed)({{ number_format($hrPreview['pension_contribution'], 2) }})
− NSSF (employee)({{ number_format($hrPreview['nssf_employee'], 2) }})
− SHIF({{ number_format($hrPreview['shif'], 2) }})
− Housing Levy (employee)({{ number_format($hrPreview['ahl_employee'], 2) }})
= Taxable Pay{{ number_format($hrPreview['taxable_pay'], 2) }}
PAYE before relief{{ number_format($hrPreview['paye_before_relief'], 2) }}
− Personal relief({{ number_format($hrPreview['personal_relief'], 2) }})
− Insurance relief({{ number_format($hrPreview['insurance_relief'], 2) }})
= PAYE Payable{{ number_format($hrPreview['paye'], 2) }}
@elseif(($staff->salary ?? 0) <= 0)
No payroll snapshot yet. Set a basic salary on the Payroll Profile to see this staff member's net pay and statutory remittance breakdown here.
@endif {{-- Emergency Contact --}} @if($staff->emergency_contact_name || $staff->emergency_contact_phone)

Emergency Contact

Name
{{ $staff->emergency_contact_name ?? '—' }}
Phone
{{ $staff->emergency_contact_phone ?? '—' }}
@endif {{-- Notes --}} @if($staff->notes)

Notes

{{ $staff->notes }}

@endif
@endsection