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 where user_id in (select id from tt_users where group_id = $group_id) order by user_id, status, project_id";
 
 264     $res = $mdb2->query($sql);
 
 266     if (!is_a($res, 'PEAR_Error')) {
 
 267       while ($val = $res->fetchRow()) {
 
 275   // The getAllCustomFields obtains all custom fields in a group.
 
 276   static function getAllCustomFields($group_id) {
 
 277     $mdb2 = getConnection();
 
 279     $sql = "select * from tt_custom_fields where group_id = $group_id order by status";
 
 281     $res = $mdb2->query($sql);
 
 283     if (!is_a($res, 'PEAR_Error')) {
 
 284       while ($val = $res->fetchRow()) {
 
 292   // The getAllCustomFieldOptions obtains all custom field options in a group.
 
 293   static function getAllCustomFieldOptions($group_id) {
 
 294     $mdb2 = getConnection();
 
 296     $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";
 
 298     $res = $mdb2->query($sql);
 
 300     if (!is_a($res, 'PEAR_Error')) {
 
 301       while ($val = $res->fetchRow()) {
 
 309   // The getCustomFieldLog obtains all custom field log entries for a group.
 
 310   static function getCustomFieldLog($group_id) {
 
 311     $mdb2 = getConnection();
 
 313     $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";
 
 315     $res = $mdb2->query($sql);
 
 317     if (!is_a($res, 'PEAR_Error')) {
 
 318       while ($val = $res->fetchRow()) {
 
 326   // getFavReports - obtains all favorite reports for all users in a group.
 
 327   static function getFavReports($group_id) {
 
 328     $mdb2 = getConnection();
 
 331     $sql = "select * from tt_fav_reports where user_id in (select id from tt_users where group_id = $group_id)";
 
 332     $res = $mdb2->query($sql);
 
 334     if (!is_a($res, 'PEAR_Error')) {
 
 335       while ($val = $res->fetchRow()) {
 
 343   // getExpenseItems - obtains all expense items for all users in a group.
 
 344   static function getExpenseItems($group_id) {
 
 345     $mdb2 = getConnection();
 
 348     $sql = "select * from tt_expense_items where user_id in (select id from tt_users where group_id = $group_id)";
 
 349     $res = $mdb2->query($sql);
 
 351     if (!is_a($res, 'PEAR_Error')) {
 
 352       while ($val = $res->fetchRow()) {
 
 360   // getMonthlyQuotas - obtains monthly quotas for a group.
 
 361   static function getMonthlyQuotas($group_id) {
 
 362     $mdb2 = getConnection();
 
 365     $sql = "select year, month, minutes from tt_monthly_quotas where group_id = $group_id";
 
 366     $res = $mdb2->query($sql);
 
 368     if (!is_a($res, 'PEAR_Error')) {
 
 369       while ($val = $res->fetchRow()) {
 
 377   // The delete function permanently deletes all data for a group.
 
 378   static function delete($group_id) {
 
 379     $mdb2 = getConnection();
 
 382     $sql = "select id from tt_users where group_id = $group_id";
 
 383     $res = $mdb2->query($sql);
 
 384     if (is_a($res, 'PEAR_Error')) return false;
 
 385     while ($val = $res->fetchRow()) {
 
 386       $user_id = $val['id'];
 
 387       if (!ttUserHelper::delete($user_id)) return false;
 
 391     if (!ttTeamHelper::deleteTasks($group_id)) return false;
 
 393     // Delete client to project binds.
 
 394     $sql = "delete from tt_client_project_binds where client_id in (select id from tt_clients where group_id = $group_id)";
 
 395     $affected = $mdb2->exec($sql);
 
 396     if (is_a($affected, 'PEAR_Error')) return false;
 
 399     $sql = "delete from tt_projects where group_id = $group_id";
 
 400     $affected = $mdb2->exec($sql);
 
 401     if (is_a($affected, 'PEAR_Error')) return false;
 
 404     $sql = "delete from tt_clients where group_id = $group_id";
 
 405     $affected = $mdb2->exec($sql);
 
 406     if (is_a($affected, 'PEAR_Error')) return false;
 
 409     $sql = "delete from tt_invoices where group_id = $group_id";
 
 410     $affected = $mdb2->exec($sql);
 
 411     if (is_a($affected, 'PEAR_Error')) return false;
 
 413     // Delete custom fields.
 
 414     if (!ttTeamHelper::deleteCustomFields($group_id)) return false;
 
 417     $sql = "delete from tt_roles where group_id = $group_id";
 
 418     $affected = $mdb2->exec($sql);
 
 419     if (is_a($affected, 'PEAR_Error')) return false;
 
 421     // Delete cron entries.
 
 422     $sql = "delete from tt_cron where group_id = $group_id";
 
 423     $affected = $mdb2->exec($sql);
 
 424     if (is_a($affected, 'PEAR_Error')) return false;
 
 426     // Delete predefined expenses.
 
 427     $sql = "delete from tt_predefined_expenses where group_id = $group_id";
 
 428     $affected = $mdb2->exec($sql);
 
 429     if (is_a($affected, 'PEAR_Error')) return false;
 
 431     // Delete monthly quotas.
 
 432     $sql = "delete from tt_monthly_quotas where group_id = $group_id";
 
 433     $affected = $mdb2->exec($sql);
 
 434     if (is_a($affected, 'PEAR_Error')) return false;
 
 437     $sql = "delete from tt_groups where id = $group_id";
 
 438     $affected = $mdb2->exec($sql);
 
 439     if (is_a($affected, 'PEAR_Error')) return false;
 
 444   // The deleteTasks deletes all tasks and task binds for an inactive group.
 
 445   static function deleteTasks($group_id) {
 
 446     $mdb2 = getConnection();
 
 447     $sql = "select id from tt_tasks where group_id = $group_id";
 
 448     $res = $mdb2->query($sql);
 
 449     if (is_a($res, 'PEAR_Error')) return false;
 
 451     while ($val = $res->fetchRow()) {
 
 453       // Delete task binds.
 
 454       $task_id = $val['id'];
 
 455       $sql = "delete from tt_project_task_binds where task_id = $task_id";
 
 456       $affected = $mdb2->exec($sql);
 
 457       if (is_a($affected, 'PEAR_Error')) return false;
 
 460       $sql = "delete from tt_tasks where id = $task_id";
 
 461       $affected = $mdb2->exec($sql);
 
 462       if (is_a($affected, 'PEAR_Error')) return false;
 
 468   // The deleteCustomFields cleans up tt_custom_field_log, tt_custom_field_options and tt_custom_fields tables for an inactive group.
 
 469   static function deleteCustomFields($group_id) {
 
 470     $mdb2 = getConnection();
 
 471     $sql = "select id from tt_custom_fields where group_id = $group_id";
 
 472     $res = $mdb2->query($sql);
 
 473     if (is_a($res, 'PEAR_Error')) return false;
 
 475     while ($val = $res->fetchRow()) {
 
 476       $field_id = $val['id'];
 
 478       // Clean up tt_custom_field_log.
 
 479       $sql = "delete from tt_custom_field_log where field_id = $field_id";
 
 480       $affected = $mdb2->exec($sql);
 
 481       if (is_a($affected, 'PEAR_Error')) return false;
 
 483       // Clean up tt_custom_field_options.
 
 484       $sql = "delete from tt_custom_field_options where field_id = $field_id";
 
 485       $affected = $mdb2->exec($sql);
 
 486       if (is_a($affected, 'PEAR_Error')) return false;
 
 488       // Delete custom field.
 
 489       $sql = "delete from tt_custom_fields where id = $field_id";
 
 490       $affected = $mdb2->exec($sql);
 
 491       if (is_a($affected, 'PEAR_Error')) return false;