diff --git a/app/Config/AuthGroups.php b/app/Config/AuthGroups.php index 011bbbf..bb7ed09 100644 --- a/app/Config/AuthGroups.php +++ b/app/Config/AuthGroups.php @@ -113,6 +113,7 @@ class AuthGroups extends ShieldAuthGroups 'beta.access' => 'Can access beta-level features', 'billing.access' => 'Can access billing module', 'opd.doctor-panel.access' => 'Can access OPD doctor work panel (doctor-only)', + 'media.image.preupload-edit' => 'Can rotate/crop images before upload (requires hospital setting ON)', 'billing.patient.edit-name-anytime' => 'Can edit patient name even after 24-hour restriction', 'billing.opd.edit' => 'Can edit OPD registrations', @@ -199,6 +200,7 @@ class AuthGroups extends ShieldAuthGroups 'users.*', 'beta.*', 'billing.*', + 'media.image.preupload-edit', 'opd.doctor-panel.access', 'settings.bed_status.view', 'settings.charges.access', @@ -221,6 +223,7 @@ class AuthGroups extends ShieldAuthGroups 'users.delete', 'beta.access', 'billing.*', + 'media.image.preupload-edit', 'billing.patient.edit-name-anytime', 'opd.doctor-panel.access', 'settings.bed_status.view', @@ -244,6 +247,7 @@ class AuthGroups extends ShieldAuthGroups 'users.edit', 'beta.access', 'billing.*', + 'media.image.preupload-edit', 'opd.doctor-panel.access', 'settings.bed_status.view', 'settings.charges.access', diff --git a/app/Controllers/Opd.php b/app/Controllers/Opd.php index ce23dfb..e90db23 100644 --- a/app/Controllers/Opd.php +++ b/app/Controllers/Opd.php @@ -2934,6 +2934,7 @@ class Opd extends BaseController if (!empty($data['rx_advices']) && is_array($data['rx_advices'])) { $parts = []; $partsLocal = []; + $partsPreferred = []; foreach ($data['rx_advices'] as $adv) { $txt = trim((string) ($adv['advice_txt'] ?? $adv['advice'] ?? '')); if ($txt !== '') { @@ -2945,10 +2946,51 @@ class Opd extends BaseController if ($localTxt !== '') { $partsLocal[] = $localTxt; } + + $preferredTxt = $localTxt !== '' ? $localTxt : $txt; + if ($preferredTxt !== '') { + $partsPreferred[] = $preferredTxt; + } } - if ($rxAdvice === '' && !empty($parts)) { - $rxAdvice = implode(', ', array_values(array_unique($parts))); + // Build final printable advice as: typed advice + selected advice + // (selected uses Hindi when available, else English), with de-duplication. + $typedAdviceLines = []; + $typedRaw = trim((string) $rxAdvice); + if ($typedRaw !== '') { + $typedRaw = str_replace(["\r\n", "\r"], "\n", $typedRaw); + $typedAdviceLines = array_values(array_filter(array_map( + static fn(string $v): string => trim($v), + explode("\n", $typedRaw) + ), static fn(string $v): bool => $v !== '')); + } + + $selectedPreferred = !empty($partsPreferred) + ? array_values(array_unique($partsPreferred)) + : array_values(array_unique($parts)); + + $seen = []; + $combined = []; + foreach ($typedAdviceLines as $line) { + $key = mb_strtolower(trim($line)); + if ($key === '' || isset($seen[$key])) { + continue; + } + $seen[$key] = true; + $combined[] = $line; + } + foreach ($selectedPreferred as $line) { + $line = trim((string) $line); + $key = mb_strtolower($line); + if ($key === '' || isset($seen[$key])) { + continue; + } + $seen[$key] = true; + $combined[] = $line; + } + + if (!empty($combined)) { + $rxAdvice = implode("\n", $combined); } if (!empty($partsLocal)) { @@ -2986,9 +3028,6 @@ class Opd extends BaseController $complaintLocal = $this->translateToLocalPatientText($complaintText); $diagnosisLocal = $this->translateToLocalPatientText($diagnosisText); $investigationLocal = $this->translateToLocalPatientText($rxInvestigation); - if ($rxAdviceLocal === '') { - $rxAdviceLocal = $this->translateToLocalPatientText($rxAdvice); - } if (strtolower(trim($complaintLocal)) === strtolower(trim($complaintText))) { $complaintLocal = ''; @@ -4200,18 +4239,10 @@ class Opd extends BaseController $tokens['RemarksBlock'] = (string) ($tokens['Prescriber_Remarks'] ?? ''); $adviceBlockBody = trim((string) ($tokens['advice'] ?? '')); $adviceBlockLocal = trim((string) ($tokens['advice_local'] ?? '')); - if ($adviceBlockBody !== '' || $adviceBlockLocal !== '') { - $adviceBlockLines = []; - if ($adviceBlockBody !== '') { - $adviceBlockLines[] = 'Advice : ' . $adviceBlockBody; - } - if ($adviceBlockLocal !== '') { - $adviceBlockLines[] = 'सलाह : ' . $adviceBlockLocal; - } - $tokens['AdviceBlock'] = implode('
', $adviceBlockLines); - } else { - $tokens['AdviceBlock'] = ''; - } + $adviceBlockPreferred = $adviceBlockBody !== '' ? $adviceBlockBody : $adviceBlockLocal; + $tokens['AdviceBlock'] = $adviceBlockPreferred !== '' + ? ('Advice : ' . $adviceBlockPreferred) + : ''; $tokens['NextVisitBlock'] = (string) ($tokens['next_visit'] ?? ''); $tokens['RxTable'] = $medicalHtml; @@ -4296,7 +4327,8 @@ class Opd extends BaseController $tokens['content'] = (string) ($tokens['content'] ?? ''); $adviceLocal = trim((string) ($tokens['advice_local'] ?? '')); - $tokens['advice_local_line'] = $adviceLocal !== '' + $adviceMain = trim((string) ($tokens['advice'] ?? '')); + $tokens['advice_local_line'] = ($adviceMain === '' && $adviceLocal !== '') ? ('
सलाह: ' . $adviceLocal) : ''; @@ -6062,10 +6094,15 @@ class Opd extends BaseController $personInfo[0]->age = get_age_1($personInfo[0]->dob ?? null, $personInfo[0]->age ?? '', $personInfo[0]->age_in_month ?? '', $personInfo[0]->estimate_dob ?? '', $opdRow->apointment_date ?? null); } + $hospitalEnabled = hospital_setting_value('ALLOW_IMAGE_PREUPLOAD_EDIT', '0') === '1'; + $user = function_exists('auth') ? auth()->user() : null; + $userAllowed = $user && method_exists($user, 'can') && $user->can('media.image.preupload-edit'); + return view('billing/opd_scan_modal_body', [ 'opdid' => $opdid, 'opd_master' => $opdMaster, 'person_info' => $personInfo, + 'allow_image_preupload_edit' => ($hospitalEnabled && $userAllowed) ? 1 : 0, ]); } diff --git a/app/Controllers/Patient.php b/app/Controllers/Patient.php index 9df1f65..fde5c2f 100644 --- a/app/Controllers/Patient.php +++ b/app/Controllers/Patient.php @@ -953,10 +953,14 @@ class Patient extends BaseController } $profileFilePath = $this->getProfileFilePath((int) ($patient->profile_file_id ?? 0)); + $hospitalEnabled = hospital_setting_value('ALLOW_IMAGE_PREUPLOAD_EDIT', '0') === '1'; + $user = function_exists('auth') ? auth()->user() : null; + $userAllowed = $user && method_exists($user, 'can') && $user->can('media.image.preupload-edit'); return view('billing/Patient_Profile_Image_V', [ 'patient' => $patient, 'profileFilePath' => $profileFilePath, + 'allow_image_preupload_edit' => ($hospitalEnabled && $userAllowed) ? 1 : 0, ]); } diff --git a/app/Controllers/Setting/HospitalProfile.php b/app/Controllers/Setting/HospitalProfile.php index 799d492..634f8b8 100644 --- a/app/Controllers/Setting/HospitalProfile.php +++ b/app/Controllers/Setting/HospitalProfile.php @@ -38,6 +38,7 @@ class HospitalProfile extends BaseController 'sidebar_auto_hide_seconds' => $this->readSettingValue('SIDEBAR_AUTO_HIDE_SECONDS') !== '' ? $this->readSettingValue('SIDEBAR_AUTO_HIDE_SECONDS') : '7', + 'allow_image_preupload_edit' => $this->readSettingValue('ALLOW_IMAGE_PREUPLOAD_EDIT') === '1' ? '1' : '0', ]); } @@ -69,6 +70,7 @@ class HospitalProfile extends BaseController $pharmacyGst = trim((string) $this->request->getPost('pharmacy_gst')); $sidebarAutoHideSecondsRaw = trim((string) $this->request->getPost('sidebar_auto_hide_seconds')); $sidebarAutoHideSeconds = $sidebarAutoHideSecondsRaw === '' ? 7 : (int) $sidebarAutoHideSecondsRaw; + $allowImagePreuploadEdit = $this->request->getPost('allow_image_preupload_edit') === '1' ? '1' : '0'; if ($name === '' || $address === '') { return $this->response->setJSON([ @@ -134,6 +136,9 @@ class HospitalProfile extends BaseController if ($this->upsertSettingValue('SIDEBAR_AUTO_HIDE_SECONDS', (string) $sidebarAutoHideSeconds)) { $savedCount++; } + if ($this->upsertSettingValue('ALLOW_IMAGE_PREUPLOAD_EDIT', $allowImagePreuploadEdit)) { + $savedCount++; + } $logoResult = $this->processLogoUpload( $this->request->getFile('hospital_logo'), @@ -244,6 +249,7 @@ class HospitalProfile extends BaseController 'H_Med_GST', 'H_Med_logo', 'SIDEBAR_AUTO_HIDE_SECONDS', + 'ALLOW_IMAGE_PREUPLOAD_EDIT', ])->delete(); if ($logo !== '') { diff --git a/app/Views/Setting/Admin/hospital_profile.php b/app/Views/Setting/Admin/hospital_profile.php index 032c1a5..bb30e18 100644 --- a/app/Views/Setting/Admin/hospital_profile.php +++ b/app/Views/Setting/Admin/hospital_profile.php @@ -41,6 +41,14 @@
Desktop only. Set 0 to disable auto-hide.
+
+ +
+ > + +
+
Global master switch. User must also be granted permission media.image.preupload-edit from User Management → Give Permissions.
+
@@ -159,6 +167,7 @@ fd.append('hospital_hfr_id', ($('#hospital_hfr_id').val() || '').trim()); fd.append('footer_version', ($('#footer_version').val() || '').trim()); fd.append('sidebar_auto_hide_seconds', ($('#sidebar_auto_hide_seconds').val() || '').trim()); + fd.append('allow_image_preupload_edit', $('#allow_image_preupload_edit').is(':checked') ? '1' : '0'); fd.append('pharmacy_name', ($('#pharmacy_name').val() || '').trim()); fd.append('pharmacy_address', ($('#pharmacy_address').val() || '').trim()); fd.append('pharmacy_phone', ($('#pharmacy_phone').val() || '').trim()); @@ -275,6 +284,7 @@ $('#hospital_hfr_id').val(''); $('#footer_version').val(''); $('#sidebar_auto_hide_seconds').val('7'); + $('#allow_image_preupload_edit').prop('checked', false); $('#pharmacy_name').val(''); $('#pharmacy_address').val(''); $('#pharmacy_phone').val(''); diff --git a/app/Views/billing/Patient_Profile_Image_V.php b/app/Views/billing/Patient_Profile_Image_V.php index 3d7bc6d..b2a95d4 100644 --- a/app/Views/billing/Patient_Profile_Image_V.php +++ b/app/Views/billing/Patient_Profile_Image_V.php @@ -29,7 +29,16 @@
- + +
+
+ +
+ + +
@@ -37,6 +46,7 @@
+
Camera: detecting resolution...
Camera is idle.
@@ -57,14 +67,14 @@
-
- +
@@ -92,31 +102,272 @@
+ +