feat: add Doctor Master OPD validity editing with hospital fallback

- Add OPD Validity (Days) field in Doctor add/edit forms\n- Save/update doctor_master.opd_valid_no_days from Doctor module\n- Use hospital_setting fallback keys when doctor validity is blank/zero\n- Apply fallback consistently in OPD showfee, print expiry, and running_opd lookup window\n- Supports hospital-wide defaults while preserving doctor-specific overrides
This commit is contained in:
DevSoftTech Server 2026-04-10 12:58:17 +05:30
parent eec0642466
commit 910f46b06c
5 changed files with 186 additions and 11 deletions

View File

@ -1364,10 +1364,8 @@ class Opd extends BaseController
$query = $this->db->query($sql);
$doctorMaster = $query->getResult();
$noOpdDays = 5 - 1;
if (count($doctorMaster) > 0 && !empty($doctorMaster[0]->opd_valid_no_days)) {
$noOpdDays = (int) $doctorMaster[0]->opd_valid_no_days - 1;
}
$doctorRow = $doctorMaster[0] ?? null;
$noOpdDays = $this->resolveOpdValiditySpanDays($doctorRow);
$sql = "select d.id, d.p_fname, group_concat(m.SpecName) as SpecName,
if(d.gender=1,'Male','Female') as xGender
@ -3487,6 +3485,35 @@ class Opd extends BaseController
return trim((string) ($row['s_value'] ?? ''));
}
private function resolveOpdValiditySpanDays(?object $doctorRow): int
{
$validDays = (int) ($doctorRow->opd_valid_no_days ?? 0);
if ($validDays <= 0) {
$validDays = $this->getHospitalDefaultOpdValidityDays();
}
return max(0, $validDays - 1);
}
private function getHospitalDefaultOpdValidityDays(): int
{
$keys = [
'OPD_VALID_NO_DAYS',
'OPD_VALIDITY_DAYS',
'DEFAULT_OPD_VALID_NO_DAYS',
'DEFAULT_OPD_VALIDITY_DAYS',
];
foreach ($keys as $key) {
$value = (int) $this->readSettingValueFromDb($key);
if ($value > 0) {
return min(365, $value);
}
}
return 5;
}
private function buildOpdLetterPrintData(int $opdId, int $sessionId = 0, bool $includeContent = true): ?array
{
$sql = "Select * from opd_master where opd_id=" . (int) $opdId;
@ -3499,7 +3526,7 @@ class Opd extends BaseController
$data = [];
$docId = (int) ($opdMaster[0]->doc_id ?? 0);
$noOpdDays = 5 - 1;
$noOpdDays = $this->resolveOpdValiditySpanDays(null);
$data['doctor_master'] = [];
if ($docId > 0) {
@ -3511,9 +3538,7 @@ class Opd extends BaseController
group by d.id";
$query = $this->db->query($sql);
$data['doctor_master'] = $query->getResult();
if (!empty($data['doctor_master']) && !empty($data['doctor_master'][0]->opd_valid_no_days)) {
$noOpdDays = (int) $data['doctor_master'][0]->opd_valid_no_days - 1;
}
$noOpdDays = $this->resolveOpdValiditySpanDays($data['doctor_master'][0] ?? null);
}
$sql = "select o.*,date_format(o.apointment_date,'%d-%m-%Y') as str_apointment_date,

View File

@ -27,6 +27,7 @@ class Doctor extends BaseController
'template_options' => $templateContext['options'],
'opd_print_template_options' => $templateContext['opd_print_options'],
'template_fields' => $templateContext['fields'],
'hospital_default_opd_valid_no_days' => $this->getHospitalDefaultOpdValidityDays(),
]);
}
@ -47,6 +48,7 @@ class Doctor extends BaseController
'template_options' => $templateContext['options'],
'opd_print_template_options' => $templateContext['opd_print_options'],
'template_fields' => $templateContext['fields'],
'hospital_default_opd_valid_no_days' => $this->getHospitalDefaultOpdValidityDays(),
]);
}
@ -90,6 +92,11 @@ class Doctor extends BaseController
'doc_sign' => $shortDescription,
];
$doctorFields = $this->db->tableExists('doctor_master') ? ($this->db->getFieldNames('doctor_master') ?? []) : [];
if (in_array('opd_valid_no_days', $doctorFields, true)) {
$data['opd_valid_no_days'] = $this->resolveOpdValidityInput((string) $this->request->getPost('input_opd_valid_no_days'));
}
$templateContext = $this->getDoctorTemplateContext();
$templateFieldMap = [
'opd_print_format' => 'tmpl_opd_print_format',
@ -125,6 +132,7 @@ class Doctor extends BaseController
'template_options' => $templateContext['options'],
'opd_print_template_options' => $templateContext['opd_print_options'],
'template_fields' => $templateContext['fields'],
'hospital_default_opd_valid_no_days' => $this->getHospitalDefaultOpdValidityDays(),
]);
}
@ -138,9 +146,11 @@ class Doctor extends BaseController
{
$doctorModel = new DoctorModel();
$templateContext = $this->getDoctorTemplateContext();
$doctorRows = $doctorModel->getDoctorById($id);
$doctorRow = $doctorRows[0] ?? null;
return view('Setting/Doctor/Doctor_profile_V', [
'data' => $doctorModel->getDoctorById($id),
'data' => $doctorRows,
'doc_spec_a' => $doctorModel->getDoctorSpecs($id),
'doc_spec_l' => $doctorModel->getSpecsList(),
'doc_fee_type' => $doctorModel->getFeeTypes(),
@ -150,6 +160,8 @@ class Doctor extends BaseController
'template_options' => $templateContext['options'],
'opd_print_template_options' => $templateContext['opd_print_options'],
'template_fields' => $templateContext['fields'],
'hospital_default_opd_valid_no_days' => $this->getHospitalDefaultOpdValidityDays(),
'doctor_opd_valid_no_days' => $this->resolveDoctorOpdValidityDaysForView($doctorRow),
]);
}
@ -189,6 +201,11 @@ class Doctor extends BaseController
'email1' => $this->request->getPost('input_email'),
];
$doctorFields = $this->db->tableExists('doctor_master') ? ($this->db->getFieldNames('doctor_master') ?? []) : [];
if (in_array('opd_valid_no_days', $doctorFields, true)) {
$data['opd_valid_no_days'] = $this->resolveOpdValidityInput((string) $this->request->getPost('input_opd_valid_no_days'));
}
$templateContext = $this->getDoctorTemplateContext();
$templateFieldMap = [
'opd_print_format' => 'tmpl_opd_print_format',
@ -695,4 +712,70 @@ class Doctor extends BaseController
return $options;
}
private function resolveDoctorOpdValidityDaysForView(?object $doctorRow): int
{
$doctorValue = (int) ($doctorRow->opd_valid_no_days ?? 0);
if ($doctorValue > 0) {
return $doctorValue;
}
return $this->getHospitalDefaultOpdValidityDays();
}
private function resolveOpdValidityInput(string $raw): int
{
$raw = trim($raw);
if ($raw === '') {
return $this->getHospitalDefaultOpdValidityDays();
}
$value = (int) $raw;
if ($value < 1) {
$value = 1;
}
if ($value > 365) {
$value = 365;
}
return $value;
}
private function getHospitalDefaultOpdValidityDays(): int
{
if (! $this->db->tableExists('hospital_setting')) {
return 5;
}
$keys = [
'OPD_VALID_NO_DAYS',
'OPD_VALIDITY_DAYS',
'DEFAULT_OPD_VALID_NO_DAYS',
'DEFAULT_OPD_VALIDITY_DAYS',
];
$rows = $this->db->table('hospital_setting')
->select('s_name,s_value')
->whereIn('s_name', $keys)
->get()
->getResultArray();
$map = [];
foreach ($rows as $row) {
$name = strtoupper(trim((string) ($row['s_name'] ?? '')));
if ($name === '') {
continue;
}
$map[$name] = (string) ($row['s_value'] ?? '');
}
foreach ($keys as $key) {
$value = (int) ($map[$key] ?? 0);
if ($value > 0) {
return min(365, $value);
}
}
return 5;
}
}

