From 435192f81a51b2a590b316d38996025b1598f512 Mon Sep 17 00:00:00 2001 From: DevSoftTech Server Date: Fri, 3 Apr 2026 13:29:03 +0530 Subject: [PATCH] IPD payment receipt: fix modal loader, add PDF print route, and bank mode details --- app/Config/Routes.php | 1 + app/Controllers/Billing/Ipd.php | 85 +++++++++++- app/Models/IpdBillingModel.php | 3 +- .../billing/ipd/ipd_model_payment_box.php | 4 +- .../ipd/ipd_panel_deduction_payment.php | 4 +- .../billing/ipd/ipd_payment_receipt_pdf.php | 123 ++++++++++++++++++ .../billing/ipd/ipd_payment_receipt_print.php | 91 +++++++++++-- app/Views/billing/ipd/panel_payments.php | 8 +- 8 files changed, 293 insertions(+), 26 deletions(-) create mode 100644 app/Views/billing/ipd/ipd_payment_receipt_pdf.php diff --git a/app/Config/Routes.php b/app/Config/Routes.php index 30e1037..abfc72d 100644 --- a/app/Config/Routes.php +++ b/app/Config/Routes.php @@ -379,6 +379,7 @@ $routes->group('billing', function($routes) { $routes->post('ipd/payment/deduct', 'Billing\\Ipd::deductPayment'); $routes->post('ipd/payment/tpa', 'Billing\\Ipd::tpaPayment'); $routes->get('ipd/payment/receipt/(:num)/(:num)', 'Billing\\Ipd::ipdCashPrintPdf/$1/$2'); + $routes->get('ipd/payment/pdf-receipt/(:num)/(:num)', 'Billing\\Ipd::pdfPaymentReceipt/$1/$2'); $routes->get('ipd/cash-balance', 'Billing\\Ipd::cashBalance'); $routes->get('ipd/cash-balance/report', 'Billing\\Ipd::cashBalanceReport'); $routes->get('ipd/cash-balance/export', 'Billing\\Ipd::cashBalanceExport'); diff --git a/app/Controllers/Billing/Ipd.php b/app/Controllers/Billing/Ipd.php index 24615c4..c484c85 100644 --- a/app/Controllers/Billing/Ipd.php +++ b/app/Controllers/Billing/Ipd.php @@ -2053,11 +2053,13 @@ class Ipd extends BaseController return $permission; } - $payment = $this->db->table('payment_history') - ->select("*,date_format(payment_date,'%d-%m-%Y %h:%i %p') as payment_date_str,if(credit_debit=0,'','Return') as Amount_str", false) - ->where('payof_type', 4) - ->where('payof_id', $ipdId) - ->where('id', $payId) + $payment = $this->db->table('payment_history p') + ->select("p.*,date_format(p.payment_date,'%d-%m-%Y %h:%i %p') as payment_date_str,if(p.credit_debit=0,'','Return') as Amount_str,s.pay_type,b.bank_name", false) + ->join('hospital_bank_payment_source s', 's.id = p.pay_bank_id', 'left') + ->join('hospital_bank b', 'b.id = s.bank_id', 'left') + ->where('p.payof_type', 4) + ->where('p.payof_id', $ipdId) + ->where('p.id', $payId) ->get() ->getResult(); @@ -2085,6 +2087,79 @@ class Ipd extends BaseController ]); } + public function pdfPaymentReceipt(int $ipdId, int $payId) + { + $permission = $this->requireAnyPermission([ + 'billing.access', + 'billing.ipd.invoice', + ]); + if ($permission) { + return $permission; + } + + $payment = $this->db->table('payment_history p') + ->select("p.*,date_format(p.payment_date,'%d-%m-%Y %h:%i %p') as payment_date_str,if(p.credit_debit=0,'','Return') as Amount_str,s.pay_type,b.bank_name", false) + ->join('hospital_bank_payment_source s', 's.id = p.pay_bank_id', 'left') + ->join('hospital_bank b', 'b.id = s.bank_id', 'left') + ->where('p.payof_type', 4) + ->where('p.payof_id', $ipdId) + ->where('p.id', $payId) + ->get() + ->getResult(); + + $ipdMaster = $this->db->table('ipd_master') + ->where('id', $ipdId) + ->get() + ->getResult(); + + if (empty($ipdMaster)) { + return $this->response->setStatusCode(404)->setBody('IPD not found'); + } + + $patient = $this->db->table('patient_master') + ->select("*,if(gender=1,'Male','Female') as xgender", false) + ->where('id', $ipdMaster[0]->p_id) + ->get() + ->getResult(); + + $html = view('billing/ipd/ipd_payment_receipt_pdf', [ + 'ipd_payment' => $payment, + 'ipd_master' => $ipdMaster, + 'patient_master' => $patient, + 'ipd_id' => $ipdId, + 'payid' => $payId, + ]); + + $mpdfTempDir = WRITEPATH . 'cache' . DIRECTORY_SEPARATOR . 'mpdf'; + if (! is_dir($mpdfTempDir)) { + mkdir($mpdfTempDir, 0755, true); + } + + $mpdf = new Mpdf([ + 'tempDir' => $mpdfTempDir, + 'format' => 'A4', + ]); + + $hospitalName = defined('H_Name') ? (string) constant('H_Name') : ''; + if ($hospitalName !== '') { + $mpdf->SetWatermarkText($hospitalName); + $mpdf->showWatermarkText = false; + } + + // Strip BOM and sanitize to valid UTF-8 before passing to mPDF + $html = ltrim($html, "\xEF\xBB\xBF"); + $html = mb_convert_encoding($html, 'UTF-8', 'UTF-8'); + + $mpdf->WriteHTML($html); + + $fileName = 'IPD_Payment_Receipt_' . $payId . '_' . date('YmdHis') . '.pdf'; + + return $this->response + ->setHeader('Content-Type', 'application/pdf') + ->setHeader('Content-Disposition', 'inline; filename="' . $fileName . '"') + ->setBody($mpdf->Output($fileName, 'S')); + } + private function parseDateRange(string $range): array { $start = date('Y-m-d'); diff --git a/app/Models/IpdBillingModel.php b/app/Models/IpdBillingModel.php index 2b34558..62fde1e 100644 --- a/app/Models/IpdBillingModel.php +++ b/app/Models/IpdBillingModel.php @@ -604,8 +604,7 @@ class IpdBillingModel extends Model public function getPayments(int $ipdId): array { return $this->db->table('payment_history') - ->select("*,date_format(payment_date,'%d-%M-%Y') as pay_date_str,") - ->select("concat(if(payment_mode=1,'Cash','BANK'),if(credit_debit=0,'','-Return')) as pay_mode", false) + ->select("*,date_format(payment_date,'%d-%M-%Y') as pay_date_str,concat(if(payment_mode=1,'Cash','Bank'),if(credit_debit=0,'','-Return')) as pay_mode", false) ->where('payof_type', 4) ->where('payof_id', $ipdId) ->orderBy('id', 'DESC') diff --git a/app/Views/billing/ipd/ipd_model_payment_box.php b/app/Views/billing/ipd/ipd_model_payment_box.php index d7511a5..087758b 100644 --- a/app/Views/billing/ipd/ipd_model_payment_box.php +++ b/app/Views/billing/ipd/ipd_model_payment_box.php @@ -125,7 +125,7 @@ if ($person) { } if (data.ipd_id && data.payid) { - load_report_div('/' + data.ipd_id + '/' + data.payid, 'payModal-bodyc'); + load_form_div('/' + data.ipd_id + '/' + data.payid, 'payModal-bodyc'); } }, 'json'); }); @@ -157,7 +157,7 @@ if ($person) { } if (data.ipd_id && data.payid) { - load_report_div('/' + data.ipd_id + '/' + data.payid, 'payModal-bodyc'); + load_form_div('/' + data.ipd_id + '/' + data.payid, 'payModal-bodyc'); } }, 'json'); }); diff --git a/app/Views/billing/ipd/ipd_panel_deduction_payment.php b/app/Views/billing/ipd/ipd_panel_deduction_payment.php index 3dae95f..2ae8293 100644 --- a/app/Views/billing/ipd/ipd_panel_deduction_payment.php +++ b/app/Views/billing/ipd/ipd_panel_deduction_payment.php @@ -99,7 +99,7 @@ } if (data.ipd_id && data.payid) { - load_report_div('/' + data.ipd_id + '/' + data.payid, 'payModal_ded-bodyc'); + load_form_div('/' + data.ipd_id + '/' + data.payid, 'payModal_ded-bodyc'); } }, 'json'); }); @@ -125,7 +125,7 @@ } if (data.ipd_id && data.payid) { - load_report_div('/' + data.ipd_id + '/' + data.payid, 'payModal_ded-bodyc'); + load_form_div('/' + data.ipd_id + '/' + data.payid, 'payModal_ded-bodyc'); } }, 'json'); }); diff --git a/app/Views/billing/ipd/ipd_payment_receipt_pdf.php b/app/Views/billing/ipd/ipd_payment_receipt_pdf.php new file mode 100644 index 0000000..b14c215 --- /dev/null +++ b/app/Views/billing/ipd/ipd_payment_receipt_pdf.php @@ -0,0 +1,123 @@ +amount ?? 0) . ':PT' . date('dmYhis'); +?> + + + + + + + + + +
+ + + + +

+

+ +
Phone: +

+
+ +
+

IPD Payment Amount_str ?? '') ?> Receipt :

