diff --git a/include/ajax.reports.php b/include/ajax.reports.php
index b9b5362f3ba2ff9b5034df6ce41db38af5fcc263..bdaa7d9fe3fb828fe7428ed7a2c4cb03101d328d 100644
--- a/include/ajax.reports.php
+++ b/include/ajax.reports.php
@@ -70,7 +70,7 @@ class OverviewReportAjaxAPI extends AjaxController {
                       (T1.staff_id='.db_input($thisstaff->getId())
                         .(($depts=$thisstaff->getManagedDepartments())?
                             (' OR T1.dept_id IN('.implode(',', db_input($depts)).')'):'')
-                        .(($thisstaff->canViewStaffStats())?
+                        .(($thisstaff->getRole()->canViewStaffStats())?
                             (' OR T1.dept_id IN('.implode(',', db_input($thisstaff->getDepts())).')'):'')
                      .')'
                      )
diff --git a/include/ajax.tickets.php b/include/ajax.tickets.php
index d8fccf5dc451aa81a673e56627f00e7c82e25854..196bcc390e7147479bc5fd073dfaef3ec25e331b 100644
--- a/include/ajax.tickets.php
+++ b/include/ajax.tickets.php
@@ -536,6 +536,8 @@ class TicketsAjaxAPI extends AjaxController {
                 || !$ticket->checkStaffAccess($thisstaff))
             Http::response(404, 'Unknown ticket #');
 
+        $role = $thisstaff->getRole($ticket->getDeptId());
+
         $info = array();
         $state = null;
         switch($status) {
@@ -544,12 +546,12 @@ class TicketsAjaxAPI extends AjaxController {
                 $state = 'open';
                 break;
             case 'close':
-                if (!$thisstaff->canCloseTickets())
+                if (!$role->canCloseTickets())
                     Http::response(403, 'Access denied');
                 $state = 'closed';
                 break;
             case 'delete':
-                if (!$thisstaff->canDeleteTickets())
+                if (!$role->canDeleteTickets())
                     Http::response(403, 'Access denied');
                 $state = 'deleted';
                 break;
@@ -584,20 +586,21 @@ class TicketsAjaxAPI extends AjaxController {
                     __($status->getName()));
         else {
             // Make sure the agent has permission to set the status
+            $role = $thisstaff->getRole($ticket->getDeptId());
             switch(mb_strtolower($status->getState())) {
                 case 'open':
-                    if (!$thisstaff->canCloseTickets()
-                            && !$thisstaff->canCreateTickets())
+                    if (!$role->canCloseTickets()
+                            && !$role->canCreateTickets())
                         $errors['err'] = sprintf(__('You do not have permission %s.'),
                                 __('to reopen tickets'));
                     break;
                 case 'closed':
-                    if (!$thisstaff->canCloseTickets())
+                    if (!$role->canCloseTickets())
                         $errors['err'] = sprintf(__('You do not have permission %s.'),
                                 __('to resolve/close tickets'));
                     break;
                 case 'deleted':
-                    if (!$thisstaff->canDeleteTickets())
+                    if (!$role->canDeleteTickets())
                         $errors['err'] = sprintf(__('You do not have permission %s.'),
                                 __('to archive/delete tickets'));
                     break;
diff --git a/include/class.nav.php b/include/class.nav.php
index 30300468fb51e058e32183a82c08928e176a7a68..551d6265be765983d602570863eda20733500dca 100644
--- a/include/class.nav.php
+++ b/include/class.nav.php
@@ -161,9 +161,9 @@ class StaffNav {
                 case 'kbase':
                     $subnav[]=array('desc'=>__('FAQs'),'href'=>'kb.php', 'urls'=>array('faq.php'), 'iconclass'=>'kb');
                     if($staff) {
-                        if($staff->canManageFAQ())
+                        if($staff->getRole()->canManageFAQ())
                             $subnav[]=array('desc'=>__('Categories'),'href'=>'categories.php','iconclass'=>'faq-categories');
-                        if($staff->canManageCannedResponses())
+                        if($staff->getRole()->canManageCannedResponses())
                             $subnav[]=array('desc'=>__('Canned Responses'),'href'=>'canned.php','iconclass'=>'canned');
                     }
                    break;
diff --git a/include/class.role.php b/include/class.role.php
index ff3a238e8fcea62db2a58d0b4a314e26cb22c711..36ea3f9a5a74eac80e077ef46221b6e300f8c9b3 100644
--- a/include/class.role.php
+++ b/include/class.role.php
@@ -103,6 +103,16 @@ class Role extends RoleModel {
         return (string) $this->getName();
     }
 
+    function __call($what, $args) {
+        $rv = null;
+        if($this->getPermission() && is_callable(array($this->_perm, $what)))
+            $rv = $args
+                ? call_user_func_array(array($this->_perm, $what), $args)
+                : call_user_func(array($this->_perm, $what));
+
+        return $rv;
+    }
+
     private function updatePerms($vars, &$errors=array()) {
 
         $config = array();
@@ -275,5 +285,64 @@ class RolePermission extends Config {
         return static::$_permissions;
     }
 
+    function get($var) {
+        return (bool) parent::get($var);
+    }
+
+    /* tickets */
+    function canCreateTickets() {
+        return ($this->get('ticket.create'));
+    }
+
+    function canEditTickets() {
+        return ($this->get('ticket.edit'));
+    }
+
+    function canAssignTickets() {
+        return ($this->get('ticket.assign'));
+    }
+
+    function canTransferTickets() {
+        return ($this->get('ticket.transfer'));
+    }
+
+    function canPostReply() {
+        return ($this->get('ticket.reply'));
+    }
+
+    function canCloseTickets() {
+        return ($this->get('ticket.close'));
+    }
+
+    function canDeleteTickets() {
+        return ($this->get('ticket.delete'));
+    }
+
+    /* Knowledge base */
+    function canManagePremade() {
+        return ($this->get('kb.premade'));
+    }
+
+    function canManageCannedResponses() {
+        return ($this->canManagePremade());
+    }
+
+    function canManageFAQ() {
+        return ($this->get('kb.faq'));
+    }
+
+    function canManageFAQs() {
+        return ($this->canManageFAQ());
+    }
+
+    /* stats */
+    function canViewStaffStats() {
+        return ($this->get('stats.agents'));
+    }
+
+    /* email */
+    function canBanEmails() {
+        return ($this->get('emails.banlist'));
+    }
 }
 ?>
diff --git a/include/class.staff.php b/include/class.staff.php
index 01af86260fa795274201de4872e8ae8b7ed7a80f..d420ca6dab918bdc2c8d60e14f3be4287473086a 100644
--- a/include/class.staff.php
+++ b/include/class.staff.php
@@ -51,6 +51,7 @@ implements AuthenticatedUser {
     var $stats = array();
     var $_extra;
     var $passwd_change;
+    var $_roles = null;
     var $_teams = null;
 
     function __onload() {
@@ -268,6 +269,57 @@ implements AuthenticatedUser {
         return $this->locale;
     }
 
+    function getRole($dept=null) {
+
+        if ($dept) {
+            $deptId = is_object($dept) ? $dept->getId() : $dept;
+            if (isset($this->_roles[$deptId]))
+                return $this->_roles[$deptId];
+
+            if (($role=$this->group->getRole($deptId)))
+                return $this->_roles[$deptId] = $role;
+        }
+
+        return $this->group->getRole();
+    }
+
+    function hasPermission($perm) {
+        static $perms = null;
+        if (!isset($perms[$perm])) {
+            $perms[$perm] = false;
+            foreach($this->getDepartments() as $deptId) {
+                if (($role=$this->getRole($deptId))
+                        && $role->getPermission()
+                        && $role->getPermission()->get($perm))
+                    $perms[$perm] = true;
+            }
+        }
+
+        return $perms[$perm];
+    }
+
+    function canCreateTickets() {
+        return $this->hasPermission('ticket.create');
+    }
+
+    function canAssignTickets() {
+        return $this->hasPermission('ticket.create');
+    }
+
+    function canCloseTickets() {
+        return $this->hasPermission('ticket.close');
+    }
+
+    function canDeleteTickets() {
+        return $this->hasPermission('ticket.delete');
+    }
+
+    function canManageTickets() {
+        return ($this->isAdmin()
+                || $this->canDeleteTickets()
+                || $this->canCloseTickets());
+    }
+
     function isManager() {
         return (($dept=$this->getDept()) && $dept->getManagerId()==$this->getId());
     }
@@ -316,6 +368,7 @@ implements AuthenticatedUser {
         return ($deptId && in_array($deptId, $this->getDepts()) && !$this->isAccessLimited());
     }
 
+<<<<<<< HEAD
     function canCreateTickets() {
         return $this->group->can_create_tickets;
     }
@@ -378,6 +431,8 @@ implements AuthenticatedUser {
         return $this->show_assigned_tickets;
     }
 
+=======
+>>>>>>> 5847307... roles : Implement role-based access system-wide
     function getTeams() {
 
         if (!isset($this->_teams)) {
diff --git a/include/class.team.php b/include/class.team.php
index 7784d87bc842db4fb9bac561c89b70c6bdb62908..b7bd6a5026bb1991f04e8e58f55dd55208d660f9 100644
--- a/include/class.team.php
+++ b/include/class.team.php
@@ -229,7 +229,8 @@ class Team extends VerySimpleModel {
                 list($id, $name, $enabled) = $row;
                 $items[$id] = sprintf('%s%s',
                     self::getLocalById($id, 'name', $name),
-                    $enabled ? '' : ' ' . __('(disabled)'));
+                    ($enabled || isset($criteria['active']))
+                        ? '' : ' ' . __('(disabled)'));
             }
 
             //TODO: sort if $criteria['localize'];
diff --git a/include/class.ticket.php b/include/class.ticket.php
index a4afc52f9e2b6733ab853b66f47274760840f0c3..38f751a15a81acc12015e26dbe1866348790061a 100644
--- a/include/class.ticket.php
+++ b/include/class.ticket.php
@@ -182,10 +182,10 @@ class Ticket {
         if(!$id && !($id=$this->getId()))
             return false;
 
-        $sql='SELECT  ticket.*, lock_id, dept_name '
+        $sql='SELECT  ticket.*, lock_id, dept.name as dept_name '
             .' ,count(distinct attach.attach_id) as attachments'
             .' FROM '.TICKET_TABLE.' ticket '
-            .' LEFT JOIN '.DEPT_TABLE.' dept ON (ticket.dept_id=dept.dept_id) '
+            .' LEFT JOIN '.DEPT_TABLE.' dept ON (ticket.dept_id=dept.id) '
             .' LEFT JOIN '.SLA_TABLE.' sla ON (ticket.sla_id=sla.id AND sla.isactive=1) '
             .' LEFT JOIN '.TICKET_LOCK_TABLE.' tlock
                 ON ( ticket.ticket_id=tlock.ticket_id AND tlock.expire>NOW()) '
@@ -980,15 +980,29 @@ class Ticket {
     function setStatus($status, $comments='', &$errors=array()) {
         global $thisstaff;
 
+        if (!$thisstaff || !($role=$thisstaff->getRole($this->getDeptId())))
+            return false;
+
         if ($status && is_numeric($status))
             $status = TicketStatus::lookup($status);
 
         if (!$status || !$status instanceof TicketStatus)
             return false;
 
-        // XXX: intercept deleted status and do hard delete
-        if (!strcasecmp($status->getState(), 'deleted'))
-            return $this->delete($comments);
+        // Double check permissions
+        switch ($status->getState()) {
+        case 'closed':
+            if (!($role->canCloseTickets()))
+                return false;
+            break;
+        case 'deleted':
+            // XXX: intercept deleted status and do hard delete
+            if ($role->canDeleteTickets())
+                return $this->delete($comments);
+            // Agent doesn't have permission to delete  tickets
+            return false;
+            break;
+        }
 
         if ($this->getStatusId() == $status->getId())
             return true;
@@ -996,6 +1010,7 @@ class Ticket {
         $sql = 'UPDATE '.TICKET_TABLE.' SET updated=NOW() '.
                ' ,status_id='.db_input($status->getId());
 
+        //TODO: move this up.
         $ecb = null;
         switch($status->getState()) {
             case 'closed':
@@ -1593,7 +1608,9 @@ class Ticket {
 
         global $cfg, $thisstaff;
 
-        if(!$thisstaff || !$thisstaff->canTransferTickets())
+        if(!$thisstaff
+                || !($role=$thisstaff->getRole($this->getDeptId()))
+                || !$role->canTransferTickets())
             return false;
 
         $currentDept = $this->getDeptName(); //Current department
@@ -1745,7 +1762,8 @@ class Ticket {
 
         if (!$user
                 || ($user->getId() == $this->getOwnerId())
-                || !$thisstaff->canEditTickets())
+                || !($role=$thisstaff->getRole($this->getDeptId()))
+                || !$role->canEditTickets())
             return false;
 
         $sql ='UPDATE '.TICKET_TABLE.' SET updated = NOW() '
@@ -2224,7 +2242,10 @@ class Ticket {
 
         global $cfg, $thisstaff;
 
-        if(!$cfg || !$thisstaff || !$thisstaff->canEditTickets())
+        if (!$cfg
+                || !$thisstaff
+                || !($role=$thisstaff->getRole($this->getDeptId()))
+                || !$role->canEditTickets())
             return false;
 
         $fields=array();
@@ -2926,7 +2947,7 @@ class Ticket {
     static function open($vars, &$errors) {
         global $thisstaff, $cfg;
 
-        if(!$thisstaff || !$thisstaff->canCreateTickets()) return false;
+        if (!$thisstaff || !$thisstaff->canCreateTickets()) return false;
 
         if($vars['source'] && !in_array(strtolower($vars['source']),array('email','phone','other')))
             $errors['source']=sprintf(__('Invalid source given - %s'),Format::htmlchars($vars['source']));
@@ -2943,6 +2964,9 @@ class Ticket {
         if (!$thisstaff->canAssignTickets())
             unset($vars['assignId']);
 
+        //TODO: Deny action based on selected department.
+
+
         $create_vars = $vars;
         $tform = TicketForm::objects()->one()->getForm($create_vars);
         $create_vars['cannedattachments']
@@ -2953,16 +2977,19 @@ class Ticket {
 
         $vars['msgId']=$ticket->getLastMsgId();
 
+        // Effective role for the department
+        $role = $thisstaff->getRole($ticket->getDeptId());
+
         // post response - if any
         $response = null;
-        if($vars['response'] && $thisstaff->canPostReply()) {
+        if($vars['response'] && $role->canPostReply()) {
 
             $vars['response'] = $ticket->replaceVars($vars['response']);
             // $vars['cannedatachments'] contains the attachments placed on
             // the response form.
             if(($response=$ticket->postReply($vars, $errors, false))) {
                 //Only state supported is closed on response
-                if(isset($vars['ticket_state']) && $thisstaff->canCloseTickets())
+                if(isset($vars['ticket_state']) && $role->canCloseTickets())
                     $ticket->setState($vars['ticket_state']);
             }
         }
diff --git a/include/staff/category.inc.php b/include/staff/category.inc.php
index f96fc6019d9563ed94e72706fd41042f44719c3c..dc0eaf086d51d997ba2659f985d93b873d408b61 100644
--- a/include/staff/category.inc.php
+++ b/include/staff/category.inc.php
@@ -1,5 +1,5 @@
 <?php
-if(!defined('OSTSCPINC') || !$thisstaff || !$thisstaff->canManageFAQ()) die('Access Denied');
+if(!defined('OSTSCPINC') || !$thisstaff || !$thisstaff->getRole()->canManageFAQ()) die('Access Denied');
 $info=array();
 $qstr='';
 if($category && $_REQUEST['a']!='add'){
diff --git a/include/staff/faq-category.inc.php b/include/staff/faq-category.inc.php
index 8ff80af13b9a0be313d561ea17af13a4bf14cd65..f4edf2d9a1f33f088e5d8c48ce23890deeefcaa1 100644
--- a/include/staff/faq-category.inc.php
+++ b/include/staff/faq-category.inc.php
@@ -17,7 +17,7 @@ if(!defined('OSTSTAFFINC') || !$category || !$thisstaff) die('Access Denied');
 <?php echo Format::display($category->getDescription()); ?>
 </div>
 <?php
-if($thisstaff->canManageFAQ()) {
+if($thisstaff->getRole()->canManageFAQ()) {
     echo sprintf('<div class="cat-manage-bar"><a href="categories.php?id=%d" class="Icon editCategory">'.__('Edit Category').'</a>
              <a href="categories.php" class="Icon deleteCategory">'.__('Delete Category').'</a>
              <a href="faq.php?cid=%d&a=add" class="Icon newFAQ">'.__('Add New FAQ').'</a></div>',
diff --git a/include/staff/faq-view.inc.php b/include/staff/faq-view.inc.php
index 7b120f0d21aab98d411e024015ec1892ad26de40..2c20b6dcb793727089e49db063fa4afab3417fed 100644
--- a/include/staff/faq-view.inc.php
+++ b/include/staff/faq-view.inc.php
@@ -79,7 +79,7 @@ $query = http_build_query($query); ?>
         echo __('Print'); ?>
     </a></button>
 <?php
-if ($thisstaff->canManageFAQ()) { ?>
+if ($thisstaff->getRole()->canManageFAQ()) { ?>
     <button>
     <i class="icon-edit"></i>
     <a href="faq.php?id=<?php echo $faq->getId(); ?>&a=edit"><?php
@@ -104,7 +104,7 @@ if ($thisstaff->canManageFAQ()) { ?>
 <hr>
 
 <?php
-if ($thisstaff->canManageFAQ()) { ?>
+if ($thisstaff->getRole()->canManageFAQ()) { ?>
 <form action="faq.php?id=<?php echo  $faq->getId(); ?>" method="post">
     <?php csrf_token(); ?>
     <input type="hidden" name="do" value="manage-faq">
diff --git a/include/staff/faq.inc.php b/include/staff/faq.inc.php
index 5e32630d014942c0a4d2cad5b6a5629371dac19f..01b404b3fc6115970a46e332797164635813b618 100644
--- a/include/staff/faq.inc.php
+++ b/include/staff/faq.inc.php
@@ -1,5 +1,5 @@
 <?php
-if(!defined('OSTSCPINC') || !$thisstaff || !$thisstaff->canManageFAQ()) die('Access Denied');
+if(!defined('OSTSCPINC') || !$thisstaff || !$thisstaff->getRole()->canManageFAQ()) die('Access Denied');
 $info=array();
 $qstr='';
 if($faq){
diff --git a/include/staff/staffmembers.inc.php b/include/staff/staffmembers.inc.php
index 9360ffa6ea08ed206d5c1ec5c80892fb91dcfc1c..fe312a01f043c3918cfd9d547dee5d5f397e99fe 100644
--- a/include/staff/staffmembers.inc.php
+++ b/include/staff/staffmembers.inc.php
@@ -156,7 +156,7 @@ $agents->limit($pageNav->getLimit())->offset($pageNav->getStart());
                 <td><?php echo $agent->getUserName(); ?></td>
                 <td><?php echo $agent->isActive() ? __('Active') :'<b>'.__('Locked').'</b>'; ?>&nbsp;<?php
                     echo $agent->onvacation ? '<small>(<i>'.__('vacation').'</i>)</small>' : ''; ?></td>
-                <td><a href="groups.php?id=<?php echo $agent->getGroupId(); ?>"><?php
+                <td><a href="groups.php?id=<?php echo $agent->group_id; ?>"><?php
                     echo Format::htmlchars('FIXME'/*$agent->group->getName()*/); ?></a></td>
                 <td><a href="departments.php?id=<?php echo
                     $agent->getDeptId(); ?>"><?php
diff --git a/include/staff/templates/ticket-preview.tmpl.php b/include/staff/templates/ticket-preview.tmpl.php
index 4d6e301961aa4bdccc56b78e01577ad91eb94759..55276c6d62b9d01aad30773a532d672295eb805a 100644
--- a/include/staff/templates/ticket-preview.tmpl.php
+++ b/include/staff/templates/ticket-preview.tmpl.php
@@ -6,6 +6,7 @@
 
 $staff=$ticket->getStaff();
 $lock=$ticket->getLock();
+$role=$thisstaff->getRole($ticket->getDeptId());
 $error=$msg=$warn=null;
 
 if($lock && $lock->getStaffId()==$thisstaff->getId())
@@ -154,15 +155,15 @@ if($ticket->getNumNotes())
 if($ticket->isOpen())
     $options[]=array('action'=>__('Reply'),'url'=>"tickets.php?id=$tid#reply");
 
-if($thisstaff->canAssignTickets())
+if ($role->canAssignTickets())
     $options[]=array('action'=>($ticket->isAssigned()?__('Reassign'):__('Assign')),'url'=>"tickets.php?id=$tid#assign");
 
-if($thisstaff->canTransferTickets())
+if ($role->canTransferTickets())
     $options[]=array('action'=>__('Transfer'),'url'=>"tickets.php?id=$tid#transfer");
 
 $options[]=array('action'=>__('Post Note'),'url'=>"tickets.php?id=$tid#note");
 
-if($thisstaff->canEditTickets())
+if ($role->canEditTickets())
     $options[]=array('action'=>__('Edit Ticket'),'url'=>"tickets.php?id=$tid&a=edit");
 
 if($options) {
diff --git a/include/staff/ticket-edit.inc.php b/include/staff/ticket-edit.inc.php
index ca63955bbf3970a0cfb6bf2b5e82613f3c5ff48e..5b464cdca0a2b2997e37125b4b810026ffaae02e 100644
--- a/include/staff/ticket-edit.inc.php
+++ b/include/staff/ticket-edit.inc.php
@@ -1,5 +1,10 @@
 <?php
-if(!defined('OSTSCPINC') || !$thisstaff || !$thisstaff->canEditTickets() || !$ticket) die('Access Denied');
+if (!defined('OSTSCPINC')
+        || !$thisstaff
+        || !$ticket
+        || !($role=$thisstaff->getRole($ticket->getDeptId()))
+        || !$role->canEditTickets())
+    die('Access Denied');
 
 $info=Format::htmlchars(($errors && $_POST)?$_POST:$ticket->getUpdateInfo());
 if ($_POST)
diff --git a/include/staff/ticket-open.inc.php b/include/staff/ticket-open.inc.php
index 0c0c6dfe2b61199b0ac658ef82cc2588910ec0a5..9af71ea08c13084ff2aa55c4e25d8f6c87ac4ddc 100644
--- a/include/staff/ticket-open.inc.php
+++ b/include/staff/ticket-open.inc.php
@@ -272,7 +272,7 @@ if ($_POST)
         <tbody>
         <?php
         //is the user allowed to post replies??
-        if($thisstaff->canPostReply()) { ?>
+        if($thisstaff->getRole()->canPostReply()) { ?>
         <tr>
             <th colspan="2">
                 <em><strong><?php echo __('Response');?></strong>: <?php echo __('Optional response to the above issue.');?></em>
diff --git a/include/staff/ticket-view.inc.php b/include/staff/ticket-view.inc.php
index 207d573c5da4c312a1f7ba9448167cfb2a7dec72..f3ab38354b3c3b186fa0f04260df8e3342046fb3 100644
--- a/include/staff/ticket-view.inc.php
+++ b/include/staff/ticket-view.inc.php
@@ -14,6 +14,7 @@ if($cfg->getLockTime() && !$ticket->acquireLock($thisstaff->getId(),$cfg->getLoc
 
 //Get the goodies.
 $dept  = $ticket->getDept();  //Dept
+$role  = $thisstaff->getRole($dept);
 $staff = $ticket->getStaff(); //Assigned or closed by..
 $user  = $ticket->getOwner(); //Ticket User (EndUser)
 $team  = $ticket->getTeam();  //Assigned team.
@@ -59,8 +60,8 @@ if($ticket->isOverdue())
         </td>
         <td width="auto" class="flush-right has_bottom_border">
             <?php
-            if ($thisstaff->canBanEmails()
-                    || $thisstaff->canEditTickets()
+            if ($role->canBanEmails()
+                    || $role->canEditTickets()
                     || ($dept && $dept->isManager($thisstaff))) { ?>
             <span class="action-button pull-right" data-dropdown="#action-dropdown-more">
                 <i class="icon-caret-down pull-right"></i>
@@ -71,12 +72,12 @@ if($ticket->isOverdue())
             // Status change options
             echo TicketStatus::status_options();
 
-            if ($thisstaff->canEditTickets()) { ?>
+            if ($role->canEditTickets()) { ?>
                 <a class="action-button pull-right" href="tickets.php?id=<?php echo $ticket->getId(); ?>&a=edit"><i class="icon-edit"></i> <?php
                     echo __('Edit'); ?></a>
             <?php
             }
-            if ($ticket->isOpen() && !$ticket->isAssigned() && $thisstaff->canAssignTickets()) {?>
+            if ($ticket->isOpen() && !$ticket->isAssigned() && $role->canAssignTickets()) {?>
                 <a id="ticket-claim" class="action-button pull-right confirm-action" href="#claim"><i class="icon-user"></i> <?php
                     echo __('Claim'); ?></a>
 
@@ -98,13 +99,13 @@ if($ticket->isOverdue())
             <div id="action-dropdown-more" class="action-dropdown anchor-right">
               <ul>
                 <?php
-                 if($thisstaff->canEditTickets()) { ?>
+                 if ($role->canEditTickets()) { ?>
                     <li><a class="change-user" href="#tickets/<?php
                     echo $ticket->getId(); ?>/change-user"><i class="icon-user"></i> <?php
                     echo __('Change Owner'); ?></a></li>
                 <?php
                  }
-                 if($thisstaff->canDeleteTickets()) {
+                 if ($role->canDeleteTickets()) {
                      ?>
                     <li><a class="ticket-action" href="#tickets/<?php
                     echo $ticket->getId(); ?>/status/delete"
@@ -142,7 +143,7 @@ if($ticket->isOverdue())
                     return false"
                     ><i class="icon-paste"></i> <?php echo __('Manage Forms'); ?></a></li>
 
-<?php           if($thisstaff->canBanEmails()) {
+<?php           if ($role->canBanEmails()) {
                      if(!$emailBanned) {?>
                         <li><a class="confirm-action" id="ticket-banemail"
                             href="#banemail"><i class="icon-ban-circle"></i> <?php echo sprintf(
@@ -446,24 +447,24 @@ $tcount+= $ticket->getNumNotes();
 <div id="response_options">
     <ul class="tabs">
         <?php
-        if($thisstaff->canPostReply()) { ?>
+        if ($role->canPostReply()) { ?>
         <li><a id="reply_tab" href="#reply"><?php echo __('Post Reply');?></a></li>
         <?php
         } ?>
         <li><a id="note_tab" href="#note"><?php echo __('Post Internal Note');?></a></li>
         <?php
-        if($thisstaff->canTransferTickets()) { ?>
+        if ($role->canTransferTickets()) { ?>
         <li><a id="transfer_tab" href="#transfer"><?php echo __('Department Transfer');?></a></li>
         <?php
         }
 
-        if($thisstaff->canAssignTickets()) { ?>
+        if ($role->canAssignTickets()) { ?>
         <li><a id="assign_tab" href="#assign"><?php echo $ticket->isAssigned()?__('Reassign Ticket'):__('Assign Ticket'); ?></a></li>
         <?php
         } ?>
     </ul>
     <?php
-    if($thisstaff->canPostReply()) { ?>
+    if ($role->canPostReply()) { ?>
     <form id="reply" class="tab_content" action="tickets.php?id=<?php echo $ticket->getId(); ?>#reply" name="reply" method="post" enctype="multipart/form-data">
         <?php csrf_token(); ?>
         <input type="hidden" name="id" value="<?php echo $ticket->getId(); ?>">
@@ -621,7 +622,7 @@ print $response_form->getField('attachments')->render();
                     <?php
                     $statusId = $info['reply_status_id'] ?: $ticket->getStatusId();
                     $states = array('open');
-                    if ($thisstaff->canCloseTickets() && !$outstanding)
+                    if ($role->canCloseTickets() && !$outstanding)
                         $states = array_merge($states, array('closed'));
 
                     foreach (TicketStatusList::getStatuses(
@@ -704,7 +705,7 @@ print $note_form->getField('attachments')->render();
                         <?php
                         $statusId = $info['note_status_id'] ?: $ticket->getStatusId();
                         $states = array('open');
-                        if ($thisstaff->canCloseTickets())
+                        if ($role->canCloseTickets())
                             $states = array_merge($states, array('closed'));
                         foreach (TicketStatusList::getStatuses(
                                     array('states' => $states)) as $s) {
@@ -730,7 +731,7 @@ print $note_form->getField('attachments')->render();
        </p>
    </form>
     <?php
-    if($thisstaff->canTransferTickets()) { ?>
+    if ($role->canTransferTickets()) { ?>
     <form id="transfer" class="tab_content" action="tickets.php?id=<?php echo $ticket->getId(); ?>#transfer" name="transfer" method="post" enctype="multipart/form-data">
         <?php csrf_token(); ?>
         <input type="hidden" name="ticket_id" value="<?php echo $ticket->getId(); ?>">
@@ -790,7 +791,7 @@ print $note_form->getField('attachments')->render();
     <?php
     } ?>
     <?php
-    if($thisstaff->canAssignTickets()) { ?>
+    if ($role->canAssignTickets()) { ?>
     <form id="assign" class="tab_content" action="tickets.php?id=<?php echo $ticket->getId(); ?>#assign" name="assign" method="post" enctype="multipart/form-data">
         <?php csrf_token(); ?>
         <input type="hidden" name="id" value="<?php echo $ticket->getId(); ?>">
diff --git a/scp/canned.php b/scp/canned.php
index 5de2f87b50e128d08c615275f9c6e2e25b5d14e8..d6a9ffa9af4858d4a0c8585d09daf4575ea85007 100644
--- a/scp/canned.php
+++ b/scp/canned.php
@@ -17,7 +17,7 @@ require('staff.inc.php');
 include_once(INCLUDE_DIR.'class.canned.php');
 
 /* check permission */
-if(!$thisstaff || !$thisstaff->canManageCannedResponses()) {
+if(!$thisstaff || !$thisstaff->getRole()->canManageCannedResponses()) {
     header('Location: kb.php');
     exit;
 }
@@ -35,7 +35,7 @@ $canned_form = new Form(array(
    )),
 ));
 
-if($_POST && $thisstaff->canManageCannedResponses()) {
+if($_POST && $thisstaff->getRole()->canManageCannedResponses()) {
     switch(strtolower($_POST['do'])) {
         case 'update':
             if(!$canned) {
diff --git a/scp/categories.php b/scp/categories.php
index 422ec184135fe7a1dc6af185d02aa3a8b6a135cb..059e52d8064cfd12b6df0167e17ae299bcd2eede 100644
--- a/scp/categories.php
+++ b/scp/categories.php
@@ -17,7 +17,7 @@ require('staff.inc.php');
 include_once(INCLUDE_DIR.'class.category.php');
 
 /* check permission */
-if(!$thisstaff || !$thisstaff->canManageFAQ()) {
+if(!$thisstaff || !$thisstaff->getRole()->canManageFAQ()) {
     header('Location: kb.php');
     exit;
 }
diff --git a/scp/faq.php b/scp/faq.php
index 196b0862b1a2f7bb1e0b89e58bc099c40e634b22..322420fd796e389b8a7f1b19b5203ae1332db4e0 100644
--- a/scp/faq.php
+++ b/scp/faq.php
@@ -153,11 +153,11 @@ else {
 $inc='faq-categories.inc.php'; //FAQs landing page.
 if($faq) {
     $inc='faq-view.inc.php';
-    if($_REQUEST['a']=='edit' && $thisstaff->canManageFAQ())
+    if($_REQUEST['a']=='edit' && $thisstaff->getRole()->canManageFAQ())
         $inc='faq.inc.php';
     elseif ($_REQUEST['a'] == 'print')
         return $faq->printPdf();
-}elseif($_REQUEST['a']=='add' && $thisstaff->canManageFAQ()) {
+}elseif($_REQUEST['a']=='add' && $thisstaff->getRole()->canManageFAQ()) {
     $inc='faq.inc.php';
 } elseif($category && $_REQUEST['a']!='search') {
     $inc='faq-category.inc.php';
diff --git a/scp/tickets.php b/scp/tickets.php
index 36f075bc15c125cbb4ab2332ab9a7f1e340c8e80..f65cfd4c189bfd828d4531c5a4d1a7c25c80c9b2 100644
--- a/scp/tickets.php
+++ b/scp/tickets.php
@@ -58,9 +58,10 @@ if($_POST && !$errors):
         //More coffee please.
         $errors=array();
         $lock=$ticket->getLock(); //Ticket lock if any
+        $role = $thistaff->getRole($ticket->getDeptId);
         switch(strtolower($_POST['a'])):
         case 'reply':
-            if(!$thisstaff->canPostReply())
+            if(!$role || !$role->canPostReply())
                 $errors['err'] = __('Action denied. Contact admin for access');
             else {
 
@@ -108,7 +109,7 @@ if($_POST && !$errors):
             break;
         case 'transfer': /** Transfer ticket **/
             //Check permission
-            if(!$thisstaff->canTransferTickets())
+            if(!$role->canTransferTickets())
                 $errors['err']=$errors['transfer'] = __('Action Denied. You are not allowed to transfer tickets.');
             else {
 
@@ -141,7 +142,7 @@ if($_POST && !$errors):
             break;
         case 'assign':
 
-             if(!$thisstaff->canAssignTickets())
+             if(!$role->canAssignTickets())
                  $errors['err']=$errors['assign'] = __('Action Denied. You are not allowed to assign/reassign tickets.');
              else {
 
@@ -212,7 +213,7 @@ if($_POST && !$errors):
             break;
         case 'edit':
         case 'update':
-            if(!$ticket || !$thisstaff->canEditTickets())
+            if(!$ticket || !$role->canEditTickets())
                 $errors['err']=__('Permission Denied. You are not allowed to edit tickets');
             elseif($ticket->update($_POST,$errors)) {
                 $msg=__('Ticket updated successfully');
@@ -240,7 +241,7 @@ if($_POST && !$errors):
                     }
                     break;
                 case 'claim':
-                    if(!$thisstaff->canAssignTickets()) {
+                    if(!$role->canAssignTickets()) {
                         $errors['err'] = __('Permission Denied. You are not allowed to assign/claim tickets.');
                     } elseif(!$ticket->isOpen()) {
                         $errors['err'] = __('Only open tickets can be assigned');
@@ -286,7 +287,7 @@ if($_POST && !$errors):
                     }
                     break;
                 case 'banemail':
-                    if(!$thisstaff->canBanEmails()) {
+                    if(!$role->canBanEmails()) {
                         $errors['err']=__('Permission Denied. You are not allowed to ban emails');
                     } elseif(BanList::includes($ticket->getEmail())) {
                         $errors['err']=__('Email already in banlist');
@@ -297,7 +298,7 @@ if($_POST && !$errors):
                     }
                     break;
                 case 'unbanemail':
-                    if(!$thisstaff->canBanEmails()) {
+                    if(!$role->canBanEmails()) {
                         $errors['err'] = __('Permission Denied. You are not allowed to remove emails from banlist.');
                     } elseif(Banlist::remove($ticket->getEmail())) {
                         $msg = __('Email removed from banlist');
@@ -308,7 +309,7 @@ if($_POST && !$errors):
                     }
                     break;
                 case 'changeuser':
-                    if (!$thisstaff->canEditTickets()) {
+                    if (!$role->canEditTickets()) {
                         $errors['err']=__('Permission Denied. You are not allowed to edit tickets');
                     } elseif (!$_POST['user_id'] || !($user=User::lookup($_POST['user_id']))) {
                         $errors['err'] = __('Unknown user selected');
@@ -471,7 +472,8 @@ if($ticket) {
     $ost->setPageTitle(sprintf(__('Ticket #%s'),$ticket->getNumber()));
     $nav->setActiveSubMenu(-1);
     $inc = 'ticket-view.inc.php';
-    if($_REQUEST['a']=='edit' && $thisstaff->canEditTickets()) {
+    if ($_REQUEST['a']=='edit'
+            && $thisstaff->getRole($ticket->getDeptId())->canEditTickets()) {
         $inc = 'ticket-edit.inc.php';
         if (!$forms) $forms=DynamicFormEntry::forTicket($ticket->getId());
         // Auto add new fields to the entries