/**
  * Hook performing actual save
  *
  * @param string $newCode
  * @param int $userId
  * @return $changed
  */
 public function setReceptionCode($newCode, $userId)
 {
     $oldCode = $this->respondentTrack->getReceptionCode()->getCode();
     // Use the repesondent track function as that cascades the consent code
     $changed = $this->respondentTrack->setReceptionCode($newCode, $this->formData['gr2t_comment'], $userId);
     if ($this->unDelete) {
         $this->addMessage($this->_('Track restored.'));
         if (isset($this->formData['restore_tokens']) && $this->formData['restore_tokens']) {
             $count = 0;
             foreach ($this->respondentTrack->getTokens() as $token) {
                 if ($token instanceof \Gems_Tracker_Token) {
                     if ($oldCode === $token->getReceptionCode()->getCode()) {
                         $count += $token->setReceptionCode($newCode, null, $userId);
                     }
                 }
             }
             $this->addMessage(sprintf($this->plural('%d token reception codes restored.', '%d tokens reception codes restored.', $count), $count));
         }
     } else {
         if ($this->util->getReceptionCode($newCode)->isStopCode()) {
             $this->addMessage($this->_('Track stopped.'));
         } else {
             $this->addMessage($this->_('Track deleted.'));
         }
     }
     return $changed;
 }
 /**
  * The place to check if the data set in the snippet is valid
  * to generate the snippet.
  *
  * When invalid data should result in an error, you can throw it
  * here but you can also perform the check in the
  * checkRegistryRequestsAnswers() function from the
  * {@see \MUtil_Registry_TargetInterface}.
  *
  * @return boolean
  */
 public function hasHtmlOutput()
 {
     if ($this->respondent instanceof \Gems_Tracker_Respondent) {
         if (!$this->patientId) {
             $this->patientId = $this->respondent->getPatientNumber();
         }
         if (!$this->organizationId) {
             $this->organizationId = $this->respondent->getOrganizationId();
         }
     }
     // Try to get $this->respondentTrackId filled
     if (!$this->respondentTrackId) {
         if ($this->respondentTrack) {
             $this->respondentTrackId = $this->respondentTrack->getRespondentTrackId();
         } else {
             $this->respondentTrackId = $this->request->getParam(\Gems_Model::RESPONDENT_TRACK);
         }
     }
     // Try to get $this->respondentTrack filled
     if ($this->respondentTrackId && !$this->respondentTrack) {
         $this->respondentTrack = $this->loader->getTracker()->getRespondentTrack($this->respondentTrackId);
     }
     // Set the user id
     if (!$this->userId) {
         $this->userId = $this->loader->getCurrentUser()->getUserId();
     }
     if ($this->respondentTrack) {
         // We are updating
         $this->createData = false;
         // Try to get $this->trackEngine filled
         if (!$this->trackEngine) {
             // Set the engine used
             $this->trackEngine = $this->respondentTrack->getTrackEngine();
         }
     } else {
         // We are inserting
         $this->createData = true;
         $this->saveLabel = $this->_($this->_('Add track'));
         // Try to get $this->trackId filled
         if (!$this->trackId) {
             if ($this->trackEngine) {
                 $this->trackId = $this->trackEngine->getTrackId();
             } else {
                 $this->trackId = $this->request->getParam(\Gems_Model::TRACK_ID);
             }
         }
         // Try to get $this->trackEngine filled
         if ($this->trackId && !$this->trackEngine) {
             $this->trackEngine = $this->loader->getTracker()->getTrackEngine($this->trackId);
         }
         if (!($this->trackEngine && $this->patientId && $this->organizationId && $this->userId)) {
             throw new \Gems_Exception_Coding('Missing parameter for ' . __CLASS__ . ': could not find data for editing a respondent track nor the track engine, patientId and organizationId needed for creating one.');
         }
     }
     return parent::hasHtmlOutput();
 }
 /**
  * Process the data and do what must be done
  *
  * Storing the changed $values is handled by the calling function.
  *
  * @param \Gems_Tracker_RespondentTrack $respTrack Gems respondent track object
  * @param int   $userId The current userId
  * @return void
  */
 public function processFieldUpdate(\Gems_Tracker_RespondentTrack $respTrack, $userId)
 {
     $agenda = $this->loader->getAgenda();
     $change = false;
     $token = $respTrack->getFirstToken();
     if (!$token) {
         return;
     }
     do {
         if ($token->isCompleted()) {
             continue;
         }
         $appId = $respTrack->getRoundAfterAppointmentId($token->getRoundId());
         // Not a round without appointment id
         if ($appId !== false) {
             if ($appId) {
                 $appointment = $agenda->getAppointment($appId);
             } else {
                 $appointment = null;
             }
             if ($appointment && $appointment->isActive()) {
                 $newCode = \GemsEscort::RECEPTION_OK;
                 $newText = null;
             } else {
                 $newCode = 'skip';
                 $newText = $this->_('Skipped until appointment is set');
             }
             $oldCode = \GemsEscort::RECEPTION_OK === $newCode ? 'skip' : \GemsEscort::RECEPTION_OK;
             $curCode = $token->getReceptionCode()->getCode();
             // \MUtil_Echo::track($token->getTokenId(), $curCode, $oldCode, $newCode);
             if ($oldCode === $curCode && $curCode !== $newCode) {
                 $change = true;
                 $token->setReceptionCode($newCode, $newText, $userId);
             }
         }
     } while ($token = $token->getNextToken());
     if ($change) {
         $respTrack->refresh();
     }
 }
 protected function loadExport()
 {
     $this->export = $this->loader->getRespondentExport();
     if ($this->token instanceof \Gems_Tracker_Token) {
         $this->addRespondent($this->token->getPatientNumber(), $this->token->getOrganizationId());
         $this->export->addRespondentTrackFilter($this->token->getRespondentTrackId());
         $this->export->addTokenFilter($this->token->getTokenId());
     } elseif ($this->respondentTrack instanceof \Gems_Tracker_RespondentTrack) {
         $this->addRespondent($this->respondentTrack->getPatientNumber(), $this->respondentTrack->getOrganizationId());
         $this->export->addRespondentTrackFilter($this->respondentTrack->getRespondentTrackId());
     } elseif ($this->respondent instanceof \Gems_Tracker_Respondent) {
         $this->addRespondent($this->respondent->getPatientNumber(), $this->respondent->getOrganizationId());
     }
 }
 /**
  * The place to check if the data set in the snippet is valid
  * to generate the snippet.
  *
  * When invalid data should result in an error, you can throw it
  * here but you can also perform the check in the
  * checkRegistryRequestsAnswers() function from the
  * {@see \MUtil_Registry_TargetInterface}.
  *
  * @return boolean
  */
 public function hasHtmlOutput()
 {
     if (!$this->multiTracks) {
         return false;
     }
     $this->tracker = $this->loader->getTracker();
     if (!$this->respondentTrackId) {
         $this->respondentTrackId = $this->request->getParam(\Gems_Model::RESPONDENT_TRACK);
     }
     if ($this->respondentTrackId) {
         if (!$this->respondentTrack instanceof \Gems_Tracker_RespondentTrack) {
             $this->respondentTrack = $this->tracker->getRespondentTrack($this->respondentTrackId);
         }
     }
     if ($this->respondentTrack instanceof \Gems_Tracker_RespondentTrack) {
         if (!$this->respondentTrackId) {
             $this->respondentTrackId = $this->respondentTrack->getRespondentTrackId();
         }
         $this->trackId = $this->respondentTrack->getTrackId();
         if (!$this->respondentId) {
             $this->respondentId = $this->respondentTrack->getRespondentId();
         }
         if (!$this->organizationId) {
             $this->organizationId = $this->respondentTrack->getOrganizationId();
         }
         $this->caption = $this->_('Other assignments of this track to this respondent.');
         $this->onEmpty = $this->_('This track is assigned only once to this respondent.');
     } else {
         if ($this->respondent instanceof \Gems_Tracker_Respondent) {
             if (!$this->respondentId) {
                 $this->respondentId = $this->respondent->getId();
             }
             if (!$this->organizationId) {
                 $this->organizationId = $this->respondent->getOrganizationId();
             }
         }
         $this->caption = $this->_('Existing assignments of this track to this respondent.');
         $this->onEmpty = $this->_('This track is not assigned to this respondent.');
     }
     if (!$this->trackId) {
         $this->trackId = $this->request->getParam(\Gems_Model::TRACK_ID);
     }
     if (!$this->trackId && $this->trackEngine instanceof \Gems_Tracker_Engine_TrackEngineInterface) {
         $this->trackId = $this->trackEngine->getTrackId();
     }
     return $this->trackId && $this->respondentId && $this->organizationId && parent::hasHtmlOutput();
 }
 /**
  * The place to check if the data set in the snippet is valid
  * to generate the snippet.
  *
  * When invalid data should result in an error, you can throw it
  * here but you can also perform the check in the
  * checkRegistryRequestsAnswers() function from the
  * {@see \MUtil_Registry_TargetInterface}.
  *
  * @return boolean
  */
 public function hasHtmlOutput()
 {
     // Try to set $this->respondentTrackId, it can be ok when not set
     if (!$this->respondentTrackId) {
         if ($this->respondentTrack) {
             $this->respondentTrackId = $this->respondentTrack->getRespondentTrackId();
         } else {
             $this->respondentTrackId = $this->request->getParam(\Gems_Model::RESPONDENT_TRACK);
         }
     }
     // First attempt at trackId
     if (!$this->trackId && $this->trackEngine) {
         $this->trackId = $this->trackEngine->getTrackId();
     }
     // Check if a sufficient set of data is there
     if (!($this->trackId || $this->patientId || $this->organizationId)) {
         // Now we really need $this->respondentTrack
         if (!$this->respondentTrack) {
             if ($this->respondentTrackId) {
                 $this->respondentTrack = $this->loader->getTracker()->getRespondentTrack($this->respondentTrackId);
             } else {
                 // Parameters not valid
                 return false;
             }
         }
     }
     if (!$this->trackId) {
         $this->trackId = $this->respondentTrack->getTrackId();
     }
     if (!$this->patientId) {
         $this->patientId = $this->respondentTrack->getPatientNumber();
     }
     if (!$this->organizationId) {
         $this->organizationId = $this->respondentTrack->getOrganizationId();
     }
     // \MUtil_Echo::track($this->trackId, $this->patientId, $this->organizationId, $this->respondentTrackId);
     return $this->getModel()->loadFirst() && parent::hasHtmlOutput();
 }
 /**
  * Returns the date to use to calculate the ValidUntil if any
  *
  * @param string $fieldSource Source for field from round
  * @param string $fieldName Name from round
  * @param int $prevRoundId Id from round
  * @param \Gems_Tracker_Token $token
  * @param \Gems_Tracker_RespondentTrack $respTrack
  * @param \MUtil_Date $validFrom The calculated new valid from value or null
  * @return \MUtil_Date date time or null
  */
 protected function getValidUntilDate($fieldSource, $fieldName, $prevRoundId, \Gems_Tracker_Token $token, \Gems_Tracker_RespondentTrack $respTrack, $validFrom)
 {
     $date = null;
     switch ($fieldSource) {
         case parent::NO_TABLE:
             break;
         case parent::TOKEN_TABLE:
             // Always uses the current token
             if ($fieldName == 'gto_valid_from') {
                 // May be changed but is not yet stored
                 $date = $validFrom;
             } else {
                 // No previous here, date is always from this tokens date
                 $date = $token->getDateTime($fieldName);
             }
             break;
         case parent::ANSWER_TABLE:
             if ($prev = $token->getPreviousSuccessToken()) {
                 $date = $prev->getAnswerDateTime($fieldName);
             }
             break;
         case parent::APPOINTMENT_TABLE:
         case parent::RESPONDENT_TRACK_TABLE:
             $date = $respTrack->getDate($fieldName);
             break;
     }
     return $date;
 }
 /**
  * Remove the unanswered tokens for inactive rounds.
  *
  * @param \Gems_Tracker_RespondentTrack $respTrack The respondent track to check
  * @param int $userId Id of the user who takes the action (for logging)
  * @return int The number of tokens changed by this code
  */
 protected function removeInactiveRounds(\Gems_Tracker_RespondentTrack $respTrack, $userId)
 {
     $qTrackId = $this->db->quote($this->_trackId);
     $qRespTrackId = $this->db->quote($respTrack->getRespondentTrackId());
     $orgId = $this->db->quote($respTrack->getOrganizationId());
     $where = "gto_start_time IS NULL AND\n            gto_id_respondent_track = {$qRespTrackId} AND\n            gto_id_round != 0 AND\n            gto_id_round IN (SELECT gro_id_round\n                    FROM gems__rounds\n                    WHERE (gro_active = 0 OR gro_organizations NOT LIKE CONCAT('%|',{$orgId},'|%')) AND\n                        gro_id_track = {$qTrackId})";
     return $this->db->delete('gems__tokens', $where);
 }
 public function testGetFields()
 {
     $trackData = array('gr2t_id_respondent_track' => 1, 'gr2t_id_track' => 1);
     $respondentTrack = new \Gems_Tracker_RespondentTrack($trackData);
     $respondentTrack->answerRegistryRequest('tracker', $this->tracker);
     $date = new MUtil_Date('2010-10-08', 'yyyy-MM-dd');
     $expected = array('f__1' => 'test', 'code' => 'test', 'f__2' => $date, 'datecode' => $date);
     $actual = $respondentTrack->getFieldData();
     $this->assertArrayWithDateMatch($expected, $actual, '', 1, 0);
 }
 /**
  * Check the valid from and until dates in the track
  *
  * @param \Gems_Tracker_RespondentTrack $respTrack The respondent track to check
  * @param int $userId Id of the user who takes the action (for logging)
  * @return int The number of tokens changed by this code
  */
 public function checkTokensFromStart(\Gems_Tracker_RespondentTrack $respTrack, $userId)
 {
     $token = $respTrack->getFirstToken();
     if ($token instanceof \Gems_Tracker_Token) {
         return $this->checkTokensFrom($respTrack, $respTrack->getFirstToken(), $userId);
     } else {
         return 0;
     }
 }
 /**
  * Returns the date to use to calculate the ValidUntil if any
  *
  * @param string $fieldSource Source for field from round
  * @param string $fieldName Name from round
  * @param int $prevRoundId Id from round
  * @param \Gems_Tracker_Token $token
  * @param \Gems_Tracker_RespondentTrack $respTrack
  * @param \MUtil_Date $validFrom The calculated new valid from value
  * @return \MUtil_Date date time or null
  */
 protected function getValidUntilDate($fieldSource, $fieldName, $prevRoundId, \Gems_Tracker_Token $token, \Gems_Tracker_RespondentTrack $respTrack, $validFrom)
 {
     $date = null;
     switch ($fieldSource) {
         case parent::ANSWER_TABLE:
             if ($prev = $respTrack->getActiveRoundToken($prevRoundId, $token)) {
                 $date = $prev->getAnswerDateTime($fieldName);
             }
             break;
         case parent::TOKEN_TABLE:
             if ($prev = $respTrack->getActiveRoundToken($prevRoundId, $token)) {
                 if (false !== $validFrom && $prev === $token && $fieldName == 'gto_valid_from') {
                     $date = $validFrom;
                 } else {
                     $date = $prev->getDateTime($fieldName);
                 }
             }
             break;
         case parent::APPOINTMENT_TABLE:
         case parent::RESPONDENT_TRACK_TABLE:
             $date = $respTrack->getDate($fieldName);
             break;
     }
     return $date;
 }
 /**
  * Exports all the tokens of a single track, grouped by round
  *
  * @param \Gems_Tracker_RespondentTrack $track
  */
 protected function _exportTrackTokens(\Gems_Tracker_RespondentTrack $track)
 {
     $groupSurveys = $this->_group;
     $token = $track->getFirstToken();
     $engine = $track->getTrackEngine();
     $surveys = array();
     $table = $this->html->table(array('class' => 'browser table'));
     $table->th($this->_('Survey'))->th($this->_('Round'))->th($this->_('Token'))->th($this->_('Status'));
     $this->html->br();
     while ($token) {
         //Should this token be in the list?
         if (!$this->_isTokenInFilter($token)) {
             $token = $token->getNextToken();
             continue;
         }
         $table->tr()->td($token->getSurveyName())->td($engine->getTrackType() == 'T' ? $token->getRoundDescription() : $this->_('Single Survey'))->td(strtoupper($token->getTokenId()))->td($token->getStatus());
         //Should we display the answers?
         if (!$this->_displayToken($token)) {
             $token = $token->getNextToken();
             continue;
         }
         $showToken = false;
         if ($engine->getTrackType() == 'S' || !$groupSurveys) {
             // For single survey tracks or when $groupSurvey === false we show all tokens
             $showToken = true;
         } else {
             // For multi survey tracks and $groupSurveys === true, we show only the first token
             // as the snippet takes care of showing the other tokens
             if (!isset($surveys[$token->getSurveyId()])) {
                 $showToken = true;
                 $surveys[$token->getSurveyId()] = 1;
             }
         }
         if ($showToken) {
             $params = array('token' => $token, 'tokenId' => $token->getTokenId(), 'showHeaders' => false, 'showButtons' => false, 'showSelected' => false, 'showTakeButton' => false, 'grouped' => $groupSurveys);
             $snippets = $token->getAnswerSnippetNames();
             if (!is_array($snippets)) {
                 $snippets = array($snippets);
             }
             list($snippets, $snippetParams) = \MUtil_Ra::keySplit($snippets);
             $params = $params + $snippetParams;
             $this->html->snippet('Export_SurveyHeaderSnippet', 'token', $token);
             foreach ($snippets as $snippet) {
                 $this->html->snippet($snippet, $params);
             }
             $this->html->br();
         }
         $token = $token->getNextToken();
     }
 }
 /**
  * When only providing one or two fields, the others should not get nulled
  */
 public function testSetFieldsPartial()
 {
     $trackData = array('gr2t_id_respondent_track' => 1, 'gr2t_id_track' => 1);
     $respondentTrack = new Gems_Tracker_RespondentTrack($trackData);
     $respondentTrack->answerRegistryRequest('tracker', $this->tracker);
     $expected = $respondentTrack->getFieldData();
     $expected['f__1'] = $expected['code'] = 'newvalue';
     $actual = $respondentTrack->setFieldData(array('code' => 'newvalue'));
     $this->assertArrayWithDateMatch($expected, $actual, '', 1, 0);
 }