permit non-numeric prescription quantity
[openemr.git] / controllers / C_Prescription.class.php
blob01ea0cf87187742a11b91e3b79eca77245e4a574
1 <?php
3 require_once($GLOBALS['fileroot'] . "/library/classes/Controller.class.php");
4 require_once($GLOBALS['fileroot'] . "/library/classes/Prescription.class.php");
5 require_once($GLOBALS['fileroot'] . "/library/classes/Provider.class.php");
6 require_once($GLOBALS['fileroot'] . "/library/classes/RXList.class.php");
8 class C_Prescription extends Controller {
10 var $template_mod;
11 var $pconfig;
13 function C_Prescription($template_mod = "general") {
14 parent::Controller();
16 $this->template_mod = $template_mod;
17 $this->assign("FORM_ACTION", $GLOBALS['webroot']."/controller.php?" . $_SERVER['QUERY_STRING']);
18 $this->assign("TOP_ACTION", $GLOBALS['webroot']."/controller.php?" . "prescription" . "&");
19 $this->assign("STYLE", $GLOBALS['style']);
20 $this->assign("WEIGHT_LOSS_CLINIC", $GLOBALS['weight_loss_clinic']);
21 $this->assign("SIMPLIFIED_PRESCRIPTIONS", $GLOBALS['simplified_prescriptions']);
22 $this->pconfig = $GLOBALS['oer_config']['prescriptions'];
24 if ($GLOBALS['inhouse_pharmacy']) {
25 // Make an array of drug IDs and selectors for the template.
26 $drug_array_values = array(0);
27 $drug_array_output = array("-- or select from inventory --");
28 $drug_attributes = '';
30 // $res = sqlStatement("SELECT * FROM drugs ORDER BY selector");
32 $res = sqlStatement("SELECT d.name, d.ndc_number, d.form, d.size, " .
33 "d.unit, d.route, d.substitute, t.drug_id, t.selector, t.dosage, " .
34 "t.period, t.quantity, t.refills " .
35 "FROM drug_templates AS t, drugs AS d WHERE " .
36 "d.drug_id = t.drug_id ORDER BY t.selector");
38 while ($row = sqlFetchArray($res)) {
39 $tmp_output = $row['selector'];
40 if ($row['ndc_number']) {
41 $tmp_output .= ' [' . $row['ndc_number'] . ']';
43 $drug_array_values[] = $row['drug_id'];
44 $drug_array_output[] = $tmp_output;
45 if ($drug_attributes) $drug_attributes .= ',';
46 $drug_attributes .= "['" .
47 $row['name'] . "'," . // 0
48 $row['form'] . ",'" . // 1
49 $row['dosage'] . "'," . // 2
50 $row['size'] . "," . // 3
51 $row['unit'] . "," . // 4
52 $row['route'] . "," . // 5
53 $row['period'] . "," . // 6
54 $row['substitute'] . "," . // 7
55 $row['quantity'] . "," . // 8
56 $row['refills'] . "," . // 9
57 $row['quantity'] . "]"; // 10 quantity per_refill
59 $this->assign("DRUG_ARRAY_VALUES", $drug_array_values);
60 $this->assign("DRUG_ARRAY_OUTPUT", $drug_array_output);
61 $this->assign("DRUG_ATTRIBUTES", $drug_attributes);
65 function default_action() {
66 $this->assign("prescription",$this->prescriptions[0]);
67 $this->display($GLOBALS['template_dir'] . "prescription/" . $this->template_mod . "_edit.html");
70 function edit_action($id = "",$patient_id="",$p_obj = null) {
72 if ($p_obj != null && get_class($p_obj) == "prescription") {
73 $this->prescriptions[0] = $p_obj;
75 elseif (get_class($this->prescriptions[0]) != "prescription" ) {
76 $this->prescriptions[0] = new Prescription($id);
79 if (!empty($patient_id)) {
80 $this->prescriptions[0]->set_patient_id($patient_id);
83 // If quantity to dispense is not already set from a POST, set its
84 // default value.
85 if (! $this->get_template_vars('DISP_QUANTITY')) {
86 $this->assign('DISP_QUANTITY', $this->prescriptions[0]->quantity);
89 $this->default_action();
92 function list_action($id,$sort = "") {
93 if (empty($id)) {
94 $this->function_argument_error();
95 exit;
97 if (!empty($sort)) {
98 $this->assign("prescriptions", Prescription::prescriptions_factory($id,$sort));
100 else {
101 $this->assign("prescriptions", Prescription::prescriptions_factory($id));
103 //print_r(Prescription::prescriptions_factory($id));
104 $this->display($GLOBALS['template_dir'] . "prescription/" . $this->template_mod . "_list.html");
107 function block_action($id,$sort = "") {
108 if (empty($id)) {
109 $this->function_argument_error();
110 exit;
112 if (!empty($sort)) {
113 $this->assign("prescriptions", Prescription::prescriptions_factory($id,$sort));
115 else {
116 $this->assign("prescriptions", Prescription::prescriptions_factory($id));
118 //print_r(Prescription::prescriptions_factory($id));
119 $this->display($GLOBALS['template_dir'] . "prescription/" . $this->template_mod . "_block.html");
122 function lookup_action() {
123 $this->do_lookup();
124 $this->display($GLOBALS['template_dir'] . "prescription/" . $this->template_mod . "_lookup.html");
127 function edit_action_process() {
128 if ($_POST['process'] != "true")
129 return;
130 //print_r($_POST);
132 $this->prescriptions[0] = new Prescription($_POST['id']);
133 parent::populate_object($this->prescriptions[0]);
134 //echo $this->prescriptions[0]->toString(true);
135 $this->prescriptions[0]->persist();
136 $_POST['process'] = "";
138 // If the "Prescribe and Dispense" button was clicked, then
139 // redisplay as in edit_action() but also replicate the fee and
140 // include a piece of javascript to call dispense().
142 if ($_POST['disp_button']) {
143 $this->assign("DISP_QUANTITY", $_POST['disp_quantity']);
144 $this->assign("DISP_FEE", $_POST['disp_fee']);
145 $this->assign("ENDING_JAVASCRIPT", "dispense();");
146 $this->_state = false;
147 return $this->edit_action($this->prescriptions[0]->id);
150 return $this->send_action($this->prescriptions[0]->id);
153 function send_action($id) {
154 $_POST['process'] = "true";
155 if(empty($id)) {
156 $this->function_argument_error();
159 $rx = new Prescription($id);
160 // Populate pharmacy info if the patient has a default pharmacy.
161 // Probably the Prescription object should handle this instead, but
162 // doing it there will require more careful research and testing.
163 $prow = sqlQuery("SELECT pt.pharmacy_id FROM prescriptions AS rx, " .
164 "patient_data AS pt WHERE rx.id = '$id' AND pt.pid = rx.patient_id");
165 if ($prow['pharmacy_id']) {
166 $rx->pharmacy->set_id($prow['pharmacy_id']);
167 $rx->pharmacy->populate();
169 $this->assign("prescription", $rx);
171 $this->_state = false;
172 return $this->fetch($GLOBALS['template_dir'] . "prescription/" .
173 $this->template_mod . "_send.html");
176 function multiprint_header(& $pdf, $p) {
177 //print header
178 $pdf->ezImage($GLOBALS['fileroot'] . '/interface/pic/Rx.png','','50','','center','');
179 $pdf->ezColumnsStart(array('num'=>2, 'gap'=>10));
180 $res = sqlQuery("SELECT concat('<b>',f.name,'</b>\n',f.street,'\n',f.city,', ',f.state,' ',f.postal_code,'\nTel:',f.phone,if(f.fax != '',concat('\nFax: ',f.fax),'')) addr FROM users JOIN facility AS f ON f.name = users.facility where users.id ='"
181 . mysql_real_escape_string($p->provider->id) . "'");
183 $pdf->ezText($res['addr'],12);
184 $my_y = $pdf->y;
185 $pdf->ezNewPage();
186 $pdf->ezText('<b>' . $p->provider->get_name_display() . '</b>',12);
187 $pdf->ezText('<b>DEA:</b>' . $p->provider->federal_drug_id,12);
188 $pdf->ezColumnsStop();
189 if ($my_y < $pdf->y){
190 $pdf->ezSetY($my_y);
192 $pdf->ezText('',10);
193 $pdf->setLineStyle(1);
194 $pdf->ezColumnsStart(array('num'=>2));
195 $pdf->line($pdf->ez['leftMargin'],$pdf->y,$pdf->ez['pageWidth']-$pdf->ez['rightMargin'],$pdf->y);
196 $pdf->ezText('<b>Patient Name & Address</b>',6);
197 $pdf->ezText($p->patient->get_name_display(),10);
198 $res = sqlQuery("SELECT concat(street,'\n',city,', ',state,' ',postal_code,'\n',if(phone_home!='',phone_home,if(phone_cell!='',phone_cell,if(phone_biz!='',phone_biz,'')))) addr from patient_data where pid =". mysql_real_escape_string ($p->patient->id));
199 $pdf->ezText($res['addr']);
200 $my_y = $pdf->y;
201 $pdf->ezNewPage();
202 $pdf->line($pdf->ez['leftMargin'],$pdf->y,$pdf->ez['pageWidth']-$pdf->ez['rightMargin'],$pdf->y);
203 $pdf->ezText('<b>Date of Birth</b>',6);
204 $pdf->ezText($p->patient->date_of_birth,10);
205 $pdf->ezText('');
206 $pdf->line($pdf->ez['leftMargin'],$pdf->y,$pdf->ez['pageWidth']-$pdf->ez['rightMargin'],$pdf->y);
207 $pdf->ezText('<b>Medical Record #</b>',6);
208 $pdf->ezText(str_pad($p->patient->get_id(), 10, "0", STR_PAD_LEFT),10);
209 $pdf->ezColumnsStop();
210 if ($my_y < $pdf->y){
211 $pdf->ezSetY($my_y);
213 $pdf->ezText('');
214 $pdf->line($pdf->ez['leftMargin'],$pdf->y,$pdf->ez['pageWidth']-$pdf->ez['rightMargin'],$pdf->y);
216 $pdf->ezText('<b>Prescriptions</b>',6);
217 $pdf->ezText('',10);
220 function multiprint_footer(& $pdf){
221 if($this->pconfig['use_signature'] == true ) {
222 $pdf->ezImage($this->pconfig['signature'],"","","none","left");
224 else{
225 $pdf->ezText("\n\n\n\nSignature:________________________________\nDate: " . date('Y-m-d'),12);
229 function get_prescription_body_text($p) {
230 $body = '<b>Rx: ' . $p->get_drug() . ' ' . $p->get_size() . ' ' . $p->get_unit_display();
231 if ($p->get_form()) $body .= ' [' . $p->form_array[$p->get_form()] . "]";
232 $body .= "</b> <i>"
233 . $p->substitute_array[$p->get_substitute()] . "</i>\n"
234 . '<b>Disp #:</b> <u>' . $p->get_quantity() . "</u>\n"
235 . '<b>Sig:</b> ' . $p->get_dosage() . ' ' . $p->form_array[$p->get_form()] .' '
236 . $p->route_array[$p->get_route()] . ' ' . $p->interval_array[$p->get_interval()] . "\n";
237 if ($p->get_refills() > 0) {
238 $body .= "\n<b>Refills:</b> <u>" . $p->get_refills() . " of quantity " . $p->get_per_refill() . "</u>\n";
240 else {
241 $body .= "\n<b>Refills:</b> <u>0 (Zero)</u>\n";
243 $note = $p->get_note();
244 if ($note != '') {
245 $body .= "\n$note\n";
247 return $body;
250 function multiprint_body(& $pdf, $p){
251 $pdf->ez['leftMargin'] += $pdf->ez['leftMargin'];
252 $pdf->ez['rightMargin'] += $pdf->ez['rightMargin'];
253 $d = $this->get_prescription_body_text($p);
255 if ( $pdf->ezText($d,10,array(),1) ) {
256 $pdf->ez['leftMargin'] -= $pdf->ez['leftMargin'];
257 $pdf->ez['rightMargin'] -= $pdf->ez['rightMargin'];
258 $this->multiprint_footer($pdf, $p);
259 $pdf->ezNewPage();
260 $this->multiprint_header($pdf, $p);
261 $pdf->ez['leftMargin'] += $pdf->ez['leftMargin'];
262 $pdf->ez['rightMargin'] += $pdf->ez['rightMargin'];
264 $my_y = $pdf->y;
265 $pdf->ezText($d,10);
266 $pdf->setColor(.9,.9,.9);
267 $pdf->filledRectangle($pdf->ez['leftMargin'],$pdf->y,$pdf->ez['pageWidth']-$pdf->ez['rightMargin']-$pdf->ez['leftMargin'],$my_y - $pdf->y);
268 $pdf->setColor(0,0,0);
269 $pdf->ezSetY($my_y);
270 $pdf->ezText($d,10);
271 $pdf->ez['leftMargin'] = $GLOBALS['oer_config']['prescriptions']['left'];
272 $pdf->ez['rightMargin'] = $GLOBALS['oer_config']['prescriptions']['right'];
273 $pdf->ezText('');
274 $pdf->line($pdf->ez['leftMargin'],$pdf->y,$pdf->ez['pageWidth']-$pdf->ez['rightMargin'],$pdf->y);
275 $pdf->ezText('');
279 function multiprint_action($id = "") {
280 $_POST['process'] = "true";
281 if(empty($id)) {
282 $this->function_argument_error();
284 require_once ($GLOBALS['fileroot'] . "/library/classes/class.ezpdf.php");
285 $pdf =& new Cezpdf($GLOBALS['oer_config']['prescriptions']['paper_size']);
286 $pdf->ezSetMargins($GLOBALS['oer_config']['prescriptions']['top']
287 ,$GLOBALS['oer_config']['prescriptions']['bottom']
288 ,$GLOBALS['oer_config']['prescriptions']['left']
289 ,$GLOBALS['oer_config']['prescriptions']['right']
291 $pdf->selectFont($GLOBALS['fileroot'] . "/library/fonts/Helvetica.afm");
294 $print_header = true;
296 //print prescriptions body
297 $this->_state = false; // Added by Rod - see Controller.class.php
298 $ids = preg_split('/::/', substr($id,1,strlen($id) - 2), -1, PREG_SPLIT_NO_EMPTY);
299 foreach ($ids as $id) {
300 $p = new Prescription($id);
301 if ($print_header == true) {
302 $this->multiprint_header($pdf, $p);
303 $print_header = false;
305 $this->multiprint_body($pdf, $p);
308 $this->multiprint_footer($pdf);
310 $pdf->ezStream();
311 return;
314 function send_action_process($id) {
315 $dummy = ""; // Added by Rod to avoid run-time warnings
316 if ($_POST['process'] != "true")
317 return;
318 if(empty($id)) {
319 $this->function_argument_error();
321 $p = new Prescription($id);
322 switch ($_POST['submit']) {
324 case "Print":
325 // The following statement added by Rod.
326 // Looking at Controller.class.php, it appears that _state is set to false
327 // to indicate that no further HTML is to be generated.
328 $this->_state = false; // Added by Rod - see Controller.class.php
329 return $this->_print_prescription($p, $dummy);
330 break;
331 case "Email":
332 return $this->_email_prescription($p,$_POST['email_to']);
333 break;
334 case "Fax":
335 //this is intended to be the hook for the hylafax code we already have that hasn't worked its way into the tree yet.
336 //$this->assign("process_result","No fax server is currently setup.");
337 return $this->_fax_prescription($p,$_POST['fax_to']);
338 break;
339 case "Auto Send":
340 $pharmacy_id = $_POST['pharmacy_id'];
341 //echo "auto sending to : " . $_POST['pharmacy_id'];
342 $phar = new Pharmacy($_POST['pharmacy_id']);
343 //print_r($phar);
344 if ($phar->get_transmit_method() == TRANSMIT_PRINT) {
345 return $this->_print_prescription($p, $dummy);
347 elseif ($phar->get_transmit_method() == TRANSMIT_EMAIL) {
348 $email = $phar->get_email();
349 if (!empty($email)) {
350 return $this->_email_prescription($p,$phar->get_email());
352 //else print it
354 elseif ($phar->get_transmit_method() == TRANSMIT_FAX) {
355 $faxNum= $phar->get_fax();
356 if(!empty($faxNum)) {
357 Return $this->_fax_prescription ($p,$faxNum);
359 // return $this->assign("process_result","No fax server is currently setup.");
360 // else default is printing,
362 else {
363 //the pharmacy has no default or default is print
364 return $this->_print_prescription($p, $dummy);
366 break;
369 return;
373 function _print_prescription($p, & $toFile) {
375 require_once ($GLOBALS['fileroot'] . "/library/classes/class.ezpdf.php");
376 $pdf =& new Cezpdf($GLOBALS['oer_config']['prescriptions']['paper_size']);
377 $pdf->ezSetMargins($GLOBALS['oer_config']['prescriptions']['top']
378 ,$GLOBALS['oer_config']['prescriptions']['bottom']
379 ,$GLOBALS['oer_config']['prescriptions']['left']
380 ,$GLOBALS['oer_config']['prescriptions']['right']
383 $pdf->selectFont($GLOBALS['fileroot'] . "/library/fonts/Helvetica.afm");
385 $this->multiprint_header($pdf, $p);
387 $this->multiprint_body($pdf, $p);
389 $this->multiprint_footer($pdf);
391 if(!empty($toFile))
393 $toFile = $pdf->ezOutput();
395 else
397 $pdf->ezStream();
398 // $pdf->ezStream(array('compress' => 0)); // for testing with uncompressed output
400 return;
403 function _print_prescription_old($p, & $toFile) {
405 require_once ($GLOBALS['fileroot'] . "/library/classes/class.ezpdf.php");
406 $pdf =& new Cezpdf($GLOBALS['oer_config']['prescriptions']['paper_size']);
407 $pdf->ezSetMargins($GLOBALS['oer_config']['prescriptions']['top']
408 ,$GLOBALS['oer_config']['prescriptions']['bottom']
409 ,$GLOBALS['oer_config']['prescriptions']['left']
410 ,$GLOBALS['oer_config']['prescriptions']['right']
413 $pdf->selectFont($GLOBALS['fileroot'] . "/library/fonts/Helvetica.afm");
415 if(!empty($this->pconfig['logo'])) {
416 $pdf->ezImage($this->pconfig['logo'],"","","none","left");
418 $pdf->ezText($p->get_prescription_display(),10);
419 if($this->pconfig['use_signature'] == true ) {
420 $pdf->ezImage($this->pconfig['signature'],"","","none","left");
422 else{
423 $pdf->ezText("\n\n\n\nSignature:________________________________",10);
426 if(!empty($toFile))
428 $toFile = $pdf->ezOutput();
430 else
432 $pdf->ezStream();
433 // $pdf->ezStream(array('compress' => 0)); // for testing with uncompressed output
435 return;
438 function _email_prescription($p,$email) {
439 if (empty($email)) {
440 $this->assign("process_result","Email could not be sent, the address supplied: '$email' was empty or invalid.");
441 return;
443 require($GLOBALS['fileroot'] . "/library/classes/class.phpmailer.php");
444 $mail = new PHPMailer();
445 $mail->SetLanguage("en",$GLOBALS['fileroot'] . "/library/" );
446 //this is a temporary config item until the rest of the per practice billing settings make their way in
447 $mail->From = $GLOBALS['practice_return_email_path'];
448 $mail->FromName = $p->provider->get_name_display();
449 $mail->isMail();
450 $mail->Host = "localhost";
451 $mail->Mailer = "mail";
452 $text_body = $p->get_prescription_display();
453 $mail->Body = $text_body;
454 $mail->Subject = "Prescription for: " . $p->patient->get_name_display();
455 $mail->AddAddress($email);
456 if($mail->Send()) {
457 $this->assign("process_result","Email was successfully sent to: " . $email);
458 return;
460 else {
461 $this->assign("process_result","There has been a mail error sending to " . $_POST['email_to'] . " " . $mail->ErrorInfo);
462 return;
466 function do_lookup() {
467 if ($_POST['process'] != "true")
468 return;
469 $list = array();
470 if (!empty($_POST['drug'])) {
471 $list = @RxList::get_list($_POST['drug']);
473 if (is_array($list)) {
474 $list = array_flip($list);
475 $this->assign("drug_options",$list);
476 $this->assign("drug_values",array_keys($list));
478 else {
479 $this->assign("NO_RESULTS","No results found for: " .$_POST['drug'] . "<br />");
481 //print_r($_POST);
482 //$this->assign("PROCESS","");
484 $_POST['process'] = "";
487 function _fax_prescription($p,$faxNum)
489 $err = "Sent fax";
490 //strip - ,(, ), and ws
491 $faxNum = preg_replace("/(-*)(\(*)(\)*)(\s*)/","",$faxNum);
492 //validate the number
494 if(!empty($faxNum) && is_numeric($faxNum))
496 //get the sendfax command and execute it
497 $cmd = $this->pconfig['sendfax'];
498 // prepend any prefix to the fax number
499 $pref=$this->pconfig['prefix'];
500 $faxNum=$pref.$faxNum;
501 if(empty($cmd))
503 $err .= " Send fax not set in includes/config.php";
504 break;
506 else
508 //generate file to fax
509 $faxFile = "Failed";
510 $this->_print_prescription($p, $faxFile);
511 if(empty($faxFile))
513 $err .= " _print_prescription returned empty file";
514 break;
516 $fileName = dirname(__FILE__)."/../documents/".$p->get_id()
517 .$p->get_patient_id()."_fax_.pdf";
518 //print "filename is $fileName";
519 touch($fileName); // php bug
520 $handle = fopen($fileName,"w");
521 if(!$handle)
523 $err .= " Failed to open file $fileName to write fax to";
524 break;
526 if(fwrite($handle, $faxFile) === false)
528 $err .= " Failed to write data to $fileName";
529 break;
531 fclose($handle);
532 $args = " -n -d $faxNum $fileName";
533 //print "command is $cmd $args<br>";
534 exec($cmd . $args);
538 else
540 $err = "bad fax number passed to function";
542 if($err)
544 $this->assign("process_result",$err);