return false;
}
- // The getRoleID looks up a role by its rank.
+ // The getLegacyRole obtains a legacy role value for a role_id.
+ // This is a temporary function to allow usage of both old and new roles
+ // while new role code is being written and deployed.
+ static function getLegacyRole($role_id) {
+ global $user;
+ $mdb2 = getConnection();
+
+ $sql = "select rank from tt_roles where team_id = $user->team_id and id = $role_id";
+ $res = $mdb2->query($sql);
+
+ if (!is_a($res, 'PEAR_Error')) {
+ $val = $res->fetchRow();
+ if ($val['rank']) {
+ $rank = $val['rank'];
+ if ($rank >= ROLE_MANAGER)
+ return ROLE_MANAGER;
+ else if ($rank >= ROLE_COMANAGER)
+ return ROLE_COMANAGER;
+ else if ($rank >= ROLE_CLIENT)
+ return ROLE_CLIENT;
+ else
+ return ROLE_USER;
+ }
+ }
+ return false;
+ }
+
+ // isClientRole determines if the role is a "client" role.
+ // This simply means the role has no "data_entry" right.
+ static function isClientRole($role_id) {
+ global $user;
+ $mdb2 = getConnection();
+
+ $sql = "select rights from tt_roles where team_id = $user->team_id and id = $role_id";
+ $res = $mdb2->query($sql);
+
+ if (!is_a($res, 'PEAR_Error')) {
+ $val = $res->fetchRow();
+ if ($val['rights']) {
+ return !in_array('data_entry', explode(',', $val['rights']));
+ }
+ }
+ return false;
+ }
+
+ // getRoleByRank looks up a role by its rank.
static function getRoleByRank($rank) {
global $user;
$mdb2 = getConnection();
return false;
}
+ // getActiveRolesForUser - returns an array of relevant active roles for user with rank less than self.
+ // "Relevant" means that client roles are filtered out if Client plugin is disabled.
+ static function getActiveRolesForUser()
+ {
+ global $user;
+ $result = array();
+ $mdb2 = getConnection();
+
+ $sql = "select id, name, description, rank, rights from tt_roles where team_id = $user->team_id and rank < $user->rank and status = 1 order by rank";
+ $res = $mdb2->query($sql);
+ $result = array();
+ if (!is_a($res, 'PEAR_Error')) {
+ while ($val = $res->fetchRow()) {
+ $val['is_client'] = in_array('data_entry', explode(',', $val['rights'])) ? 0 : 1; // Clients do not have data entry right.
+ if ($val['is_client'] && !$user->isPluginEnabled('cl'))
+ continue; // Skip adding a client role/
+ $result[] = $val;
+ }
+ }
+ return $result;
+ }
+
// getActiveRoles - returns an array of active roles for team.
static function getActiveRoles($team_id)
{
$result = array();
$mdb2 = getConnection();
- $sql = "select id, name, rank, description from tt_roles where team_id = $team_id and status = 1 order by rank";
+ $sql = "select id, name, description, rank, rights from tt_roles where team_id = $team_id and status = 1 order by rank";
$res = $mdb2->query($sql);
$result = array();
if (!is_a($res, 'PEAR_Error')) {
while ($val = $res->fetchRow()) {
+ $val['is_client'] = in_array('data_entry', explode(',', $val['rights'])) ? 0 : 1; // Clients do not have data entry right.
$result[] = $val;
}
}
var $name = null; // User name.
var $id = null; // User id.
var $team_id = null; // Team id.
- var $role = null; // User role (user, client, comanager, manager, admin).
+ var $role = null; // User role (user, client, comanager, manager, admin). TODO: remove when new roles are done.
+ var $role_id = null; // Role id.
+ var $rank = null; // User role rank.
var $client_id = null; // Client id for client user role.
var $behalf_id = null; // User id, on behalf of whom we are working.
var $behalf_name = null; // User name, on behalf of whom we are working.
$mdb2 = getConnection();
- $sql = "SELECT u.id, u.login, u.name, u.team_id, u.role, u.client_id, u.email, t.name as team_name,
+ $sql = "SELECT u.id, u.login, u.name, u.team_id, u.role, u.role_id, r.rank, u.client_id, u.email, t.name as team_name,
t.currency, t.lang, t.decimal_mark, t.date_format, t.time_format, t.week_start,
t.tracking_mode, t.project_required, t.task_required, t.record_type,
t.bcc_email, t.plugins, t.config, t.lock_spec, t.workday_minutes, t.custom_logo
- FROM tt_users u LEFT JOIN tt_teams t ON (u.team_id = t.id) WHERE ";
+ FROM tt_users u LEFT JOIN tt_teams t ON (u.team_id = t.id) LEFT JOIN tt_roles r on (r.id = u.role_id) WHERE ";
if ($id)
$sql .= "u.id = $id";
else
$this->id = $val['id'];
$this->team_id = $val['team_id'];
$this->role = $val['role'];
+ $this->role_id = $val['role_id'];
+ $this->rank = $val['rank'];
+ // Downgrade rank to legacy role, if it is still in use.
+ if ($this->role > 0 && $this->rank > $this->role)
+ $this->rank = $this->role; // TODO: remove after roles revamp.
+ // Upgrade rank from legacy role, for user who does not yet have a role_id.
+ if (!$this->rank && !$this->role_id && $this->role > 0)
+ $this->rank = $this->role; // TODO: remove after roles revamp.
$this->client_id = $val['client_id'];
$this->email = $val['email'];
$this->lang = $val['lang'];
$role = (int) $fields['role'];
$role_part = ", role = $role";
}
+ if (isset($fields['role_id'])) {
+ $role_id = (int) $fields['role_id'];
+ $role_id_part = ", role_id = $role_id";
+ }
if (array_key_exists('client_id', $fields)) // Could be NULL.
$client_part = ", client_id = ".$mdb2->quote($fields['client_id']);
}
$sql = "update tt_users set login = ".$mdb2->quote($fields['login']).
"$pass_part, name = ".$mdb2->quote($fields['name']).
- "$role_part $client_part $rate_part $status_part, email = ".$mdb2->quote($fields['email']).
+ "$role_part $role_id_part $client_part $rate_part $status_part, email = ".$mdb2->quote($fields['email']).
" where id = $user_id";
$affected = $mdb2->exec($sql);
if (is_a($affected, 'PEAR_Error')) return false;
<br>
<table cellspacing="0" cellpadding="4" width="100%" border="0">
<tr>
- <td align="center"> Anuko Time Tracker 1.17.36.4049 | Copyright © <a href="https://www.anuko.com/lp/tt_3.htm" target="_blank">Anuko</a> |
+ <td align="center"> Anuko Time Tracker 1.17.37.4050 | Copyright © <a href="https://www.anuko.com/lp/tt_3.htm" target="_blank">Anuko</a> |
<a href="https://www.anuko.com/lp/tt_4.htm" target="_blank">{$i18n.footer.credits}</a> |
<a href="https://www.anuko.com/lp/tt_5.htm" target="_blank">{$i18n.footer.license}</a> |
<a href="https://www.anuko.com/lp/tt_7.htm" target="_blank">{$i18n.footer.improve}</a>
<script>
+// Prepare an array of available roles. We need it for "is_client" property.
+// It is used to selectively display client selector for client roles.
+roles = new Array();
+var idx = 0;
+{foreach $active_roles as $active_role}
+roles[idx] = new Array({$active_role.id}, '{$active_role.is_client}');
+idx++;
+{/foreach}
+
// The setDefaultRate function sets / unsets default rate for a project
// when a corresponding checkbox is ticked.
function setDefaultRate(element) {
// handleClientControl - controls visibility of the client dropdown depending on the selected user role.
// We need to show it only when the "Client" user role is selected.
function handleClientControl() {
+ var selectedRoleId = document.getElementById("role").value;
var clientControl = document.getElementById("client");
- if ("16" == document.getElementById("role").value)
- clientControl.style.visibility = "visible";
- else
- clientControl.style.visibility = "hidden";
+ var len = roles.length;
+ for (var i = 0; i < len; i++) {
+ if (selectedRoleId == roles[i][0]) {
+ var isClient = roles[i][1];
+ if (isClient == 1)
+ clientControl.style.visibility = "visible";
+ else
+ clientControl.style.visibility = "hidden";
+ break;
+ }
+ }
}
</script>
<script>
+// Prepare an array of available roles. We need it for "is_client" property.
+// It is used to selectively display client selector for client roles.
+roles = new Array();
+var idx = 0;
+{foreach $active_roles as $active_role}
+roles[idx] = new Array({$active_role.id}, '{$active_role.is_client}');
+idx++;
+{/foreach}
+
// Prepare an array of rates.
// Format: project_rates[0] = Array(100, '25.00'), project_rates[1] = Array(120, '30.00'), etc...
// First element = project_id, second element = rate for project. Quotes needed for string representation of rates.
// handleClientControl - controls visibility of the client dropdown depending on the selected user role.
// We need to show it only when the "Client" user role is selected.
function handleClientControl() {
+ var selectedRoleId = document.getElementById("role").value;
var clientControl = document.getElementById("client");
- if ("16" == document.getElementById("role").value)
- clientControl.style.visibility = "visible";
- else
- clientControl.style.visibility = "hidden";
+ var len = roles.length;
+ for (var i = 0; i < len; i++) {
+ if (selectedRoleId == roles[i][0]) {
+ var isClient = roles[i][1];
+ if (isClient == 1)
+ clientControl.style.visibility = "visible";
+ else
+ clientControl.style.visibility = "hidden";
+ break;
+ }
+ }
}
</script>
}
// If there are no roles in team, introduce default ones.
-if (!ttRoleHelper::rolesExist()) ttRoleHelper::createDefaultRoles();
+if (!ttRoleHelper::rolesExist()) ttRoleHelper::createDefaultRoles(); // TODO: refactor or remove after roles revamp.
$smarty->assign('active_roles', ttTeamHelper::getActiveRoles($user->team_id));
$smarty->assign('inactive_roles', ttTeamHelper::getInactiveRoles($user->team_id));
import('ttUserHelper');
import('form.Table');
import('form.TableColumn');
+import('ttRoleHelper');
// Access check.
if (!ttAccessCheck(right_manage_team)) {
}
$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'email','value'=>$cl_email));
-$roles[ROLE_USER] = $i18n->getKey('label.user');
-$roles[ROLE_COMANAGER] = $i18n->getKey('form.users.comanager');
-if ($user->isPluginEnabled('cl'))
- $roles[ROLE_CLIENT] = $i18n->getKey('label.client');
-$form->addInput(array('type'=>'combobox','onchange'=>'handleClientControl()','name'=>'role','value'=>$cl_role,'data'=>$roles));
+$active_roles = ttTeamHelper::getActiveRolesForUser();
+//$roles[ROLE_USER] = $i18n->getKey('label.user');
+//$roles[ROLE_COMANAGER] = $i18n->getKey('form.users.comanager');
+//if ($user->isPluginEnabled('cl'))
+// $roles[ROLE_CLIENT] = $i18n->getKey('label.client');
+$form->addInput(array('type'=>'combobox','onchange'=>'handleClientControl()','name'=>'role','value'=>$cl_role,'data'=>$active_roles,'datakeys'=>array('id', 'name')));
if ($user->isPluginEnabled('cl'))
$form->addInput(array('type'=>'combobox','name'=>'client','value'=>$cl_client_id,'data'=>$clients,'datakeys'=>array('id', 'name'),'empty'=>array(''=>$i18n->getKey('dropdown.select'))));
}
if (!ttValidEmail($cl_email, true)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.email'));
// Require selection of a client for a client role.
- if ($user->isPluginEnabled('cl') && $cl_role == ROLE_CLIENT && !$cl_client_id) $err->add($i18n->getKey('error.client'));
+ if ($user->isPluginEnabled('cl') && ttRoleHelper::isClientRole($cl_role) && !$cl_client_id) $err->add($i18n->getKey('error.client'));
if (!ttValidFloat($cl_rate, true)) $err->add($i18n->getKey('error.field'), $i18n->getKey('form.users.default_rate'));
if ($err->no()) {
if (!ttUserHelper::getUserByLogin($cl_login)) {
+ // Get legacy role value.
+ $legacy_role = ttRoleHelper::getLegacyRole($cl_role); // TODO: remove after roles revamp.
$fields = array(
'name' => $cl_name,
'login' => $cl_login,
'password' => $cl_password1,
'rate' => $cl_rate,
'team_id' => $user->team_id,
- 'role' => $cl_role,
+ 'role' => $legacy_role,
+ 'role_id' => $cl_role,
'client_id' => $cl_client_id,
'projects' => $assigned_projects,
'email' => $cl_email);
} // isPost
$smarty->assign('auth_external', $auth->isPasswordExternal());
+$smarty->assign('active_roles', $active_roles);
$smarty->assign('forms', array($form->getName()=>$form->toArray()));
$smarty->assign('onload', 'onLoad="document.userForm.name.focus();handleClientControl();"');
$smarty->assign('title', $i18n->getKey('title.add_user'));
import('ttUserHelper');
import('form.Table');
import('form.TableColumn');
+import('ttRoleHelper');
// Access check.
if (!ttAccessCheck(right_manage_team)) {
$cl_login = $user_details['login'];
$cl_email = $user_details['email'];
$cl_rate = str_replace('.', $user->decimal_mark, $user_details['rate']);
- $cl_role = $user_details['role'];
+ $cl_role = $user_details['role_id'];
+
+ // In case role_id is not yet assigned...
+ if (!$cl_role && $user_details['role'])
+ $cl_role = ttRoleHelper::gerRoleByRank($user_details['role']); // TODO: remove after roles revamp.
+
$cl_client_id = $user_details['client_id'];
$cl_status = $user_details['status'];
$cl_projects = array();
}
$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'email','style'=>'width: 300px;','value'=>$cl_email));
-$roles[ROLE_USER] = $i18n->getKey('label.user');
-$roles[ROLE_COMANAGER] = $i18n->getKey('form.users.comanager');
-if ($user->isPluginEnabled('cl'))
- $roles[ROLE_CLIENT] = $i18n->getKey('label.client');
-$form->addInput(array('type'=>'combobox','onchange'=>'handleClientControl()','name'=>'role','value'=>$cl_role,'data'=>$roles));
+$active_roles = ttTeamHelper::getActiveRolesForUser();
+//$roles[ROLE_USER] = $i18n->getKey('label.user');
+//$roles[ROLE_COMANAGER] = $i18n->getKey('form.users.comanager');
+//if ($user->isPluginEnabled('cl'))
+// $roles[ROLE_CLIENT] = $i18n->getKey('label.client');
+$form->addInput(array('type'=>'combobox','onchange'=>'handleClientControl()','name'=>'role','value'=>$cl_role,'data'=>$active_roles, 'datakeys'=>array('id', 'name')));
if ($user->isPluginEnabled('cl'))
$form->addInput(array('type'=>'combobox','name'=>'client','value'=>$cl_client_id,'data'=>$clients,'datakeys'=>array('id', 'name'),'empty'=>array(''=>$i18n->getKey('dropdown.select'))));
}
if (!ttValidEmail($cl_email, true)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.email'));
// Require selection of a client for a client role.
- if ($user->isPluginEnabled('cl') && $cl_role == ROLE_CLIENT && !$cl_client_id) $err->add($i18n->getKey('error.client'));
+ if ($user->isPluginEnabled('cl') && ttRoleHelper::isClientRole($cl_role) && !$cl_client_id) $err->add($i18n->getKey('error.client'));
if (!ttValidFloat($cl_rate, true)) $err->add($i18n->getKey('error.field'), $i18n->getKey('form.users.default_rate'));
if ($err->no()) {
$existing_user = ttUserHelper::getUserByLogin($cl_login);
if (!$existing_user || ($user_id == $existing_user['id'])) {
- $fields = array(
+ $fields = array(
'name' => $cl_name,
'login' => $cl_login,
'password' => $cl_password1,
'rate' => $cl_rate,
'projects' => $assigned_projects);
if (right_assign_roles & $user->rights) {
- $fields['role'] = $cl_role;
+ // Get legacy role value.
+ $legacy_role = ttRoleHelper::getLegacyRole($cl_role); // TODO: remove after roles revamp.
+ $fields['role'] = $legacy_role;
+ $fields['role_id'] = $cl_role;
$fields['client_id'] = $cl_client_id;
}
$smarty->assign('rates', $rates);
$smarty->assign('auth_external', $auth->isPasswordExternal());
+$smarty->assign('active_roles', $active_roles);
$smarty->assign('forms', array($form->getName()=>$form->toArray()));
$smarty->assign('onload', 'onLoad="document.userForm.name.focus();handleClientControl();"');
$smarty->assign('user_id', $user_id);
import('form.Form');
import('ttTeamHelper');
import('ttTimeHelper');
+import('ttRoleHelper');
// Access check.
if (!ttAccessCheck(right_data_entry)) {
// Get users.
$active_users = ttTeamHelper::getActiveUsers(array('getAllFields'=>true));
if($user->canManageTeam()) {
+
+ // If there are no roles in team, introduce default ones.
+ if (!ttRoleHelper::rolesExist()) ttRoleHelper::createDefaultRoles(); // TODO: refactor or remove after roles revamp.
+ // This is here temporarily so that we have roles to work with to manage users.
+ // Normally, this should be done during an upgrade step (not yet implemented).
+
$can_delete_manager = (1 == count($active_users));
$inactive_users = ttTeamHelper::getInactiveUsers($user->team_id, true);
}