This is a rewrite of (fidel's v1.6 mod), tested and working with v1.7.0. Note that the following patches should be applied at the TLD of your osTicket installation (using patch -p0 < ). Several files are affected:
include/ajax.tickets.php
include/class.pdf.php
include/class.ticket.php
include/staff/ticket-view.inc.php
scp/tickets.php
Note that my line numbers might differ from yours, and the order in which I apply this mod with others will most likely differ form the order in which you do.
NB - Before using this patch, you must add time_spent columns to your ticket and ticket_thread tables:
ALTER TABLE `ost_ticket` ADD `time_spent` FLOAT(4,2) NULL DEFAULT '0.00';
ALTER TABLE `ost_ticket_thread` ADD `time_spent` FLOAT(4,2) NULL DEFAULT '0.00';
The patch containing all changes:
--- include/ajax.tickets.php 2013-04-01 23.000000000 -0600
+++ include/ajax.tickets.php 2013-05-02 10.000000000 -0600
@@ -319,6 +319,13 @@
</tr>',
Format:($ticket->getEstDueDate()));
}
+ echo sprintf('
+ <tr>
+ <th width="100">Time Spent:</th>
+ <td>%s</td>
+ </tr>',
+ Format:($ticket->formatTime($ticket->getTimeSpent()))
+ );
echo '</table>';
--- include/class.pdf.php 2013-04-01 23.000000000 -0600
+++ include/class.pdf.php 2013-05-03 14.000000000 -0600
@@ -195,12 +195,16 @@
$this->SetFont('');
$this->Cell($c, 7, Format:($ticket->getCloseDate()), 1, 0, 'L', true);
}
-
$this->SetFont('Arial', 'B', 11);
$this->Cell($l, 7, 'Last Message', 1, 0, 'L', true);
$this->SetFont('');
$this->Cell($c, 7, Format:($ticket->getLastMsgDate()), 1, 1, 'L', true);
- $this->Ln(5);
+
+ $this->SetFont('Arial', 'B', 11);
+ $this->Cell($l, 7, 'Time Spent', 1, 0, 'L', true);
+ $this->SetFont('');
+ $this->Cell($c, 7, Format:($ticket->formatTime($ticket->getTimeSpent())), 1, 0, 'L', true);
+ $this->Ln(10);
$this->SetFont('Arial', 'B', 11);
$this->cMargin = 0;
--- include/class.ticket.php 2013-04-01 23.000000000 -0600
+++ include/class.ticket.php 2013-05-04 17.000000000 -0600
@@ -234,6 +234,10 @@
return $this->ht;
}
+ function getTimeSpent() {
+ return $this->ht;
+ }
+
function getStatus() {
return $this->ht;
}
@@ -316,6 +320,24 @@
return $this->tlock;
}
+ function formatTime($time) {
+
+ $hours = floor($time);
+ $minutes = round(($time-$hours) * 60);
+
+ if ($hours > 0) {
+ $formatted_time .= $hours.($hours == 1 ? ' hour' : ' hours');
+ if ($minutes > 0) {
+ $formatted_time .= ' '.$minutes.($minutes == 1 ? ' minute' : ' minutes');
+ }
+ }
+ else {
+ $formatted_time .= $minutes.($minutes == 1 ? ' minute' : ' minutes');
+ }
+
+ return $formatted_time;
+ }
+
function acquireLock($staffId, $lockTime) {
if(!$staffId or !$lockTime) //Lockig disabled?
@@ -713,6 +735,57 @@
return (db_query($sql) && db_affected_rows());
}
+ function timeSpent($time) {
+ if (empty($time) || !is_numeric($time)) {
+ $time = 0.00;
+ } else {
+ $time = round($time, 2);
+ }
+
+ $sql='UPDATE '.TICKET_TABLE.' SET time_spent=time_spent+'.db_input($time)
+ .' WHERE ticket_id='.db_input($this->getId());
+
+ return (db_query($sql) && db_affected_rows());
+ }
+
+ function timeSpentDel($time) {
+ if (empty($time) || !is_numeric($time)) {
+ $time = 0.00;
+ } else {
+ $time = round($time, 2);
+ }
+
+ $sql='UPDATE '.TICKET_TABLE.' SET time_spent=time_spent-'.db_input($time)
+ .' WHERE ticket_id='.db_input($this->getId());
+
+ return (db_query($sql) && db_affected_rows());
+ }
+
+ function timeSpentEntry($id, $time) {
+ if (empty($time) || !is_numeric($time)) {
+ $time = 0.00;
+ } else {
+ $time = round($time, 2);
+ }
+
+ $sql='UPDATE '.TICKET_THREAD_TABLE.' SET time_spent='.db_input($time)
+ .' WHERE id='.db_input($id);
+
+ $this->timeSpent($time);
+
+ return (db_query($sql) && db_affected_rows());
+ }
+
+ function timeSpentEntryDel($id) {
+ $sql='SELECT time_spent FROM '.TICKET_THREAD_TABLE
+ .' WHERE id='.db_input($id);
+
+ $result = db_query($sql);
+ $row = db_fetch_array($result);
+ $time = $row;
+ $this->timeSpentDel($time);
+ }
+
function onNewTicket($message, $autorespond=true, $alertstaff=true) {
global $cfg;
--- include/staff/ticket-view.inc.php 2013-04-01 23.000000000 -0600
+++ include/staff/ticket-view.inc.php 2013-05-03 16.000000000 -0600
@@ -245,6 +245,10 @@
<?php
}
?>
+ <tr>
+ <th>Time Spent:</th>
+ <td><?php echo Format:($ticket->formatTime($ticket->getTimeSpent())); ?></td>
+ </tr>
</table>
</td>
<td width="50%">
@@ -314,6 +318,11 @@
</tr>
<?php
}?>
+ <tr>
+ <td class="info" colspan="2">
+ <b>Time Spent:</b> <?php echo Format:($ticket->formatTime($note)); ?>
+ </td>
+ </tr>
</table>
<?php
}
@@ -349,6 +358,11 @@
</tr>
<?php
}?>
+ <tr>
+ <td class="info" colspan="3">
+ <b>Time Spent:</b> <?php echo Format:($ticket->formatTime($entry)); ?>
+ </td>
+ </tr>
</table>
<?php
if($entry=='M')
@@ -482,6 +496,18 @@
</td>
</tr>
<?php
+ if($ticket->isOpen()) { ?>
+ <tr>
+ <td width="160">
+ <label for="reply_time_spent" class="left">Time Spent:</label>
+ </td>
+ <td width="765">
+ <input type="text" name="reply_time_spent" size="5" value="<?php if (isset($_POST)) echo $_POST; ?>"/> (0.75 = 45 minutes)
+ </td>
+ </tr>
+ <?php
+ } ?>
+ <?php
if($ticket->isClosed() || $thisstaff->canCloseTickets()) { ?>
<tr>
<td width="160">
@@ -558,7 +584,19 @@
<?php
}
?>
- <tr><td colspan="2"> </td></tr>
+ <?php
+ if($ticket->isOpen()) { ?>
+ <tr>
+ <td width="160">
+ <label for="note_time_spent" class="left">Time Spent:</label>
+ </td>
+ <td width="765">
+ <input type="text" name="note_time_spent" size="5" value="<?php if (isset($_POST)) echo $_POST; ?>"/> (0.75 = 45 minutes)
+ </td>
+ </tr>
+ <?php
+ }
+ ?>
<tr>
<td width="160">
<label>Ticket Status:</label>
--- scp/tickets.php 2013-04-01 23.000000000 -0600
+++ scp/tickets.php 2013-05-03 16.000000000 -0600
@@ -66,6 +66,7 @@
if(!$errors && ($response=$ticket->postReply($vars, $errors, isset($_POST)))) {
$msg='Reply posted successfully';
+ $ticket->timeSpentEntry($response->getId(),$_POST);
$ticket->reload();
if($ticket->isClosed() && $wasOpen)
$ticket=null;
@@ -168,6 +169,7 @@
if(($note=$ticket->postNote($vars, $errors, $thisstaff))) {
$msg='Internal note posted successfully';
+ $ticket->timeSpentEntry($note->getId(),$_POST);
if($wasOpen && $ticket->isClosed())
$ticket = null; //Going back to main listing.