removed redundant docs (it is on the wiki)
[openemr.git] / library / amc.php
blob806025eeaae61d0c463c0f472413ad01c8046596
1 <?php
2 // Copyright (C) 2011 Brady Miller <brady@sparmy.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 {
59 // do nothing
60 return;
64 // Function to add an item to the amc_misc_data sql table
65 // $amc_id - amc rule id
66 // $complete - boolean for whether to complete the date_completed row
67 // $patient_id - pid
68 // $object_category - specific item category (such as prescriptions, transactions etc.)
69 // $object_id - specific item id (such as encounter id, prescription id, etc.)
70 function amcAdd($amc_id, $complete, $patient_id, $object_category='', $object_id='0') {
72 // Attempt to collect the item
73 $item = amcCollect($amc_id, $patient_id, $object_category, $object_id);
75 if (empty($item)) {
76 // does not yet exist, so add the item
77 $sqlBindArray = array($amc_id,$patient_id,$object_category,$object_id);
78 if ($complete) {
79 sqlStatement("INSERT INTO `amc_misc_data` (`amc_id`,`pid`,`map_category`,`map_id`,`date_created`,`date_completed`) VALUES(?,?,?,?,NOW(),NOW())", $sqlBindArray);
81 else {
82 sqlStatement("INSERT INTO `amc_misc_data` (`amc_id`,`pid`,`map_category`,`map_id`,`date_created`) VALUES(?,?,?,?,NOW())", $sqlBindArray);
85 else {
86 // already exist, so only ensure complete date is set (if applicable)
87 if ($complete) {
88 amcComplete($amc_id, $patient_id, $object_category, $object_id);
93 // Function to add an item to the amc_misc_data sql table
94 // This function will allow duplicates (unlike the above amcAdd function)
95 // $amc_id - amc rule id
96 // $complete - boolean for whether to complete the date_completed row
97 // $patient_id - pid
98 // $object_category - specific item category (such as prescriptions, transactions etc.)
99 // $object_id - specific item id (such as encounter id, prescription id, etc.)
100 function amcAddForce($amc_id, $complete, $patient_id, $object_category='', $object_id='0') {
102 // add the item
103 $sqlBindArray = array($amc_id,$patient_id,$object_category,$object_id);
104 if ($complete) {
105 sqlStatement("INSERT INTO `amc_misc_data` (`amc_id`,`pid`,`map_category`,`map_id`,`date_created`,`date_completed`) VALUES(?,?,?,?,NOW(),NOW())", $sqlBindArray);
107 else {
108 sqlStatement("INSERT INTO `amc_misc_data` (`amc_id`,`pid`,`map_category`,`map_id`,`date_created`) VALUES(?,?,?,?,NOW())", $sqlBindArray);
112 // Function to remove an item from the amc_misc_data sql table
113 // $amc_id - amc rule id
114 // $patient_id - pid
115 // $object_category - specific item category (such as prescriptions, transactions etc.)
116 // $object_id - specific item id (such as encounter id, prescription id, etc.)
117 function amcRemove($amc_id, $patient_id, $object_category='', $object_id='0') {
118 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) );
121 // Function to complete an item from the amc_misc_data sql table
122 // $amc_id - amc rule id
123 // $patient_id - pid
124 // $object_category - specific item category (such as prescriptions, transactions etc.)
125 // $object_id - specific item id (such as encounter id, prescription id, etc.)
126 function amcComplete($amc_id, $patient_id, $object_category='', $object_id='0') {
127 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) );
130 // Function to complete an item from the amc_misc_data sql table
131 // As opposed to above function, this is safe for when expect to have duplicate entries
132 // $amc_id - amc rule id
133 // $patient_id - pid
134 // $object_category - specific item category (such as prescriptions, transactions etc.)
135 // $object_id - specific item id (such as encounter id, prescription id, etc.)
136 // $date_created - date created.
137 function amcCompleteSafe($amc_id, $patient_id, $object_category='', $object_id='0', $date_created='') {
138 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) );
141 // Function to remove completion date/flag from an item in the amc_misc_data sql table
142 // $amc_id - amc rule id
143 // $patient_id - pid
144 // $object_category - specific item category (such as prescriptions, transactions etc.)
145 // $object_id - specific item id (such as encounter id, prescription id, etc.)
146 function amcUnComplete($amc_id, $patient_id, $object_category='', $object_id='0') {
147 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) );
150 // Function to remove completion date/flag from an item in the amc_misc_data sql table
151 // As opposed to above function, this is safe for when expect to have duplicate entries
152 // $amc_id - amc rule id
153 // $patient_id - pid
154 // $object_category - specific item category (such as prescriptions, transactions etc.)
155 // $object_id - specific item id (such as encounter id, prescription id, etc.)
156 // $date_created - date created.
157 function amcUnCompleteSafe($amc_id, $patient_id, $object_category='', $object_id='0', $date_created='') {
158 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) );
161 // Function to complete an item from the amc_misc_data sql table
162 // $amc_id - amc rule id
163 // $patient_id - pid
164 // $object_category - specific item category (such as prescriptions, transactions etc.)
165 // $object_id - specific item id (such as encounter id, prescription id, etc.)
166 function amcCollect($amc_id, $patient_id, $object_category='', $object_id='0') {
167 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) );
170 // Function to support the AMC tracking report
171 // $amc_id - amc rule id
172 // $start - date start range
173 // $end - date end range
174 // $provider_id - provider id
175 function amcTrackingRequest($amc_id,$start='',$end='',$provider_id='') {
177 # Collect the patient list first (from the provider)
178 $patients = array();
179 if (empty($provider)) {
180 // Look at entire practice
181 $rez = sqlStatement("SELECT `pid`, `fname`, `lname` FROM `patient_data`");
182 for($iter=0; $row=sqlFetchArray($rez); $iter++) {
183 $patients[$iter]=$row;
186 else {
187 // Look at one provider
188 $rez = sqlStatement("SELECT `pid`, `fname`, `lname` FROM `patient_data` " .
189 "WHERE providerID=?", array($provider) );
190 for($iter=0; $row=sqlFetchArray($rez); $iter++) {
191 $patients[$iter]=$row;
195 $results = array();
196 foreach ($patients as $patient) {
197 $tempResults = array();
199 if ($amc_id == "send_sum_amc") {
200 $sqlBindArray = array();
201 array_push($sqlBindArray,$patient['pid']);
202 if (!(empty($start))) {
203 $where = " AND `date`>=? ";
204 array_push($sqlBindArray,$start);
206 if (!(empty($end))) {
207 $where .= " AND `date`<=? ";
208 array_push($sqlBindArray,$end);
210 $rez = sqlStatement("SELECT `id`, `date` FROM `transactions` WHERE `title` = 'LBTref' AND `pid` = ? $where ORDER BY `date` DESC", $sqlBindArray);
211 while ($res = sqlFetchArray($rez)) {
212 $amcCheck = amcCollect("send_sum_amc",$patient['pid'],"transactions",$res['id']);
213 if (empty($amcCheck)) {
214 // Records have not been sent, so send this back
215 array_push($tempResults, array("pid"=>$patient['pid'], "fname"=>$patient['fname'], "lname"=>$patient['lname'], "date"=>$res['date'], "id"=>$res['id']));
220 else if ($amc_id == "provide_rec_pat_amc") {
221 $sqlBindArray = array();
222 array_push($sqlBindArray,$patient['pid']);
223 if (!(empty($start))) {
224 $where = " AND `date_created`>=? ";
225 array_push($sqlBindArray,$start);
227 if (!(empty($end))) {
228 $where .= " AND `date_created`<=? ";
229 array_push($sqlBindArray,$end);
231 $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);
232 while ($res = sqlFetchArray($rez)) {
233 // Records have not been sent, so send this back
234 array_push($tempResults, array("pid"=>$patient['pid'], "fname"=>$patient['fname'], "lname"=>$patient['lname'], "date"=>$res['date_created']));
238 else if ($amc_id == "provide_sum_pat_amc") {
239 $sqlBindArray = array();
240 array_push($sqlBindArray,$patient['pid']);
241 if (!(empty($start))) {
242 $where = " AND `date`>=? ";
243 array_push($sqlBindArray,$start);
245 if (!(empty($end))) {
246 $where .= " AND `date`<=? ";
247 array_push($sqlBindArray,$end);
249 $rez = sqlStatement("SELECT `encounter`, `date` FROM `form_encounter` WHERE `pid`=? $where ORDER BY `date` DESC", $sqlBindArray);
250 while ($res = sqlFetchArray($rez)) {
251 $amcCheck = amcCollect("provide_sum_pat_amc",$patient['pid'],"form_encounter",$res['encounter']);
252 if (empty($amcCheck)) {
253 // Records have not been given, so send this back
254 array_push($tempResults, array("pid"=>$patient['pid'], "fname"=>$patient['fname'], "lname"=>$patient['lname'], "date"=>$res['date'], "id"=>$res['encounter']));
259 else {
260 // report nothing
261 return;
264 // process results
265 $results = array_merge($results,$tempResults);
269 // send results
270 return $results;
273 // The function returns the no. of business days between two dates and it skips the holidays
274 // $start in YYYY-MM-DD
275 // $end in YYYY-MM-DD
276 // $holiday is an array containing YYYY-MM-DD
277 function businessDaysDifference($startDate,$endDate,$holidays=array()) {
278 //The total number of days between the two dates. We compute the no. of seconds and divide it to 60*60*24
279 //We add one to inlude both dates in the interval.
280 $days = (strtotime($endDate) - strtotime($startDate)) / 86400 + 1;
282 $no_full_weeks = floor($days / 7);
283 $no_remaining_days = fmod($days, 7);
285 //It will return 1 if it's Monday,.. ,7 for Sunday
286 $the_first_day_of_week = date("N", strtotime($startDate));
287 $the_last_day_of_week = date("N", strtotime($endDate));
289 //---->The two can be equal in leap years when february has 29 days, the equal sign is added here
290 //In the first case the whole interval is within a week, in the second case the interval falls in two weeks.
291 if ($the_first_day_of_week <= $the_last_day_of_week) {
292 if ($the_first_day_of_week <= 6 && 6 <= $the_last_day_of_week) $no_remaining_days--;
293 if ($the_first_day_of_week <= 7 && 7 <= $the_last_day_of_week) $no_remaining_days--;
295 else {
296 // (edit by Tokes to fix an edge case where the start day was a Sunday
297 // and the end day was NOT a Saturday)
299 // the day of the week for start is later than the day of the week for end
300 if ($the_first_day_of_week == 7) {
301 // if the start date is a Sunday, then we definitely subtract 1 day
302 $no_remaining_days--;
304 if ($the_last_day_of_week == 6) {
305 // if the end date is a Saturday, then we subtract another day
306 $no_remaining_days--;
309 else {
310 // the start date was a Saturday (or earlier), and the end date was (Mon..Fri)
311 // so we skip an entire weekend and subtract 2 days
312 $no_remaining_days -= 2;
316 //The no. of business days is: (number of weeks between the two dates) * (5 working days) + the remainder
317 //---->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
318 $workingDays = $no_full_weeks * 5;
319 if ($no_remaining_days > 0 ) {
320 $workingDays += $no_remaining_days;
323 //We subtract the holidays
324 foreach($holidays as $holiday){
325 $time_stamp=strtotime($holiday);
326 //If the holiday doesn't fall in weekend
327 if (strtotime($startDate) <= $time_stamp && $time_stamp <= strtotime($endDate) && date("N",$time_stamp) != 6 && date("N",$time_stamp) != 7)
328 $workingDays--;
331 return $workingDays;