added many new features
[openemr.git] / interface / reports / ippf_statistics.php
blob8d3bcb8b24c4089ffee5e6cd0c3af342d93abb3c
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_sexes = $_POST['form_sexes']; // this is a scalar
21 if (empty($form_by)) $form_by = '1';
22 if (empty($form_show)) $form_show = array('1');
23 if (empty($form_sexes)) $form_sexes = '3';
25 // One of these is chosen as the left column, or Y-axis, of the report.
27 if ($report_type == 'm') {
28 $arr_by = array(
29 101 => xl('MA Category'),
30 102 => xl('Specific Service'),
31 17 => xl('Patient'),
32 9 => xl('Referrals'),
35 else {
36 $arr_by = array(
37 1 => xl('General Service Category'),
38 // 2 => xl('Gynecology/Obstretrics'),
39 // 3 => xl('Urology'),
40 4 => xl('Specific Service'),
41 5 => xl('Abortion Method'),
42 6 => xl('Contraceptive Method'),
43 7 => xl('Con. Method Following Abortion'),
44 8 => xl('Post-Abortion Care by Source'),
45 9 => xl('Referrals'),
46 // 10 => xl('Abortion Referral Followups'), // duplicates #8?
47 11 => xl('Complications of Abortion'),
51 /*******************************************************************
53 // 2 Rows: New, Old.
54 7 => xl('New and Old Clients'),
56 // 9 Rows: 0-10, 11-14, 15-19, 20-24, 25-29, 30-34, 35-39, 40-44, 45+.
57 8 => xl('Age Category'),
59 // 2 Rows: Male, Female.
60 9 => xl('Sex'),
62 // One row for each unique marital status.
63 10 => xl('Marital Status'),
65 // One row for each unique zone of residence.
66 11 => xl('Residence Zone'),
68 // One row for each unique country.
69 12 => xl('Nationality'),
71 // One row for each unique education level.
72 13 => xl('Education Level'),
74 // One row for each unique occupation.
75 14 => xl('Occupation'),
77 // One row for each unique number of living children.
78 15 => xl('Number of Living Children'),
80 // One row for each practitioner at the clinic.
81 16 => xl('Provider'),
83 *******************************************************************/
85 // A reported value is either scalar, or an array listed horizontally. If
86 // multiple items are chosen then each starts in the next available column.
88 $arr_show = array(
89 1 => xl('Total Services'),
90 2 => xl('Age Category'),
91 3 => xl('Sex'),
92 4 => xl('Religion'),
93 5 => xl('Nationality'),
94 6 => xl('Marital Status'),
95 7 => xl('State/Parish'),
96 8 => xl('Occupation'),
97 /*******************************************************************
98 7 => xl('Contraceptive Method'),
99 8 => xl('Type of Complication'),
100 *******************************************************************/
103 // These are ICD9 codes that indicate complications of abortion.
104 // Emailed to Rod by AM on 2008-03-19.
105 // A = Incomplete abortion or retention of ovular products
106 // B = Excessive bleeding/hemorrhage
107 // C = Trauma to vagina, cervix, or uterus
108 // D = Shock
109 // E = Infection
110 // F = Continuing pregnancy
111 // G = Ectopic pregnancy
112 // H = Other complications
113 // They really want to use ICD10 instead, but the decision was to do
114 // that later.
115 $arr_dx_attrs = array(
116 '632' => 'A',
117 '634' => 'E',
118 '634.01' => 'EA',
119 '634.02' => 'E',
120 '634.1' => 'B',
121 '634.11' => 'BA',
122 '634.12' => 'B',
123 '634.2' => 'C',
124 '634.21' => 'CA',
125 '634.22' => 'C',
126 '634.3' => 'D',
127 '634.31' => 'DA',
128 '634.32' => 'D',
129 '634.4' => 'H',
130 '634.41' => 'HA',
131 '634.42' => 'H',
132 '634.5' => 'D',
133 '634.51' => 'DA',
134 '634.52' => 'D',
135 '634.6' => 'D',
136 '634.61' => 'DA',
137 '634.62' => 'D',
138 '634.7' => 'H',
139 '634.71' => 'HA',
140 '634.72' => 'H',
141 '634.8' => 'H',
142 '634.81' => 'HA',
143 '634.82' => 'H',
144 '634.91' => 'A',
145 '635' => 'E',
146 '635.01' => 'EA',
147 '635.02' => 'E',
148 '635.1' => 'B',
149 '635.11' => 'BA',
150 '635.12' => 'B',
151 '635.2' => 'C',
152 '635.21' => 'CA',
153 '635.22' => 'C',
154 '635.3' => 'D',
155 '635.31' => 'DA',
156 '635.32' => 'D',
157 '635.4' => 'H',
158 '635.41' => 'HA',
159 '635.42' => 'H',
160 '635.5' => 'D',
161 '635.51' => 'DA',
162 '635.52' => 'D',
163 '635.6' => 'D',
164 '635.61' => 'DA',
165 '635.62' => 'D',
166 '635.7' => 'H',
167 '635.71' => 'HA',
168 '635.72' => 'H',
169 '635.8' => 'H',
170 '635.81' => 'HA',
171 '635.82' => 'H',
172 '635.91' => 'A',
173 '636' => 'E',
174 '636.01' => 'EA',
175 '636.02' => 'E',
176 '636.1' => 'B',
177 '636.11' => 'BA',
178 '636.12' => 'B',
179 '636.2' => 'C',
180 '636.21' => 'CA',
181 '636.22' => 'C',
182 '636.3' => 'D',
183 '636.31' => 'DA',
184 '636.32' => 'D',
185 '636.4' => 'H',
186 '636.41' => 'HA',
187 '636.42' => 'H',
188 '636.5' => 'D',
189 '636.51' => 'DA',
190 '636.52' => 'D',
191 '636.6' => 'D',
192 '636.61' => 'DA',
193 '636.62' => 'D',
194 '636.7' => 'H',
195 '636.71' => 'HA',
196 '636.72' => 'H',
197 '636.8' => 'H',
198 '636.81' => 'HA',
199 '636.82' => 'H',
200 '636.91' => 'A',
201 '637' => 'E',
202 '637.01' => 'AE',
203 '637.02' => 'E',
204 '637.1' => 'B',
205 '637.11' => 'AB',
206 '637.12' => 'B',
207 '637.2' => 'C',
208 '637.21' => 'AC',
209 '637.22' => 'C',
210 '637.3' => 'D',
211 '637.31' => 'AD',
212 '637.32' => 'D',
213 '637.4' => 'H',
214 '637.41' => 'AH',
215 '637.42' => 'H',
216 '637.5' => 'D',
217 '637.51' => 'AD',
218 '637.52' => 'D',
219 '637.6' => 'D',
220 '637.61' => 'AD',
221 '637.62' => 'D',
222 '637.7' => 'H',
223 '637.71' => 'AH',
224 '637.72' => 'H',
225 '637.8' => 'H',
226 '637.81' => 'AH',
227 '637.82' => 'H',
228 '637.9' => 'H',
229 '637.91' => 'A',
230 '638' => 'EF',
231 '638.1' => 'BF',
232 '638.2' => 'CF',
233 '638.3' => 'DF',
234 '638.4' => 'HF',
235 '638.5' => 'DF',
236 '638.6' => 'DF',
237 '638.7' => 'HF',
238 '638.8' => 'HF',
239 '638.9' => 'F',
240 '639' => 'Eg', // lower case means "possibly" ... how to handle that?
241 '639.1' => 'Bg',
242 '639.2' => 'Cg',
243 '639.3' => 'Dg',
244 '639.4' => 'Hg',
245 '639.5' => 'Dg',
246 '639.6' => 'Dg',
247 '639.8' => 'Hg',
248 '639.9' => 'Hg',
249 '640' => 'A',
250 '640.01' => 'A',
251 '640.03' => 'A',
254 // This will become the array of reportable values.
255 $areport = array();
257 // Arrays of titles for some column headings.
258 $arr_titles = array(
259 'rel' => array(),
260 'nat' => array(),
261 'mar' => array(),
262 'sta' => array(),
263 'occ' => array(),
264 // 'met' => array(),
265 // 'toc' => array(),
268 // This tracks the descriptive name of the last abortion method
269 // encountered for the current patient.
270 $last_abortion_method = '';
272 // This is so we know when the above-mentioned current patient changes.
273 $last_pid = '';
275 // Compute age in years given a DOB and "as of" date.
277 function getAge($dob, $asof='') {
278 if (empty($asof)) $asof = date('Y-m-d');
279 $a1 = explode('-', substr($dob , 0, 10));
280 $a2 = explode('-', substr($asof, 0, 10));
281 $age = $a2[0] - $a1[0];
282 if ($a2[1] < $a1[1] || ($a2[1] == $a1[1] && $a2[2] < $a1[2])) --$age;
283 // echo "<!-- $dob $asof $age -->\n"; // debugging
284 return $age;
287 $cellcount = 0;
289 function genStartRow($att) {
290 global $cellcount;
291 if (! $_POST['form_csvexport']) echo " <tr $att>\n";
292 $cellcount = 0;
295 function genEndRow() {
296 if ($_POST['form_csvexport']) {
297 echo "\n";
299 else {
300 echo " </tr>\n";
304 function genAnyCell($data, $right=false, $class='') {
305 global $cellcount;
306 if ($_POST['form_csvexport']) {
307 if ($cellcount) echo ',';
308 echo '"' . $data . '"';
310 else {
311 echo " <td";
312 if ($class) echo " class='$class'";
313 if ($right) echo " align='right'";
314 echo ">$data</td>\n";
316 ++$cellcount;
319 function genHeadCell($data, $right=false) {
320 genAnyCell($data, $right, 'dehead');
323 function genNumCell($num) {
324 if (empty($num) && !$_POST['form_csvexport']) $num = '&nbsp;';
325 genAnyCell($num, $right, 'detail');
328 // Translate an IPPF code to the corresponding descriptive name of its
329 // contraceptive method, or to an empty string if none applies.
331 function getContraceptiveMethod($code) {
332 $key = '';
333 if (preg_match('/^111101/', $code)) {
334 $key = xl('Pills');
336 else if (preg_match('/^11111[1-9]/', $code)) {
337 $key = xl('Injectables');
339 else if (preg_match('/^11112[1-9]/', $code)) {
340 $key = xl('Implants');
342 else if (preg_match('/^111132/', $code)) {
343 $key = xl('Patch');
345 else if (preg_match('/^111133/', $code)) {
346 $key = xl('Vaginal Ring');
348 else if (preg_match('/^112141/', $code)) {
349 $key = xl('Male Condoms');
351 else if (preg_match('/^112142/', $code)) {
352 $key = xl('Female Condoms');
354 else if (preg_match('/^11215[1-9]/', $code)) {
355 $key = xl('Diaphragms/Caps');
357 else if (preg_match('/^11216[1-9]/', $code)) {
358 $key = xl('Spermicides');
360 else if (preg_match('/^11317[1-9]/', $code)) {
361 $key = xl('IUD');
363 else if (preg_match('/^145212/', $code)) {
364 $key = xl('Emergency Contraception');
366 else if (preg_match('/^121181.13/', $code)) {
367 $key = xl('Female VSC');
369 else if (preg_match('/^122182.13/', $code)) {
370 $key = xl('Male VSC');
372 else if (preg_match('/^131191.10/', $code)) {
373 $key = xl('Awareness-Based');
375 return $key;
378 // Translate an IPPF code to the corresponding descriptive name of its
379 // abortion method, or to an empty string if none applies.
381 function getAbortionMethod($code) {
382 $key = '';
383 if (preg_match('/^25222[34]/', $code)) {
384 if (preg_match('/^2522231/', $code)) {
385 $key = xl('D&C');
387 else if (preg_match('/^2522232/', $code)) {
388 $key = xl('D&E');
390 else if (preg_match('/^2522233/', $code)) {
391 $key = xl('MVA');
393 else if (preg_match('/^252224/', $code)) {
394 $key = xl('Medical');
396 else {
397 $key = xl('Other Surgical');
400 return $key;
403 // Helper function called after the reporting key is determined for a row.
405 function loadColumnData($key, $row) {
406 global $areport, $arr_titles;
408 // If first instance of this key, initialize its arrays.
409 if (empty($areport[$key])) {
410 $areport[$key] = array();
411 $areport[$key]['wom'] = 0; // number of services for women
412 $areport[$key]['men'] = 0; // number of services for men
413 $areport[$key]['age'] = array(0,0,0,0,0,0,0,0,0); // age array
414 $areport[$key]['rel'] = array(); // religion array
415 $areport[$key]['nat'] = array(); // nationality array
416 $areport[$key]['mar'] = array(); // marital status array
417 $areport[$key]['sta'] = array(); // state/parish array
418 $areport[$key]['occ'] = array(); // occupation array
421 // Increment the correct sex category.
422 if (strcasecmp($row['sex'], 'Male') == 0)
423 ++$areport[$key]['men'];
424 else
425 ++$areport[$key]['wom'];
427 // Increment the correct age category.
428 $age = getAge(fixDate($row['DOB']), $row['encdate']);
429 $i = min(intval(($age - 5) / 5), 8);
430 if ($age < 11) $i = 0;
431 ++$areport[$key]['age'][$i];
433 // Increment the correct religion category.
434 $religion = empty($row['userlist5']) ? 'Unspecified' : $row['userlist5'];
435 $areport[$key]['rel'][$religion] += 1;
436 $arr_titles['rel'][$religion] += 1;
438 // Increment the correct nationality category.
439 $nationality = empty($row['country_code']) ? 'Unspecified' : $row['country_code'];
440 $areport[$key]['nat'][$nationality] += 1;
441 $arr_titles['nat'][$nationality] += 1;
443 // Increment the correct marital status category.
444 $status = empty($row['status']) ? 'Unspecified' : $row['status'];
445 $areport[$key]['mar'][$status] += 1;
446 $arr_titles['mar'][$status] += 1;
448 // Increment the correct state/parish category.
449 $status = empty($row['state']) ? 'Unspecified' : $row['state'];
450 $areport[$key]['sta'][$status] += 1;
451 $arr_titles['sta'][$status] += 1;
453 // Increment the correct occupation category.
454 $status = empty($row['occupation']) ? 'Unspecified' : $row['occupation'];
455 $areport[$key]['occ'][$status] += 1;
456 $arr_titles['occ'][$status] += 1;
459 // This is called for each IPPF service code that is selected.
461 function process_ippf_code($row, $code) {
462 global $areport, $arr_titles, $form_by, $last_abortion_method, $last_pid;
464 // This tracks the last abortion method for the current patient.
465 // The reason for this is that when we encounter a diagnosis code
466 // for complication of abortion, we will know what the corresponding
467 // abortion method was.
468 if ($row['pid'] != $last_pid) {
469 $last_abortion_method = '';
470 $last_pid = $row['pid'];
472 $abortion_method = getAbortionMethod($code);
473 if ($abortion_method) $last_abortion_method = $abortion_method;
475 $key = 'Unspecified';
477 // General Service Category.
479 if ($form_by === '1') {
480 if (preg_match('/^1/', $code)) {
481 $key = xl('SRH - Family Planning');
483 else if (preg_match('/^2/', $code)) {
484 $key = xl('SRH Non Family Planning');
486 else if (preg_match('/^3/', $code)) {
487 $key = xl('Non-SRH Medical');
489 else if (preg_match('/^4/', $code)) {
490 $key = xl('Non-SRH Non-Medical');
492 else {
493 $key = xl('Invalid Service Codes');
497 /*******************************************************************
498 // Gynecology and Obstretrics.
500 else if ($form_by === '2') {
501 if (preg_match('/^25[56]/', $code)) { // All gynecological and obstretric
502 if (preg_match('/^255251/', $code)) {
503 $key = xl('Gyn Diagnostic Biopsy');
505 else if (preg_match('/^255252/', $code)) {
506 $key = xl('Gyn Diagnostic Endoscopy');
508 else if (preg_match('/^255253/', $code)) {
509 $key = xl('Gyn Diagnostic Imaging');
511 else if (preg_match('/^255254/', $code)) {
512 $key = xl('Gyn Diagnostic Exam');
514 else if (preg_match('/^255255/', $code)) {
515 $key = xl('Gyn Diagnostic Cytology');
517 else if (preg_match('/^255256/', $code)) {
518 $key = xl('Gyn Therapy');
520 else if (preg_match('/^255257/', $code)) {
521 $key = xl('Gyn Surgery');
523 else if (preg_match('/^255258/', $code)) {
524 $key = xl('Gyn Counseling');
526 else if (preg_match('/^256261/', $code)) {
527 $key = xl('Obs Pre Natal Diagn');
529 else if (preg_match('/^256262/', $code)) {
530 $key = xl('Obs Pre Natal Care');
532 else if (preg_match('/^256263/', $code)) {
533 $key = xl('Obs Pre Natal Counsel');
535 else if (preg_match('/^256264/', $code)) {
536 $key = xl('Obs Pregnancy Tests');
538 else if (preg_match('/^256265/', $code)) {
539 $key = xl('Obs Pre Natal Tests');
541 else if (preg_match('/^256267/', $code)) {
542 $key = xl('Obs Childbirth Surgery');
544 else if (preg_match('/^256268/', $code)) {
545 $key = xl('Obs Post Natal Care');
547 else if (preg_match('/^256269/', $code)) {
548 $key = xl('Obs Post Natal Counsel');
550 else {
551 $key = xl('Other Gyn/Obs');
554 else {
555 return; // not gynecological
559 // Urology
561 else if ($form_by === '3') {
562 if (preg_match('/^257/', $code)) { // All Urological
563 if (preg_match('/^257271/', $code)) {
564 $key = xl('Diag/Therapy Endoscopy');
566 else if (preg_match('/^257272/', $code)) {
567 $key = xl('Diag/Therapy Imaging');
569 else if (preg_match('/^257273/', $code)) {
570 $key = xl('Diagnostic Other');
572 else if (preg_match('/^257274/', $code)) {
573 $key = xl('Surgery');
575 else {
576 $key = xl('Other Urological');
579 else {
580 return; // not urological
583 *******************************************************************/
585 // Specific Services. One row for each IPPF code.
587 else if ($form_by === '4') {
588 $key = $code;
591 // Abortion Method.
593 else if ($form_by === '5') {
594 if (!$abortion_method) return;
595 $key = $abortion_method;
598 // Contraceptive Method.
600 else if ($form_by === '6') {
601 $key = getContraceptiveMethod($code);
602 if (empty($key)) return;
605 // Contraceptive method for new contraceptive adoption following abortion.
607 else if ($form_by === '7') {
608 // Determine if this is a post-abortion care visit.
609 if ($row['pc_catdesc'] !== 'fal' &&
610 $row['pc_catdesc'] !== 'far' &&
611 $row['pc_catdesc'] !== 'faw') return;
612 // If yes, generate a separate row for each contraceptive method.
613 $key = getContraceptiveMethod($code);
614 if (empty($key)) return;
617 // Post-Abortion Care by Source.
618 // Requirements just call for counting sessions, but this way the columns
619 // can be anything - age category, religion, whatever.
621 else if ($form_by === '8') {
622 // We generate a row for each type of post-abortion visit.
623 // Skip all other visit categories.
624 if ($row['pc_catdesc'] === 'fal') $key = xl('For abortions at this clinic');
625 else if ($row['pc_catdesc'] === 'far') $key = xl('For abortions referred out');
626 else if ($row['pc_catdesc'] === 'faw') $key = xl('For outside abortions');
627 else return;
630 // Patient Name.
632 else if ($form_by === '17') {
633 $key = $row['lname'] . ', ' . $row['fname'] . ' ' . $row['mname'];
636 else {
637 return;
640 // 2 Rows: New, Old.
641 // 7 => xl('New and Old Clients'),
643 // 9 Rows: 0-10, 11-14, 15-19, 20-24, 25-29, 30-34, 35-39, 40-44, 45+.
644 // 8 => xl('Age Category'),
646 // 2 Rows: Male, Female.
647 // 9 => xl('Sex'),
649 // One row for each unique marital status.
650 // 10 => xl('Marital Status'),
652 // One row for each unique zone of residence.
653 // 11 => xl('Residence Zone'),
655 // One row for each unique country.
656 // 12 => xl('Nationality'),
658 // One row for each unique education level.
659 // 13 => xl('Education Level'),
661 // One row for each unique occupation.
662 // 14 => xl('Occupation'),
664 // One row for each unique number of living children.
665 // 15 => xl('Number of Living Children'),
667 // One row for each practitioner at the clinic.
668 // 16 => xl('Provider'),
671 // OK we now have the reporting key for this issue.
673 loadColumnData($key, $row);
676 // This is called for each MA service code that is selected.
678 function process_ma_code($row) {
679 global $form_by;
681 $key = 'Unspecified';
683 // One row for each service category.
685 if ($form_by === '101') {
686 if (!empty($row['title'])) $key = xl($row['title']);
689 // Specific Services. One row for each MA code.
691 else if ($form_by === '102') {
692 $key = $row['code'];
695 else {
696 return;
699 loadColumnData($key, $row);
702 // This is called for each icd9 code that is selected.
704 function process_icd_code($row) {
705 global $form_by, $last_abortion_method, $arr_dx_attrs;
706 // echo "<!-- ICD9 = '" . $row['code'] . "' -->\n"; // debugging
708 // One row for each service category.
710 if ($form_by === '11' && !empty($arr_dx_attrs[$row['code']])) {
711 $attrs = $arr_dx_attrs[$row['code']];
712 for ($i = 0; $i < strlen($attrs); ++$i) {
713 $c = strtoupper(substr($attrs, $i, 1));
714 if ($c == 'A') $ctype = 'Incomplete abortion or retention of ovular products';
715 else if ($c == 'B') $ctype = 'Excessive bleeding/hemorrhage';
716 else if ($c == 'C') $ctype = 'Trauma to vagina, cervix, or uterus';
717 else if ($c == 'D') $ctype = 'Shock';
718 else if ($c == 'E') $ctype = 'Infection';
719 else if ($c == 'F') $ctype = 'Continuing pregnancy';
720 else if ($c == 'G') $ctype = 'Ectopic pregnancy';
721 else if ($c == 'H') $ctype = 'Other complications';
722 else $ctype = '???';
723 $key = $last_abortion_method ? $last_abortion_method : 'Unknown';
724 $key .= ': ' . $ctype;
725 loadColumnData($key, $row);
730 // This is called for each selected referral.
731 // Row keys are the first specified MA code, if any.
733 function process_referral($row) {
734 $key = 'Unspecified';
735 if (!empty($row['refer_related_code'])) {
736 $relcodes = explode(';', $row['refer_related_code']);
737 foreach ($relcodes as $codestring) {
738 if ($codestring === '') continue;
739 list($codetype, $code) = explode(':', $codestring);
740 if ($codetype !== 'MA') continue;
741 $key = $code;
742 break;
745 loadColumnData($key, $row);
748 // If we are doing the CSV export then generate the needed HTTP headers.
749 // Otherwise generate HTML.
751 if ($_POST['form_csvexport']) {
752 header("Pragma: public");
753 header("Expires: 0");
754 header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
755 header("Content-Type: application/force-download");
756 header("Content-Disposition: attachment; filename=service_statistics_report.csv");
757 header("Content-Description: File Transfer");
759 else {
761 <html>
762 <head>
763 <?php html_header_show();?>
764 <title><?php xl('Service Statistics Report','e'); ?></title>
765 <style type="text/css">@import url(../../library/dynarch_calendar.css);</style>
766 <style type="text/css">
767 body { font-family:sans-serif; font-size:10pt; font-weight:normal }
768 .dehead { color:#000000; font-family:sans-serif; font-size:10pt; font-weight:bold }
769 .detail { color:#000000; font-family:sans-serif; font-size:10pt; font-weight:normal }
770 </style>
771 <script type="text/javascript" src="../../library/textformat.js"></script>
772 <script type="text/javascript" src="../../library/dynarch_calendar.js"></script>
773 <script type="text/javascript" src="../../library/dynarch_calendar_en.js"></script>
774 <script type="text/javascript" src="../../library/dynarch_calendar_setup.js"></script>
775 <script language="JavaScript">
776 var mypcc = '<? echo $GLOBALS['phone_country_code'] ?>';
777 </script>
778 </head>
780 <body leftmargin='0' topmargin='0' marginwidth='0' marginheight='0'>
782 <center>
784 <h2><? xl('Service Statistics Report','e'); ?></h2>
786 <form name='theform' method='post' action='ippf_statistics.php?t=<?php echo $report_type ?>'>
788 <table border='0' cellspacing='0' cellpadding='2'>
790 <tr>
791 <td valign='top' nowrap>
792 For each
793 </td>
794 <td valign='top'>
795 <select name='form_by' title='Left column of report'>
796 <?php
797 foreach ($arr_by as $key => $value) {
798 echo " <option value='$key'";
799 if ($key == $form_by) echo " selected";
800 echo ">" . $value . "</option>\n";
803 </select>
804 </td>
805 <td align='center' valign='top' rowspan='3' nowrap
806 ><input type='submit' name='form_refresh' value='<?php xl('Show','e'); ?>' title='<?php xl('Click to generate the report','e'); ?>'
807 /><br /><?php xl('or','e'); ?><br
808 /><input type='submit' name='form_csvexport' value='<?php xl('Export','e'); ?>' title='<?php xl('Click to downlaod in CSV format','e'); ?>'
809 /></td>
810 <td valign='top' rowspan='3'>
811 <select name='form_show[]' size='4' multiple
812 title='<?php xl('Hold down Ctrl to select multiple items','e'); ?>'>
813 <?php
814 foreach ($arr_show as $key => $value) {
815 echo " <option value='$key'";
816 if (is_array($form_show) && in_array($key, $form_show)) echo " selected";
817 echo ">" . $value . "</option>\n";
820 </select>
821 </td>
822 <td valign='top' rowspan='3' nowrap>
823 &nbsp;
824 for:
825 </td>
826 <td valign='top' rowspan='3'>
827 <select name='form_sexes' title='<?php xl('To filter by sex','e'); ?>'>
828 <?php
829 foreach (array(3 => xl('Men and Women'), 1 => xl('Women Only'), 2 => xl('Men Only')) as $key => $value) {
830 echo " <option value='$key'";
831 if ($key == $form_sexes) echo " selected";
832 echo ">$value</option>\n";
835 </select>
836 <br />&nbsp;<br />
837 <input type='button' value='<?php xl('Print','e'); ?>' onclick='window.print()' />
838 </td>
839 </tr>
840 <tr>
841 <td valign='top' nowrap>
842 from
843 </td>
844 <td valign='top' nowrap>
845 <input type='text' name='form_from_date' id='form_from_date' size='10' value='<?php echo $from_date ?>'
846 onkeyup='datekeyup(this,mypcc)' onblur='dateblur(this,mypcc)' title='Start date yyyy-mm-dd'>
847 <img src='../pic/show_calendar.gif' align='absbottom' width='24' height='22'
848 id='img_from_date' border='0' alt='[?]' style='cursor:pointer'
849 title='<?php xl('Click here to choose a date','e'); ?>'>
850 </td>
851 </tr>
852 <tr>
853 <td valign='top' nowrap>
855 </td>
856 <td valign='top' nowrap>
857 <input type='text' name='form_to_date' id='form_to_date' size='10' value='<?php echo $to_date ?>'
858 onkeyup='datekeyup(this,mypcc)' onblur='dateblur(this,mypcc)' title='End date yyyy-mm-dd'>
859 <img src='../pic/show_calendar.gif' align='absbottom' width='24' height='22'
860 id='img_to_date' border='0' alt='[?]' style='cursor:pointer'
861 title='<?php xl('Click here to choose a date','e'); ?>'>
862 </td>
863 </tr>
865 <tr>
866 <td height="1">
867 </td>
868 </tr>
870 </table>
872 <?php
873 } // end not export
875 if ($_POST['form_refresh'] || $_POST['form_csvexport']) {
876 $sexcond = '';
877 if ($form_sexes == '1') $sexcond = "AND pd.sex NOT LIKE 'Male' ";
878 else if ($form_sexes == '2') $sexcond = "AND pd.sex LIKE 'Male' ";
880 if ($form_by === '9') {
881 $query = "SELECT " .
882 "t.refer_related_code, " .
883 "pd.sex, pd.DOB, pd.lname, pd.fname, pd.mname, pd.userlist5, " .
884 "pd.country_code, pd.status, pd.state, pd.occupation " .
885 "FROM transactions AS t " .
886 "JOIN patient_data AS pd ON pd.pid = t.pid $sexcond" .
887 "WHERE t.title = 'Referral' AND t.refer_date >= '$from_date' AND " .
888 "t.refer_date <= '$to_date' " .
889 "ORDER BY t.pid, t.id";
890 $res = sqlStatement($query);
891 while ($row = sqlFetchArray($res)) {
892 process_referral($row);
895 else {
896 // This gets us all MA and ICD9 codes, with encounter and patient
897 // info attached and grouped by patient and encounter.
898 $query = "SELECT " .
899 "fe.pid, fe.date AS encdate, opc.pc_catdesc, " .
900 "pd.sex, pd.DOB, pd.lname, pd.fname, pd.mname, pd.userlist5, " .
901 "pd.country_code, pd.status, pd.state, pd.occupation, " .
902 "b.code_type, b.code, " .
903 "c.related_code, lo.title " .
904 "FROM form_encounter AS fe " .
905 "JOIN patient_data AS pd ON pd.pid = fe.pid $sexcond" .
906 "LEFT OUTER JOIN openemr_postcalendar_categories AS opc ON " .
907 "opc.pc_catid = fe.pc_catid " .
908 "LEFT OUTER JOIN billing AS b ON " .
909 "b.pid = fe.pid AND b.encounter = fe.encounter AND b.activity = 1 " .
910 "AND ( b.code_type = 'MA' OR b.code_type = 'ICD9' ) " .
911 "LEFT OUTER JOIN codes AS c ON b.code_type = 'MA' AND c.code_type = '12' AND " .
912 "c.code = b.code AND c.modifier = b.modifier " .
913 "LEFT OUTER JOIN list_options AS lo ON " .
914 "lo.list_id = 'superbill' AND lo.option_id = c.superbill " .
915 "WHERE fe.date >= '$from_date 00:00:00' AND " .
916 "fe.date <= '$to_date 23:59:59' " .
917 "ORDER BY fe.pid, fe.encounter, b.code_type DESC, b.code";
918 // Note: sorting to get MA codes before ICD9 codes.
919 $res = sqlStatement($query);
920 while ($row = sqlFetchArray($res)) {
921 if ($row['code_type'] === 'MA') {
922 process_ma_code($row);
923 if (!empty($row['related_code'])) {
924 $relcodes = explode(';', $row['related_code']);
925 foreach ($relcodes as $codestring) {
926 if ($codestring === '') continue;
927 list($codetype, $code) = explode(':', $codestring);
928 if ($codetype !== 'IPPF') continue;
929 process_ippf_code($row, $code);
933 else {
934 process_icd_code($row);
939 // Sort everything by key for reporting.
940 ksort($areport);
941 ksort($arr_titles['rel']);
942 ksort($arr_titles['nat']);
943 ksort($arr_titles['mar']);
944 ksort($arr_titles['sta']);
945 ksort($arr_titles['occ']);
947 if (! $_POST['form_csvexport']) {
948 echo "<table border='0' cellpadding='1' cellspacing='2' width='98%'>\n";
949 } // end not csv export
951 genStartRow("bgcolor='#dddddd'");
952 genHeadCell($arr_by[$form_by]);
954 // Generate headings for values to be shown.
955 foreach ($form_show as $value) {
956 if ($value == '1') { // Total Services
957 genHeadCell(xl('Services'));
959 else if ($value == '2') { // Age
960 genHeadCell(xl('0-10' ), true);
961 genHeadCell(xl('11-14'), true);
962 genHeadCell(xl('15-19'), true);
963 genHeadCell(xl('20-24'), true);
964 genHeadCell(xl('25-29'), true);
965 genHeadCell(xl('30-34'), true);
966 genHeadCell(xl('35-39'), true);
967 genHeadCell(xl('40-44'), true);
968 genHeadCell(xl('45+' ), true);
970 else if ($value == '3') { // Sex
971 genHeadCell(xl('Women'), true);
972 genHeadCell(xl('Men' ), true);
974 else if ($value == '4') { // Religion
975 foreach ($arr_titles['rel'] as $key => $value) {
976 genHeadCell($key, true);
979 else if ($value == '5') { // Nationality
980 foreach ($arr_titles['nat'] as $key => $value) {
981 genHeadCell($key, true);
984 else if ($value == '6') { // Marital Status
985 foreach ($arr_titles['mar'] as $key => $value) {
986 genHeadCell($key, true);
989 else if ($value == '7') { // State/Parish
990 foreach ($arr_titles['sta'] as $key => $value) {
991 genHeadCell($key, true);
994 else if ($value == '8') { // Occupation
995 foreach ($arr_titles['occ'] as $key => $value) {
996 genHeadCell($key, true);
1001 genEndRow();
1003 $encount = 0;
1005 foreach ($areport as $key => $varr) {
1006 $bgcolor = (++$encount & 1) ? "#ddddff" : "#ffdddd";
1008 $dispkey = $key;
1009 if ($form_by === '4') {
1010 // Append IPPF service descriptions to their codes.
1011 $crow = sqlQuery("SELECT code_text FROM codes WHERE " .
1012 "code_type = '11' AND code = '$key' ORDER BY id LIMIT 1");
1013 if (!empty($crow['code_text'])) $dispkey .= ' ' . $crow['code_text'];
1015 else if ($form_by === '102' || $form_by === '9') {
1016 // Append MA service descriptions to their codes.
1017 $crow = sqlQuery("SELECT code_text FROM codes WHERE " .
1018 "code_type = '12' AND code = '$key' ORDER BY id LIMIT 1");
1019 if (!empty($crow['code_text'])) $dispkey .= ' ' . $crow['code_text'];
1022 genStartRow("bgcolor='$bgcolor'");
1024 genAnyCell($dispkey, false, 'detail');
1026 // Generate data for this row.
1027 foreach ($form_show as $value) {
1028 if ($value == '1') { // Total Services
1029 genNumCell($areport[$key]['wom'] + $areport[$key]['men']);
1031 else if ($value == '2') { // Age
1032 for ($i = 0; $i < 9; ++$i) {
1033 genNumCell($areport[$key]['age'][$i]);
1036 else if ($value == '3') { // Sex
1037 genNumCell($areport[$key]['wom']);
1038 genNumCell($areport[$key]['men']);
1040 else if ($value == '4') { // Religion
1041 foreach ($arr_titles['rel'] as $title => $nothing) {
1042 genNumCell($areport[$key]['rel'][$title]);
1045 else if ($value == '5') { // Nationality
1046 foreach ($arr_titles['nat'] as $title => $nothing) {
1047 genNumCell($areport[$key]['nat'][$title]);
1050 else if ($value == '6') { // Marital Status
1051 foreach ($arr_titles['mar'] as $title => $nothing) {
1052 genNumCell($areport[$key]['mar'][$title]);
1055 else if ($value == '7') { // State/Parish
1056 foreach ($arr_titles['sta'] as $title => $nothing) {
1057 genNumCell($areport[$key]['sta'][$title]);
1060 else if ($value == '8') { // Occupation
1061 foreach ($arr_titles['occ'] as $title => $nothing) {
1062 genNumCell($areport[$key]['occ'][$title]);
1065 /*************************************************************
1066 else if ($value == '7') { // Contraceptive Method
1067 foreach ($arr_titles['met'] as $title => $nothing) { // TBD
1068 genNumCell($areport[$key]['met'][$title]);
1071 else if ($value == '8') { // Type of Complication
1072 foreach ($arr_titles['toc'] as $title => $nothing) { // TBD
1073 genNumCell($areport[$key]['toc'][$title]);
1076 *************************************************************/
1079 genEndRow();
1080 } // end foreach
1082 if (! $_POST['form_csvexport']) echo "</table>\n";
1083 } // end of if refresh or export
1085 if (! $_POST['form_csvexport']) {
1087 </form>
1088 </center>
1090 <script language='JavaScript'>
1091 Calendar.setup({inputField:"form_from_date", ifFormat:"%Y-%m-%d", button:"img_from_date"});
1092 Calendar.setup({inputField:"form_to_date", ifFormat:"%Y-%m-%d", button:"img_to_date"});
1093 </script>
1095 </body>
1096 </html>
1097 <?php
1098 } // end not export