Archive

Posts Tagged ‘FIND’

[osTicket][1.7][MOD] Batch Ticket Assign

June 27th, 2013 3 comments

Partly modified from [MOD] Batch Ticket Assign for osTicket 1.6, but with some better (I think) modifications where each ticket can have it’s own corresponding assignee options and comment.

Features:

  1. Unassigned Tickets tag
  2. assignees options for each ticket
  3. popup comments for each ticket
  4. confirm box

How to:

  1. new tag Unassigned Tickets including its ticket count under the Tickets tab. This sub tab will only appear if you have unassigned ticket, and will disappear if there is no unassigned ticket in your osTicket system.
  2. In every open tickets tags (ie. not in close tickets tag), the options of assignees of each ticket are on the right of each ticket row.
  3. Comment box will popup after chosen a assignee, box can be closed by either click X or anywhere outside the box. (Note: I make it allow empty comment here since my company prefer it…)
  4. Click the Apply Assign button and a confirmation box would popup like other batch actions.

Preview:

Assignee options

Assignee options


Popup comment box

Popup comment box


Confirm box

Confirm box

Install

1. include/staff/tickets.inc.php
FIND

$showoverdue=$showanswered=false;

ADD AFTER

// MOD: BOF - Batch Assign
$showunassigned=false;
// MOD: EOF - Batch Assign

FIND

    case 'assigned':
        $status='open';
        $staffId=$thisstaff->getId();
        $results_type='My Tickets';
        break;

ADD AFTER

// MOD: BOF - Batch Assign
    case 'unassigned':
        $showunassigned=true;
        $staffId=0;
        break;
// MOD: EOF - Batch Assign

FIND

    if(!($cfg->showAssignedTickets() || $thisstaff->showAssignedTickets())) {
        $qwhere.=' AND ticket.staff_id=0 '; //XXX: NOT factoring in team assignments - only staff assignments.
        $showassigned=false; //Not showing Assigned To column since assigned tickets are not part of open queue
    }
}

ADD AFTER

// MOD: BOF - Batch Assign
elseif($showunassigned) {
    $results_type='Unassigned Tickets';
    $qwhere.=' AND ticket.staff_id=0 AND ticket.status="open" ';
}
// MOD: EOF - Batch Assign

FIND

                <th width="150">
                    <a <?php echo $dept_sort; ?> href="tickets.php?sort=dept&order=<?php echo $negorder;?><?php echo $qstr; ?>" 
                        title="Sort By Department <?php echo $negorder; ?>">Department</a></th>
            <?php
            } ?>

ADD AFTER

            <!-- MOD: BOF - Batch Assign -->
            <?php if(!strcasecmp($status,'open')) { ?>
	        <th>Assign To</th>
            <?php } ?>
            <!-- MOD: EOF - Batch Assign -->

FIND

                <td nowrap>&nbsp;<?php echo $lc; ?></td>

ADD AFTER

                <!-- MOD: BOF - Batch Assign -->
                <td>
                	<?php if($ticket=Ticket::lookup($row['ticket_id'])){ ?>
                  <select id="assignId" name="assignId">
                        <option value="0" selected="selected">&mdash; Select Staff Member OR a Team &mdash;</option>
                        <?php
                        if($ticket->isOpen() && !$ticket->isAssigned())
                            echo sprintf('<option value="%d">Claim Ticket</option>', $thisstaff->getId());
 
                        $sid=$tid=0;
                        if(($users=Staff::getAvailableStaffMembers())) {
                            echo '<OPTGROUP label="Staff Members ('.count($users).')">';
                            $staffId=$ticket->isAssigned()?$ticket->getStaffId():0;
                            foreach($users as $id => $name) {
                                if($staffId && $staffId==$id)
                                    continue;
 
                                $k="s$id";
                                echo sprintf('<option value="%s" %s>%s</option>',
                                        $k,(($info['assignId']==$k)?'selected="selected"':''),$name);
                            }
                            echo '</OPTGROUP>';
                        }
 
                        if(($teams=Team::getActiveTeams())) {
                            echo '<OPTGROUP label="Teams ('.count($teams).')">';
                            $teamId=(!$sid && $ticket->isAssigned())?$ticket->getTeamId():0;
                            foreach($teams as $id => $name) {
                                if($teamId && $teamId==$id)
                                    continue;
 
                                $k="t$id";
                                echo sprintf('<option value="%s" %s>%s</option>',
                                        $k,(($info['assignId']==$k)?'selected="selected"':''),$name);
                            }
                            echo '</OPTGROUP>';
                        }
                        ?>
                    </select>
                    <?php } ?>
                </td>
                <!-- MOD: EOF - Batch Assign -->

