Additional fixes, mostly due to changes in schema for procedure orders and results.
[openemr.git] / library / classes / rulesets / Amc / library / AbstractAmcReport.php
blobd87dbc84011bc9c34723cb4f75a54b45837c6d75
1 <?php
2 // Copyright (C) 2011 Ken Chapple <ken@mi-squared.com>
3 //
4 // This program is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU General Public License
6 // as published by the Free Software Foundation; either version 2
7 // of the License, or (at your option) any later version.
8 //
9 require_once( 'AmcFilterIF.php' );
10 require_once( dirname(__FILE__)."/../../../../clinical_rules.php" );
11 require_once( dirname(__FILE__)."/../../../../amc.php" );
13 abstract class AbstractAmcReport implements RsReportIF
15 protected $_amcPopulation;
17 protected $_resultsArray = array();
19 protected $_rowRule;
20 protected $_ruleId;
21 protected $_beginMeasurement;
22 protected $_endMeasurement;
24 protected $_manualLabNumber;
26 public function __construct( array $rowRule, array $patientIdArray, $dateTarget, $options )
28 // require all .php files in the report's sub-folder
29 $className = get_class( $this );
30 foreach ( glob( dirname(__FILE__)."/../reports/".$className."/*.php" ) as $filename ) {
31 require_once( $filename );
33 // require common .php files
34 foreach ( glob( dirname(__FILE__)."/../reports/common/*.php" ) as $filename ) {
35 require_once( $filename );
37 // require clinical types
38 foreach ( glob( dirname(__FILE__)."/../../../ClinicalTypes/*.php" ) as $filename ) {
39 require_once( $filename );
42 $this->_amcPopulation = new AmcPopulation( $patientIdArray );
43 $this->_rowRule = $rowRule;
44 $this->_ruleId = isset( $rowRule['id'] ) ? $rowRule['id'] : '';
45 // Parse measurement period, which is stored as array in $dateTarget ('dateBegin' and 'dateTarget').
46 $this->_beginMeasurement = $dateTarget['dateBegin'];
47 $this->_endMeasurement = $dateTarget['dateTarget'];
48 $this->_manualLabNumber = $options['labs_manual'];
51 public abstract function createNumerator();
52 public abstract function createDenominator();
53 public abstract function getObjectToCount();
55 public function getResults() {
56 return $this->_resultsArray;
59 public function execute()
61 $numerator = $this->createNumerator();
62 if ( !$numerator instanceof AmcFilterIF ) {
63 throw new Exception( "Numerator must be an instance of AmcFilterIF" );
66 $denominator = $this->createDenominator();
67 if ( !$denominator instanceof AmcFilterIF ) {
68 throw new Exception( "Denominator must be an instance of AmcFilterIF" );
71 $totalPatients = count( $this->_amcPopulation );
73 // Figure out object to be counted
74 // (patients, labs, transitions, visits, or prescriptions)
75 $object_to_count = $this->getObjectToCount();
76 if (empty($object_to_count)) {
77 $object_to_count="patients";
80 $numeratorObjects = 0;
81 $denominatorObjects = 0;
82 foreach ( $this->_amcPopulation as $patient )
84 // If begin measurement is empty, then make the begin
85 // measurement the patient dob.
86 $tempBeginMeasurement = "";
87 if (empty($this->_beginMeasurement)) {
88 $tempBeginMeasurement = $patient->dob;
90 else {
91 $tempBeginMeasurement = $this->_beginMeasurement;
94 // Count Denominators
95 if ($object_to_count == "patients") {
96 // Counting patients
97 if ( !$denominator->test( $patient, $tempBeginMeasurement, $this->_endMeasurement ) ) {
98 continue;
100 $denominatorObjects++;
102 else {
103 // Counting objects other than patients
104 // First, collect the pertinent objects
105 $objects = $this->collectObjects($patient,$object_to_count,$tempBeginMeasurement,$this->_endMeasurement);
107 // Second, test each object
108 $objects_pass=array();
109 foreach ($objects as $object) {
110 $patient->object=$object;
111 if ( $denominator->test( $patient, $tempBeginMeasurement, $this->_endMeasurement ) ) {
112 $denominatorObjects++;
113 array_push($objects_pass,$object);
118 // Count Numerators
119 if ($object_to_count == "patients") {
120 // Counting patients
121 if ( !$numerator->test( $patient, $tempBeginMeasurement, $this->_endMeasurement ) ) {
122 continue;
124 $numeratorObjects++;
126 else {
127 // Counting objects other than patients
128 // test each object that passed the above denominator testing
129 foreach ($objects_pass as $object) {
130 $patient->object=$object;
131 if ( $numerator->test( $patient, $tempBeginMeasurement, $this->_endMeasurement ) ) {
132 $numeratorObjects++;
139 // Deal with the manually added labs for the electronic labs AMC measure
140 if ($object_to_count == "labs") {
141 $denominatorObjects = $denominatorObjects + $this->_manualLabNumber;
144 $percentage = calculate_percentage( $denominatorObjects, 0, $numeratorObjects );
145 $result = new AmcResult( $this->_rowRule, $totalPatients, $denominatorObjects, 0, $numeratorObjects, $percentage );
146 $this->_resultsArray[]= $result;
149 private function collectObjects ($patient,$object_label,$begin,$end) {
151 $results = array();
152 $sqlBindArray = array();
154 switch ($object_label) {
155 case "transitions-in":
156 $sql = "SELECT amc_misc_data.map_id as `encounter`, amc_misc_data.date_completed as `completed`, form_encounter.date as `date` " .
157 "FROM `amc_misc_data`, `form_encounter` " .
158 "WHERE amc_misc_data.map_id = form_encounter.encounter " .
159 "AND amc_misc_data.map_category = 'form_encounter' " .
160 "AND amc_misc_data.pid = form_encounter.pid = ? " .
161 "AND amc_misc_data.amc_id = 'med_reconc_amc' " .
162 "AND form_encounter.date >= ? AND form_encounter.date <= ?";
163 array_push($sqlBindArray, $patient->id, $begin, $end);
164 break;
165 case "transitions-out":
166 $sql = "SELECT * " .
167 "FROM `transactions` " .
168 "WHERE `title` = 'Referral' " .
169 "AND `pid` = ? " .
170 "AND `date` >= ? AND `date` <= ?";
171 array_push($sqlBindArray, $patient->id, $begin, $end);
172 break;
173 case "encounters":
174 $sql = "SELECT * " .
175 "FROM `form_encounter` " .
176 "WHERE `pid` = ? " .
177 "AND `date` >= ? AND `date` <= ?";
178 array_push($sqlBindArray, $patient->id, $begin, $end);
179 break;
180 case "prescriptions":
181 $sql = "SELECT * " .
182 "FROM `prescriptions` " .
183 "WHERE `patient_id` = ? " .
184 "AND `date_added` >= ? AND `date_added` <= ?";
185 array_push($sqlBindArray, $patient->id, $begin, $end);
186 break;
187 case "labs":
188 $sql = "SELECT procedure_result.result FROM " .
189 "procedure_order, " .
190 "procedure_report, " .
191 "procedure_result " .
192 "WHERE " .
193 "procedure_order.patient_id = ? AND " .
194 "procedure_order.procedure_order_id = procedure_report.procedure_order_id AND " .
195 "procedure_report.procedure_report_id = procedure_result.procedure_report_id AND " .
196 "procedure_report.date_collected >= ? AND procedure_report.date_collected <= ?";
197 array_push($sqlBindArray, $patient->id, $begin, $end);
198 break;
201 $rez = sqlStatement($sql, $sqlBindArray);
202 for($iter=0; $row=sqlFetchArray($rez); $iter++)
203 $results[$iter]=$row;
205 return $results;