/**
  * Override this function when you need to perform any actions when the data is loaded.
  *
  * Test for the availability of variables as these objects can be loaded data first after
  * deserialization or registry variables first after normal instantiation.
  *
  * That is why this function called both at the end of afterRegistry() and after exchangeArray(),
  * but NOT after unserialize().
  *
  * After this the object should be ready for serialization
  */
 protected function afterLoad()
 {
     if ($this->_data && $this->agenda instanceof \Gems_Agenda && !$this->_subFilters) {
         // Flexible determination of filters to load. Save for future expansion of numbe rof fields
         $i = 1;
         $field = 'gaf_filter_text' . $i;
         $filterIds = array();
         while (array_key_exists($field, $this->_data)) {
             if ($this->_data[$field]) {
                 $filterIds[] = intval($this->_data[$field]);
             }
             $i++;
             $field = 'gaf_filter_text' . $i;
         }
         if ($filterIds) {
             $filterObjects = $this->agenda->getFilters("SELECT *\n                    FROM gems__appointment_filters \n                    WHERE gaf_id IN (" . implode(', ', $filterIds) . ")\n                    ORDER BY gaf_id_order");
             // The order we get the filters may not be the same as the one in which they are specified
             foreach ($filterIds as $id) {
                 foreach ($filterObjects as $filterObject) {
                     if ($filterObject instanceof AppointmentFilterInterface) {
                         if ($filterObject->getFilterId() == $id) {
                             $this->_subFilters[$id] = $filterObject;
                             break;
                         }
                     }
                 }
             }
         }
     }
 }
 /**
  * Perform any translations necessary for the code to work
  *
  * @param mixed $row array or \Traversable row
  * @param scalar $key
  * @return mixed Row array or false when errors occurred
  */
 public function translateRowValues($row, $key)
 {
     $row = parent::translateRowValues($row, $key);
     if (!$row) {
         return false;
     }
     // Set fixed values for import
     $row['gap_source'] = 'import';
     $row['gap_manual_edit'] = 0;
     if (!isset($row['gap_id_user'])) {
         if (isset($row['gr2o_patient_nr'], $row[$this->orgIdField])) {
             $sql = 'SELECT gr2o_id_user
                     FROM gems__respondent2org
                     WHERE gr2o_patient_nr = ? AND gr2o_id_organization = ?';
             $id = $this->db->fetchOne($sql, array($row['gr2o_patient_nr'], $row[$this->orgIdField]));
             if ($id) {
                 $row['gap_id_user'] = $id;
             }
         }
         if (!isset($row['gap_id_user'])) {
             // No user no import if still not set
             return false;
         }
     }
     if (isset($row['gap_admission_time'], $row['gap_discharge_time']) && $row['gap_admission_time'] instanceof \MUtil_Date && $row['gap_discharge_time'] instanceof \MUtil_Date) {
         if ($row['gap_discharge_time']->diffDays($row['gap_admission_time']) > 366) {
             if ($row['gap_discharge_time']->diffDays() > 366) {
                 $row['gap_discharge_time'] = null;
             }
         }
     }
     $skip = false;
     if (isset($row['gas_name_attended_by'])) {
         $row['gap_id_attended_by'] = $this->_agenda->matchHealthcareStaff($row['gas_name_attended_by'], $row[$this->orgIdField]);
         $skip = $skip || false === $row['gap_id_attended_by'];
     }
     if (isset($row['gas_name_referred_by'])) {
         $row['gap_id_referred_by'] = $this->_agenda->matchHealthcareStaff($row['gas_name_referred_by'], $row[$this->orgIdField]);
         $skip = $skip || false === $row['gap_id_referred_by'];
     }
     if (isset($row['gaa_name'])) {
         $row['gap_id_activity'] = $this->_agenda->matchActivity($row['gaa_name'], $row[$this->orgIdField]);
         $skip = $skip || false === $row['gap_id_activity'];
     }
     if (isset($row['gapr_name'])) {
         $row['gap_id_procedure'] = $this->_agenda->matchProcedure($row['gapr_name'], $row[$this->orgIdField]);
         $skip = $skip || false === $row['gap_id_procedure'];
     }
     if (isset($row['glo_name'])) {
         $location = $this->_agenda->matchLocation($row['glo_name'], $row[$this->orgIdField]);
         $row['gap_id_location'] = $location['glo_id_location'];
         $skip = $skip || $location['glo_filter'];
     }
     if ($skip) {
         return null;
     }
     // \MUtil_Echo::track($row);
     return $row;
 }
 /**
  * Load filter dependencies into model and populate the filterOptions
  *
  * @return array filterClassName => Label
  */
 protected function loadFilterDependencies($activateDependencies = true)
 {
     if (!$this->filterOptions) {
         $maxLength = $this->get('gaf_calc_name', 'maxlength');
         $this->filterOptions = array();
         foreach ($this->filterDependencies as $dependencyClass) {
             $dependency = $this->agenda->newFilterObject($dependencyClass);
             if ($dependency instanceof FilterModelDependencyAbstract) {
                 $this->filterOptions[$dependency->getFilterClass()] = $dependency->getFilterName();
                 if ($activateDependencies) {
                     $dependency->setMaximumCalcLength($maxLength);
                     $this->addDependency($dependency);
                 }
             }
         }
         asort($this->filterOptions);
     }
     return $this->filterOptions;
 }
 /**
  * Called after the check that all required registry values
  * have been set correctly has run.
  *
  * @return void
  */
 public function afterRegistry()
 {
     $this->_filters = $this->util->getTranslated()->getEmptyDropdownArray() + $this->agenda->getFilterList();
     parent::afterRegistry();
 }
 /**
  * Get the settings for the gaf_filter_textN fields
  *
  * Fields not in this array are not shown in any way
  *
  * @return array gaf_filter_textN => array(modelFieldName => fieldValue)
  */
 public function getTextSettings()
 {
     $fields = $this->agenda->getFieldLabels();
     $description = $this->_("Use the %%-sign to search for zero or more random characters and an _ for a single random character.");
     return array('gaf_filter_text1' => array('label' => $this->_('Field 1'), 'multiOptions' => $fields, 'required' => true), 'gaf_filter_text2' => array('label' => $this->_('Search text 1'), 'description' => $description, 'required' => true), 'gaf_filter_text3' => array('label' => $this->_('Field 2'), 'multiOptions' => $this->util->getTranslated()->getEmptyDropdownArray() + $fields), 'gaf_filter_text4' => array('label' => $this->_('Search text 2'), 'description' => sprintf($this->_("Required when filled - use %%-sign as well."))));
 }
 /**
  * Recalculate all tracks that use this appointment
  *
  * @return int The number of tokens changed by this code
  */
 public function updateTracks()
 {
     $tokenChanges = 0;
     $tracker = $this->loader->getTracker();
     $userId = $this->currentUser->getUserId();
     // Find all the fields that use this agenda item
     $select = $this->db->select();
     $select->from('gems__respondent2track2appointment', array('gr2t2a_id_respondent_track'))->joinInner('gems__respondent2track', 'gr2t_id_respondent_track = gr2t2a_id_respondent_track', array('gr2t_id_track'))->where('gr2t2a_id_appointment = ?', $this->_appointmentId)->distinct();
     // AND find the filters for any new fields to fill
     $filters = $this->agenda->matchFilters($this);
     if ($filters) {
         $ids = array_map(function ($value) {
             return $value->getTrackId();
         }, $filters);
         // \MUtil_Echo::track(array_keys($filters), $ids);
         $respId = $this->getRespondentId();
         $orgId = $this->getOrganizationId();
         $select->orWhere("gr2t_id_user = {$respId} AND gr2t_id_organization = {$orgId} AND gr2t_id_track IN (" . implode(', ', $ids) . ")");
         // \MUtil_Echo::track($this->getId(), implode(', ', $ids));
     }
     // \MUtil_Echo::track($select->__toString());
     // Now find all the existing tracks that should be checked
     $respTracks = $this->db->fetchPairs($select);
     // \MUtil_Echo::track($respTracks);
     if ($respTracks) {
         foreach ($respTracks as $respTrackId => $trackId) {
             $respTrack = $tracker->getRespondentTrack($respTrackId);
             // Recalculate this track
             $fieldsChanged = false;
             $tokenChanges += $respTrack->recalculateFields($fieldsChanged);
             // Store the track for creation checking
             $existingTracks[$trackId][] = $respTrack;
         }
     } else {
         $existingTracks = array();
         $respTracks = array();
     }
     // \MUtil_Echo::track($tokenChanges);
     // Never create tracks for inactive appointments and for appointments in the past
     if (!$this->isActive() || $this->getAdmissionTime()->isEarlierOrEqual(new \MUtil_Date())) {
         return $tokenChanges;
     }
     // \MUtil_Echo::track(count($filters));
     // Check for tracks that should be created
     foreach ($filters as $filter) {
         if ($filter instanceof AppointmentFilterInterface && $filter->isCreator()) {
             $createTrack = true;
             $trackId = $filter->getTrackId();
             if (isset($existingTracks[$trackId])) {
                 foreach ($existingTracks[$trackId] as $respTrack) {
                     if ($respTrack instanceof \Gems_Tracker_RespondentTrack) {
                         if ($respTrack->hasSuccesCode()) {
                             // \MUtil_Echo::track($trackId, $respTrack->isOpen());
                             // An open track of this type exists: do not create a new one
                             if ($respTrack->isOpen()) {
                                 $createTrack = false;
                                 break;
                             }
                             // A closed tracks exist.
                             // Is there one that ended less than wait days ago
                             $curr = $this->getAdmissionTime();
                             $end = $respTrack->getEndDate();
                             $wait = $filter->getWaitDays();
                             if ($wait === null || !$curr || !$end || $curr->diffDays($end) <= $wait) {
                                 // \MUtil_Echo::track($trackId, $curr->diffDays($end), $wait);
                                 $createTrack = false;
                                 break;
                             }
                             // \MUtil_Echo::track($trackId, $curr->diffDays($end), $wait);
                             // Track has already been assigned
                             $data = $respTrack->getFieldData();
                             if (isset($data[$filter->getFieldId()]) && $this->getId() == $data[$filter->getFieldId()]) {
                                 // \MUtil_Echo::track($data[$filter->getFieldId()]);
                                 $createTrack = false;
                                 break;
                             }
                         }
                     }
                 }
             }
             // \MUtil_Echo::track($trackId, $createTrack, $filter->getName(), $filter->getSqlWhere(), $filter->getFilterId());
             if ($createTrack) {
                 $trackData = array('gr2t_comment' => sprintf($this->_('Track created by %s filter'), $filter->getName()));
                 $fields = array($filter->getFieldId() => $this->getId());
                 $respTrack = $tracker->createRespondentTrack($this->getRespondentId(), $this->getOrganizationId(), $trackId, $userId, $trackData, $fields);
                 $existingTracks[$trackId][] = $respTrack;
                 $tokenChanges += $respTrack->getCount();
             }
         }
     }
     return $tokenChanges;
 }
 /**
  * Select only active agenda items
  *
  * @return \Gems\Agenda\AppointmentSelect
  */
 public function onlyActive()
 {
     $this->_select->where('gap_status IN (?)', $this->agenda->getStatusKeysActiveDbQuoted());
     return $this;
 }