FIND

            if($thisstaff->canDeleteTickets()) { ?>
                <input class="button" type="submit" name="delete" value="Delete">
            <?php } ?>

ADD AFTER

            <!-- MOD: BOF - Batch Assign -->
            <?php if(strtolower($status) != 'closed'){ ?>
                <input class="button" type="submit" name="assign" value="Apply Assign" >
                <?php
                if($errors['assign'])
                    echo $errors['assign']; 
            		?>
            <?php } ?>                
            <!-- MOD: EOF - Batch Assign -->

FIND

    <p class="confirm-action" style="display:none;" id="delete-confirm">
        <font color="red"><strong>Are you sure you want to DELETE selected tickets?</strong></font>
        <br><br>Deleted tickets CANNOT be recovered, including any associated attachments.
    </p>

ADD AFTER

    <!-- MOD: BOF - Batch Assign -->
    <p class="confirm-action" style="display:none;" id="assign-confirm">
        Are you sure want to <font color="red"><b>assign</b></font> the selected tickets to the corresponding staffs?
    </p>
    <!-- MOD: EOF - Batch Assign -->

2. include/class.ticket.php
FIND

        $sql='SELECT count(open.ticket_id) as open, count(answered.ticket_id) as answered '
            .' ,count(overdue.ticket_id) as overdue, count(assigned.ticket_id) as assigned, count(closed.ticket_id) as closed '

ADD AFTER

// MOD: BOF - Batch Assign
            .',count(unassigned.ticket_id) as unassigned '
// MOD: EOF - Batch Assign

FIND

            .' LEFT JOIN '.TICKET_TABLE.' closed
                ON (closed.ticket_id=ticket.ticket_id
                        AND closed.status='closed' )'

ADD AFTER

// MOD: BOF - Batch Assign
            .'LEFT JOIN '.TICKET_TABLE.' unassigned
                ON unassigned.ticket_id=ticket.ticket_id
                        AND unassigned.staff_id=0
                        AND unassigned.status='open' '
// MOD: EOF - Batch Assign

3. scp/js/scp.js
FIND

        if($('.dialog#confirm-action p#'+this.name+'-confirm').length == 0) {
            alert('Unknown action '+this.name+' - get technical help.');

ADD AFTER

        // MOD: BOF - Batch Assign
        }else if(this.name == 'assign'){
            var assigned = 0;
            $('select[name="assignId\[\]"]').each(function(){
                if($(this).val() != 0) assigned++;
            });
            if(!assigned) {
                alert("Please make at least 1 assignment.");
                return (false);
            }
            var action = this.name;
            $('.dialog#confirm-action').undelegate('.confirm');
            $('.dialog#confirm-action').delegate('input.confirm', 'click.confirm', function(e) {
                e.preventDefault();
                $('.dialog#confirm-action').hide();
                $('#overlay').hide();
                $('input#action', formObj).val(action);
                formObj.submit();
                return false;
             });
            $('#overlay').show();
            $('.dialog#confirm-action .confirm-action').hide();
            $('.dialog#confirm-action p#'+this.name+'-confirm')
            .show()
            .parent('div').show().trigger('click');
        // MOD: EOF - Batch Assign

ADD BEFORE LAST });

    // MOD: BOF - Batch Assign
    $('select[name="assignId\[\]"]').change(function(e) {
        var elem = $(this);
        if(elem.val() != '0'){
            if(elem.parent().find('.tip_box').length > 0) {
            	elem.parent().find('.tip_box').show();
            	elem.parent().find('.note').focus();
            } else {
                var ind = elem.index('select[name="assignId\[\]"]');
                var pos = elem.offset();
 
                var y_pos = pos.top + 22;
                var x_pos = pos.left;
 
                var tip_box = $('<div>').addClass('tip_box');
                var note_header = $('<div><label><strong>Comments</strong></label>');
                var note_textarea = $('<textarea name="assign_comments['+ind+']" wrap="off" rows="4" class="assign_comments"></textarea>');
                var tip_content = $('<div>').addClass('tip_content').prepend('<a href="#" class="assign_comments_close">x</a>').append(note_header).append(note_textarea);
 
                var the_tip = tip_box.append(tip_content);
                the_tip.css({
                    "top":y_pos + "px",
                    "left":x_pos + "px"
                });
 
                tip_timer = setTimeout(function() {
                    elem.parent().find('.tip_box').remove();
                    elem.parent().append(the_tip.hide().fadeIn());
                    note_textarea.focus();
                }, 500);
            }
        }
    });
    $('body').delegate('.assign_comments_close', 'click', function(e) {
        e.preventDefault();
        $(this).parent().parent().hide();
    });    
    $('body').delegate('.assign_comments', 'blur', function(e) {
        e.preventDefault();
        $(this).parent().parent().hide();
    });
    // MOD: EOF - Batch Assign

