feat: upgrade IPD Document Master to OPD-style print builder
- Add paper print settings to IPD templates (page size/custom size/margins)\n- Add Header HTML, Footer HTML, and Style (CSS) support\n- Update IPD PDF renderer to honor template paper settings and header/footer\n- Extend IPD placeholders with logo/QR support: {{H_logo}}, {{H_logo_abs}}, {{hospital_logo_html}}, {{qr_content}}, {{qr_code_html}}\n- Improve token rendering with robust curly placeholder parser for body/header/footer\n- Keep legacy sticker forms aligned with custom label dimensions and migrate old default rows
This commit is contained in:
parent
503c26a70f
commit
1a2dbf5366
|
|
@ -861,8 +861,26 @@ class Ipd extends BaseController
|
|||
|
||||
$html = view('billing/ipd/ipd_form_print', $data);
|
||||
$customTemplate = $this->getActiveIpdDocumentTemplate($formNo);
|
||||
$templatePageSize = '';
|
||||
$templateCustomWidth = 210;
|
||||
$templateCustomHeight = 297;
|
||||
$templateMarginTop = 0.8;
|
||||
$templateMarginBottom = 0.8;
|
||||
$templateMarginLeft = 0.8;
|
||||
$templateMarginRight = 0.8;
|
||||
$templateMarginHeader = 0.5;
|
||||
$templateMarginFooter = 0.5;
|
||||
if ($customTemplate !== null) {
|
||||
$html = $this->renderIpdDocumentTemplateHtml($customTemplate, $data);
|
||||
$templatePageSize = strtoupper(trim((string) ($customTemplate['page_size'] ?? '')));
|
||||
$templateCustomWidth = (int) ($customTemplate['custom_width_mm'] ?? 210);
|
||||
$templateCustomHeight = (int) ($customTemplate['custom_height_mm'] ?? 297);
|
||||
$templateMarginTop = (float) ($customTemplate['page_margin_top_cm'] ?? 0.8);
|
||||
$templateMarginBottom = (float) ($customTemplate['page_margin_bottom_cm'] ?? 0.8);
|
||||
$templateMarginLeft = (float) ($customTemplate['page_margin_left_cm'] ?? 0.8);
|
||||
$templateMarginRight = (float) ($customTemplate['page_margin_right_cm'] ?? 0.8);
|
||||
$templateMarginHeader = (float) ($customTemplate['margin_header_cm'] ?? 0.5);
|
||||
$templateMarginFooter = (float) ($customTemplate['margin_footer_cm'] ?? 0.5);
|
||||
}
|
||||
|
||||
$mpdfTempDir = WRITEPATH . 'cache' . DIRECTORY_SEPARATOR . 'mpdf';
|
||||
|
|
@ -876,12 +894,33 @@ class Ipd extends BaseController
|
|||
'margin_bottom' => 8,
|
||||
'margin_left' => 8,
|
||||
'margin_right' => 8,
|
||||
'margin_header' => 5,
|
||||
'margin_footer' => 5,
|
||||
'default_font' => 'freeserif',
|
||||
'autoScriptToLang' => true,
|
||||
'autoLangToFont' => true,
|
||||
];
|
||||
|
||||
if (in_array($formNo, [10, 11], true)) {
|
||||
if ($customTemplate !== null && $templatePageSize !== '') {
|
||||
if ($templatePageSize === 'CUSTOM') {
|
||||
$templateCustomWidth = max(20, min(600, $templateCustomWidth));
|
||||
$templateCustomHeight = max(20, min(1000, $templateCustomHeight));
|
||||
$mpdfConfig['format'] = [$templateCustomWidth, $templateCustomHeight];
|
||||
} elseif ($templatePageSize === 'A4-L') {
|
||||
$mpdfConfig['format'] = 'A4';
|
||||
$mpdfConfig['orientation'] = 'L';
|
||||
} else {
|
||||
$allowedFormats = ['A4', 'A5', 'A6', 'LETTER', 'LEGAL'];
|
||||
$mpdfConfig['format'] = in_array($templatePageSize, $allowedFormats, true) ? $templatePageSize : 'A4';
|
||||
}
|
||||
|
||||
$mpdfConfig['margin_top'] = max(0, min(250, (int) round($templateMarginTop * 10)));
|
||||
$mpdfConfig['margin_bottom'] = max(0, min(250, (int) round($templateMarginBottom * 10)));
|
||||
$mpdfConfig['margin_left'] = max(0, min(250, (int) round($templateMarginLeft * 10)));
|
||||
$mpdfConfig['margin_right'] = max(0, min(250, (int) round($templateMarginRight * 10)));
|
||||
$mpdfConfig['margin_header'] = max(0, min(250, (int) round($templateMarginHeader * 10)));
|
||||
$mpdfConfig['margin_footer'] = max(0, min(250, (int) round($templateMarginFooter * 10)));
|
||||
} elseif (in_array($formNo, [10, 11], true)) {
|
||||
$mpdfConfig['format'] = $formNo === 10 ? [50.8, 152.4] : [50.8, 203.2];
|
||||
$mpdfConfig['margin_top'] = 2;
|
||||
$mpdfConfig['margin_bottom'] = 2;
|
||||
|
|
@ -2278,7 +2317,12 @@ class Ipd extends BaseController
|
|||
}
|
||||
|
||||
$hospitalName = defined('H_Name') ? (string) constant('H_Name') : 'Hospital';
|
||||
$hospitalAddress = defined('H_address_1') ? (string) constant('H_address_1') : '';
|
||||
$hospitalAddress1 = defined('H_address_1') ? (string) constant('H_address_1') : '';
|
||||
$hospitalAddress2 = defined('H_address_2') ? (string) constant('H_address_2') : '';
|
||||
$hospitalAddress = trim($hospitalAddress1 . ', ' . $hospitalAddress2, ', ');
|
||||
$hospitalPhone = defined('H_phone_No') ? (string) constant('H_phone_No') : '';
|
||||
$hospitalEmail = defined('H_Email') ? (string) constant('H_Email') : '';
|
||||
$hospitalLogo = defined('H_logo') ? (string) constant('H_logo') : '';
|
||||
|
||||
return [
|
||||
'form_no' => $formNo,
|
||||
|
|
@ -2289,6 +2333,11 @@ class Ipd extends BaseController
|
|||
'insurance_name' => $insuranceName,
|
||||
'hospital_name' => $hospitalName,
|
||||
'hospital_address' => $hospitalAddress,
|
||||
'hospital_address_1' => $hospitalAddress1,
|
||||
'hospital_address_2' => $hospitalAddress2,
|
||||
'hospital_phone' => $hospitalPhone,
|
||||
'hospital_email' => $hospitalEmail,
|
||||
'hospital_logo' => $hospitalLogo,
|
||||
'generated_at' => date('d-m-Y h:i A'),
|
||||
];
|
||||
}
|
||||
|
|
@ -2300,7 +2349,7 @@ class Ipd extends BaseController
|
|||
}
|
||||
|
||||
$row = $this->db->table('ipd_document_templates')
|
||||
->select('id, form_no, template_name, template_html')
|
||||
->select('id, form_no, template_name, page_size, custom_width_mm, custom_height_mm, page_margin_top_cm, page_margin_bottom_cm, page_margin_left_cm, page_margin_right_cm, margin_header_cm, margin_footer_cm, header_html, footer_html, template_css, template_html')
|
||||
->where('form_no', $formNo)
|
||||
->where('status', 1)
|
||||
->orderBy('id', 'DESC')
|
||||
|
|
@ -2338,24 +2387,100 @@ class Ipd extends BaseController
|
|||
$ageGender = '-';
|
||||
}
|
||||
|
||||
$qrContent = trim(
|
||||
(string) ($person->p_code ?? '')
|
||||
. ':' . (string) ($ipd->ipd_code ?? '')
|
||||
. ':P-' . date('Y-m-d H:i:s')
|
||||
. ':C-' . (string) ($person->p_fname ?? '')
|
||||
, ':');
|
||||
$hospitalLogo = trim((string) ($data['hospital_logo'] ?? ''));
|
||||
$hospitalLogoAbs = $hospitalLogo !== '' ? (FCPATH . 'assets/images/' . $hospitalLogo) : '';
|
||||
$hospitalLogoHtml = $hospitalLogoAbs !== ''
|
||||
? '<img style="width: 75px;vertical-align: top;" src="' . esc($hospitalLogoAbs, 'attr') . '" />'
|
||||
: '';
|
||||
$qrCodeHtml = $qrContent !== ''
|
||||
? '<barcode code="' . esc($qrContent, 'attr') . '" size="0.8" type="QR" error="M" class="barcode" />'
|
||||
: '';
|
||||
|
||||
$replacements = [
|
||||
'{{FORM_TITLE}}' => esc((string) ($formMeta['title'] ?? 'IPD Form')),
|
||||
'{{HOSPITAL_NAME}}' => esc((string) ($data['hospital_name'] ?? 'Hospital')),
|
||||
'{{HOSPITAL_ADDRESS}}' => esc((string) ($data['hospital_address'] ?? '')),
|
||||
'{{H_Name}}' => esc((string) ($data['hospital_name'] ?? 'Hospital')),
|
||||
'{{H_address_1}}' => esc((string) ($data['hospital_address_1'] ?? '')),
|
||||
'{{H_address_2}}' => esc((string) ($data['hospital_address_2'] ?? '')),
|
||||
'{{H_phone_No}}' => esc((string) ($data['hospital_phone'] ?? '')),
|
||||
'{{H_Email}}' => esc((string) ($data['hospital_email'] ?? '')),
|
||||
'{{H_logo}}' => esc($hospitalLogo),
|
||||
'{{H_logo_abs}}' => esc($hospitalLogoAbs),
|
||||
'{{hospital_logo_html}}' => $hospitalLogoHtml,
|
||||
'{{HOSPITAL_LOGO_HTML}}' => $hospitalLogoHtml,
|
||||
'{{PATIENT_NAME}}' => esc($patientName),
|
||||
'{{pName}}' => esc($patientName),
|
||||
'{{AGE}}' => esc($age),
|
||||
'{{GENDER}}' => esc($gender),
|
||||
'{{AGE_GENDER}}' => esc($ageGender),
|
||||
'{{age_sex}}' => esc($ageGender),
|
||||
'{{UHID}}' => esc((string) ($person->p_code ?? '-')),
|
||||
'{{IPD_CODE}}' => esc((string) ($ipd->ipd_code ?? '-')),
|
||||
'{{ADMIT_DATE}}' => esc((string) ($ipd->str_register_date ?? ($ipd->register_date ?? '-'))),
|
||||
'{{DOCTORS}}' => esc(! empty($doctorNames) ? implode(', ', $doctorNames) : '-'),
|
||||
'{{doctor_name}}' => esc(! empty($doctorNames) ? implode(', ', $doctorNames) : '-'),
|
||||
'{{doctor_sign_html}}' => '',
|
||||
'{{phoneno}}' => esc((string) ($person->mphone1 ?? '-')),
|
||||
'{{INSURANCE_NAME}}' => esc((string) ($data['insurance_name'] ?? 'Direct')),
|
||||
'{{CURRENT_DATE}}' => esc(date('d-m-Y')),
|
||||
'{{CURRENT_DATETIME}}' => esc((string) ($data['generated_at'] ?? date('d-m-Y h:i A'))),
|
||||
'{{print_time}}' => esc((string) ($data['generated_at'] ?? date('d-m-Y h:i A'))),
|
||||
'{{qr_content}}' => esc($qrContent),
|
||||
'{{QR_CONTENT}}' => esc($qrContent),
|
||||
'{{qr_code_html}}' => $qrCodeHtml,
|
||||
'{{QR_CODE_HTML}}' => $qrCodeHtml,
|
||||
];
|
||||
|
||||
$html = strtr($templateHtml, $replacements);
|
||||
$headerHtml = trim((string) ($templateRow['header_html'] ?? ''));
|
||||
$footerHtml = trim((string) ($templateRow['footer_html'] ?? ''));
|
||||
$templateCss = trim((string) ($templateRow['template_css'] ?? ''));
|
||||
|
||||
$bodyHtml = $this->applyIpdTemplateTokens($templateHtml, $replacements);
|
||||
$renderedHeader = $headerHtml !== '' ? $this->applyIpdTemplateTokens($headerHtml, $replacements) : '';
|
||||
$renderedFooter = $footerHtml !== '' ? $this->applyIpdTemplateTokens($footerHtml, $replacements) : '';
|
||||
|
||||
$pageTop = (float) ($templateRow['page_margin_top_cm'] ?? 0.8);
|
||||
$pageBottom = (float) ($templateRow['page_margin_bottom_cm'] ?? 0.8);
|
||||
$pageLeft = (float) ($templateRow['page_margin_left_cm'] ?? 0.8);
|
||||
$pageRight = (float) ($templateRow['page_margin_right_cm'] ?? 0.8);
|
||||
$marginHeader = (float) ($templateRow['margin_header_cm'] ?? 0.5);
|
||||
$marginFooter = (float) ($templateRow['margin_footer_cm'] ?? 0.5);
|
||||
|
||||
$pageStyle = '<style>@page {'
|
||||
. 'margin-top:' . max(0, min(25, $pageTop)) . 'cm;'
|
||||
. 'margin-bottom:' . max(0, min(25, $pageBottom)) . 'cm;'
|
||||
. 'margin-left:' . max(0, min(25, $pageLeft)) . 'cm;'
|
||||
. 'margin-right:' . max(0, min(25, $pageRight)) . 'cm;'
|
||||
. 'margin-header:' . max(0, min(25, $marginHeader)) . 'cm;'
|
||||
. 'margin-footer:' . max(0, min(25, $marginFooter)) . 'cm;'
|
||||
. ($renderedHeader !== '' ? 'header: html_myHeader;' : '')
|
||||
. ($renderedFooter !== '' ? 'footer: html_myFooter;' : '')
|
||||
. '}</style>';
|
||||
|
||||
$userStyle = $templateCss !== '' ? ('<style>' . $templateCss . '</style>') : '';
|
||||
|
||||
$headerBlock = '';
|
||||
if ($renderedHeader !== '') {
|
||||
$headerBlock = preg_match('/<\s*htmlpageheader\b/i', $renderedHeader)
|
||||
? $renderedHeader
|
||||
: ('<htmlpageheader name="myHeader">' . $renderedHeader . '</htmlpageheader>');
|
||||
}
|
||||
|
||||
$footerBlock = '';
|
||||
if ($renderedFooter !== '') {
|
||||
$footerBlock = preg_match('/<\s*htmlpagefooter\b/i', $renderedFooter)
|
||||
? $renderedFooter
|
||||
: ('<htmlpagefooter name="myFooter">' . $renderedFooter . '</htmlpagefooter>');
|
||||
}
|
||||
|
||||
$html = $pageStyle . $userStyle . $headerBlock . $footerBlock . $bodyHtml;
|
||||
|
||||
// Force a Unicode-capable fallback stack so Devanagari text renders in mPDF.
|
||||
$fontStyle = '<style>body,table,td,th,p,span,div{font-family:freeserif,dejavusans,sans-serif !important;}</style>';
|
||||
|
|
@ -2363,6 +2488,57 @@ class Ipd extends BaseController
|
|||
return $fontStyle . $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, string> $replacements
|
||||
*/
|
||||
private function applyIpdTemplateTokens(string $html, array $replacements): string
|
||||
{
|
||||
if ($html === '') {
|
||||
return '';
|
||||
}
|
||||
|
||||
$tokenMap = [];
|
||||
foreach ($replacements as $token => $value) {
|
||||
$cleanToken = trim($token, '{} ');
|
||||
if ($cleanToken === '') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$tokenMap[$cleanToken] = $value;
|
||||
$lower = strtolower($cleanToken);
|
||||
if (! array_key_exists($lower, $tokenMap)) {
|
||||
$tokenMap[$lower] = $value;
|
||||
}
|
||||
$upper = strtoupper($cleanToken);
|
||||
if (! array_key_exists($upper, $tokenMap)) {
|
||||
$tokenMap[$upper] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
return (string) preg_replace_callback('/\{\{\s*([a-zA-Z0-9_]+)\s*\}\}/', static function (array $match) use ($tokenMap) {
|
||||
$name = (string) ($match[1] ?? '');
|
||||
if ($name === '') {
|
||||
return (string) ($match[0] ?? '');
|
||||
}
|
||||
|
||||
if (array_key_exists($name, $tokenMap)) {
|
||||
return $tokenMap[$name];
|
||||
}
|
||||
|
||||
$lower = strtolower($name);
|
||||
if (array_key_exists($lower, $tokenMap)) {
|
||||
return $tokenMap[$lower];
|
||||
}
|
||||
|
||||
$upper = strtoupper($name);
|
||||
if (array_key_exists($upper, $tokenMap)) {
|
||||
return $tokenMap[$upper];
|
||||
}
|
||||
|
||||
return (string) ($match[0] ?? '');
|
||||
}, $html);
|
||||
}
|
||||
|
||||
private function calculateCashBalanceTotals(array $rows): array
|
||||
{
|
||||
$totalPaid = 0.0;
|
||||
|
|
|
|||
|
|
@ -1366,6 +1366,7 @@ HTML;
|
|||
private function ensureIpdDocumentTemplateTable(): void
|
||||
{
|
||||
if ($this->db->tableExists('ipd_document_templates')) {
|
||||
$this->ensureIpdDocumentTemplateColumns();
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1373,6 +1374,18 @@ HTML;
|
|||
id INT NOT NULL AUTO_INCREMENT,
|
||||
form_no INT NOT NULL,
|
||||
template_name VARCHAR(160) NOT NULL,
|
||||
page_size VARCHAR(16) NOT NULL DEFAULT 'A4',
|
||||
custom_width_mm INT NOT NULL DEFAULT 210,
|
||||
custom_height_mm INT NOT NULL DEFAULT 297,
|
||||
page_margin_top_cm DECIMAL(5,2) NOT NULL DEFAULT 0.80,
|
||||
page_margin_bottom_cm DECIMAL(5,2) NOT NULL DEFAULT 0.80,
|
||||
page_margin_left_cm DECIMAL(5,2) NOT NULL DEFAULT 0.80,
|
||||
page_margin_right_cm DECIMAL(5,2) NOT NULL DEFAULT 0.80,
|
||||
margin_header_cm DECIMAL(5,2) NOT NULL DEFAULT 0.50,
|
||||
margin_footer_cm DECIMAL(5,2) NOT NULL DEFAULT 0.50,
|
||||
header_html LONGTEXT NULL,
|
||||
footer_html LONGTEXT NULL,
|
||||
template_css LONGTEXT NULL,
|
||||
template_html LONGTEXT NOT NULL,
|
||||
status TINYINT(1) NOT NULL DEFAULT 1,
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
|
|
@ -1383,6 +1396,40 @@ HTML;
|
|||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4";
|
||||
|
||||
$this->db->query($sql);
|
||||
$this->ensureIpdDocumentTemplateColumns();
|
||||
}
|
||||
|
||||
private function ensureIpdDocumentTemplateColumns(): void
|
||||
{
|
||||
if (! $this->db->tableExists('ipd_document_templates')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$columns = [
|
||||
'page_size' => "ALTER TABLE ipd_document_templates ADD COLUMN page_size VARCHAR(16) NOT NULL DEFAULT 'A4' AFTER template_name",
|
||||
'custom_width_mm' => "ALTER TABLE ipd_document_templates ADD COLUMN custom_width_mm INT NOT NULL DEFAULT 210 AFTER page_size",
|
||||
'custom_height_mm' => "ALTER TABLE ipd_document_templates ADD COLUMN custom_height_mm INT NOT NULL DEFAULT 297 AFTER custom_width_mm",
|
||||
'page_margin_top_cm' => "ALTER TABLE ipd_document_templates ADD COLUMN page_margin_top_cm DECIMAL(5,2) NOT NULL DEFAULT 0.80 AFTER custom_height_mm",
|
||||
'page_margin_bottom_cm' => "ALTER TABLE ipd_document_templates ADD COLUMN page_margin_bottom_cm DECIMAL(5,2) NOT NULL DEFAULT 0.80 AFTER page_margin_top_cm",
|
||||
'page_margin_left_cm' => "ALTER TABLE ipd_document_templates ADD COLUMN page_margin_left_cm DECIMAL(5,2) NOT NULL DEFAULT 0.80 AFTER page_margin_bottom_cm",
|
||||
'page_margin_right_cm' => "ALTER TABLE ipd_document_templates ADD COLUMN page_margin_right_cm DECIMAL(5,2) NOT NULL DEFAULT 0.80 AFTER page_margin_left_cm",
|
||||
'margin_header_cm' => "ALTER TABLE ipd_document_templates ADD COLUMN margin_header_cm DECIMAL(5,2) NOT NULL DEFAULT 0.50 AFTER page_margin_right_cm",
|
||||
'margin_footer_cm' => "ALTER TABLE ipd_document_templates ADD COLUMN margin_footer_cm DECIMAL(5,2) NOT NULL DEFAULT 0.50 AFTER margin_header_cm",
|
||||
'header_html' => "ALTER TABLE ipd_document_templates ADD COLUMN header_html LONGTEXT NULL AFTER margin_footer_cm",
|
||||
'footer_html' => "ALTER TABLE ipd_document_templates ADD COLUMN footer_html LONGTEXT NULL AFTER header_html",
|
||||
'template_css' => "ALTER TABLE ipd_document_templates ADD COLUMN template_css LONGTEXT NULL AFTER footer_html",
|
||||
];
|
||||
|
||||
foreach ($columns as $col => $sql) {
|
||||
try {
|
||||
$exists = $this->db->query("SHOW COLUMNS FROM ipd_document_templates LIKE '" . $col . "'")->getRowArray();
|
||||
if (empty($exists)) {
|
||||
$this->db->query($sql);
|
||||
}
|
||||
} catch (\Throwable $e) {
|
||||
// Keep template screen usable even if schema alter fails in restricted env.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function defaultIpdDocumentTemplates(): array
|
||||
|
|
@ -1616,10 +1663,35 @@ HTML,
|
|||
$table->insert([
|
||||
'form_no' => $formNo,
|
||||
'template_name' => $templateName,
|
||||
'page_size' => in_array($formNo, [10, 11], true) ? 'CUSTOM' : 'A4',
|
||||
'custom_width_mm' => $formNo === 10 ? 51 : ($formNo === 11 ? 51 : 210),
|
||||
'custom_height_mm' => $formNo === 10 ? 152 : ($formNo === 11 ? 203 : 297),
|
||||
'page_margin_top_cm' => in_array($formNo, [10, 11], true) ? 0.2 : 0.8,
|
||||
'page_margin_bottom_cm' => in_array($formNo, [10, 11], true) ? 0.2 : 0.8,
|
||||
'page_margin_left_cm' => in_array($formNo, [10, 11], true) ? 0.2 : 0.8,
|
||||
'page_margin_right_cm' => in_array($formNo, [10, 11], true) ? 0.2 : 0.8,
|
||||
'margin_header_cm' => 0.5,
|
||||
'margin_footer_cm' => 0.5,
|
||||
'template_html' => (string) ($row['template_html'] ?? ''),
|
||||
'status' => 1,
|
||||
]);
|
||||
}
|
||||
|
||||
// Upgrade legacy sticker templates created before page-size columns existed.
|
||||
$this->db->table('ipd_document_templates')
|
||||
->whereIn('form_no', [10, 11])
|
||||
->where('page_size', 'A4')
|
||||
->where('custom_width_mm', 210)
|
||||
->where('custom_height_mm', 297)
|
||||
->where('template_name LIKE', 'Legacy Sticker%')
|
||||
->set('page_size', 'CUSTOM')
|
||||
->set('custom_width_mm', 'CASE WHEN form_no=10 THEN 51 ELSE 51 END', false)
|
||||
->set('custom_height_mm', 'CASE WHEN form_no=10 THEN 152 ELSE 203 END', false)
|
||||
->set('page_margin_top_cm', 0.2)
|
||||
->set('page_margin_bottom_cm', 0.2)
|
||||
->set('page_margin_left_cm', 0.2)
|
||||
->set('page_margin_right_cm', 0.2)
|
||||
->update();
|
||||
}
|
||||
|
||||
public function ipd_document_templates()
|
||||
|
|
@ -1638,6 +1710,24 @@ HTML,
|
|||
$formNo = (int) ($this->request->getPost('form_no') ?? 0);
|
||||
$templateName = trim((string) ($this->request->getPost('template_name') ?? ''));
|
||||
$templateHtml = (string) ($this->request->getPost('template_html') ?? '');
|
||||
$headerHtml = (string) ($this->request->getPost('header_html') ?? '');
|
||||
$footerHtml = (string) ($this->request->getPost('footer_html') ?? '');
|
||||
$templateCss = (string) ($this->request->getPost('template_css') ?? '');
|
||||
$pageSize = strtoupper(trim((string) ($this->request->getPost('page_size') ?? 'A4')));
|
||||
if (! in_array($pageSize, ['A4', 'A4-L', 'A5', 'A6', 'LETTER', 'LEGAL', 'CUSTOM'], true)) {
|
||||
$pageSize = 'A4';
|
||||
}
|
||||
$customWidthMm = (int) ($this->request->getPost('custom_width_mm') ?? 210);
|
||||
$customHeightMm = (int) ($this->request->getPost('custom_height_mm') ?? 297);
|
||||
$customWidthMm = max(20, min(600, $customWidthMm));
|
||||
$customHeightMm = max(20, min(1000, $customHeightMm));
|
||||
|
||||
$marginTop = max(0, min(25, (float) ($this->request->getPost('page_margin_top_cm') ?? 0.8)));
|
||||
$marginBottom = max(0, min(25, (float) ($this->request->getPost('page_margin_bottom_cm') ?? 0.8)));
|
||||
$marginLeft = max(0, min(25, (float) ($this->request->getPost('page_margin_left_cm') ?? 0.8)));
|
||||
$marginRight = max(0, min(25, (float) ($this->request->getPost('page_margin_right_cm') ?? 0.8)));
|
||||
$marginHeader = max(0, min(25, (float) ($this->request->getPost('margin_header_cm') ?? 0.5)));
|
||||
$marginFooter = max(0, min(25, (float) ($this->request->getPost('margin_footer_cm') ?? 0.5)));
|
||||
$status = (int) ($this->request->getPost('status') ?? 1) === 1 ? 1 : 0;
|
||||
|
||||
if (! in_array($formNo, [1, 3, 5, 8, 9, 10, 11], true)) {
|
||||
|
|
@ -1651,6 +1741,18 @@ HTML,
|
|||
$data = [
|
||||
'form_no' => $formNo,
|
||||
'template_name' => $templateName,
|
||||
'page_size' => $pageSize,
|
||||
'custom_width_mm' => $customWidthMm,
|
||||
'custom_height_mm' => $customHeightMm,
|
||||
'page_margin_top_cm' => $marginTop,
|
||||
'page_margin_bottom_cm' => $marginBottom,
|
||||
'page_margin_left_cm' => $marginLeft,
|
||||
'page_margin_right_cm' => $marginRight,
|
||||
'margin_header_cm' => $marginHeader,
|
||||
'margin_footer_cm' => $marginFooter,
|
||||
'header_html' => $headerHtml,
|
||||
'footer_html' => $footerHtml,
|
||||
'template_css' => $templateCss,
|
||||
'template_html' => $templateHtml,
|
||||
'status' => $status,
|
||||
];
|
||||
|
|
|
|||
|
|
@ -8,6 +8,18 @@ $editId = (int) ($edit['id'] ?? 0);
|
|||
$formNo = (int) ($edit['form_no'] ?? 1);
|
||||
$templateName = (string) ($edit['template_name'] ?? '');
|
||||
$templateHtml = (string) ($edit['template_html'] ?? '<h3>{{FORM_TITLE}}</h3><p>{{PATIENT_NAME}}</p>');
|
||||
$headerHtml = (string) ($edit['header_html'] ?? '');
|
||||
$footerHtml = (string) ($edit['footer_html'] ?? '');
|
||||
$templateCss = (string) ($edit['template_css'] ?? '');
|
||||
$pageSize = strtoupper((string) ($edit['page_size'] ?? 'A4'));
|
||||
$customWidthMm = (int) ($edit['custom_width_mm'] ?? 210);
|
||||
$customHeightMm = (int) ($edit['custom_height_mm'] ?? 297);
|
||||
$marginTop = (string) ($edit['page_margin_top_cm'] ?? '0.8');
|
||||
$marginBottom = (string) ($edit['page_margin_bottom_cm'] ?? '0.8');
|
||||
$marginLeft = (string) ($edit['page_margin_left_cm'] ?? '0.8');
|
||||
$marginRight = (string) ($edit['page_margin_right_cm'] ?? '0.8');
|
||||
$marginHeader = (string) ($edit['margin_header_cm'] ?? '0.5');
|
||||
$marginFooter = (string) ($edit['margin_footer_cm'] ?? '0.5');
|
||||
$status = (int) ($edit['status'] ?? 1);
|
||||
|
||||
$formMap = [
|
||||
|
|
@ -36,7 +48,11 @@ $formMap = [
|
|||
Placeholders: <code>{{FORM_TITLE}}</code>, <code>{{HOSPITAL_NAME}}</code>, <code>{{HOSPITAL_ADDRESS}}</code>,
|
||||
<code>{{PATIENT_NAME}}</code>, <code>{{AGE}}</code>, <code>{{GENDER}}</code>, <code>{{AGE_GENDER}}</code>, <code>{{UHID}}</code>,
|
||||
<code>{{IPD_CODE}}</code>, <code>{{ADMIT_DATE}}</code>, <code>{{DOCTORS}}</code>, <code>{{INSURANCE_NAME}}</code>,
|
||||
<code>{{CURRENT_DATE}}</code>, <code>{{CURRENT_DATETIME}}</code>.
|
||||
<code>{{CURRENT_DATE}}</code>, <code>{{CURRENT_DATETIME}}</code>,
|
||||
<code>{{H_Name}}</code>, <code>{{H_address_1}}</code>, <code>{{H_address_2}}</code>, <code>{{H_phone_No}}</code>, <code>{{H_Email}}</code>,
|
||||
<code>{{H_logo}}</code>, <code>{{H_logo_abs}}</code>, <code>{{hospital_logo_html}}</code>,
|
||||
<code>{{doctor_name}}</code>, <code>{{doctor_sign_html}}</code>, <code>{{pName}}</code>, <code>{{age_sex}}</code>, <code>{{phoneno}}</code>, <code>{{print_time}}</code>,
|
||||
<code>{{qr_content}}</code>, <code>{{qr_code_html}}</code>.
|
||||
</div>
|
||||
|
||||
<div class="alert alert-warning py-2 small">
|
||||
|
|
@ -67,6 +83,66 @@ $formMap = [
|
|||
<option value="0" <?= $status === 0 ? 'selected' : '' ?>>Inactive</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<label class="form-label small">Page Size</label>
|
||||
<select name="page_size" id="ipd_page_size" class="form-select form-select-sm">
|
||||
<option value="A4" <?= $pageSize === 'A4' ? 'selected' : '' ?>>A4</option>
|
||||
<option value="A4-L" <?= $pageSize === 'A4-L' ? 'selected' : '' ?>>A4 Landscape</option>
|
||||
<option value="A5" <?= $pageSize === 'A5' ? 'selected' : '' ?>>A5</option>
|
||||
<option value="A6" <?= $pageSize === 'A6' ? 'selected' : '' ?>>A6</option>
|
||||
<option value="LETTER" <?= $pageSize === 'LETTER' ? 'selected' : '' ?>>Letter</option>
|
||||
<option value="LEGAL" <?= $pageSize === 'LEGAL' ? 'selected' : '' ?>>Legal</option>
|
||||
<option value="CUSTOM" <?= $pageSize === 'CUSTOM' ? 'selected' : '' ?>>Custom (mm)</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="col-md-3" id="ipd_custom_width_wrap" style="display:none;">
|
||||
<label class="form-label small">Custom Width (mm)</label>
|
||||
<input type="number" name="custom_width_mm" class="form-control form-control-sm" value="<?= esc((string) $customWidthMm) ?>" min="20" max="600" step="1">
|
||||
</div>
|
||||
<div class="col-md-3" id="ipd_custom_height_wrap" style="display:none;">
|
||||
<label class="form-label small">Custom Height (mm)</label>
|
||||
<input type="number" name="custom_height_mm" class="form-control form-control-sm" value="<?= esc((string) $customHeightMm) ?>" min="20" max="1000" step="1">
|
||||
</div>
|
||||
|
||||
<div class="col-md-2">
|
||||
<label class="form-label small">Top (cm)</label>
|
||||
<input type="number" name="page_margin_top_cm" class="form-control form-control-sm" value="<?= esc($marginTop) ?>" step="0.1" min="0" max="25">
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<label class="form-label small">Bottom (cm)</label>
|
||||
<input type="number" name="page_margin_bottom_cm" class="form-control form-control-sm" value="<?= esc($marginBottom) ?>" step="0.1" min="0" max="25">
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<label class="form-label small">Left (cm)</label>
|
||||
<input type="number" name="page_margin_left_cm" class="form-control form-control-sm" value="<?= esc($marginLeft) ?>" step="0.1" min="0" max="25">
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<label class="form-label small">Right (cm)</label>
|
||||
<input type="number" name="page_margin_right_cm" class="form-control form-control-sm" value="<?= esc($marginRight) ?>" step="0.1" min="0" max="25">
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<label class="form-label small">Header (cm)</label>
|
||||
<input type="number" name="margin_header_cm" class="form-control form-control-sm" value="<?= esc($marginHeader) ?>" step="0.1" min="0" max="25">
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<label class="form-label small">Footer (cm)</label>
|
||||
<input type="number" name="margin_footer_cm" class="form-control form-control-sm" value="<?= esc($marginFooter) ?>" step="0.1" min="0" max="25">
|
||||
</div>
|
||||
|
||||
<div class="col-12">
|
||||
<label class="form-label small">Header HTML</label>
|
||||
<textarea name="header_html" rows="4" class="form-control" style="font-family:Consolas,Monaco,monospace;"><?= esc($headerHtml) ?></textarea>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<label class="form-label small">Footer HTML</label>
|
||||
<textarea name="footer_html" rows="4" class="form-control" style="font-family:Consolas,Monaco,monospace;"><?= esc($footerHtml) ?></textarea>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<label class="form-label small">Style (CSS)</label>
|
||||
<textarea name="template_css" rows="4" class="form-control" style="font-family:Consolas,Monaco,monospace;" placeholder="Example: .title{font-size:16px;font-weight:bold;}"><?= esc($templateCss) ?></textarea>
|
||||
<small class="text-muted">Simple CSS textbox, similar to OPD template settings.</small>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<label class="form-label small">Template HTML</label>
|
||||
<textarea name="template_html" id="ipd_document_template_editor" rows="12" class="form-control" required><?= esc($templateHtml) ?></textarea>
|
||||
|
|
@ -123,6 +199,9 @@ $formMap = [
|
|||
var form = document.getElementById('ipd_document_template_form');
|
||||
var editorFieldId = 'ipd_document_template_editor';
|
||||
var submitBtn = form ? form.querySelector('button[type="submit"]') : null;
|
||||
var pageSizeEl = document.getElementById('ipd_page_size');
|
||||
var customWidthWrap = document.getElementById('ipd_custom_width_wrap');
|
||||
var customHeightWrap = document.getElementById('ipd_custom_height_wrap');
|
||||
|
||||
function initEditor() {
|
||||
if (!window.CKEDITOR) {
|
||||
|
|
@ -165,6 +244,20 @@ $formMap = [
|
|||
|
||||
initEditor();
|
||||
|
||||
function toggleCustomSize() {
|
||||
if (!pageSizeEl || !customWidthWrap || !customHeightWrap) {
|
||||
return;
|
||||
}
|
||||
var isCustom = pageSizeEl.value === 'CUSTOM';
|
||||
customWidthWrap.style.display = isCustom ? '' : 'none';
|
||||
customHeightWrap.style.display = isCustom ? '' : 'none';
|
||||
}
|
||||
|
||||
if (pageSizeEl) {
|
||||
pageSizeEl.addEventListener('change', toggleCustomSize);
|
||||
}
|
||||
toggleCustomSize();
|
||||
|
||||
if (form) {
|
||||
form.addEventListener('submit', function (event) {
|
||||
event.preventDefault();
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user