PageRenderTime 37ms CodeModel.GetById 10ms RepoModel.GetById 1ms app.codeStats 0ms

/library/appointments.inc.php

https://github.com/kgenaidy/openemr
PHP | 373 lines | 306 code | 49 blank | 18 comment | 65 complexity | cd31080c16c4525f6f349c20f7706c12 MD5 | raw file
  1. <?php
  2. // Copyright (C) 2011 Ken Chapple
  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. // Holds library functions (and hashes) used by the appointment reporting module
  9. $COMPARE_FUNCTION_HASH = array(
  10. 'doctor' => 'compareAppointmentsByDoctorName',
  11. 'patient' => 'compareAppointmentsByPatientName',
  12. 'pubpid' => 'compareAppointmentsByPatientId',
  13. 'date' => 'compareAppointmentsByDate',
  14. 'time' => 'compareAppointmentsByTime',
  15. 'type' => 'compareAppointmentsByType',
  16. 'comment' => 'compareAppointmentsByComment'
  17. );
  18. $ORDERHASH = array(
  19. 'doctor' => array( 'doctor', 'date', 'time' ),
  20. 'patient' => array( 'patient', 'date', 'time' ),
  21. 'pubpid' => array( 'pubpid', 'date', 'time' ),
  22. 'date' => array( 'date', 'time', 'type', 'patient' ),
  23. 'time' => array( 'time', 'date', 'patient' ),
  24. 'type' => array( 'type', 'date', 'time', 'patient' ),
  25. 'comment' => array( 'comment', 'date', 'time', 'patient' )
  26. );
  27. function fetchEvents( $from_date, $to_date, $where_param = null, $orderby_param = null )
  28. {
  29. $where =
  30. "( (e.pc_endDate >= '$from_date' AND e.pc_eventDate <= '$to_date' AND e.pc_recurrtype = '1') OR " .
  31. "(e.pc_eventDate >= '$from_date' AND e.pc_eventDate <= '$to_date') )";
  32. if ( $where_param ) $where .= $where_param;
  33. $order_by = "e.pc_eventDate, e.pc_startTime";
  34. if ( $orderby_param ) {
  35. $order_by = $orderby_param;
  36. }
  37. $query = "SELECT " .
  38. "e.pc_eventDate, e.pc_endDate, e.pc_startTime, e.pc_endTime, e.pc_duration, e.pc_recurrtype, e.pc_recurrspec, e.pc_recurrfreq, e.pc_catid, e.pc_eid, " .
  39. "e.pc_title, e.pc_hometext, " .
  40. "p.fname, p.mname, p.lname, p.pid, p.pubpid, p.phone_home, p.phone_cell, " .
  41. "u.fname AS ufname, u.mname AS umname, u.lname AS ulname, u.id AS uprovider_id, " .
  42. "c.pc_catname, c.pc_catid " .
  43. "FROM openemr_postcalendar_events AS e " .
  44. "LEFT OUTER JOIN patient_data AS p ON p.pid = e.pc_pid " .
  45. "LEFT OUTER JOIN users AS u ON u.id = e.pc_aid " .
  46. "LEFT OUTER JOIN openemr_postcalendar_categories AS c ON c.pc_catid = e.pc_catid " .
  47. "WHERE $where " .
  48. "ORDER BY $order_by";
  49. $res = sqlStatement( $query );
  50. $events = array();
  51. if ( $res )
  52. {
  53. while ( $row = sqlFetchArray($res) )
  54. {
  55. // if it's a repeating appointment, fetch all occurances in date range
  56. if ( $row['pc_recurrtype'] ) {
  57. $reccuringEvents = getRecurringEvents( $row, $from_date, $to_date );
  58. $events = array_merge( $events, $reccuringEvents );
  59. } else {
  60. $events []= $row;
  61. }
  62. }
  63. }
  64. return $events;
  65. }
  66. function fetchAllEvents( $from_date, $to_date, $provider_id = null, $facility_id = null )
  67. {
  68. $where = "";
  69. if ( $provider_id ) $where .= " AND e.pc_aid = '$provider_id'";
  70. $facility_filter = '';
  71. if ( $facility_id ) {
  72. $event_facility_filter = " AND e.pc_facility = '$facility_id'";
  73. $provider_facility_filter = " AND u.facility_id = '$facility_id'";
  74. $facility_filter = $event_facility_filter . $provider_facility_filter;
  75. }
  76. $where .= $facility_filter;
  77. $appointments = fetchEvents( $from_date, $to_date, $where );
  78. return $appointments;
  79. }
  80. function fetchAppointments( $from_date, $to_date, $patient_id = null, $provider_id = null, $facility_id = null )
  81. {
  82. $where = "";
  83. if ( $provider_id ) $where .= " AND e.pc_aid = '$provider_id'";
  84. if ( $patient_id ) {
  85. $where .= " AND e.pc_pid = '$patient_id'";
  86. } else {
  87. $where .= " AND e.pc_pid != ''";
  88. }
  89. $facility_filter = '';
  90. if ( $facility_id ) {
  91. $event_facility_filter = " AND e.pc_facility = '$facility_id'";
  92. $provider_facility_filter = " AND u.facility_id = '$facility_id'";
  93. $facility_filter = $event_facility_filter . $provider_facility_filter;
  94. }
  95. $where .= $facility_filter;
  96. $appointments = fetchEvents( $from_date, $to_date, $where );
  97. return $appointments;
  98. }
  99. function getRecurringEvents( $event, $from_date, $to_date )
  100. {
  101. $repeatEvents = array();
  102. $from_date_time = strtotime( $from_date . " 00:00:00" );
  103. $thistime = strtotime( $event['pc_eventDate'] . " 00:00:00" );
  104. //$thistime = max( $thistime, $from_date_time );
  105. if ( $event['pc_recurrtype'] )
  106. {
  107. preg_match( '/"event_repeat_freq_type";s:1:"(\d)"/', $event['pc_recurrspec'], $matches );
  108. $repeattype = $matches[1];
  109. preg_match( '/"event_repeat_freq";s:1:"(\d)"/', $event['pc_recurrspec'], $matches );
  110. $repeatfreq = $matches[1];
  111. if ( !$repeatfreq ) $repeatfreq = 1;
  112. $upToDate = strtotime( $to_date." 23:59:59" ); // set the up-to-date to the last second of the "to_date"
  113. $endtime = strtotime( $event['pc_endDate'] . " 23:59:59" );
  114. if ( $endtime > $upToDate ) $endtime = $upToDate;
  115. $repeatix = 0;
  116. while ( $thistime < $endtime )
  117. {
  118. // Skip the event if a repeat frequency > 1 was specified and this is
  119. // not the desired occurrence.
  120. if ( !$repeatix ) {
  121. $inRange = ( $thistime >= $from_date_time && $thistime < $upToDate );
  122. if ( $inRange ) {
  123. $newEvent = $event;
  124. $eventDate = date( "Y-m-d", $thistime );
  125. $newEvent['pc_eventDate'] = $eventDate;
  126. $newEvent['pc_endDate'] = $eventDate;
  127. $repeatEvents []= $newEvent;
  128. }
  129. }
  130. if ( ++$repeatix >= $repeatfreq ) $repeatix = 0;
  131. $adate = getdate($thistime);
  132. if ($repeattype == 0) { // daily
  133. $adate['mday'] += 1;
  134. } else if ($repeattype == 1) { // weekly
  135. $adate['mday'] += 7;
  136. } else if ($repeattype == 2) { // monthly
  137. $adate['mon'] += 1;
  138. } else if ($repeattype == 3) { // yearly
  139. $adate['year'] += 1;
  140. } else if ($repeattype == 4) { // work days
  141. if ($adate['wday'] == 5) // if friday, skip to monday
  142. $adate['mday'] += 3;
  143. else if ($adate['wday'] == 6) // saturday should not happen
  144. $adate['mday'] += 2;
  145. else
  146. $adate['mday'] += 1;
  147. } else {
  148. die("Invalid repeat type '$repeattype'");
  149. }
  150. $thistime = mktime(0, 0, 0, $adate['mon'], $adate['mday'], $adate['year']);
  151. }
  152. }
  153. return $repeatEvents;
  154. }
  155. // get the event slot size in seconds
  156. function getSlotSize()
  157. {
  158. if ( isset( $GLOBALS['calendar_interval'] ) ) {
  159. return $GLOBALS['calendar_interval'] * 60;
  160. }
  161. return 15 * 60;
  162. }
  163. function getAvailableSlots( $from_date, $to_date, $provider_id = null, $facility_id = null )
  164. {
  165. $appointments = fetchAllEvents( $from_date, $to_date, $provider_id, $facility_id );
  166. $appointments = sortAppointments( $appointments, "date" );
  167. $from_datetime = strtotime( $from_date." 00:00:00" );
  168. $to_datetime = strtotime( $to_date." 23:59:59" );
  169. $availableSlots = array();
  170. $start_time = 0;
  171. $date = 0;
  172. for ( $i = 0; $i < count( $appointments ); ++$i )
  173. {
  174. if ( $appointments[$i]['pc_catid'] == 2 ) { // 2 == In Office
  175. $start_time = $appointments[$i]['pc_startTime'];
  176. $date = $appointments[$i]['pc_eventDate'];
  177. $provider_id = $appointments[$i]['uprovider_id'];
  178. } else if ( $appointments[$i]['pc_catid'] == 3 ) { // 3 == Out Of Office
  179. continue;
  180. } else {
  181. $start_time = $appointments[$i]['pc_endTime'];
  182. $date = $appointments[$i]['pc_eventDate'];
  183. $provider_id = $appointments[$i]['uprovider_id'];
  184. }
  185. // find next appointment with the same provider
  186. $next_appointment_date = 0;
  187. $next_appointment_time = 0;
  188. for ( $j = $i+1; $j < count( $appointments ); ++$j ) {
  189. if ( $appointments[$j]['uprovider_id'] == $provider_id ) {
  190. $next_appointment_date = $appointments[$j]['pc_eventDate'];
  191. $next_appointment_time = $appointments[$j]['pc_startTime'];
  192. break;
  193. }
  194. }
  195. $same_day = ( strtotime( $next_appointment_date ) == strtotime( $date ) ) ? true : false;
  196. if ( $next_appointment_time && $same_day ) {
  197. // check the start time of the next appointment
  198. $start_datetime = strtotime( $date." ".$start_time );
  199. $next_appointment_datetime = strtotime( $next_appointment_date." ".$next_appointment_time );
  200. $curr_time = $start_datetime;
  201. while ( $curr_time < $next_appointment_datetime - (getSlotSize() / 2) ) {
  202. //create a new appointment ever 15 minutes
  203. $time = date( "H:i:s", $curr_time );
  204. $available_slot = createAvailableSlot(
  205. $appointments[$i]['pc_eventDate'],
  206. $time,
  207. $appointments[$i]['ufname'],
  208. $appointments[$i]['ulname'],
  209. $appointments[$i]['umname'] );
  210. $availableSlots []= $available_slot;
  211. $curr_time += getSlotSize(); // add a 15-minute slot
  212. }
  213. }
  214. }
  215. return $availableSlots;
  216. }
  217. function createAvailableSlot( $event_date, $start_time, $provider_fname, $provider_lname, $provider_mname = "", $cat_name = "Available" )
  218. {
  219. $newSlot = array();
  220. $newSlot['ulname'] = $provider_lname;
  221. $newSlot['ufname'] = $provider_fname;
  222. $newSlot['umname'] = $provider_mname;
  223. $newSlot['pc_eventDate'] = $event_date;
  224. $newSlot['pc_startTime'] = $start_time;
  225. $newSlot['pc_endTime'] = $start_time;
  226. $newSlot['pc_catname'] = $cat_name;
  227. return $newSlot;
  228. }
  229. function getCompareFunction( $code ) {
  230. global $COMPARE_FUNCTION_HASH;
  231. return $COMPARE_FUNCTION_HASH[$code];
  232. }
  233. function getComparisonOrder( $code ) {
  234. global $ORDERHASH;
  235. return $ORDERHASH[$code];
  236. }
  237. function sortAppointments( array $appointments, $orderBy = 'date' )
  238. {
  239. global $appointment_sort_order;
  240. $appointment_sort_order = $orderBy;
  241. usort( $appointments, "compareAppointments" );
  242. return $appointments;
  243. }
  244. // cmp_function for usort
  245. // The comparison function must return an integer less than, equal to,
  246. // or greater than zero if the first argument is considered to be respectively less than, equal to, or greater than the second.
  247. function compareAppointments( $appointment1, $appointment2 )
  248. {
  249. global $appointment_sort_order;
  250. $comparisonOrder = getComparisonOrder( $appointment_sort_order );
  251. foreach ( $comparisonOrder as $comparison )
  252. {
  253. $cmp_function = getCompareFunction( $comparison );
  254. $result = $cmp_function( $appointment1, $appointment2 );
  255. if ( 0 != $result ) {
  256. return $result;
  257. }
  258. }
  259. return 0;
  260. }
  261. function compareBasic( $e1, $e2 )
  262. {
  263. if ( $e1 < $e2 ) {
  264. return -1;
  265. } else if ( $e1 > $e2 ) {
  266. return 1;
  267. }
  268. return 0;
  269. }
  270. function compareAppointmentsByDate( $appointment1, $appointment2 )
  271. {
  272. $date1 = strtotime( $appointment1['pc_eventDate'] );
  273. $date2 = strtotime( $appointment2['pc_eventDate'] );
  274. return compareBasic( $date1, $date2 );
  275. }
  276. function compareAppointmentsByTime( $appointment1, $appointment2 )
  277. {
  278. $time1 = strtotime( $appointment1['pc_startTime'] );
  279. $time2 = strtotime( $appointment2['pc_startTime'] );
  280. return compareBasic( $time1, $time2 );
  281. }
  282. function compareAppointmentsByDoctorName( $appointment1, $appointment2 )
  283. {
  284. $name1 = $appointment1['ulname'];
  285. $name2 = $appointment2['ulname'];
  286. $cmp = compareBasic( $name1, $name2 );
  287. if ( $cmp == 0 ) {
  288. $name1 = $appointment1['ufname'];
  289. $name2 = $appointment2['ufname'];
  290. return compareBasic( $name1, $name2 );
  291. }
  292. return $cmp;
  293. }
  294. function compareAppointmentsByPatientName( $appointment1, $appointment2 )
  295. {
  296. $name1 = $appointment1['lname'];
  297. $name2 = $appointment2['lname'];
  298. $cmp = compareBasic( $name1, $name2 );
  299. if ( $cmp == 0 ) {
  300. $name1 = $appointment1['fname'];
  301. $name2 = $appointment2['fname'];
  302. return compareBasic( $name1, $name2 );
  303. }
  304. return $cmp;
  305. }
  306. function compareAppointmentsByType( $appointment1, $appointment2 )
  307. {
  308. $type1 = $appointment1['pc_catid'];
  309. $type2 = $appointment2['pc_catid'];
  310. return compareBasic( $type1, $type2 );
  311. }
  312. function compareAppointmentsByPatientId( $appointment1, $appointment2 )
  313. {
  314. $id1 = $appointment1['pubpid'];
  315. $id2 = $appointment2['pubpid'];
  316. return compareBasic( $id1, $id2 );
  317. }
  318. function compareAppointmentsByComment( $appointment1, $appointment2 )
  319. {
  320. $comment1 = $appointment1['pc_hometext'];
  321. $comment2 = $appointment2['pc_hometext'];
  322. return compareBasic( $comment1, $comment2 );
  323. }
  324. ?>