4. scp/tickets.php
FIND

if(!$thisstaff->canManageTickets())
                    $errors['err']='You do not have permission to mass manage tickets. Contact admin for such access';

ADD AFTER

                // MOD: BOF - Batch Assign
                elseif(strtolower($_POST['do']) == 'assign'){
                		if(!$_POST['assignId'] || !is_array($_POST['assignId']) || !$_POST['assignTId'] || !is_array($_POST['assignTId'])) {
                			$errors['err']=$errors['assign'] = 'No assignee is selected.';
                		} elseif(!$thisstaff->canAssignTickets()) {
                			$errors['err']=$errors['assign'] = 'Action Denied. You are not allowed to assign/reassign tickets.';
                		} else {
 
                			foreach($_POST['assignId'] as $k=>$v){
 
                				// continue for not assigned tickets
                				if($v == '0') continue;
 
                				$id = preg_replace("/[^0-9]/", "",$v);
                				$claim = (is_numeric($v) && $v==$thisstaff->getId());
 
                				if(!($ticket=Ticket::lookup($_POST['assignTId'][$k])))
                					$errors['assignId'][$k]='Unknown or invalid ticket ID';
                				elseif(!$ticket->checkStaffAccess($thisstaff)) {
                					$errors['err']='Access denied. Contact admin if you believe this is in error';
                				}
 
                				if($v[0]!='s' && $v[0]!='t' && !$claim)
                					$errors['assignId'][$k]='Invalid assignee ID - get technical support';
                				elseif($ticket->isAssigned()) {
                					if($v[0]=='s' && $id==$ticket->getStaffId())
                						$errors['assignId'][$k]='Ticket already assigned to the staff.';
                					elseif($v[0]=='t' && $id==$ticket->getTeamId())
                					$errors['assignId'][$k]='Ticket already assigned to the team.';
                				}
 
                				if($claim && !$_POST['assign_comments'][$k])
                					$_POST['assign_comments'][$k] = 'Ticket claimed by '.$thisstaff->getName();
                				elseif(!$_POST['assign_comments'][$k])
                					$_POST['assign_comments'][$k] = 'Ticket batch assigned by '.$thisstaff->getName();
 
                				if(!$errors && $ticket->assign($v, $_POST['assign_comments'], !$claim)) {
                					if($claim) {
                						$numClaim++;
                					} else {
                						$numAssignOthers++;
                						TicketLock::removeStaffLocks($thisstaff->getId(), $ticket->getId());
                					}
                				} elseif(!$errors['assign']) {
                					$errors['err'] = 'Unable to complete the ticket assignment';
                					$errors['assign'] = 'Correct the error(s) below and try again!';
                				}
                			}
                			$msg = (int)$numClaim . ' ticket are assigned to you, ' . (int)$numAssignOthers . ' tickets are assigned successfully to others.';
                		}
                		$ticket=null;
                		break;
 
                }
                // MOD: EOF - Batch Assign

FIND

if($stats['assigned']) {
    if(!$ost->getWarning() && $stats['assigned']>10)
        $ost->setWarning($stats['assigned'].' tickets assigned to you! Do something about it!');
 
    $nav->addSubMenu(array('desc'=>'My Tickets ('.number_format($stats['assigned']).')',
                           'title'=>'Assigned Tickets',
                           'href'=>'tickets.php?status=assigned',
                           'iconclass'=>'assignedTickets'),
                        ($_REQUEST['status']=='assigned'));
}

ADD AFTER

// MOD: BOF - Batch Assign
if($stats['unassigned']) {
    $nav->addSubMenu(array('desc'=>'Unassigned Tickets ('.number_format($stats['unassigned']).')',
                           'title'=>'Unassigned Tickets',
                           'href'=>'tickets.php?status=unassigned',
                           'iconclass'=>'assignedTickets'),
                        ($_REQUEST['status']=='unassigned'));
}
// MOD: EOF - Batch Assign

5. scp/css/scp.css
FIND

.tip_close {
    position:absolute;
    left:100%;
    top:0;
    margin-left:-12px;
}

ADD AFTER

/*MOD: BOF - Batch Assign*/
.assign_comments_close {
    position:absolute;
    left:100%;
    top:0;
    margin-left:-12px;
}
/*MOD: EOF - Batch Assign*/

Files Pack
Support Forums
GitHub

[osTicket][1.7][MOD] Toggle Tickets Content Preview

June 27th, 2013 9 comments

osTicket 1.7ST comes with the ticket header preview in tickets listing page, but sometime it’s not enough to determine what action should do toward the tickets. And it’s time-consuming for admin/managers to open each ticket and read its content one by one. So why don’t we hide the ticket content and only display them when we need?

Feature:

1. Fancy JQuery sliding effect
2. One-click to expend/hide all
3. User profile setting to expend all on default

How to:

1. When staffs click the toggle icon beside ticket subjects, the content toggle just below the ticket .
2. Toggle ALL tickets content by clicking “Toggle Content Preview” button.
3. Staffs can set to expend all tickets by default in their profile page.

Best to use with Batch Ticket Assign together, so admin/managers can preview and assign tickets directly in the tickets list page, without going into each ticket.

Preview:

Single ticket content expended

Single ticket content expended


All tickets content expended

All tickets content expended


Staff profile setting on default expending

Staff profile setting on default expending

Install Instruction:

1. MySQL

ALTER TABLE ost_staff ADD toggle_tickets_content_preview TINYINT(1) AFTER show_assigned_tickets;

change ost_staff if you have different table prefix

2. Upload Images
images/icons/closed.gif
images/icons/opened.gif

3.include/staff/tickets.inc.php
FIND

                <td><a <?php if($flag) { ?> class="Icon <?php echo $flag; ?>Ticket" title="<?php echo ucfirst($flag); ?> Ticket" <?php } ?> 
                    href="tickets.php?id=<?php echo $row['ticket_id']; ?>"><?php echo $subject; ?></a>
                     &nbsp;

REPLACE WITH

                <!-- MOD: BOF - Toggle Tickets Content Preview -->
                <td><span class="ticketContentPreview"><img src="../images/icons/closed.gif" alt="Expend Ticket Content Preview"></span><a <?php if($flag) { ?> class="Icon <?php echo $flag; ?>Ticket" title="<?php echo ucfirst($flag); ?> Ticket" <?php } ?> 
                    href="tickets.php?id=<?php echo $row['ticket_id']; ?>"><?php echo $subject; ?></a>
                     &nbsp;
                <!-- MOD: BOF - Toggle Tickets Content Preview -->

FIND

                <td nowrap>&nbsp;<?php echo $lc; ?></td>
            </tr>

