diff --git a/app/Controllers/Billing/CaseMaster.php b/app/Controllers/Billing/CaseMaster.php
index 4ac34a5..1369c6d 100644
--- a/app/Controllers/Billing/CaseMaster.php
+++ b/app/Controllers/Billing/CaseMaster.php
@@ -562,7 +562,6 @@ class CaseMaster extends BaseController
and (
o.insurance_case_id = cast(c.id as char)
or o.insurance_case_id = c.case_id_code
- or o.p_id = c.p_id
)
union all
@@ -585,7 +584,7 @@ class CaseMaster extends BaseController
where i.ipd_include = 1 and i.invoice_status = 1
and (
i.insurance_case_id = c.id
- or i.attach_id = c.p_id
+ or i.insurance_case_id = c.case_id_code
)
) v
order by v.Charge_type, v.Adate
@@ -627,7 +626,6 @@ class CaseMaster extends BaseController
->groupStart()
->where('insurance_case_id', (string) $caseId)
->orWhere('insurance_case_id', (string) ($caseRow->case_id_code ?? ''))
- ->orWhere('p_id', (int) ($caseRow->p_id ?? 0))
->groupEnd()
->get()
->getRow();
@@ -645,7 +643,7 @@ class CaseMaster extends BaseController
->where('invoice_status', 1)
->groupStart()
->where('insurance_case_id', $caseId)
- ->orWhere('attach_id', (int) ($caseRow->p_id ?? 0))
+ ->orWhere('insurance_case_id', (string) ($caseRow->case_id_code ?? ''))
->groupEnd()
->get()
->getRow();
diff --git a/app/Controllers/Ipd_discharge.php b/app/Controllers/Ipd_discharge.php
index 56b8c77..6c1985e 100644
--- a/app/Controllers/Ipd_discharge.php
+++ b/app/Controllers/Ipd_discharge.php
@@ -835,19 +835,58 @@ class Ipd_discharge extends BaseController
$hasUhidMarker = $patientCode !== '' && stripos($scanHead, $patientCode) !== false;
$hasIpdMarker = $ipdCode !== '' && stripos($scanHead, $ipdCode) !== false;
$hasDischargeHeading = stripos($scanHead, 'Discharge Summary') !== false;
+ $hasDemographicGrid = stripos($scanHead, 'UHID') !== false
+ && (stripos($scanHead, 'IPD No.') !== false || stripos($scanHead, 'IPD') !== false)
+ && (stripos($scanHead, 'Admission') !== false || stripos($scanHead, 'Discharge') !== false)
+ && stripos($scanHead, '
]*>\s*discharge\s*summary\s*<\/h[1-6]>\s*)?'
- . '(?:]*>.*?<\/table>\s*){1,2}/is';
+ . '(?:(?:
]*>\s*)?]*>.*?<\/table>\s*){1,2}/is';
$cleaned = preg_replace($pattern, '', $content, 1);
if (is_string($cleaned) && trim($cleaned) !== '') {
return trim($cleaned);
}
+ // Fallback for legacy plain-text/fragmented blocks: cut everything before first
+ // known clinical section heading when duplicate demographics are detected.
+ $sectionMarkers = [
+ 'Final Diagnosis',
+ 'Presenting Complaints',
+ 'Pain Measurement Scale',
+ 'General Examination on Admission',
+ 'Clinical Investigation Reports',
+ 'Course in the hospital',
+ 'Examination on Discharge',
+ 'Surgery',
+ 'Procedure',
+ 'Personal History',
+ 'Drug Allergy / ADR',
+ 'Co-Morbidities',
+ 'Discharge Medications',
+ 'Dietary Advice',
+ 'Discharge Advice/Instructions/Summary',
+ ];
+
+ $firstSectionPos = null;
+ foreach ($sectionMarkers as $marker) {
+ $pos = stripos($content, $marker);
+ if ($pos !== false && ($firstSectionPos === null || $pos < $firstSectionPos)) {
+ $firstSectionPos = $pos;
+ }
+ }
+
+ if ($firstSectionPos !== null && $firstSectionPos > 120) {
+ $trimmed = trim((string) substr($content, $firstSectionPos));
+ if ($trimmed !== '') {
+ return $trimmed;
+ }
+ }
+
return $content;
}
@@ -5142,19 +5181,35 @@ class Ipd_discharge extends BaseController
$withHeader = $printType !== 0;
$renderedHtml = $this->sanitizeDischargePdfHtml((string) ($templatePack['rendered_html'] ?? $content));
+ $renderedHtml = $this->dedupeTopDemographicTables($renderedHtml);
$templateName = (string) ($templatePack['selected_template_name'] ?? 'Discharge Template');
$templateTokenVars = $this->buildDischargeTemplateTokenVars($panelData, $content);
$templateTokenVars['TEMPLATE_NAME'] = esc($templateName);
+ $patient = $panelData['person_info'] ?? null;
+ $ipd = $panelData['ipd_info'] ?? null;
+ $patientName = trim((string) ($patient->p_fname ?? 'Patient'));
+ $ipdCode = trim((string) ($ipd->ipd_code ?? $ipdId));
+ $fileName = 'discharge_' . preg_replace('/[^A-Za-z0-9_-]+/', '_', $ipdCode !== '' ? $ipdCode : (string) $ipdId) . '.pdf';
+
$this->createIpdDischargeWorkTask($ipdId, $panelData);
try {
- $patient = $panelData['person_info'] ?? null;
- $ipd = $panelData['ipd_info'] ?? null;
+ $headerHtml = '';
+ if ($withHeader) {
+ $headerHtml = $this->sanitizeDischargePdfHtml(
+ $this->applyDischargeTemplateTokens(trim((string) ($templateSettings['header_html'] ?? '')), $templateTokenVars),
+ false
+ );
+ }
- $patientName = trim((string) ($patient->p_fname ?? 'Patient'));
- $ipdCode = trim((string) ($ipd->ipd_code ?? $ipdId));
- $fileName = 'discharge_' . preg_replace('/[^A-Za-z0-9_-]+/', '_', $ipdCode !== '' ? $ipdCode : (string) $ipdId) . '.pdf';
+ $footerHtml = $this->sanitizeDischargePdfHtml(
+ $this->applyDischargeTemplateTokens(trim((string) ($templateSettings['footer_html'] ?? '')), $templateTokenVars),
+ false
+ );
+ if ($footerHtml === '') {
+ $footerHtml = 'Page {PAGENO}/{nbpg}
';
+ }
$pdfHtml = $this->buildDischargePdfHtml($panelData, $renderedHtml, $withHeader, $templateName);
@@ -5169,6 +5224,8 @@ class Ipd_discharge extends BaseController
'margin_bottom' => max(0, ((float) ($templateSettings['page_margin_bottom_cm'] ?? 0.8)) * 10),
'margin_header' => max(0, ((float) ($templateSettings['margin_header_cm'] ?? 0.5)) * 10),
'margin_footer' => max(0, ((float) ($templateSettings['margin_footer_cm'] ?? 0.5)) * 10),
+ 'autoTopMargin' => 'stretch',
+ 'autoBottomMargin' => 'stretch',
'default_font' => 'freeserif',
'tempDir' => WRITEPATH . 'cache',
]);
@@ -5178,25 +5235,17 @@ class Ipd_discharge extends BaseController
$mpdf->SetTitle('Discharge Summary - ' . ($patientName !== '' ? $patientName : ('IPD ' . $ipdId)));
$mpdf->SetAuthor('Atria HMS');
- if ($withHeader) {
- $headerHtml = $this->sanitizeDischargePdfHtml(
- $this->applyDischargeTemplateTokens(trim((string) ($templateSettings['header_html'] ?? '')), $templateTokenVars)
- );
- if ($headerHtml !== '') {
- $mpdf->SetHTMLHeader($headerHtml);
- }
+ if ($withHeader && $headerHtml !== '') {
+ $mpdf->SetHTMLHeader($headerHtml, 'O', true);
+ $mpdf->SetHTMLHeader($headerHtml, 'E', true);
}
+ $mpdf->SetHTMLFooter($footerHtml, 'O', true);
+ $mpdf->SetHTMLFooter($footerHtml, 'E', true);
+ $pdfBinary = $this->runMpdfWithTolerantWarnings(static function () use ($mpdf, $pdfHtml, $fileName): string {
+ $mpdf->WriteHTML($pdfHtml);
- $footerHtml = $this->sanitizeDischargePdfHtml(
- $this->applyDischargeTemplateTokens(trim((string) ($templateSettings['footer_html'] ?? '')), $templateTokenVars)
- );
- if ($footerHtml === '') {
- $footerHtml = 'Page {PAGENO}/{nbpg}
';
- }
- $mpdf->SetHTMLFooter($footerHtml);
- $mpdf->WriteHTML($pdfHtml);
-
- $pdfBinary = $mpdf->Output($fileName, Destination::STRING_RETURN);
+ return $mpdf->Output($fileName, Destination::STRING_RETURN);
+ });
return $this->response
->setHeader('Content-Type', 'application/pdf')
->setHeader('Content-Disposition', 'inline; filename="' . $fileName . '"')
@@ -5208,10 +5257,103 @@ class Ipd_discharge extends BaseController
]);
if ($printType !== 0) {
- return $this->response
- ->setStatusCode(500)
- ->setHeader('Content-Type', 'text/plain; charset=UTF-8')
- ->setBody('Unable to generate discharge PDF for this template. Please remove legacy @page html header/footer directives from template CSS/HTML and retry.');
+ try {
+ $safeBodySource = trim($renderedHtml) !== '' ? $renderedHtml : (string) $content;
+ $safeBody = $this->sanitizeDischargePdfHtml($safeBodySource);
+ $safeBody = (string) preg_replace('/