580 lines
26 KiB
HTML
580 lines
26 KiB
HTML
{% extends "base.html" %}
|
|
{% load static %}
|
|
|
|
{% block title %}{% if object %}Edit Claim{% else %}Submit Insurance Claim{% endif %} - {{ 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">{% if object %}Edit Insurance Claim{% else %}Submit Insurance Claim{% endif %}</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"><a href="{% url 'billing:claim_list' %}">Insurance Claims</a></li>
|
|
<li class="breadcrumb-item active">{% if object %}Edit{% else %}Submit{% endif %}</li>
|
|
</ol>
|
|
</nav>
|
|
{% if object %}
|
|
<div class="mt-2 small text-muted">
|
|
<strong>Claim #:</strong> <code>{{ object.claim_number }}</code>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
<div class="btn-group">
|
|
<a href="{% url 'billing:claim_list' %}" class="btn btn-outline-secondary">
|
|
<i class="fas fa-arrow-left me-2"></i>Back to List
|
|
</a>
|
|
{% if object %}
|
|
<a href="{% url 'billing:claim_detail' object.claim_id %}" class="btn btn-outline-primary">
|
|
<i class="fas fa-eye me-2"></i>View Details
|
|
</a>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
|
|
<form method="post"
|
|
id="claimForm"
|
|
hx-post="{% if object %}{% url 'billing:claim_update' object.claim_id %}{% else %}{% url 'billing:claim_create' %}{% endif %}"
|
|
hx-target="#form-container">
|
|
{% csrf_token %}
|
|
|
|
<div class="row">
|
|
<!-- Main Form -->
|
|
<div class="col-lg-8">
|
|
<div id="form-container">
|
|
<!-- Bill Selection (not a form field; handled in view) -->
|
|
<div class="card mb-4">
|
|
<div class="card-header">
|
|
<h5 class="mb-0">
|
|
<i class="fas fa-file-invoice me-2"></i>Bill Information
|
|
</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="row g-3">
|
|
<div class="col-md-6">
|
|
<div class="form-floating">
|
|
<select id="id_medical_bill" name="medical_bill" class="form-select">
|
|
<option value="">Select a bill...</option>
|
|
{% for bill in available_bills %}
|
|
<option value="{{ bill.bill_id }}"
|
|
{% if object and object.medical_bill.bill_id == bill.bill_id %}selected{% endif %}>
|
|
{{ bill.bill_number }} — {{ bill.patient.get_full_name }}
|
|
</option>
|
|
{% endfor %}
|
|
</select>
|
|
<label for="id_medical_bill">Medical Bill *</label>
|
|
</div>
|
|
</div>
|
|
{% if object %}
|
|
<div class="col-md-6">
|
|
<div class="alert alert-secondary mb-0 small">
|
|
<strong>Current Bill:</strong> {{ object.medical_bill.bill_number }}<br>
|
|
<strong>Patient:</strong> {{ object.medical_bill.patient.get_full_name }}
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
|
|
<!-- Bill Details Display -->
|
|
<div id="bill-details" class="mt-3" style="display:none;">
|
|
<div class="alert alert-info">
|
|
<h6 class="alert-heading">Bill Details</h6>
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<strong>Patient:</strong> <span id="bill-patient"></span><br>
|
|
<strong>Bill Number:</strong> <span id="bill-number"></span><br>
|
|
<strong>Bill Date:</strong> <span id="bill-date"></span>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<strong>Total Amount:</strong> <span id="bill-total" class="text-success"></span><br>
|
|
<strong>Service Range:</strong> <span id="bill-service-range"></span><br>
|
|
<strong>Billing Provider:</strong> <span id="bill-provider"></span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Insurance & Dates (uses form fields) -->
|
|
<div class="card mb-4">
|
|
<div class="card-header">
|
|
<h5 class="mb-0">
|
|
<i class="fas fa-shield-alt me-2"></i>Insurance & Service Dates
|
|
</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="row g-3">
|
|
<div class="col-md-6">
|
|
<div class="form-floating">
|
|
{{ form.insurance_info }}
|
|
<label for="{{ form.insurance_info.id_for_label }}">Insurance Information *</label>
|
|
{% if form.insurance_info.errors %}<div class="invalid-feedback d-block">{{ form.insurance_info.errors.0 }}</div>{% endif %}
|
|
</div>
|
|
</div>
|
|
<div class="col-md-3">
|
|
<div class="form-floating">
|
|
{{ form.service_date_from }}
|
|
<label for="{{ form.service_date_from.id_for_label }}">Service From *</label>
|
|
{% if form.service_date_from.errors %}<div class="invalid-feedback d-block">{{ form.service_date_from.errors.0 }}</div>{% endif %}
|
|
</div>
|
|
</div>
|
|
<div class="col-md-3">
|
|
<div class="form-floating">
|
|
{{ form.service_date_to }}
|
|
<label for="{{ form.service_date_to.id_for_label }}">Service To *</label>
|
|
{% if form.service_date_to.errors %}<div class="invalid-feedback d-block">{{ form.service_date_to.errors.0 }}</div>{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Insurance Details Display -->
|
|
<div id="insurance-details" class="mt-3" style="display:none;">
|
|
<div class="alert alert-light">
|
|
<h6 class="alert-heading">Insurance Details</h6>
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<strong>Company:</strong> <span id="insurance-company"></span><br>
|
|
<strong>Policy #:</strong> <span id="insurance-policy"></span><br>
|
|
<strong>Group #:</strong> <span id="insurance-group"></span>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<strong>Member ID:</strong> <span id="insurance-member"></span><br>
|
|
<strong>Plan Type:</strong> <span id="insurance-plan"></span><br>
|
|
<strong>Copay:</strong> <span id="insurance-copay"></span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Claim Details (from form) -->
|
|
<div class="card mb-4">
|
|
<div class="card-header">
|
|
<h5 class="mb-0">
|
|
<i class="fas fa-file-medical me-2"></i>Claim Details
|
|
</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="row g-3">
|
|
<div class="col-md-4">
|
|
<div class="form-floating">
|
|
{{ form.billed_amount }}
|
|
<label for="{{ form.billed_amount.id_for_label }}">Billed Amount *</label>
|
|
{% if form.billed_amount.errors %}<div class="invalid-feedback d-block">{{ form.billed_amount.errors.0 }}</div>{% endif %}
|
|
</div>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<div class="form-floating">
|
|
{{ form.claim_type }}
|
|
<label for="{{ form.claim_type.id_for_label }}">Claim Type *</label>
|
|
{% if form.claim_type.errors %}<div class="invalid-feedback d-block">{{ form.claim_type.errors.0 }}</div>{% endif %}
|
|
</div>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<div class="form-floating">
|
|
{{ form.clearinghouse }}
|
|
<label for="{{ form.clearinghouse.id_for_label }}">Clearinghouse</label>
|
|
{% if form.clearinghouse.errors %}<div class="invalid-feedback d-block">{{ form.clearinghouse.errors.0 }}</div>{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="row g-3 mt-1">
|
|
<div class="col-md-6">
|
|
<div class="form-floating">
|
|
{{ form.batch_number }}
|
|
<label for="{{ form.batch_number.id_for_label }}">Batch Number</label>
|
|
{% if form.batch_number.errors %}<div class="invalid-feedback d-block">{{ form.batch_number.errors.0 }}</div>{% endif %}
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="form-floating">
|
|
{{ form.prior_auth_number }}
|
|
<label for="{{ form.prior_auth_number.id_for_label }}">Prior Auth Number</label>
|
|
{% if form.prior_auth_number.errors %}<div class="invalid-feedback d-block">{{ form.prior_auth_number.errors.0 }}</div>{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="row g-3 mt-1">
|
|
<div class="col-12">
|
|
<div class="form-floating">
|
|
{{ form.notes }}
|
|
<label for="{{ form.notes.id_for_label }}">Notes</label>
|
|
{% if form.notes.errors %}<div class="invalid-feedback d-block">{{ form.notes.errors.0 }}</div>{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Claim Line Items (client-side helper; not bound to form) -->
|
|
<div class="card mb-4">
|
|
<div class="card-header d-flex justify-content-between align-items-center">
|
|
<h5 class="mb-0">
|
|
<i class="fas fa-list me-2"></i>Claim Line Items
|
|
</h5>
|
|
<button type="button" class="btn btn-sm btn-outline-primary" onclick="addLineItem()">
|
|
<i class="fas fa-plus me-1"></i>Add Line Item
|
|
</button>
|
|
</div>
|
|
<div class="card-body p-0">
|
|
<div class="table-responsive">
|
|
<table class="table table-hover mb-0" id="line-items-table">
|
|
<thead class="table-light">
|
|
<tr>
|
|
<th>Service Code *</th>
|
|
<th>Description *</th>
|
|
<th>Service Date *</th>
|
|
<th width="100">Quantity *</th>
|
|
<th width="120">Amount *</th>
|
|
<th width="80">Actions</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody id="line-items-body"></tbody>
|
|
</table>
|
|
</div>
|
|
<div class="p-3 bg-light">
|
|
<div class="d-flex justify-content-between">
|
|
<span class="fw-bold">Total Billed Amount:</span>
|
|
<span class="fw-bold text-primary" id="total-billed-amount">$0.00</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Form Actions -->
|
|
<div class="card">
|
|
<div class="card-body">
|
|
<div class="d-flex justify-content-between">
|
|
<div>
|
|
<a href="{% url 'billing:claim_list' %}" class="btn btn-outline-secondary">
|
|
<i class="fas fa-times me-2"></i>Cancel
|
|
</a>
|
|
</div>
|
|
<div class="btn-group">
|
|
<button type="submit" name="action" value="save_draft" class="btn btn-outline-primary">
|
|
<i class="fas fa-save me-2"></i>Save as Draft
|
|
</button>
|
|
<button type="submit" name="action" value="save_and_submit" class="btn btn-success">
|
|
<i class="fas fa-paper-plane me-2"></i>{% if object %}Update{% else %}Submit{% endif %} Claim
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Sidebar -->
|
|
<div class="col-lg-4">
|
|
<!-- Claim Summary -->
|
|
<div class="card mb-4">
|
|
<div class="card-header">
|
|
<h5 class="mb-0"><i class="fas fa-calculator me-2"></i>Claim Summary</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="d-flex justify-content-between mb-2">
|
|
<span>Total Billed:</span>
|
|
<span id="summary-billed" class="fw-bold text-primary">$0.00</span>
|
|
</div>
|
|
<div class="d-flex justify-content-between mb-2">
|
|
<span>Line Items:</span>
|
|
<span id="summary-items">0</span>
|
|
</div>
|
|
<div class="d-flex justify-content-between mb-2">
|
|
<span>Expected Copay:</span>
|
|
<span id="summary-copay" class="text-warning">$0.00</span>
|
|
</div>
|
|
<hr>
|
|
<div class="d-flex justify-content-between fw-bold">
|
|
<span>Expected Payment:</span>
|
|
<span id="summary-expected" class="text-success">$0.00</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Quick Actions -->
|
|
<div class="card mb-4">
|
|
<div class="card-header">
|
|
<h5 class="mb-0"><i class="fas fa-bolt me-2"></i>Quick Actions</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="d-grid gap-2">
|
|
<button type="button" class="btn btn-outline-primary" onclick="copyFromBill()">
|
|
<i class="fas fa-copy me-2"></i>Copy from Bill
|
|
</button>
|
|
<button type="button" class="btn btn-outline-secondary" onclick="validateClaim()">
|
|
<i class="fas fa-check-circle me-2"></i>Validate Claim
|
|
</button>
|
|
<button type="button" class="btn btn-outline-info" onclick="previewClaim()">
|
|
<i class="fas fa-eye me-2"></i>Preview Claim
|
|
</button>
|
|
<button type="button" class="btn btn-outline-warning" onclick="checkEligibility()">
|
|
<i class="fas fa-shield-alt me-2"></i>Check Eligibility
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Help -->
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h5 class="mb-0"><i class="fas fa-question-circle me-2"></i>Help & Guidelines</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="accordion accordion-flush" id="helpAccordion">
|
|
<div class="accordion-item">
|
|
<h2 class="accordion-header">
|
|
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#help-codes">
|
|
Coding Tips
|
|
</button>
|
|
</h2>
|
|
<div id="help-codes" class="accordion-collapse collapse" data-bs-parent="#helpAccordion">
|
|
<div class="accordion-body">
|
|
<ul class="list-unstyled mb-0">
|
|
<li><i class="fas fa-code text-primary me-2"></i>ICD-10 for diagnosis</li>
|
|
<li><i class="fas fa-code text-success me-2"></i>CPT/HCPCS for procedures</li>
|
|
<li><i class="fas fa-search text-info me-2"></i>Verify current codes</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="accordion-item">
|
|
<h2 class="accordion-header">
|
|
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#help-validation">
|
|
Validation Rules
|
|
</button>
|
|
</h2>
|
|
<div id="help-validation" class="accordion-collapse collapse" data-bs-parent="#helpAccordion">
|
|
<div class="accordion-body">
|
|
<ul class="list-unstyled mb-0">
|
|
<li>Service dates within coverage period</li>
|
|
<li>Valid codes & correct POS</li>
|
|
<li>Provider credentials verified</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="accordion-item">
|
|
<h2 class="accordion-header">
|
|
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#help-submission">
|
|
Submission Tips
|
|
</button>
|
|
</h2>
|
|
<div id="help-submission" class="accordion-collapse collapse" data-bs-parent="#helpAccordion">
|
|
<div class="accordion-body">
|
|
<ul class="list-unstyled mb-0">
|
|
<li>File within time limits</li>
|
|
<li>Attach required docs</li>
|
|
<li>Review before submit</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div> <!-- /accordion -->
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
|
|
<script>
|
|
let lineItemCounter = 0;
|
|
|
|
// Helpers
|
|
function toMoney(val) {
|
|
const n = parseFloat(val);
|
|
return isNaN(n) ? '0.00' : `${n.toFixed(2)}`;
|
|
}
|
|
|
|
// Hook up once the DOM is ready
|
|
document.addEventListener('DOMContentLoaded', function () {
|
|
const billSelect = document.getElementById('id_medical_bill');
|
|
if (!billSelect) return;
|
|
|
|
billSelect.addEventListener('change', function () {
|
|
const billId = this.value;
|
|
const details = document.getElementById('bill-details');
|
|
if (!billId) {
|
|
if (details) details.style.display = 'none';
|
|
return;
|
|
}
|
|
|
|
// Use the correct URL name and pass the billId
|
|
fetch(`{% url 'billing:bill_details_api' '00000000-0000-0000-0000-000000000000' %}`.replace('00000000-0000-0000-0000-000000000000', billId))
|
|
.then(r => {
|
|
if (!r.ok) throw new Error('Failed to fetch bill details');
|
|
return r.json();
|
|
})
|
|
.then(data => {
|
|
// Update the info panel
|
|
document.getElementById('bill-patient').textContent = data.patient_name || '-';
|
|
document.getElementById('bill-number').textContent = data.bill_number || '-';
|
|
document.getElementById('bill-date').textContent = data.bill_date || '-';
|
|
document.getElementById('bill-total').textContent = toMoney(data.total_amount);
|
|
// IMPORTANT: make sure this ID matches your template (bill-service-date vs bill-service-range)
|
|
const serviceEl = document.getElementById('bill-service-date') || document.getElementById('bill-service-range');
|
|
if (serviceEl) {
|
|
const from = data.service_date_from || '-';
|
|
const to = data.service_date_to || '-';
|
|
serviceEl.textContent = from && to ? `${from} → ${to}` : '-';
|
|
}
|
|
document.getElementById('bill-provider').textContent = data.billing_provider || '-';
|
|
if (details) details.style.display = 'block';
|
|
|
|
// Push defaults into the claim form
|
|
const billedInput = document.getElementById('{{ form.billed_amount.id_for_label }}') || document.querySelector('[name="billed_amount"]');
|
|
if (billedInput) billedInput.value = (parseFloat(data.total_amount) || 0).toFixed(2);
|
|
|
|
const fromInput = document.getElementById('{{ form.service_date_from.id_for_label }}') || document.querySelector('[name="service_date_from"]');
|
|
const toInput = document.getElementById('{{ form.service_date_to.id_for_label }}') || document.querySelector('[name="service_date_to"]');
|
|
if (fromInput && data.service_date_from) fromInput.value = data.service_date_from;
|
|
if (toInput && data.service_date_to) toInput.value = data.service_date_to;
|
|
|
|
if (typeof updateSummary === 'function') updateSummary();
|
|
})
|
|
.catch(err => {
|
|
console.error('Bill details error:', err);
|
|
if (details) details.style.display = 'none';
|
|
});
|
|
});
|
|
});
|
|
|
|
// Insurance selection -> details
|
|
const insuranceSelect = document.getElementById('{{ form.insurance_info.id_for_label }}');
|
|
{#if (insuranceSelect){#}
|
|
{# insuranceSelect.addEventListener('change', function(){#}
|
|
{# const insuranceId = this.value;#}
|
|
{# if (!insuranceId){#}
|
|
{# document.getElementById('insurance-details').style.display = 'none';#}
|
|
{# return;#}
|
|
{# }#}
|
|
{# fetch(`{% url 'billing:insurance_details_api' %}?insurance_id=${insuranceId}`)#}
|
|
{# .then(r => r.json())#}
|
|
{# .then(data => {#}
|
|
{# document.getElementById('insurance-company').textContent = data.company || '-';#}
|
|
{# document.getElementById('insurance-policy').textContent = data.policy_number || '-';#}
|
|
{# document.getElementById('insurance-group').textContent = data.group_number || '-';#}
|
|
{# document.getElementById('insurance-member').textContent = data.member_id || '-';#}
|
|
{# document.getElementById('insurance-plan').textContent = data.plan_type || '-';#}
|
|
{# document.getElementById('insurance-copay').textContent = data.copay_amount ? toMoney(data.copay_amount) : '0.00';#}
|
|
{# document.getElementById('insurance-details').style.display = 'block';#}
|
|
{# updateSummary();#}
|
|
{# })#}
|
|
{# .catch(err => console.error('Insurance details error:', err));#}
|
|
{# });#}
|
|
{# }#}
|
|
|
|
// Line items
|
|
function addLineItem(){
|
|
lineItemCounter++;
|
|
const tbody = document.getElementById('line-items-body');
|
|
const tr = document.createElement('tr');
|
|
tr.innerHTML = `
|
|
<td><input type="text" class="form-control form-control-sm" name="li_${lineItemCounter}_service_code" required></td>
|
|
<td><input type="text" class="form-control form-control-sm" name="li_${lineItemCounter}_description" required></td>
|
|
<td><input type="date" class="form-control form-control-sm" name="li_${lineItemCounter}_service_date" required></td>
|
|
<td><input type="number" class="form-control form-control-sm" name="li_${lineItemCounter}_quantity" value="1" min="1" required></td>
|
|
<td><input type="number" step="0.01" min="0" class="form-control form-control-sm line-item-amount" name="li_${lineItemCounter}_amount" value="0.00" required></td>
|
|
<td><button type="button" class="btn btn-sm btn-outline-danger" onclick="removeLineItem(this)"><i class="fas fa-trash"></i></button></td>
|
|
`;
|
|
tbody.appendChild(tr);
|
|
tr.querySelector('.line-item-amount').addEventListener('input', updateSummary);
|
|
updateSummary();
|
|
}
|
|
function removeLineItem(btn){
|
|
btn.closest('tr').remove(); updateSummary();
|
|
}
|
|
|
|
function updateSummary(){
|
|
let total = 0, items = 0;
|
|
document.querySelectorAll('.line-item-amount').forEach(inp=>{
|
|
const v = parseFloat(inp.value)||0;
|
|
total += v; if (v>0) items++;
|
|
});
|
|
document.getElementById('total-billed-amount').textContent = toMoney(total);
|
|
document.getElementById('summary-billed').textContent = toMoney(total);
|
|
document.getElementById('summary-items').textContent = items;
|
|
|
|
const copayText = (document.getElementById('insurance-copay')?.textContent||'$0').replace('$','');
|
|
const copay = parseFloat(copayText)||0;
|
|
const expected = Math.max(0, total - copay);
|
|
document.getElementById('summary-copay').textContent = toMoney(copay);
|
|
document.getElementById('summary-expected').textContent = toMoney(expected);
|
|
|
|
// Push to billed_amount field
|
|
const billedInput = document.getElementById('{{ form.billed_amount.id_for_label }}');
|
|
if (billedInput) billedInput.value = total.toFixed(2);
|
|
}
|
|
|
|
// Quick actions (optional endpoints)
|
|
function copyFromBill(){
|
|
const billId = document.getElementById('id_medical_bill').value;
|
|
if (!billId){ alert('Select a bill first.'); return; }
|
|
fetch(`{% url 'billing:bill_line_items_api' '00000000-0000-0000-0000-000000000000' %}`.replace('00000000-0000-0000-0000-000000000000', billId))
|
|
.then(r=>r.json())
|
|
.then(data=>{
|
|
document.getElementById('line-items-body').innerHTML='';
|
|
lineItemCounter=0;
|
|
(data.line_items||[]).forEach(item=>{
|
|
addLineItem();
|
|
const row = document.getElementById('line-items-body').lastElementChild;
|
|
row.querySelector(`[name="li_${lineItemCounter}_service_code"]`).value = item.service_code || '';
|
|
row.querySelector(`[name="li_${lineItemCounter}_description"]`).value = item.description || '';
|
|
row.querySelector(`[name="li_${lineItemCounter}_service_date"]`).value = item.service_date || '';
|
|
row.querySelector(`[name="li_${lineItemCounter}_quantity"]`).value = item.quantity || 1;
|
|
row.querySelector(`[name="li_${lineItemCounter}_amount"]`).value = item.unit_price || 0;
|
|
});
|
|
updateSummary();
|
|
})
|
|
.catch(err=>{ console.error(err); alert('Unable to copy line items from bill.'); });
|
|
}
|
|
|
|
function validateClaim(){
|
|
let ok = true;
|
|
document.querySelectorAll('[required]').forEach(el=>{
|
|
if (!String(el.value||'').trim()){ el.classList.add('is-invalid'); ok=false; }
|
|
else { el.classList.remove('is-invalid'); }
|
|
});
|
|
alert(ok ? 'Claim validation passed.' : 'Please complete all required fields.');
|
|
}
|
|
|
|
{#function previewClaim(){#}
|
|
{# const fd = new FormData(document.getElementById('claimForm'));#}
|
|
{# const w = window.open('', '_blank', 'width=900,height=700');#}
|
|
{# w.document.write('<h3>Claim Preview</h3><p>Loading…</p>');#}
|
|
{# fetch('{% url "billing:claim_preview" %}', {method:'POST', body:fd})#}
|
|
{# .then(r=>r.text())#}
|
|
{# .then(html=>{ w.document.open(); w.document.write(html); w.document.close(); })#}
|
|
{# .catch(()=>{ w.document.write('<p>Error generating preview.</p>'); });#}
|
|
{# }#}
|
|
|
|
function checkEligibility(){
|
|
const ins = document.getElementById('{{ form.insurance_info.id_for_label }}').value;
|
|
const from = document.getElementById('{{ form.service_date_from.id_for_label }}').value;
|
|
if (!ins || !from){ alert('Select insurance and service date(s) first.'); return; }
|
|
alert('Eligibility check initiated…');
|
|
setTimeout(()=>alert('Eligibility verified for the specified dates.'), 1200);
|
|
}
|
|
|
|
// Seed one row on create
|
|
{% if not object %}
|
|
document.addEventListener('DOMContentLoaded', ()=>{ addLineItem(); });
|
|
{% endif %}
|
|
|
|
// Final guard before submit
|
|
document.getElementById('claimForm').addEventListener('submit', function(e){
|
|
const rows = document.querySelectorAll('#line-items-body tr');
|
|
if (!rows.length){ e.preventDefault(); alert('Please add at least one line item.'); return false; }
|
|
const billed = parseFloat(document.getElementById('{{ form.billed_amount.id_for_label }}').value||0);
|
|
if (billed <= 0){ e.preventDefault(); alert('Billed amount must be greater than zero.'); return false; }
|
|
// Ensure summary → billed field is synced:
|
|
updateSummary();
|
|
});
|
|
</script>
|
|
{% endblock %} |