added drug waste management (lot destruction)
[openemr.git] / controllers / C_Prescription.class.php
blobb9667569b93797f49b771bdadc2bea20139ed549
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();
15 $this->template_mod = $template_mod;
16 $this->assign("FORM_ACTION", $GLOBALS['webroot']."/controller.php?" . $_SERVER['QUERY_STRING']);
17 $this->assign("TOP_ACTION", $GLOBALS['webroot']."/controller.php?" . "prescription" . "&");
18 $this->assign("STYLE", $GLOBALS['style']);
19 $this->pconfig = $GLOBALS['oer_config']['prescriptions'];
21 if ($GLOBALS['inhouse_pharmacy']) {
22 // Make an array of drug IDs and selectors for the template.
23 $drug_array = array(0 => "-- or select from inventory --");
24 $drug_attributes = '';
25 $res = sqlStatement("SELECT * FROM drugs ORDER BY selector");
26 while ($row = sqlFetchArray($res)) {
27 $drug_array[$row['drug_id']] = $row['selector'];
28 if ($row['ndc_number']) {
29 $drug_array[$row['drug_id']] .= ' [' . $row['ndc_number'] . ']';
31 if ($drug_attributes) $drug_attributes .= ',';
32 $drug_attributes .= "['" .
33 $row['name'] . "'," . // 0
34 $row['form'] . ",'" . // 1
35 $row['dosage'] . "'," . // 2
36 $row['size'] . "," . // 3
37 $row['unit'] . "," . // 4
38 $row['route'] . "," . // 5
39 $row['period'] . "," . // 6
40 $row['substitute'] . "," . // 7
41 $row['quantity'] . "," . // 8
42 $row['refills'] . "," . // 9
43 $row['per_refill'] . "]"; // 10
45 $this->assign("DRUG_ARRAY", $drug_array);
46 $this->assign("DRUG_ATTRIBUTES", $drug_attributes);
51 function default_action() {
52 $this->assign("prescription",$this->prescriptions[0]);
53 $this->display($GLOBALS['template_dir'] . "prescription/" . $this->template_mod . "_edit.html");
56 function edit_action($id = "",$patient_id="",$p_obj = null) {
58 if ($p_obj != null && get_class($p_obj) == "prescription") {
59 $this->prescriptions[0] = $p_obj;
61 elseif (get_class($this->prescriptions[0]) != "prescription" ) {
62 $this->prescriptions[0] = new Prescription($id);
65 if (!empty($patient_id)) {
66 $this->prescriptions[0]->set_patient_id($patient_id);
68 $this->default_action();
71 function list_action($id,$sort = "") {
72 if (empty($id)) {
73 $this->function_argument_error();
74 exit;
76 if (!empty($sort)) {
77 $this->assign("prescriptions", Prescription::prescriptions_factory($id,$sort));
79 else {
80 $this->assign("prescriptions", Prescription::prescriptions_factory($id));
82 //print_r(Prescription::prescriptions_factory($id));
83 $this->display($GLOBALS['template_dir'] . "prescription/" . $this->template_mod . "_list.html");
86 function block_action($id,$sort = "") {
87 if (empty($id)) {
88 $this->function_argument_error();
89 exit;
91 if (!empty($sort)) {
92 $this->assign("prescriptions", Prescription::prescriptions_factory($id,$sort));
94 else {
95 $this->assign("prescriptions", Prescription::prescriptions_factory($id));
97 //print_r(Prescription::prescriptions_factory($id));
98 $this->display($GLOBALS['template_dir'] . "prescription/" . $this->template_mod . "_block.html");
101 function lookup_action() {
102 $this->do_lookup();
103 $this->display($GLOBALS['template_dir'] . "prescription/" . $this->template_mod . "_lookup.html");
106 function edit_action_process() {
107 if ($_POST['process'] != "true")
108 return;
109 //print_r($_POST);
111 $this->prescriptions[0] = new Prescription($_POST['id']);
112 parent::populate_object($this->prescriptions[0]);
113 //echo $this->prescriptions[0]->toString(true);
114 $this->prescriptions[0]->persist();
115 $_POST['process'] = "";
117 // If the "Prescribe and Dispense" button was clicked, then
118 // redisplay as in edit_action() but also replicate the fee and
119 // include a piece of javascript to call dispense().
121 if ($_POST['disp_button']) {
122 $this->assign("DISP_QUANTITY", $_POST['disp_quantity']);
123 $this->assign("DISP_FEE", $_POST['disp_fee']);
124 $this->assign("ENDING_JAVASCRIPT", "dispense();");
125 $this->_state = false;
126 return $this->edit_action($this->prescriptions[0]->id);
129 return $this->send_action($this->prescriptions[0]->id);
132 function send_action($id) {
133 $_POST['process'] = "true";
134 if(empty($id)) {
135 $this->function_argument_error();
138 $rx = new Prescription($id);
139 // Populate pharmacy info if the patient has a default pharmacy.
140 // Probably the Prescription object should handle this instead, but
141 // doing it there will require more careful research and testing.
142 $prow = sqlQuery("SELECT pt.pharmacy_id FROM prescriptions AS rx, " .
143 "patient_data AS pt WHERE rx.id = '$id' AND pt.pid = rx.patient_id");
144 if ($prow['pharmacy_id']) {
145 $rx->pharmacy->set_id($prow['pharmacy_id']);
146 $rx->pharmacy->populate();
148 $this->assign("prescription", $rx);
150 $this->_state = false;
151 return $this->fetch($GLOBALS['template_dir'] . "prescription/" .
152 $this->template_mod . "_send.html");
155 function multiprint_header(& $pdf, $p) {
156 //print header
157 $pdf->ezImage($GLOBALS['fileroot'] . '/interface/pic/Rx.png','','50','','center','');
158 $pdf->ezColumnsStart(array('num'=>2, 'gap'=>10));
159 $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 ='"
160 . mysql_real_escape_string($p->provider->id) . "'");
162 $pdf->ezText($res['addr'],12);
163 $my_y = $pdf->y;
164 $pdf->ezNewPage();
165 $pdf->ezText('<b>' . $p->provider->get_name_display() . '</b>',12);
166 $pdf->ezText('<b>DEA:</b>' . $p->provider->federal_drug_id,12);
167 $pdf->ezColumnsStop();
168 if ($my_y < $pdf->y){
169 $pdf->ezSetY($my_y);
171 $pdf->ezText('',10);
172 $pdf->setLineStyle(1);
173 $pdf->ezColumnsStart(array('num'=>2));
174 $pdf->line($pdf->ez['leftMargin'],$pdf->y,$pdf->ez['pageWidth']-$pdf->ez['rightMargin'],$pdf->y);
175 $pdf->ezText('<b>Patient Name & Address</b>',6);
176 $pdf->ezText($p->patient->get_name_display(),10);
177 $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));
178 $pdf->ezText($res['addr']);
179 $my_y = $pdf->y;
180 $pdf->ezNewPage();
181 $pdf->line($pdf->ez['leftMargin'],$pdf->y,$pdf->ez['pageWidth']-$pdf->ez['rightMargin'],$pdf->y);
182 $pdf->ezText('<b>Date of Birth</b>',6);
183 $pdf->ezText($p->patient->date_of_birth,10);
184 $pdf->ezText('');
185 $pdf->line($pdf->ez['leftMargin'],$pdf->y,$pdf->ez['pageWidth']-$pdf->ez['rightMargin'],$pdf->y);
186 $pdf->ezText('<b>Medical Record #</b>',6);
187 $pdf->ezText(str_pad($p->patient->get_id(), 10, "0", STR_PAD_LEFT),10);
188 $pdf->ezColumnsStop();
189 if ($my_y < $pdf->y){
190 $pdf->ezSetY($my_y);
192 $pdf->ezText('');
193 $pdf->line($pdf->ez['leftMargin'],$pdf->y,$pdf->ez['pageWidth']-$pdf->ez['rightMargin'],$pdf->y);
195 $pdf->ezText('<b>Prescriptions</b>',6);
196 $pdf->ezText('',10);
199 function multiprint_footer(& $pdf){
200 if($this->pconfig['use_signature'] == true ) {
201 $pdf->ezImage($this->pconfig['signature'],"","","none","left");
203 else{
204 $pdf->ezText("\n\n\n\nSignature:________________________________\nDate: " . date('Y-m-d'),12);
208 function get_prescription_body_text($p) {
209 $body = '<b>Rx: ' . $p->get_drug() . ' ' . $p->get_size() . ' ' . $p->get_unit_display()
210 . ' [' . $p->form_array[$p->get_form()] . "]</b> <i>"
211 . $p->substitute_array[$p->get_substitute()] . "</i>\n"
212 . '<b>Disp #:</b> <u>' . $p->get_quantity() . "</u>\n"
213 . '<b>Sig:</b> ' . $p->get_dosage() . ' ' . $p->form_array[$p->get_form()] .' '
214 . $p->route_array[$p->get_route()] . ' ' . $p->interval_array[$p->get_interval()] . "\n";
215 if ($p->get_refills() > 0) {
216 $body .= "\n<b>Refills:</b> <u>" . $p->get_refills() . " of quantity " . $p->get_per_refill() . "</u>\n";
218 else {
219 $body .= "\n<b>Refills:</b> <u>0 (Zero)</u>\n";
221 $note = $p->get_note();
222 if ($note != '') {
223 $body .= "\n$note\n";
225 return $body;
228 function multiprint_body(& $pdf, $p){
229 $pdf->ez['leftMargin'] += $pdf->ez['leftMargin'];
230 $pdf->ez['rightMargin'] += $pdf->ez['rightMargin'];
231 $d = $this->get_prescription_body_text($p);
233 if ( $pdf->ezText($d,10,array(),1) ) {
234 $pdf->ez['leftMargin'] -= $pdf->ez['leftMargin'];
235 $pdf->ez['rightMargin'] -= $pdf->ez['rightMargin'];
236 $this->multiprint_footer($pdf, $p);
237 $pdf->ezNewPage();
238 $this->multiprint_header($pdf, $p);
239 $pdf->ez['leftMargin'] += $pdf->ez['leftMargin'];
240 $pdf->ez['rightMargin'] += $pdf->ez['rightMargin'];
242 $my_y = $pdf->y;
243 $pdf->ezText($d,10);
244 $pdf->setColor(.9,.9,.9);
245 $pdf->filledRectangle($pdf->ez['leftMargin'],$pdf->y,$pdf->ez['pageWidth']-$pdf->ez['rightMargin']-$pdf->ez['leftMargin'],$my_y - $pdf->y);
246 $pdf->setColor(0,0,0);
247 $pdf->ezSetY($my_y);
248 $pdf->ezText($d,10);
249 $pdf->ez['leftMargin'] = $GLOBALS['oer_config']['prescriptions']['left'];
250 $pdf->ez['rightMargin'] = $GLOBALS['oer_config']['prescriptions']['right'];
251 $pdf->ezText('');
252 $pdf->line($pdf->ez['leftMargin'],$pdf->y,$pdf->ez['pageWidth']-$pdf->ez['rightMargin'],$pdf->y);
253 $pdf->ezText('');
257 function multiprint_action($id = "") {
258 $_POST['process'] = "true";
259 if(empty($id)) {
260 $this->function_argument_error();
262 require_once ($GLOBALS['fileroot'] . "/library/classes/class.ezpdf.php");
263 $pdf =& new Cezpdf($GLOBALS['oer_config']['prescriptions']['paper_size']);
264 $pdf->ezSetMargins($GLOBALS['oer_config']['prescriptions']['top']
265 ,$GLOBALS['oer_config']['prescriptions']['bottom']
266 ,$GLOBALS['oer_config']['prescriptions']['left']
267 ,$GLOBALS['oer_config']['prescriptions']['right']
269 $pdf->selectFont($GLOBALS['fileroot'] . "/library/fonts/Helvetica.afm");
272 $print_header = true;
274 //print prescriptions body
275 $this->_state = false; // Added by Rod - see Controller.class.php
276 $ids = preg_split('/::/', substr($id,1,strlen($id) - 2), -1, PREG_SPLIT_NO_EMPTY);
277 foreach ($ids as $id) {
278 $p = new Prescription($id);
279 if ($print_header == true) {
280 $this->multiprint_header($pdf, $p);
281 $print_header = false;
283 $this->multiprint_body($pdf, $p);
286 $this->multiprint_footer($pdf);
288 $pdf->ezStream();
289 return;
292 function send_action_process($id) {
293 $dummy = ""; // Added by Rod to avoid run-time warnings
294 if ($_POST['process'] != "true")
295 return;
296 if(empty($id)) {
297 $this->function_argument_error();
299 $p = new Prescription($id);
300 switch ($_POST['submit']) {
302 case "Print":
303 // The following statement added by Rod.
304 // Looking at Controller.class.php, it appears that _state is set to false
305 // to indicate that no further HTML is to be generated.
306 $this->_state = false; // Added by Rod - see Controller.class.php
307 return $this->_print_prescription($p, $dummy);
308 break;
309 case "Email":
310 return $this->_email_prescription($p,$_POST['email_to']);
311 break;
312 case "Fax":
313 //this is intended to be the hook for the hylafax code we already have that hasn't worked its way into the tree yet.
314 //$this->assign("process_result","No fax server is currently setup.");
315 return $this->_fax_prescription($p,$_POST['fax_to']);
316 break;
317 case "Auto Send":
318 $pharmacy_id = $_POST['pharmacy_id'];
319 //echo "auto sending to : " . $_POST['pharmacy_id'];
320 $phar = new Pharmacy($_POST['pharmacy_id']);
321 //print_r($phar);
322 if ($phar->get_transmit_method() == TRANSMIT_PRINT) {
323 return $this->_print_prescription($p, $dummy);
325 elseif ($phar->get_transmit_method() == TRANSMIT_EMAIL) {
326 $email = $phar->get_email();
327 if (!empty($email)) {
328 return $this->_email_prescription($p,$phar->get_email());
330 //else print it
332 elseif ($phar->get_transmit_method() == TRANSMIT_FAX) {
333 $faxNum= $phar->get_fax();
334 if(!empty($faxNum)) {
335 Return $this->_fax_prescription ($p,$faxNum);
337 // return $this->assign("process_result","No fax server is currently setup.");
338 // else default is printing,
340 else {
341 //the pharmacy has no default or default is print
342 return $this->_print_prescription($p, $dummy);
344 break;
347 return;
351 function _print_prescription($p, & $toFile) {
352 require_once ($GLOBALS['fileroot'] . "/library/classes/class.ezpdf.php");
353 $pdf =& new Cezpdf($GLOBALS['oer_config']['prescriptions']['paper_size']);
354 $pdf->ezSetMargins($GLOBALS['oer_config']['prescriptions']['top']
355 ,$GLOBALS['oer_config']['prescriptions']['bottom']
356 ,$GLOBALS['oer_config']['prescriptions']['left']
357 ,$GLOBALS['oer_config']['prescriptions']['right']
360 $pdf->selectFont($GLOBALS['fileroot'] . "/library/fonts/Helvetica.afm");
362 $this->multiprint_header($pdf, $p);
364 $this->multiprint_body($pdf, $p);
366 $this->multiprint_footer($pdf);
368 if(!empty($toFile))
370 $toFile = $pdf->ezOutput();
372 else
374 $pdf->ezStream();
375 // $pdf->ezStream(array('compress' => 0)); // for testing with uncompressed output
377 return;
380 function _print_prescription_old($p, & $toFile) {
381 require_once ($GLOBALS['fileroot'] . "/library/classes/class.ezpdf.php");
382 $pdf =& new Cezpdf($GLOBALS['oer_config']['prescriptions']['paper_size']);
383 $pdf->ezSetMargins($GLOBALS['oer_config']['prescriptions']['top']
384 ,$GLOBALS['oer_config']['prescriptions']['bottom']
385 ,$GLOBALS['oer_config']['prescriptions']['left']
386 ,$GLOBALS['oer_config']['prescriptions']['right']
389 $pdf->selectFont($GLOBALS['fileroot'] . "/library/fonts/Helvetica.afm");
391 if(!empty($this->pconfig['logo'])) {
392 $pdf->ezImage($this->pconfig['logo'],"","","none","left");
394 $pdf->ezText($p->get_prescription_display(),10);
395 if($this->pconfig['use_signature'] == true ) {
396 $pdf->ezImage($this->pconfig['signature'],"","","none","left");
398 else{
399 $pdf->ezText("\n\n\n\nSignature:________________________________",10);
402 if(!empty($toFile))
404 $toFile = $pdf->ezOutput();
406 else
408 $pdf->ezStream();
409 // $pdf->ezStream(array('compress' => 0)); // for testing with uncompressed output
411 return;
414 function _email_prescription($p,$email) {
415 if (empty($email)) {
416 $this->assign("process_result","Email could not be sent, the address supplied: '$email' was empty or invalid.");
417 return;
419 require($GLOBALS['fileroot'] . "/library/classes/class.phpmailer.php");
420 $mail = new PHPMailer();
421 $mail->SetLanguage("en",$GLOBALS['fileroot'] . "/library/" );
422 //this is a temporary config item until the rest of the per practice billing settings make their way in
423 $mail->From = $GLOBALS['practice_return_email_path'];
424 $mail->FromName = $p->provider->get_name_display();
425 $mail->isMail();
426 $mail->Host = "localhost";
427 $mail->Mailer = "mail";
428 $text_body = $p->get_prescription_display();
429 $mail->Body = $text_body;
430 $mail->Subject = "Prescription for: " . $p->patient->get_name_display();
431 $mail->AddAddress($email);
432 if($mail->Send()) {
433 $this->assign("process_result","Email was successfully sent to: " . $email);
434 return;
436 else {
437 $this->assign("process_result","There has been a mail error sending to " . $_POST['email_to'] . " " . $mail->ErrorInfo);
438 return;
442 function do_lookup() {
443 if ($_POST['process'] != "true")
444 return;
445 $list = array();
446 if (!empty($_POST['drug'])) {
447 $list = @RxList::get_list($_POST['drug']);
449 if (is_array($list)) {
450 $list = array_flip($list);
451 $this->assign("drug_options",$list);
452 $this->assign("drug_values",array_keys($list));
454 else {
455 $this->assign("NO_RESULTS","No results found for: " .$_POST['drug'] . "<br />");
457 //print_r($_POST);
458 //$this->assign("PROCESS","");
460 $_POST['process'] = "";
463 function _fax_prescription($p,$faxNum)
465 $err = "Sent fax";
466 //strip - ,(, ), and ws
467 $faxNum = preg_replace("/(-*)(\(*)(\)*)(\s*)/","",$faxNum);
468 //validate the number
470 if(!empty($faxNum) && is_numeric($faxNum))
472 //get the sendfax command and execute it
473 $cmd = $this->pconfig['sendfax'];
474 // prepend any prefix to the fax number
475 $pref=$this->pconfig['prefix'];
476 $faxNum=$pref.$faxNum;
477 if(empty($cmd))
479 $err .= " Send fax not set in includes/config.php";
480 break;
482 else
484 //generate file to fax
485 $faxFile = "Failed";
486 $this->_print_prescription($p, $faxFile);
487 if(empty($faxFile))
489 $err .= " _print_prescription returned empty file";
490 break;
492 $fileName = dirname(__FILE__)."/../documents/".$p->get_id()
493 .$p->get_patient_id()."_fax_.pdf";
494 //print "filename is $fileName";
495 touch($fileName); // php bug
496 $handle = fopen($fileName,"w");
497 if(!$handle)
499 $err .= " Failed to open file $fileName to write fax to";
500 break;
502 if(fwrite($handle, $faxFile) === false)
504 $err .= " Failed to write data to $fileName";
505 break;
507 fclose($handle);
508 $args = " -n -d $faxNum $fileName";
509 //print "command is $cmd $args<br>";
510 exec($cmd . $args);
514 else
516 $err = "bad fax number passed to function";
518 if($err)
520 $this->assign("process_result",$err);