public function listHistoryAction()
 {
     $personId = (int) $this->_getParam('personId');
     $future = (int) $this->_getParam('future');
     $rows = array();
     $appointmentTemplate = new AppointmentTemplate();
     $reasons = $appointmentTemplate->getAppointmentReasons();
     $iterator = new AppointmentIterator(null, false);
     $filters = array('patientId' => $personId);
     if ($future) {
         $filters['start'] = date('Y-m-d');
     }
     $iterator->setFilters($filters);
     foreach ($iterator as $app) {
         $personId = (int) $app->patientId;
         $appointmentId = (int) $app->appointmentId;
         $providerId = (int) $app->providerId;
         $roomId = (int) $app->roomId;
         list($dateStart, $timeStart) = explode(' ', $app->start);
         list($dateEnd, $timeEnd) = explode(' ', $app->end);
         $providerName = '';
         if ($providerId > 0) {
             $provider = new Provider();
             $provider->setPersonId($providerId);
             $provider->populate();
             $providerName = $provider->displayName;
         }
         $roomName = '';
         if ($roomId > 0) {
             $room = new Room();
             $room->setRoomId($roomId);
             $room->populate();
             $roomName = $room->displayName;
         }
         $routing = new Routing();
         $routing->personId = $personId;
         $routing->appointmentId = $appointmentId;
         $routing->providerId = $providerId;
         $routing->roomId = $roomId;
         $routing->populateByAppointments();
         $station = $routing->stationId;
         $reason = $app->reason;
         $appointmentReason = isset($reasons[$reason]) ? $reasons[$reason]['name'] : '';
         $row = array();
         $row['id'] = $appointmentId;
         $row['data'] = array();
         $row['data'][] = $dateStart;
         $row['data'][] = $timeStart . ' - ' . $timeEnd;
         $row['data'][] = $providerName;
         $row['data'][] = $app->title;
         $row['data'][] = $roomName;
         $row['data'][] = $appointmentReason;
         $row['data'][] = $app->appointmentCode;
         $row['data'][] = $routing->stationId;
         $rows[] = $row;
     }
     $json = Zend_Controller_Action_HelperBroker::getStaticHelper('json');
     $json->suppressExit = true;
     $json->direct(array('rows' => $rows));
 }
 protected function generateEventColumnData($columnIndex, $includeHeader = false)
 {
     $columnIndex = (int) $columnIndex;
     $appointmentIterator = new AppointmentIterator();
     if (!isset($this->getCurrentDisplayFilter($columnIndex)->columns[$columnIndex])) {
         throw new Exception(__("Cannot generate column with that index, there is no filter defined for that column Index: ") . $columnIndex);
     }
     $this->_session->currentAppointments[$columnIndex] = array();
     $filter = $this->getCurrentDisplayFilter();
     $filterTimeStart = strtotime($filter->start);
     $filterTimeEnd = strtotime($filter->end);
     $paramFilters = $filter->columns[$columnIndex];
     if (isset($paramFilters['dateFilter'])) {
         $filter->date = date('Y-m-d', strtotime($paramFilters['dateFilter']));
     }
     $paramFilters['start'] = $filter->date . ' ' . self::FILTER_TIME_START;
     $paramFilters['end'] = $filter->date . ' ' . self::FILTER_TIME_END;
     $columnData = array();
     // we need to get the length of time to create number of rows in the grid
     $timeLen = ($filterTimeEnd - $filterTimeStart) / 60 / self::FILTER_MINUTES_INTERVAL;
     for ($i = 0; $i <= $timeLen; $i++) {
         $row = array();
         // assign row id as rowNumber and columnIndex
         $row['id'] = $i . $columnIndex;
         $row['data'][0] = '';
         $columnData[$i] = $row;
     }
     $filterToTimeStart = strtotime($paramFilters['start']);
     $appointmentIterator->setFilter($paramFilters);
     // hold the temporary data counter
     $tmpDataCtr = array();
     $colMultiplier = 1;
     $zIndex = 0;
     $refHeight = 22;
     foreach ($appointmentIterator as $row) {
         $startToTime = strtotime($row->start);
         $endToTime = strtotime($row->end);
         $tmpStart = date('H:i', $startToTime);
         $tmpEnd = date('H:i', $endToTime);
         $tmpLen = ($endToTime - $startToTime) / 60 / self::FILTER_MINUTES_INTERVAL;
         $timeLen = ceil($tmpLen);
         $tmpIdx = ($startToTime - $filterToTimeStart) / 60 / self::FILTER_MINUTES_INTERVAL;
         $tmpIndex = ceil($tmpIdx);
         if (!isset($columnData[$tmpIndex])) {
             break;
         }
         $height = $refHeight * $timeLen;
         $heightDiff = 0;
         if ($tmpLen != $timeLen) {
             $diff = $refHeight * ($timeLen - $tmpLen);
             $heightDiff = $refHeight - $diff;
             $height -= $heightDiff;
         }
         $marginLeft = 8;
         $multiplier = 1;
         $marginTop = -11.9;
         if ($tmpIdx != $tmpIndex) {
             $marginTop -= $refHeight * ($tmpIndex - $tmpIdx);
             $height -= $refHeight;
             $timeLen--;
             $height += $heightDiff * 2;
         }
         // check for appointment intersection
         foreach ($tmpDataCtr as $keyCtr => $dataCtr) {
             if ($startToTime >= $dataCtr['ranges']['start'] && $startToTime < $dataCtr['ranges']['end']) {
                 if ($endToTime > $dataCtr['ranges']['end']) {
                     $tmpDataCtr[$keyCtr]['ranges']['end'] = $endToTime;
                 }
                 $tmpDataCtr[$keyCtr]['multiplier']++;
                 $multiplier = $tmpDataCtr[$keyCtr]['multiplier'];
                 break;
             }
         }
         if ($multiplier === 1) {
             $ranges = array('start' => $startToTime, 'end' => $endToTime);
             $tmpDataCtr[] = array('ranges' => $ranges, 'multiplier' => $multiplier);
         } else {
             $marginLeft = ($multiplier - 1) * 250;
         }
         if ($multiplier > $colMultiplier) {
             $colMultiplier = $multiplier;
         }
         $patient = new Patient();
         $patient->setPersonId($row->patientId);
         $patient->populate();
         $person = $patient->person;
         $this->_session->currentAppointments[$columnIndex][$row->appointmentId] = $row;
         $zIndex++;
         $columnData[$tmpIndex]['id'] = $row->appointmentId . 'i' . $columnData[$tmpIndex]['id'];
         $appointmentId = $row->appointmentId;
         $visitIcon = '';
         $visit = new Visit();
         $visit->appointmentId = $appointmentId;
         $visit->populateByAppointmentId();
         if ($visit->visitId > 0) {
             $visitIcon = '<img src="' . $this->view->baseUrl . '/img/appointment_visit.png" alt="' . __('Visit') . '" title="' . __('Visit') . '" style="border:0px;height:18px;width:18px;margin-left:5px;" />';
         }
         $routingStatuses = array();
         if (strlen($row->appointmentCode) > 0) {
             $routingStatuses[] = __('Mark') . ': ' . $row->appointmentCode;
         }
         $routing = new Routing();
         $routing->personId = $row->patientId;
         $routing->appointmentId = $row->appointmentId;
         $routing->providerId = $row->providerId;
         $routing->roomId = $row->roomId;
         $routing->populateByAppointments();
         if (strlen($routing->stationId) > 0) {
             $routingStatuses[] = __('Station') . ': ' . $routing->stationId;
         }
         $routingStatus = implode(' ', $routingStatuses);
         $nameLink = '';
         if ($row->patientId > 0) {
             $nameLink = "<a href=\"javascript:showPatientDetails({$row->patientId});\">{$person->last_name}, {$person->first_name} (#{$patient->recordNumber})</a>";
         }
         $columnIndex = (int) $columnIndex;
         $divContent = '<div';
         $divContent .= ' id="event' . $appointmentId . '"';
         $divContent .= ' class="dataForeground"';
         $divContent .= ' appointmentId="' . (int) $row->appointmentId . '" visitId="' . (int) $visit->visitId . '"';
         $divContent .= ' style="float:left;position:absolute;margin-top:' . $marginTop . 'px;height:' . $height . 'px;width:230px;overflow:hidden;border:thin solid black;margin-left:' . $marginLeft . 'px;padding-left:2px;background-color:lightgrey;z-index:' . $zIndex . ';"';
         $divContent .= ' onmouseover="appointmentMouseOver(' . $appointmentId . ',this,' . $height . ');"';
         $divContent .= ' onmouseout="appointmentMouseOut(' . $appointmentId . ',this,' . $height . ',' . $zIndex . ');"';
         $divContent .= ' ondblclick="appointmentDoubleClicked(event,' . $appointmentId . ')"';
         $divContent .= ' oncontextmenu="appointmentClicked(this,event,' . $columnIndex . ');return false;"';
         $divContent .= ' onmousedown="appointmentMouseDown(this,event,' . $columnIndex . ')"';
         $divContent .= '>';
         $divContent .= $tmpStart . '-' . $tmpEnd . ' ' . $nameLink . ' ' . $visitIcon . ' <br />' . $routingStatus . '<div class="bottomInner" id="bottomInnerId' . $appointmentId . '" style="white-space:normal;">' . $row->title . '</div>';
         $divContent .= '</div>';
         $columnData[$tmpIndex]['data'][0] .= $divContent;
         $columnData[$tmpIndex]['userdata']['visitId'] = $visit->visitId;
         $columnData[$tmpIndex]['userdata']['appointmentId'] = $row->appointmentId;
         $columnData[$tmpIndex]['userdata']['length'] = $timeLen;
         if (!isset($columnData[$tmpIndex]['userdata']['ctr'])) {
             $columnData[$tmpIndex]['userdata']['ctr'] = 0;
         }
         $columnData[$tmpIndex]['userdata']['ctr']++;
     }
     $columnData[0]['userdata']['colMultiplier'] = $colMultiplier;
     $columnData[0]['userdata']['providerId'] = $paramFilters['providerId'];
     $roomId = 0;
     if (isset($paramFilters['roomId'])) {
         $roomId = $paramFilters['roomId'];
     }
     $columnData[0]['userdata']['roomId'] = $roomId;
     if ($includeHeader) {
         $header = "{$paramFilters['dateFilter']}<br>";
         $title = $paramFilters['dateFilter'];
         // temporarily set the header as providerId
         $providerId = (int) $paramFilters['providerId'];
         if ($providerId > 0) {
             $provider = new Provider();
             $provider->setPersonId($providerId);
             $provider->populate();
             $name = $provider->optionName;
             // we simply replace the comma with its html equivalent (&#44;) because this may cause not to render the header
             $header .= str_replace(',', '&#44;', $name);
             $title .= ' -> ' . $name;
         }
         if ($roomId > 0) {
             $room = new Room();
             $room->id = $roomId;
             $room->populate();
             if ($providerId > 0) {
                 $header .= '<br>';
             }
             $header .= $room->name;
             $title .= ' -> ' . $room->name;
         }
     }
     $buildings = array();
     $db = Zend_Registry::get('dbAdapter');
     $sqlSelect = $db->select()->from('scheduleEvents', array('start', 'end', 'roomId', 'buildingId', 'title'))->joinLeft('provider', 'scheduleEvents.providerId=provider.person_id', array('providerColor' => 'color'))->joinLeft('person', 'person.person_id=provider.person_id', array('providerName' => 'CONCAT(person.last_name,\', \',person.first_name,\' \',person.middle_name)'))->where('start <= end')->order('start ASC');
     if ((int) $paramFilters['roomId'] > 0 && (int) $paramFilters['providerId'] > 0) {
         $sqlSelect->joinLeft('buildings', 'scheduleEvents.buildingId=buildings.id', null)->joinLeft('rooms', 'rooms.building_id=buildings.id', array('roomColor' => 'color'))->where('rooms.id = ?', (int) $paramFilters['roomId'])->where('providerId = ?', (int) $paramFilters['providerId']);
     } else {
         $sqlSelect->joinLeft('rooms', 'scheduleEvents.roomId=rooms.id', array('roomColor' => 'color'))->where('roomId = ?', (int) $paramFilters['roomId'])->where('providerId = ?', (int) $paramFilters['providerId']);
     }
     if (isset($paramFilters['start'])) {
         $sqlSelect->where('start >= ?', $paramFilters['start']);
     }
     if (isset($paramFilters['end'])) {
         $sqlSelect->where('end <= ?', $paramFilters['end']);
     }
     $stmt = $db->query($sqlSelect);
     $stmt->setFetchMode(Zend_Db::FETCH_ASSOC);
     while ($event = $stmt->fetch()) {
         $x = explode(' ', $event['start']);
         $eventTimeStart = strtotime($x[1]);
         $x = explode(' ', $event['end']);
         $eventTimeEnd = strtotime($x[1]);
         // get the starting index
         $index = ($eventTimeStart - $filterTimeStart) / 60 / self::FILTER_MINUTES_INTERVAL;
         $tmpIndex = $index;
         $color = $event['providerColor'];
         if ($event['roomId'] > 0 && strlen($event['roomColor']) > 0) {
             $color = $event['roomColor'];
         }
         if (substr($color, 0, 1) != '#') {
             $color = '#' . $color;
         }
         if (!isset($buildings[$event['buildingId']])) {
             $building = new Building();
             $building->buildingId = $event['buildingId'];
             $building->populate();
             $buildings[$building->buildingId] = $building;
         }
         $columnData[$tmpIndex]['data'][0] = '<div style="overflow:hidden;white-space:nowrap;margin-top:-6px;">' . $event['title'] . ' - ' . $buildings[$event['buildingId']]->displayName . '</div>' . $columnData[$tmpIndex]['data'][0];
         while ($eventTimeStart < $eventTimeEnd) {
             $eventDateTimeStart = date('Y-m-d H:i:s', $eventTimeStart);
             $eventTimeStart = strtotime('+' . self::FILTER_MINUTES_INTERVAL . ' minutes', $eventTimeStart);
             $columnData[$tmpIndex]['style'] = 'background-color:' . $color . ';border-color:lightgrey;';
             $columnData[$tmpIndex]['userdata']['title'] = $event['title'] . ' of ' . $event['providerName'] . ' (' . $buildings[$event['buildingId']]->displayName . ')';
             $tmpIndex++;
         }
     }
     $ret = array('rows' => $columnData);
     if ($includeHeader) {
         $tmp = array();
         foreach ($buildings as $building) {
             $tmp[] = $building->displayName;
         }
         $eventBuilding = implode(', ', $tmp);
         $header .= '<br>(' . $eventBuilding . ')';
         $title .= ' -> (' . $eventBuilding . ')';
         $header = '<label title="' . $title . '">' . $header . '</label>';
         $ret = array('header' => $header, 'events' => $ret);
     }
     return $ret;
 }
 protected function generateEventColumnData($columnIndex)
 {
     $columnIndex = (int) $columnIndex;
     $columnData = array();
     $scheduleEventIterator = new ScheduleEventIterator();
     $appointmentIterator = new AppointmentIterator();
     if (!isset($this->getCurrentDisplayFilter()->columns[$columnIndex])) {
         throw new Exception(__("Cannot generate column with that index, there is no filter defined for that column Index: ") . $columnIndex);
     }
     $this->_session->currentAppointments[$columnIndex] = array();
     $filter = $this->getCurrentDisplayFilter();
     $filterTimeStart = strtotime($filter->start);
     $filterTimeEnd = strtotime($filter->end);
     $paramFilters = $filter->columns[$columnIndex];
     if (isset($paramFilters['dateFilter'])) {
         $filter->date = date('Y-m-d', strtotime($paramFilters['dateFilter']));
     }
     $paramFilters['start'] = $filter->date . ' ' . $filter->start;
     $paramFilters['end'] = $filter->date . ' ' . $filter->end;
     $paramFilters['start'] = $filter->date . ' ' . $filter->start;
     $paramFilters['end'] = $filter->date . ' 23:59:59';
     $scheduleEventIterator->setFilter($paramFilters);
     // we need to get the length of time to create number of rows in the grid
     $timeLen = ($filterTimeEnd - $filterTimeStart) / 60 / $filter->increment;
     for ($i = 0; $i <= $timeLen; $i++) {
         $row = array();
         // assign row id as rowNumber and columnIndex
         $row['id'] = $i . $columnIndex;
         $row['data'][0] = '';
         $columnData[$i] = $row;
     }
     $filterToTimeStart = strtotime($paramFilters['start']);
     $appointmentIterator->setFilter($paramFilters);
     // hold the temporary data counter
     $tmpDataCtr = array();
     $colMultiplier = 1;
     $patient = new Patient();
     $room = new Room();
     $zIndex = 0;
     foreach ($appointmentIterator as $row) {
         $startToTime = strtotime($row->start);
         $endToTime = strtotime($row->end);
         $tmpStart = date('H:i', $startToTime);
         $tmpEnd = date('H:i', $endToTime);
         $timeLen = ($endToTime - $startToTime) / 60 / $filter->increment;
         $tmpIndex = ($startToTime - $filterToTimeStart) / 60 / $filter->increment;
         if (!isset($columnData[$tmpIndex])) {
             break;
         }
         $index = $tmpIndex;
         for ($j = 1; $j <= $timeLen; $j++) {
             if (!isset($columnData[$index])) {
                 break;
             }
             $index++;
         }
         $j--;
         $height = 20 * $j * 1.1;
         $marginLeft = 8;
         $multiplier = 1;
         // generate ranges code inside if ($multiplier === 1) block
         $incTime = $startToTime;
         $ranges = array();
         for ($ctr = 1; $ctr <= $timeLen; $ctr++) {
             $ranges[] = date('H:i', $incTime);
             $incTime = strtotime("+{$filter->increment} minutes", $incTime);
         }
         // check for appointment intersection
         foreach ($tmpDataCtr as $keyCtr => $dataCtr) {
             if (in_array($tmpStart, $dataCtr['ranges'])) {
                 // merge the ranges if we need to have a nested multiple bookings
                 // uncomment if this is not the case and move the generate ranges to its proper location for code optimization
                 $tmpDataCtr[$keyCtr]['ranges'] = array_merge($dataCtr['ranges'], $ranges);
                 $tmpDataCtr[$keyCtr]['multiplier']++;
                 $multiplier = $tmpDataCtr[$keyCtr]['multiplier'];
                 break;
             }
         }
         if ($multiplier === 1) {
             $tmpDataCtr[] = array('ranges' => $ranges, 'multiplier' => $multiplier);
         } else {
             $marginLeft = ($multiplier - 1) * 250;
         }
         if ($multiplier > $colMultiplier) {
             $colMultiplier = $multiplier;
         }
         $patient->setPersonId($row->patientId);
         $patient->populate();
         $person = $patient->person;
         $room->setRoomId($row->roomId);
         $room->populate();
         $this->_session->currentAppointments[$columnIndex][$row->appointmentId] = $row;
         $mark = '';
         if (strlen($row->appointmentCode) > 0) {
             $mark = "({$row->appointmentCode})";
         }
         $zIndex++;
         // where to use room?
         $columnData[$tmpIndex]['id'] = $row->appointmentId . 'i' . $columnData[$tmpIndex]['id'];
         $appointmentId = $row->appointmentId;
         $columnData[$tmpIndex]['data'][0] .= "<div style=\"float:left;position:absolute;margin-top:-11.9px;height:{$height}px;width:230px;overflow:hidden;border:thin solid black;margin-left:{$marginLeft}px;padding-left:2px;background-color:lightgrey;z-index:{$zIndex};\" class=\"dataForeground\" id=\"event{$appointmentId}\" onmouseover=\"expandAppointment({$appointmentId},this);\" onmouseout=\"shrinkAppointment({$appointmentId},this,{$height},{$zIndex});\">{$tmpStart}-{$tmpEnd} <a href=\"\">{$person->last_name}, {$person->first_name} (#{$row->patientId})</a> <div class=\"bottomInner\" id=\"bottomInnerId{$appointmentId}\">{$row->title} {$mark}</div></div>";
         $columnData[$tmpIndex]['userdata']['appointmentId'] = $row->appointmentId;
     }
     $columnData[0]['userdata']['colMultiplier'] = $colMultiplier;
     $columnData[0]['userdata']['providerId'] = $paramFilters['providerId'];
     $roomId = 0;
     if (isset($paramFilters['roomId'])) {
         $roomId = $paramFilters['roomId'];
     }
     $columnData[0]['userdata']['roomId'] = $roomId;
     foreach ($scheduleEventIterator as $event) {
         $x = explode(' ', $event->start);
         $eventTimeStart = strtotime($x[1]);
         $x = explode(' ', $event->end);
         $eventTimeEnd = strtotime($x[1]);
         // get the starting index
         $index = ($eventTimeStart - $filterTimeStart) / 60 / $filter->increment;
         $tmpIndex = $index;
         $color = $event->provider->color;
         if ($event->roomId > 0 && strlen($event->room->color) > 0) {
             $color = $event->room->color;
         }
         if (substr($color, 0, 1) != '#') {
             $color = '#' . $color;
         }
         while ($eventTimeStart < $eventTimeEnd) {
             $eventDateTimeStart = date('Y-m-d H:i:s', $eventTimeStart);
             $eventTimeStart = strtotime("+{$filter->increment} minutes", $eventTimeStart);
             $columnData[$tmpIndex]['style'] = 'background-color:' . $color . ';border-color:lightgrey;';
             $columnData[$index]['userdata']['title'] = $event->title;
             $tmpIndex++;
         }
     }
     $ret = array();
     $ret['rows'] = $columnData;
     return $ret;
 }