+
+ + + + + + +
+ Patient Info.
+ UHID : p_code ?? '') ?>
+ Name : title ?? '') ?> p_fname ?? '')) ?>
+ p_relative ?? '') ?> p_rname ?? '')) ?>
+ Sex : xgender ?? '') ?> age ?? '') ?> P.No. :mphone1 ?? '') ?> +
+ IPD No. : ipd_code ?? '') ?>
+ Date : payment_date_str ?? '') ?> +
+
+payment_mode ?? 0) === 1) ? 'Cash' : 'Bank'; +$isBankPayment = ((int) ($payment->payment_mode ?? 0) !== 1); +$paymentSource = trim((string) ($payment->pay_type ?? '')); +$bankName = trim((string) ($payment->bank_name ?? '')); +$cardTranId = trim((string) ($payment->card_tran_id ?? '')); +$bankMachine = trim((string) ($payment->bankcard_machine ?? '')); +$cardNumber = trim((string) ($payment->cust_card ?? '')); +$cardRemark = trim((string) ($payment->card_remark ?? '')); +?> +

+ IPD Amount_str ?? '') ?> Amount : Rs. amount ?? 0), 2) ?>
+ Payment Mode :
+ + + Bank/UPI Type :
+ + + Bank Name :
+ + + Transaction ID :
+ + + Bank/Card Machine :
+ + + Card/Reference No :
+ + + Bank Remark :
+ + + Amount In Words : Rs.amount ?? 0))) ?> Only +

