public function calculateEndDate()
    {
        // Exclude the tokens whose end date is calculated from the track end date
        $excludeWheres[] = sprintf(
                "gro_valid_for_source = '%s' AND gro_valid_for_field = 'gr2t_end_date'",
                \Gems_Tracker_Engine_StepEngineAbstract::RESPONDENT_TRACK_TABLE
                );

        // Exclude the tokens whose start date is calculated from the track end date, while the
        // end date is calculated using that same start date
        $excludeWheres[] = sprintf(
                "gro_valid_after_source = '%s' AND gro_valid_after_field = 'gr2t_end_date' AND
                    gro_id_round = gro_valid_for_id AND
                    gro_valid_for_source = '%s' AND gro_valid_for_field = 'gto_valid_from'",
                \Gems_Tracker_Engine_StepEngineAbstract::RESPONDENT_TRACK_TABLE,
                \Gems_Tracker_Engine_StepEngineAbstract::TOKEN_TABLE
                );
        // In future we may want to add some nesting to this, e.g. tokens with an end date calculated
        // from another token whose... for the time being users should use the end date directly in
        // each token, otherwise the end date will not be calculated

        $maxExpression = "
            CASE
            WHEN SUM(
                CASE WHEN COALESCE(gto_completion_time, gto_valid_until) IS NULL THEN 1 ELSE 0 END
                ) > 0
            THEN NULL
            ELSE MAX(COALESCE(gto_completion_time, gto_valid_until))
            END as enddate";

        $tokenSelect = $this->tracker->getTokenSelect(array(new \Zend_Db_Expr($maxExpression)));
        $tokenSelect->andReceptionCodes(array())
                ->andRounds(array())
                ->forRespondentTrack($this->_respTrackId)
                ->onlySucces();

        foreach ($excludeWheres as $where) {
            $tokenSelect->forWhere('NOT (' . $where . ')');
        }

        $endDate = $tokenSelect->fetchOne();

        // \MUtil_Echo::track($endDate, $tokenSelect->getSelect()->__toString());

        if (false === $endDate) {
            return null;;
        } else {
            return $endDate;
        }
    }
public function calculateEndDate()
    {
        // Exclude the tokens whose end date is calculated from the track end date
        $excludeWheres[] = sprintf(
                "gro_valid_for_source = '%s' AND gro_valid_for_field = 'gr2t_end_date'",
                \Gems_Tracker_Engine_StepEngineAbstract::RESPONDENT_TRACK_TABLE
                );

        // Exclude the tokens whose start date is calculated from the track end date, while the
        // end date is calculated using that same start date
        $excludeWheres[] = sprintf(
                "gro_valid_after_source = '%s' AND gro_valid_after_field = 'gr2t_end_date' AND
                    gro_id_round = gro_valid_for_id AND
                    gro_valid_for_source = '%s' AND gro_valid_for_field = 'gto_valid_from'",
                \Gems_Tracker_Engine_StepEngineAbstract::RESPONDENT_TRACK_TABLE,
                \Gems_Tracker_Engine_StepEngineAbstract::TOKEN_TABLE
                );
        // In future we may want to add some nesting to this, e.g. tokens with an end date calculated
        // from another token whose... for the time being users should use the end date directly in
        // each token, otherwise the end date will not be calculated

        $maxExpression = "
            CASE
            WHEN SUM(
                CASE WHEN COALESCE(gto_completion_time, gto_valid_until) IS NULL THEN 1 ELSE 0 END
                ) > 0
            THEN NULL
            ELSE MAX(COALESCE(gto_completion_time, gto_valid_until))
            END as enddate";

        $tokenSelect = $this->tracker->getTokenSelect(array(new \Zend_Db_Expr($maxExpression)));
        $tokenSelect->andReceptionCodes(array())
                ->andRounds(array())
                ->forRespondentTrack($this->_respTrackId)
                ->onlySucces();

        foreach ($excludeWheres as $where) {
            $tokenSelect->forWhere('NOT (' . $where . ')');
        }

        $endDate = $tokenSelect->fetchOne();

        // \MUtil_Echo::track($endDate, $tokenSelect->getSelect()->__toString());

        if (false === $endDate) {
            return null;;
        } else {
            return $endDate;
        }
    }
public function calculateEndDate ( ) { // Exclude the tokens whose end date is calculated from the track end date $ excludeWheres [ ] = sprintf ( "gro_valid_for_source = '%s' AND gro_valid_for_field = 'gr2t_end_date'" , \ Gems_Tracker_Engine_StepEngineAbstract :: RESPONDENT_TRACK_TABLE ) ; // Exclude the tokens whose start date is calculated from the track end date, while the // end date is calculated using that same start date $ excludeWheres [ ] = sprintf ( "gro_valid_after_source = '%s' AND gro_valid_after_field = 'gr2t_end_date' AND
                    gro_id_round = gro_valid_for_id AND
                    gro_valid_for_source = '%s' AND gro_valid_for_field = 'gto_valid_from'" , \ Gems_Tracker_Engine_StepEngineAbstract :: RESPONDENT_TRACK_TABLE , \ Gems_Tracker_Engine_StepEngineAbstract :: TOKEN_TABLE ) ; // In future we may want to add some nesting to this, e.g. tokens with an end date calculated // from another token whose... for the time being users should use the end date directly in // each token, otherwise the end date will not be calculated $ maxExpression = "
            CASE
            WHEN SUM(
                CASE WHEN COALESCE(gto_completion_time, gto_valid_until) IS NULL THEN 1 ELSE 0 END
                ) > 0
            THEN NULL
            ELSE MAX(COALESCE(gto_completion_time, gto_valid_until))
            END as enddate" ; $ tokenSelect = $ this -> tracker -> getTokenSelect ( array ( new \ Zend_Db_Expr ( $ maxExpression ) ) ) ; $ tokenSelect -> andReceptionCodes ( array ( ) ) -> andRounds ( array ( ) ) -> forRespondentTrack ( $ this -> _respTrackId ) -> onlySucces ( ) ; foreach ( $ excludeWheres as $ where ) { $ tokenSelect -> forWhere ( 'NOT (' . $ where . ')' ) ; } $ endDate = $ tokenSelect -> fetchOne ( ) ; // \MUtil_Echo::track($endDate, $tokenSelect->getSelect()->__toString()); if ( false === $ endDate ) { return null ; ; } else { return $ endDate ; } }
Calculates the track end date

The end date can be calculated when:
- all active tokens have a completion date
- or all active tokens have a valid until date
- or the end date of the tokens is calculated using the end date

You can overrule this calculation at the project level.

@return string or null
Calculates the track end date