Bump phpmailer/phpmailer from 6.1.5 to 6.1.6 (#3567)
[openemr.git] / library / amc.php
blob0102118ce2284e31c2fc9da41cc79842e56fa33d
1 <?php
3 // Copyright (C) 2011 Brady Miller <brady.g.miller@gmail.com>
4 //
5 // This program is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU General Public License
7 // as published by the Free Software Foundation; either version 2
8 // of the License, or (at your option) any later version.
9 //
11 // This file contains functions to:
12 // --manage AMC items in the amc_misc_data sql table
13 // --support the AMC Tracking report
15 // Main function to process items in the amc_misc_data sql table
16 // Parameter:
17 // $amc_id - amc rule id
18 // $complete - boolean for whether to complete the date_completed row
19 // $mode - 'add' or 'remove'
20 // $patient_id - pid
21 // $object_category - specific item category (such as prescriptions, transactions etc.)
22 // $object_id - specific item id (such as encounter id, prescription id, etc.)
23 // $date_created - specifically for the uncomplete_safe mode only to ensure safe for duplicate entries.
24 function processAmcCall($amc_id, $complete, $mode, $patient_id, $object_category = '', $object_id = '0', $date_created = '')
27 // Ensure empty variables are set correctly
28 if (empty($object_category)) {
29 $object_category = '';
32 if (empty($date_created)) {
33 $date_created = '';
36 if (empty($object_id)) {
37 $object_id = '0';
40 // Ensure $complete is a boolean
41 // (since this is run via javascript/ajax, need to convert the boolean)
42 if (!($complete === true || $complete === false)) {
43 if ($complete === "true") {
44 $complete = true;
47 if ($complete === "false") {
48 $complete = false;
52 if ($mode == "add") {
53 amcAdd($amc_id, $complete, $patient_id, $object_category, $object_id);
56 if ($mode == "add_force") {
57 amcAddForce($amc_id, $complete, $patient_id, $object_category, $object_id);
58 } elseif ($mode == "remove") {
59 amcRemove($amc_id, $patient_id, $object_category, $object_id);
60 } elseif ($mode == "complete") {
61 amcComplete($amc_id, $patient_id, $object_category, $object_id);
62 } elseif ($mode == "complete_safe") {
63 amcCompleteSafe($amc_id, $patient_id, $object_category, $object_id, $date_created);
64 } elseif ($mode == "uncomplete") {
65 amcUnComplete($amc_id, $patient_id, $object_category, $object_id);
66 } elseif ($mode == "uncomplete_safe") {
67 amcUnCompleteSafe($amc_id, $patient_id, $object_category, $object_id, $date_created);
68 } elseif ($mode == "soc_provided") {
69 amcSoCProvided($amc_id, $patient_id, $object_category, $object_id);
70 } elseif ($mode == "no_soc_provided") {
71 amcNoSoCProvided($amc_id, $patient_id, $object_category, $object_id);
72 } else {
73 // do nothing
74 return;
78 // Function to add an item to the amc_misc_data sql table
79 // $amc_id - amc rule id
80 // $complete - boolean for whether to complete the date_completed row
81 // $patient_id - pid
82 // $object_category - specific item category (such as prescriptions, transactions etc.)
83 // $object_id - specific item id (such as encounter id, prescription id, etc.)
84 function amcAdd($amc_id, $complete, $patient_id, $object_category = '', $object_id = '0')
87 // Attempt to collect the item
88 $item = amcCollect($amc_id, $patient_id, $object_category, $object_id);
90 if (empty($item)) {
91 // does not yet exist, so add the item
92 $sqlBindArray = array($amc_id,$patient_id,$object_category,$object_id);
93 if ($complete) {
94 sqlStatement("INSERT INTO `amc_misc_data` (`amc_id`,`pid`,`map_category`,`map_id`,`date_created`,`date_completed`) VALUES(?,?,?,?,NOW(),NOW())", $sqlBindArray);
95 } else {
96 sqlStatement("INSERT INTO `amc_misc_data` (`amc_id`,`pid`,`map_category`,`map_id`,`date_created`) VALUES(?,?,?,?,NOW())", $sqlBindArray);
98 } else {
99 // already exist, so only ensure complete date is set (if applicable)
100 if ($complete) {
101 amcComplete($amc_id, $patient_id, $object_category, $object_id);
106 // Function to add an item to the amc_misc_data sql table
107 // This function will allow duplicates (unlike the above amcAdd function)
108 // $amc_id - amc rule id
109 // $complete - boolean for whether to complete the date_completed row
110 // $patient_id - pid
111 // $object_category - specific item category (such as prescriptions, transactions etc.)
112 // $object_id - specific item id (such as encounter id, prescription id, etc.)
113 function amcAddForce($amc_id, $complete, $patient_id, $object_category = '', $object_id = '0')
116 // add the item
117 $sqlBindArray = array($amc_id,$patient_id,$object_category,$object_id);
118 if ($complete) {
119 sqlStatement("INSERT INTO `amc_misc_data` (`amc_id`,`pid`,`map_category`,`map_id`,`date_created`,`date_completed`) VALUES(?,?,?,?,NOW(),NOW())", $sqlBindArray);
120 } else {
121 sqlStatement("INSERT INTO `amc_misc_data` (`amc_id`,`pid`,`map_category`,`map_id`,`date_created`) VALUES(?,?,?,?,NOW())", $sqlBindArray);
125 // Function to remove an item from the amc_misc_data sql table
126 // $amc_id - amc rule id
127 // $patient_id - pid
128 // $object_category - specific item category (such as prescriptions, transactions etc.)
129 // $object_id - specific item id (such as encounter id, prescription id, etc.)
130 function amcRemove($amc_id, $patient_id, $object_category = '', $object_id = '0')
132 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));
135 // Function to complete an item from the amc_misc_data sql table
136 // $amc_id - amc rule id
137 // $patient_id - pid
138 // $object_category - specific item category (such as prescriptions, transactions etc.)
139 // $object_id - specific item id (such as encounter id, prescription id, etc.)
140 function amcComplete($amc_id, $patient_id, $object_category = '', $object_id = '0')
142 sqlStatement(
143 "UPDATE `amc_misc_data` SET `date_completed`=NOW() WHERE `amc_id`=? AND `pid`=? AND `map_category`=? AND `map_id`=? AND " .
144 dateEmptySql('date_completed', true),
145 array($amc_id,$patient_id,$object_category,$object_id)
149 // Function to complete an item from the amc_misc_data sql table
150 // As opposed to above function, this is safe for when expect to have duplicate entries
151 // $amc_id - amc rule id
152 // $patient_id - pid
153 // $object_category - specific item category (such as prescriptions, transactions etc.)
154 // $object_id - specific item id (such as encounter id, prescription id, etc.)
155 // $date_created - date created.
156 function amcCompleteSafe($amc_id, $patient_id, $object_category = '', $object_id = '0', $date_created = '')
158 sqlStatement("UPDATE `amc_misc_data` SET `date_completed`=NOW() WHERE `amc_id`=? AND `pid`=? AND `map_category`=? AND `map_id`=? AND" .
159 dateEmptySql('date_completed', true) .
160 "AND `date_created`=?", array($amc_id,$patient_id,$object_category,$object_id,$date_created));
163 // Function to remove completion date/flag from an item in the amc_misc_data sql table
164 // $amc_id - amc rule id
165 // $patient_id - pid
166 // $object_category - specific item category (such as prescriptions, transactions etc.)
167 // $object_id - specific item id (such as encounter id, prescription id, etc.)
168 function amcUnComplete($amc_id, $patient_id, $object_category = '', $object_id = '0')
170 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));
173 // Function to remove completion date/flag from an item in the amc_misc_data sql table
174 // As opposed to above function, this is safe for when expect to have duplicate entries
175 // $amc_id - amc rule id
176 // $patient_id - pid
177 // $object_category - specific item category (such as prescriptions, transactions etc.)
178 // $object_id - specific item id (such as encounter id, prescription id, etc.)
179 // $date_created - date created.
180 function amcUnCompleteSafe($amc_id, $patient_id, $object_category = '', $object_id = '0', $date_created = '')
182 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));
185 // Function to complete an item from the amc_misc_data sql table
186 // $amc_id - amc rule id
187 // $patient_id - pid
188 // $object_category - specific item category (such as prescriptions, transactions etc.)
189 // $object_id - specific item id (such as encounter id, prescription id, etc.)
190 function amcCollect($amc_id, $patient_id, $object_category = '', $object_id = '0')
192 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));
195 // Function to support the AMC tracking report
196 // $amc_id - amc rule id
197 // $start - date start range
198 // $end - date end range
199 // $provider_id - provider id
200 function amcTrackingRequest($amc_id, $start = '', $end = '', $provider_id = '')
203 # Collect the patient list first (from the provider)
204 $patients = array();
205 if (empty($provider)) {
206 // Look at entire practice
207 $rez = sqlStatement("SELECT `pid`, `fname`, `lname` FROM `patient_data`");
208 for ($iter = 0; $row = sqlFetchArray($rez); $iter++) {
209 $patients[$iter] = $row;
211 } else {
212 // Look at one provider
213 $rez = sqlStatement("SELECT `pid`, `fname`, `lname` FROM `patient_data` " .
214 "WHERE providerID=?", array($provider));
215 for ($iter = 0; $row = sqlFetchArray($rez); $iter++) {
216 $patients[$iter] = $row;
220 $results = array();
221 foreach ($patients as $patient) {
222 $tempResults = array();
224 if ($amc_id == "send_sum_amc") {
225 $sqlBindArray = array();
226 array_push($sqlBindArray, $patient['pid']);
227 if (!(empty($start))) {
228 $where = " AND `date`>=? ";
229 array_push($sqlBindArray, $start);
232 if (!(empty($end))) {
233 $where .= " AND `date`<=? ";
234 array_push($sqlBindArray, $end);
237 $rez = sqlStatement("SELECT `id`, `date` FROM `transactions` WHERE `title` = 'LBTref' AND `pid` = ? $where ORDER BY `date` DESC", $sqlBindArray);
238 while ($res = sqlFetchArray($rez)) {
239 $amcCheck = amcCollect("send_sum_amc", $patient['pid'], "transactions", $res['id']);
240 if (empty($amcCheck)) {
241 // Records have not been sent, so send this back
242 array_push($tempResults, array("pid" => $patient['pid'], "fname" => $patient['fname'], "lname" => $patient['lname'], "date" => $res['date'], "id" => $res['id']));
245 } elseif ($amc_id == "provide_rec_pat_amc") {
246 $sqlBindArray = array();
247 array_push($sqlBindArray, $patient['pid']);
248 if (!(empty($start))) {
249 $where = " AND `date_created`>=? ";
250 array_push($sqlBindArray, $start);
253 if (!(empty($end))) {
254 $where .= " AND `date_created`<=? ";
255 array_push($sqlBindArray, $end);
258 $rez = sqlStatement("SELECT * FROM `amc_misc_data` WHERE `amc_id`='provide_rec_pat_amc' AND `pid`=? AND " .
259 dateEmptySql('date_completed', true) .
260 "$where ORDER BY `date_created` DESC", $sqlBindArray);
261 while ($res = sqlFetchArray($rez)) {
262 // Records have not been sent, so send this back
263 array_push($tempResults, array("pid" => $patient['pid'], "fname" => $patient['fname'], "lname" => $patient['lname'], "date" => $res['date_created']));
265 } elseif ($amc_id == "provide_sum_pat_amc") {
266 $sqlBindArray = array();
267 array_push($sqlBindArray, $patient['pid']);
268 if (!(empty($start))) {
269 $where = " AND `date`>=? ";
270 array_push($sqlBindArray, $start);
273 if (!(empty($end))) {
274 $where .= " AND `date`<=? ";
275 array_push($sqlBindArray, $end);
278 $rez = sqlStatement("SELECT `encounter`, `date` FROM `form_encounter` WHERE `pid`=? $where ORDER BY `date` DESC", $sqlBindArray);
279 while ($res = sqlFetchArray($rez)) {
280 $amcCheck = amcCollect("provide_sum_pat_amc", $patient['pid'], "form_encounter", $res['encounter']);
281 if (empty($amcCheck)) {
282 // Records have not been given, so send this back
283 array_push($tempResults, array("pid" => $patient['pid'], "fname" => $patient['fname'], "lname" => $patient['lname'], "date" => $res['date'], "id" => $res['encounter']));
286 } else {
287 // report nothing
288 return;
291 // process results
292 $results = array_merge($results, $tempResults);
295 // send results
296 return $results;
299 // The function returns the no. of business days between two dates and it skips the holidays
300 // $start in YYYY-MM-DD
301 // $end in YYYY-MM-DD
302 // $holiday is an array containing YYYY-MM-DD
303 function businessDaysDifference($startDate, $endDate, $holidays = array())
305 //The total number of days between the two dates. We compute the no. of seconds and divide it to 60*60*24
306 //We add one to include both dates in the interval.
307 $days = (strtotime($endDate) - strtotime($startDate)) / 86400 + 1;
309 $no_full_weeks = floor($days / 7);
310 $no_remaining_days = fmod($days, 7);
312 //It will return 1 if it's Monday,.. ,7 for Sunday
313 $the_first_day_of_week = date("N", strtotime($startDate));
314 $the_last_day_of_week = date("N", strtotime($endDate));
316 //---->The two can be equal in leap years when february has 29 days, the equal sign is added here
317 //In the first case the whole interval is within a week, in the second case the interval falls in two weeks.
318 if ($the_first_day_of_week <= $the_last_day_of_week) {
319 if ($the_first_day_of_week <= 6 && 6 <= $the_last_day_of_week) {
320 $no_remaining_days--;
323 if ($the_first_day_of_week <= 7 && 7 <= $the_last_day_of_week) {
324 $no_remaining_days--;
326 } else {
327 // (edit by Tokes to fix an edge case where the start day was a Sunday
328 // and the end day was NOT a Saturday)
330 // the day of the week for start is later than the day of the week for end
331 if ($the_first_day_of_week == 7) {
332 // if the start date is a Sunday, then we definitely subtract 1 day
333 $no_remaining_days--;
335 if ($the_last_day_of_week == 6) {
336 // if the end date is a Saturday, then we subtract another day
337 $no_remaining_days--;
339 } else {
340 // the start date was a Saturday (or earlier), and the end date was (Mon..Fri)
341 // so we skip an entire weekend and subtract 2 days
342 $no_remaining_days -= 2;
346 //The no. of business days is: (number of weeks between the two dates) * (5 working days) + the remainder
347 //---->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
348 $workingDays = $no_full_weeks * 5;
349 if ($no_remaining_days > 0) {
350 $workingDays += $no_remaining_days;
353 //We subtract the holidays
354 foreach ($holidays as $holiday) {
355 $time_stamp = strtotime($holiday);
356 //If the holiday doesn't fall in weekend
357 if (strtotime($startDate) <= $time_stamp && $time_stamp <= strtotime($endDate) && date("N", $time_stamp) != 6 && date("N", $time_stamp) != 7) {
358 $workingDays--;
362 return $workingDays;
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 amcSoCProvided($amc_id, $patient_id, $object_category = '', $object_id = '0')
372 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));
374 // Function to set summary of care provided for a encounter/patient from the amc_misc_data sql table
375 // $amc_id - amc rule id
376 // $patient_id - pid
377 // $object_category - specific item category (such as prescriptions, transactions etc.)
378 // $object_id - specific item id (such as encounter id, prescription id, etc.)
379 function amcNoSoCProvided($amc_id, $patient_id, $object_category = '', $object_id = '0')
381 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));