2 // +----------------------------------------------------------------------+
 
   3 // | Anuko Time Tracker
 
   4 // +----------------------------------------------------------------------+
 
   5 // | Copyright (c) Anuko International Ltd. (https://www.anuko.com)
 
   6 // +----------------------------------------------------------------------+
 
   7 // | LIBERAL FREEWARE LICENSE: This source code document may be used
 
   8 // | by anyone for any purpose, and freely redistributed alone or in
 
   9 // | combination with other software, provided that the license is obeyed.
 
  11 // | There are only two ways to violate the license:
 
  13 // | 1. To redistribute this code in source form, with the copyright
 
  14 // |    notice or license removed or altered. (Distributing in compiled
 
  15 // |    forms without embedded copyright notices is permitted).
 
  17 // | 2. To redistribute modified versions of this code in *any* form
 
  18 // |    that bears insufficient indications that the modifications are
 
  19 // |    not the work of the original author(s).
 
  21 // | This license applies to this document only, not any other software
 
  22 // | that it may be combined with.
 
  24 // +----------------------------------------------------------------------+
 
  26 // | https://www.anuko.com/time_tracker/credits.htm
 
  27 // +----------------------------------------------------------------------+
 
  29 import('ttUserHelper');
 
  30 import('DateAndTime');
 
  31 import('ttInvoiceHelper');
 
  33 // Class ttTeamHelper - contains helper functions that operate with groups.
 
  36   // The swapRolesWith swaps existing user role with that of another user.
 
  37   static function swapRolesWith($user_id) {
 
  39     $mdb2 = getConnection();
 
  41     // Obtain role id for the user we are swapping ourselves with.
 
  42     $sql = "select u.id, u.role_id from tt_users u left join tt_roles r on (u.role_id = r.id) where u.id = $user_id and u.group_id = $user->group_id and u.status = 1 and r.rank < $user->rank";
 
  43     $res = $mdb2->query($sql);
 
  44     if (is_a($res, 'PEAR_Error'))
 
  46     $val = $res->fetchRow();
 
  47     if (!$val['id'] || !$val['role_id'])
 
  50     $modified_part = ', modified = now(), modified_ip = '.$mdb2->quote($_SERVER['REMOTE_ADDR']).', modified_by = '.$user->id;
 
  53     $sql = "update tt_users set role_id = $user->role_id".$modified_part." where id = $user_id and group_id = $user->group_id";
 
  54     $affected = $mdb2->exec($sql);
 
  55     if (is_a($affected, 'PEAR_Error')) return false;
 
  58     $role_id = $val['role_id'];
 
  59     $sql = "update tt_users set role_id = $role_id".$modified_part." where id = $user->id and group_id = $user->group_id";
 
  60     $affected = $mdb2->exec($sql);
 
  61     if (is_a($affected, 'PEAR_Error')) return false;
 
  66   // The getUsersForSwap obtains all users a current user can swap roles with.
 
  67   static function getUsersForSwap() {
 
  69     $mdb2 = getConnection();
 
  71     $sql = "select u.id, u.name, r.rank, r.rights from tt_users u left join tt_roles r on (u.role_id = r.id) where u.group_id = $user->group_id and u.status = 1 and r.rank < $user->rank order by upper(u.name)";
 
  72     $res = $mdb2->query($sql);
 
  74     if (is_a($res, 'PEAR_Error'))
 
  76     while ($val = $res->fetchRow()) {
 
  77       $isClient = in_array('track_own_time', explode(',', $val['rights'])) ? 0 : 1; // Clients do not have track_own_time right.
 
  79         continue; // Skip adding clients.
 
  86   // The getInactiveUsers obtains all inactive users in a group.
 
  87   static function getInactiveUsers($group_id, $all_fields = false) {
 
  88     $mdb2 = getConnection();
 
  91       $sql = "select u.*, r.name as role_name from tt_users u left join tt_roles r on (u.role_id = r.id) where u.group_id = $group_id and u.status = 0 order by upper(u.name)";
 
  93       $sql = "select id, name from tt_users where group_id = $group_id and status = 0 order by upper(name)";
 
  94     $res = $mdb2->query($sql);
 
  96     if (!is_a($res, 'PEAR_Error')) {
 
  97       while ($val = $res->fetchRow()) {
 
 105   // The getAllProjects obtains all projects in a group.
 
 106   static function getAllProjects($group_id, $all_fields = false) {
 
 107     $mdb2 = getConnection();
 
 110       $sql = "select * from tt_projects where group_id = $group_id order by status, upper(name)";
 
 112       $sql = "select id, name from tt_projects where group_id = $group_id order by status, upper(name)";
 
 113     $res = $mdb2->query($sql);
 
 115     if (!is_a($res, 'PEAR_Error')) {
 
 116       while ($val = $res->fetchRow()) {
 
 124   // getActiveRolesForUser - returns an array of relevant active roles for user with rank less than self.
 
 125   // "Relevant" means that client roles are filtered out if Client plugin is disabled.
 
 126   static function getActiveRolesForUser()
 
 130     $mdb2 = getConnection();
 
 132     $group_id = $user->getGroup();
 
 133     $org_id = $user->org_id;
 
 135     // Determine max rank. If we are working in on behalf group
 
 136     // then rank restriction does not apply.
 
 137     $max_rank = $user->behalfGroup ? MAX_RANK : $user->rank;
 
 139     $sql = "select id, name, description, rank, rights from tt_roles where group_id = $group_id and org_id = $org_id and rank < $max_rank and status = 1 order by rank";
 
 140     $res = $mdb2->query($sql);
 
 142     if (!is_a($res, 'PEAR_Error')) {
 
 143       while ($val = $res->fetchRow()) {
 
 144         $val['is_client'] = in_array('track_own_time', explode(',', $val['rights'])) ? 0 : 1; // Clients do not have data entry right.
 
 145         if ($val['is_client'] && !$user->isPluginEnabled('cl'))
 
 146           continue; // Skip adding a client role.
 
 153   // getActiveRoles - returns an array of active roles for a group.
 
 154   static function getActiveRoles($group_id)
 
 157     $mdb2 = getConnection();
 
 159     $sql = "select id, name, description, rank, rights from tt_roles where group_id = $group_id and status = 1 order by rank";
 
 160     $res = $mdb2->query($sql);
 
 162     if (!is_a($res, 'PEAR_Error')) {
 
 163       while ($val = $res->fetchRow()) {
 
 164         $val['is_client'] = in_array('track_own_time', explode(',', $val['rights'])) ? 0 : 1; // Clients do not have track_own_time right.
 
 171   // getInactiveRoles - returns an array of inactive roles for a group.
 
 172   static function getInactiveRoles($group_id)
 
 175     $mdb2 = getConnection();
 
 177     $sql = "select id, name, rank, description from tt_roles
 
 178       where group_id = $group_id and status = 0 order by rank";
 
 179     $res = $mdb2->query($sql);
 
 181     if (!is_a($res, 'PEAR_Error')) {
 
 182       while ($val = $res->fetchRow()) {
 
 189   // getInactiveRolesForUser - returns an array of relevant active roles for user with rank less than self.
 
 190   // "Relevant" means that client roles are filtered out if Client plugin is disabled.
 
 191   static function getInactiveRolesForUser()
 
 195     $mdb2 = getConnection();
 
 197     $group_id = $user->getGroup();
 
 198     $org_id = $user->org_id;
 
 200     // Determine max rank. If we are working in on behalf group
 
 201     // then rank restriction does not apply.
 
 202     $max_rank = $user->behalfGroup ? MAX_RANK : $user->rank;
 
 204     $sql = "select id, name, description, rank, rights from tt_roles where group_id = $group_id and org_id = $org_id and rank < $max_rank and status = 0 order by rank";
 
 205     $res = $mdb2->query($sql);
 
 207     if (!is_a($res, 'PEAR_Error')) {
 
 208       while ($val = $res->fetchRow()) {
 
 209         $val['is_client'] = in_array('track_own_time', explode(',', $val['rights'])) ? 0 : 1; // Clients do not have data entry right.
 
 210         if ($val['is_client'] && !$user->isPluginEnabled('cl'))
 
 211           continue; // Skip adding a client role.
 
 218   // The getAllClients obtains all clients in a group.
 
 219   static function getAllClients($group_id, $all_fields = false) {
 
 220     $mdb2 = getConnection();
 
 223       $sql = "select * from tt_clients where group_id = $group_id order by status, upper(name)";
 
 225       $sql = "select id, name from tt_clients where group_id = $group_id order by status, upper(name)";
 
 227     $res = $mdb2->query($sql);
 
 229     if (!is_a($res, 'PEAR_Error')) {
 
 230       while ($val = $res->fetchRow()) {
 
 238   // The getAllInvoices returns an array of all invoices for a group.
 
 239   static function getAllInvoices()
 
 244     $mdb2 = getConnection();
 
 246     $sql = "select * from tt_invoices where group_id = $user->group_id";
 
 247     $res = $mdb2->query($sql);
 
 249     if (!is_a($res, 'PEAR_Error')) {
 
 250       $dt = new DateAndTime(DB_DATEFORMAT);
 
 251       while ($val = $res->fetchRow()) {
 
 258   // getUserToProjectBinds - obtains all user to project binds for a group.
 
 259   static function getUserToProjectBinds($group_id) {
 
 260     $mdb2 = getConnection();
 
 263     $sql = "select * from tt_user_project_binds".
 
 264       " where user_id in (select id from tt_users where group_id = $group_id)".
 
 265       " and group_id = $group_id order by user_id, status, project_id";
 
 266     $res = $mdb2->query($sql);
 
 268     if (!is_a($res, 'PEAR_Error')) {
 
 269       while ($val = $res->fetchRow()) {
 
 277   // The getAllCustomFields obtains all custom fields in a group.
 
 278   static function getAllCustomFields($group_id) {
 
 279     $mdb2 = getConnection();
 
 281     $sql = "select * from tt_custom_fields where group_id = $group_id order by status";
 
 283     $res = $mdb2->query($sql);
 
 285     if (!is_a($res, 'PEAR_Error')) {
 
 286       while ($val = $res->fetchRow()) {
 
 294   // The getAllCustomFieldOptions obtains all custom field options in a group.
 
 295   static function getAllCustomFieldOptions($group_id) {
 
 296     $mdb2 = getConnection();
 
 298     $sql = "select * from tt_custom_field_options where field_id in (select id from tt_custom_fields where group_id = $group_id) order by id";
 
 300     $res = $mdb2->query($sql);
 
 302     if (!is_a($res, 'PEAR_Error')) {
 
 303       while ($val = $res->fetchRow()) {
 
 311   // The getCustomFieldLog obtains all custom field log entries for a group.
 
 312   static function getCustomFieldLog($group_id) {
 
 313     $mdb2 = getConnection();
 
 315     $sql = "select * from tt_custom_field_log where field_id in (select id from tt_custom_fields where group_id = $group_id) order by id";
 
 317     $res = $mdb2->query($sql);
 
 319     if (!is_a($res, 'PEAR_Error')) {
 
 320       while ($val = $res->fetchRow()) {
 
 328   // getFavReports - obtains all favorite reports for all users in a group.
 
 329   static function getFavReports($group_id) {
 
 330     $mdb2 = getConnection();
 
 333     $sql = "select * from tt_fav_reports where user_id in (select id from tt_users where group_id = $group_id)";
 
 334     $res = $mdb2->query($sql);
 
 336     if (!is_a($res, 'PEAR_Error')) {
 
 337       while ($val = $res->fetchRow()) {
 
 345   // getExpenseItems - obtains all expense items for all users in a group.
 
 346   static function getExpenseItems($group_id) {
 
 347     $mdb2 = getConnection();
 
 350     $sql = "select * from tt_expense_items where user_id in (select id from tt_users where group_id = $group_id)";
 
 351     $res = $mdb2->query($sql);
 
 353     if (!is_a($res, 'PEAR_Error')) {
 
 354       while ($val = $res->fetchRow()) {
 
 362   // getMonthlyQuotas - obtains monthly quotas for a group.
 
 363   static function getMonthlyQuotas($group_id) {
 
 364     $mdb2 = getConnection();
 
 367     $sql = "select year, month, minutes from tt_monthly_quotas where group_id = $group_id";
 
 368     $res = $mdb2->query($sql);
 
 370     if (!is_a($res, 'PEAR_Error')) {
 
 371       while ($val = $res->fetchRow()) {
 
 379   // The delete function permanently deletes all data for a group.
 
 380   static function delete($group_id) {
 
 381     $mdb2 = getConnection();
 
 384     $sql = "select id from tt_users where group_id = $group_id";
 
 385     $res = $mdb2->query($sql);
 
 386     if (is_a($res, 'PEAR_Error')) return false;
 
 387     while ($val = $res->fetchRow()) {
 
 388       $user_id = $val['id'];
 
 389       if (!ttUserHelper::delete($user_id)) return false;
 
 393     if (!ttTeamHelper::deleteTasks($group_id)) return false;
 
 395     // Delete client to project binds.
 
 396     $sql = "delete from tt_client_project_binds where client_id in (select id from tt_clients where group_id = $group_id)";
 
 397     $affected = $mdb2->exec($sql);
 
 398     if (is_a($affected, 'PEAR_Error')) return false;
 
 401     $sql = "delete from tt_projects where group_id = $group_id";
 
 402     $affected = $mdb2->exec($sql);
 
 403     if (is_a($affected, 'PEAR_Error')) return false;
 
 406     $sql = "delete from tt_clients where group_id = $group_id";
 
 407     $affected = $mdb2->exec($sql);
 
 408     if (is_a($affected, 'PEAR_Error')) return false;
 
 411     $sql = "delete from tt_invoices where group_id = $group_id";
 
 412     $affected = $mdb2->exec($sql);
 
 413     if (is_a($affected, 'PEAR_Error')) return false;
 
 415     // Delete custom fields.
 
 416     if (!ttTeamHelper::deleteCustomFields($group_id)) return false;
 
 419     $sql = "delete from tt_roles where group_id = $group_id";
 
 420     $affected = $mdb2->exec($sql);
 
 421     if (is_a($affected, 'PEAR_Error')) return false;
 
 423     // Delete cron entries.
 
 424     $sql = "delete from tt_cron where group_id = $group_id";
 
 425     $affected = $mdb2->exec($sql);
 
 426     if (is_a($affected, 'PEAR_Error')) return false;
 
 428     // Delete predefined expenses.
 
 429     $sql = "delete from tt_predefined_expenses where group_id = $group_id";
 
 430     $affected = $mdb2->exec($sql);
 
 431     if (is_a($affected, 'PEAR_Error')) return false;
 
 433     // Delete monthly quotas.
 
 434     $sql = "delete from tt_monthly_quotas where group_id = $group_id";
 
 435     $affected = $mdb2->exec($sql);
 
 436     if (is_a($affected, 'PEAR_Error')) return false;
 
 439     $sql = "delete from tt_groups where id = $group_id";
 
 440     $affected = $mdb2->exec($sql);
 
 441     if (is_a($affected, 'PEAR_Error')) return false;
 
 446   // The deleteTasks deletes all tasks and task binds for an inactive group.
 
 447   static function deleteTasks($group_id) {
 
 448     $mdb2 = getConnection();
 
 449     $sql = "select id from tt_tasks where group_id = $group_id";
 
 450     $res = $mdb2->query($sql);
 
 451     if (is_a($res, 'PEAR_Error')) return false;
 
 453     while ($val = $res->fetchRow()) {
 
 455       // Delete task binds.
 
 456       $task_id = $val['id'];
 
 457       $sql = "delete from tt_project_task_binds where task_id = $task_id";
 
 458       $affected = $mdb2->exec($sql);
 
 459       if (is_a($affected, 'PEAR_Error')) return false;
 
 462       $sql = "delete from tt_tasks where id = $task_id";
 
 463       $affected = $mdb2->exec($sql);
 
 464       if (is_a($affected, 'PEAR_Error')) return false;
 
 470   // The deleteCustomFields cleans up tt_custom_field_log, tt_custom_field_options and tt_custom_fields tables for an inactive group.
 
 471   static function deleteCustomFields($group_id) {
 
 472     $mdb2 = getConnection();
 
 473     $sql = "select id from tt_custom_fields where group_id = $group_id";
 
 474     $res = $mdb2->query($sql);
 
 475     if (is_a($res, 'PEAR_Error')) return false;
 
 477     while ($val = $res->fetchRow()) {
 
 478       $field_id = $val['id'];
 
 480       // Clean up tt_custom_field_log.
 
 481       $sql = "delete from tt_custom_field_log where field_id = $field_id";
 
 482       $affected = $mdb2->exec($sql);
 
 483       if (is_a($affected, 'PEAR_Error')) return false;
 
 485       // Clean up tt_custom_field_options.
 
 486       $sql = "delete from tt_custom_field_options where field_id = $field_id";
 
 487       $affected = $mdb2->exec($sql);
 
 488       if (is_a($affected, 'PEAR_Error')) return false;
 
 490       // Delete custom field.
 
 491       $sql = "delete from tt_custom_fields where id = $field_id";
 
 492       $affected = $mdb2->exec($sql);
 
 493       if (is_a($affected, 'PEAR_Error')) return false;