Skip to content
Snippets Groups Projects
Commit f4d79b1e authored by Peter Rotich's avatar Peter Rotich
Browse files

User Tickets

Include collaborated tickets
Pagenate user and org tickets listing
Add ability to export tickets
parent 4deb401e
No related branches found
No related tags found
No related merge requests found
...@@ -1292,6 +1292,10 @@ class QuerySet implements IteratorAggregate, ArrayAccess, Serializable, Countabl ...@@ -1292,6 +1292,10 @@ class QuerySet implements IteratorAggregate, ArrayAccess, Serializable, Countabl
function asView() { function asView() {
$unique = spl_object_hash($this); $unique = spl_object_hash($this);
$classname = "QueryView{$unique}"; $classname = "QueryView{$unique}";
if (class_exists($classname))
return $classname;
$class = <<<EOF $class = <<<EOF
class {$classname} extends VerySimpleModel { class {$classname} extends VerySimpleModel {
static \$meta = array( static \$meta = array(
......
...@@ -22,6 +22,7 @@ include_once(INCLUDE_DIR.'class.dept.php'); ...@@ -22,6 +22,7 @@ include_once(INCLUDE_DIR.'class.dept.php');
include_once(INCLUDE_DIR.'class.topic.php'); include_once(INCLUDE_DIR.'class.topic.php');
include_once(INCLUDE_DIR.'class.lock.php'); include_once(INCLUDE_DIR.'class.lock.php');
include_once(INCLUDE_DIR.'class.file.php'); include_once(INCLUDE_DIR.'class.file.php');
include_once(INCLUDE_DIR.'class.export.php');
include_once(INCLUDE_DIR.'class.attachment.php'); include_once(INCLUDE_DIR.'class.attachment.php');
include_once(INCLUDE_DIR.'class.banlist.php'); include_once(INCLUDE_DIR.'class.banlist.php');
include_once(INCLUDE_DIR.'class.template.php'); include_once(INCLUDE_DIR.'class.template.php');
......
<?php <?php
$args = array();
parse_str($_SERVER['QUERY_STRING'], $args);
$args['t'] = 'tickets';
unset($args['p'], $args['_pjax']);
$tickets = TicketModel::objects(); $tickets = TicketModel::objects();
if ($user) { if ($user) {
$tickets->filter(array('user_id' => $user->getId())); $filter = $tickets->copy()
} ->values_flat('ticket_id')
elseif ($org) { ->filter(array('user_id' => $user->getId()))
$tickets->filter(array('user__org' => $org)); ->union($tickets->copy()
->values_flat('ticket_id')
->filter(array('thread__collaborators__user_id' => $user->getId()))
, false);
} elseif ($org) {
$filter = $tickets->copy()
->values_flat('ticket_id')
->filter(array('user__org' => $org));
} }
// Apply filter
$tickets->filter(array('ticket_id__in' => $filter));
// Apply staff visibility
if (!$thisstaff->hasPerm(SearchBackend::PERM_EVERYTHING)) { if (!$thisstaff->hasPerm(SearchBackend::PERM_EVERYTHING)) {
// -- Open and assigned to me // -- Open and assigned to me
$visibility = array( $visibility = array(
...@@ -25,10 +40,22 @@ if (!$thisstaff->hasPerm(SearchBackend::PERM_EVERYTHING)) { ...@@ -25,10 +40,22 @@ if (!$thisstaff->hasPerm(SearchBackend::PERM_EVERYTHING)) {
$tickets->filter(Q::any($visibility)); $tickets->filter(Q::any($visibility));
} }
$tickets->constrain(array('lock' => array( $tickets->constrain(array('lock' => array(
'lock__expire__gt' => SqlFunction::NOW()))); 'lock__expire__gt' => SqlFunction::NOW())));
// Group by ticket_id.
$tickets->distinct('ticket_id');
// Save the query to the session for exporting
$queue = sprintf(':%s:tickets', $user ? 'U' : 'O');
$_SESSION[$queue] = $tickets;
// Apply pagination
$total = $tickets->count();
$page = ($_GET['p'] && is_numeric($_GET['p'])) ? $_GET['p'] : 1;
$pageNav = new Pagenate($total, $page, PAGE_LIMIT);
$pageNav->setURL(($user ? 'users.php' : 'orgs.php'), $args);
$tickets = $pageNav->paginate($tickets);
$tickets->annotate(array( $tickets->annotate(array(
'collab_count' => SqlAggregate::COUNT('thread__collaborators', true), 'collab_count' => SqlAggregate::COUNT('thread__collaborators', true),
...@@ -48,16 +75,15 @@ $tickets->annotate(array( ...@@ -48,16 +75,15 @@ $tickets->annotate(array(
$tickets->values('staff_id', 'staff__firstname', 'staff__lastname', 'team__name', 'team_id', 'lock__lock_id', 'lock__staff_id', 'isoverdue', 'status_id', 'status__name', 'status__state', 'number', 'cdata__subject', 'ticket_id', 'source', 'dept_id', 'dept__name', 'user_id', 'user__default_email__address', 'user__name', 'lastupdate'); $tickets->values('staff_id', 'staff__firstname', 'staff__lastname', 'team__name', 'team_id', 'lock__lock_id', 'lock__staff_id', 'isoverdue', 'status_id', 'status__name', 'status__state', 'number', 'cdata__subject', 'ticket_id', 'source', 'dept_id', 'dept__name', 'user_id', 'user__default_email__address', 'user__name', 'lastupdate');
TicketForm::ensureDynamicDataView(); $tickets->order_by('-created');
TicketForm::ensureDynamicDataView();
// Fetch the results // Fetch the results
$results = count($tickets);
?> ?>
<div class="pull-left" style="margin-top:5px;"> <div class="pull-left" style="margin-top:5px;">
<?php <?php
if ($results) { if ($total) {
echo '<strong>'.sprintf(_N('Showing %d ticket', 'Showing %d tickets', echo '<strong>'.$pageNav->showing().'</strong>';
count($results)), count($results)).'</strong>';
} else { } else {
echo sprintf(__('%s does not have any tickets'), $user? 'User' : 'Organization'); echo sprintf(__('%s does not have any tickets'), $user? 'User' : 'Organization');
} }
...@@ -76,7 +102,7 @@ $results = count($tickets); ...@@ -76,7 +102,7 @@ $results = count($tickets);
<br/> <br/>
<div> <div>
<?php <?php
if ($results) { ?> if ($total) { ?>
<form action="users.php" method="POST" name='tickets' style="padding-top:10px;"> <form action="users.php" method="POST" name='tickets' style="padding-top:10px;">
<?php csrf_token(); ?> <?php csrf_token(); ?>
<input type="hidden" name="a" value="mass_process" > <input type="hidden" name="a" value="mass_process" >
...@@ -107,6 +133,7 @@ if ($results) { ?> ...@@ -107,6 +133,7 @@ if ($results) { ?>
<tbody> <tbody>
<?php <?php
$subject_field = TicketForm::objects()->one()->getField('subject'); $subject_field = TicketForm::objects()->one()->getField('subject');
$user_id = $user ? $user->getId() : 0;
foreach($tickets as $T) { foreach($tickets as $T) {
$flag=null; $flag=null;
if ($T['lock__lock_id'] && $T['lock__staff_id'] != $thisstaff->getId()) if ($T['lock__lock_id'] && $T['lock__staff_id'] != $thisstaff->getId())
...@@ -139,13 +166,19 @@ if ($results) { ?> ...@@ -139,13 +166,19 @@ if ($results) { ?>
</td> </td>
<?php <?php
} ?> } ?>
<td align="center" nowrap> <td nowrap>
<a class="Icon <?php <a class="Icon <?php
echo strtolower($T['source']); ?>Ticket preview" echo strtolower($T['source']); ?>Ticket preview"
title="<?php echo __('Preview Ticket'); ?>" title="<?php echo __('Preview Ticket'); ?>"
href="tickets.php?id=<?php echo $T['ticket_id']; ?>" href="tickets.php?id=<?php echo $T['ticket_id']; ?>"
data-preview="#tickets/<?php echo $T['ticket_id']; ?>/preview"><?php echo $tid; ?></a></td> data-preview="#tickets/<?php echo $T['ticket_id']; ?>/preview"><?php
<td align="center" nowrap><?php echo Format::datetime($T['lastupdate']); ?></td> echo $tid; ?></a>
<?php
if ($user_id && $user_id != $T['user_id'])
echo '<span class="pull-right faded-more" data-toggle="tooltip" title="'
.__('Collaborator').'"><i class="icon-eye-open"></i></span>';
?></td>
<td nowrap><?php echo Format::datetime($T['lastupdate']); ?></td>
<td><?php echo $status; ?></td> <td><?php echo $status; ?></td>
<td><a class="truncate <?php if ($flag) { ?> Icon <?php echo $flag; ?>Ticket" title="<?php echo ucfirst($flag); ?> Ticket<?php } ?>" <td><a class="truncate <?php if ($flag) { ?> Icon <?php echo $flag; ?>Ticket" title="<?php echo ucfirst($flag); ?> Ticket<?php } ?>"
style="max-width: 230px;" style="max-width: 230px;"
...@@ -187,6 +220,18 @@ if ($results) { ?> ...@@ -187,6 +220,18 @@ if ($results) { ?>
?> ?>
</tbody> </tbody>
</table> </table>
<?php
if ($total>0) {
echo '<div>';
echo __('Page').':'.$pageNav->getPageLinks('tickets', '#tickets').'&nbsp;';
echo sprintf('<a class="export-csv no-pjax" href="?%s">%s</a>',
Http::build_query(array(
'id' => $user ? $user->getId(): $org->getId(),
'a' => 'export',
't' => 'tickets')),
__('Export'));
echo '</div>';
} ?>
</form> </form>
<?php <?php
} ?> } ?>
......
...@@ -148,7 +148,7 @@ if ($thisstaff->hasPerm(User::PERM_EDIT)) { ?> ...@@ -148,7 +148,7 @@ if ($thisstaff->hasPerm(User::PERM_EDIT)) { ?>
<div class="clear"></div> <div class="clear"></div>
<ul class="clean tabs" id="user-view-tabs"> <ul class="clean tabs" id="user-view-tabs">
<li class="active"><a href="#tickets"><i <li class="active"><a href="#tickets"><i
class="icon-list-alt"></i>&nbsp;<?php echo __('User Tickets'); ?></a></li> class="icon-list-alt"></i>&nbsp;<?php echo __('Tickets'); ?></a></li>
<li><a href="#notes"><i <li><a href="#notes"><i
class="icon-pushpin"></i>&nbsp;<?php echo __('Notes'); ?></a></li> class="icon-pushpin"></i>&nbsp;<?php echo __('Notes'); ?></a></li>
</ul> </ul>
......
...@@ -95,7 +95,7 @@ if ($_POST) { ...@@ -95,7 +95,7 @@ if ($_POST) {
default: default:
$errors['err'] = __('Unknown action'); $errors['err'] = __('Unknown action');
} }
} elseif ($_REQUEST['a'] == 'export') { } elseif (!$org && $_REQUEST['a'] == 'export') {
require_once(INCLUDE_DIR.'class.export.php'); require_once(INCLUDE_DIR.'class.export.php');
$ts = strftime('%Y%m%d'); $ts = strftime('%Y%m%d');
if (!($token=$_REQUEST['qh'])) if (!($token=$_REQUEST['qh']))
...@@ -106,7 +106,26 @@ if ($_POST) { ...@@ -106,7 +106,26 @@ if ($_POST) {
$errors['err'] = __('Internal error: Unable to export results'); $errors['err'] = __('Internal error: Unable to export results');
} }
$page = $org? 'org-view.inc.php' : 'orgs.inc.php'; $page = 'orgs.inc.php';
if ($org) {
$page = 'org-view.inc.php';
switch (strtolower($_REQUEST['t'])) {
case 'tickets':
if (isset($_SERVER['HTTP_X_PJAX'])) {
$page='templates/tickets.tmpl.php';
$pjax_container = @$_SERVER['HTTP_X_PJAX_CONTAINER'];
require(STAFFINC_DIR.$page);
return;
} elseif ($_REQUEST['a'] == 'export' && ($query=$_SESSION[':O:tickets'])) {
$filename = sprintf('%s-tickets-%s.csv',
$org->getName(), strftime('%Y%m%d'));
if (!Export::saveTickets($query, $filename, 'csv'))
$errors['err'] = __('Internal error: Unable to dump query results');
}
break;
}
}
$nav->setTabActive('users'); $nav->setTabActive('users');
require(STAFFINC_DIR.'header.inc.php'); require(STAFFINC_DIR.'header.inc.php');
require(STAFFINC_DIR.$page); require(STAFFINC_DIR.$page);
......
...@@ -159,7 +159,7 @@ if ($_POST) { ...@@ -159,7 +159,7 @@ if ($_POST) {
$errors['err'] = __('Unknown action'); $errors['err'] = __('Unknown action');
break; break;
} }
} elseif($_REQUEST['a'] == 'export') { } elseif(!$user && $_REQUEST['a'] == 'export') {
require_once(INCLUDE_DIR.'class.export.php'); require_once(INCLUDE_DIR.'class.export.php');
$ts = strftime('%Y%m%d'); $ts = strftime('%Y%m%d');
if (!($token=$_REQUEST['qh'])) if (!($token=$_REQUEST['qh']))
...@@ -170,7 +170,25 @@ if ($_POST) { ...@@ -170,7 +170,25 @@ if ($_POST) {
$errors['err'] = __('Internal error: Unable to dump query results'); $errors['err'] = __('Internal error: Unable to dump query results');
} }
$page = $user? 'user-view.inc.php' : 'users.inc.php'; $page = 'users.inc.php';
if ($user ) {
$page = 'user-view.inc.php';
switch (strtolower($_REQUEST['t'])) {
case 'tickets':
if (isset($_SERVER['HTTP_X_PJAX'])) {
$page='templates/tickets.tmpl.php';
$pjax_container = @$_SERVER['HTTP_X_PJAX_CONTAINER'];
require(STAFFINC_DIR.$page);
return;
} elseif ($_REQUEST['a'] == 'export' && ($query=$_SESSION[':U:tickets'])) {
$filename = sprintf('%s-tickets-%s.csv',
$user->getName(), strftime('%Y%m%d'));
if (!Export::saveTickets($query, $filename, 'csv'))
$errors['err'] = __('Internal error: Unable to dump query results');
}
break;
}
}
$nav->setTabActive('users'); $nav->setTabActive('users');
require(STAFFINC_DIR.'header.inc.php'); require(STAFFINC_DIR.'header.inc.php');
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment