2025-08-12 13:33:25 +03:00

476 lines
26 KiB
HTML

{% extends "base.html" %}
{% load static %}
{% block title %}Insurance Claims - {{ block.super }}{% endblock %}
{% block content %}
<div class="container-fluid">
<!-- Page Header -->
<div class="d-flex justify-content-between align-items-center mb-4">
<div>
<h1 class="h3 mb-1">Insurance Claims</h1>
<nav aria-label="breadcrumb">
<ol class="breadcrumb mb-0">
<li class="breadcrumb-item"><a href="{% url 'billing:dashboard' %}">Billing</a></li>
<li class="breadcrumb-item active">Insurance Claims</li>
</ol>
</nav>
</div>
<div class="btn-group">
<a href="{% url 'billing:claim_create' %}" class="btn btn-info">
<i class="fas fa-plus me-2"></i>Submit Claim
</a>
<button type="button" class="btn btn-outline-secondary dropdown-toggle dropdown-toggle-split" data-bs-toggle="dropdown">
<span class="visually-hidden">Toggle Dropdown</span>
</button>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="{% url 'billing:export_claims' %}">
<i class="fas fa-download me-2"></i>Export Claims
</a></li>
<li><a class="dropdown-item" href="{% url 'billing:batch_submit_claims' %}">
<i class="fas fa-upload me-2"></i>Batch Submit
</a></li>
<li><a class="dropdown-item" href="#" onclick="window.print()">
<i class="fas fa-print me-2"></i>Print List
</a></li>
</ul>
</div>
</div>
<!-- Statistics Cards -->
<div class="row mb-4" hx-get="{% url 'billing:claim_stats' %}" hx-trigger="load, every 60s">
<div class="col-md-3 mb-3">
<div class="card bg-gradient-info text-white">
<div class="card-body">
<div class="d-flex justify-content-between align-items-center">
<div>
<h6 class="card-title mb-1 opacity-75">Total Claims</h6>
<h3 class="mb-0">{{ stats.total_claims|default:0 }}</h3>
</div>
<div class="text-white-50">
<i class="fas fa-file-medical fa-2x"></i>
</div>
</div>
</div>
</div>
</div>
<div class="col-md-3 mb-3">
<div class="card bg-gradient-primary text-white">
<div class="card-body">
<div class="d-flex justify-content-between align-items-center">
<div>
<h6 class="card-title mb-1 opacity-75">Total Amount</h6>
<h3 class="mb-0">${{ stats.total_amount|default:0|floatformat:2 }}</h3>
</div>
<div class="text-white-50">
<i class="fas fa-dollar-sign fa-2x"></i>
</div>
</div>
</div>
</div>
</div>
<div class="col-md-3 mb-3">
<div class="card bg-gradient-warning text-white">
<div class="card-body">
<div class="d-flex justify-content-between align-items-center">
<div>
<h6 class="card-title mb-1 opacity-75">Pending</h6>
<h3 class="mb-0">{{ stats.pending_count|default:0 }}</h3>
</div>
<div class="text-white-50">
<i class="fas fa-clock fa-2x"></i>
</div>
</div>
</div>
</div>
</div>
<div class="col-md-3 mb-3">
<div class="card bg-gradient-danger text-white">
<div class="card-body">
<div class="d-flex justify-content-between align-items-center">
<div>
<h6 class="card-title mb-1 opacity-75">Denied</h6>
<h3 class="mb-0">{{ stats.denied_count|default:0 }}</h3>
</div>
<div class="text-white-50">
<i class="fas fa-times-circle fa-2x"></i>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Search and Filter Card -->
<div class="card mb-4">
<div class="card-header">
<h5 class="mb-0">
<i class="fas fa-search me-2"></i>Search & Filter
</h5>
</div>
<div class="card-body">
<form method="get" class="row g-3" hx-get="{% url 'billing:claim_list' %}" hx-target="#claim-list-container" hx-trigger="submit, change delay:500ms">
<div class="col-md-3">
<div class="form-floating">
<input type="text" class="form-control" id="search" name="search" value="{{ request.GET.search }}" placeholder="Search claims...">
<label for="search">Search Claims</label>
</div>
</div>
<div class="col-md-2">
<div class="form-floating">
<select class="form-select" id="status" name="status">
<option value="">All Statuses</option>
<option value="DRAFT" {% if request.GET.status == 'DRAFT' %}selected{% endif %}>Draft</option>
<option value="SUBMITTED" {% if request.GET.status == 'SUBMITTED' %}selected{% endif %}>Submitted</option>
<option value="PENDING" {% if request.GET.status == 'PENDING' %}selected{% endif %}>Pending</option>
<option value="APPROVED" {% if request.GET.status == 'APPROVED' %}selected{% endif %}>Approved</option>
<option value="PARTIALLY_APPROVED" {% if request.GET.status == 'PARTIALLY_APPROVED' %}selected{% endif %}>Partially Approved</option>
<option value="DENIED" {% if request.GET.status == 'DENIED' %}selected{% endif %}>Denied</option>
<option value="PAID" {% if request.GET.status == 'PAID' %}selected{% endif %}>Paid</option>
<option value="APPEALED" {% if request.GET.status == 'APPEALED' %}selected{% endif %}>Appealed</option>
</select>
<label for="status">Status</label>
</div>
</div>
<div class="col-md-2">
<div class="form-floating">
<input type="text" class="form-control" id="insurance_company" name="insurance_company" value="{{ request.GET.insurance_company }}" placeholder="Insurance Company">
<label for="insurance_company">Insurance Company</label>
</div>
</div>
<div class="col-md-2">
<div class="form-floating">
<input type="date" class="form-control" id="date_from" name="date_from" value="{{ request.GET.date_from }}">
<label for="date_from">From Date</label>
</div>
</div>
<div class="col-md-2">
<div class="form-floating">
<input type="date" class="form-control" id="date_to" name="date_to" value="{{ request.GET.date_to }}">
<label for="date_to">To Date</label>
</div>
</div>
<div class="col-md-1">
<button type="submit" class="btn btn-primary h-100 w-100">
<i class="fas fa-search"></i>
</button>
</div>
</form>
</div>
</div>
<!-- Claims List Card -->
<div class="card">
<div class="card-header d-flex justify-content-between align-items-center">
<h5 class="mb-0">
<i class="fas fa-file-medical me-2"></i>Insurance Claims
<span class="badge bg-secondary ms-2">{{ page_obj.paginator.count }} total</span>
</h5>
<div class="btn-group btn-group-sm">
<button type="button" class="btn btn-outline-secondary" onclick="selectAll()">
<i class="fas fa-check-square me-1"></i>Select All
</button>
<button type="button" class="btn btn-outline-secondary" onclick="clearSelection()">
<i class="fas fa-square me-1"></i>Clear
</button>
<div class="btn-group" role="group">
<button type="button" class="btn btn-outline-secondary dropdown-toggle" data-bs-toggle="dropdown">
<i class="fas fa-cog me-1"></i>Bulk Actions
</button>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="#" onclick="bulkAction('export')">
<i class="fas fa-download me-2"></i>Export Selected
</a></li>
<li><a class="dropdown-item" href="#" onclick="bulkAction('submit')">
<i class="fas fa-paper-plane me-2"></i>Submit Selected
</a></li>
<li><a class="dropdown-item" href="#" onclick="bulkAction('resubmit')">
<i class="fas fa-redo me-2"></i>Resubmit Selected
</a></li>
</ul>
</div>
</div>
</div>
<div class="card-body p-0">
<div id="claim-list-container">
<div class="table-responsive">
<table class="table table-hover mb-0">
<thead class="table-light">
<tr>
<th width="40">
<div class="form-check">
<input class="form-check-input" type="checkbox" id="selectAllCheckbox" onchange="toggleSelectAll()">
</div>
</th>
<th>Claim Number</th>
<th>Patient</th>
<th>Bill Number</th>
<th>Insurance Company</th>
<th>Submit Date</th>
<th>Billed Amount</th>
<th>Approved Amount</th>
<th>Status</th>
<th>Days Pending</th>
<th width="120">Actions</th>
</tr>
</thead>
<tbody>
{% for claim in page_obj %}
<tr>
<td>
<div class="form-check">
<input class="form-check-input claim-checkbox" type="checkbox" value="{{ claim.claim_id }}">
</div>
</td>
<td>
<a href="{% url 'billing:claim_detail' claim.claim_id %}" class="text-decoration-none fw-bold">
{{ claim.claim_number }}
</a>
</td>
<td>
<div>
<strong>{{ claim.medical_bill.patient.get_full_name }}</strong>
<br><small class="text-muted">MRN: {{ claim.medical_bill.patient.mrn }}</small>
</div>
</td>
<td>
<a href="{% url 'billing:bill_detail' claim.medical_bill.bill_id %}" class="text-decoration-none">
{{ claim.medical_bill.bill_number }}
</a>
</td>
<td>
<div>
<strong>{{ claim.insurance_info.insurance_company }}</strong>
<br><small class="text-muted">{{ claim.insurance_info.policy_number }}</small>
</div>
</td>
<td>
{% if claim.submission_date %}
{{ claim.submission_date|date:"M d, Y" }}
{% else %}
<span class="text-muted">Not submitted</span>
{% endif %}
</td>
<td class="text-end">${{ claim.billed_amount|floatformat:2 }}</td>
<td class="text-end">
{% if claim.approved_amount %}
<span class="text-success fw-bold">${{ claim.approved_amount|floatformat:2 }}</span>
{% else %}
<span class="text-muted">-</span>
{% endif %}
</td>
<td>
{% if claim.status == 'DRAFT' %}
<span class="badge bg-secondary">Draft</span>
{% elif claim.status == 'SUBMITTED' %}
<span class="badge bg-info">Submitted</span>
{% elif claim.status == 'PENDING' %}
<span class="badge bg-warning">Pending</span>
{% elif claim.status == 'APPROVED' %}
<span class="badge bg-success">Approved</span>
{% elif claim.status == 'PARTIALLY_APPROVED' %}
<span class="badge bg-primary">Partially Approved</span>
{% elif claim.status == 'DENIED' %}
<span class="badge bg-danger">Denied</span>
{% elif claim.status == 'PAID' %}
<span class="badge bg-success">Paid</span>
{% elif claim.status == 'APPEALED' %}
<span class="badge bg-dark">Appealed</span>
{% endif %}
</td>
<td>
{% if claim.submission_date %}
<span class="{% if claim.days_pending > 30 %}text-warning{% elif claim.days_pending > 60 %}text-danger{% endif %}">
{{ claim.days_pending }} days
</span>
{% else %}
<span class="text-muted">-</span>
{% endif %}
</td>
<td>
<div class="btn-group btn-group-sm">
<a href="{% url 'billing:claim_detail' claim.claim_id %}" class="btn btn-outline-primary btn-sm" title="View Details">
<i class="fas fa-eye"></i>
</a>
{% if claim.status == 'DRAFT' %}
<a href="{% url 'billing:claim_update' claim.claim_id %}" class="btn btn-outline-secondary btn-sm" title="Edit">
<i class="fas fa-edit"></i>
</a>
{% endif %}
<div class="btn-group" role="group">
<button type="button" class="btn btn-outline-secondary btn-sm dropdown-toggle dropdown-toggle-split" data-bs-toggle="dropdown">
<span class="visually-hidden">Toggle Dropdown</span>
</button>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="{% url 'billing:claim_print' claim.claim_id %}">
<i class="fas fa-print me-2"></i>Print Claim
</a></li>
<li><a class="dropdown-item" href="{% url 'billing:claim_download' claim.claim_id %}">
<i class="fas fa-download me-2"></i>Download
</a></li>
{% if claim.status == 'DRAFT' %}
<li><hr class="dropdown-divider"></li>
<li><a class="dropdown-item text-info" href="{% url 'billing:claim_submit' claim.claim_id %}">
<i class="fas fa-paper-plane me-2"></i>Submit
</a></li>
{% elif claim.status == 'DENIED' %}
<li><hr class="dropdown-divider"></li>
<li><a class="dropdown-item text-warning" href="{% url 'billing:claim_appeal' claim.claim_id %}">
<i class="fas fa-gavel me-2"></i>Appeal
</a></li>
<li><a class="dropdown-item text-info" href="{% url 'billing:claim_resubmit' claim.claim_id %}">
<i class="fas fa-redo me-2"></i>Resubmit
</a></li>
{% endif %}
{% if claim.status in 'DRAFT,DENIED' %}
<li><hr class="dropdown-divider"></li>
<li><a class="dropdown-item text-danger" href="{% url 'billing:claim_delete' claim.claim_id %}">
<i class="fas fa-trash me-2"></i>Delete
</a></li>
{% endif %}
</ul>
</div>
</div>
</td>
</tr>
{% empty %}
<tr>
<td colspan="11" class="text-center py-5">
<div class="text-muted">
<i class="fas fa-file-medical fa-3x mb-3 opacity-50"></i>
<h5>No claims found</h5>
<p>No insurance claims match your current filters.</p>
<a href="{% url 'billing:claim_create' %}" class="btn btn-info">
<i class="fas fa-plus me-2"></i>Submit First Claim
</a>
</div>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
<!-- Pagination -->
{% if page_obj.has_other_pages %}
<div class="card-footer">
<div class="d-flex justify-content-between align-items-center">
<div class="text-muted">
Showing {{ page_obj.start_index }} to {{ page_obj.end_index }} of {{ page_obj.paginator.count }} claims
</div>
<nav aria-label="Claims pagination">
<ul class="pagination pagination-sm mb-0">
{% if page_obj.has_previous %}
<li class="page-item">
<a class="page-link" href="?{% for key, value in request.GET.items %}{% if key != 'page' %}{{ key }}={{ value }}&{% endif %}{% endfor %}page=1">First</a>
</li>
<li class="page-item">
<a class="page-link" href="?{% for key, value in request.GET.items %}{% if key != 'page' %}{{ key }}={{ value }}&{% endif %}{% endfor %}page={{ page_obj.previous_page_number }}">Previous</a>
</li>
{% endif %}
{% for num in page_obj.paginator.page_range %}
{% if page_obj.number == num %}
<li class="page-item active">
<span class="page-link">{{ num }}</span>
</li>
{% elif num > page_obj.number|add:'-3' and num < page_obj.number|add:'3' %}
<li class="page-item">
<a class="page-link" href="?{% for key, value in request.GET.items %}{% if key != 'page' %}{{ key }}={{ value }}&{% endif %}{% endfor %}page={{ num }}">{{ num }}</a>
</li>
{% endif %}
{% endfor %}
{% if page_obj.has_next %}
<li class="page-item">
<a class="page-link" href="?{% for key, value in request.GET.items %}{% if key != 'page' %}{{ key }}={{ value }}&{% endif %}{% endfor %}page={{ page_obj.next_page_number }}">Next</a>
</li>
<li class="page-item">
<a class="page-link" href="?{% for key, value in request.GET.items %}{% if key != 'page' %}{{ key }}={{ value }}&{% endif %}{% endfor %}page={{ page_obj.paginator.num_pages }}">Last</a>
</li>
{% endif %}
</ul>
</nav>
</div>
</div>
{% endif %}
</div>
</div>
<script>
// Bulk selection functionality
function toggleSelectAll() {
const selectAllCheckbox = document.getElementById('selectAllCheckbox');
const claimCheckboxes = document.querySelectorAll('.claim-checkbox');
claimCheckboxes.forEach(checkbox => {
checkbox.checked = selectAllCheckbox.checked;
});
}
function selectAll() {
const claimCheckboxes = document.querySelectorAll('.claim-checkbox');
const selectAllCheckbox = document.getElementById('selectAllCheckbox');
claimCheckboxes.forEach(checkbox => {
checkbox.checked = true;
});
selectAllCheckbox.checked = true;
}
function clearSelection() {
const claimCheckboxes = document.querySelectorAll('.claim-checkbox');
const selectAllCheckbox = document.getElementById('selectAllCheckbox');
claimCheckboxes.forEach(checkbox => {
checkbox.checked = false;
});
selectAllCheckbox.checked = false;
}
function bulkAction(action) {
const selectedClaims = Array.from(document.querySelectorAll('.claim-checkbox:checked')).map(cb => cb.value);
if (selectedClaims.length === 0) {
alert('Please select at least one claim.');
return;
}
switch(action) {
case 'export':
window.location.href = `{% url 'billing:export_claims' %}?claims=${selectedClaims.join(',')}`;
break;
case 'submit':
if (confirm(`Submit ${selectedClaims.length} selected claims?`)) {
htmx.ajax('POST', '{% url "billing:bulk_submit_claims" %}', {
values: {claims: selectedClaims, csrfmiddlewaretoken: '{{ csrf_token }}'}
});
}
break;
case 'resubmit':
if (confirm(`Resubmit ${selectedClaims.length} selected claims?`)) {
htmx.ajax('POST', '{% url "billing:bulk_resubmit_claims" %}', {
values: {claims: selectedClaims, csrfmiddlewaretoken: '{{ csrf_token }}'}
});
}
break;
}
}
// Update select all checkbox based on individual selections
document.addEventListener('change', function(e) {
if (e.target.classList.contains('claim-checkbox')) {
const claimCheckboxes = document.querySelectorAll('.claim-checkbox');
const selectAllCheckbox = document.getElementById('selectAllCheckbox');
const checkedCount = document.querySelectorAll('.claim-checkbox:checked').length;
selectAllCheckbox.checked = checkedCount === claimCheckboxes.length;
selectAllCheckbox.indeterminate = checkedCount > 0 && checkedCount < claimCheckboxes.length;
}
});
</script>
{% endblock %}