Skip to content
Snippets Groups Projects
class.ticket.php 147 KiB
Newer Older
Jared Hancock's avatar
Jared Hancock committed
<?php
/*********************************************************************
    class.ticket.php

    The most important class! Don't play with fire please.

    Peter Rotich <peter@osticket.com>
    Copyright (c)  2006-2013 osTicket
Jared Hancock's avatar
Jared Hancock committed
    http://www.osticket.com

    Released under the GNU General Public License WITHOUT ANY WARRANTY.
    See LICENSE.TXT for details.

    vim: expandtab sw=4 ts=4 sts=4:
**********************************************************************/
include_once(INCLUDE_DIR.'class.thread.php');
Jared Hancock's avatar
Jared Hancock committed
include_once(INCLUDE_DIR.'class.staff.php');
include_once(INCLUDE_DIR.'class.client.php');
Jared Hancock's avatar
Jared Hancock committed
include_once(INCLUDE_DIR.'class.team.php');
include_once(INCLUDE_DIR.'class.email.php');
include_once(INCLUDE_DIR.'class.dept.php');
include_once(INCLUDE_DIR.'class.topic.php');
include_once(INCLUDE_DIR.'class.lock.php');
include_once(INCLUDE_DIR.'class.file.php');
Peter Rotich's avatar
Peter Rotich committed
include_once(INCLUDE_DIR.'class.export.php');
Jared Hancock's avatar
Jared Hancock committed
include_once(INCLUDE_DIR.'class.attachment.php');
include_once(INCLUDE_DIR.'class.banlist.php');
include_once(INCLUDE_DIR.'class.template.php');
include_once(INCLUDE_DIR.'class.variable.php');
Jared Hancock's avatar
Jared Hancock committed
include_once(INCLUDE_DIR.'class.priority.php');
Peter Rotich's avatar
Peter Rotich committed
include_once(INCLUDE_DIR.'class.sla.php');
include_once(INCLUDE_DIR.'class.canned.php');
Jared Hancock's avatar
Jared Hancock committed
require_once(INCLUDE_DIR.'class.dynamic_forms.php');
require_once(INCLUDE_DIR.'class.user.php');
require_once(INCLUDE_DIR.'class.collaborator.php');
Peter Rotich's avatar
Peter Rotich committed
require_once(INCLUDE_DIR.'class.task.php');
require_once(INCLUDE_DIR.'class.faq.php');
class Ticket extends VerySimpleModel
implements RestrictedAccess, Threadable, Searchable {
    static $meta = array(
        'table' => TICKET_TABLE,
        'pk' => array('ticket_id'),
        'select_related' => array('topic', 'staff', 'user', 'team', 'dept',
            'sla', 'thread', 'user__default_email', 'status'),
        'joins' => array(
            'user' => array(
                'constraint' => array('user_id' => 'User.id')
            ),
            'status' => array(
                'constraint' => array('status_id' => 'TicketStatus.id')
            ),
            'lock' => array(
                'constraint' => array('lock_id' => 'Lock.lock_id'),
                'null' => true,
            ),
            'dept' => array(
                'constraint' => array('dept_id' => 'Dept.id'),
            'sla' => array(
                'constraint' => array('sla_id' => 'Sla.id'),
                'null' => true,
            ),
Jared Hancock's avatar
Jared Hancock committed
                'constraint' => array('staff_id' => 'Staff.staff_id'),
            'tasks' => array(
                'reverse' => 'Task.ticket',
            ),
            'team' => array(
                'constraint' => array('team_id' => 'Team.team_id'),
                'null' => true,
            ),
            'topic' => array(
                'constraint' => array('topic_id' => 'Topic.topic_id'),
                'null' => true,
            ),
                'reverse' => 'TicketThread.ticket',
                'list' => false,
                'null' => true,
            ),
            'cdata' => array(
                'reverse' => 'TicketCData.ticket',
                'list' => false,
            ),
            'entries' => array(
                'constraint' => array(
                    "'T'" => 'DynamicFormEntry.object_type',
                    'ticket_id' => 'DynamicFormEntry.object_id',
                ),
Peter Rotich's avatar
Peter Rotich committed
                'list' => true,
    const PERM_CREATE   = 'ticket.create';
    const PERM_EDIT     = 'ticket.edit';
    const PERM_ASSIGN   = 'ticket.assign';
    const PERM_RELEASE  = 'ticket.release';
    const PERM_TRANSFER = 'ticket.transfer';
    const PERM_REFER    = 'ticket.refer';
    const PERM_REPLY    = 'ticket.reply';
    const PERM_CLOSE    = 'ticket.close';
    const PERM_DELETE   = 'ticket.delete';

    static protected $perms = array(
            self::PERM_CREATE => array(
Peter Rotich's avatar
Peter Rotich committed
                'title' =>
                /* @trans */ 'Create',
Peter Rotich's avatar
Peter Rotich committed
                'desc'  =>
                /* @trans */ 'Ability to open tickets on behalf of users'),
            self::PERM_EDIT => array(
Peter Rotich's avatar
Peter Rotich committed
                'title' =>
                /* @trans */ 'Edit',
Peter Rotich's avatar
Peter Rotich committed
                'desc'  =>
                /* @trans */ 'Ability to edit tickets'),
            self::PERM_ASSIGN => array(
Peter Rotich's avatar
Peter Rotich committed
                'title' =>
                /* @trans */ 'Assign',
Peter Rotich's avatar
Peter Rotich committed
                'desc'  =>
                /* @trans */ 'Ability to assign tickets to agents or teams'),
            self::PERM_RELEASE => array(
                'title' =>
                /* @trans */ 'Release',
                'desc'  =>
                /* @trans */ 'Ability to release ticket assignment'),
            self::PERM_TRANSFER => array(
Peter Rotich's avatar
Peter Rotich committed
                'title' =>
                /* @trans */ 'Transfer',
Peter Rotich's avatar
Peter Rotich committed
                'desc'  =>
                /* @trans */ 'Ability to transfer tickets between departments'),
            self::PERM_REFER => array(
                'title' =>
                /* @trans */ 'Refer',
                'desc'  =>
                /* @trans */ 'Ability to manage ticket referrals'),
            self::PERM_REPLY => array(
Peter Rotich's avatar
Peter Rotich committed
                'title' =>
                /* @trans */ 'Post Reply',
Peter Rotich's avatar
Peter Rotich committed
                'desc'  =>
                /* @trans */ 'Ability to post a ticket reply'),
            self::PERM_CLOSE => array(
Peter Rotich's avatar
Peter Rotich committed
                'title' =>
                /* @trans */ 'Close',
Peter Rotich's avatar
Peter Rotich committed
                'desc'  =>
                /* @trans */ 'Ability to close tickets'),
            self::PERM_DELETE => array(
Peter Rotich's avatar
Peter Rotich committed
                'title' =>
                /* @trans */ 'Delete',
Peter Rotich's avatar
Peter Rotich committed
                'desc'  =>
                /* @trans */ 'Ability to delete tickets'),
            );
Peter Rotich's avatar
Peter Rotich committed
    // Ticket Sources
    static protected $sources =  array(
            'Phone' =>
            /* @trans */ 'Phone',
            'Email' =>
            /* @trans */ 'Email',
Peter Rotich's avatar
Peter Rotich committed

            'Web' =>
            /* @trans */ 'Web',
            'API' =>
            /* @trans */ 'API',
Peter Rotich's avatar
Peter Rotich committed
            'Other' =>
            /* @trans */ 'Other',
            );
Jared Hancock's avatar
Jared Hancock committed

    var $lastMsgId;
    var $last_message;
    var $owner;     // TicketOwner
    var $_user;      // EndUser
    var $_answers;
    var $collaborators;
    var $active_collaborators;
    var $recipients;
    var $lastrespondent;
    function loadDynamicData($force=false) {
        if (!isset($this->_answers) || $force) {
            $this->_answers = array();
            foreach (DynamicFormEntryAnswer::objects()
                ->filter(array(
                    'entry__object_id' => $this->getId(),
                    'entry__object_type' => 'T'
                )) as $answer
            ) {
                $tag = mb_strtolower($answer->field->name)
                    ?: 'field.' . $answer->field->id;
                    $this->_answers[$tag] = $answer;
        return $this->_answers;
    function getAnswer($field, $form=null) {
        // TODO: Prefer CDATA ORM relationship if already loaded
        $this->loadDynamicData();
        return $this->_answers[$field];
    }

    function getId() {
        return $this->ticket_id;
    }

    function hasState($state) {
        return  strcasecmp($this->getState(), $state) == 0;
Jared Hancock's avatar
Jared Hancock committed
    function isOpen() {
        return $this->hasState('open');
Jared Hancock's avatar
Jared Hancock committed
    }

    function isReopened() {
        return null !== $this->getReopenDate();
    function isReopenable() {
        return ($this->getStatus()->isReopenable() && $this->getDept()->allowsReopen()
JediKev's avatar
JediKev committed
        && ($this->getTopic() ? $this->getTopic()->allowsReopen() : true));
Jared Hancock's avatar
Jared Hancock committed
    function isClosed() {
         return $this->hasState('closed');
    }

    function isCloseable() {
        global $cfg;

        if ($this->isClosed())
            return true;

        $warning = null;
        if (self::getMissingRequiredFields($this)) {
            $warning = sprintf(
                    __( '%1$s is missing data on %2$s one or more required fields %3$s and cannot be closed'),
                    __('This ticket'),
                    '', '');
        } elseif (($num=$this->getNumOpenTasks())) {
            $warning = sprintf(__('%1$s has %2$d open tasks and cannot be closed'),
                    __('This ticket'), $num);
        } elseif ($cfg->requireTopicToClose() && !$this->getTopicId()) {
            $warning = sprintf(
                    __( '%1$s is missing a %2$s and cannot be closed'),
                    __('This ticket'), __('Help Topic'), '');
    function isArchived() {
         return $this->hasState('archived');
    }

    function isDeleted() {
         return $this->hasState('deleted');
    function isAssigned($to=null) {
        if (!$this->isOpen())
            return false;

            return ($this->getStaffId() || $this->getTeamId());

        switch (true) {
        case $to instanceof Staff:
            return ($to->getId() == $this->getStaffId() ||
                    $to->isTeamMember($this->getTeamId()));
            break;
        case $to instanceof Team:
            return ($to->getId() == $this->getTeamId());
            break;
        }

        return false;
Jared Hancock's avatar
Jared Hancock committed
    }

    function isOverdue() {
        return $this->ht['isoverdue'];
Jared Hancock's avatar
Jared Hancock committed
    function isAnswered() {
       return $this->ht['isanswered'];
Jared Hancock's avatar
Jared Hancock committed
    }

    function isLocked() {
        return null !== $this->getLock();
    function getRole($staff) {
        if (!$staff instanceof Staff)
            return null;

        return $staff->getRole($this->getDept(), $this->isAssigned($staff));
    }

    function checkStaffPerm($staff, $perm=null) {
        // Must be a valid staff
        if ((!$staff instanceof Staff) && !($staff=Staff::lookup($staff)))
Jared Hancock's avatar
Jared Hancock committed
            return false;

        // check department access first
        if (!$staff->canAccessDept($this->getDept())
                // check assignment
                && !$this->isAssigned($staff)
                // check referral
                && !$this->thread->isReferred($staff))
Jared Hancock's avatar
Jared Hancock committed
            return false;

        // At this point staff has view access unless a specific permission is
        // requested
        if ($perm === null)
        // Permission check requested -- get role if any
        if (!($role=$this->getRole($staff)))
        // Check permission based on the effective role
        return $role->hasPerm($perm);
    function checkUserAccess($user) {
        if (!$user || !($user instanceof EndUser))
        // Ticket Owner
        if ($user->getId() == $this->getUserId())
        // Organization
        if ($user->canSeeOrgTickets()
            && ($U = $this->getUser())
            && ($U->getOrgId() == $user->getOrgId())
        ) {
            // The owner of this ticket is in the same organization as the
            // user in question, and the organization is configured to allow
            // the user in question to see other tickets in the
            // organization.
            return true;
        }

        // Collaborator?
        // 1) If the user was authorized via this ticket.
        if ($user->getTicketId() == $this->getId()
            && !strcasecmp($user->getUserType(), 'collaborator')
        ) {
            return true;
        // 2) Query the database to check for expanded access...
        if (Collaborator::lookup(array(
            'user_id' => $user->getId(),
            'thread_id' => $this->getThreadId()))
        ) {
            return true;
    // Getters
    function getOwnerId() {
        return $this->user_id;
        if (!isset($this->owner)) {
            $this->owner = new TicketOwner(new EndUser($this->user), $this);
        }
        return $this->owner;
    function getEmail() {
        if ($o = $this->getOwner()) {
            return $o->getEmail();
        return null;
    }

    function getReplyToEmail() {
        //TODO: Determine the email to use (once we enable multi-email support)
        return $this->getEmail();
    // Deprecated
    function getOldAuthToken() {
        # XXX: Support variable email address (for CCs)
        return md5($this->getId() . strtolower($this->getEmail()) . SECRET_SALT);
Jared Hancock's avatar
Jared Hancock committed
    function getName(){
        if ($o = $this->getOwner()) {
            return $o->getName();
Jared Hancock's avatar
Jared Hancock committed
    }

    function getSubject() {
        return (string) $this->getAnswer('subject');
Jared Hancock's avatar
Jared Hancock committed
    }

    /* Help topic title  - NOT object -> $topic */
    function getHelpTopic() {
        if ($this->topic)
            return $this->topic->getFullName();
        return $this->created;
Jared Hancock's avatar
Jared Hancock committed
    }

    function getOpenDate() {
        return $this->getCreateDate();
    }

    function getReopenDate() {
        return $this->reopened;
        return $this->updated;
    function getEffectiveDate() {
        return $this->lastupdate;
        return $this->duedate;
    function getSLADueDate($datetime=null) {
        if ($sla = $this->getSLA()) {
            $dt = new DateTime($datetime ?: $this->getReopenDate() ?: $this->getCreateDate());
            return $dt
                ->add(new DateInterval('PT' . $sla->getGracePeriod() . 'H'))
                ->format('Y-m-d H:i:s');
        }
    function updateEstDueDate($clearOverdue=true) {
        $DueDate = $this->getEstDueDate();
        $this->est_duedate = $this->getSLADueDate();
        // Clear overdue flag if duedate or SLA changes and the ticket is no longer overdue.
        if ($this->isOverdue()
            && $clearOverdue
            && (!$DueDate // Duedate + SLA cleared
                || Misc::db2gmtime($DueDate) > Misc::gmtime() //New due date in the future.
        )) {
             $this->isoverdue = 0;
        }

        return $this->save();
    }

    function getEstDueDate() {
        // Real due date or  sla due date (If ANY)
        return $this->getDueDate() ?: $this->getSLADueDate();
        return $this->closed;
    function getStatusId() {
        return $this->status_id;
    /**
     * setStatusId
     *
     * Forceably set the ticket status ID to the received status ID. No
     * checks are made. Use ::setStatus() to change the ticket status
     */
    // XXX: Use ::setStatus to change the status. This can be used as a
    //      fallback if the logic in ::setStatus fails.
    function setStatusId($id) {
        $this->status_id = $id;
        return $this->save();
        return $this->status;
    }

    function getState() {
        if (!$this->getStatus()) {
            return '';
        return $this->getStatus()->getState();
       return $this->dept_id;
        if ($this->dept instanceof Dept)
            return $this->dept->getFullName();
Jared Hancock's avatar
Jared Hancock committed
    }

    function getPriorityId() {
Peter Rotich's avatar
Peter Rotich committed
        if (($priority = $this->getPriority()))
            return $priority->getId();

        return $cfg->getDefaultPriorityId();
    function getPriority() {
Peter Rotich's avatar
Peter Rotich committed

        if (($a = $this->getAnswer('priority')))
            return $a->getValue();

        return null;
Jared Hancock's avatar
Jared Hancock committed
    function getPhoneNumber() {
        return (string)$this->getOwner()->getPhoneNumber();
Jared Hancock's avatar
Jared Hancock committed
    }

    function getSource() {
aydreeihn's avatar
aydreeihn committed
        $sources = $this->getSources();
        return $sources[$this->source] ?: $this->source;
Jared Hancock's avatar
Jared Hancock committed
    function getIP() {
        return $this->ip_address;
Peter Rotich's avatar
Peter Rotich committed
    function getHashtable() {
        return $this->ht;
    }

    function getUpdateInfo() {
Peter Rotich's avatar
Peter Rotich committed
        global $cfg;

        return array(
aydreeihn's avatar
aydreeihn committed
            'source'    => $this->source,
            'topicId'   => $this->getTopicId(),
            'slaId'     => $this->getSLAId(),
            'user_id'   => $this->getOwnerId(),
            'duedate'   => Misc::db2gmtime($this->getDueDate()),
        $lock = $this->lock;
        if ($lock && !$lock->isExpired())
            return $lock;
    function acquireLock($staffId, $lockTime=null) {
        global $cfg;

        if (!isset($lockTime))
            $lockTime = $cfg->getLockTime();
        if (!$staffId or !$lockTime) //Lockig disabled?
Jared Hancock's avatar
Jared Hancock committed
            return null;

        // Check if the ticket is already locked.
        if (($lock = $this->getLock()) && !$lock->isExpired()) {
            if ($lock->getStaffId() != $staffId) //someone else locked the ticket.
Jared Hancock's avatar
Jared Hancock committed
                return null;

            //Lock already exits...renew it
            $lock->renew($lockTime); //New clock baby.
Jared Hancock's avatar
Jared Hancock committed
            return $lock;
        }
        // No lock on the ticket or it is expired
        $this->lock = Lock::acquire($staffId, $lockTime); //Create a new lock..
        if ($this->lock) {
            $this->save();
        // load and return the newly created lock if any!
        return $this->lock;
    function releaseLock($staffId=false) {
        if (!($lock = $this->getLock()))
            return false;

        if ($staffId && $lock->staff_id != $staffId)
            return false;

        if (!$lock->delete())
            return false;
        $this->lock = null;
        return $this->save();
        return $this->dept ?: $cfg->getDefaultDept();
    function getUserId() {
        return $this->getOwnerId();
    }
    function getUser() {
        if (!isset($this->_user) && $this->user) {
            $this->_user = new EndUser($this->user);
        }
        return $this->_user;
        return $this->staff_id;
Jared Hancock's avatar
Jared Hancock committed
        return $this->staff;
    }

        return $this->team_id;
Jared Hancock's avatar
Jared Hancock committed
        return $this->team;
    }

Peter Rotich's avatar
Peter Rotich committed
    function getAssigneeId() {
Peter Rotich's avatar
Peter Rotich committed
        if (!($assignee=$this->getAssignee()))
            return null;

        $id = '';
        if ($assignee instanceof Staff)
            $id = 's'.$assignee->getId();
        elseif ($assignee instanceof Team)
            $id = 't'.$assignee->getId();

        return $id;
Jared Hancock's avatar
Jared Hancock committed
    }

    function getAssignee() {

Peter Rotich's avatar
Peter Rotich committed
        if (!$this->isOpen() || !$this->isAssigned())
            return false;
Peter Rotich's avatar
Peter Rotich committed
        if ($this->staff)
            return $this->staff;
Peter Rotich's avatar
Peter Rotich committed
        if ($this->team)
            return $this->team;
Peter Rotich's avatar
Peter Rotich committed
        return null;
Peter Rotich's avatar
Peter Rotich committed
    function getAssignees() {
        $assignees = array();
        if ($staff = $this->getStaff())
            $assignees[] = $staff->getName();
        if ($team = $this->getTeam())
            $assignees[] = $team->getName();
Peter Rotich's avatar
Peter Rotich committed

        return $assignees;
    }
    function getAssigned($glue='/') {
        $assignees = $this->getAssignees();
        return $assignees ? implode($glue, $assignees) : '';
    function getTopicId() {
        return $this->topic_id;
Jared Hancock's avatar
Jared Hancock committed
        return $this->topic;
    }

Jared Hancock's avatar
Jared Hancock committed
    function getSLAId() {
        return $this->sla_id;
Jared Hancock's avatar
Jared Hancock committed
    }

    function getSLA() {
        return $this->sla;
    }

    function getLastRespondent() {
Peter Rotich's avatar
Peter Rotich committed
        if (!isset($this->lastrespondent)) {
            if (!$this->thread || !$this->thread->entries)
                return $this->lastrespondent = false;
            $this->lastrespondent = Staff::objects()
                ->filter(array(
                'staff_id' => $this->thread->entries
                    ->filter(array(
                        'type' => 'R',
                        'staff_id__gt' => 0,
                    ->values_flat('staff_id')
                    ->order_by('-id')
                    ->limit(1)
                ->first()
                ?: false;
Peter Rotich's avatar
Peter Rotich committed
        }
        return $this->lastrespondent;
    function getLastUserRespondent() {
        if (!isset($this->$lastuserrespondent)) {
            if (!$this->thread || !$this->thread->entries)
                return $this->$lastuserrespondent = false;
            $this->$lastuserrespondent = User::objects()
                ->filter(array(
                'id' => $this->thread->entries
                    ->filter(array(
                        'user_id__gt' => 0,
                    ))
                    ->values_flat('user_id')
                    ->order_by('-id')
                    ->limit(1)
                ))
                ->first()
                ?: false;
        }
        return $this->$lastuserrespondent;
    }

Jared Hancock's avatar
Jared Hancock committed
    function getLastMessageDate() {
        return $this->thread->lastmessage;
Jared Hancock's avatar
Jared Hancock committed
    }

    function getLastMsgDate() {
        return $this->getLastMessageDate();
    }

    function getLastResponseDate() {
        return $this->thread->lastresponse;
Jared Hancock's avatar
Jared Hancock committed
    }

    function getLastRespDate() {
        return $this->getLastResponseDate();
    }

    function getLastMsgId() {
        return $this->lastMsgId;
    }

    function getLastMessage() {
        if (!isset($this->last_message)) {
            if ($this->getLastMsgId())
                $this->last_message = MessageThreadEntry::lookup(
                    $this->getLastMsgId(), $this->getThreadId());
            if (!$this->last_message)
                $this->last_message = $this->getThread()->getLastMessage();
        }
        return $this->last_message;
Peter Rotich's avatar
Peter Rotich committed
    function getNumTasks() {
        // FIXME: Implement this after merging Tasks
        return count($this->tasks);
Peter Rotich's avatar
Peter Rotich committed
    }

    function getNumOpenTasks() {
        return count($this->tasks->filter(array(
                        'flags__hasbit' => TaskModel::ISOPEN)));
    }
Peter Rotich's avatar
Peter Rotich committed
    function getThreadId() {
        if ($this->thread)
            return $this->thread->id;
    function getThread() {
        return $this->thread;
Jared Hancock's avatar
Jared Hancock committed
    }

    function getThreadCount() {
        return $this->getClientThread()->count();
Jared Hancock's avatar
Jared Hancock committed
    }

    function getNumMessages() {
        return $this->getThread()->getNumMessages();
Jared Hancock's avatar
Jared Hancock committed
    }

    function getNumResponses() {
        return $this->getThread()->getNumResponses();
Jared Hancock's avatar
Jared Hancock committed
    }

    function getNumNotes() {
        return $this->getThread()->getNumNotes();
    function getMessages() {
        return $this->getThreadEntries(array('M'));
    function getResponses() {
        return $this->getThreadEntries(array('R'));
    function getNotes() {
        return $this->getThreadEntries(array('N'));
    function getClientThread() {
        return $this->getThreadEntries(array('M', 'R'));
    function getThreadEntry($id) {
        return $this->getThread()->getEntry($id);
    function getThreadEntries($type=false) {
Peter Rotich's avatar
Peter Rotich committed
        $entries = $this->getThread()->getEntries();
Peter Rotich's avatar
Peter Rotich committed
            $entries->filter(array('type__in' => $type));

        return $entries;
    // MailingList of participants  (owner + collaborators)
    function getRecipients($who='all', $whitelist=array(), $active=true) {
        $list = new MailingList();
        switch (strtolower($who)) {
            case 'user':
                $list->addTo($this->getOwner());
                break;
            case 'all':
                $list->addTo($this->getOwner());
                // Fall-trough
            case 'collabs':
                if (($collabs = $active ?  $this->getActiveCollaborators() :
                    $this->getCollaborators())) {
                    foreach ($collabs as $c)
                        if (!$whitelist || in_array($c->getUserId(),
                                    $whitelist))
                            $list->addCc($c);
                }
                break;
            default:
                return null;
        return $list;
Peter Rotich's avatar
Peter Rotich committed
    function getCollaborators() {
        return $this->getThread()->getCollaborators();
    }

    function getNumCollaborators() {
        return $this->getThread()->getNumCollaborators();
    }

    function getActiveCollaborators() {
        return $this->getThread()->getActiveCollaborators();
    }

    function getNumActiveCollaborators() {
        return $this->getThread()->getNumActiveCollaborators();
    }

Peter Rotich's avatar
Peter Rotich committed
    function getAssignmentForm($source=null, $options=array()) {
        $prompt = $assignee = '';
        // Possible assignees
        $dept = $this->getDept();
        switch (strtolower($options['target'])) {
            case 'agents':
                foreach ($dept->getAssignees() as $member)
                    $assignees['s'.$member->getId()] = $member;
                if (!$source && $this->isOpen() && $this->staff)
                    $assignee = sprintf('s%d', $this->staff->getId());
                $prompt = __('Select an Agent');
                break;
            case 'teams':
                if (($teams = Team::getActiveTeams()))
                    foreach ($teams as $id => $name)
                        $assignees['t'.$id] = $name;

                if (!$source && $this->isOpen() && $this->team)
Peter Rotich's avatar
Peter Rotich committed
                    $assignee = sprintf('t%d', $this->team->getId());
                $prompt = __('Select a Team');
                break;
        }

        // Default to current assignee if source is not set
Peter Rotich's avatar
Peter Rotich committed
        if (!$source)
            $source = array('assignee' => array($assignee));

        $form = AssignmentForm::instantiate($source, $options);
            $form->setAssignees($assignees);

        if (($refer = $form->getField('refer'))) {
            if ($assignee) {
                $visibility = new VisibilityConstraint(
                        new Q(array()), VisibilityConstraint::HIDDEN);
                $refer->set('visibility', $visibility);
            } else {
                $refer->configure('desc', sprintf(__('Maintain referral access to %s'),
                        $this->getAssigned()));
            }
        }

        // Field configurations
        if ($f=$form->getField('assignee')) {
            if ($prompt)
                $f->configure('prompt', $prompt);
            $f->configure('dept', $dept);
        }
Peter Rotich's avatar
Peter Rotich committed
        return $form;
Peter Rotich's avatar
Peter Rotich committed
    function getReferralForm($source=null, $options=array()) {

        $form = ReferralForm::instantiate($source, $options);
        $dept = $this->getDept();
        // Agents
        $staff = Staff::objects()->filter(array(
         'isactive' => 1,
         ))
         ->filter(Q::not(array('dept_id' => $dept->getId())));
        $staff = Staff::nsort($staff);
        $agents = array();
        foreach ($staff as $s)
          $agents[$s->getId()] = $s;
        $form->setChoices('agent', $agents);
        // Teams
        $form->setChoices('team', Team::getActiveTeams());
        // Depts
        $form->setChoices('dept', Dept::getDepartments());
Peter Rotich's avatar
Peter Rotich committed

        return $form;
    }

Peter Rotich's avatar
Peter Rotich committed
    function getClaimForm($source=null, $options=array()) {
        global $thisstaff;
Peter Rotich's avatar
Peter Rotich committed
        $id = sprintf('s%d', $thisstaff->getId());
        if(!$source)
            $source = array('assignee' => array($id));
Peter Rotich's avatar
Peter Rotich committed
        $form = ClaimForm::instantiate($source, $options);
        $form->setAssignees(array($id => $thisstaff->getName()));
Peter Rotich's avatar
Peter Rotich committed
    function getTransferForm($source=null) {
Peter Rotich's avatar
Peter Rotich committed
        if (!$source)
            $source = array('dept' => array($this->getDeptId()),
                    'refer' => false);
Peter Rotich's avatar
Peter Rotich committed

        return TransferForm::instantiate($source);
    }

Peter Rotich's avatar
Peter Rotich committed
    function getField($fid) {

        if (is_numeric($fid))
            return $this->getDymanicFieldById($fid);

        // Special fields
        switch ($fid) {
        case 'priority':
            if (($a = $this->getAnswer('priority')))
Peter Rotich's avatar
Peter Rotich committed
                return $a->getField();

            return TicketForm::getInstance()->getField('priority');
Peter Rotich's avatar
Peter Rotich committed
            break;
        case 'sla':
            return ChoiceField::init(array(
                        'id' => $fid,
                        'name' => "{$fid}_id",
                        'label' => __('SLA Plan'),