View File

@ -116,7 +116,50 @@ class OpdModel
->where('id', $docId)
->get()
->getRow();
$validDays = max(4, (int) ($docRow->opd_valid_no_days ?? 5) - 1);
return date('Y-m-d', strtotime('-' . $validDays . ' days'));
$validDays = (int) ($docRow->opd_valid_no_days ?? 0);
if ($validDays <= 0) {
$validDays = $this->getHospitalDefaultOpdValidityDays();
}
$spanDays = max(0, $validDays - 1);
return date('Y-m-d', strtotime('-' . $spanDays . ' days'));
}
private function getHospitalDefaultOpdValidityDays(): int
{
if (! $this->db->tableExists('hospital_setting')) {
return 5;
}
$keys = [
'OPD_VALID_NO_DAYS',
'OPD_VALIDITY_DAYS',
'DEFAULT_OPD_VALID_NO_DAYS',
'DEFAULT_OPD_VALIDITY_DAYS',
];
$rows = $this->db->table('hospital_setting')
->select('s_name,s_value')
->whereIn('s_name', $keys)
->get()
->getResultArray();
$map = [];
foreach ($rows as $row) {
$name = strtoupper(trim((string) ($row['s_name'] ?? '')));
if ($name === '') {
continue;
}
$map[$name] = (string) ($row['s_value'] ?? '');
}
foreach ($keys as $key) {
$value = (int) ($map[$key] ?? 0);
if ($value > 0) {
return min(365, $value);
}
}
return 5;
}
}

