fix(billing & pharmacy): fix IPD medical bill package classification, default empty qty, and doctor ajax selection
- IPD Billing: replace ambiguous 'In Package' switch with explicit 'Include in IPD Bill (Normal)' / 'In Package (Covered)' dropdown selector in Medical Bills and Package tabs - IPD Billing: return recalculated summary metrics from credit-type endpoint and update dashboard cards in real-time - Pharmacy: classify IPD bills using ipd_credit_type instead of group_invoice_id to correctly show Package: No for credit bills and add to Total Credit - Pharmacy Billing: default item quantity to blank instead of 0 to allow direct typing without backspacing, with validation against 0/empty submissions - Pharmacy Invoice: add outside doctor/consulting doctor selection and auto-save via AJAX
This commit is contained in:
parent
6cc34057b5
commit
51c06304d0
|
|
@ -2318,12 +2318,22 @@ class Ipd extends BaseController
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->recalculateIpdBillingSafely($ipdId, 'medical-bill.credit-type');
|
$this->recalculateIpdBillingSafely($ipdId, 'medical-bill.credit-type');
|
||||||
|
$updatedIpd = $this->db->table('ipd_master')->where('id', $ipdId)->get()->getRow();
|
||||||
|
|
||||||
return $this->response->setJSON([
|
return $this->response->setJSON([
|
||||||
'ok' => true,
|
'ok' => true,
|
||||||
'invoice_id' => $invoiceId,
|
'invoice_id' => $invoiceId,
|
||||||
'ipd_id' => $ipdId,
|
'ipd_id' => $ipdId,
|
||||||
'ipd_credit_type' => $creditType,
|
'ipd_credit_type' => $creditType,
|
||||||
|
'summary' => [
|
||||||
|
'charge_amount' => number_format((float) ($updatedIpd->charge_amount ?? 0), 2),
|
||||||
|
'med_amount' => number_format((float) ($updatedIpd->med_amount ?? 0), 2),
|
||||||
|
'net_amount' => number_format((float) ($updatedIpd->net_amount ?? 0), 2),
|
||||||
|
'total_paid_amount' => number_format((float) ($updatedIpd->total_paid_amount ?? 0), 2),
|
||||||
|
'balance_amount' => number_format((float) ($updatedIpd->balance_amount ?? 0), 2),
|
||||||
|
'cash_med_amount' => number_format((float) ($updatedIpd->cash_med_amount ?? 0), 2),
|
||||||
|
'med_paid' => number_format((float) ($updatedIpd->med_paid ?? 0), 2),
|
||||||
|
],
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1590,11 +1590,26 @@ class Medical extends BaseController
|
||||||
return $this->invoiceUpdateResponse(false, 'Not Done');
|
return $this->invoiceUpdateResponse(false, 'Not Done');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (! $this->db->tableExists('invoice_med_master')) {
|
||||||
|
return $this->invoiceUpdateResponse(false, 'Invoice table missing');
|
||||||
|
}
|
||||||
|
|
||||||
|
$invoice = $this->db->table('invoice_med_master')->where('id', $invoiceId)->get()->getRow();
|
||||||
|
if (! $invoice) {
|
||||||
|
return $this->invoiceUpdateResponse(false, 'Invoice not found');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->isInvoiceFinalized($invoice)) {
|
||||||
|
return $this->invoiceUpdateResponse(false, 'Invoice is finalized');
|
||||||
|
}
|
||||||
|
|
||||||
if ($docId > 0 && $this->db->tableExists('doctor_master')) {
|
if ($docId > 0 && $this->db->tableExists('doctor_master')) {
|
||||||
$doc = $this->db->table('doctor_master')->where('id', $docId)->get()->getRow();
|
$doc = $this->db->table('doctor_master')->where('id', $docId)->get()->getRow();
|
||||||
if ($doc) {
|
if ($doc) {
|
||||||
$docName = (string) ($doc->p_fname ?? $docName);
|
$docName = trim((string) ($doc->p_fname ?? $docName));
|
||||||
}
|
}
|
||||||
|
} elseif ($docId < 0) {
|
||||||
|
$docId = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
$ok = $this->updateInvoiceMasterByFields($invoiceId, [
|
$ok = $this->updateInvoiceMasterByFields($invoiceId, [
|
||||||
|
|
@ -2329,8 +2344,8 @@ class Medical extends BaseController
|
||||||
$legacyBalanceTotal += $balance;
|
$legacyBalanceTotal += $balance;
|
||||||
|
|
||||||
$ipdCredit = (int) ($row->ipd_credit ?? 0);
|
$ipdCredit = (int) ($row->ipd_credit ?? 0);
|
||||||
$groupInvoiceId = (int) ($row->group_invoice_id ?? 0);
|
$ipdCreditType = (int) ($row->ipd_credit_type ?? 1);
|
||||||
if ($ipdCredit > 0 && $groupInvoiceId > 0) {
|
if ($ipdCredit > 0 && $ipdCreditType === 0) {
|
||||||
$packageTotal += $net;
|
$packageTotal += $net;
|
||||||
} elseif ($ipdCredit > 0) {
|
} elseif ($ipdCredit > 0) {
|
||||||
$creditTotal += $net;
|
$creditTotal += $net;
|
||||||
|
|
@ -4075,6 +4090,33 @@ class Medical extends BaseController
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$docList = [];
|
||||||
|
if ($this->db->tableExists('doctor_master')) {
|
||||||
|
$docBuilder = $this->db->table('doctor_master');
|
||||||
|
$docFields = $this->db->getFieldNames('doctor_master') ?? [];
|
||||||
|
if (in_array('active', $docFields, true)) {
|
||||||
|
$docBuilder->where('active', 1);
|
||||||
|
}
|
||||||
|
$docList = $docBuilder->orderBy('p_fname', 'ASC')->get()->getResult();
|
||||||
|
|
||||||
|
$invDocId = (int) ($invoice->doc_id ?? 0);
|
||||||
|
if ($invDocId > 0) {
|
||||||
|
$found = false;
|
||||||
|
foreach ($docList as $d) {
|
||||||
|
if ((int) ($d->id ?? 0) === $invDocId) {
|
||||||
|
$found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (! $found) {
|
||||||
|
$docRow = $this->db->table('doctor_master')->where('id', $invDocId)->get()->getRow();
|
||||||
|
if ($docRow) {
|
||||||
|
$docList[] = $docRow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'invoice' => $invoice,
|
'invoice' => $invoice,
|
||||||
'items' => $items,
|
'items' => $items,
|
||||||
|
|
@ -4083,7 +4125,8 @@ class Medical extends BaseController
|
||||||
'totals' => $totals,
|
'totals' => $totals,
|
||||||
'oldInvoices' => $oldInvoices,
|
'oldInvoices' => $oldInvoices,
|
||||||
'isFinalized' => $this->isInvoiceFinalized($invoice),
|
'isFinalized' => $this->isInvoiceFinalized($invoice),
|
||||||
'message' => (string) $this->request->getGet('msg'),
|
'message' => (string) ($this->request ? $this->request->getGet('msg') : ''),
|
||||||
|
'docList' => $docList,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -10131,11 +10174,11 @@ class Medical extends BaseController
|
||||||
ELSE 0
|
ELSE 0
|
||||||
END) AS ipd_cash_amount,
|
END) AS ipd_cash_amount,
|
||||||
SUM(CASE
|
SUM(CASE
|
||||||
WHEN IFNULL(m.ipd_id,0)>0 AND IFNULL(m.ipd_credit,0)=1 AND IFNULL(m.group_invoice_id,0)=0 THEN " . $netExpr . "
|
WHEN IFNULL(m.ipd_id,0)>0 AND IFNULL(m.ipd_credit,0)=1 AND IFNULL(m.ipd_credit_type,1)=1 THEN " . $netExpr . "
|
||||||
ELSE 0
|
ELSE 0
|
||||||
END) AS ipd_credit_amount,
|
END) AS ipd_credit_amount,
|
||||||
SUM(CASE
|
SUM(CASE
|
||||||
WHEN IFNULL(m.ipd_id,0)>0 AND IFNULL(m.ipd_credit,0)=1 AND IFNULL(m.group_invoice_id,0)>0 THEN " . $netExpr . "
|
WHEN IFNULL(m.ipd_id,0)>0 AND IFNULL(m.ipd_credit,0)=1 AND IFNULL(m.ipd_credit_type,1)=0 THEN " . $netExpr . "
|
||||||
ELSE 0
|
ELSE 0
|
||||||
END) AS ipd_package_amount
|
END) AS ipd_package_amount
|
||||||
FROM invoice_med_master m
|
FROM invoice_med_master m
|
||||||
|
|
@ -10173,10 +10216,10 @@ class Medical extends BaseController
|
||||||
$billCondition = ' AND IFNULL(m.ipd_id,0)>0 AND IFNULL(m.ipd_credit,0)=0';
|
$billCondition = ' AND IFNULL(m.ipd_id,0)>0 AND IFNULL(m.ipd_credit,0)=0';
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
$billCondition = ' AND IFNULL(m.ipd_id,0)>0 AND IFNULL(m.ipd_credit,0)=1 AND IFNULL(m.group_invoice_id,0)=0';
|
$billCondition = ' AND IFNULL(m.ipd_id,0)>0 AND IFNULL(m.ipd_credit,0)=1 AND IFNULL(m.ipd_credit_type,1)=1';
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
$billCondition = ' AND IFNULL(m.ipd_id,0)>0 AND IFNULL(m.ipd_credit,0)=1 AND IFNULL(m.group_invoice_id,0)>0';
|
$billCondition = ' AND IFNULL(m.ipd_id,0)>0 AND IFNULL(m.ipd_credit,0)=1 AND IFNULL(m.ipd_credit_type,1)=0';
|
||||||
break;
|
break;
|
||||||
case 6:
|
case 6:
|
||||||
$billCondition = ' AND IFNULL(m.sale_return,0)=1';
|
$billCondition = ' AND IFNULL(m.sale_return,0)=1';
|
||||||
|
|
@ -10220,8 +10263,8 @@ class Medical extends BaseController
|
||||||
WHEN IFNULL(m.ipd_id,0)=0 AND IFNULL(m.case_id,0)=0 AND IFNULL(m.case_credit,0)=0 THEN 'OPD CASH'
|
WHEN IFNULL(m.ipd_id,0)=0 AND IFNULL(m.case_id,0)=0 AND IFNULL(m.case_credit,0)=0 THEN 'OPD CASH'
|
||||||
WHEN IFNULL(m.ipd_id,0)=0 AND IFNULL(m.case_id,0)>0 THEN 'OPD ORG'
|
WHEN IFNULL(m.ipd_id,0)=0 AND IFNULL(m.case_id,0)>0 THEN 'OPD ORG'
|
||||||
WHEN IFNULL(m.ipd_id,0)>0 AND IFNULL(m.ipd_credit,0)=0 THEN 'IPD CASH'
|
WHEN IFNULL(m.ipd_id,0)>0 AND IFNULL(m.ipd_credit,0)=0 THEN 'IPD CASH'
|
||||||
WHEN IFNULL(m.ipd_id,0)>0 AND IFNULL(m.ipd_credit,0)=1 AND IFNULL(m.group_invoice_id,0)=0 THEN 'IPD CREDIT'
|
WHEN IFNULL(m.ipd_id,0)>0 AND IFNULL(m.ipd_credit,0)=1 AND IFNULL(m.ipd_credit_type,1)=1 THEN 'IPD CREDIT'
|
||||||
WHEN IFNULL(m.ipd_id,0)>0 AND IFNULL(m.ipd_credit,0)=1 AND IFNULL(m.group_invoice_id,0)>0 THEN 'IPD PACKAGE'
|
WHEN IFNULL(m.ipd_id,0)>0 AND IFNULL(m.ipd_credit,0)=1 AND IFNULL(m.ipd_credit_type,1)=0 THEN 'IPD PACKAGE'
|
||||||
ELSE 'OTHER'
|
ELSE 'OTHER'
|
||||||
END AS bill_type,
|
END AS bill_type,
|
||||||
" . $orgNameExpr . " AS org_name
|
" . $orgNameExpr . " AS org_name
|
||||||
|
|
|
||||||
|
|
@ -26,18 +26,19 @@ $csrfHash = csrf_hash();
|
||||||
<td><?= esc($row->inv_date ?? '') ?></td>
|
<td><?= esc($row->inv_date ?? '') ?></td>
|
||||||
<td class="text-end"><?= number_format((float) ($row->net_amount ?? 0), 2) ?></td>
|
<td class="text-end"><?= number_format((float) ($row->net_amount ?? 0), 2) ?></td>
|
||||||
<td>
|
<td>
|
||||||
<?php $includeInBill = (int) ($row->ipd_credit_type ?? 0) === 1; ?>
|
<?php $includeInBill = (int) ($row->ipd_credit_type ?? 1) === 1; ?>
|
||||||
<div class="form-check form-switch mb-0">
|
<div class="d-flex align-items-center gap-2">
|
||||||
<input
|
<select
|
||||||
class="form-check-input"
|
class="form-select form-select-sm"
|
||||||
type="checkbox"
|
|
||||||
role="switch"
|
|
||||||
id="medical-bill-type-<?= (int) $row->id ?>"
|
id="medical-bill-type-<?= (int) $row->id ?>"
|
||||||
<?= $includeInBill ? 'checked' : '' ?>
|
style="width: auto; min-width: 210px; font-weight: 600;"
|
||||||
onchange="ipdMedicalBillsToggleType(this, <?= (int) $row->id ?>)">
|
onchange="ipdMedicalBillsChangeType(this, <?= (int) $row->id ?>)">
|
||||||
<label class="form-check-label" for="medical-bill-type-<?= (int) $row->id ?>">
|
<option value="1" <?= $includeInBill ? 'selected' : '' ?>>✓ Include in IPD Bill (Normal)</option>
|
||||||
|
<option value="0" <?= ! $includeInBill ? 'selected' : '' ?>>📦 In Package (Covered)</option>
|
||||||
|
</select>
|
||||||
|
<span id="badge-bill-type-<?= (int) $row->id ?>" class="badge <?= $includeInBill ? 'bg-success-subtle text-success border border-success' : 'bg-warning-subtle text-warning border border-warning' ?>">
|
||||||
<?= $includeInBill ? 'Include in Bill' : 'In Package' ?>
|
<?= $includeInBill ? 'Include in Bill' : 'In Package' ?>
|
||||||
</label>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
|
|
@ -65,33 +66,104 @@ $csrfHash = csrf_hash();
|
||||||
var ipdMedicalBillsUpdateUrl = '<?= site_url('billing/ipd/medical-bill/credit-type') ?>';
|
var ipdMedicalBillsUpdateUrl = '<?= site_url('billing/ipd/medical-bill/credit-type') ?>';
|
||||||
var ipdMedicalBillsDetailsUrl = '<?= site_url('billing/ipd/medical-bill') ?>';
|
var ipdMedicalBillsDetailsUrl = '<?= site_url('billing/ipd/medical-bill') ?>';
|
||||||
|
|
||||||
function ipdMedicalBillsToggleType(checkbox, invoiceId) {
|
function ipdMedicalBillsChangeType(select, invoiceId) {
|
||||||
var label = document.querySelector('label[for="' + checkbox.id + '"]');
|
var val = parseInt(select.value, 10);
|
||||||
|
var badge = document.getElementById('badge-bill-type-' + invoiceId);
|
||||||
var payload = {
|
var payload = {
|
||||||
ipd_id: ipdMedicalBillsIpdId,
|
ipd_id: ipdMedicalBillsIpdId,
|
||||||
ipd_credit_type: checkbox.checked ? 1 : 0
|
ipd_credit_type: val
|
||||||
};
|
};
|
||||||
payload[ipdMedicalBillsCsrfName] = ipdMedicalBillsCsrfHash;
|
payload[ipdMedicalBillsCsrfName] = ipdMedicalBillsCsrfHash;
|
||||||
checkbox.disabled = true;
|
select.disabled = true;
|
||||||
|
|
||||||
|
if (badge) {
|
||||||
|
badge.className = 'badge bg-secondary-subtle text-secondary border border-secondary';
|
||||||
|
badge.textContent = 'Updating...';
|
||||||
|
}
|
||||||
|
|
||||||
$.post(ipdMedicalBillsUpdateUrl + '/' + invoiceId, payload, function(resp) {
|
$.post(ipdMedicalBillsUpdateUrl + '/' + invoiceId, payload, function(resp) {
|
||||||
if (!resp || !resp.ok) {
|
if (!resp || !resp.ok) {
|
||||||
checkbox.checked = !checkbox.checked;
|
select.value = val === 1 ? '0' : '1';
|
||||||
alert((resp && resp.error) ? resp.error : 'Unable to update medical bill type.');
|
alert((resp && resp.error) ? resp.error : 'Unable to update medical bill type.');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
label.textContent = checkbox.checked ? 'Include in Bill' : 'In Package';
|
|
||||||
|
var isIncluded = val === 1;
|
||||||
|
if (badge) {
|
||||||
|
badge.className = isIncluded
|
||||||
|
? 'badge bg-success-subtle text-success border border-success'
|
||||||
|
: 'badge bg-warning-subtle text-warning border border-warning';
|
||||||
|
badge.textContent = isIncluded ? 'Include in Bill' : 'In Package';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Real-time update top dashboard summary numbers
|
||||||
|
if (resp.summary) {
|
||||||
|
ipdMedicalBillsUpdateDashboardCards(resp.summary);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Invalidate Bill Details tab so it loads fresh calculated data when clicked
|
||||||
|
var billPanel = document.getElementById('tab_bill_content');
|
||||||
|
if (billPanel) {
|
||||||
|
billPanel.innerHTML = 'Loading...';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof window.notify === 'function') {
|
||||||
|
window.notify('success', 'Medical Bill', isIncluded ? 'Bill marked as Include in IPD Bill' : 'Bill marked as In Package');
|
||||||
|
}
|
||||||
}).fail(function(xhr) {
|
}).fail(function(xhr) {
|
||||||
checkbox.checked = !checkbox.checked;
|
select.value = val === 1 ? '0' : '1';
|
||||||
var message = xhr.responseJSON && xhr.responseJSON.error
|
var message = xhr.responseJSON && xhr.responseJSON.error
|
||||||
? xhr.responseJSON.error
|
? xhr.responseJSON.error
|
||||||
: 'Unable to update medical bill type.';
|
: 'Unable to update medical bill type.';
|
||||||
alert(message);
|
alert(message);
|
||||||
}).always(function() {
|
}).always(function() {
|
||||||
checkbox.disabled = false;
|
select.disabled = false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function ipdMedicalBillsUpdateDashboardCards(s) {
|
||||||
|
var orangeCard = document.querySelector('.ipd-summary-card.orange');
|
||||||
|
if (orangeCard) {
|
||||||
|
var spans = orangeCard.querySelectorAll('span');
|
||||||
|
spans.forEach(function(sp) {
|
||||||
|
var txt = sp.textContent || '';
|
||||||
|
if (txt.indexOf('Charges') >= 0 && s.charge_amount !== undefined) {
|
||||||
|
sp.textContent = 'Charges : ' + s.charge_amount;
|
||||||
|
} else if (txt.indexOf('Pharmacy Cr. IPD') >= 0 && s.med_amount !== undefined) {
|
||||||
|
sp.textContent = 'Pharmacy Cr. IPD : ' + s.med_amount;
|
||||||
|
} else if (txt.indexOf('Net Amount') >= 0 && s.net_amount !== undefined) {
|
||||||
|
sp.textContent = 'Net Amount : ' + s.net_amount;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
var greenCard = document.querySelector('.ipd-summary-card.green');
|
||||||
|
if (greenCard) {
|
||||||
|
var gSpans = greenCard.querySelectorAll('span');
|
||||||
|
gSpans.forEach(function(sp) {
|
||||||
|
var txt = sp.textContent || '';
|
||||||
|
if (txt.indexOf('Total Paid') >= 0 && s.total_paid_amount !== undefined) {
|
||||||
|
sp.textContent = 'Total Paid : ' + s.total_paid_amount;
|
||||||
|
} else if (txt.indexOf('Balance') >= 0 && s.balance_amount !== undefined) {
|
||||||
|
sp.textContent = 'Balance : ' + s.balance_amount;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
var blueCard = document.querySelector('.ipd-summary-card.blue');
|
||||||
|
if (blueCard) {
|
||||||
|
var bSpans = blueCard.querySelectorAll('span');
|
||||||
|
bSpans.forEach(function(sp) {
|
||||||
|
var txt = sp.textContent || '';
|
||||||
|
if (txt.indexOf('Pharmacy Bill') >= 0 && s.cash_med_amount !== undefined) {
|
||||||
|
sp.textContent = 'Pharmacy Bill : ' + s.cash_med_amount;
|
||||||
|
} else if (txt.indexOf('Paid Amount') >= 0 && s.med_paid !== undefined) {
|
||||||
|
sp.textContent = 'Paid Amount : ' + s.med_paid;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function ipdMedicalBillsShowInvoice(button, invoiceId) {
|
function ipdMedicalBillsShowInvoice(button, invoiceId) {
|
||||||
var details = $('#ipd-medical-bill-details');
|
var details = $('#ipd-medical-bill-details');
|
||||||
button.disabled = true;
|
button.disabled = true;
|
||||||
|
|
|
||||||
|
|
@ -324,7 +324,7 @@ $ayushmanChecklistItems = $ayushman_checklist_items ?? [];
|
||||||
<div class="card border-top border-3 border-info mt-3">
|
<div class="card border-top border-3 border-info mt-3">
|
||||||
<div class="card-header d-flex justify-content-between align-items-center">
|
<div class="card-header d-flex justify-content-between align-items-center">
|
||||||
<strong>Pharmacy Bills Package Mapping</strong>
|
<strong>Pharmacy Bills Package Mapping</strong>
|
||||||
<span class="small text-muted">Unchecked = In Package, Checked = Include in Bill</span>
|
<span class="small text-muted">Select whether pharmacy bill is covered In Package or billed to IPD</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<div class="table-responsive">
|
<div class="table-responsive">
|
||||||
|
|
@ -335,14 +335,14 @@ $ayushmanChecklistItems = $ayushman_checklist_items ?? [];
|
||||||
<th>Invoice Code</th>
|
<th>Invoice Code</th>
|
||||||
<th>Date</th>
|
<th>Date</th>
|
||||||
<th class="text-end">Amount</th>
|
<th class="text-end">Amount</th>
|
||||||
<th class="text-center">Include in Bill</th>
|
<th class="text-center">Bill Type</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<?php if (! empty($medical_bills)) : ?>
|
<?php if (! empty($medical_bills)) : ?>
|
||||||
<?php $medicalSrNo = 1; ?>
|
<?php $medicalSrNo = 1; ?>
|
||||||
<?php foreach ($medical_bills as $medicalBill) : ?>
|
<?php foreach ($medical_bills as $medicalBill) : ?>
|
||||||
<?php $includeInBillChecked = (int) ($medicalBill->ipd_credit_type ?? 1) === 1 ? 'checked' : ''; ?>
|
<?php $includeInBill = (int) ($medicalBill->ipd_credit_type ?? 1) === 1; ?>
|
||||||
<tr>
|
<tr>
|
||||||
<td><?= $medicalSrNo++ ?></td>
|
<td><?= $medicalSrNo++ ?></td>
|
||||||
<td>
|
<td>
|
||||||
|
|
@ -356,14 +356,10 @@ $ayushmanChecklistItems = $ayushman_checklist_items ?? [];
|
||||||
<td><?= esc((string) ($medicalBill->inv_date ?? '')) ?></td>
|
<td><?= esc((string) ($medicalBill->inv_date ?? '')) ?></td>
|
||||||
<td class="text-end"><?= esc(number_format((float) ($medicalBill->net_amount ?? 0), 2)) ?></td>
|
<td class="text-end"><?= esc(number_format((float) ($medicalBill->net_amount ?? 0), 2)) ?></td>
|
||||||
<td class="text-center">
|
<td class="text-center">
|
||||||
<div class="form-check d-inline-flex justify-content-center mb-0">
|
<select class="form-select form-select-sm d-inline-block" style="width: auto; min-width: 210px; font-weight: 600;" onchange="ipdPackageMedicalBillChangeType(this, <?= (int) ($medicalBill->id ?? 0) ?>)">
|
||||||
<input
|
<option value="1" <?= $includeInBill ? 'selected' : '' ?>>✓ Include in IPD Bill (Normal)</option>
|
||||||
class="form-check-input"
|
<option value="0" <?= ! $includeInBill ? 'selected' : '' ?>>📦 In Package (Covered)</option>
|
||||||
type="checkbox"
|
</select>
|
||||||
onchange="ipdMedicalBillToggleType(this, <?= (int) ($medicalBill->id ?? 0) ?>)"
|
|
||||||
<?= $includeInBillChecked ?>
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<?php endforeach; ?>
|
<?php endforeach; ?>
|
||||||
|
|
@ -539,23 +535,31 @@ $ayushmanChecklistItems = $ayushman_checklist_items ?? [];
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function ipdMedicalBillToggleType(checkbox, invoiceId) {
|
function ipdPackageMedicalBillChangeType(select, invoiceId) {
|
||||||
|
var val = parseInt(select.value, 10);
|
||||||
var payload = {};
|
var payload = {};
|
||||||
payload[ipdPackageCsrfName] = ipdPackageCsrfHash;
|
payload[ipdPackageCsrfName] = ipdPackageCsrfHash;
|
||||||
payload.ipd_id = ipdPackageIpdId;
|
payload.ipd_id = ipdPackageIpdId;
|
||||||
payload.ipd_credit_type = checkbox.checked ? 1 : 0;
|
payload.ipd_credit_type = val;
|
||||||
|
select.disabled = true;
|
||||||
|
|
||||||
$.post(ipdMedicalBillCreditTypeUrlBase + '/' + invoiceId, payload, function(resp) {
|
$.post(ipdMedicalBillCreditTypeUrlBase + '/' + invoiceId, payload, function(resp) {
|
||||||
if (!resp || !resp.ok) {
|
if (!resp || !resp.ok) {
|
||||||
checkbox.checked = !checkbox.checked;
|
select.value = val === 1 ? '0' : '1';
|
||||||
alert((resp && resp.error) ? resp.error : 'Unable to update pharmacy bill option.');
|
alert((resp && resp.error) ? resp.error : 'Unable to update pharmacy bill option.');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// Update dashboard summary cards if function exists
|
||||||
|
if (resp.summary && typeof ipdMedicalBillsUpdateDashboardCards === 'function') {
|
||||||
|
ipdMedicalBillsUpdateDashboardCards(resp.summary);
|
||||||
|
}
|
||||||
ipdPackageReload();
|
ipdPackageReload();
|
||||||
}).fail(function(xhr) {
|
}).fail(function(xhr) {
|
||||||
checkbox.checked = !checkbox.checked;
|
select.value = val === 1 ? '0' : '1';
|
||||||
var msg = (xhr && xhr.responseJSON && xhr.responseJSON.error) ? xhr.responseJSON.error : 'Unable to update pharmacy bill option.';
|
var msg = (xhr && xhr.responseJSON && xhr.responseJSON.error) ? xhr.responseJSON.error : 'Unable to update pharmacy bill option.';
|
||||||
alert(msg);
|
alert(msg);
|
||||||
|
}).always(function() {
|
||||||
|
select.disabled = false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -36,18 +36,66 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<?php if (empty($isFinalized)): ?>
|
<?php if (empty($isFinalized)): ?>
|
||||||
<form method="post" action="<?= base_url('Medical/go_final') ?>" class="row g-2 mb-3">
|
<?php
|
||||||
<?= csrf_field() ?>
|
$currentDocId = (int) ($invoice->doc_id ?? 0);
|
||||||
<input type="hidden" name="inv_id" value="<?= (int)($invoice->id ?? 0) ?>">
|
$currentDocName = trim((string) ($invoice->doc_name ?? ''));
|
||||||
<div class="col-md-2">
|
|
||||||
<label class="form-label form-label-sm mb-1">Doctor ID</label>
|
$docFound = false;
|
||||||
<input type="number" name="doc_id" value="<?= esc($invoice->doc_id ?? 0) ?>" class="form-control form-control-sm" min="0" step="1">
|
if (!empty($docList) && $currentDocId > 0) {
|
||||||
|
foreach ($docList as $d) {
|
||||||
|
if ((int) ($d->id ?? 0) === $currentDocId) {
|
||||||
|
$docFound = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// If not found in hospital doctors list but doctor name exists, treat as outside doctor
|
||||||
|
$isOtherDoc = (!$docFound && ($currentDocId === 0 || $currentDocId === 999999) && $currentDocName !== '');
|
||||||
|
?>
|
||||||
|
<div class="row g-2 mb-3 align-items-end" id="invoice-doctor-panel">
|
||||||
|
<input type="hidden" name="doc_id" id="hidden_doc_id" value="<?= $currentDocId ?>">
|
||||||
|
<input type="hidden" name="doc_name" id="hidden_doc_name" value="<?= esc($currentDocName) ?>">
|
||||||
|
|
||||||
|
<div class="col-md-4 col-sm-6">
|
||||||
|
<label class="form-label form-label-sm mb-1 fw-bold text-secondary">
|
||||||
|
<i class="bi bi-person-badge"></i> Doctor
|
||||||
|
</label>
|
||||||
|
<select id="invoice_doc_select" class="form-select form-select-sm">
|
||||||
|
<option value="">-- Select Doctor --</option>
|
||||||
|
<?php foreach (($docList ?? []) as $doc): ?>
|
||||||
|
<?php
|
||||||
|
$dId = (int) ($doc->id ?? 0);
|
||||||
|
$dName = trim((string) ($doc->p_fname ?? ('Doctor #' . $dId)));
|
||||||
|
$isSelected = (!$isOtherDoc && $currentDocId === $dId);
|
||||||
|
?>
|
||||||
|
<option value="<?= $dId ?>" data-name="<?= esc($dName) ?>" <?= $isSelected ? 'selected' : '' ?>>
|
||||||
|
<?= esc($dName) ?>
|
||||||
|
</option>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
<option value="other" <?= $isOtherDoc ? 'selected' : '' ?>>Outside Doctor / Other</option>
|
||||||
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-3">
|
|
||||||
<label class="form-label form-label-sm mb-1">Doctor Name</label>
|
<div class="col-md-4 col-sm-6" id="wrap_doc_other" style="<?= $isOtherDoc ? '' : 'display: none;' ?>">
|
||||||
<input type="text" name="doc_name" value="<?= esc($invoice->doc_name ?? '') ?>" class="form-control form-control-sm">
|
<label class="form-label form-label-sm mb-1 fw-bold text-secondary">
|
||||||
|
<i class="bi bi-pencil-square"></i> Outside Doctor Name
|
||||||
|
</label>
|
||||||
|
<div class="input-group input-group-sm">
|
||||||
|
<input type="text" id="input_doc_other" class="form-control form-control-sm" placeholder="Enter Doctor Name" value="<?= $isOtherDoc ? esc($currentDocName) : '' ?>">
|
||||||
|
<button type="button" id="btn_save_doc_other" class="btn btn-outline-primary btn-sm" title="Save Doctor">Save</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
|
||||||
|
<div class="col-auto">
|
||||||
|
<span id="doc_save_indicator" class="badge bg-success-subtle text-success border border-success-subtle py-1 px-2 d-none">
|
||||||
|
<i class="bi bi-check-circle-fill"></i> Saved
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<?php else: ?>
|
||||||
|
<div class="small mb-2 text-muted">
|
||||||
|
<strong>Doctor :</strong> <span class="badge bg-light text-dark border"><?= esc($invoice->doc_name ?: 'Not Specified') ?></span>
|
||||||
|
</div>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
|
||||||
<div id="show_item_list" class="table-responsive mb-3">
|
<div id="show_item_list" class="table-responsive mb-3">
|
||||||
|
|
@ -210,11 +258,11 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-4">
|
<div class="col-md-4">
|
||||||
<label class="form-label form-label-sm mb-1">Qty</label>
|
<label class="form-label form-label-sm mb-1">Qty</label>
|
||||||
<input class="form-control form-control-sm" name="qty" id="input_product_qty" placeholder="Qty Like No. of Tab." type="number" min="0" step="1" value="0" autocomplete="off">
|
<input class="form-control form-control-sm" name="qty" id="input_product_qty" placeholder="Qty" type="number" min="1" step="1" value="" autocomplete="off" required>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-3">
|
<div class="col-md-3">
|
||||||
<label class="form-label form-label-sm mb-1">Disc %</label>
|
<label class="form-label form-label-sm mb-1">Disc %</label>
|
||||||
<input class="form-control form-control-sm" name="disc_per" id="input_disc" placeholder="Discount %" type="number" min="0" max="100" $11" value="0" autocomplete="off">
|
<input class="form-control form-control-sm" name="disc_per" id="input_disc" placeholder="Discount %" type="number" min="0" max="100" value="0" autocomplete="off">
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-2">
|
<div class="col-md-2">
|
||||||
<button class="btn btn-sm btn-primary w-100" type="submit" id="additem" disabled>Add</button>
|
<button class="btn btn-sm btn-primary w-100" type="submit" id="additem" disabled>Add</button>
|
||||||
|
|
@ -250,7 +298,7 @@
|
||||||
<input type="hidden" name="inv_id" value="<?= (int)($invoice->id ?? 0) ?>">
|
<input type="hidden" name="inv_id" value="<?= (int)($invoice->id ?? 0) ?>">
|
||||||
<input type="hidden" name="stock_id" value="<?= (int)($row->stock_id ?? 0) ?>">
|
<input type="hidden" name="stock_id" value="<?= (int)($row->stock_id ?? 0) ?>">
|
||||||
<input type="number" name="qty" value="1" min="1" step="1" class="form-control form-control-sm" style="width:80px;">
|
<input type="number" name="qty" value="1" min="1" step="1" class="form-control form-control-sm" style="width:80px;">
|
||||||
<input type="number" name="disc_per" value="0" min="0" max="100" $11" class="form-control form-control-sm" style="width:90px;" title="Disc %">
|
<input type="number" name="disc_per" value="0" min="0" max="100" class="form-control form-control-sm" style="width:90px;" title="Disc %">
|
||||||
<button class="btn btn-sm btn-primary" type="submit">Add</button>
|
<button class="btn btn-sm btn-primary" type="submit">Add</button>
|
||||||
</form>
|
</form>
|
||||||
</td>
|
</td>
|
||||||
|
|
@ -545,6 +593,7 @@
|
||||||
addBtn.disabled = !item.l_ss_no;
|
addBtn.disabled = !item.l_ss_no;
|
||||||
}
|
}
|
||||||
if (qtyInput) {
|
if (qtyInput) {
|
||||||
|
qtyInput.value = '';
|
||||||
qtyInput.focus();
|
qtyInput.focus();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -737,11 +786,13 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
var qtyInput = document.getElementById('input_product_qty');
|
var qtyInput = document.getElementById('input_product_qty');
|
||||||
var qtyValue = parseFloat((qtyInput && qtyInput.value) ? qtyInput.value : '0');
|
var rawQty = (qtyInput && qtyInput.value) ? qtyInput.value.trim() : '';
|
||||||
if (!qtyValue || qtyValue <= 0) {
|
var qtyValue = parseFloat(rawQty || '0');
|
||||||
|
if (!rawQty || isNaN(qtyValue) || qtyValue <= 0) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
alert('Enter valid Qty greater than 0.');
|
alert('Please enter valid Qty greater than 0.');
|
||||||
if (qtyInput) {
|
if (qtyInput) {
|
||||||
|
qtyInput.value = '';
|
||||||
qtyInput.focus();
|
qtyInput.focus();
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|
@ -774,5 +825,129 @@
|
||||||
if (addBtn) {
|
if (addBtn) {
|
||||||
addBtn.accessKey = 'i';
|
addBtn.accessKey = 'i';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Doctor Select & Outside Doctor AJAX save handler
|
||||||
|
(function () {
|
||||||
|
var docSelect = document.getElementById('invoice_doc_select');
|
||||||
|
var wrapOther = document.getElementById('wrap_doc_other');
|
||||||
|
var inputOther = document.getElementById('input_doc_other');
|
||||||
|
var btnSaveOther = document.getElementById('btn_save_doc_other');
|
||||||
|
var hiddenDocId = document.getElementById('hidden_doc_id');
|
||||||
|
var hiddenDocName = document.getElementById('hidden_doc_name');
|
||||||
|
var saveIndicator = document.getElementById('doc_save_indicator');
|
||||||
|
var invId = <?= (int) ($invoice->id ?? 0) ?>;
|
||||||
|
|
||||||
|
if (!docSelect || !invId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
function showSaveStatus(text, isError) {
|
||||||
|
if (!saveIndicator) return;
|
||||||
|
saveIndicator.classList.remove('d-none', 'bg-success-subtle', 'text-success', 'border-success-subtle', 'bg-danger-subtle', 'text-danger', 'border-danger-subtle');
|
||||||
|
if (isError) {
|
||||||
|
saveIndicator.classList.add('bg-danger-subtle', 'text-danger', 'border-danger-subtle');
|
||||||
|
saveIndicator.innerHTML = '<i class="bi bi-exclamation-circle-fill"></i> ' + (text || 'Error');
|
||||||
|
} else {
|
||||||
|
saveIndicator.classList.add('bg-success-subtle', 'text-success', 'border-success-subtle');
|
||||||
|
saveIndicator.innerHTML = '<i class="bi bi-check-circle-fill"></i> ' + (text || 'Saved');
|
||||||
|
}
|
||||||
|
setTimeout(function () {
|
||||||
|
if (saveIndicator) saveIndicator.classList.add('d-none');
|
||||||
|
}, 2500);
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateDoctorAjax(docId, docName, onSuccess) {
|
||||||
|
var csrfInput = document.querySelector('input[name="<?= csrf_token() ?>"]');
|
||||||
|
var csrfHash = csrfInput ? csrfInput.value : '';
|
||||||
|
|
||||||
|
var body = new URLSearchParams();
|
||||||
|
body.append('<?= csrf_token() ?>', csrfHash);
|
||||||
|
body.append('med_invoice_id', String(invId));
|
||||||
|
body.append('doc_id', String(docId));
|
||||||
|
body.append('doc_name', String(docName || ''));
|
||||||
|
|
||||||
|
fetch('<?= base_url('Medical/update_doctor') ?>', {
|
||||||
|
method: 'POST',
|
||||||
|
body: body,
|
||||||
|
headers: {
|
||||||
|
'X-Requested-With': 'XMLHttpRequest',
|
||||||
|
'Content-Type': 'application/x-www-form-urlencoded'
|
||||||
|
}
|
||||||
|
}).then(function (res) {
|
||||||
|
return res.json();
|
||||||
|
}).then(function (res) {
|
||||||
|
if (res && res.csrfHash) {
|
||||||
|
document.querySelectorAll('input[name="<?= csrf_token() ?>"]').forEach(function (inp) {
|
||||||
|
inp.value = res.csrfHash;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (res && res.status) {
|
||||||
|
if (hiddenDocId) hiddenDocId.value = docId;
|
||||||
|
if (hiddenDocName) hiddenDocName.value = docName;
|
||||||
|
showSaveStatus(docId === 0 ? 'Outside Doctor Saved' : 'Doctor Updated', false);
|
||||||
|
if (typeof onSuccess === 'function') onSuccess();
|
||||||
|
} else {
|
||||||
|
showSaveStatus((res && res.remark) ? res.remark : 'Save Failed', true);
|
||||||
|
}
|
||||||
|
}).catch(function () {
|
||||||
|
showSaveStatus('Network Error', true);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
docSelect.addEventListener('change', function () {
|
||||||
|
var val = docSelect.value;
|
||||||
|
if (val === 'other') {
|
||||||
|
if (wrapOther) {
|
||||||
|
wrapOther.style.display = '';
|
||||||
|
}
|
||||||
|
if (inputOther) {
|
||||||
|
inputOther.focus();
|
||||||
|
if (inputOther.value.trim() !== '') {
|
||||||
|
updateDoctorAjax(0, inputOther.value.trim());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (val === '') {
|
||||||
|
if (wrapOther) {
|
||||||
|
wrapOther.style.display = 'none';
|
||||||
|
}
|
||||||
|
updateDoctorAjax(0, '');
|
||||||
|
} else {
|
||||||
|
if (wrapOther) {
|
||||||
|
wrapOther.style.display = 'none';
|
||||||
|
}
|
||||||
|
var opt = docSelect.options[docSelect.selectedIndex];
|
||||||
|
var docName = opt ? (opt.getAttribute('data-name') || opt.text.trim()) : '';
|
||||||
|
updateDoctorAjax(parseInt(val, 10), docName);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function saveOtherDoctor() {
|
||||||
|
if (!inputOther) return;
|
||||||
|
var otherName = inputOther.value.trim();
|
||||||
|
if (!otherName) {
|
||||||
|
inputOther.focus();
|
||||||
|
showSaveStatus('Enter Doctor Name', true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
updateDoctorAjax(0, otherName);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (btnSaveOther) {
|
||||||
|
btnSaveOther.addEventListener('click', saveOtherDoctor);
|
||||||
|
}
|
||||||
|
if (inputOther) {
|
||||||
|
inputOther.addEventListener('keydown', function (e) {
|
||||||
|
if (e.key === 'Enter') {
|
||||||
|
e.preventDefault();
|
||||||
|
saveOtherDoctor();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
inputOther.addEventListener('blur', function () {
|
||||||
|
if (docSelect.value === 'other' && inputOther.value.trim() !== '') {
|
||||||
|
saveOtherDoctor();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})();
|
||||||
})();
|
})();
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -164,23 +164,51 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card mb-0">
|
<div class="card mb-0">
|
||||||
<div class="card-body d-flex flex-wrap gap-2">
|
<div class="card-body">
|
||||||
<div class="flex-grow-1">
|
<?php
|
||||||
<label class="form-label">Doctor</label>
|
$masterDocId = (int) ($invoice->doc_id ?? 0);
|
||||||
<select class="form-select" id="doc-select">
|
$masterDocName = trim((string) ($invoice->doc_name ?? ''));
|
||||||
<option value="">Select</option>
|
$masterDocFound = false;
|
||||||
<?php foreach (($docList ?? []) as $doc): ?>
|
if (!empty($docList) && $masterDocId > 0) {
|
||||||
<option value="<?= esc($doc->id ?? '') ?>" data-name="<?= esc($doc->p_fname ?? '') ?>" <?= ((int)($invoice->doc_id ?? 0) === (int)($doc->id ?? 0)) ? 'selected' : '' ?>>
|
foreach ($docList as $d) {
|
||||||
<?= esc($doc->p_fname ?? ('Doctor #' . ($doc->id ?? ''))) ?>
|
if ((int) ($d->id ?? 0) === $masterDocId) {
|
||||||
</option>
|
$masterDocFound = true;
|
||||||
<?php endforeach; ?>
|
break;
|
||||||
</select>
|
}
|
||||||
<input type="hidden" name="doc_id" id="doc_id" value="<?= (int)($invoice->doc_id ?? 0) ?>">
|
}
|
||||||
<input type="hidden" name="doc_name" id="doc_name" value="<?= esc($invoice->doc_name ?? '') ?>">
|
}
|
||||||
</div>
|
$masterIsOtherDoc = (!$masterDocFound && ($masterDocId === 0 || $masterDocId === 999999) && $masterDocName !== '');
|
||||||
<div class="d-flex align-items-end gap-2">
|
?>
|
||||||
<button type="submit" class="btn btn-success">Update Invoice Header</button>
|
<div class="row g-2 align-items-end">
|
||||||
<a class="btn btn-outline-secondary" href="javascript:load_form_div('<?= base_url('Medical/invoice_edit/' . (int)($invoice->id ?? 0)) ?>','medical-main');">Cancel</a>
|
<div class="col-md-4">
|
||||||
|
<label class="form-label">Doctor</label>
|
||||||
|
<select class="form-select" id="doc-select">
|
||||||
|
<option value="">-- Select Doctor --</option>
|
||||||
|
<?php foreach (($docList ?? []) as $doc): ?>
|
||||||
|
<?php
|
||||||
|
$dId = (int) ($doc->id ?? 0);
|
||||||
|
$dName = trim((string) ($doc->p_fname ?? ('Doctor #' . $dId)));
|
||||||
|
$isSelected = (!$masterIsOtherDoc && $masterDocId === $dId);
|
||||||
|
?>
|
||||||
|
<option value="<?= $dId ?>" data-name="<?= esc($dName) ?>" <?= $isSelected ? 'selected' : '' ?>>
|
||||||
|
<?= esc($dName) ?>
|
||||||
|
</option>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
<option value="other" <?= $masterIsOtherDoc ? 'selected' : '' ?>>Outside Doctor / Other</option>
|
||||||
|
</select>
|
||||||
|
<input type="hidden" name="doc_id" id="doc_id" value="<?= $masterDocId ?>">
|
||||||
|
<input type="hidden" name="doc_name" id="doc_name" value="<?= esc($masterDocName) ?>">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-4" id="wrap_master_doc_other" style="<?= $masterIsOtherDoc ? '' : 'display: none;' ?>">
|
||||||
|
<label class="form-label">Outside Doctor Name</label>
|
||||||
|
<input type="text" class="form-control" id="master_doc_other_input" placeholder="Enter Doctor Name" value="<?= $masterIsOtherDoc ? esc($masterDocName) : '' ?>">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-4 d-flex align-items-end gap-2">
|
||||||
|
<button type="submit" class="btn btn-success">Update Invoice Header</button>
|
||||||
|
<a class="btn btn-outline-secondary" href="javascript:load_form_div('<?= base_url('Medical/invoice_edit/' . (int)($invoice->id ?? 0)) ?>','medical-main');">Cancel</a>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -419,20 +447,37 @@
|
||||||
|
|
||||||
(function () {
|
(function () {
|
||||||
var select = document.getElementById('doc-select');
|
var select = document.getElementById('doc-select');
|
||||||
|
var wrapOther = document.getElementById('wrap_master_doc_other');
|
||||||
|
var otherInput = document.getElementById('master_doc_other_input');
|
||||||
|
var docIdInput = document.getElementById('doc_id');
|
||||||
|
var docNameInput = document.getElementById('doc_name');
|
||||||
if (!select) {
|
if (!select) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
select.addEventListener('change', function () {
|
function syncDoctor() {
|
||||||
var option = select.options[select.selectedIndex];
|
var val = select.value;
|
||||||
var docIdInput = document.getElementById('doc_id');
|
if (val === 'other') {
|
||||||
var docNameInput = document.getElementById('doc_name');
|
if (wrapOther) wrapOther.style.display = '';
|
||||||
if (docIdInput) {
|
if (docIdInput) docIdInput.value = 0;
|
||||||
docIdInput.value = option ? (option.value || 0) : 0;
|
if (docNameInput && otherInput) docNameInput.value = otherInput.value.trim();
|
||||||
|
if (otherInput) otherInput.focus();
|
||||||
|
} else {
|
||||||
|
if (wrapOther) wrapOther.style.display = 'none';
|
||||||
|
var option = select.options[select.selectedIndex];
|
||||||
|
if (docIdInput) docIdInput.value = option ? (option.value || 0) : 0;
|
||||||
|
if (docNameInput) docNameInput.value = option ? (option.getAttribute('data-name') || '') : '';
|
||||||
}
|
}
|
||||||
if (docNameInput) {
|
}
|
||||||
docNameInput.value = option ? (option.getAttribute('data-name') || '') : '';
|
|
||||||
}
|
select.addEventListener('change', syncDoctor);
|
||||||
});
|
if (otherInput) {
|
||||||
|
otherInput.addEventListener('input', function () {
|
||||||
|
if (select.value === 'other' && docNameInput) {
|
||||||
|
docNameInput.value = otherInput.value.trim();
|
||||||
|
if (docIdInput) docIdInput.value = 0;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
})();
|
})();
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -96,9 +96,9 @@
|
||||||
<?php
|
<?php
|
||||||
$invoiceId = (int) ($row->id ?? 0);
|
$invoiceId = (int) ($row->id ?? 0);
|
||||||
$ipdCredit = (int)($row->ipd_credit ?? 0);
|
$ipdCredit = (int)($row->ipd_credit ?? 0);
|
||||||
$groupInvoiceId = (int)($row->group_invoice_id ?? 0);
|
$ipdCreditType = (int)($row->ipd_credit_type ?? 1);
|
||||||
$creditText = ($ipdCredit > 0) ? 'Credit' : 'CASH';
|
$creditText = ($ipdCredit > 0) ? 'Credit' : 'CASH';
|
||||||
$packageText = ($ipdCredit > 0 && $groupInvoiceId > 0) ? 'Yes' : 'No';
|
$packageText = ($ipdCredit > 0 && $ipdCreditType === 0) ? 'Yes' : 'No';
|
||||||
$editMeta = $invoiceEditMeta[$invoiceId] ?? ['can_edit' => true, 'reason' => ''];
|
$editMeta = $invoiceEditMeta[$invoiceId] ?? ['can_edit' => true, 'reason' => ''];
|
||||||
$canEditRow = !empty($editMeta['can_edit']);
|
$canEditRow = !empty($editMeta['can_edit']);
|
||||||
$editReason = (string) ($editMeta['reason'] ?? 'Invoice is view-only.');
|
$editReason = (string) ($editMeta['reason'] ?? 'Invoice is view-only.');
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user