diff --git a/controllers/C_Prescription.class.php b/controllers/C_Prescription.class.php index c264f79cb66..b2a34107ed8 100644 --- a/controllers/C_Prescription.class.php +++ b/controllers/C_Prescription.class.php @@ -18,9 +18,12 @@ require_once($GLOBALS['fileroot'] . "/library/amc.php"); use OpenEMR\Common\Csrf\CsrfUtils; +use OpenEMR\Common\Forms\FormActionBarSettings; use OpenEMR\Common\Http\oeHttp; use OpenEMR\Rx\RxList; use PHPMailer\PHPMailer\PHPMailer; +use OpenEMR\Common\Database\QueryUtils; +use OpenEMR\Common\Twig\TwigContainer; class C_Prescription extends Controller { @@ -36,7 +39,6 @@ function __construct($template_mod = "general") { parent::__construct(); $this->template_mod = $template_mod; - $this->assign("FORM_ACTION", $GLOBALS['webroot'] . "/controller.php?" . attr($_SERVER['QUERY_STRING'])); $this->assign("TOP_ACTION", $GLOBALS['webroot'] . "/controller.php?" . "prescription" . "&"); $this->assign("STYLE", $GLOBALS['style']); $this->assign("WEIGHT_LOSS_CLINIC", $GLOBALS['weight_loss_clinic']); @@ -100,8 +102,21 @@ function __construct($template_mod = "general") function default_action() { - $this->assign("prescription", $this->prescriptions[0]); - $this->display($GLOBALS['template_dir'] . "prescription/" . $this->template_mod . "_edit.html"); + $prescription = $this->prescriptions[0]; + $this->assign("prescription", $prescription); + $vars = $this->getTemplateVars(); + $vars['enable_amc_prompting'] = $GLOBALS['enable_amc_prompting'] ?? false; + $vars['weno_rx_enable'] = $GLOBALS['weno_rx_enable'] ?? false; + $vars['topActionBarDisplay'] = FormActionBarSettings::shouldDisplayTopActionBar(); + $vars['bottomActionBarDisplay'] = FormActionBarSettings::shouldDisplayBottomActionBar(); + + if ($GLOBALS['enable_amc_prompting']) { + $vars['amcCollectReturnFlag'] = amcCollect('e_prescribe_amc', $prescription->patient->id, 'prescriptions', $prescription->id); + $vars['amcCollectReturnFormulary'] = amcCollect('e_prescribe_chk_formulary_amc', $prescription->patient->id, 'prescriptions', $prescription->id); + $vars['amcCollectReturnControlledSubstances'] = amcCollect('e_prescribe_cont_subst_amc', $prescription->patient->id, 'prescriptions', $prescription->id); + } + $twig = (new TwigContainer(null, $GLOBALS['kernel']))->getTwig(); + echo $twig->render("prescription/" . $this->template_mod . "_edit.html.twig", $vars); } function edit_action($id = "", $patient_id = "", $p_obj = null) @@ -189,7 +204,25 @@ function list_action($id, $sort = "") // flag to indicate the CAMOS form is regsitered and active $this->assign("CAMOS_FORM", isRegistered("CAMOS")); - $this->display($GLOBALS['template_dir'] . "prescription/" . $this->template_mod . "_list.html"); + $vars = $this->getTemplateVars(); + $vars['pid'] = $id; + $vars['rx_send_email'] = $GLOBALS['rx_send_email'] ?? false; + $vars['rx_show_drug_drug'] = $GLOBALS['rx_show_drug_drug'] ?? false; + $vars['rx_zend_pdf_template'] = $GLOBALS['rx_zend_pdf_template'] ?? false; + $vars['baseModDir'] = $GLOBALS['baseModDir'] ?? ''; + $vars['zendModDir'] = $GLOBALS['zendModDir'] ?? ''; + $vars['printm'] = null; // TODO: figure out where printm is used or defined + $vars['rx_zend_pdf_action'] = $GLOBALS['rx_zend_pdf_action'] ?? ''; + $vars['rx_zend_html_template'] = $GLOBALS['rx_zend_html_template'] ?? ''; + $vars['rx_zend_html_action'] = $GLOBALS['rx_zend_pdf_action'] ?? ''; + $vars['rx_use_fax_template'] = $GLOBALS['rx_use_fax_template'] ?? ''; + $vars['rx_send_email'] = $GLOBALS['rx_send_email'] ?? false; + $vars['faxSignatureMissing'] = false; + if (!($this->pconfig['use_signature'] && $this->current_user_has_signature())) { + $vars['faxSignatureMissing'] = true; + } + $twig = (new TwigContainer(null, $GLOBALS['kernel']))->getTwig(); + echo $twig->render("prescription/" . $this->template_mod . "_list.html.twig", $vars); } function block_action($id, $sort = "") @@ -209,6 +242,14 @@ function block_action($id, $sort = "") $this->display($GLOBALS['template_dir'] . "prescription/" . $this->template_mod . "_block.html"); } + /** + * TODO: remove this function in a future expansion. + * @deprecated As far as we can see this function isn't used + * @param $id + * @param $sort + * @return void + * @throws SmartyException + */ function fragment_action($id, $sort = "") { if (empty($id)) { @@ -228,6 +269,7 @@ function fragment_action($id, $sort = "") function lookup_action() { + $this->assign("FORM_ACTION", $GLOBALS['webroot'] . "/controller.php?" . attr($_SERVER['QUERY_STRING'])); $this->do_lookup(); $this->display($GLOBALS['template_dir'] . "prescription/" . $this->template_mod . "_lookup.html"); } @@ -297,39 +339,10 @@ function edit_action_process() processAmcCall('e_prescribe_cont_subst_amc', true, 'remove', $this->prescriptions[0]->get_patient_id(), 'prescriptions', $this->prescriptions[0]->id); } -// TajEmo Work by CB 2012/05/29 02:58:29 PM to stop from going to send screen. Improves Work Flow -// if ($this->prescriptions[0]->get_active() > 0) { -// return $this->send_action($this->prescriptions[0]->id); -// } $this->list_action($this->prescriptions[0]->get_patient_id()); exit; } - function send_action($id) - { - $_POST['process'] = "true"; - if (empty($id)) { - $this->function_argument_error(); - } - - $rx = new Prescription($id); - // Populate pharmacy info if the patient has a default pharmacy. - // Probably the Prescription object should handle this instead, but - // doing it there will require more careful research and testing. - $prow = sqlQuery("SELECT pt.pharmacy_id FROM prescriptions AS rx, " . - "patient_data AS pt WHERE rx.id = ? AND pt.pid = rx.patient_id", [$id]); - if ($prow['pharmacy_id']) { - $rx->pharmacy->set_id($prow['pharmacy_id']); - $rx->pharmacy->populate(); - } - - $this->assign("prescription", $rx); - - $this->_state = false; - return $this->fetch($GLOBALS['template_dir'] . "prescription/" . - $this->template_mod . "_send.html"); - } - function multiprintfax_header(&$pdf, $p) { return $this->multiprint_header($pdf, $p); @@ -551,14 +564,29 @@ function multiprintfax_footer(&$pdf) return $this->multiprint_footer($pdf); } + function current_user_has_signature() + { + if (!empty($this->pconfig['signature'])) { + $sigfile = str_replace('{userid}', $_SESSION["authUser"], $this->pconfig['signature']); + if (file_exists($sigfile)) { + return true; + } + } + return false; + } + function multiprint_footer(&$pdf) { - if ($this->pconfig['use_signature'] && ( $this->is_faxing || $this->is_print_to_fax )) { + if ( + $this->pconfig['use_signature'] + && $this->current_user_has_signature() + && ( $this->is_faxing || $this->is_print_to_fax ) + ) { $sigfile = str_replace('{userid}', $_SESSION["authUser"], $this->pconfig['signature']); if (file_exists($sigfile)) { $pdf->ezText(xl('Signature') . ": ", 12); - // $pdf->ezImage($sigfile, "", "", "none", "left"); - $pdf->ezImage($sigfile, "", "", "none", "center"); + $width = 0; // set to 0 so it uses the image width + $pdf->ezImage($sigfile, null, 0, "none", "center"); $pdf->ezText(xl('Date') . ": " . date('Y-m-d'), 12); if ($this->is_print_to_fax) { $pdf->ezText(xl('Please do not accept this prescription unless it was received via facsimile.')); @@ -688,40 +716,157 @@ function multiprint_action($id = "") $this->function_argument_error(); } - $pdf = new Cezpdf($GLOBALS['rx_paper_size']); - $pdf->ezSetMargins($GLOBALS['rx_top_margin'], $GLOBALS['rx_bottom_margin'], $GLOBALS['rx_left_margin'], $GLOBALS['rx_right_margin']); - $pdf->selectFont('Helvetica'); + list($pdf, $patient) = $this->generatePdfObjectForPrescriptionIds($id); - // $print_header = true; - $on_this_page = 0; + $pFirstName = $patient->fname; //modified by epsdky for prescription filename change to include patient name and ID + $pFName = convert_safe_file_dir_name($pFirstName); + $modedFileName = "Rx_{$pFName}_{$patient->id}.pdf"; + $pdf->ezStream(array('Content-Disposition' => $modedFileName)); + return; + } - //print prescriptions body - $this->_state = false; // Added by Rod - see Controller.class.php - $ids = preg_split('/::/', substr($id, 1, strlen($id) - 2), -1, PREG_SPLIT_NO_EMPTY); + function multiprintplain_header($p) + { + $this->providerid = $p->provider->id; + $sql = "SELECT f.name, f.street, f.state, f.postal_code, f.phone, if(f.fax != '', f.fax, '') FROM users JOIN facility AS f ON f.name = users.facility where users.id = ?"; + $result = QueryUtils::fetchRecords($sql, [$p->provider->id]); + $address = ''; + if (!empty($result)) { + $res = $result[0]; + $parts = []; + $parts[] = $res['name']; + $parts[] = $res['street']; + if (!empty($res['city'])) { + $parts[] = $res['city'] ?? '' . ', ' . $res['state'] ?? '' . ' ' . $res['postal_code'] ?? ''; + } else if (!empty($res['state']) && !empty($res['postal_code'])) { + $parts[] = $res['state'] ?? '' . ' ' . $res['postal_code'] ?? ''; + } + if (!empty($res['phone'])) { + $parts[] = xl('Tel:') . $res['phone'] ?? ''; + } + if (!empty($res['fax'])) { + $parts[] = xl('Fax:') . $res['fax'] ?? ''; + } + $address = implode("\n", $parts); + if (trim($address) == "") { + $address = ""; + } + } + echo xl("Digital Prescription Information") . "\n"; + echo xl("Prescriber") . "\n"; + echo $address; + echo ("\n"); + echo ("\n"); + echo ($p->provider->get_name_display()) . "\n"; + + if ($GLOBALS['rx_enable_DEA']) { + if ($GLOBALS['rx_show_DEA']) { + echo (xl('DEA') . ':' . $p->provider->federal_drug_id . "\n"); + } else { + echo (xl('DEA') . ": ________________________\n" ); + } + } + + if ($GLOBALS['rx_enable_NPI']) { + if ($GLOBALS['rx_show_NPI']) { + echo (xl('NPI') . ':' . $p->provider->npi . '') . "\n"; + } else { + echo ('' . xl('NPI') . ": ________________________\n"); + } + } + + if ($GLOBALS['rx_enable_SLN']) { + if ($GLOBALS['rx_show_SLN']) { + echo (xl('State Lic. #') . ':' . $p->provider->state_license_number . "\n"); + } else { + echo (xl('State Lic. #') . ": ________________________\n"); + } + } + echo "\n\n"; + echo (xl('Patient Name & Address') . "\n"); + echo ($p->patient->get_name_display() . "\n"); + $sql = "SELECT street, city, `state`, postal_code, if(phone_home!='',phone_home,if(phone_cell!='',phone_cell,if(phone_biz!='',phone_biz,''))) AS phone from patient_data where pid = ?"; + $result = QueryUtils::fetchRecords($sql, [$p->patient->id]); + $address = ''; + if (!empty($result)) { + $res = $result[0]; + $parts = []; + $parts[] = $res['street']; + if (!empty($res['city'])) { + $parts[] = $res['city'] ?? '' . ', ' . $res['state'] ?? '' . ' ' . $res['postal_code'] ?? ''; + } else if (!empty($res['state']) && !empty($res['postal_code'])) { + $parts[] = $res['state'] ?? '' . ' ' . $res['postal_code'] ?? ''; + } + + if (!empty($res['phone'])) { + $parts[] = xl('Tel:') . $res['phone'] ?? ''; + } + $address = implode("\n", $parts); + $address = trim($address); + } + + echo ($address); + echo "\n"; + echo (xl('Date of Birth')) . " "; + echo ($p->patient->date_of_birth ); + echo "\n"; + echo xl('Medical Record #'); + echo (str_pad($p->patient->get_pubpid(), 10, "0", STR_PAD_LEFT)); + echo "\n\n"; + echo xl('Prescriptions') . "\n"; + } + + + function multiprintplain_footer() + { + echo xl('Signature') . ":________________________________\n"; + echo xl('Date') . ": " . date('Y-m-d') . "\n"; + } + + + /** + * Outputs a JSON response of the subject and message body for the prescription contents to go into a native + * email client. Useful if you want to use the native mailto: handler in the browser or user-agent's operating system. + * @return void + */ + function getDefaultMailClientText_action() + { + $idsGet = $_GET['ids']; + + if (empty($idsGet)) { + $this->function_argument_error(); + return; + } + ob_start(); + + $ids = preg_split('/::/', substr($idsGet, 1, strlen($idsGet) - 2), -1, PREG_SPLIT_NO_EMPTY); + + $on_this_page = 0; foreach ($ids as $id) { $p = new Prescription($id); - // if ($print_header == true) { if ($on_this_page == 0) { - $this->multiprint_header($pdf, $p); + $this->multiprintplain_header($p); } if (++$on_this_page > 3 || $p->provider->id != $this->providerid) { - $this->multiprint_footer($pdf); - $pdf->ezNewPage(); - $this->multiprint_header($pdf, $p); - // $print_header = false; + $this->multiprintplain_footer(); + $this->multiprintplain_header($p); $on_this_page = 1; } - $this->multiprint_body($pdf, $p); + // we don't want any html in the plain text rendering + echo strip_tags($this->get_prescription_body_text($p)); } - $this->multiprint_footer($pdf); - - $pFirstName = $p->patient->fname; //modified by epsdky for prescription filename change to include patient name and ID - $pFName = convert_safe_file_dir_name($pFirstName); - $modedFileName = "Rx_{$pFName}_{$p->patient->id}.pdf"; - $pdf->ezStream(array('Content-Disposition' => $modedFileName)); + $this->multiprintplain_footer(); + $data = ob_get_clean(); + $result = [ + 'subject' => $GLOBALS['openemr_name'] . " " . xl(" Prescription ") + ,'message' => $data + ]; + http_response_code(200); + header("Content-Type:" . "application/json"); + echo json_encode($result); return; } @@ -758,73 +903,21 @@ function multiprintcss_action($id = "") return; } - function send_action_process($id) + function send_action_process() { $dummy = ""; // Added by Rod to avoid run-time warnings if ($_POST['process'] != "true") { return; } + $id = $_POST['sendEmailPrescriptionIds']; if (empty($id)) { $this->function_argument_error(); } + $sendAsPDF = intval($_POST['sendAsPdf'] ?? 0) == 1; - $p = new Prescription($id); - switch ($_POST['submit']) { - case (xl("Print") . " (" . xl("PDF") . ")"): - // The following statement added by Rod. - // Looking at Controller.class.php, it appears that _state is set to false - // to indicate that no further HTML is to be generated. - $this->_state = false; // Added by Rod - see Controller.class.php - return $this->print_prescription($p, $dummy); - break; - case (xl("Print") . " (" . xl("HTML") . ")"): - $this->_state = false; - return $this->print_prescription_css($p, $dummy); - break; - case xl("Print To Fax"): - $this->_state = false; - $this->is_print_to_fax = true; - return $this->print_prescription($p, $dummy); - break; - case xl("Email"): - return $this->email_prescription($p, $_POST['email_to']); - break; - case xl("Fax"): - //this is intended to be the hook for the hylafax code we already have that hasn't worked its way into the tree yet. - //$this->assign("process_result","No fax server is currently setup."); - return $this->fax_prescription($p, $_POST['fax_to']); - break; - case xl("Auto Send"): - $pharmacy_id = $_POST['pharmacy_id']; - //echo "auto sending to : " . $_POST['pharmacy_id']; - $phar = new Pharmacy($_POST['pharmacy_id']); - //print_r($phar); - if ($phar->get_transmit_method() == TRANSMIT_PRINT) { - return $this->print_prescription($p, $dummy); - } elseif ($phar->get_transmit_method() == TRANSMIT_EMAIL) { - $email = $phar->get_email(); - if (!empty($email)) { - return $this->email_prescription($p, $phar->get_email()); - } - - //else print it - } elseif ($phar->get_transmit_method() == TRANSMIT_FAX) { - $faxNum = $phar->get_fax(); - if (!empty($faxNum)) { - return $this->fax_prescription($p, $faxNum); - } - - // return $this->assign("process_result","No fax server is currently setup."); - // else default is printing, - } else { - //the pharmacy has no default or default is print - return $this->print_prescription($p, $dummy); - } - break; - } - - return; + $patient = $this->email_prescription($id, $_POST['email_to'], $sendAsPDF); + return $this->list_action($patient->id); } function print_prescription($p, &$toFile) @@ -863,56 +956,39 @@ function print_prescription_css($p, &$toFile) $this->multiprintcss_postfooter(); } - function print_prescription_old($p, &$toFile) - { - $pdf = new Cezpdf($GLOBALS['rx_paper_size']); - $pdf->ezSetMargins($GLOBALS['rx_top_margin'], $GLOBALS['rx_bottom_margin'], $GLOBALS['rx_left_margin'], $GLOBALS['rx_right_margin']); - $pdf->selectFont('Helvetica'); - if (!empty($this->pconfig['logo'])) { - $pdf->ezImage($this->pconfig['logo'], "", "", "none", "left"); - } - - $pdf->ezText($p->get_prescription_display(), 10); - if ($this->pconfig['use_signature']) { - $pdf->ezImage($this->pconfig['signature'], "", "", "none", "left"); - } else { - $pdf->ezText("\n\n\n\nSignature:________________________________", 10); - } - - if (!empty($toFile)) { - $toFile = $pdf->ezOutput(); - } else { - $pdf->ezStream(); - // $pdf->ezStream(array('compress' => 0)); // for testing with uncompressed output - } - - return; - } - - function email_prescription($p, $email) + function email_prescription($id, $email, $sendAsPdf) { if (empty($email)) { $this->assign("process_result", "Email could not be sent, the address supplied: '$email' was empty or invalid."); return; } - $mail = new PHPMailer(); - //this is a temporary config item until the rest of the per practice billing settings make their way in + $mail = new MyMailer(); + if ($sendAsPdf) { + list($pdf, $patient) = $this->generatePdfObjectForPrescriptionIds($id); + $pdfAsString = $pdf->output(); + $mailBody = $GLOBALS['openemr_name'] . " " . xl("Prescription attached to this email.") . " " . xl("Patient") . " " . $patient->get_name_display(); + } else { + list($mailBody, $patient) = $this->generateHtmlObjectForPrescriptionIds($id); + $mail->isHTML(true); + } + $mail->From = $GLOBALS['practice_return_email_path']; - $mail->FromName = $p->provider->get_name_display(); - $mail->isMail(); - $mail->Host = "localhost"; - $mail->Mailer = "mail"; - $text_body = $p->get_prescription_display(); - $mail->Body = $text_body; - $mail->Subject = "Prescription for: " . $p->patient->get_name_display(); +// $mail->FromName = $p->provider->get_name_display(); +// $text_body = $p->get_prescription_display(); + $mail->Body = $mailBody; + $mail->Subject = $GLOBALS['openemr_name'] . " " . xl("Prescription"); $mail->AddAddress($email); + if ($sendAsPdf) { + $mail->addStringAttachment($pdfAsString, 'Prescription-' . date("Y-m-d_H_i_s") . ".pdf"); + } + if ($mail->Send()) { $this->assign("process_result", "Email was successfully sent to: " . $email); - return; + return $patient; } else { $this->assign("process_result", "There has been a mail error sending to " . $_POST['email_to'] . " " . $mail->ErrorInfo); - return; + return $patient; } } @@ -994,4 +1070,54 @@ function fax_prescription($p, $faxNum) $this->assign("process_result", $err); } } + + /** + * @param mixed $id + * @return array + */ + private function generatePdfObjectForPrescriptionIds(mixed $id): array + { + $pdf = new Cezpdf($GLOBALS['rx_paper_size']); + $pdf->ezSetMargins($GLOBALS['rx_top_margin'], $GLOBALS['rx_bottom_margin'], $GLOBALS['rx_left_margin'], $GLOBALS['rx_right_margin']); + $pdf->selectFont('Helvetica'); + + // $print_header = true; + $on_this_page = 0; + + //print prescriptions body + $this->_state = false; // Added by Rod - see Controller.class.php + $ids = preg_split('/::/', substr($id, 1, strlen($id) - 2), -1, PREG_SPLIT_NO_EMPTY); + foreach ($ids as $id) { + $p = new Prescription($id); + // if ($print_header == true) { + if ($on_this_page == 0) { + $this->multiprint_header($pdf, $p); + } + + if (++$on_this_page > 3 || $p->provider->id != $this->providerid) { + $this->multiprint_footer($pdf); + $pdf->ezNewPage(); + $this->multiprint_header($pdf, $p); + // $print_header = false; + $on_this_page = 1; + } + + $this->multiprint_body($pdf, $p); + } + + $this->multiprint_footer($pdf); + return array($pdf, $p->patient); + } + + private function generateHtmlObjectForPrescriptionIds($id) + { + ob_start(); + $this->multiprintcss_action($id); + $html = ob_get_clean(); + $ids = preg_split('/::/', substr($id, 1, strlen($id) - 2), -1, PREG_SPLIT_NO_EMPTY); + if (!empty($ids)) { + $prescription = new Prescription($ids[0]); + } + return [$html, $prescription->patient]; + } } diff --git a/interface/forms/eye_mag/js/eye_base.php b/interface/forms/eye_mag/js/eye_base.php index c3d8c1d14a9..39011a48a3a 100644 --- a/interface/forms/eye_mag/js/eye_base.php +++ b/interface/forms/eye_mag/js/eye_base.php @@ -1033,17 +1033,15 @@ function editScripts(url) { let w = 810; w = 910; - dlgopen(url, 'editScripts', w, 300, '', '', { - buttons: [ - {text: 'Add', close: false, style: 'primary btn-sm', click: AddScript}, - {text: 'List', close: false, style: 'primary btn-sm', click: ListScripts}, - {text: 'Done', close: true, style: 'default btn-sm'} - ], - onClosed: 'refreshme', + dlgopen(url, 'editScripts', w, 400, '', '', { + resolvePromiseOn: 'close', allowResize: true, allowDrag: true, dialogId: 'editscripts', type: 'iframe' + }).then(() => { + top.restoreSession(); + location.reload(); }); } diff --git a/interface/patient_file/encounter/coding.php b/interface/patient_file/encounter/coding.php index 03ce3c29f87..29dfcf0a9ff 100644 --- a/interface/patient_file/encounter/coding.php +++ b/interface/patient_file/encounter/coding.php @@ -1,6 +1,7 @@ /controller.php?prescription&edit&id=0&pid=' + ; - }; - var ListScripts = function () { - var __this = $(this); - __this.find("#clearButton").css("display", "none"); - __this.find("#backButton").css("display", "none"); - __this.find("#addButton").css("display", ""); - var iam = top.frames.editScripts - iam.location.href = '/controller.php?prescription&list&id=' + ; - }; let title = ; let w = 960; // for weno width dlgopen(url, 'editScripts', w, 400, '', '', { - buttons: [{ - text: , - close: false, - id: 'addButton', - class: 'btn-primary btn-sm', - click: AddScript - }, - { - text: , - close: false, - id: 'clearButton', - style: 'display:none;', - class: 'btn-primary btn-sm', - click: AddScript - }, - { - text: , - close: false, - id: 'backButton', - style: 'display:none;', - class: 'btn-primary btn-sm', - click: ListScripts - }, - { - text: , - close: true, - id: 'doneButton', - class: 'btn-secondary btn-sm' - } - ], - onClosed: 'refreshme', + resolvePromiseOn: 'close', allowResize: true, allowDrag: true, dialogId: 'editscripts', type: 'iframe' - }); + }) + .then(() => refreshme()); return false; } diff --git a/interface/patient_file/summary/demographics_full.php b/interface/patient_file/summary/demographics_full.php index e1d0bf2aa37..0eaeb771d91 100644 --- a/interface/patient_file/summary/demographics_full.php +++ b/interface/patient_file/summary/demographics_full.php @@ -21,6 +21,7 @@ require_once("$srcdir/patient.inc.php"); use OpenEMR\Common\Acl\AclMain; +use OpenEMR\Common\Forms\FormActionBarSettings; use OpenEMR\Common\Csrf\CsrfUtils; use OpenEMR\Core\Header; use OpenEMR\Events\PatientDemographics\UpdateEvent; @@ -418,6 +419,7 @@ function validate(f) {
+

@@ -432,6 +434,11 @@ function validate(f) {

+ +
+

+
+ + +
+
+
+
+
+ + + + +
+
+
+
+
diff --git a/library/globals.inc.php b/library/globals.inc.php index c9cf54aea73..ec939e5c0c7 100644 --- a/library/globals.inc.php +++ b/library/globals.inc.php @@ -76,6 +76,7 @@ // Uzbek // xl('Uzbek') // Vietnamese // xl('Vietnamese') +use OpenEMR\Common\Forms\FormActionBarSettings; use OpenEMR\Events\Globals\GlobalsInitializedEvent; use OpenEMR\OeUI\RenderFormFieldHelper; use OpenEMR\Services\Globals\GlobalsService; @@ -433,6 +434,13 @@ function gblTimeZones() xl('Recommended setting is warn and prevent web browser refresh. Only use other settings if needed and use at own risk.') ), + 'form_actionbar_position' => array( + xl('Form ActionBar (save, cancel, etc) position') + ,FormActionBarSettings::getGlobalSettingsList() + ,FormActionBarSettings::getDefaultSetting() // default = top of the form + ,xl('Placement of the save/cancel, and other bottons where supported (Demographics, Encounter Forms, etc).') + ), + ), 'Branding' => [ @@ -3804,6 +3812,12 @@ function gblTimeZones() 'default', xl('Name of zend template for pdf export, possible to add custom template in the PrescriptionTemplate module') ), + 'rx_send_email' => array( + xl('Allow email sending of prescriptions'), + 'bool', // data type + '1', + xl('Enable email option (available on prescriptions list screen) for emailing prescriptions') + ), ), 'PDF' => array( 'pdf_layout' => array( diff --git a/src/Common/Forms/FormActionBarSettings.php b/src/Common/Forms/FormActionBarSettings.php new file mode 100644 index 00000000000..1b737c4c8c5 --- /dev/null +++ b/src/Common/Forms/FormActionBarSettings.php @@ -0,0 +1,37 @@ + xl('Top of Form (default)') + ,self::ACTION_BAR_DISPLAY_FORM_BOTTOM => xl('Bottom of Form') +// ,self::ACTION_BAR_DISPLAY_FORM_TOP_AND_BOTTOM => xl('Top and Bottom of Form') + ); + } + + public static function getDefaultSetting() + { + return self::ACTION_BAR_DISPLAY_FORM_TOP; + } + + public static function shouldDisplayTopActionBar() + { + // probably could make this more efficient by doing integer position comparisons, but the global values are stored as strings... + return $GLOBALS['form_actionbar_position'] == self::ACTION_BAR_DISPLAY_FORM_TOP + || $GLOBALS['form_actionbar_position'] == self::ACTION_BAR_DISPLAY_FORM_TOP_AND_BOTTOM; + } + public static function shouldDisplayBottomActionBar() + { + return $GLOBALS['form_actionbar_position'] == self::ACTION_BAR_DISPLAY_FORM_BOTTOM + || $GLOBALS['form_actionbar_position'] == self::ACTION_BAR_DISPLAY_FORM_TOP_AND_BOTTOM; + } +} diff --git a/templates/prescription/general_edit.html b/templates/prescription/general_edit.html.twig similarity index 52% rename from templates/prescription/general_edit.html rename to templates/prescription/general_edit.html.twig index 91ab7456d91..5685670fbb4 100644 --- a/templates/prescription/general_edit.html +++ b/templates/prescription/general_edit.html.twig @@ -1,4 +1,4 @@ -{** +{## * Prescription edit * * @package OpenEMR @@ -6,13 +6,11 @@ * @author Brady Miller * @copyright Copyright (c) 2017-2018 Brady Miller * @license https://github.com/openemr/openemr/blob/master/LICENSE GNU General Public License 3 - *} +#} - - {headerTemplate assets='datetime-picker|select2'} - + {{ setupHeader(['datetime-picker','datetime-picker-translated', 'select2']) }} @@ -318,7 +379,7 @@ }); - {if $GLOBALS.weno_rx_enable} + {% if weno_rx_enable %} $("#drug").select2({ ajax: { @@ -326,7 +387,7 @@ dataType: 'json', data: function(params) { return { - csrf_token_form: {$CSRF_TOKEN_FORM|js_escape}, + csrf_token_form: {{ CSRF_TOKEN_FORM|js_escape }}, term: params.term }; @@ -347,7 +408,7 @@ minimumInputLength: 3 } }); - {else} + {% else %} $("#drug").select2({ ajax: { @@ -355,7 +416,7 @@ dataType: 'json', data: function(params) { return { - csrf_token_form: {$CSRF_TOKEN_FORM|js_escape}, + csrf_token_form: {{ CSRF_TOKEN_FORM|js_escape }}, term: params.term, use_rxnorm: document.prescribe.rxcui_select[1].checked, @@ -379,13 +440,13 @@ tags: true, minimumInputLength: 3 }); - {/if} - {if $prescription->drug} + {% endif %} + {% if prescription.drug %} // Show the current drug name in the select - var newOption = new Option({$prescription->drug|js_escape}, {$prescription->drug|js_escape}, true, true); + var newOption = new Option({{prescription.drug|js_escape}}, {{prescription.drug|js_escape}}, true, true); $('#drug').append(newOption).trigger('change'); - {/if} + {% endif %} $("#drug").focus(); @@ -412,7 +473,7 @@ // for text boxes if ($('#'+objID).is('input')) { if ($('#'+objID).val() == "") { - alert({xlj t='Missing a required field and will be highlighted'}); + alert({{'Missing a required field and will be highlighted'|xlj}}); $('#'+objID).css("backgroundColor", "pink"); return false; } @@ -421,7 +482,7 @@ // for select boxes if ($('#'+objID).is('select')) { if ($('#'+objID).val() == "0") { - alert({xlj t='Missing a required field'}); + alert({{'Missing a required field'|xlj}}); $('#'+objID).css("backgroundColor", "pink"); return false; } @@ -442,7 +503,11 @@ }); $(function () { - {datetimepickerSupport input='format'} + datetimepickerTranslated('.datepicker', { + timepicker: false + , showSeconds: false + , formatInput: true + }); }); diff --git a/templates/prescription/general_list.html b/templates/prescription/general_list.html deleted file mode 100644 index 41489ab51db..00000000000 --- a/templates/prescription/general_list.html +++ /dev/null @@ -1,316 +0,0 @@ -{** - * Prescription list - * - * @package OpenEMR - * @link http://www.open-emr.org - * @author Brady Miller - * @author Sherwin Gaddis - * @copyright Copyright (c) 2017-2018 Brady Miller - * @copyright Copyright (c) 2018 Sherwin Gaddis - * @license https://github.com/openemr/openemr/blob/master/LICENSE GNU General Public License 3 - *} - - - -{headerTemplate assets='no_textformat|no_dialog'} - - - - - - - -
-
- {if $prescriptions} -
-

{xlt t='List'}

-
-
-
- {if $GLOBALS.rx_zend_pdf_template} - {xlt t='Download'} ({xlt t='PDF'}) - {else} - {xlt t='Download'} ({xl t='PDF'}) - {/if} - {if $GLOBALS.rx_zend_html_template} - {xl t='View Printable Version'|text} ({xlt t='HTML'}) - {else} - - {xlt t='View Printable Version'} ({xlt t='HTML'}) - {/if} - {if $GLOBALS.rx_use_fax_template} - {xlt t='Download'} ({xlt t='Fax'}) - {/if} - {if $CAMOS_FORM == true} - {xlt t='View Four Panel'} - {/if} -
- -
-
-
-
-
- - - - - - - - - - - - - - - - - - - {foreach from=$prescriptions item=prescription} - - - - {if empty($prescription->erx_source) || $prescription->erx_source==0} - - - {else} - - - {/if} - - - - {if empty($prescription->erx_source) || $prescription->erx_source==0} - - {else} - - {/if} - - - - - - {/foreach} - -
  {xlt t='Drug'}{xlt t='RxNorm'}{xlt t='Created'}
{xlt t='Changed'}
{xlt t='Dosage'}{xlt t='Qty'}.{xlt t='Unit'}{xlt t='Refills'}{xlt t='Provider'}
- encounter) && $prescription->encounter == $prescription->get_encounter() && $prescription->active > 0}checked="checked" {/if}onclick="changeLinkHref('multiprint',this.checked, this.value);changeLinkHref('multiprintcss',this.checked, this.value);changeLinkHref('multiprintToFax',this.checked, this.value)" title="{xla t='Select for printing'}"> - - {xlt t='Edit'} - - - {if $prescription->active > 0}{/if}{$prescription->drug|text}{if $prescription->active > 0}{/if}  -
{$prescription->note|text} -
  - {if $prescription->active > 0}{/if}{$prescription->drug|text}{if $prescription->active > 0}{/if}  -
{$prescription->note|text} -
- {$prescription->rxnorm_drugcode|text}  - - {$prescription->date_added|oeFormatShortDate|text}
- {$prescription->date_modified|oeFormatShortDate|text}  -
- {$prescription->get_dosage_display()|text}   - - {$prescription->quantity|text}   - - {$prescription->quantity|text}   - - {$prescription->get_size()|text} {$prescription->get_unit_display()|text}  - - {$prescription->refills|text}   - - {$prescription->provider->get_name_display()|text}  - {xlt t='Delete'}
-
-
-
-
- {if $GLOBALS.rx_show_drug_drug} -
-
-

{xlt t='Drug-Drug Interaction'}

-

*{xlt t='Notice'}

-
- {$INTERACTION} -
-
-
- {/if} - - {else} -
{xlt t='There are currently no prescriptions'}.
- {/if} -
-
- - - - - diff --git a/templates/prescription/general_list.html.twig b/templates/prescription/general_list.html.twig new file mode 100644 index 00000000000..86be53fb126 --- /dev/null +++ b/templates/prescription/general_list.html.twig @@ -0,0 +1,520 @@ +{## + * Prescription list + * + * @package OpenEMR + * @link http://www.open-emr.org + * @author Brady Miller + * @author Sherwin Gaddis + * @author Stephen Nielson + * @copyright Copyright (c) 2017-2018 Brady Miller + * @copyright Copyright (c) 2018 Sherwin Gaddis + * @copyright Copyright (c) 2024 Discover and Change, Inc. + * @license https://github.com/openemr/openemr/blob/master/LICENSE GNU General Public License 3 + * +#} + + +{{ setupHeader(['no_textformat']) }} + + + + + + + +
+
+ {% if prescriptions %} +
+

{{'List'|xlt}}

+
+ {% block prescriptionTopNavbar %} +
+
+ {# Don't think the top.restoreSessions are needed here since the CheckForChecks function does that, but leaving it just in case #} + {% block prescriptionTopNavbarButtons %} + {% if rx_zend_pdf_template %} + {{'Download'|xlt}} ({{'PDF'|xlt}}) + {% else %} + {{'Download'|xlt}} ({{'PDF'|xlt}}) + {% endif %} + {% if rx_zend_html_template %} + {{'View Printable Version'|xlt}} ({{'HTML'|xlt}}) + {% else %} + + {{'View Printable Version'|xlt}} ({{'HTML'|xlt}}) + {% endif %} + {%if rx_use_fax_template%} + {{'Download'|xlt}} ({{'Fax'|xlt}}) + {% endif %} + {% if rx_send_email %} + {{'Send Email'|xlt}} + {% endif %} + {% if CAMOS_FORM == true %} + {{'View Four Panel'|xlt}} + {% endif %} + {% endblock %} +
+ +
+ {% endblock %} + + {% if process_result %} +
+
+ {{process_result|text}} +
+
+ {% endif %} +
+
+
+

{{ "Email Prescriptions"|xlt }}

+
+
+ {# Note this will call the send_action_process, there is no corresponding send_action method #} +
+
+
+
+ + + +
+
+
+
+ + +
+
+ + +
+
+
+
+
+ +
+
+ +
+
+
+
+
+
+
+
+ + + + + + + + + + + + + + + + + + + {% for prescription in prescriptions %} + + + + {% if prescription.erx_source is empty or prescription.erx_source==0 %} + + + {% else %} + + + {% endif %} + + + + {%if prescription.erx_source is empty or prescription.erx_source==0%} + + {% else %} + + {% endif %} + + + + + + {% endfor %} + +
  {{'Drug'|xlt}}{{'RxNorm'|xlt}}{{'Created'|xlt}}
{{'Changed'|xlt}}
{{'Dosage'|xlt}}{{'Qty'|xlt}}.{{'Unit'|xlt}}{{'Refills'|xlt}}{{'Provider'|xlt}}
+ 0 %} + checked="checked" + {% endif %} + title="{{'Select for printing'|xla}}"> + + {{'Edit'|xlt}} + + {% if prescription.active > 0%} + {{prescription.drug|text}} + {% else %} + {{prescription.drug|text}} + {% endif %}  +
{{prescription.note|text}} +
  + {% if prescription.active > 0%} + {{prescription.drug|text}} + {% else %} + {{prescription.drug|text}} + {% endif %}  +
{{prescription.note|text}} +
+ {{prescription.rxnorm_drugcode|text}}  + + {{prescription.date_added|shortDate|text}}
+ {{prescription.date_modified|shortDate|text}}  +
+ {{prescription.get_dosage_display()|text}}   + + {{ prescription.quantity|text }}   + + {{prescription.quantity|text}}   + + {{prescription.get_size()|text}} {{prescription.get_unit_display()|text}}  + + {{prescription.refills|text}}   + + {{prescription.provider.get_name_display()|text}}  + + {{'Delete'|xlt}} +
+
+
+
+
+ {% if rx_show_drug_drug %} +
+
+

{{'Drug-Drug Interaction'|xlt}}

+

*{{'Notice'|xlt}}

+
+ {{INTERACTION|text}} +
+
+
+ {% endif %} + + {% else %} +
{{ "There are currently no prescriptions"|xlt}}.
+ {% endif %} +
+ +
+ + + + +