added gacl config files to upgrade instructions
[openemr.git] / interface / reports / ippf_statistics.php
blob3035d8435d232d769db89ef4ca6c8b11adec48bc
1 <?php
2 // This module creates statistical reports related to family planning
3 // and sexual and reproductive health.
5 include_once("../globals.php");
6 include_once("../../library/patient.inc");
7 include_once("../../library/acl.inc");
9 // Might want something different here.
11 if (! acl_check('acct', 'rep')) die("Unauthorized access.");
13 $report_type = empty($_GET['t']) ? 'i' : $_GET['t'];
15 $from_date = fixDate($_POST['form_from_date']);
16 $to_date = fixDate($_POST['form_to_date'], date('Y-m-d'));
17 $form_by = $_POST['form_by']; // this is a scalar
18 $form_show = $_POST['form_show']; // this is an array
19 $form_facility = isset($_POST['form_facility']) ? $_POST['form_facility'] : '';
20 $form_sexes = isset($_POST['form_sexes']) ? $_POST['form_sexes'] : '3';
21 $form_cors = isset($_POST['form_cors']) ? $_POST['form_cors'] : '1';
22 $form_output = isset($_POST['form_output']) ? 0 + $_POST['form_output'] : 1;
24 if (empty($form_by)) $form_by = '1';
25 if (empty($form_show)) $form_show = array('1');
27 // One of these is chosen as the left column, or Y-axis, of the report.
29 if ($report_type == 'm') {
30 $report_title = xl('Member Association Statistics Report');
31 $arr_by = array(
32 101 => xl('MA Category'),
33 102 => xl('Specific Service'),
34 17 => xl('Patient'),
35 9 => xl('Internal Referrals'),
36 10 => xl('External Referrals'),
37 103 => xl('Referral Source'),
38 2 => xl('Total'),
41 else if ($report_type == 'g') {
42 $report_title = xl('GCAC Statistics Report');
43 $arr_by = array(
44 1 => xl('Total SRH & Family Planning'),
45 12 => xl('Pre-Abortion Counseling'), // not yet implemented
46 5 => xl('Abortion Method'), // includes surgical and drug-induced
47 8 => xl('Post-Abortion Followup'),
48 7 => xl('Post-Abortion Contraception'),
49 11 => xl('Complications of Abortion'),
52 else {
53 $report_title = xl('IPPF Statistics Report');
54 $arr_by = array(
55 1 => xl('General Service Category'),
56 4 => xl('Specific Service'),
57 6 => xl('Contraceptive Method'),
58 9 => xl('Internal Referrals'),
59 10 => xl('External Referrals'),
63 if ($report_type == 'm') {
64 $arr_content = array(
65 1 => xl('Services'),
66 2 => xl('Unique Clients'),
67 4 => xl('Unique New Clients')
70 else {
71 $arr_content = array(
72 1 => xl('Services'),
73 2 => xl('Unique Clients'),
74 3 => xl('New Acceptors'),
75 4 => xl('Unique New Clients')
79 // A reported value is either scalar, or an array listed horizontally. If
80 // multiple items are chosen then each starts in the next available column.
82 $arr_show = array(
83 1 => xl('Total'),
84 // 9 => xl('Total Clients'),
85 2 => xl('Age Category'),
86 3 => xl('Sex'),
87 4 => xl('Religion'),
88 5 => xl('Nationality'),
89 6 => xl('Marital Status'),
90 7 => xl('State/Parish'),
91 10 => xl('City'),
92 8 => xl('Occupation'),
93 11 => xl('Education'),
94 12 => xl('Income'),
95 13 => xl('Provider'),
98 // This will become the array of reportable values.
99 $areport = array();
101 // This accumulates the bottom line totals.
102 $atotals = array();
104 // Arrays of titles for some column headings.
105 $arr_titles = array(
106 'rel' => array(),
107 'nat' => array(),
108 'mar' => array(),
109 'sta' => array(),
110 'occ' => array(),
111 'cit' => array(),
112 'edu' => array(),
113 'inc' => array(),
114 'pro' => array(),
117 // This is so we know when the current patient changes.
118 // $previous_pid = 0;
120 // Compute age in years given a DOB and "as of" date.
122 function getAge($dob, $asof='') {
123 if (empty($asof)) $asof = date('Y-m-d');
124 $a1 = explode('-', substr($dob , 0, 10));
125 $a2 = explode('-', substr($asof, 0, 10));
126 $age = $a2[0] - $a1[0];
127 if ($a2[1] < $a1[1] || ($a2[1] == $a1[1] && $a2[2] < $a1[2])) --$age;
128 // echo "<!-- $dob $asof $age -->\n"; // debugging
129 return $age;
132 $cellcount = 0;
134 function genStartRow($att) {
135 global $cellcount, $form_output;
136 if ($form_output != 3) echo " <tr $att>\n";
137 $cellcount = 0;
140 function genEndRow() {
141 global $form_output;
142 if ($form_output == 3) {
143 echo "\n";
145 else {
146 echo " </tr>\n";
150 /*********************************************************************
151 function genAnyCell($data, $right=false, $class='') {
152 global $cellcount;
153 if ($_POST['form_csvexport']) {
154 if ($cellcount) echo ',';
155 echo '"' . $data . '"';
157 else {
158 echo " <td";
159 if ($class) echo " class='$class'";
160 if ($right) echo " align='right'";
161 echo ">$data</td>\n";
163 ++$cellcount;
165 *********************************************************************/
167 function getListTitle($list, $option) {
168 $row = sqlQuery("SELECT title FROM list_options WHERE " .
169 "list_id = '$list' AND option_id = '$option'");
170 if (empty($row['title'])) return $option;
171 return $row['title'];
174 // Usually this generates one cell, but allows for two or more.
176 function genAnyCell($data, $right=false, $class='') {
177 global $cellcount, $form_output;
178 if (!is_array($data)) {
179 $data = array(0 => $data);
181 foreach ($data as $datum) {
182 if ($form_output == 3) {
183 if ($cellcount) echo ',';
184 echo '"' . $datum . '"';
186 else {
187 echo " <td";
188 if ($class) echo " class='$class'";
189 if ($right) echo " align='right'";
190 echo ">$datum</td>\n";
192 ++$cellcount;
196 function genHeadCell($data, $right=false) {
197 genAnyCell($data, $right, 'dehead');
200 // Create an HTML table cell containing a numeric value, and track totals.
202 function genNumCell($num, $cnum) {
203 global $atotals, $form_output;
204 $atotals[$cnum] += $num;
205 if (empty($num) && $form_output != 3) $num = '&nbsp;';
206 genAnyCell($num, true, 'detail');
209 // Translate an IPPF code to the corresponding descriptive name of its
210 // contraceptive method, or to an empty string if none applies.
212 function getContraceptiveMethod($code) {
213 $key = '';
214 if (preg_match('/^111101/', $code)) {
215 $key = xl('Pills');
217 else if (preg_match('/^11111[1-9]/', $code)) {
218 $key = xl('Injectables');
220 else if (preg_match('/^11112[1-9]/', $code)) {
221 $key = xl('Implants');
223 else if (preg_match('/^111132/', $code)) {
224 $key = xl('Patch');
226 else if (preg_match('/^111133/', $code)) {
227 $key = xl('Vaginal Ring');
229 else if (preg_match('/^112141/', $code)) {
230 $key = xl('Male Condoms');
232 else if (preg_match('/^112142/', $code)) {
233 $key = xl('Female Condoms');
235 else if (preg_match('/^11215[1-9]/', $code)) {
236 $key = xl('Diaphragms/Caps');
238 else if (preg_match('/^11216[1-9]/', $code)) {
239 $key = xl('Spermicides');
241 else if (preg_match('/^11317[1-9]/', $code)) {
242 $key = xl('IUD');
244 else if (preg_match('/^145212/', $code)) {
245 $key = xl('Emergency Contraception');
247 else if (preg_match('/^121181.13/', $code)) {
248 $key = xl('Female VSC');
250 else if (preg_match('/^122182.13/', $code)) {
251 $key = xl('Male VSC');
253 else if (preg_match('/^131191.10/', $code)) {
254 $key = xl('Awareness-Based');
256 return $key;
259 // Translate an IPPF code to the corresponding descriptive name of its
260 // abortion method, or to an empty string if none applies.
262 function getAbortionMethod($code) {
263 $key = '';
264 if (preg_match('/^25222[34]/', $code)) {
265 if (preg_match('/^2522231/', $code)) {
266 $key = xl('D&C');
268 else if (preg_match('/^2522232/', $code)) {
269 $key = xl('D&E');
271 else if (preg_match('/^2522233/', $code)) {
272 $key = xl('MVA');
274 else if (preg_match('/^252224/', $code)) {
275 $key = xl('Medical');
277 else {
278 $key = xl('Other Surgical');
281 return $key;
284 // Helper function to look up the GCAC issue associated with a visit.
285 // Ideally this is the one and only GCAC issue linked to the encounter.
286 // However if there are multiple such issues, or if only unlinked issues
287 // are found, then we pick the one with its start date closest to the
288 // encounter date.
290 function getGcacData($row, $what, $morejoins="") {
291 $patient_id = $row['pid'];
292 $encounter_id = $row['encounter'];
293 $encdate = substr($row['encdate'], 0, 10);
294 $query = "SELECT $what " .
295 "FROM lists AS l " .
296 "JOIN lists_ippf_gcac AS lg ON l.type = 'ippf_gcac' AND lg.id = l.id " .
297 "LEFT JOIN issue_encounter AS ie ON ie.pid = '$patient_id' AND " .
298 "ie.encounter = '$encounter_id' AND ie.list_id = l.id " .
299 "$morejoins " .
300 "WHERE l.pid = '$patient_id' AND " .
301 "l.activity = 1 AND l.type = 'ippf_gcac' " .
302 "ORDER BY ie.pid DESC, ABS(DATEDIFF(l.begdate, '$encdate')) ASC " .
303 "LIMIT 1";
304 // Note that reverse-ordering by ie.pid is a trick for sorting
305 // issues linked to the encounter (non-null values) first.
306 return sqlQuery($query);
309 // Get the "client status" field from the related GCAC issue.
311 function getGcacClientStatus($row) {
312 $irow = getGcacData($row, "lo.title", "LEFT JOIN list_options AS lo ON " .
313 "lo.list_id = 'clientstatus' AND lo.option_id = lg.client_status");
314 if (empty($irow['title'])) {
315 $key = xl('Indeterminate');
317 else {
318 // The client status description should be just fine for this.
319 $key = $irow['title'];
321 return $key;
324 // Helper function called after the reporting key is determined for a row.
326 function loadColumnData($key, $row) {
327 global $areport, $arr_titles, $form_cors, $from_date, $to_date;
329 // global $previous_pid;
330 // if ($form_cors == '2' && $row['pid'] == $previous_pid) return;
331 // $previous_pid = $row['pid'];
333 // If first instance of this key, initialize its arrays.
334 if (empty($areport[$key])) {
335 $areport[$key] = array();
336 $areport[$key]['wom'] = 0; // number of services for women
337 $areport[$key]['men'] = 0; // number of services for men
338 $areport[$key]['age'] = array(0,0,0,0,0,0,0,0,0); // age array
339 $areport[$key]['rel'] = array(); // religion array
340 $areport[$key]['nat'] = array(); // nationality array
341 $areport[$key]['mar'] = array(); // marital status array
342 $areport[$key]['sta'] = array(); // state/parish array
343 $areport[$key]['occ'] = array(); // occupation array
344 $areport[$key]['cit'] = array(); // city array
345 $areport[$key]['edu'] = array(); // education array
346 $areport[$key]['inc'] = array(); // income array
347 $areport[$key]['pro'] = array(); // provider array
348 $areport[$key]['prp'] = 0; // previous pid
351 // Skip this key if we are counting unique patients and the key
352 // has already seen this patient.
353 if ($form_cors == '2' && $row['pid'] == $areport[$key]['prp']) return;
355 // If we are counting new acceptors, then require a unique patient
356 // whose contraceptive start date is within the reporting period.
357 if ($form_cors == '3') {
358 if ($row['pid'] == $areport[$key]['prp']) return;
359 // Check contraceptive start date.
360 if (!$row['contrastart'] || $row['contrastart'] < $from_date ||
361 $row['contrastart'] > $to_date) return;
364 // If we are counting new clients, then require a unique patient
365 // whose registration date is within the reporting period.
366 if ($form_cors == '4') {
367 if ($row['pid'] == $areport[$key]['prp']) return;
368 // Check registration date.
369 if (!$row['regdate'] || $row['regdate'] < $from_date ||
370 $row['regdate'] > $to_date) return;
373 // Flag this patient as having been encountered for this report row.
374 $areport[$key]['prp'] = $row['pid'];
376 /*******************************************************************
377 // Increment the number of unique clients.
378 if ($row['pid'] != $previous_pid) {
379 ++$areport[$key]['cli'];
380 $previous_pid = $row['pid'];
382 *******************************************************************/
384 // Increment the correct sex category.
385 if (strcasecmp($row['sex'], 'Male') == 0)
386 ++$areport[$key]['men'];
387 else
388 ++$areport[$key]['wom'];
390 // Increment the correct age category.
391 $age = getAge(fixDate($row['DOB']), $row['encdate']);
392 $i = min(intval(($age - 5) / 5), 8);
393 if ($age < 11) $i = 0;
394 ++$areport[$key]['age'][$i];
396 // Increment the correct religion category.
397 $religion = empty($row['userlist5']) ? 'Unspecified' : $row['userlist5'];
398 $areport[$key]['rel'][$religion] += 1;
399 $arr_titles['rel'][$religion] += 1;
401 // Increment the correct nationality category.
402 $nationality = empty($row['country_code']) ? 'Unspecified' : $row['country_code'];
403 $areport[$key]['nat'][$nationality] += 1;
404 $arr_titles['nat'][$nationality] += 1;
406 // Increment the correct marital status category.
407 $status = empty($row['status']) ? 'Unspecified' : $row['status'];
408 $areport[$key]['mar'][$status] += 1;
409 $arr_titles['mar'][$status] += 1;
411 // Increment the correct state/parish category.
412 $status = empty($row['state']) ? 'Unspecified' : $row['state'];
413 $areport[$key]['sta'][$status] += 1;
414 $arr_titles['sta'][$status] += 1;
416 // Increment the correct occupation category.
417 $status = empty($row['occupation']) ? 'Unspecified' : $row['occupation'];
418 $areport[$key]['occ'][$status] += 1;
419 $arr_titles['occ'][$status] += 1;
421 // Increment the correct city category.
422 $status = empty($row['city']) ? 'Unspecified' : $row['city'];
423 $areport[$key]['cit'][$status] += 1;
424 $arr_titles['cit'][$status] += 1;
426 // Increment the correct education category.
427 $status = empty($row['userlist2']) ? 'Unspecified' : $row['userlist2'];
428 $areport[$key]['edu'][$status] += 1;
429 $arr_titles['edu'][$status] += 1;
431 // Increment the correct income category.
432 $status = empty($row['userlist3']) ? 'Unspecified' : $row['userlist3'];
433 $areport[$key]['inc'][$status] += 1;
434 $arr_titles['inc'][$status] += 1;
436 // Increment the correct provider category.
437 $status = empty($row['provider']) ? 'Unknown' : $row['provider'];
438 $areport[$key]['pro'][$status] += 1;
439 $arr_titles['pro'][$status] += 1;
442 // This is called for each IPPF service code that is selected.
444 function process_ippf_code($row, $code) {
445 global $areport, $arr_titles, $form_by;
447 $key = 'Unspecified';
449 // General Service Category.
451 if ($form_by === '1') {
452 if (preg_match('/^1/', $code)) {
453 $key = xl('SRH - Family Planning');
455 else if (preg_match('/^2/', $code)) {
456 $key = xl('SRH Non Family Planning');
458 else if (preg_match('/^3/', $code)) {
459 $key = xl('Non-SRH Medical');
461 else if (preg_match('/^4/', $code)) {
462 $key = xl('Non-SRH Non-Medical');
464 else {
465 $key = xl('Invalid Service Codes');
469 // Specific Services. One row for each IPPF code.
471 else if ($form_by === '4') {
472 $key = $code;
475 // Abortion Method.
477 else if ($form_by === '5') {
478 $key = getAbortionMethod($code);
479 if (empty($key)) return;
482 // Contraceptive Method.
484 else if ($form_by === '6') {
485 $key = getContraceptiveMethod($code);
486 if (empty($key)) return;
489 // Contraceptive method for new contraceptive adoption following abortion.
490 // Get it from the IPPF code if an abortion issue is linked to the visit.
491 // Note we are handling this during processing of services rather than
492 // by enumerating issues, because we need the service date.
494 else if ($form_by === '7') {
495 $key = getContraceptiveMethod($code);
496 if (empty($key)) return;
497 $patient_id = $row['pid'];
498 $encounter_id = $row['encounter'];
499 $query = "SELECT COUNT(*) AS count " .
500 "FROM lists AS l " .
501 "JOIN issue_encounter AS ie ON ie.pid = '$patient_id' AND " .
502 "ie.encounter = '$encounter_id' AND ie.list_id = l.id " .
503 "WHERE l.pid = '$patient_id' AND " .
504 "l.activity = 1 AND l.type = 'ippf_gcac'";
505 // echo "<!-- $key: $query -->\n"; // debugging
506 $irow = sqlQuery($query);
507 if (empty($irow['count'])) return;
510 // Post-Abortion Care by Source.
511 // Requirements just call for counting sessions, but this way the columns
512 // can be anything - age category, religion, whatever.
514 else if ($form_by === '8') {
515 if (preg_match('/^252226/', $code)) { // all post-abortion care
516 $key = getGcacClientStatus($row);
517 } else {
518 return;
522 // Complications from abortion by abortion method and complication type.
523 // These may be noted either during recovery or during a followup visit.
524 // Again, driven by services in order to report by service date.
525 // Note: If there are multiple complications, they will all be reported.
527 else if ($form_by === '11') {
528 $compl_type = '';
529 if (preg_match('/^25222[345]/', $code)) { // all abortions including incomplete
530 $compl_type = 'rec_compl';
532 else if (preg_match('/^252226/', $code)) { // all post-abortion care
533 $compl_type = 'fol_compl';
535 else {
536 return;
538 $irow = getGcacData($row, "lg.$compl_type, lo.title",
539 "LEFT JOIN list_options AS lo ON lo.list_id = 'in_ab_proc' AND " .
540 "lo.option_id = lg.in_ab_proc");
541 if (empty($irow)) return; // this should not happen
542 if (empty($irow[$compl_type])) return; // ok, no complications
543 // We have one or more complications.
544 $abtype = empty($irow['title']) ? xl('Indeterminate') : $irow['title'];
545 $acompl = explode('|', $irow[$compl_type]);
546 foreach ($acompl as $compl) {
547 $crow = sqlQuery("SELECT title FROM list_options WHERE " .
548 "list_id = 'complication' AND option_id = '$compl'");
549 $key = "$abtype / " . $crow['title'];
550 loadColumnData($key, $row);
552 return; // because loadColumnData() is already done.
555 // Pre-Abortion Counseling. Three possible situations:
556 // Provided abortion in the MA clinics
557 // Referred to other service providers (govt,private clinics)
558 // Decided not to have the abortion
560 else if ($form_by === '12') {
561 if (preg_match('/^252221/', $code)) { // all pre-abortion counseling
562 $key = getGcacClientStatus($row);
563 } else {
564 return;
568 // Patient Name.
570 else if ($form_by === '17') {
571 $key = $row['lname'] . ', ' . $row['fname'] . ' ' . $row['mname'];
574 else {
575 return;
578 // OK we now have the reporting key for this issue.
580 loadColumnData($key, $row);
583 // This is called for each MA service code that is selected.
585 function process_ma_code($row) {
586 global $form_by, $arr_content, $form_cors;
588 $key = 'Unspecified';
590 // One row for each service category.
592 if ($form_by === '101') {
593 if (!empty($row['title'])) $key = xl($row['title']);
596 // Specific Services. One row for each MA code.
598 else if ($form_by === '102') {
599 $key = $row['code'];
602 // One row for each referral source.
604 else if ($form_by === '103') {
605 $key = $row['referral_source'];
608 // Just one row.
610 else if ($form_by === '2') {
611 $key = $arr_content[$form_cors];
614 else {
615 return;
618 loadColumnData($key, $row);
621 /*********************************************************************
622 // This is called for each issue that is selected.
624 function process_issue($row) {
625 global $form_by;
627 $key = 'Unspecified';
629 // Pre-Abortion Counseling. Three possible rows:
630 // Provided abortion in the MA clinics
631 // Referred to other service providers (govt,private clinics)
632 // Decided not to have the abortion
634 if ($form_by === '12') {
636 // TBD: Assign one of the 3 keys, or just return.
640 // Others TBD
642 else {
643 return;
646 // TBD: Load column data from the issue.
647 // loadColumnData($key, $row);
649 *********************************************************************/
651 // This is called for each selected referral.
652 // Row keys are the first specified MA code, if any.
654 function process_referral($row) {
655 $key = 'Unspecified';
656 if (!empty($row['refer_related_code'])) {
657 $relcodes = explode(';', $row['refer_related_code']);
658 foreach ($relcodes as $codestring) {
659 if ($codestring === '') continue;
660 list($codetype, $code) = explode(':', $codestring);
661 if ($codetype !== 'MA') continue;
662 $key = $code;
663 break;
666 loadColumnData($key, $row);
669 // If we are doing the CSV export then generate the needed HTTP headers.
670 // Otherwise generate HTML.
672 if ($form_output == 3) {
673 header("Pragma: public");
674 header("Expires: 0");
675 header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
676 header("Content-Type: application/force-download");
677 header("Content-Disposition: attachment; filename=service_statistics_report.csv");
678 header("Content-Description: File Transfer");
680 else {
682 <html>
683 <head>
684 <?php html_header_show(); ?>
685 <title><?php echo $report_title; ?></title>
686 <style type="text/css">@import url(../../library/dynarch_calendar.css);</style>
687 <style type="text/css">
688 body { font-family:sans-serif; font-size:10pt; font-weight:normal }
689 .dehead { color:#000000; font-family:sans-serif; font-size:10pt; font-weight:bold }
690 .detail { color:#000000; font-family:sans-serif; font-size:10pt; font-weight:normal }
691 </style>
692 <script type="text/javascript" src="../../library/textformat.js"></script>
693 <script type="text/javascript" src="../../library/dynarch_calendar.js"></script>
694 <script type="text/javascript" src="../../library/dynarch_calendar_en.js"></script>
695 <script type="text/javascript" src="../../library/dynarch_calendar_setup.js"></script>
696 <script language="JavaScript">
697 var mypcc = '<?php echo $GLOBALS['phone_country_code'] ?>';
698 </script>
699 </head>
701 <body leftmargin='0' topmargin='0' marginwidth='0' marginheight='0'>
703 <center>
705 <h2><?php echo $report_title; ?></h2>
707 <form name='theform' method='post'
708 action='ippf_statistics.php?t=<?php echo $report_type ?>'>
710 <table border='0' cellspacing='5' cellpadding='1'>
711 <tr>
712 <td valign='top' class='dehead' nowrap>
713 <?php xl('Rows','e'); ?>:
714 </td>
715 <td valign='top' class='detail'>
716 <select name='form_by' title='Left column of report'>
717 <?php
718 foreach ($arr_by as $key => $value) {
719 echo " <option value='$key'";
720 if ($key == $form_by) echo " selected";
721 echo ">" . $value . "</option>\n";
724 </select>
725 </td>
726 <td valign='top' class='dehead' nowrap>
727 <?php xl('Content','e'); ?>:
728 </td>
729 <td valign='top' class='detail'>
730 <select name='form_cors' title='<?php xl('What is to be counted?','e'); ?>'>
731 <?php
732 foreach ($arr_content as $key => $value) {
733 echo " <option value='$key'";
734 if ($key == $form_cors) echo " selected";
735 echo ">$value</option>\n";
738 </select>
739 </td>
740 <td valign='top' class='detail'>
741 &nbsp;
742 </td>
743 </tr>
744 <tr>
745 <td valign='top' class='dehead' nowrap>
746 <?php xl('Columns','e'); ?>:
747 </td>
748 <td valign='top' class='detail'>
749 <select name='form_show[]' size='4' multiple
750 title='<?php xl('Hold down Ctrl to select multiple items','e'); ?>'>
751 <?php
752 foreach ($arr_show as $key => $value) {
753 echo " <option value='$key'";
754 if (is_array($form_show) && in_array($key, $form_show)) echo " selected";
755 echo ">" . $value . "</option>\n";
758 </select>
759 </td>
760 <td valign='top' class='dehead' nowrap>
761 <?php xl('Filters','e'); ?>:
762 </td>
763 <td colspan='2' class='detail' style='border-style:solid;border-width:1px;border-color:#cccccc'>
764 <table>
765 <tr>
766 <td valign='top' class='detail' nowrap>
767 <?php xl('Sex','e'); ?>:
768 </td>
769 <td class='detail' valign='top'>
770 <select name='form_sexes' title='<?php xl('To filter by sex','e'); ?>'>
771 <?php
772 foreach (array(3 => xl('Men and Women'), 1 => xl('Women Only'), 2 => xl('Men Only')) as $key => $value) {
773 echo " <option value='$key'";
774 if ($key == $form_sexes) echo " selected";
775 echo ">$value</option>\n";
778 </select>
779 </td>
780 </tr>
781 <tr>
782 <td valign='top' class='detail' nowrap>
783 <?php xl('Facility','e'); ?>:
784 </td>
785 <td valign='top' class='detail'>
786 <?php
787 // Build a drop-down list of facilities.
789 $query = "SELECT id, name FROM facility ORDER BY name";
790 $fres = sqlStatement($query);
791 echo " <select name='form_facility'>\n";
792 echo " <option value=''>-- All Facilities --\n";
793 while ($frow = sqlFetchArray($fres)) {
794 $facid = $frow['id'];
795 echo " <option value='$facid'";
796 if ($facid == $_POST['form_facility']) echo " selected";
797 echo ">" . $frow['name'] . "\n";
799 echo " </select>\n";
801 </td>
802 </tr>
803 <tr>
804 <td colspan='2' class='detail' nowrap>
805 <?php xl('From','e'); ?>
806 <input type='text' name='form_from_date' id='form_from_date' size='10' value='<?php echo $from_date ?>'
807 onkeyup='datekeyup(this,mypcc)' onblur='dateblur(this,mypcc)' title='Start date yyyy-mm-dd'>
808 <img src='../pic/show_calendar.gif' align='absbottom' width='24' height='22'
809 id='img_from_date' border='0' alt='[?]' style='cursor:pointer'
810 title='<?php xl('Click here to choose a date','e'); ?>'>
811 <?php xl('To','e'); ?>
812 <input type='text' name='form_to_date' id='form_to_date' size='10' value='<?php echo $to_date ?>'
813 onkeyup='datekeyup(this,mypcc)' onblur='dateblur(this,mypcc)' title='End date yyyy-mm-dd'>
814 <img src='../pic/show_calendar.gif' align='absbottom' width='24' height='22'
815 id='img_to_date' border='0' alt='[?]' style='cursor:pointer'
816 title='<?php xl('Click here to choose a date','e'); ?>'>
817 </td>
818 </tr>
819 </table>
820 </td>
821 </tr>
822 <tr>
823 <td valign='top' class='dehead' nowrap>
824 <?php xl('To','e'); ?>:
825 </td>
826 <td colspan='3' valign='top' class='detail' nowrap>
827 <?php
828 foreach (array(1 => 'Screen', 2 => 'Printer', 3 => 'Export File') as $key => $value) {
829 echo " <input type='radio' name='form_output' value='$key'";
830 if ($key == $form_output) echo ' checked';
831 echo " />$value &nbsp;";
834 </td>
835 <td align='right' valign='top' class='detail' nowrap>
836 <input type='submit' name='form_submit' value='<?php xl('Submit','e'); ?>'
837 title='<?php xl('Click to generate the report','e'); ?>' />
838 </td>
839 </tr>
840 <tr>
841 <td colspan='5' height="1">
842 </td>
843 </tr>
844 </table>
845 <?php
846 } // end not export
848 if ($_POST['form_submit']) {
849 $sexcond = '';
850 if ($form_sexes == '1') $sexcond = "AND pd.sex NOT LIKE 'Male' ";
851 else if ($form_sexes == '2') $sexcond = "AND pd.sex LIKE 'Male' ";
853 // Get referrals and related patient data.
854 if ($form_by === '9' || $form_by === '10') {
855 $exttest = $form_by === '9' ? '=' : '!=';
856 $query = "SELECT " .
857 "t.refer_related_code, t.pid, pd.regdate, pd.referral_source, " .
858 "pd.sex, pd.DOB, pd.lname, pd.fname, pd.mname, pd.userlist5, " .
859 "pd.country_code, pd.status, pd.state, pd.occupation, pd.contrastart, " .
860 "pd.city, pd.userlist2, pd.userlist3 " .
861 "FROM transactions AS t " .
862 "JOIN patient_data AS pd ON pd.pid = t.pid $sexcond" .
863 "WHERE t.title = 'Referral' AND t.refer_date >= '$from_date' AND " .
864 "t.refer_date <= '$to_date' AND refer_external $exttest '0' " .
865 "ORDER BY t.pid, t.id";
866 $res = sqlStatement($query);
867 while ($row = sqlFetchArray($res)) {
868 process_referral($row);
871 /*****************************************************************
872 else if ($form_by === '12') {
873 // We are reporting on a date range, and assume the applicable date is
874 // the issue start date which is presumably also the date of pre-
875 // abortion counseling. The issue end date and the surgery date are
876 // not of interest here.
877 $query = "SELECT " .
878 "l.type, l.begdate, l.pid, " .
879 "pd.sex, pd.DOB, pd.lname, pd.fname, pd.mname, pd.userlist5, " .
880 "pd.country_code, pd.status, pd.state, pd.occupation, " .
881 "lg.client_status, lg.ab_location " .
882 "FROM lists AS l " .
883 "JOIN patient_data AS pd ON pd.pid = l.pid $sexcond" .
884 "LEFT OUTER JOIN lists_ippf_gcac AS lg ON l.type = 'ippf_gcac' AND lg.id = l.id " .
885 // "LEFT OUTER JOIN lists_ippf_con AS lc ON l.type = 'contraceptive' AND lc.id = l.id " .
886 "WHERE l.begdate >= '$from_date' AND l.begdate <= '$to_date' AND " .
887 "l.activity = 1 AND l.type = 'ippf_gcac' " .
888 "ORDER BY l.pid, l.id";
889 $res = sqlStatement($query);
890 while ($row = sqlFetchArray($res)) {
891 process_issue($row);
894 *****************************************************************/
895 else {
896 // This gets us all MA codes, with encounter and patient
897 // info attached and grouped by patient and encounter.
898 $query = "SELECT " .
899 "fe.pid, fe.encounter, fe.date AS encdate, pd.regdate, " .
900 "f.user AS provider, " .
901 "pd.sex, pd.DOB, pd.lname, pd.fname, pd.mname, pd.userlist5, " .
902 "pd.country_code, pd.status, pd.state, pd.occupation, pd.contrastart, " .
903 "pd.referral_source, pd.city, pd.userlist2, pd.userlist3, " .
904 "b.code_type, b.code, c.related_code, lo.title " .
905 "FROM form_encounter AS fe " .
906 "JOIN forms AS f ON f.pid = fe.pid AND f.encounter = fe.encounter AND " .
907 "f.formdir = 'newpatient' AND f.form_id = fe.id AND f.deleted = 0 " .
908 "JOIN patient_data AS pd ON pd.pid = fe.pid $sexcond" .
909 "LEFT OUTER JOIN billing AS b ON " .
910 "b.pid = fe.pid AND b.encounter = fe.encounter AND b.activity = 1 " .
911 "AND b.code_type = 'MA' " .
912 "LEFT OUTER JOIN codes AS c ON b.code_type = 'MA' AND c.code_type = '12' AND " .
913 "c.code = b.code AND c.modifier = b.modifier " .
914 "LEFT OUTER JOIN list_options AS lo ON " .
915 "lo.list_id = 'superbill' AND lo.option_id = c.superbill " .
916 "WHERE fe.date >= '$from_date 00:00:00' AND " .
917 "fe.date <= '$to_date 23:59:59' ";
919 if ($form_facility) {
920 $query .= "AND fe.facility_id = '$form_facility' ";
922 $query .= "ORDER BY fe.pid, fe.encounter, b.code";
923 $res = sqlStatement($query);
924 while ($row = sqlFetchArray($res)) {
925 if ($row['code_type'] === 'MA') {
926 process_ma_code($row);
927 if (!empty($row['related_code'])) {
928 $relcodes = explode(';', $row['related_code']);
929 foreach ($relcodes as $codestring) {
930 if ($codestring === '') continue;
931 list($codetype, $code) = explode(':', $codestring);
932 if ($codetype !== 'IPPF') continue;
933 process_ippf_code($row, $code);
937 } // end while
938 } // end else
940 // Sort everything by key for reporting.
941 ksort($areport);
942 ksort($arr_titles['rel']);
943 ksort($arr_titles['nat']);
944 ksort($arr_titles['mar']);
945 ksort($arr_titles['sta']);
946 ksort($arr_titles['occ']);
947 ksort($arr_titles['cit']);
948 ksort($arr_titles['edu']);
949 ksort($arr_titles['inc']);
950 ksort($arr_titles['pro']);
952 if ($form_output != 3) {
953 echo "<table border='0' cellpadding='1' cellspacing='2' width='98%'>\n";
954 } // end not csv export
956 genStartRow("bgcolor='#dddddd'");
958 // If the key is an MA or IPPF code, then add a column for its description.
959 if ($form_by === '4' || $form_by === '102' || $form_by === '9' || $form_by === '10') {
960 genHeadCell(array($arr_by[$form_by], xl('Description')));
961 } else {
962 genHeadCell($arr_by[$form_by]);
965 // Generate headings for values to be shown.
966 foreach ($form_show as $value) {
967 if ($value == '1') { // Total Services
968 genHeadCell(xl('Total'));
970 /***************************************************************
971 else if ($value == '9') { // Total Unique Clients
972 genHeadCell(xl('Clients'));
974 ***************************************************************/
975 else if ($value == '2') { // Age
976 genHeadCell(xl('0-10' ), true);
977 genHeadCell(xl('11-14'), true);
978 genHeadCell(xl('15-19'), true);
979 genHeadCell(xl('20-24'), true);
980 genHeadCell(xl('25-29'), true);
981 genHeadCell(xl('30-34'), true);
982 genHeadCell(xl('35-39'), true);
983 genHeadCell(xl('40-44'), true);
984 genHeadCell(xl('45+' ), true);
986 else if ($value == '3') { // Sex
987 genHeadCell(xl('Women'), true);
988 genHeadCell(xl('Men' ), true);
990 else if ($value == '4') { // Religion
991 foreach ($arr_titles['rel'] as $key => $value) {
992 genHeadCell(getListTitle('userlist5',$key), true);
995 else if ($value == '5') { // Nationality
996 foreach ($arr_titles['nat'] as $key => $value) {
997 genHeadCell(getListTitle('country',$key), true);
1000 else if ($value == '6') { // Marital Status
1001 foreach ($arr_titles['mar'] as $key => $value) {
1002 genHeadCell(getListTitle('marital',$key), true);
1005 else if ($value == '7') { // State/Parish
1006 foreach ($arr_titles['sta'] as $key => $value) {
1007 genHeadCell($key, true);
1010 else if ($value == '8') { // Occupation
1011 foreach ($arr_titles['occ'] as $key => $value) {
1012 genHeadCell(getListTitle('occupations',$key), true);
1015 else if ($value == '10') { // City
1016 foreach ($arr_titles['cit'] as $key => $value) {
1017 genHeadCell($key, true);
1020 else if ($value == '11') { // Education
1021 foreach ($arr_titles['edu'] as $key => $value) {
1022 genHeadCell(getListTitle('userlist2',$key), true);
1025 else if ($value == '12') { // Income
1026 foreach ($arr_titles['inc'] as $key => $value) {
1027 genHeadCell(getListTitle('userlist3',$key), true);
1030 else if ($value == '13') { // Provider
1031 foreach ($arr_titles['pro'] as $key => $value) {
1032 genHeadCell($key, true);
1037 if ($form_output != 3) {
1038 genHeadCell(xl('Total'), true);
1041 genEndRow();
1043 $encount = 0;
1045 foreach ($areport as $key => $varr) {
1046 $bgcolor = (++$encount & 1) ? "#ddddff" : "#ffdddd";
1048 $dispkey = $key;
1050 // If the key is an MA or IPPF code, then add a column for its description.
1051 if ($form_by === '4' || $form_by === '102' || $form_by === '9' || $form_by === '10') {
1052 $dispkey = array($key, '');
1053 $type = $form_by === '4' ? 11 : 12; // IPPF or MA
1054 $crow = sqlQuery("SELECT code_text FROM codes WHERE " .
1055 "code_type = '$type' AND code = '$key' ORDER BY id LIMIT 1");
1056 if (!empty($crow['code_text'])) $dispkey[1] = $crow['code_text'];
1059 genStartRow("bgcolor='$bgcolor'");
1061 genAnyCell($dispkey, false, 'detail');
1063 // This is the column index for accumulating column totals.
1064 $cnum = 0;
1065 $totalsvcs = $areport[$key]['wom'] + $areport[$key]['men'];
1067 // Generate data for this row.
1068 foreach ($form_show as $value) {
1069 if ($value == '1') { // Total Services
1070 genNumCell($totalsvcs, $cnum++);
1072 /*************************************************************
1073 else if ($value == '9') { // Total Unique Clients
1074 genNumCell($areport[$key]['cli'], $cnum++);
1076 *************************************************************/
1077 else if ($value == '2') { // Age
1078 for ($i = 0; $i < 9; ++$i) {
1079 genNumCell($areport[$key]['age'][$i], $cnum++);
1082 else if ($value == '3') { // Sex
1083 genNumCell($areport[$key]['wom'], $cnum++);
1084 genNumCell($areport[$key]['men'], $cnum++);
1086 else if ($value == '4') { // Religion
1087 foreach ($arr_titles['rel'] as $title => $nothing) {
1088 genNumCell($areport[$key]['rel'][$title], $cnum++);
1091 else if ($value == '5') { // Nationality
1092 foreach ($arr_titles['nat'] as $title => $nothing) {
1093 genNumCell($areport[$key]['nat'][$title], $cnum++);
1096 else if ($value == '6') { // Marital Status
1097 foreach ($arr_titles['mar'] as $title => $nothing) {
1098 genNumCell($areport[$key]['mar'][$title], $cnum++);
1101 else if ($value == '7') { // State/Parish
1102 foreach ($arr_titles['sta'] as $title => $nothing) {
1103 genNumCell($areport[$key]['sta'][$title], $cnum++);
1106 else if ($value == '8') { // Occupation
1107 foreach ($arr_titles['occ'] as $title => $nothing) {
1108 genNumCell($areport[$key]['occ'][$title], $cnum++);
1111 else if ($value == '10') { // City
1112 foreach ($arr_titles['cit'] as $title => $nothing) {
1113 genNumCell($areport[$key]['cit'][$title], $cnum++);
1116 else if ($value == '11') { // Education
1117 foreach ($arr_titles['edu'] as $title => $nothing) {
1118 genNumCell($areport[$key]['edu'][$title], $cnum++);
1121 else if ($value == '12') { // Income
1122 foreach ($arr_titles['inc'] as $title => $nothing) {
1123 genNumCell($areport[$key]['inc'][$title], $cnum++);
1126 else if ($value == '13') { // Provider
1127 foreach ($arr_titles['pro'] as $title => $nothing) {
1128 genNumCell($areport[$key]['pro'][$title], $cnum++);
1133 // Write the Total column data.
1134 if ($form_output != 3) {
1135 $atotals[$cnum] += $totalsvcs;
1136 genAnyCell($totalsvcs, true, 'dehead');
1139 genEndRow();
1140 } // end foreach
1142 if ($form_output != 3) {
1143 // Generate the line of totals.
1144 genStartRow("bgcolor='#dddddd'");
1146 // If the key is an MA or IPPF code, then add a column for its description.
1147 if ($form_by === '4' || $form_by === '102' || $form_by === '9' || $form_by === '10') {
1148 genHeadCell(array(xl('Totals'), ''));
1149 } else {
1150 genHeadCell(xl('Totals'));
1153 for ($cnum = 0; $cnum < count($atotals); ++$cnum) {
1154 genHeadCell($atotals[$cnum], true);
1156 genEndRow();
1157 // End of table.
1158 echo "</table>\n";
1161 } // end of if refresh or export
1163 if ($form_output != 3) {
1165 </form>
1166 </center>
1168 <script language='JavaScript'>
1169 Calendar.setup({inputField:"form_from_date", ifFormat:"%Y-%m-%d", button:"img_from_date"});
1170 Calendar.setup({inputField:"form_to_date", ifFormat:"%Y-%m-%d", button:"img_to_date"});
1171 <?php if ($form_output == 2) { ?>
1172 window.print();
1173 <?php } ?>
1174 </script>
1176 </body>
1177 </html>
1178 <?php
1179 } // end not export