Refine IPD charge display and billing print outputs

This commit is contained in:
DevSoftTech Server 2026-08-01 15:55:00 +05:30
parent 2ea2f9f2dc
commit 151ea7a53f
5 changed files with 89 additions and 15 deletions

View File

@ -10,6 +10,18 @@ class IpdBillingModel extends Model
private ?bool $ipdItemTypeHasSortOrder = null;
private function ipdGroupOrderExpr(string $column): string
{
return "CASE "
. "WHEN UPPER(" . $column . ") LIKE '%REGISTRATION%' THEN 10 "
. "WHEN UPPER(" . $column . ") LIKE '%ACCOMMOD%' OR UPPER(" . $column . ") LIKE '%ACCOMOD%' OR UPPER(" . $column . ") LIKE '%BEDSIDE%' THEN 20 "
. "WHEN UPPER(" . $column . ") LIKE '%SURGERY%' OR UPPER(" . $column . ") LIKE '%OPERATION%' THEN 30 "
. "WHEN UPPER(" . $column . ") LIKE '%PROCEDURE%' THEN 40 "
. "WHEN UPPER(" . $column . ") LIKE '%PROFESSIONAL%' OR UPPER(" . $column . ") LIKE '%DOCTOR VISIT%' THEN 50 "
. "WHEN UPPER(" . $column . ") LIKE '%LAB%' OR UPPER(" . $column . ") LIKE '%PATHO%' OR UPPER(" . $column . ") LIKE '%RADIO%' THEN 90 "
. "ELSE 70 END";
}
private function ipdItemTypeHasSortOrder(): bool
{
if ($this->ipdItemTypeHasSortOrder === null) {
@ -216,16 +228,22 @@ class IpdBillingModel extends Model
{
$builder = $this->db->table('ipd_invoice_item i')
->select('t.group_desc, i.*, sum(i.item_amount) as xAmount')
->select("trim(concat_ws(' ', 'Dr.', d.p_fname, d.p_mname, d.p_lname)) as doctor_display_name", false)
->select('ds.spec_names as doctor_specialization', false)
->join('ipd_item_type t', 'i.item_type = t.itype_id', 'left')
->join('doctor_master d', 'd.id = i.doc_id', 'left')
->join(
'(select s.doc_id, group_concat(distinct m.SpecName separator ", ") as spec_names from doc_spec s join med_spec m on m.id = s.med_spec_id group by s.doc_id) ds',
'ds.doc_id = i.doc_id',
'left',
false
)
->where('i.ipd_id', $ipdId)
->groupBy('i.item_type,i.id');
if ($this->ipdItemTypeHasSortOrder()) {
$builder->orderBy('COALESCE(t.sort_order, 0)', 'ASC', false);
}
return $builder
->orderBy('i.item_type', 'ASC')
->orderBy($this->ipdGroupOrderExpr('t.group_desc'), 'ASC', false)
->orderBy('t.group_desc', 'ASC')
->orderBy('i.id', 'ASC')
->get()
->getResult();
@ -393,20 +411,23 @@ class IpdBillingModel extends Model
public function getIpdInvoiceItems(int $ipdId, bool $excludePackage = false): array
{
$docSpecSubquery = '(select s.doc_id, group_concat(distinct m.SpecName separator ", ") as spec_names from doc_spec s join med_spec m on m.id = s.med_spec_id group by s.doc_id) ds';
$builder = $this->db->table('ipd_invoice_item i')
->select('t.group_desc,i.*')
->select("trim(concat_ws(' ', 'Dr.', d.p_fname, d.p_mname, d.p_lname)) as doctor_display_name", false)
->select('ds.spec_names as doctor_specialization', false)
->join('ipd_item_type t', 'i.item_type = t.itype_id', 'left')
->join('doctor_master d', 'd.id = i.doc_id', 'left')
->join($docSpecSubquery, 'ds.doc_id = i.doc_id', 'left', false)
->where('i.ipd_id', $ipdId);
if ($excludePackage) {
$builder->where('i.package_id', 0);
}
if ($this->ipdItemTypeHasSortOrder()) {
$builder->orderBy('COALESCE(t.sort_order, 0)', 'ASC', false);
}
return $builder
->orderBy($this->ipdGroupOrderExpr('t.group_desc'), 'ASC', false)
->orderBy('t.group_desc', 'ASC')
->orderBy('i.id', 'ASC')
->get()
@ -423,6 +444,7 @@ class IpdBillingModel extends Model
->where('i.ipd_id', $ipdId)
->where('i.ipd_include', 1)
->groupBy('i.ipd_id,t.item_id,t.item_rate,l.group_desc,t.org_code,t.item_name')
->orderBy($this->ipdGroupOrderExpr('l.group_desc'), 'ASC', false)
->orderBy('Charge_type', 'ASC')
->get()
->getResult();

View File

@ -126,6 +126,10 @@ $isDischargeFinal = (int) ($ipd->discarge_patient_status ?? 0) > 0;
$billHeadingText = $isDischargeFinal
? 'Bill No. : ' . (string) ($ipd->ipd_code ?? '')
: $billTitle;
$cleanNursingMarker = static function (string $text): string {
return trim((string) preg_replace('/\s*\[NURSING_CHARGE_ID:\d+\]\s*/', ' ', $text));
};
?>
<!doctype html>
<html lang="en">
@ -266,9 +270,27 @@ $billHeadingText = $isDischargeFinal
}
$amt = (float) ($row->item_amount ?? 0);
$desc = trim((string) ($row->item_name ?? ''));
$cleanComment = $cleanNursingMarker((string) ($row->comment ?? ''));
if ($cleanComment !== '') {
$desc = trim($desc . ' ' . $cleanComment);
}
$docLine = trim((string) ($row->doctor_display_name ?? ''));
if ($docLine === '') {
$docLine = trim((string) ($row->doc_name ?? ''));
}
$docSpec = trim((string) ($row->doctor_specialization ?? ''));
if ($docSpec !== '' && $docLine !== '') {
$docLine .= ' [' . $docSpec . ']';
}
echo '<tr>';
echo '<td class="center">' . $srNo . '</td>';
echo '<td>' . esc(trim((string) (($row->item_name ?? '') . ' ' . ($row->comment ?? '')))) . '</td>';
echo '<td>' . esc($desc);
if ($docLine !== '') {
echo '<br><small><em>' . esc($docLine) . '</em></small>';
}
echo '</td>';
echo '<td class="center">' . esc((string) ($row->org_code ?? '')) . '</td>';
echo '<td class="center">' . esc((string) ($row->item_qty ?? '')) . '</td>';
echo '<td class="right">' . esc(number_format((float) ($row->item_rate ?? 0), 2)) . '</td>';

View File

@ -105,7 +105,7 @@ $cardRemark = trim((string) ($payment->card_remark ?? ''));
<b>Bank Remark : </b><?= htmlspecialchars($cardRemark) ?><br/>
<?php endif; ?>
<?php endif; ?>
<b>Amount In Words : </b>Rs.<?= htmlspecialchars(number_to_word((float)($payment->amount ?? 0))) ?> Only
<b>Amount In Words : </b>Rs.<?= htmlspecialchars(number_to_word((float)($payment->amount ?? 0))) ?>
</p>
<p>
<b>Prepared By :</b><?= htmlspecialchars($payment->update_by ?? '') ?>

View File

@ -43,6 +43,10 @@ $hasFinalAdjustments = $payableByTpa > 0 || $discountForTpa > 0 || $discountByHo
$finalBalanceAmount = $hasFinalAdjustments ? (float) ($ipd->balance_discount_after ?? $balanceAmount) : $balanceAmount;
$isDischargeFinal = (int) ($ipd->discarge_patient_status ?? 0) > 0;
$billHeaderTitle = $isDischargeFinal ? 'Bill No. : ' . (string) ($ipd->ipd_code ?? '') : 'IPD Invoice';
$cleanNursingMarker = static function (string $text): string {
return trim((string) preg_replace('/\s*\[NURSING_CHARGE_ID:\d+\]\s*/', ' ', $text));
};
?>
<div class="card border-top border-3 border-danger">
@ -157,9 +161,27 @@ $billHeaderTitle = $isDischargeFinal ? 'Bill No. : ' . (string) ($ipd->ipd_code
$headTotal = 0.0;
}
$desc = trim((string) ($row->item_name ?? ''));
$cleanComment = $cleanNursingMarker((string) ($row->comment ?? ''));
if ($cleanComment !== '') {
$desc = trim($desc . ' ' . $cleanComment);
}
$docLine = trim((string) ($row->doctor_display_name ?? ''));
if ($docLine === '') {
$docLine = trim((string) ($row->doc_name ?? ''));
}
$docSpec = trim((string) ($row->doctor_specialization ?? ''));
if ($docSpec !== '' && $docLine !== '') {
$docLine .= ' [' . $docSpec . ']';
}
echo '<tr>';
echo '<td>' . $srNo . '</td>';
echo '<td>' . esc(($row->item_name ?? '') . ' ' . ($row->comment ?? '')) . '</td>';
echo '<td>' . esc($desc);
if ($docLine !== '') {
echo '<br><small><em>' . esc($docLine) . '</em></small>';
}
echo '</td>';
echo '<td>' . esc($row->org_code ?? '') . '</td>';
echo '<td>' . esc($row->item_qty ?? '') . '</td>';
echo '<td class="text-end">' . esc(number_format((float) ($row->item_rate ?? 0), 2)) . '</td>';

View File

@ -10,6 +10,10 @@ $today = date('Y-m-d');
$bedsideItemsByCategory = $bedside_items_by_category ?? [];
$doctorVisitFeeTypes = $doctor_visit_fee_types ?? [];
$doctorVisitFeeMap = $doctor_visit_fee_map ?? [];
$cleanNursingMarker = static function (string $text): string {
return trim((string) preg_replace('/\s*\[NURSING_CHARGE_ID:\d+\]\s*/', ' ', $text));
};
?>
<style>
@ -104,8 +108,12 @@ $doctorVisitFeeMap = $doctor_visit_fee_map ?? [];
$itemId = (int) ($row->id ?? 0);
$qty = (float) ($row->item_qty ?? 0);
$rate = (float) ($row->item_rate ?? 0);
$docName = (string) ($row->doc_name ?? '');
$comment = (string) ($row->comment ?? '');
$docName = trim((string) ($row->doctor_display_name ?? ''));
if ($docName === '') {
$docName = trim((string) ($row->doc_name ?? ''));
}
$docSpec = trim((string) ($row->doctor_specialization ?? ''));
$comment = $cleanNursingMarker((string) ($row->comment ?? ''));
$packageChecked = (int) ($row->package_id ?? 0) > 0 ? 'checked' : '';
?>
<tr>
@ -125,7 +133,7 @@ $doctorVisitFeeMap = $doctor_visit_fee_map ?? [];
<td>#</td>
<td colspan="3">
<?php if ($docName !== '') : ?>
<div>Dr. <?= esc($docName) ?></div>
<div><?= esc($docName) ?><?= $docSpec !== '' ? ' [' . esc($docSpec) . ']' : '' ?></div>
<?php endif; ?>
<?php if ($comment !== '') : ?>
<div><em><?= esc($comment) ?></em></div>