438 lines
23 KiB
HTML
438 lines
23 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="">
|
|
<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>
|
|
<i class="fas fa-ellipsis-v"></i>
|
|
</button>
|
|
<ul class="dropdown-menu">
|
|
<li><a class="dropdown-item" href="">
|
|
<i class="fas fa-print me-2"></i>Print Claim
|
|
</a></li>
|
|
<li><a class="dropdown-item" href="">
|
|
<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="">
|
|
<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="">
|
|
<i class="fas fa-gavel me-2"></i>Appeal
|
|
</a></li>
|
|
<li><a class="dropdown-item text-info" href="">
|
|
<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="">
|
|
<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 is_paginated %}
|
|
{% include 'partial/pagination.html' %}
|
|
{% 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 %}
|
|
|