This mod is an update of the old 1.6ST Pending Status and Autoclose mod for osTicket version 1.7ST. It adds a new “Pending” status that can be used on tickets, it also adds an autoclose feature for tickets that are left in pending for more then 5 days. Here are instructions on what the steps are and how to do so:
version: 1.7.b
Summary:
- 1. Install the additional files
- 2. Update the database
- 3. Editing the files
- 4. Customizing the Mod
This mod is an update of the old 1.6ST Pending Status and Autoclose mod for osTicket version 1.7ST. It adds a new “Pending” status that can be used on tickets, it also adds an autoclose feature for tickets that are left in pending for more then 5 days. Here are instructions on what the steps are and how to do so:
version: 1.7.b
note: some of this might not cut and paste correctly.
Summary:
- 1. Install the additional files
- 2. Update the database
- 3. Editing the files
- 4. Customizing the Mod
Step 1 – Install the additional Files
Copy the two files [preLogin.pgp and autoClose.php from archive below] to /include/staff
In /scp/login.php
circa line 31 locate:
require_once('index.php'); //Just incase header is messed up.
below add the following:
define("OMEGAPVTLTD",TRUE); //Make includes happy
// do tasks prior to redirecting
include_once(INCLUDE_DIR.'staff/preLogin.php');
Files: pending-mod-files.zip
Step 2 – Update the database
update the database [please edit this to fit your installation] with the following MySQL Queries:
ALTER TABLE ost_ticket CHANGE status status ENUM('open','closed','pending') DEFAULT 'open';
ALTER TABLE ost_ticket_event CHANGE state state ENUM('created','closed','reopened','assigned','transferred','overdue','pending')
Step 3 – Editing the files
open \scp\tickets.php
circa line 42 locate:
$statusKeys=array('open'=>'Open','Reopen'=>'Open','Close'=>'Closed');
replace it with
$statusKeys=array('open'=>'Open','Reopen'=>'Open','Close'=>'Closed','pending'=>'Pending');
circa line 506 locate:
if($stats['overdue']) {
$nav->addSubMenu(array('desc'=>'Overdue ('.number_format($stats['overdue']).')',
'title'=>'Stale Tickets',
'href'=>'tickets.php?status=overdue',
'iconclass'=>'overdueTickets'),
($_REQUEST['status']=='overdue'));
if(!$sysnotice && $stats['overdue']>10)
$sysnotice=$stats['overdue'] .' overdue tickets!';
}
below it add:
$nav->addSubMenu(array('desc'=>'Pending Tickets ('.number_format($stats['pending']).')',
'title'=>'Pending Tickets',
'href'=>'tickets.php?status=pending',
'iconclass'=>'closedTickets'),
(!$_REQUEST['status'] || $_REQUEST['status']=='Pending'));
open \include\class.ticket.php
circa line 113 locate:
function isReopened() {
return ($this->getReopenDate());
}
below it add:
function isPending(){
return (strcasecmp($this->getStatus(),'Pending')==0);
}
circa line 631 locate:
function setStatus($status) {
if(strcasecmp($this->getStatus(), $status)==0)
return true; //No changes needed.
switch(strtolower($status)) {
case 'open':
return $this->reopen();
break;
case 'closed':
return $this->close();
break;
}
return false;
}
replace with:
function setStatus($status) {
if(strcasecmp($this->getStatus(), $status)==0)
return true; //No changes needed.
switch(strtolower($status)) {
case 'open':
return $this->reopen();
break;
case 'pending':
return $this->pending();
break;
case 'closed':
return $this->close();
break;
}
return false;
}
circa line 648 locate:
function setState($state, $alerts=false) {
switch(strtolower($state)) {
case 'open':
return $this->setStatus('open');
break;
case 'closed':
return $this->setStatus('closed');
break;
case 'answered':
return $this->setAnsweredState(1);
break;
case 'unanswered':
return $this->setAnsweredState(0);
break;
case 'overdue':
return $this->markOverdue();
break;
case 'notdue':
return $this->clearOverdue();
break;
case 'unassined':
return $this->unassign();
}
return false;
}
replace with:
function setState($state, $alerts=false) {
switch(strtolower($state)) {
case 'open':
return $this->setStatus('open');
break;
case 'pending':
return $this->setStatus('pending');
break;
case 'closed':
return $this->setStatus('closed');
break;
case 'answered':
return $this->setAnsweredState(1);
break;
case 'unanswered':
return $this->setAnsweredState(0);
break;
case 'overdue':
return $this->markOverdue();
break;
case 'notdue':
return $this->clearOverdue();
break;
case 'unassined':
return $this->unassign();
}
return false;
}
circa line 688 locate:
//Close the ticket
function close() {
global $thisstaff;
$sql='UPDATE '.TICKET_TABLE.' SET closed=NOW(),isoverdue=0, duedate=NULL, updated=NOW(),
status='.db_input('closed');
if($thisstaff) //Give the closing staff credit.
$sql.=', staff_id='.db_input($thisstaff->getId());
$sql.=' WHERE ticket_id='.db_input($this->getId());
if(!db_query($sql) || !db_affected_rows())
return false;
$this->reload();
$this->logEvent('closed');
return true;
}
above it add:
//Mark Ticket as Pending
function pending() {
global $thisstaff;
$sql='UPDATE '.TICKET_TABLE.' SET isoverdue=0, duedate=NULL, updated=NOW(), status='.db_input
('pending');
if($thisstaff) //Give the closing staff credit.
$sql.=', staff_id='.db_input($thisstaff->getId());
$sql.=' WHERE ticket_id='.db_input($this->getId());
if(!db_query($sql) || !db_affected_rows())
return false;
$this->reload();
$this->logEvent('pending');
return true;
}
circa line 1763 locate:
$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 '
.' FROM '.TICKET_TABLE.' ticket '
.' LEFT JOIN '.TICKET_TABLE.' open ON (open.ticket_id=ticket.ticket_id AND open.status=\'open\'
AND open.isanswered=0 '.((!($cfg->showAssignedTickets() || $staff->showAssignedTickets()))? ' AND
open.staff_id=0 ':'').') '
.' LEFT JOIN '.TICKET_TABLE.' answered ON (answered.ticket_id=ticket.ticket_id AND
answered.status=\'open\' AND answered.isanswered=1) '
.' LEFT JOIN '.TICKET_TABLE.' overdue ON (overdue.ticket_id=ticket.ticket_id AND
overdue.status=\'open\' AND overdue.isoverdue=1) '
.' LEFT JOIN '.TICKET_TABLE.' assigned ON (assigned.ticket_id=ticket.ticket_id AND
assigned.status=\'open\' AND assigned.staff_id='.db_input($staff->getId()).')'
.' LEFT JOIN '.TICKET_TABLE.' closed ON (closed.ticket_id=ticket.ticket_id AND closed.status=\'closed\' )'
.' WHERE (ticket.staff_id='.db_input($staff->getId());
replace with:
$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(pending.ticket_id) as pending, count(closed.ticket_id) as closed '
.' FROM '.TICKET_TABLE.' ticket '
.' LEFT JOIN '.TICKET_TABLE.' open ON (open.ticket_id=ticket.ticket_id AND open.status=\'open\' AND open.isanswered=0 '.((!($cfg->showAssignedTickets() || $staff->showAssignedTickets()))? ' AND open.staff_id=0 ':'').') '
.' LEFT JOIN '.TICKET_TABLE.' answered ON (answered.ticket_id=ticket.ticket_id AND answered.status=\'open\' AND answered.isanswered=1) '
.' LEFT JOIN '.TICKET_TABLE.' pending ON (pending.ticket_id=ticket.ticket_id AND pending.status=\'pending\' )'
.' LEFT JOIN '.TICKET_TABLE.' overdue ON (overdue.ticket_id=ticket.ticket_id AND overdue.status=\'open\' AND overdue.isoverdue=1) '
.' LEFT JOIN '.TICKET_TABLE.' assigned ON (assigned.ticket_id=ticket.ticket_id AND assigned.status=\'open\' AND assigned.staff_id='.db_input($staff->getId()).')'
.' LEFT JOIN '.TICKET_TABLE.' closed ON (closed.ticket_id=ticket.ticket_id AND closed.status=\'closed\' )'
.' WHERE (ticket.staff_id='.db_input($staff->getId());
circa line 1796 locate:
$sql='SELECT count(open.ticket_id) as open, count(closed.ticket_id) as closed '
.' FROM '.TICKET_TABLE.' ticket '
.' LEFT JOIN '.TICKET_TABLE.' open
ON (open.ticket_id=ticket.ticket_id AND open.status=\'open\') '
.' LEFT JOIN '.TICKET_TABLE.' closed
ON (closed.ticket_id=ticket.ticket_id AND closed.status=\'closed\')'
.' WHERE ticket.email='.db_input($email);
replace with:
$sql='SELECT count(open.ticket_id) as open, count(pending.ticket_id) as pending, count(closed.ticket_id) as closed '
.' FROM '.TICKET_TABLE.' ticket '
.' LEFT JOIN '.TICKET_TABLE.' open ON (open.ticket_id=ticket.ticket_id AND open.status=\'open\') '
.' LEFT JOIN '.TICKET_TABLE.' pending ON (pending.ticket_id=ticket.ticket_id AND pending.status=\'pending\') '
.' LEFT JOIN '.TICKET_TABLE.' closed ON (closed.ticket_id=ticket.ticket_id AND closed.status=\'closed\')'
.' WHERE ticket.email='.db_input($email);
open include\staff\tickets.inc.php
circa line 32 locate:
case 'open':
$status='open';
break;
below add:
case 'pending':
$status='pending';
break;
open include\staff\ticket-view.inc.php
circa line 485 locate:
<?php
if($ticket->isClosed() || $thisstaff->canCloseTickets()) { ?>
<tr>
<td width="160">
<label><strong>Ticket Status:</strong></label>
</td>
<td width="765">
<?php
$statusChecked=isset($info['reply_ticket_status'])?'checked="checked"':'';
if($ticket->isClosed()) { ?>
<label><input type="checkbox" name="reply_ticket_status" id="reply_ticket_status" value="Open"
<?php echo $statusChecked; ?>> Reopen on Reply
<?php
} elseif($thisstaff->canCloseTickets()) { ?>
<label><input type="checkbox" name="reply_ticket_status" id="reply_ticket_status" value="Closed"
<?php echo $statusChecked; ?>> Close on Reply</label>
<?php
} ?>
</td>
</tr>
<?php
} ?>
replace with:
<?php
if($ticket->isClosed() || $thisstaff->canCloseTickets()) { ?>
<tr>
<td width="160">
<label><strong>Ticket Status:</strong></label>
</td>
<td width="765">
<?php
$statusChecked=isset($info['reply_ticket_status'])?'checked="checked"':'';
if($ticket->isOpen()) { ?>
<label><input type="checkbox" name="reply_ticket_status" id="reply_ticket_status" value="Pending"
<?php echo $statusChecked; ?>> Mark as Pending</label>
<?php
} elseif($ticket->isPending()) { ?>
<label><input type="checkbox" name="reply_ticket_status" id="reply_ticket_status" value="Open"
<?php echo $statusChecked; ?>> Unmark as Pending</label>
<?php
} ?>
<?php
$statusChecked=isset($info['reply_ticket_status'])?'checked="checked"':'';
if($ticket->isClosed()) { ?>
<label><input type="checkbox" name="reply_ticket_status" id="reply_ticket_status" value="Open"
<?php echo $statusChecked; ?>> Reopen on Reply
<?php
} elseif($thisstaff->canCloseTickets()) { ?>
<label><input type="checkbox" name="reply_ticket_status" id="reply_ticket_status" value="Closed"
<?php echo $statusChecked; ?>> Close on Reply</label>
<?php
} ?>
</td>
</tr>
<?php
} ?>
Step 4 – Customizing your mod to fit your installation more
You may want to close tickets sooner (or later than) the default 5 days. The number of days is handled in the autoClose.php by part of the sql statement:
Locate:
$sql .= " AND updated <= '" . date("Y-m-d", strtotime('-5 days')) . " 00:00:00'";
modifying the part of the statement that reads ‘-5 days’ will change the number of days.