diff --git a/include/staff/ticket-view.inc.php b/include/staff/ticket-view.inc.php index 4d171fd8f3a65f2257b53a6fd8dd9052b32ed156..111852e3883b48ca3238b00aeb958751d1ee7a9c 100644 --- a/include/staff/ticket-view.inc.php +++ b/include/staff/ticket-view.inc.php @@ -359,36 +359,47 @@ if(!$cfg->showNotesInline()) { ?> <input type="hidden" name="a" value="reply"> <span class="error"></span> <table border="0" cellspacing="0" cellpadding="3"> - <tr> - <td width="160"> </td> - <td class="error"><?php echo $errors['response']; ?></td> - </tr> - <?php - if(($cannedResponses=Canned::responsesByDeptId($ticket->getDeptId()))) {?> <tr> <td width="160"> - <label> </label> + <label><strong>TO:</strong></label> </td> <td width="765"> - <select id="cannedResp" name="cannedResp"> - <option value="0" selected="selected">Select a canned response</option> - <?php - foreach($cannedResponses as $id =>$title) { - echo sprintf('<option value="%d">%s</option>',$id,$title); - } - ?> - </select> + <?php + $to = $ticket->getEmail(); + if(($name=$ticket->getName()) && !strpos($name,'@')) + $to =sprintf('%s <em><%s></em>', $name, $ticket->getEmail()); + echo $to; + ?> - <label><input type='checkbox' value='1' name="append" id="append" checked="checked"> Append</label> + <label><input type='checkbox' value='1' name="emailreply" id="remailreply" + <?php echo ((!$info['emailreply'] && !$errors) || isset($info['emailreply']))?'checked="checked"':''; ?>> Email Reply</label> </td> </tr> <?php + if($errors['response']) {?> + <tr><td width="160"> </td><td class="error"><?php echo $errors['response']; ?> </td></tr> + <?php }?> <tr> <td width="160"> <label><strong>Response:</strong></label> </td> <td width="765"> + <?php + if(($cannedResponses=Canned::responsesByDeptId($ticket->getDeptId()))) {?> + <select id="cannedResp" name="cannedResp"> + <option value="0" selected="selected">Select a canned response</option> + <?php + foreach($cannedResponses as $id =>$title) { + echo sprintf('<option value="%d">%s</option>',$id,$title); + } + ?> + </select> + + <label><input type='checkbox' value='1' name="append" id="append" checked="checked"> Append</label> + <br> + <?php + }?> <textarea name="response" id="response" cols="50" rows="9" wrap="soft"><?php echo $info['response']; ?></textarea> </td> </tr> @@ -468,31 +479,29 @@ if(!$cfg->showNotesInline()) { ?> <input type="hidden" name="id" value="<?php echo $ticket->getId(); ?>"> <input type="hidden" name="a" value="postnote"> <table border="0" cellspacing="0" cellpadding="3"> + <?php + if($errors['note']) {?> <tr> <td width="160"> </td> - <td class="error"><?php echo $errors['note']; ?></td> - </tr> - <tr> - <td width="160"> - <label><strong>Title:</strong></label> - </td> - <td width="765"> - <input type="text" name="title" id="title" size="45" value="<?php echo $info['title']; ?>" > - <span class="error">* <?php echo $errors['title']; ?></span> - </td> + <td class="error"><?php echo $errors['postnote']; ?></td> </tr> + <?php + } ?> <tr> <td width="160"> - <label><strong>Note:</strong></label> + <label><strong>Internal Note:</strong></label> </td> <td width="765"> - <div><span class="faded">Internal note details</span> - <span class="error">* <?php echo $errors['internal_note']; ?></span></div> - <textarea name="internal_note" id="internal_note" cols="50" rows="9" wrap="soft" - style="width:600px"><?php echo $info['internal_note']; ?></textarea> + <div><span class="faded">Note details</span> + <span class="error">* <?php echo $errors['note']; ?></span></div> + <textarea name="note" id="internal_note" cols="80" rows="9" wrap="soft"><?php echo $info['note']; ?></textarea><br> + <div> + <span class="faded">Note title - sumarry of the note (optional)</span> + <span class="error" <?php echo $errors['title']; ?></span> + </div> + <input type="text" name="title" id="title" size="60" value="<?php echo $info['title']; ?>" > </td> </tr> - <?php if($cfg->allowAttachments()) { ?> <tr> @@ -510,36 +519,54 @@ if(!$cfg->showNotesInline()) { ?> <?php } ?> + <tr><td colspan="2"> </td></tr> <tr> <td width="160"> <label>Ticket Status:</label> </td> <td width="765"> - <?php - $statusChecked=isset($info['note_ticket_state'])?'checked="checked"':''; - if($ticket->isClosed()){ ?> - <label><input type="checkbox" name="note_ticket_state" id="note_ticket_state" value="open" - <?php echo $statusChecked; ?>> Reopen Ticket</label> - <?php - } elseif(0 && $thisstaff->canCloseTickets()) { ?> - <label><input type="checkbox" name="note_ticket_state" id="note_ticket_state" value="Closed" - <?php echo $statusChecked; ?>> Close Ticket</label> - <?php - } elseif($ticket->isAnswered()) { ?> - <label> - <input type="checkbox" name="note_ticket_state" id="note_ticket_state" value="Unanswered" - <?php echo $statusChecked; ?>> - Mark Unanswered - </label> - <?php - } else { ?> - <label> - <input type="checkbox" name="note_ticket_state" id="note_ticket_state" value="Answered" - <?php echo $statusChecked; ?>> - Mark Answered - </label> - <?php - } ?> + <div class="faded"></div> + <select name="state"> + <option value="" selected="selected">— unchanged —</option> + <?php + $state = $info['state']; + if($ticket->isClosed()){ + echo sprintf('<option value="open" %s>Reopen Ticket</option>', + ($state=='reopen')?'selected="selelected"':''); + } else { + if($thisstaff->canCloseTickets()) + echo sprintf('<option value="closed" %s>Close Ticket</option>', + ($state=='closed')?'selected="selelected"':''); + + /* Ticket open - states */ + echo '<option value="" disabled="disabled">— Ticket States —</option>'; + + //Answer - state + if($ticket->isAnswered()) + echo sprintf('<option value="unanswered" %s>Mark As Unanswered</option>', + ($state=='unanswered')?'selected="selelected"':''); + else + echo sprintf('<option value="answered" %s>Mark As Answered</option>', + ($state=='answered')?'selected="selelected"':''); + + //overdue - state + // Only department manager can set/clear overdue flag directly. + // Staff with edit perm. can still set overdue date & change SLA. + if($dept && $dept->isManager($thisstaff)) { + if(!$ticket->isOverdue()) + echo sprintf('<option value="overdue" %s>Flag As Overdue</option>', + ($state=='answered')?'selected="selelected"':''); + else + echo sprintf('<option value="notdue" %s>Clear Overdue Flag</option>', + ($state=='notdue')?'selected="selelected"':''); + + if($ticket->isAssigned()) + echo sprintf('<option value="unassigned" %s>Release (Unassign) Ticket</option>', + ($state=='unassigned')?'selected="selelected"':''); + } + }?> + </select> + <span class='error'>* <?php echo $errors['state']; ?></span> </td> </tr> </div> @@ -557,15 +584,24 @@ if(!$cfg->showNotesInline()) { ?> <input type="hidden" name="ticket_id" value="<?php echo $ticket->getId(); ?>"> <input type="hidden" name="a" value="transfer"> <table border="0" cellspacing="0" cellpadding="3"> + <?php + if($errors['transfer']) { + ?> <tr> <td width="160"> </td> <td class="error"><?php echo $errors['transfer']; ?></td> </tr> + <?php + } ?> <tr> <td width="160"> <label for="deptId"><strong>Department:</strong></label> </td> <td width="765"> + <?php + echo sprintf('<span class="faded">Ticket is currently in <b>%s</b> department.</span>', $ticket->getDeptName()); + ?> + <br> <select id="deptId" name="deptId"> <option value="0" selected="selected">— Select Target Department —</option> <?php @@ -586,9 +622,9 @@ if(!$cfg->showNotesInline()) { ?> </td> <td width="765"> <span class="faded">Enter reasons for the transfer.</span> - <span class="error">* <?php echo $errors['transfer_message']; ?></span><br> - <textarea name="transfer_message" id="transfer_message" - cols="80" rows="7" wrap="soft"><?php echo $info['transfer_message']; ?></textarea> + <span class="error">* <?php echo $errors['transfer_comments']; ?></span><br> + <textarea name="transfer_comments" id="transfer_comments" + cols="80" rows="7" wrap="soft"><?php echo $info['transfer_comments']; ?></textarea> </td> </tr> </table> @@ -606,30 +642,43 @@ if(!$cfg->showNotesInline()) { ?> <input type="hidden" name="id" value="<?php echo $ticket->getId(); ?>"> <input type="hidden" name="a" value="assign"> <table border="0" cellspacing="0" cellpadding="3"> + + <?php + if($errors['assign']) { + ?> <tr> <td width="160"> </td> - <td> - <?php - if($ticket->isAssigned()) - echo sprintf('<em>Ticket is currently assigned to <b>%s</b></em>',$ticket->getAssignee()); - ?> - </td> + <td class="error"><?php echo $errors['assign']; ?></td> </tr> + <?php + } ?> <tr> <td width="160"> <label for="assignId"><strong>Assignee:</strong></label> </td> <td width="765"> + <?php + if($ticket->isAssigned() && $ticket->isOpen()) { + echo sprintf('<span class="faded">Ticket is currently assigned to <b>%s</b></span>', + $ticket->getAssignee()); + } else { + echo '<span class="faded">Assigning a closed ticket will <b>reopen</b> it!</span>'; + } + ?> + <br> <select id="assignId" name="assignId"> <option value="0" selected="selected">— Select Staff Member OR a Team —</option> <?php + if($ticket->isOpen() && !$ticket->isAssigned()) + echo sprintf('<option value="%d">Claim Ticket (comments optional)</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) - $name.=' (Assigned)'; + continue; $k="s$id"; echo sprintf('<option value="%s" %s>%s</option>', @@ -643,7 +692,7 @@ if(!$cfg->showNotesInline()) { ?> $teamId=(!$sid && $ticket->isAssigned())?$ticket->getTeamId():0; foreach($teams as $id => $name) { if($teamId && $teamId==$id) - $name.=' (Assigned)'; + continue; $k="t$id"; echo sprintf('<option value="%s" %s>%s</option>', @@ -660,9 +709,9 @@ if(!$cfg->showNotesInline()) { ?> <label><strong>Comments:</strong><span class='error'> </span></label> </td> <td width="765"> - <span class="faded">Enter reasons for the assignment or instructions.</span> - <span class="error">* <?php echo $errors['assign_message']; ?></span><br> - <textarea name="assign_message" id="assign_message" cols="80" rows="7" wrap="soft"><?php echo $info['assign_message']; ?></textarea> + <span class="faded">Enter reasons for the assignment or instructions for assignee.</span> + <span class="error">* <?php echo $errors['assign_comments']; ?></span><br> + <textarea name="assign_comments" id="assign_comments" cols="80" rows="7" wrap="soft"><?php echo $info['assign_comments']; ?></textarea> </td> </tr> </table> diff --git a/scp/tickets.php b/scp/tickets.php index cf8619d500d3762d63aa7bb4e3e9c42a489be879..10cce9afc34fcf18f2a2f9a7fa7ebe87da0d0aad 100644 --- a/scp/tickets.php +++ b/scp/tickets.php @@ -57,99 +57,109 @@ if($_POST && !$errors): $wasOpen =($ticket->isOpen()); //If no error...do the do. - if(!$errors && ($respId=$ticket->postReply($_POST, $errors))) { + if(!$errors && ($respId=$ticket->postReply($_POST, $errorsi, isset($_POST['emailreply'])))) { $msg='Reply posted successfully'; $ticket->reload(); if($ticket->isClosed() && $wasOpen) $ticket=null; + } elseif(!$errors['err']) { $errors['err']='Unable to post the reply. Correct the errors below and try again!'; } break; case 'transfer': /** Transfer ticket **/ //Check permission - if($thisstaff && $thisstaff->canTransferTickets()) { + if(!$thisstaff->canTransferTickets()) + $errors['err']=$errors['transfer'] = 'Action Denied. You are not allowed to transfer tickets.'; + else { + + //Check target dept. if(!$_POST['deptId']) - $errors['deptId']='Select department'; + $errors['deptId'] = 'Select department'; elseif($_POST['deptId']==$ticket->getDeptId()) - $errors['deptId']='Ticket already in the Dept.'; + $errors['deptId'] = 'Ticket already in the department'; elseif(!($dept=Dept::lookup($_POST['deptId']))) - $errors['deptId']='Unknown or invalid department'; - - if(!$_POST['transfer_message']) - $errors['transfer_message'] = 'Transfer comments/notes required'; - elseif(strlen($_POST['transfer_message'])<5) - $errors['transfer_message'] = 'Transfer comments too short!'; - - if(!$errors && $ticket->transfer($_POST['deptId'], $_POST['transfer_message'])) { + $errors['deptId'] = 'Unknown or invalid department'; + + //Transfer message - required. + if(!$_POST['transfer_comments']) + $errors['transfer_comments'] = 'Transfer comments required'; + elseif(strlen($_POST['transfer_comments'])<5) + $errors['transfer_comments'] = 'Transfer comments too short!'; + + //If no errors - them attempt the transfer. + if(!$errors && $ticket->transfer($_POST['deptId'], $_POST['transfer_comments'])) { $msg = 'Ticket transferred successfully to '.$ticket->getDeptName(); //Check to make sure the staff still has access to the ticket if(!$ticket->checkStaffAccess($thisstaff)) $ticket=null; - } else { - $errors['transfer']='Unable to complete the transfer - try again'; - $errors['err']='Missing or invalid data. Correct the error(s) below and try again!'; + } elseif(!$errors['transfer']) { + $errors['err'] = 'Unable to complete the ticket transfer'; + $errors['transfer']='Correct the error(s) below and try again!'; } - } else { - $errors['err']=$errors['transfer']='Action Denied. You are not allowed to transfer tickets.'; } break; case 'assign': - if($thisstaff && $thisstaff->canAssignTickets()) { - if(!$_POST['assignId']) + if(!$thisstaff->canAssignTickets()) + $errors['err']=$errors['assign'] = 'Action Denied. You are not allowed to assign/reassign tickets.'; + else { + + $id = preg_replace("/[^0-9]/", "",$_POST['assignId']); + $claim = (is_numeric($_POST['assignId']) && $_POST['assignId']==$thisstaff->getId()); + + if(!$_POST['assignId'] || !$id) $errors['assignId'] = 'Select assignee'; - elseif($_POST['assignId'][0]!='s' && $_POST['assignId'][0]!='t') + elseif($_POST['assignId'][0]!='s' && $_POST['assignId'][0]!='t' && !$claim) $errors['assignId']='Invalid assignee ID - get technical support'; elseif($ticket->isAssigned()) { - $id=preg_replace("/[^0-9]/", "",$_POST['assignId']); if($_POST['assignId'][0]=='s' && $id==$ticket->getStaffId()) $errors['assignId']='Ticket already assigned to the staff.'; elseif($_POST['assignId'][0]=='t' && $id==$ticket->getTeamId()) $errors['assignId']='Ticket already assigned to the team.'; } - if(!$_POST['assign_message']) - $errors['assign_message']='Comments required'; - elseif(strlen($_POST['assign_message'])<5) - $errors['assign_message']='Comments too short'; - - if(!$errors && $ticket->assign($_POST['assignId'],$_POST['assign_message'])) { - $msg='Ticket assigned successfully to '.$ticket->getAssignee(); - TicketLock::removeStaffLocks($thisstaff->getId(),$ticket->getId()); - $ticket=null; - }elseif(!$errors['err']) { - $errors['err']='Unable to assign the ticket. Correct the errors below and try again.'; + //Comments are not required on self-assignment (claim) + if($claim && !$_POST['assign_comments']) + $_POST['assign_comments'] = 'Ticket claimed by '.$thisstaff->getName(); + elseif(!$_POST['assign_comments']) + $errors['assign_comments'] = 'Assignment comments required'; + elseif(strlen($_POST['assign_comments'])<5) + $errors['assign_comments'] = 'Comment too short'; + + if(!$errors && $ticket->assign($_POST['assignId'], $_POST['assign_comments'], !$claim)) { + if($claim) { + $msg = 'Ticket is NOW assigned to you!'; + } else { + $msg='Ticket assigned successfully to '.$ticket->getAssigned(); + TicketLock::removeStaffLocks($thisstaff->getId(), $ticket->getId()); + $ticket=null; + } + } elseif(!$errors['assign']) { + $errors['err'] = 'Unable to complete the ticket assignment'; + $errors['assign'] = 'Correct the error(s) below and try again!'; } - - } else { - $errors['err']=$errors['assign']='Action Denied. You are not allowed to assign/reassign tickets.'; } break; case 'postnote': /* Post Internal Note */ - $fields=array(); - $fields['title'] = array('type'=>'string', 'required'=>1, 'error'=>'Title required'); - $fields['internal_note'] = array('type'=>'string', 'required'=>1, 'error'=>'Note message required'); - - if(!Validator::process($fields, $_POST, $errors) && !$errors['err']) - $errors['err']=$errors['note']='Missing or invalid data. Correct the error(s) below and try again!'; - - if(!$errors && ($noteId=$ticket->postNote($_POST['title'], $_POST['internal_note'], $thisstaff))) { + //Make sure the staff can set desired state + if($_POST['state']) { + if($_POST['state']=='closed' && !$thisstaff->canCloseTickets()) + $errors['state'] = "You don't have permission to close tickets"; + elseif(in_array($_POST['state'], array('overdue', 'notdue', 'unassigned')) + && (!($dept=$ticket->getDept()) || !$dept->isManager($thisstaff))) + $errors['state'] = "You don't have permission to set the state"; + } + + $wasOpen = ($ticket->isOpen()); + if(($noteId=$ticket->postNote($_POST, $errors, $thisstaff))) { $msg='Internal note posted successfully'; - //Upload attachments IF ANY - TODO: validate attachment types?? - if($_FILES['attachments'] && ($files=Format::files($_FILES['attachments']))) - $ticket->uploadAttachments($files,$noteId,'N'); - //Set state: Error on state change not critical! - if(isset($_POST['note_ticket_state']) && $_POST['note_ticket_state']) { - if($ticket->setState($_POST['note_ticket_state']) && $ticket->reload()) { - $msg.=' and state changed to '.strtoupper($_POST['note_ticket_state']); - if($ticket->isClosed()) - $ticket=null; //Going back to main listing. - } - } - } elseif(!$errors['note']) { - $errors['note']='Error(s) occurred. Unable to post the note.'; + if($wasOpen && $ticket->isClosed()) + $ticket = null; //Going back to main listing. + } else { + $errors['err'] = 'Unable to post internal note - missing or invalid data.'; + $errors['postnote'] = 'Unable to post the note. Correct the error(s) below and try again!'; } break; case 'edit': @@ -180,13 +190,9 @@ if($_POST && !$errors): $note = $_POST['ticket_status_notes']; else $note='Ticket closed (without comments)'; - - $ticket->postNote('Ticket Closed', $note, $thisstaff); - //ban email? - - if(isset($_POST['banemail'])) - Banlist::add($ticket->getEmail(), $thisstaff->getName()); - + + $ticket->logNote('Ticket Closed', $note, $thisstaff); + //Going back to main listing. TicketLock::removeStaffLocks($thisstaff->getId(), $ticket->getId()); $page=$ticket=null; @@ -209,7 +215,8 @@ if($_POST && !$errors): else $note='Ticket reopened (without comments)'; - $ticket->postNote('Ticket Reopened', $note, $thisstaff); + $ticket->logNote('Ticket Reopened', $note, $thisstaff); + } else { $errors['err']='Problems reopening the ticket. Try again'; }