Add OPD patient list report with refer by

This commit is contained in:
DevSoftTech Server 2026-08-18 13:09:03 +05:30
parent 9bec2d2a66
commit 903478ce59
5 changed files with 240 additions and 0 deletions

View File

@ -1045,6 +1045,9 @@ $routes->get('Report/collection_report', 'Report::collection_report', ['filter'
$routes->get('Report/report_opd_total', 'Report::report_opd_total', ['filter' => $reportsCollectionFilter]);
$routes->get('Report/opd_total_data/(:segment)/(:segment)/(:segment)/(:segment)', 'Report::opd_total_data/$1/$2/$3/$4', ['filter' => $reportsCollectionFilter]);
$routes->get('Report/opd_total_data/(:segment)/(:segment)/(:segment)/(:segment)/(:num)', 'Report::opd_total_data/$1/$2/$3/$4/$5', ['filter' => $reportsCollectionFilter]);
$routes->get('Report/report_opd_patient_list', 'Report::report_opd_patient_list', ['filter' => $reportsCollectionFilter]);
$routes->get('Report/opd_patient_list_data/(:segment)/(:segment)/(:segment)', 'Report::opd_patient_list_data/$1/$2/$3', ['filter' => $reportsCollectionFilter]);
$routes->get('Report/opd_patient_list_data/(:segment)/(:segment)/(:segment)/(:num)', 'Report::opd_patient_list_data/$1/$2/$3/$4', ['filter' => $reportsCollectionFilter]);
$routes->get('Report/report_total_payment_app_show/(:segment)/(:segment)/(:segment)', 'Report::report_total_payment_app_show/$1/$2/$3', ['filter' => $reportsCollectionFilter]);
$routes->get('Report/report_total_payment_app_show/(:segment)/(:segment)/(:segment)/(:num)', 'Report::report_total_payment_app_show/$1/$2/$3/$4', ['filter' => $reportsCollectionFilter]);
$routes->get('Report/report_total_payment_app_show/(:segment)/(:segment)/(:segment)/(:segment)', 'Report::report_total_payment_app_show/$1/$2/$3/$4', ['filter' => $reportsCollectionFilter]);

View File

@ -58,6 +58,98 @@ class Report extends BaseController
]);
}
public function report_opd_patient_list()
{
$doctors = $this->db->table('doctor_master')
->select('id, p_fname')
->where('active', 1)
->orderBy('p_fname', 'ASC')
->get()
->getResult();
$referBys = $this->db->table('patient_master')
->select('referby')
->where('referby IS NOT NULL', null, false)
->where("TRIM(referby) != ''", null, false)
->where("TRIM(referby) != '0'", null, false)
->groupBy('referby')
->orderBy('referby', 'ASC')
->get()
->getResult();
return view('report/opd_patient_list_report', [
'doctors' => $doctors,
'refer_bys' => $referBys,
]);
}
public function opd_patient_list_data(
string $dateRange,
string $doctorId = '0',
string $referBy = '0',
int $output = 0
) {
[$minRange, $maxRange] = $this->parseDateRangeDateOnly($dateRange);
$builder = $this->db->table('opd_master o')
->select('o.opd_id, o.opd_code, o.P_name, p.p_code, o.apointment_date, o.doc_name, p.referby')
->select('o.opd_fee_desc, o.opd_fee_amount, o.payment_mode, o.running_opd')
->join('patient_master p', 'p.id = o.p_id', 'left')
->where("DATE(o.apointment_date) BETWEEN '{$minRange}' AND '{$maxRange}'", null, false)
->where('(o.payment_mode > 0 OR COALESCE(o.running_opd,0)=1)', null, false)
->orderBy('o.apointment_date', 'ASC')
->orderBy('o.opd_id', 'ASC');
$doctorIdValue = (int) $doctorId;
if ($doctorIdValue > 0) {
$builder->where('o.doc_id', $doctorIdValue);
}
$referByValue = trim((string) urldecode($referBy));
if ($referByValue !== '' && $referByValue !== '0' && strtolower($referByValue) !== 'all') {
$builder->where('p.referby', $referByValue);
}
$rows = $builder->get()->getResult();
$content = view('report/opd_patient_list_report_table', [
'rows' => $rows,
'min_range' => $minRange,
'max_range' => $maxRange,
]);
if ($output === 1) {
ExportExcel($content, 'OPD_Patient_List_' . date('YmdHis'));
return $this->response->setBody('');
}
if ($output === 2) {
$mpdfTempDir = WRITEPATH . 'cache' . DIRECTORY_SEPARATOR . 'mpdf';
if (! is_dir($mpdfTempDir)) {
mkdir($mpdfTempDir, 0755, true);
}
$mpdf = new Mpdf([
'tempDir' => $mpdfTempDir,
'format' => 'A4-L',
'margin_top' => 8,
'margin_bottom' => 8,
'margin_left' => 8,
'margin_right' => 8,
]);
$pdfHtml = '<style>body{font-family:Arial,sans-serif;color:#111;font-size:11px;}table{width:100%;border-collapse:collapse;}th,td{border:1px solid #9aa4ad;padding:5px 6px;}th{text-align:left;background:#f5f6f7;}</style>'
. '<h3 style="margin:0 0 10px 0;">OPD Patient List</h3>' . $content;
$mpdf->WriteHTML($pdfHtml);
$fileName = 'OPD_Patient_List_' . date('Ymd_His') . '.pdf';
return $this->response
->setHeader('Content-Type', 'application/pdf')
->setHeader('Content-Disposition', 'inline; filename="' . $fileName . '"')
->setBody($mpdf->Output($fileName, 'S'));
}
return $this->response->setBody($content);
}
public function opd_total_data(
string $dateRange,
string $doctorId = '0',

View File

@ -0,0 +1,96 @@
<?php
$doctors = $doctors ?? [];
$referBys = $refer_bys ?? [];
?>
<section class="content">
<div class="card">
<div class="card-header d-flex justify-content-between align-items-center">
<h5 class="mb-0">OPD Patient List</h5>
<button type="button" class="btn btn-sm btn-outline-secondary" id="back_to_opd_total_report">Back to OPD Total</button>
</div>
<div class="card-body">
<div class="row g-3 align-items-end">
<div class="col-md-5">
<label class="form-label">OPD Date Range</label>
<div class="d-flex gap-2">
<input type="date" class="form-control" id="opd_patient_start">
<input type="date" class="form-control" id="opd_patient_end">
</div>
</div>
<div class="col-md-3">
<label class="form-label">Doctor Name</label>
<select class="form-control select2" id="opd_patient_doctor">
<option value="0">All Doctors</option>
<?php foreach ($doctors as $row) : ?>
<option value="<?= esc((string) ($row->id ?? '')) ?>"><?= esc((string) ($row->p_fname ?? '')) ?></option>
<?php endforeach; ?>
</select>
</div>
<div class="col-md-4">
<label class="form-label">Refer By</label>
<select class="form-control select2" id="opd_patient_refer_by">
<option value="0">All Referrers</option>
<?php foreach ($referBys as $row) : ?>
<?php $referBy = trim((string) ($row->referby ?? '')); ?>
<option value="<?= esc($referBy) ?>"><?= esc($referBy) ?></option>
<?php endforeach; ?>
</select>
</div>
</div>
<div class="mt-3 d-flex flex-wrap gap-2">
<button type="button" class="btn btn-primary" id="show_opd_patient_list">Show</button>
<button type="button" class="btn btn-outline-primary" id="export_opd_patient_list">Export</button>
<button type="button" class="btn btn-outline-danger" id="pdf_opd_patient_list">PDF</button>
</div>
</div>
</div>
<div class="card mt-3">
<div class="card-body">
<div id="opd_patient_list_result" class="table-responsive">Select filters and click Show.</div>
</div>
</div>
</section>
<script>
(function () {
function toDateValue(date) {
var y = date.getFullYear();
var m = String(date.getMonth() + 1).padStart(2, '0');
var d = String(date.getDate()).padStart(2, '0');
return y + '-' + m + '-' + d;
}
var currentDate = toDateValue(new Date());
document.getElementById('opd_patient_start').value = currentDate;
document.getElementById('opd_patient_end').value = currentDate;
function buildQuery(output) {
var start = document.getElementById('opd_patient_start').value || currentDate;
var end = document.getElementById('opd_patient_end').value || currentDate;
var doctor = document.getElementById('opd_patient_doctor').value || '0';
var referBy = document.getElementById('opd_patient_refer_by').value || '0';
var url = '<?= base_url('Report/opd_patient_list_data') ?>/'
+ encodeURIComponent(start + 'S' + end) + '/'
+ encodeURIComponent(doctor) + '/'
+ encodeURIComponent(referBy);
return output ? url + '/' + output : url;
}
document.getElementById('show_opd_patient_list').addEventListener('click', function () {
load_form_div(buildQuery(), 'opd_patient_list_result');
});
document.getElementById('export_opd_patient_list').addEventListener('click', function () {
window.open(buildQuery(1), '_blank');
});
document.getElementById('pdf_opd_patient_list').addEventListener('click', function () {
window.open(buildQuery(2), '_blank');
});
document.getElementById('back_to_opd_total_report').addEventListener('click', function () {
load_form('<?= base_url('Report/report_opd_total') ?>', 'OPD Total Report');
});
$('.select2').select2({ theme: 'bootstrap4', width: '100%' });
})();
</script>

View File

@ -0,0 +1,44 @@
<?php
$rows = $rows ?? [];
$minRange = $min_range ?? '';
$maxRange = $max_range ?? '';
$formatDate = static function ($value): string {
$timestamp = strtotime((string) $value);
return $timestamp === false ? (string) $value : date('d-m-Y H:i', $timestamp);
};
?>
<p class="mb-2"><strong>OPD Date Range:</strong> <?= esc(date('d-m-Y', strtotime($minRange))) ?> to <?= esc(date('d-m-Y', strtotime($maxRange))) ?></p>
<?php if (empty($rows)) : ?>
<div class="text-muted">No OPD patient records found for the selected filters.</div>
<?php else : ?>
<table class="table table-bordered table-sm align-middle">
<thead class="table-warning">
<tr>
<th>#</th>
<th>OPD Code</th>
<th>Patient Name</th>
<th>Patient Code</th>
<th>OPD Date</th>
<th>Doctor</th>
<th>Refer By</th>
<th>Fee Type</th>
<th class="text-end">Fee</th>
</tr>
</thead>
<tbody>
<?php foreach ($rows as $index => $row) : ?>
<tr>
<td><?= esc((string) ($index + 1)) ?></td>
<td><?= esc((string) ($row->opd_code ?? '')) ?></td>
<td><?= esc((string) ($row->P_name ?? '')) ?></td>
<td><?= esc((string) ($row->p_code ?? '')) ?></td>
<td><?= esc($formatDate($row->apointment_date ?? '')) ?></td>
<td><?= esc((string) ($row->doc_name ?? '')) ?></td>
<td><?= esc((string) ($row->referby ?? '')) ?></td>
<td><?= esc((string) ($row->opd_fee_desc ?? '')) ?></td>
<td class="text-end"><?= esc(number_format((float) ($row->opd_fee_amount ?? 0), 2)) ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php endif; ?>

View File

@ -52,6 +52,7 @@ $feeTypes = $fee_types ?? [];
<button type="button" class="btn btn-primary" id="show_opd_total_report">Show</button>
<button type="button" class="btn btn-outline-primary" id="export_opd_total_report">Export</button>
<button type="button" class="btn btn-outline-danger" id="pdf_opd_total_report">PDF</button>
<button type="button" class="btn btn-outline-secondary" id="open_opd_patient_list">OPD Patient List</button>
</div>
</div>
</div>
@ -107,6 +108,10 @@ $feeTypes = $fee_types ?? [];
window.open(buildQuery() + '/2', '_blank');
});
document.getElementById('open_opd_patient_list').addEventListener('click', function() {
load_form('<?= base_url('Report/report_opd_patient_list') ?>', 'OPD Patient List');
});
$('.select2').select2({
theme: 'bootstrap4',
width: '100%'