View File

@ -17,6 +17,11 @@
[$dobDay, $dobMonth, $dobYear] = explode('/', $doctorDobValue);
$doctorDobValue = $dobYear . '-' . $dobMonth . '-' . $dobDay;
}
$hospitalDefaultOpdDays = (int) ($hospital_default_opd_valid_no_days ?? 5);
if ($hospitalDefaultOpdDays < 1) {
$hospitalDefaultOpdDays = 5;
}
$opdValidNoDaysInput = trim((string) ($formData['input_opd_valid_no_days'] ?? (string) $hospitalDefaultOpdDays));
?>
<?php if (! empty($errors)) : ?>
<div class="alert alert-danger">
@ -74,6 +79,11 @@
<label class="form-label">Date of Birth</label>
<input class="form-control" name="datepicker_dob" type="date" value="<?= esc($doctorDobValue) ?>">
</div>
<div class="col-md-4">
<label class="form-label">OPD Validity (Days)</label>
<input class="form-control" name="input_opd_valid_no_days" placeholder="5" type="number" min="1" max="365" value="<?= esc($opdValidNoDaysInput) ?>">
<small class="text-muted">Default hospital value: <?= esc((string) $hospitalDefaultOpdDays) ?> day(s)</small>
</div>
</div>
<?php
$templateFieldSet = array_flip($template_fields ?? []);

View File

@ -1,6 +1,15 @@
<?php
$doctorRegNo = '';
$doctorHprId = '';
$hospitalDefaultOpdDays = (int) ($hospital_default_opd_valid_no_days ?? 5);
if ($hospitalDefaultOpdDays < 1) {
$hospitalDefaultOpdDays = 5;
}
$existingDoctorOpdDays = (! empty($data) && ! empty($data[0])) ? (int) ($data[0]->opd_valid_no_days ?? 0) : 0;
$doctorOpdValidNoDays = (int) ($doctor_opd_valid_no_days ?? ($existingDoctorOpdDays > 0 ? $existingDoctorOpdDays : $hospitalDefaultOpdDays));
if ($doctorOpdValidNoDays < 1) {
$doctorOpdValidNoDays = $hospitalDefaultOpdDays;
}
if (!empty($data) && !empty($data[0])) {
foreach (['nmc_reg_no', 'mci_reg_no', 'registration_no', 'reg_no', 'doctor_reg_no', 'doc_reg_no', 'council_reg_no'] as $regField) {
if (isset($data[0]->{$regField}) && trim((string) $data[0]->{$regField}) !== '') {
@ -97,6 +106,11 @@ if (!empty($data) && !empty($data[0]) && !empty($data[0]->dob)) {
<label class="form-label">Date of Birth</label>
<input class="form-control" name="datepicker_dob" value="<?= esc($doctorDobValue) ?>" type="date" />
</div>
<div class="col-md-3">
<label class="form-label">OPD Validity (Days)</label>
<input class="form-control" name="input_opd_valid_no_days" placeholder="5" type="number" min="1" max="365" value="<?= esc((string) $doctorOpdValidNoDays) ?>" />
<small class="text-muted">Default hospital value: <?= esc((string) $hospitalDefaultOpdDays) ?> day(s)</small>
</div>
</div>
<div class="row g-3 mt-1">
<div class="col-md-12">