quick minor path updates (#1968)
[openemr.git] / library / amc.php
blob2e75107e6bce5a0f18190c85a40618c45d27de45
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 = '')
26 // Ensure empty variables are set correctly
27 if (empty($object_category)) {
28 $object_category='';
31 if (empty($date_created)) {
32 $date_created='';
35 if (empty($object_id)) {
36 $object_id='0';
39 // Ensure $complete is a boolean
40 // (since this is run via javascript/ajax, need to convert the boolean)
41 if (!($complete === true || $complete === false)) {
42 if ($complete === "true") {
43 $complete = true;
46 if ($complete === "false") {
47 $complete = false;
51 if ($mode == "add") {
52 amcAdd($amc_id, $complete, $patient_id, $object_category, $object_id);
55 if ($mode == "add_force") {
56 amcAddForce($amc_id, $complete, $patient_id, $object_category, $object_id);
57 } else if ($mode == "remove") {
58 amcRemove($amc_id, $patient_id, $object_category, $object_id);
59 } else if ($mode == "complete") {
60 amcComplete($amc_id, $patient_id, $object_category, $object_id);
61 } else if ($mode == "complete_safe") {
62 amcCompleteSafe($amc_id, $patient_id, $object_category, $object_id, $date_created);
63 } else if ($mode == "uncomplete") {
64 amcUnComplete($amc_id, $patient_id, $object_category, $object_id);
65 } else if ($mode == "uncomplete_safe") {
66 amcUnCompleteSafe($amc_id, $patient_id, $object_category, $object_id, $date_created);
67 } else if ($mode == "soc_provided") {
68 amcSoCProvided($amc_id, $patient_id, $object_category, $object_id);
69 } else if ($mode == "no_soc_provided") {
70 amcNoSoCProvided($amc_id, $patient_id, $object_category, $object_id);
71 } else {
72 // do nothing
73 return;
77 // Function to add an item to the amc_misc_data sql table
78 // $amc_id - amc rule id
79 // $complete - boolean for whether to complete the date_completed row
80 // $patient_id - pid
81 // $object_category - specific item category (such as prescriptions, transactions etc.)
82 // $object_id - specific item id (such as encounter id, prescription id, etc.)
83 function amcAdd($amc_id, $complete, $patient_id, $object_category = '', $object_id = '0')
86 // Attempt to collect the item
87 $item = amcCollect($amc_id, $patient_id, $object_category, $object_id);
89 if (empty($item)) {
90 // does not yet exist, so add the item
91 $sqlBindArray = array($amc_id,$patient_id,$object_category,$object_id);
92 if ($complete) {
93 sqlStatement("INSERT INTO `amc_misc_data` (`amc_id`,`pid`,`map_category`,`map_id`,`date_created`,`date_completed`) VALUES(?,?,?,?,NOW(),NOW())", $sqlBindArray);
94 } else {
95 sqlStatement("INSERT INTO `amc_misc_data` (`amc_id`,`pid`,`map_category`,`map_id`,`date_created`) VALUES(?,?,?,?,NOW())", $sqlBindArray);
97 } else {
98 // already exist, so only ensure complete date is set (if applicable)
99 if ($complete) {
100 amcComplete($amc_id, $patient_id, $object_category, $object_id);
105 // Function to add an item to the amc_misc_data sql table
106 // This function will allow duplicates (unlike the above amcAdd function)
107 // $amc_id - amc rule id
108 // $complete - boolean for whether to complete the date_completed row
109 // $patient_id - pid
110 // $object_category - specific item category (such as prescriptions, transactions etc.)
111 // $object_id - specific item id (such as encounter id, prescription id, etc.)
112 function amcAddForce($amc_id, $complete, $patient_id, $object_category = '', $object_id = '0')
115 // add the item
116 $sqlBindArray = array($amc_id,$patient_id,$object_category,$object_id);
117 if ($complete) {
118 sqlStatement("INSERT INTO `amc_misc_data` (`amc_id`,`pid`,`map_category`,`map_id`,`date_created`,`date_completed`) VALUES(?,?,?,?,NOW(),NOW())", $sqlBindArray);
119 } else {
120 sqlStatement("INSERT INTO `amc_misc_data` (`amc_id`,`pid`,`map_category`,`map_id`,`date_created`) VALUES(?,?,?,?,NOW())", $sqlBindArray);
124 // Function to remove an item from the amc_misc_data sql table
125 // $amc_id - amc rule id
126 // $patient_id - pid
127 // $object_category - specific item category (such as prescriptions, transactions etc.)
128 // $object_id - specific item id (such as encounter id, prescription id, etc.)
129 function amcRemove($amc_id, $patient_id, $object_category = '', $object_id = '0')
131 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));
134 // Function to complete an item from the amc_misc_data sql table
135 // $amc_id - amc rule id
136 // $patient_id - pid
137 // $object_category - specific item category (such as prescriptions, transactions etc.)
138 // $object_id - specific item id (such as encounter id, prescription id, etc.)
139 function amcComplete($amc_id, $patient_id, $object_category = '', $object_id = '0')
141 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));
144 // Function to complete an item from the amc_misc_data sql table
145 // As opposed to above function, this is safe for when expect to have duplicate entries
146 // $amc_id - amc rule id
147 // $patient_id - pid
148 // $object_category - specific item category (such as prescriptions, transactions etc.)
149 // $object_id - specific item id (such as encounter id, prescription id, etc.)
150 // $date_created - date created.
151 function amcCompleteSafe($amc_id, $patient_id, $object_category = '', $object_id = '0', $date_created = '')
153 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));
156 // Function to remove completion date/flag from an item in the amc_misc_data sql table
157 // $amc_id - amc rule id
158 // $patient_id - pid
159 // $object_category - specific item category (such as prescriptions, transactions etc.)
160 // $object_id - specific item id (such as encounter id, prescription id, etc.)
161 function amcUnComplete($amc_id, $patient_id, $object_category = '', $object_id = '0')
163 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));
166 // Function to remove completion date/flag from an item in the amc_misc_data sql table
167 // As opposed to above function, this is safe for when expect to have duplicate entries
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 // $date_created - date created.
173 function amcUnCompleteSafe($amc_id, $patient_id, $object_category = '', $object_id = '0', $date_created = '')
175 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));
178 // Function to complete an item from the amc_misc_data sql table
179 // $amc_id - amc rule id
180 // $patient_id - pid
181 // $object_category - specific item category (such as prescriptions, transactions etc.)
182 // $object_id - specific item id (such as encounter id, prescription id, etc.)
183 function amcCollect($amc_id, $patient_id, $object_category = '', $object_id = '0')
185 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));
188 // Function to support the AMC tracking report
189 // $amc_id - amc rule id
190 // $start - date start range
191 // $end - date end range
192 // $provider_id - provider id
193 function amcTrackingRequest($amc_id, $start = '', $end = '', $provider_id = '')
196 # Collect the patient list first (from the provider)
197 $patients = array();
198 if (empty($provider)) {
199 // Look at entire practice
200 $rez = sqlStatement("SELECT `pid`, `fname`, `lname` FROM `patient_data`");
201 for ($iter=0; $row=sqlFetchArray($rez); $iter++) {
202 $patients[$iter]=$row;
204 } else {
205 // Look at one provider
206 $rez = sqlStatement("SELECT `pid`, `fname`, `lname` FROM `patient_data` " .
207 "WHERE providerID=?", array($provider));
208 for ($iter=0; $row=sqlFetchArray($rez); $iter++) {
209 $patients[$iter]=$row;
213 $results = array();
214 foreach ($patients as $patient) {
215 $tempResults = array();
217 if ($amc_id == "send_sum_amc") {
218 $sqlBindArray = array();
219 array_push($sqlBindArray, $patient['pid']);
220 if (!(empty($start))) {
221 $where = " AND `date`>=? ";
222 array_push($sqlBindArray, $start);
225 if (!(empty($end))) {
226 $where .= " AND `date`<=? ";
227 array_push($sqlBindArray, $end);
230 $rez = sqlStatement("SELECT `id`, `date` FROM `transactions` WHERE `title` = 'LBTref' AND `pid` = ? $where ORDER BY `date` DESC", $sqlBindArray);
231 while ($res = sqlFetchArray($rez)) {
232 $amcCheck = amcCollect("send_sum_amc", $patient['pid'], "transactions", $res['id']);
233 if (empty($amcCheck)) {
234 // Records have not been sent, so send this back
235 array_push($tempResults, array("pid"=>$patient['pid'], "fname"=>$patient['fname'], "lname"=>$patient['lname'], "date"=>$res['date'], "id"=>$res['id']));
238 } else if ($amc_id == "provide_rec_pat_amc") {
239 $sqlBindArray = array();
240 array_push($sqlBindArray, $patient['pid']);
241 if (!(empty($start))) {
242 $where = " AND `date_created`>=? ";
243 array_push($sqlBindArray, $start);
246 if (!(empty($end))) {
247 $where .= " AND `date_created`<=? ";
248 array_push($sqlBindArray, $end);
251 $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);
252 while ($res = sqlFetchArray($rez)) {
253 // Records have not been sent, so send this back
254 array_push($tempResults, array("pid"=>$patient['pid'], "fname"=>$patient['fname'], "lname"=>$patient['lname'], "date"=>$res['date_created']));
256 } else if ($amc_id == "provide_sum_pat_amc") {
257 $sqlBindArray = array();
258 array_push($sqlBindArray, $patient['pid']);
259 if (!(empty($start))) {
260 $where = " AND `date`>=? ";
261 array_push($sqlBindArray, $start);
264 if (!(empty($end))) {
265 $where .= " AND `date`<=? ";
266 array_push($sqlBindArray, $end);
269 $rez = sqlStatement("SELECT `encounter`, `date` FROM `form_encounter` WHERE `pid`=? $where ORDER BY `date` DESC", $sqlBindArray);
270 while ($res = sqlFetchArray($rez)) {
271 $amcCheck = amcCollect("provide_sum_pat_amc", $patient['pid'], "form_encounter", $res['encounter']);
272 if (empty($amcCheck)) {
273 // Records have not been given, so send this back
274 array_push($tempResults, array("pid"=>$patient['pid'], "fname"=>$patient['fname'], "lname"=>$patient['lname'], "date"=>$res['date'], "id"=>$res['encounter']));
277 } else {
278 // report nothing
279 return;
282 // process results
283 $results = array_merge($results, $tempResults);
286 // send results
287 return $results;
290 // The function returns the no. of business days between two dates and it skips the holidays
291 // $start in YYYY-MM-DD
292 // $end in YYYY-MM-DD
293 // $holiday is an array containing YYYY-MM-DD
294 function businessDaysDifference($startDate, $endDate, $holidays = array())
296 //The total number of days between the two dates. We compute the no. of seconds and divide it to 60*60*24
297 //We add one to inlude both dates in the interval.
298 $days = (strtotime($endDate) - strtotime($startDate)) / 86400 + 1;
300 $no_full_weeks = floor($days / 7);
301 $no_remaining_days = fmod($days, 7);
303 //It will return 1 if it's Monday,.. ,7 for Sunday
304 $the_first_day_of_week = date("N", strtotime($startDate));
305 $the_last_day_of_week = date("N", strtotime($endDate));
307 //---->The two can be equal in leap years when february has 29 days, the equal sign is added here
308 //In the first case the whole interval is within a week, in the second case the interval falls in two weeks.
309 if ($the_first_day_of_week <= $the_last_day_of_week) {
310 if ($the_first_day_of_week <= 6 && 6 <= $the_last_day_of_week) {
311 $no_remaining_days--;
314 if ($the_first_day_of_week <= 7 && 7 <= $the_last_day_of_week) {
315 $no_remaining_days--;
317 } else {
318 // (edit by Tokes to fix an edge case where the start day was a Sunday
319 // and the end day was NOT a Saturday)
321 // the day of the week for start is later than the day of the week for end
322 if ($the_first_day_of_week == 7) {
323 // if the start date is a Sunday, then we definitely subtract 1 day
324 $no_remaining_days--;
326 if ($the_last_day_of_week == 6) {
327 // if the end date is a Saturday, then we subtract another day
328 $no_remaining_days--;
330 } else {
331 // the start date was a Saturday (or earlier), and the end date was (Mon..Fri)
332 // so we skip an entire weekend and subtract 2 days
333 $no_remaining_days -= 2;
337 //The no. of business days is: (number of weeks between the two dates) * (5 working days) + the remainder
338 //---->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
339 $workingDays = $no_full_weeks * 5;
340 if ($no_remaining_days > 0) {
341 $workingDays += $no_remaining_days;
344 //We subtract the holidays
345 foreach ($holidays as $holiday) {
346 $time_stamp=strtotime($holiday);
347 //If the holiday doesn't fall in weekend
348 if (strtotime($startDate) <= $time_stamp && $time_stamp <= strtotime($endDate) && date("N", $time_stamp) != 6 && date("N", $time_stamp) != 7) {
349 $workingDays--;
353 return $workingDays;
356 // Function to set summary of care provided for a encounter/patient from the amc_misc_data sql table
357 // $amc_id - amc rule id
358 // $patient_id - pid
359 // $object_category - specific item category (such as prescriptions, transactions etc.)
360 // $object_id - specific item id (such as encounter id, prescription id, etc.)
361 function amcSoCProvided($amc_id, $patient_id, $object_category = '', $object_id = '0')
363 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));
365 // Function to set summary of care provided for a encounter/patient from the amc_misc_data sql table
366 // $amc_id - amc rule id
367 // $patient_id - pid
368 // $object_category - specific item category (such as prescriptions, transactions etc.)
369 // $object_id - specific item id (such as encounter id, prescription id, etc.)
370 function amcNoSoCProvided($amc_id, $patient_id, $object_category = '', $object_id = '0')
372 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));