minor improvement to tabs style
[openemr.git] / library / amc.php
blobe153403e49c3c8d5e5471b14474fcdb9584ead36
1 <?php
2 // Copyright (C) 2011 Brady Miller <brady.g.miller@gmail.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 //
10 // This file contains functions to:
11 // --manage AMC items in the amc_misc_data sql table
12 // --support the AMC Tracking report
14 // Main function to process items in the amc_misc_data sql table
15 // Paramteter:
16 // $amc_id - amc rule id
17 // $complete - boolean for whether to complete the date_completed row
18 // $mode - 'add' or 'remove'
19 // $patient_id - pid
20 // $object_category - specific item category (such as prescriptions, transactions etc.)
21 // $object_id - specific item id (such as encounter id, prescription id, etc.)
22 // $date_created - specifically for the uncomplete_safe mode only to ensure safe for duplicate entries.
23 function processAmcCall($amc_id, $complete, $mode, $patient_id, $object_category='', $object_id='0', $date_created='') {
25 // Ensure empty variables are set correctly
26 if (empty($object_category)) $object_category='';
27 if (empty($date_created)) $date_created='';
28 if (empty($object_id)) $object_id='0';
30 // Ensure $complete is a boolean
31 // (since this is run via javascript/ajax, need to convert the boolean)
32 if (!($complete === True || $complete === False)) {
33 if ($complete === "true") $complete = True;
34 if ($complete === "false") $complete = False;
37 if ($mode == "add") {
38 amcAdd($amc_id, $complete, $patient_id, $object_category, $object_id);
40 if ($mode == "add_force") {
41 amcAddForce($amc_id, $complete, $patient_id, $object_category, $object_id);
43 else if ($mode == "remove") {
44 amcRemove($amc_id, $patient_id, $object_category, $object_id);
46 else if ($mode == "complete") {
47 amcComplete($amc_id, $patient_id, $object_category, $object_id);
49 else if ($mode == "complete_safe") {
50 amcCompleteSafe($amc_id, $patient_id, $object_category, $object_id, $date_created);
52 else if ($mode == "uncomplete") {
53 amcUnComplete($amc_id, $patient_id, $object_category, $object_id);
55 else if ($mode == "uncomplete_safe") {
56 amcUnCompleteSafe($amc_id, $patient_id, $object_category, $object_id, $date_created);
58 else if ($mode == "soc_provided"){
59 amcSoCProvided($amc_id, $patient_id, $object_category, $object_id);
61 else if ($mode == "no_soc_provided"){
62 amcNoSoCProvided($amc_id, $patient_id, $object_category, $object_id);
64 else {
65 // do nothing
66 return;
70 // Function to add an item to the amc_misc_data sql table
71 // $amc_id - amc rule id
72 // $complete - boolean for whether to complete the date_completed row
73 // $patient_id - pid
74 // $object_category - specific item category (such as prescriptions, transactions etc.)
75 // $object_id - specific item id (such as encounter id, prescription id, etc.)
76 function amcAdd($amc_id, $complete, $patient_id, $object_category='', $object_id='0') {
78 // Attempt to collect the item
79 $item = amcCollect($amc_id, $patient_id, $object_category, $object_id);
81 if (empty($item)) {
82 // does not yet exist, so add the item
83 $sqlBindArray = array($amc_id,$patient_id,$object_category,$object_id);
84 if ($complete) {
85 sqlStatement("INSERT INTO `amc_misc_data` (`amc_id`,`pid`,`map_category`,`map_id`,`date_created`,`date_completed`) VALUES(?,?,?,?,NOW(),NOW())", $sqlBindArray);
87 else {
88 sqlStatement("INSERT INTO `amc_misc_data` (`amc_id`,`pid`,`map_category`,`map_id`,`date_created`) VALUES(?,?,?,?,NOW())", $sqlBindArray);
91 else {
92 // already exist, so only ensure complete date is set (if applicable)
93 if ($complete) {
94 amcComplete($amc_id, $patient_id, $object_category, $object_id);
99 // Function to add an item to the amc_misc_data sql table
100 // This function will allow duplicates (unlike the above amcAdd function)
101 // $amc_id - amc rule id
102 // $complete - boolean for whether to complete the date_completed row
103 // $patient_id - pid
104 // $object_category - specific item category (such as prescriptions, transactions etc.)
105 // $object_id - specific item id (such as encounter id, prescription id, etc.)
106 function amcAddForce($amc_id, $complete, $patient_id, $object_category='', $object_id='0') {
108 // add the item
109 $sqlBindArray = array($amc_id,$patient_id,$object_category,$object_id);
110 if ($complete) {
111 sqlStatement("INSERT INTO `amc_misc_data` (`amc_id`,`pid`,`map_category`,`map_id`,`date_created`,`date_completed`) VALUES(?,?,?,?,NOW(),NOW())", $sqlBindArray);
113 else {
114 sqlStatement("INSERT INTO `amc_misc_data` (`amc_id`,`pid`,`map_category`,`map_id`,`date_created`) VALUES(?,?,?,?,NOW())", $sqlBindArray);
118 // Function to remove an item from the amc_misc_data sql table
119 // $amc_id - amc rule id
120 // $patient_id - pid
121 // $object_category - specific item category (such as prescriptions, transactions etc.)
122 // $object_id - specific item id (such as encounter id, prescription id, etc.)
123 function amcRemove($amc_id, $patient_id, $object_category='', $object_id='0') {
124 sqlStatement("DELETE FROM `amc_misc_data` WHERE `amc_id`=? AND `pid`=? AND `map_category`=? AND `map_id`=?", array($amc_id,$patient_id,$object_category,$object_id) );
127 // Function to complete an item from the amc_misc_data sql table
128 // $amc_id - amc rule id
129 // $patient_id - pid
130 // $object_category - specific item category (such as prescriptions, transactions etc.)
131 // $object_id - specific item id (such as encounter id, prescription id, etc.)
132 function amcComplete($amc_id, $patient_id, $object_category='', $object_id='0') {
133 sqlStatement("UPDATE `amc_misc_data` SET `date_completed`=NOW() WHERE `amc_id`=? AND `pid`=? AND `map_category`=? AND `map_id`=? AND (`date_completed` IS NULL OR `date_completed`='')", array($amc_id,$patient_id,$object_category,$object_id) );
136 // Function to complete an item from the amc_misc_data sql table
137 // As opposed to above function, this is safe for when expect to have duplicate entries
138 // $amc_id - amc rule id
139 // $patient_id - pid
140 // $object_category - specific item category (such as prescriptions, transactions etc.)
141 // $object_id - specific item id (such as encounter id, prescription id, etc.)
142 // $date_created - date created.
143 function amcCompleteSafe($amc_id, $patient_id, $object_category='', $object_id='0', $date_created='') {
144 sqlStatement("UPDATE `amc_misc_data` SET `date_completed`=NOW() WHERE `amc_id`=? AND `pid`=? AND `map_category`=? AND `map_id`=? AND (`date_completed` IS NULL OR `date_completed`='') AND `date_created`=?", array($amc_id,$patient_id,$object_category,$object_id,$date_created) );
147 // Function to remove completion date/flag from an item in the amc_misc_data sql table
148 // $amc_id - amc rule id
149 // $patient_id - pid
150 // $object_category - specific item category (such as prescriptions, transactions etc.)
151 // $object_id - specific item id (such as encounter id, prescription id, etc.)
152 function amcUnComplete($amc_id, $patient_id, $object_category='', $object_id='0') {
153 sqlStatement("UPDATE `amc_misc_data` SET `date_completed`=NULL WHERE `amc_id`=? AND `pid`=? AND `map_category`=? AND `map_id`=?", array($amc_id,$patient_id,$object_category,$object_id) );
156 // Function to remove completion date/flag from an item in the amc_misc_data sql table
157 // As opposed to above function, this is safe for when expect to have duplicate entries
158 // $amc_id - amc rule id
159 // $patient_id - pid
160 // $object_category - specific item category (such as prescriptions, transactions etc.)
161 // $object_id - specific item id (such as encounter id, prescription id, etc.)
162 // $date_created - date created.
163 function amcUnCompleteSafe($amc_id, $patient_id, $object_category='', $object_id='0', $date_created='') {
164 sqlStatement("UPDATE `amc_misc_data` SET `date_completed`=NULL WHERE `amc_id`=? AND `pid`=? AND `map_category`=? AND `map_id`=? AND `date_created`=?", array($amc_id,$patient_id,$object_category,$object_id,$date_created) );
167 // Function to complete an item from the amc_misc_data sql table
168 // $amc_id - amc rule id
169 // $patient_id - pid
170 // $object_category - specific item category (such as prescriptions, transactions etc.)
171 // $object_id - specific item id (such as encounter id, prescription id, etc.)
172 function amcCollect($amc_id, $patient_id, $object_category='', $object_id='0') {
173 return sqlQuery("SELECT * FROM `amc_misc_data` WHERE `amc_id`=? AND `pid`=? AND `map_category`=? AND `map_id`=?", array($amc_id,$patient_id,$object_category,$object_id) );
176 // Function to support the AMC tracking report
177 // $amc_id - amc rule id
178 // $start - date start range
179 // $end - date end range
180 // $provider_id - provider id
181 function amcTrackingRequest($amc_id,$start='',$end='',$provider_id='') {
183 # Collect the patient list first (from the provider)
184 $patients = array();
185 if (empty($provider)) {
186 // Look at entire practice
187 $rez = sqlStatement("SELECT `pid`, `fname`, `lname` FROM `patient_data`");
188 for($iter=0; $row=sqlFetchArray($rez); $iter++) {
189 $patients[$iter]=$row;
192 else {
193 // Look at one provider
194 $rez = sqlStatement("SELECT `pid`, `fname`, `lname` FROM `patient_data` " .
195 "WHERE providerID=?", array($provider) );
196 for($iter=0; $row=sqlFetchArray($rez); $iter++) {
197 $patients[$iter]=$row;
201 $results = array();
202 foreach ($patients as $patient) {
203 $tempResults = array();
205 if ($amc_id == "send_sum_amc") {
206 $sqlBindArray = array();
207 array_push($sqlBindArray,$patient['pid']);
208 if (!(empty($start))) {
209 $where = " AND `date`>=? ";
210 array_push($sqlBindArray,$start);
212 if (!(empty($end))) {
213 $where .= " AND `date`<=? ";
214 array_push($sqlBindArray,$end);
216 $rez = sqlStatement("SELECT `id`, `date` FROM `transactions` WHERE `title` = 'LBTref' AND `pid` = ? $where ORDER BY `date` DESC", $sqlBindArray);
217 while ($res = sqlFetchArray($rez)) {
218 $amcCheck = amcCollect("send_sum_amc",$patient['pid'],"transactions",$res['id']);
219 if (empty($amcCheck)) {
220 // Records have not been sent, so send this back
221 array_push($tempResults, array("pid"=>$patient['pid'], "fname"=>$patient['fname'], "lname"=>$patient['lname'], "date"=>$res['date'], "id"=>$res['id']));
226 else if ($amc_id == "provide_rec_pat_amc") {
227 $sqlBindArray = array();
228 array_push($sqlBindArray,$patient['pid']);
229 if (!(empty($start))) {
230 $where = " AND `date_created`>=? ";
231 array_push($sqlBindArray,$start);
233 if (!(empty($end))) {
234 $where .= " AND `date_created`<=? ";
235 array_push($sqlBindArray,$end);
237 $rez = sqlStatement("SELECT * FROM `amc_misc_data` WHERE `amc_id`='provide_rec_pat_amc' AND `pid`=? AND (`date_completed` IS NULL OR `date_completed`='') $where ORDER BY `date_created` DESC", $sqlBindArray);
238 while ($res = sqlFetchArray($rez)) {
239 // Records have not been sent, so send this back
240 array_push($tempResults, array("pid"=>$patient['pid'], "fname"=>$patient['fname'], "lname"=>$patient['lname'], "date"=>$res['date_created']));
244 else if ($amc_id == "provide_sum_pat_amc") {
245 $sqlBindArray = array();
246 array_push($sqlBindArray,$patient['pid']);
247 if (!(empty($start))) {
248 $where = " AND `date`>=? ";
249 array_push($sqlBindArray,$start);
251 if (!(empty($end))) {
252 $where .= " AND `date`<=? ";
253 array_push($sqlBindArray,$end);
255 $rez = sqlStatement("SELECT `encounter`, `date` FROM `form_encounter` WHERE `pid`=? $where ORDER BY `date` DESC", $sqlBindArray);
256 while ($res = sqlFetchArray($rez)) {
257 $amcCheck = amcCollect("provide_sum_pat_amc",$patient['pid'],"form_encounter",$res['encounter']);
258 if (empty($amcCheck)) {
259 // Records have not been given, so send this back
260 array_push($tempResults, array("pid"=>$patient['pid'], "fname"=>$patient['fname'], "lname"=>$patient['lname'], "date"=>$res['date'], "id"=>$res['encounter']));
265 else {
266 // report nothing
267 return;
270 // process results
271 $results = array_merge($results,$tempResults);
275 // send results
276 return $results;
279 // The function returns the no. of business days between two dates and it skips the holidays
280 // $start in YYYY-MM-DD
281 // $end in YYYY-MM-DD
282 // $holiday is an array containing YYYY-MM-DD
283 function businessDaysDifference($startDate,$endDate,$holidays=array()) {
284 //The total number of days between the two dates. We compute the no. of seconds and divide it to 60*60*24
285 //We add one to inlude both dates in the interval.
286 $days = (strtotime($endDate) - strtotime($startDate)) / 86400 + 1;
288 $no_full_weeks = floor($days / 7);
289 $no_remaining_days = fmod($days, 7);
291 //It will return 1 if it's Monday,.. ,7 for Sunday
292 $the_first_day_of_week = date("N", strtotime($startDate));
293 $the_last_day_of_week = date("N", strtotime($endDate));
295 //---->The two can be equal in leap years when february has 29 days, the equal sign is added here
296 //In the first case the whole interval is within a week, in the second case the interval falls in two weeks.
297 if ($the_first_day_of_week <= $the_last_day_of_week) {
298 if ($the_first_day_of_week <= 6 && 6 <= $the_last_day_of_week) $no_remaining_days--;
299 if ($the_first_day_of_week <= 7 && 7 <= $the_last_day_of_week) $no_remaining_days--;
301 else {
302 // (edit by Tokes to fix an edge case where the start day was a Sunday
303 // and the end day was NOT a Saturday)
305 // the day of the week for start is later than the day of the week for end
306 if ($the_first_day_of_week == 7) {
307 // if the start date is a Sunday, then we definitely subtract 1 day
308 $no_remaining_days--;
310 if ($the_last_day_of_week == 6) {
311 // if the end date is a Saturday, then we subtract another day
312 $no_remaining_days--;
315 else {
316 // the start date was a Saturday (or earlier), and the end date was (Mon..Fri)
317 // so we skip an entire weekend and subtract 2 days
318 $no_remaining_days -= 2;
322 //The no. of business days is: (number of weeks between the two dates) * (5 working days) + the remainder
323 //---->february in none leap years gave a remainder of 0 but still calculated weekends between first and last day, this is one way to fix it
324 $workingDays = $no_full_weeks * 5;
325 if ($no_remaining_days > 0 ) {
326 $workingDays += $no_remaining_days;
329 //We subtract the holidays
330 foreach($holidays as $holiday){
331 $time_stamp=strtotime($holiday);
332 //If the holiday doesn't fall in weekend
333 if (strtotime($startDate) <= $time_stamp && $time_stamp <= strtotime($endDate) && date("N",$time_stamp) != 6 && date("N",$time_stamp) != 7)
334 $workingDays--;
337 return $workingDays;
340 // Function to set summary of care provided for a encounter/patient from the amc_misc_data sql table
341 // $amc_id - amc rule id
342 // $patient_id - pid
343 // $object_category - specific item category (such as prescriptions, transactions etc.)
344 // $object_id - specific item id (such as encounter id, prescription id, etc.)
345 function amcSoCProvided($amc_id, $patient_id, $object_category='', $object_id='0') {
346 sqlStatement("UPDATE `amc_misc_data` SET `soc_provided` = NOW() WHERE `amc_id`=? AND `pid`=? AND `map_category`=? AND `map_id`=? ", array($amc_id,$patient_id,$object_category,$object_id) );
348 // Function to set summary of care provided for a encounter/patient from the amc_misc_data sql table
349 // $amc_id - amc rule id
350 // $patient_id - pid
351 // $object_category - specific item category (such as prescriptions, transactions etc.)
352 // $object_id - specific item id (such as encounter id, prescription id, etc.)
353 function amcNoSoCProvided($amc_id, $patient_id, $object_category='', $object_id='0') {
354 sqlStatement("UPDATE `amc_misc_data` SET `soc_provided` = NULL WHERE `amc_id`=? AND `pid`=? AND `map_category`=? AND `map_id`=? ", array($amc_id,$patient_id,$object_category,$object_id) );