Add package checkbox for IPD pharmacy bill inclusion

This commit is contained in:
DevSoftTech Server 2026-08-07 15:23:57 +05:30
parent a10acec63f
commit 561c0d9fc3
3 changed files with 142 additions and 2 deletions

View File

@ -459,6 +459,7 @@ $routes->group('billing', function($routes) {
$routes->post('ipd/nursing-charge/delete/(:num)/(:num)', 'Billing\\Ipd::deleteNursingCharge/$1/$2');
$routes->post('ipd/charge/package/(:num)', 'Billing\\Ipd::updateIpdChargePackage/$1');
$routes->post('ipd/package/add/(:num)', 'Billing\\Ipd::addIpdPackage/$1');
$routes->post('ipd/medical-bill/credit-type/(:num)', 'Billing\\Ipd::updateMedicalBillCreditType/$1');
$routes->get('ipd/panel/(:num)/ayushman/search', 'Billing\Ipd::searchAyushmanPackages/$1');
$routes->post('ipd/panel/(:num)/ayushman/map/(:num)', 'Billing\Ipd::saveAyushmanPackageMapping/$1/$2');
$routes->post('ipd/panel/(:num)/ayushman/checklist', 'Billing\Ipd::saveAyushmanChecklist/$1');

View File

@ -517,6 +517,7 @@ class Ipd extends BaseController
if ($tab === 'package') {
$panelData['ipd_packages'] = $this->ipdModel->getIpdPackages($ipdId);
$panelData['medical_bills'] = $this->ipdModel->getMedicalBills($ipdId);
$caseMeta = $this->ipdModel->getIpdCaseMeta($ipdId);
$insCompId = (int) ($caseMeta['insurance_id'] ?? 0);
if ($insCompId <= 0) {
@ -1975,6 +1976,67 @@ class Ipd extends BaseController
return $this->response->setJSON(['ok' => $result === 1]);
}
public function updateMedicalBillCreditType(int $invoiceId)
{
$permission = $this->requireAnyPermission([
'billing.access',
'billing.ipd.invoice',
]);
if ($permission) {
return $permission;
}
if (! $this->request->isAJAX()) {
return $this->response->setStatusCode(400)->setJSON(['ok' => false, 'error' => 'Invalid request']);
}
if ($invoiceId <= 0 || ! $this->db->tableExists('invoice_med_master')) {
return $this->response->setStatusCode(404)->setJSON(['ok' => false, 'error' => 'Medical bill not found']);
}
$fields = $this->db->getFieldNames('invoice_med_master') ?? [];
if (! in_array('ipd_credit_type', $fields, true)) {
return $this->response->setStatusCode(422)->setJSON(['ok' => false, 'error' => 'Medical bill credit type column not available']);
}
$invoice = $this->db->table('invoice_med_master')
->select('id,ipd_id')
->where('id', $invoiceId)
->get(1)
->getRowArray();
if (empty($invoice)) {
return $this->response->setStatusCode(404)->setJSON(['ok' => false, 'error' => 'Medical bill not found']);
}
$creditType = (int) ($this->request->getPost('ipd_credit_type') ?? 0) === 1 ? 1 : 0;
$update = [
'ipd_credit_type' => $creditType,
];
if (in_array('ipd_credit', $fields, true)) {
$update['ipd_credit'] = 1;
}
if (in_array('ipd_credit_type_update', $fields, true)) {
$user = function_exists('auth') ? auth()->user() : null;
$userId = (int) ($user->id ?? 0);
$userName = (string) ($user->username ?? $user->email ?? 'user');
$update['ipd_credit_type_update'] = $userName . '[' . $userId . '] D:' . date('d-m-Y h:i:s');
}
$this->db->table('invoice_med_master')
->where('id', $invoiceId)
->update($update);
return $this->response->setJSON([
'ok' => true,
'invoice_id' => $invoiceId,
'ipd_id' => (int) ($invoice['ipd_id'] ?? 0),
'ipd_credit_type' => $creditType,
]);
}
public function loadPaymentModal(int $ipdId)
{
$permission = $this->requireAnyPermission([

View File

@ -129,7 +129,7 @@ $ayushmanChecklistItems = $ayushman_checklist_items ?? [];
</div>
<div class="col-md-3">
<label class="form-label">Rate</label>
<input class="form-control form-control-sm" id="input_amount_m" value="0.00" type="number" $11" />
<input class="form-control form-control-sm" id="input_amount_m" value="0.00" type="number" step="0.01" />
</div>
<div class="col-md-3 d-flex align-items-end">
<button type="button" class="btn btn-primary btn-sm" onclick="ipdPackageAddManual()">Add in List</button>
@ -161,7 +161,7 @@ $ayushmanChecklistItems = $ayushman_checklist_items ?? [];
</div>
<div class="col-md-3">
<label class="form-label">Amount</label>
<input class="form-control form-control-sm" id="input_amount_p" value="0.00" type="number" $11" />
<input class="form-control form-control-sm" id="input_amount_p" value="0.00" type="number" step="0.01" />
</div>
<div class="col-md-6">
<label class="form-label">Comment</label>
@ -321,6 +321,63 @@ $ayushmanChecklistItems = $ayushman_checklist_items ?? [];
</div>
</div>
<div class="card border-top border-3 border-info mt-3">
<div class="card-header d-flex justify-content-between align-items-center">
<strong>Pharmacy Bills Package Mapping</strong>
<span class="small text-muted">Unchecked = In Package, Checked = Include in Bill</span>
</div>
<div class="card-body">
<div class="table-responsive">
<table class="table table-striped table-sm align-middle mb-0">
<thead>
<tr>
<th>#</th>
<th>Invoice Code</th>
<th>Date</th>
<th class="text-end">Amount</th>
<th class="text-center">Include in Bill</th>
</tr>
</thead>
<tbody>
<?php if (! empty($medical_bills)) : ?>
<?php $medicalSrNo = 1; ?>
<?php foreach ($medical_bills as $medicalBill) : ?>
<?php $includeInBillChecked = (int) ($medicalBill->ipd_credit_type ?? 1) === 1 ? 'checked' : ''; ?>
<tr>
<td><?= $medicalSrNo++ ?></td>
<td>
<?= esc($medicalBill->inv_med_code ?? $medicalBill->id ?? '') ?>
<?php if ((int) ($medicalBill->payment_status ?? 0) > 0) : ?>
<span class="badge bg-success ms-1">Paid</span>
<?php else : ?>
<span class="badge bg-warning text-dark ms-1">Pending</span>
<?php endif; ?>
</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-center">
<div class="form-check d-inline-flex justify-content-center mb-0">
<input
class="form-check-input"
type="checkbox"
onchange="ipdMedicalBillToggleType(this, <?= (int) ($medicalBill->id ?? 0) ?>)"
<?= $includeInBillChecked ?>
/>
</div>
</td>
</tr>
<?php endforeach; ?>
<?php else : ?>
<tr>
<td colspan="5" class="text-center text-muted">No pharmacy bills found for this IPD.</td>
</tr>
<?php endif; ?>
</tbody>
</table>
</div>
</div>
</div>
<div class="modal fade" id="ayushmanMappingModal" tabindex="-1" aria-labelledby="ayushmanMappingModalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg modal-dialog-scrollable">
<div class="modal-content">
@ -365,6 +422,7 @@ $ayushmanChecklistItems = $ayushman_checklist_items ?? [];
var ipdAyushmanMapUrlBase = '<?= site_url('billing/ipd/panel/' . $ipdId . '/ayushman/map') ?>';
var ipdAyushmanChecklistUrl = '<?= site_url('billing/ipd/panel/' . $ipdId . '/ayushman/checklist') ?>';
var ipdAyushmanClaimSheetUrl = '<?= site_url('billing/ipd/panel/' . $ipdId . '/ayushman/claim-sheet') ?>';
var ipdMedicalBillCreditTypeUrlBase = '<?= site_url('billing/ipd/medical-bill/credit-type') ?>';
var ipdAyushmanResults = {};
// Initialize Select2 on package list select
@ -481,6 +539,25 @@ $ayushmanChecklistItems = $ayushman_checklist_items ?? [];
});
}
function ipdMedicalBillToggleType(checkbox, invoiceId) {
var payload = {};
payload[ipdPackageCsrfName] = ipdPackageCsrfHash;
payload.ipd_credit_type = checkbox.checked ? 1 : 0;
$.post(ipdMedicalBillCreditTypeUrlBase + '/' + invoiceId, payload, function(resp) {
if (!resp || !resp.ok) {
checkbox.checked = !checkbox.checked;
alert((resp && resp.error) ? resp.error : 'Unable to update pharmacy bill option.');
return;
}
ipdPackageReload();
}).fail(function(xhr) {
checkbox.checked = !checkbox.checked;
var msg = (xhr && xhr.responseJSON && xhr.responseJSON.error) ? xhr.responseJSON.error : 'Unable to update pharmacy bill option.';
alert(msg);
});
}
function ipdAyushmanRenderResults(items) {
var tbody = $('#ayushman_search_results');
tbody.empty();