+

+ Prepared By :update_by ?? '') ?> +

+ + + + + +
  +
Authorised Signature
+
+

+ This is a computer-generated receipt and does not require a physical signature. +

diff --git a/app/Views/billing/ipd/ipd_payment_receipt_print.php b/app/Views/billing/ipd/ipd_payment_receipt_print.php index 10a2f00..698d3bf 100644 --- a/app/Views/billing/ipd/ipd_payment_receipt_print.php +++ b/app/Views/billing/ipd/ipd_payment_receipt_print.php @@ -2,27 +2,90 @@ $payment = $ipd_payment[0] ?? null; $ipd = $ipd_master[0] ?? null; $patient = $patient_master[0] ?? null; + +$hospitalName = defined('H_Name') ? (string) constant('H_Name') : 'Hospital'; +$hospitalAddress1 = defined('H_address_1') ? (string) constant('H_address_1') : ''; +$hospitalAddress2 = defined('H_address_2') ? (string) constant('H_address_2') : ''; +$hospitalPhone = defined('H_phone_No') ? (string) constant('H_phone_No') : ''; +$hospitalLogoName = defined('H_logo') ? trim((string) constant('H_logo')) : ''; + +$logoSrc = ''; +if ($hospitalLogoName !== '') { + $logoSrc = base_url('assets/images/' . rawurlencode($hospitalLogoName)); +} + +// QR Code Data: IPD-{IPD_ID}:{PAYMENT_ID}:{AMOUNT}:{TIMESTAMP} +$qrData = 'IPD-' . $ipd->id . ':' . $payid . ':' . $payment->amount . ':' . date('dmYHi'); +$qrCodeUrl = 'https://api.qrserver.com/v1/create-qr-code/?size=150x150&data=' . urlencode($qrData); ?>
-
- IPD Payment Amount_str ?? '') ?> Receipt : +
+
+ IPD Payment Receipt # +
Amount_str ?? '') ?> +
+
-
-
-

UHID : p_code ?? '') ?>

-

Name : title ?? '') ?> p_fname ?? '') ?>

-

Sex : xgender ?? '') ?> age ?? '') ?>

-

Phone : mphone1 ?? '') ?>

+ +
+
+ + Hospital Logo + +
No Logo
+
-
-

IPD No. : ipd_code ?? '') ?>

-

Date : payment_date_str ?? '') ?>

+
+
+ + '; + if ($hospitalPhone !== '') echo 'Phone: ' . esc($hospitalPhone); + ?> + +
+
+ QR Code + Receipt #
+ + +
+
+

Patient Information

+

UHID : p_code ?? '') ?>

+

Name : title ?? '') ?> p_fname ?? '') ?>

+

Gender : xgender ?? '') ?> / Age : age ?? '') ?>

+

Phone : mphone1 ?? '') ?>

+
+
+

Payment Information

+

IPD Code : ipd_code ?? '') ?>

+

Payment Date : payment_date_str ?? '') ?>

+

Receipt #:

+
+
+
-

IPD Amount_str ?? '') ?> Amount : Rs. amount ?? '') ?>

-

Amount in Words : Rs. amount ?? 0)) ?>

-

Prepared By : update_by ?? '') ?>

+ + +
+
+

Payment Amount : Rs. amount ?? 0), 2)) ?>

+

Amount in Words : Rs. amount ?? 0))) ?>

+

Prepared By : update_by ?? '') ?>

+
+
+ +
+ +
+

This is a computer-generated receipt. No signature is required.

+
diff --git a/app/Views/billing/ipd/panel_payments.php b/app/Views/billing/ipd/panel_payments.php index b61088d..d36aa8c 100644 --- a/app/Views/billing/ipd/panel_payments.php +++ b/app/Views/billing/ipd/panel_payments.php @@ -12,6 +12,7 @@ Date Amount Mode + Print @@ -24,11 +25,16 @@ pay_date_str ?? '') ?> amount ?? '') ?> pay_mode ?? '') ?> + + + + + - No payments found. + No payments found.