ADD AFTER

            <!-- MOD: BOF - Toggle Tickets Content Preview -->
            <tr class="ticketContentRow">
            	<td></td>
            	<td colspan="7">
            		<div>
	            	<?php 
	            	$qselect='SELECT body ';
	            	$qfrom=' FROM '.TICKET_THREAD_TABLE;
	            	$qwhere=' WHERE ticket_id='.db_input($row['ticket_id']).
	                         ' AND created=(SELECT max(created) FROM '.TICKET_THREAD_TABLE.' WHERE ticket_id='.db_input($row['ticket_id']).')'; 
	            	$pquery = "$qselect $qfrom $qwhere LIMIT 1";
	            	$pres = db_query($pquery);
	            	$prow = db_fetch_array($pres);
	            	echo nl2br(Format::truncate($prow['body'],600));
	            	?>
            	</div>
            	</td>
            </tr>
            <!-- MOD: EOF - Toggle Tickets Content Preview -->

FIND

        <?php
         if($thisstaff->canManageTickets()) { ?>
           <p class="centered" id="actions">
            <?php

REPLACE WITH

           <p class="centered" id="actions">
        <?php
         if($thisstaff->canManageTickets()) { ?>
            <?php

FIND

        </p>
        <?php
       }
    } ?>

REPLACE WITH

         <?php
       }
    } ?>
            <!-- MOD: BOF - Expending Ticket Content Preview -->
            <input class="button" type="button" name="toggle_tickets_content_preview" value="Toggle Content Previews">
            <?php if($thisstaff->toggleTicketsContentPreview()){ ?>
            <script>
            $(document).ready(function(){
                $('input[name="toggle_tickets_content_preview"]').click();
            });
            </script>
            <?php } ?>
            <!-- MOD: EOF - Expending Ticket Content Preview -->
        </p>

4.include/class.staff.php

FIND

            .' ,show_assigned_tickets='.db_input(isset($vars['show_assigned_tickets'])?1:0)

ADD AFTER

// MOD: BOF - Toggle Tickets Content Preview
            .' ,toggle_tickets_content_preview='.db_input(isset($vars['toggle_tickets_content_preview'])?1:0)
// MOD: BOF - Toggle Tickets Content Preview

FIND

    function showAssignedTickets() {
        return ($this->ht['show_assigned_tickets']
                && ($this->isAdmin() || $this->isManager()));
    }

ADD AFTER

    // MOD: BOF - Toggle Tickets Content Preview
    function toggleTicketsContentPreview() {
        return ($this->ht['toggle_tickets_content_preview']);
    }
    // MOD: BOF - Toggle Tickets Content Preview

5.scp/js/scp.js

ADD BEFORE LAST });

    // MOD: BOF - Toggle Tickets Content Preview
    $('.ticketContentRow').hide();
    $('.ticketContentRow div').hide();
    $('.ticketContentPreview').click(function(e) {
        var ticketContentRow = $(this).parent().parent().next();
        if(ticketContentRow.is(':hidden')) {
        	$(this).removeClass('classed');
        	$(this).addClass('opened');
            $(this).html('<img src="../images/icons/opened.gif" alt="Hide Ticket Content Preview">');
        }else{
        	$(this).removeClass('opened');
        	$(this).addClass('closed');
            $(this).html('<img src="../images/icons/closed.gif" alt="Expend Ticket Content Preview">');
        }
        toggleTicketContentPreview(ticketContentRow);
    });
    $('input[name="toggle_tickets_content_preview"]').click(function(e) {
        $('.ticketContentRow').each(function() {
            toggleTicketContentPreview($(this));
        });
        $('.ticketContentPreview').each(function () {
        	if($(this).hasClass('opened')) {
        		$(this).removeClass('opened');
        		$(this).addClass('closed');
    		    $(this).html('<img src="../images/icons/closed.gif" alt="Expend Ticket Content Preview">');
            } else {
            	$(this).removeClass('classed');
            	$(this).addClass('opened');
    	    	$(this).html('<img src="../images/icons/opened.gif" alt="Hide Ticket Content Preview">');
        	}
        });
    });
 
    function toggleTicketContentPreview(ticketContentRow){
        if(!ticketContentRow.is(':hidden')) {
            ticketContentRow.find('div').slideToggle();
            ticketContentRow.find('div').promise().done(function(){
                ticketContentRow.toggle();
            });
        } else {
            ticketContentRow.toggle();
            ticketContentRow.find('div').slideToggle();
        }
    }
    // MOD: EOF - Toggle Tickets Content Preview

Files Pack
Support Forum
GitHub