diff --git a/include/ajax.tickets.php b/include/ajax.tickets.php index 18aa44c4a066e5032fcf64989429cbc29501ceed..fd031f80f5fb7dbecbc5856c59a5cb96bf1fbcf7 100644 --- a/include/ajax.tickets.php +++ b/include/ajax.tickets.php @@ -462,6 +462,65 @@ class TicketsAjaxAPI extends AjaxController { include STAFFINC_DIR . 'templates/assign.tmpl.php'; } + function claim($tid) { + + global $thisstaff; + + if (!($ticket=Ticket::lookup($tid))) + Http::response(404, __('No such ticket')); + + // Check for premissions and such + if (!$ticket->checkStaffPerm($thisstaff, Ticket::PERM_ASSIGN) + || !$ticket->isOpen() // Claim only open + || $ticket->getStaff() // cannot claim assigned ticket + || !($form = $ticket->getClaimForm($_POST))) + Http::response(403, __('Permission Denied')); + + $errors = array(); + $info = array( + ':title' => sprintf(__('Ticket #%s: %s'), + $ticket->getNumber(), + __('Claim')), + ':action' => sprintf('#tickets/%d/claim', + $ticket->getId()), + + ); + + if ($ticket->isAssigned()) { + if ($ticket->getStaffId() == $thisstaff->getId()) + $assigned = __('you'); + else + $assigneed = $ticket->getAssigned(); + + $info['error'] = sprintf(__('%s is currently assigned to <b>%s</b>'), + __('This ticket'), + $assigned); + } else { + $info['warn'] = __('Are you sure you want to claim this ticket?'); + } + + if ($_POST && $form->isValid()) { + if ($ticket->claim($form, $errors)) { + $_SESSION['::sysmsgs']['msg'] = sprintf( + __('%s successfully'), + sprintf( + __('%s assigned to %s'), + __('Ticket'), + __('you')) + ); + Http::response(201, $ticket->getId()); + } + + $form->addErrors($errors); + $info['error'] = $errors['err'] ?: __('Unable to claim ticket'); + } + + $verb = sprintf('%s, %s', __('Yes'), __('Claim')); + + include STAFFINC_DIR . 'templates/assign.tmpl.php'; + + } + function massProcess($action) { global $thisstaff; diff --git a/include/class.forms.php b/include/class.forms.php index 7d163f361cc77000a8437d694b457313dc2c5671..39f44a5df3c580ccf7410fc4b3eaefbce29b8a05 100644 --- a/include/class.forms.php +++ b/include/class.forms.php @@ -4056,7 +4056,43 @@ class AssignmentForm extends Form { function getComments() { return $this->getField('comments')->getClean(); + } +} + +class ClaimForm extends AssignmentForm { + + var $_fields; + + function setFields($fields) { + $this->_fields = $fields; + parent::setFields($fields); + } + + function getFields() { + + if ($this->_fields) + return $this->_fields; + $fields = parent::getFields(); + + // Disable && hide assignee field selection + if (isset($fields['assignee'])) { + $visibility = new VisibilityConstraint( + new Q(array()), VisibilityConstraint::HIDDEN); + + $fields['assignee']->set('visibility', $visibility); + } + + // Change coments placeholder to reflect claim + if (isset($fields['comments'])) { + $fields['comments']->configure('placeholder', + __('Optional reason for the claim')); + } + + + $this->setFields($fields); + + return $this->fields; } } diff --git a/include/class.ticket.php b/include/class.ticket.php index a03d3bcbeb91cd87675fb34594afeef6281ae6c4..64e275559d71616a3182b5366d3b9ea0d7f21f36 100644 --- a/include/class.ticket.php +++ b/include/class.ticket.php @@ -892,6 +892,19 @@ implements RestrictedAccess, Threadable { $f->configure('prompt', $prompt); + return $form; + } + + function getClaimForm($source=null, $options=array()) { + global $thisstaff; + + $id = sprintf('s%d', $thisstaff->getId()); + if(!$source) + $source = array('assignee' => array($id)); + + $form = ClaimForm::instantiate($source, $options); + $form->setAssignees(array($id => $thisstaff->getName())); + return $form; } @@ -2061,17 +2074,25 @@ implements RestrictedAccess, Threadable { return true; } - function claim() { + function claim(ClaimForm $form, &$errors) { global $thisstaff; - if (!$thisstaff || !$this->isOpen() || $this->isAssigned()) - return false; - $dept = $this->getDept(); - if ($dept->assignMembersOnly() && !$dept->isMember($thisstaff)) + $assignee = $form->getAssignee(); + if (!($assignee instanceof Staff) + || !$thisstaff + || $thisstaff->getId() != $assignee->getId()) { + $errors['err'] = __('Unknown assignee'); + } elseif (!$assignee->isAvailable()) { + $errors['err'] = __('Agent is unavailable for assignment'); + } elseif ($dept->assignMembersOnly() && !$dept->isMember($assignee)) { + $errors['err'] = __('Permission denied'); + } + + if ($errors) return false; - return $this->assignToStaff($thisstaff->getId(), null, false); + return $this->assignToStaff($assignee, $form->getComments(), false); } function assignToStaff($staff, $note, $alert=true) { diff --git a/include/staff/ticket-view.inc.php b/include/staff/ticket-view.inc.php index d89a4d5e34da99bfdc3616234cc9df39814f5632..0770668754f1de53faf1a18284b0da08663dd873 100644 --- a/include/staff/ticket-view.inc.php +++ b/include/staff/ticket-view.inc.php @@ -96,10 +96,15 @@ if($ticket->isOverdue()) </span> <div id="action-dropdown-assign" class="action-dropdown anchor-right"> <ul> + <?php + // Agent can claim team assigned ticket + if (!$ticket->getStaff()) { ?> <li><a class="no-pjax ticket-action" data-redirect="tickets.php" - href="#tickets/<?php echo $ticket->getId(); ?>/assign/<?php echo $thisstaff->getId(); ?>"><i + href="#tickets/<?php echo $ticket->getId(); ?>/claim"><i class="icon-chevron-sign-down"></i> <?php echo __('Claim'); ?></a> + <?php + } ?> <li><a class="no-pjax ticket-action" data-redirect="tickets.php" href="#tickets/<?php echo $ticket->getId(); ?>/assign/agents"><i diff --git a/scp/ajax.php b/scp/ajax.php index 78682a36315846be8c87295a22d80d1ef521def6..20674f0603c10271b0591a9f8daa7a807c80f9e0 100644 --- a/scp/ajax.php +++ b/scp/ajax.php @@ -165,6 +165,7 @@ $dispatcher = patterns('', url_post('^mass/(?P<action>[\w.]+)', 'massProcess'), url('^(?P<tid>\d+)/transfer$', 'transfer'), url('^(?P<tid>\d+)/assign(?:/(?P<to>\w+))?$', 'assign'), + url('^(?P<tid>\d+)/claim$', 'claim'), url('^search', patterns('ajax.search.php:SearchAjaxAPI', url_get('^$', 'getAdvancedSearchDialog'), url_post('^$', 'doSearch'),