diff --git a/include/class.dept.php b/include/class.dept.php index 397df89c480b7fafa20ba09a51cd6dfa41fca78c..93f92d754ad613b3afe4ad7b3b9655ba211b6d15 100644 --- a/include/class.dept.php +++ b/include/class.dept.php @@ -51,6 +51,9 @@ implements TemplateVariable { ); var $_members; + var $_primary_members; + var $_extended_members; + var $_groupids; var $config; @@ -182,16 +185,8 @@ implements TemplateVariable { 'onvacation' => 0, )); } - switch ($cfg->getAgentNameFormat()) { - case 'last': - case 'lastfirst': - case 'legal': - $members->order_by('lastname', 'firstname'); - break; - - default: - $members->order_by('firstname', 'lastname'); - } + + $members = Staff::nsort($members); if ($criteria) return $members; @@ -205,6 +200,42 @@ implements TemplateVariable { return $this->getMembers(array('available'=>1)); } + function getPrimaryMembers() { + + if (!isset($this->_primary_members)) { + $members = clone $this->getMembers(); + $members->filter(array('dept_id' =>$this->getId())); + $members = Staff::nsort($members); + $this->_primary_members = $members->all(); + } + + return $this->_primary_members; + } + + function getExtendedMembers() { + + if (!isset($this->_exended_members)) { + // We need a query set so we can sort the names + $members = StaffDeptAccess::objects(); + $members->filter(array('dept_id' => $this->getId())); + $members = Staff::nsort($members, 'staff__'); + $extended = array(); + foreach($members->all() as $member) { + if (!$member->staff) continue; + // Annoted the staff model with alerts and role + $extended[] = new AnnotatedModel($member->staff, array( + 'alerts' => $member->isAlertsEnabled(), + 'role_id' => $member->role_id, + ) + ); + } + + $this->_extended_members = $extended; + } + + return $this->_extended_members; + } + // Get members eligible members only function getAssignees() { @@ -305,10 +336,10 @@ implements TemplateVariable { if (is_object($staff)) $staff = $staff->getId(); - // Members are indexed by ID - $members = $this->getMembers(); + $members = $this->getMembers() ?: $this->members; - return ($members && isset($members[$staff])); + return ($members->findFirst(array( + 'staff_id' => $staff))); } function isPublic() { @@ -657,11 +688,21 @@ implements TemplateVariable { unset($dropped[$staff_id]); if (!$role_id || !Role::lookup($role_id)) $errors['members'][$staff_id] = __('Select a valid role'); - if (!$staff_id || !Staff::lookup($staff_id)) + if (!$staff_id || !($staff=Staff::lookup($staff_id))) $errors['members'][$staff_id] = __('No such agent'); + + if ($staff->dept_id == $this->id) { + + // If primary member then simply update the role. + if (($m = $this->members->findFirst(array( + 'staff_id' => $staff_id)))) + $m->role_id = $role_id; + continue; + } + $da = $this->extended->findFirst(array('staff_id' => $staff_id)); if (!isset($da)) { - $da = StaffDeptAccess::create(array( + $da = new StaffDeptAccess(array( 'staff_id' => $staff_id, 'role_id' => $role_id )); $this->extended->add($da); @@ -670,14 +711,24 @@ implements TemplateVariable { $da->role_id = $role_id; } $da->setAlerts($alerts); + } - if (!$errors && $dropped) { + + if ($errors) + return false; + + if ($dropped) { + $this->extended->saveAll(); $this->extended ->filter(array('staff_id__in' => array_keys($dropped))) ->delete(); $this->extended->reset(); } - return !$errors; + + // Save any role change. + $this->members->saveAll(); + + return true; } } diff --git a/include/class.staff.php b/include/class.staff.php index 6709bac0d90e6f71e5b71822315389e24e0b6dc6..b7e79b95f49b06ecb6432e364d3950a253915c53 100644 --- a/include/class.staff.php +++ b/include/class.staff.php @@ -782,16 +782,7 @@ implements AuthenticatedUser, EmailContact, TemplateVariable { )); } - switch ($cfg->getAgentNameFormat()) { - case 'last': - case 'lastfirst': - case 'legal': - $members->order_by('lastname', 'firstname'); - break; - - default: - $members->order_by('firstname', 'lastname'); - } + $members = self::nsort($members); $users=array(); foreach ($members as $M) { @@ -805,6 +796,23 @@ implements AuthenticatedUser, EmailContact, TemplateVariable { return self::getStaffMembers(array('available'=>true)); } + static function nsort(QuerySet $qs, $path='', $format=null) { + global $cfg; + + $format = $format ?: $cfg->getAgentNameFormat(); + switch ($format) { + case 'last': + case 'lastfirst': + case 'legal': + $qs->order_by("{$path}lastname", "{$path}firstname"); + break; + default: + $qs->order_by("${path}firstname", "${path}lastname"); + } + + return $qs; + } + static function getIdByUsername($username) { $row = static::objects()->filter(array('username' => $username)) ->values_flat('staff_id')->first(); @@ -1456,6 +1464,12 @@ extends AbstractForm { list($clean['username'],) = preg_split('/[^\w.-]/u', $clean['email'], 2); if (mb_strlen($clean['username']) < 3 || Staff::lookup($clean['username'])) $clean['username'] = mb_strtolower($clean['firstname']); + + + // Inherit default dept's role as primary role + $clean['assign_use_pri_role'] = true; + + // Default permissions $clean['perms'] = array( User::PERM_CREATE, User::PERM_EDIT, diff --git a/include/staff/department.inc.php b/include/staff/department.inc.php index 66e172a8f59c018842b43d8689d9a0740b528c68..865bcbb3d5c354085e1ef49243fb78d0271d2b17 100644 --- a/include/staff/department.inc.php +++ b/include/staff/department.inc.php @@ -318,7 +318,7 @@ $info = Format::htmlchars(($errors && $_POST) ? $_POST : $info); <div id="access" class="hidden tab_content"> <table class="two-column table" width="100%"> <tbody> - <tr class="header"> + <tr class="header" id="primary-members"> <td colspan="2"> <?php echo __('Department Members'); ?> <div><small> @@ -326,6 +326,23 @@ $info = Format::htmlchars(($errors && $_POST) ? $_POST : $info); </small></div> </td> </tr> + <?php + if (!count($dept->members)) { ?> + <tr><td colspan=2><em><?php + echo __('Department does not have primary members'); ?> + </em> </td> + </tr> + <?php + } ?> + </tbody> + <tbody> + <tr class="header" id="extended-access-members"> + <td colspan="2"> + <div><small> + <?php echo __('Agents who have extended access to this department'); ?> + </small></div> + </td> + </tr> <?php $agents = Staff::getStaffMembers(); foreach ($dept->getMembers() as $member) { @@ -387,26 +404,26 @@ foreach ($dept->getMembers() as $member) { <script type="text/javascript"> var addAccess = function(staffid, name, role, alerts, primary, error) { + if (!staffid) return; var copy = $('#member_template').clone(); - + var target = (primary) ? 'extended-access-members' : 'add_extended_access'; copy.find('td:first').append(document.createTextNode(name)); if (primary) { - copy.find('td:first').append($('<span class="faded">').text(primary)); - copy.find('td:last').empty(); + copy.find('a.drop-membership').remove(); } - else { copy.find('[data-name^=member_alerts]') .attr('name', 'member_alerts['+staffid+']') - .prop('checked', alerts); + .prop('disabled', (primary)) + .prop('checked', primary || alerts); copy.find('[data-name^=member_role]') .attr('name', 'member_role['+staffid+']') .val(role || 0); copy.find('[data-name=members\\[\\]]') .attr('name', 'members[]') .val(staffid); - } - copy.attr('id', '').show().insertBefore($('#add_extended_access')); + + copy.attr('id', '').show().insertBefore($('#'+target)); copy.removeClass('hidden') if (error) $('<div class="error">').text(error).appendTo(copy.find('td:last')); @@ -433,25 +450,27 @@ $('#add_extended_access').find('button').on('click', function() { <?php if ($dept) { - $members = $dept->members->all(); - foreach ($dept->extended as $x) { - if (!$x->staff) - continue; - $members[] = new AnnotatedModel($x->staff, array( - 'alerts' => $x->isAlertsEnabled(), - 'role_id' => $x->role_id, - )); + // Primary members + foreach ($dept->getPrimaryMembers() as $member) { + $primary = $member->dept_id == $info['id']; + echo sprintf('addAccess(%d, %s, %d, %d, %d, %s);', + $member->getId(), + JsonDataEncoder::encode((string) $member->getName()), + $member->role_id, + $member->get('alerts', 0), + ($member->dept_id == $info['id']) ? 1 : 0, + JsonDataEncoder::encode($errors['members'][$member->staff_id]) + ); } - usort($members, function($a, $b) { return strcmp($a->getName(), $b->getName()); }); - foreach ($members as $member) { - $primary = $member->dept_id == $info['id']; - echo sprintf('addAccess(%d, %s, %d, %d, %s, %s);', + // Extended members. + foreach ($dept->getExtendedMembers() as $member) { + echo sprintf('addAccess(%d, %s, %d, %d, %d, %s);', $member->getId(), JsonDataEncoder::encode((string) $member->getName()), $member->role_id, $member->get('alerts', 0), - JsonDataEncoder::encode($primary ? ' — '.__('Primary') : ''), + 0, JsonDataEncoder::encode($errors['members'][$member->staff_id]) ); } diff --git a/include/staff/staff.inc.php b/include/staff/staff.inc.php index bf2f925f4f522571e9b8d7f5125a048e28e4c2fb..c063948b75a68ed6e7ae6c9c4cac1adc8f1f410c 100644 --- a/include/staff/staff.inc.php +++ b/include/staff/staff.inc.php @@ -214,12 +214,13 @@ if (count($bks) > 1) { <tbody> <tr class="header"> <th colspan="3"> - <?php echo __('Primary Department and Role'); ?> - <span class="error">*</span> + <?php echo __('Access'); ?> <div><small><?php echo __( - "Select the departments the agent is allowed to access and optionally select an effective role." + "Select the departments the agent is allowed to access and the corresponding effective role." ); ?> - </small></div> + </small></div><br> + <div><?php echo __('Primary Department'); ?> <span + class="error">*</span></div> </th> </tr> <tr> @@ -256,7 +257,7 @@ if (count($bks) > 1) { if ($staff->usePrimaryRoleOnAssignment()) echo 'checked="checked"'; ?> /> - <?php echo __('Fall back to primary role on assigned tickets'); ?> + <?php echo __('Fall back to primary role on assignments'); ?> <i class="icon-question-sign help-tip" href="#primary_role_on_assign"></i> </label>