16896ac58104301232a9610845653ebf96404bf1
[timetracker.git] / WEB-INF / lib / ttTeamHelper.class.php
1 <?php
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.
10 // |
11 // | There are only two ways to violate the license:
12 // |
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).
16 // |
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).
20 // |
21 // | This license applies to this document only, not any other software
22 // | that it may be combined with.
23 // |
24 // +----------------------------------------------------------------------+
25 // | Contributors:
26 // | https://www.anuko.com/time_tracker/credits.htm
27 // +----------------------------------------------------------------------+
28
29 import('ttUserHelper');
30 import('DateAndTime');
31 import('ttInvoiceHelper');
32
33 // Class ttTeamHelper - contains helper functions that operate with groups.
34 class ttTeamHelper {
35
36   // The getUsersForClient obtains all active and inactive users in a group that are relevant to a client.
37   static function getUsersForClient() {
38     global $user;
39     $mdb2 = getConnection();
40
41     $sql = "select u.id, u.name from tt_user_project_binds upb".
42       " inner join tt_client_project_binds cpb on (upb.project_id = cpb.project_id and cpb.client_id = $user->client_id)".
43       " inner join tt_users u on (u.id = upb.user_id)".
44       " where (u.status = 1 or u.status = 0)".
45       " group by u.id".
46       " order by upper(u.name)";
47     $res = $mdb2->query($sql);
48     $user_list = array();
49     if (is_a($res, 'PEAR_Error'))
50       return false;
51     while ($val = $res->fetchRow()) {
52       $user_list[] = $val;
53     }
54     return $user_list;
55   }
56
57   // The getActiveUsers obtains all active users in a given group.
58   static function getActiveUsers($options = null) {
59     global $user;
60     global $i18n;
61     $mdb2 = getConnection();
62
63     $group_id = $user->getGroup();
64     $org_id = $user->org_id;
65
66     if (isset($options['getAllFields']))
67       $sql = "select u.*, r.name as role_name, r.rank from tt_users u left join tt_roles r on (u.role_id = r.id) where u.group_id = $group_id and u.org_id = $org_id and u.status = 1 order by upper(u.name)";
68     else
69       $sql = "select id, name from tt_users where group_id = $group_id and org_id = $org_id and status = 1 order by upper(name)";
70     $res = $mdb2->query($sql);
71     $user_list = array();
72     if (is_a($res, 'PEAR_Error'))
73       return false;
74     while ($val = $res->fetchRow()) {
75       // Localize top manager role name, as it is not localized in db.
76       if ($val['rank'] == 512)
77         $val['role_name'] = $i18n->get('role.top_manager.label');
78       $user_list[] = $val;
79     }
80
81     if (isset($options['putSelfFirst'])) {
82       // Put own entry at the front.
83       $cnt = count($user_list);
84       for($i = 0; $i < $cnt; $i++) {
85         if ($user_list[$i]['id'] == $user->id) {
86           $self = $user_list[$i]; // Found self.
87           array_unshift($user_list, $self); // Put own entry at the front.
88           array_splice($user_list, $i+1, 1); // Remove duplicate.
89         }
90       }
91     }
92     return $user_list;
93   }
94
95   // The swapRolesWith swaps existing user role with that of another user.
96   static function swapRolesWith($user_id) {
97     global $user;
98     $mdb2 = getConnection();
99
100     // Obtain role id for the user we are swapping ourselves with.
101     $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";
102     $res = $mdb2->query($sql);
103     if (is_a($res, 'PEAR_Error'))
104       return false;
105     $val = $res->fetchRow();
106     if (!$val['id'] || !$val['role_id'])
107       return false;
108
109     $modified_part = ', modified = now(), modified_ip = '.$mdb2->quote($_SERVER['REMOTE_ADDR']).', modified_by = '.$user->id;
110
111     // Promote user.
112     $sql = "update tt_users set role_id = $user->role_id".$modified_part." where id = $user_id and group_id = $user->group_id";
113     $affected = $mdb2->exec($sql);
114     if (is_a($affected, 'PEAR_Error')) return false;
115
116     // Demote self.
117     $role_id = $val['role_id'];
118     $sql = "update tt_users set role_id = $role_id".$modified_part." where id = $user->id and group_id = $user->group_id";
119     $affected = $mdb2->exec($sql);
120     if (is_a($affected, 'PEAR_Error')) return false;
121
122     return true;
123   }
124
125   // The getUsersForSwap obtains all users a current user can swap roles with.
126   static function getUsersForSwap() {
127     global $user;
128     $mdb2 = getConnection();
129
130     $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)";
131     $res = $mdb2->query($sql);
132     $user_list = array();
133     if (is_a($res, 'PEAR_Error'))
134       return false;
135     while ($val = $res->fetchRow()) {
136       $isClient = in_array('track_own_time', explode(',', $val['rights'])) ? 0 : 1; // Clients do not have track_own_time right.
137       if ($isClient)
138         continue; // Skip adding clients.
139       $user_list[] = $val;
140     }
141
142     return $user_list;
143   }
144
145   // The getUsers obtains all active and inactive (but not deleted) users in a group.
146   static function getUsers() {
147     global $user;
148     $mdb2 = getConnection();
149     $sql = "select id, name from tt_users where group_id = $user->group_id and (status = 1 or status = 0) order by upper(name)";
150     $res = $mdb2->query($sql);
151     $user_list = array();
152     if (is_a($res, 'PEAR_Error'))
153       return false;
154     while ($val = $res->fetchRow()) {
155       $user_list[] = $val;
156     }
157     return $user_list;
158   }
159
160   // The getInactiveUsers obtains all inactive users in a group.
161   static function getInactiveUsers($group_id, $all_fields = false) {
162     $mdb2 = getConnection();
163
164     if ($all_fields)
165       $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)";
166     else
167       $sql = "select id, name from tt_users where group_id = $group_id and status = 0 order by upper(name)";
168     $res = $mdb2->query($sql);
169     $result = array();
170     if (!is_a($res, 'PEAR_Error')) {
171       while ($val = $res->fetchRow()) {
172         $result[] = $val;
173       }
174       return $result;
175     }
176     return false;
177   }
178
179   // The getAllProjects obtains all projects in a group.
180   static function getAllProjects($group_id, $all_fields = false) {
181     $mdb2 = getConnection();
182
183     if ($all_fields)
184       $sql = "select * from tt_projects where group_id = $group_id order by status, upper(name)";
185     else
186       $sql = "select id, name from tt_projects where group_id = $group_id order by status, upper(name)";
187     $res = $mdb2->query($sql);
188     $result = array();
189     if (!is_a($res, 'PEAR_Error')) {
190       while ($val = $res->fetchRow()) {
191         $result[] = $val;
192       }
193       return $result;
194     }
195     return false;
196   }
197
198   // getActiveTasks - returns an array of active tasks for a group.
199   static function getActiveTasks($group_id)
200   {
201     $result = array();
202     $mdb2 = getConnection();
203
204     $sql = "select id, name, description from tt_tasks where group_id = $group_id and status = 1 order by upper(name)";
205     $res = $mdb2->query($sql);
206     $result = array();
207     if (!is_a($res, 'PEAR_Error')) {
208       while ($val = $res->fetchRow()) {
209         $result[] = $val;
210       }
211     }
212     return $result;
213   }
214
215   // getInactiveTasks - returns an array of inactive tasks for a group.
216   static function getInactiveTasks($group_id)
217   {
218     $result = array();
219     $mdb2 = getConnection();
220
221     $sql = "select id, name, description from tt_tasks
222       where group_id = $group_id and status = 0 order by upper(name)";
223     $res = $mdb2->query($sql);
224     $result = array();
225     if (!is_a($res, 'PEAR_Error')) {
226       while ($val = $res->fetchRow()) {
227         $result[] = $val;
228       }
229     }
230     return $result;
231   }
232
233   // The getAllTasks obtains all tasks in a group.
234   static function getAllTasks($group_id, $all_fields = false) {
235     $mdb2 = getConnection();
236
237     if ($all_fields)
238       $sql = "select * from tt_tasks where group_id = $group_id order by status, upper(name)";
239     else
240       $sql = "select id, name from tt_tasks where group_id = $group_id order by status, upper(name)";
241     $res = $mdb2->query($sql);
242     $result = array();
243     if (!is_a($res, 'PEAR_Error')) {
244       while ($val = $res->fetchRow()) {
245         $result[] = $val;
246       }
247       return $result;
248     }
249     return false;
250   }
251
252   // getActiveRolesForUser - returns an array of relevant active roles for user with rank less than self.
253   // "Relevant" means that client roles are filtered out if Client plugin is disabled.
254   static function getActiveRolesForUser()
255   {
256     global $user;
257     $result = array();
258     $mdb2 = getConnection();
259
260     $group_id = $user->getGroup();
261     $org_id = $user->org_id;
262
263     // Determine max rank. If we are working in on behalf group
264     // then rank restriction does not apply.
265     $max_rank = $user->behalfGroup ? MAX_RANK : $user->rank;
266
267     $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";
268     $res = $mdb2->query($sql);
269     $result = array();
270     if (!is_a($res, 'PEAR_Error')) {
271       while ($val = $res->fetchRow()) {
272         $val['is_client'] = in_array('track_own_time', explode(',', $val['rights'])) ? 0 : 1; // Clients do not have data entry right.
273         if ($val['is_client'] && !$user->isPluginEnabled('cl'))
274           continue; // Skip adding a client role.
275         $result[] = $val;
276       }
277     }
278     return $result;
279   }
280
281   // getActiveRoles - returns an array of active roles for a group.
282   static function getActiveRoles($group_id)
283   {
284     $result = array();
285     $mdb2 = getConnection();
286
287     $sql = "select id, name, description, rank, rights from tt_roles where group_id = $group_id and status = 1 order by rank";
288     $res = $mdb2->query($sql);
289     $result = array();
290     if (!is_a($res, 'PEAR_Error')) {
291       while ($val = $res->fetchRow()) {
292         $val['is_client'] = in_array('track_own_time', explode(',', $val['rights'])) ? 0 : 1; // Clients do not have track_own_time right.
293         $result[] = $val;
294       }
295     }
296     return $result;
297   }
298
299   // getInactiveRoles - returns an array of inactive roles for a group.
300   static function getInactiveRoles($group_id)
301   {
302     $result = array();
303     $mdb2 = getConnection();
304
305     $sql = "select id, name, rank, description from tt_roles
306       where group_id = $group_id and status = 0 order by rank";
307     $res = $mdb2->query($sql);
308     $result = array();
309     if (!is_a($res, 'PEAR_Error')) {
310       while ($val = $res->fetchRow()) {
311         $result[] = $val;
312       }
313     }
314     return $result;
315   }
316
317   // getInactiveRolesForUser - returns an array of relevant active roles for user with rank less than self.
318   // "Relevant" means that client roles are filtered out if Client plugin is disabled.
319   static function getInactiveRolesForUser()
320   {
321     global $user;
322     $result = array();
323     $mdb2 = getConnection();
324
325     $group_id = $user->getGroup();
326     $org_id = $user->org_id;
327
328     // Determine max rank. If we are working in on behalf group
329     // then rank restriction does not apply.
330     $max_rank = $user->behalfGroup ? MAX_RANK : $user->rank;
331
332     $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";
333     $res = $mdb2->query($sql);
334     $result = array();
335     if (!is_a($res, 'PEAR_Error')) {
336       while ($val = $res->fetchRow()) {
337         $val['is_client'] = in_array('track_own_time', explode(',', $val['rights'])) ? 0 : 1; // Clients do not have data entry right.
338         if ($val['is_client'] && !$user->isPluginEnabled('cl'))
339           continue; // Skip adding a client role.
340         $result[] = $val;
341       }
342     }
343     return $result;
344   }
345
346   // The getAllClients obtains all clients in a group.
347   static function getAllClients($group_id, $all_fields = false) {
348     $mdb2 = getConnection();
349
350     if ($all_fields)
351       $sql = "select * from tt_clients where group_id = $group_id order by status, upper(name)";
352     else
353       $sql = "select id, name from tt_clients where group_id = $group_id order by status, upper(name)";
354
355     $res = $mdb2->query($sql);
356     $result = array();
357     if (!is_a($res, 'PEAR_Error')) {
358       while ($val = $res->fetchRow()) {
359         $result[] = $val;
360       }
361       return $result;
362     }
363     return false;
364   }
365
366   // The getAllInvoices returns an array of all invoices for a group.
367   static function getAllInvoices()
368   {
369     global $user;
370
371     $result = array();
372     $mdb2 = getConnection();
373
374     $sql = "select * from tt_invoices where group_id = $user->group_id";
375     $res = $mdb2->query($sql);
376     $result = array();
377     if (!is_a($res, 'PEAR_Error')) {
378       $dt = new DateAndTime(DB_DATEFORMAT);
379       while ($val = $res->fetchRow()) {
380         $result[] = $val;
381       }
382     }
383     return $result;
384   }
385
386   // The getRecentInvoices returns an array of recent invoices (max 3) for a client.
387   static function getRecentInvoices($group_id, $client_id)
388   {
389     global $user;
390
391     $result = array();
392     $mdb2 = getConnection();
393
394     $sql = "select i.id, i.name from tt_invoices i
395       left join tt_clients c on (c.id = i.client_id)
396       where i.group_id = $group_id and i.status = 1 and c.id = $client_id
397       order by i.id desc limit 3";
398     $res = $mdb2->query($sql);
399     $result = array();
400     if (!is_a($res, 'PEAR_Error')) {
401       $dt = new DateAndTime(DB_DATEFORMAT);
402       while ($val = $res->fetchRow()) {
403         $result[] = $val;
404       }
405     }
406     return $result;
407   }
408
409   // getUserToProjectBinds - obtains all user to project binds for a group.
410   static function getUserToProjectBinds($group_id) {
411     $mdb2 = getConnection();
412
413     $result = array();
414     $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";
415     $res = $mdb2->query($sql);
416     $result = array();
417     if (!is_a($res, 'PEAR_Error')) {
418       while ($val = $res->fetchRow()) {
419         $result[] = $val;
420       }
421       return $result;
422     }
423     return false;
424   }
425
426   // The getAllCustomFields obtains all custom fields in a group.
427   static function getAllCustomFields($group_id) {
428     $mdb2 = getConnection();
429
430     $sql = "select * from tt_custom_fields where group_id = $group_id order by status";
431
432     $res = $mdb2->query($sql);
433     $result = array();
434     if (!is_a($res, 'PEAR_Error')) {
435       while ($val = $res->fetchRow()) {
436         $result[] = $val;
437       }
438       return $result;
439     }
440     return false;
441   }
442
443   // The getAllCustomFieldOptions obtains all custom field options in a group.
444   static function getAllCustomFieldOptions($group_id) {
445     $mdb2 = getConnection();
446
447     $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";
448
449     $res = $mdb2->query($sql);
450     $result = array();
451     if (!is_a($res, 'PEAR_Error')) {
452       while ($val = $res->fetchRow()) {
453         $result[] = $val;
454       }
455       return $result;
456     }
457     return false;
458   }
459
460   // The getCustomFieldLog obtains all custom field log entries for a group.
461   static function getCustomFieldLog($group_id) {
462     $mdb2 = getConnection();
463
464     $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";
465
466     $res = $mdb2->query($sql);
467     $result = array();
468     if (!is_a($res, 'PEAR_Error')) {
469       while ($val = $res->fetchRow()) {
470         $result[] = $val;
471       }
472       return $result;
473     }
474     return false;
475   }
476
477   // getFavReports - obtains all favorite reports for all users in a group.
478   static function getFavReports($group_id) {
479     $mdb2 = getConnection();
480
481     $result = array();
482     $sql = "select * from tt_fav_reports where user_id in (select id from tt_users where group_id = $group_id)";
483     $res = $mdb2->query($sql);
484     $result = array();
485     if (!is_a($res, 'PEAR_Error')) {
486       while ($val = $res->fetchRow()) {
487         $result[] = $val;
488       }
489       return $result;
490     }
491     return false;
492   }
493
494   // getExpenseItems - obtains all expense items for all users in a group.
495   static function getExpenseItems($group_id) {
496     $mdb2 = getConnection();
497
498     $result = array();
499     $sql = "select * from tt_expense_items where user_id in (select id from tt_users where group_id = $group_id)";
500     $res = $mdb2->query($sql);
501     $result = array();
502     if (!is_a($res, 'PEAR_Error')) {
503       while ($val = $res->fetchRow()) {
504         $result[] = $val;
505       }
506       return $result;
507     }
508     return false;
509   }
510
511   // getNotifications - obtains notification descriptions for a group.
512   static function getNotifications($group_id) {
513     $mdb2 = getConnection();
514
515     $result = array();
516     $sql = "select c.id, c.cron_spec, c.email, c.report_condition, fr.name from tt_cron c
517       left join tt_fav_reports fr on (fr.id = c.report_id)
518       where c.group_id = $group_id and c.status = 1 and fr.status = 1";
519     $res = $mdb2->query($sql);
520     $result = array();
521     if (!is_a($res, 'PEAR_Error')) {
522       while ($val = $res->fetchRow()) {
523         $result[] = $val;
524       }
525       return $result;
526     }
527     return false;
528   }
529
530   // getMonthlyQuotas - obtains monthly quotas for a group.
531   static function getMonthlyQuotas($group_id) {
532     $mdb2 = getConnection();
533
534     $result = array();
535     $sql = "select year, month, minutes from tt_monthly_quotas where group_id = $group_id";
536     $res = $mdb2->query($sql);
537     $result = array();
538     if (!is_a($res, 'PEAR_Error')) {
539       while ($val = $res->fetchRow()) {
540         $result[] = $val;
541       }
542       return $result;
543     }
544     return false;
545   }
546
547   // The delete function permanently deletes all data for a group.
548   static function delete($group_id) {
549     $mdb2 = getConnection();
550
551     // Delete users.
552     $sql = "select id from tt_users where group_id = $group_id";
553     $res = $mdb2->query($sql);
554     if (is_a($res, 'PEAR_Error')) return false;
555     while ($val = $res->fetchRow()) {
556       $user_id = $val['id'];
557       if (!ttUserHelper::delete($user_id)) return false;
558     }
559
560     // Delete tasks.
561     if (!ttTeamHelper::deleteTasks($group_id)) return false;
562
563     // Delete client to project binds.
564     $sql = "delete from tt_client_project_binds where client_id in (select id from tt_clients where group_id = $group_id)";
565     $affected = $mdb2->exec($sql);
566     if (is_a($affected, 'PEAR_Error')) return false;
567
568     // Delete projects.
569     $sql = "delete from tt_projects where group_id = $group_id";
570     $affected = $mdb2->exec($sql);
571     if (is_a($affected, 'PEAR_Error')) return false;
572
573     // Delete clients.
574     $sql = "delete from tt_clients where group_id = $group_id";
575     $affected = $mdb2->exec($sql);
576     if (is_a($affected, 'PEAR_Error')) return false;
577
578     // Delete invoices.
579     $sql = "delete from tt_invoices where group_id = $group_id";
580     $affected = $mdb2->exec($sql);
581     if (is_a($affected, 'PEAR_Error')) return false;
582
583     // Delete custom fields.
584     if (!ttTeamHelper::deleteCustomFields($group_id)) return false;
585
586     // Delete roles.
587     $sql = "delete from tt_roles where group_id = $group_id";
588     $affected = $mdb2->exec($sql);
589     if (is_a($affected, 'PEAR_Error')) return false;
590
591     // Delete cron entries.
592     $sql = "delete from tt_cron where group_id = $group_id";
593     $affected = $mdb2->exec($sql);
594     if (is_a($affected, 'PEAR_Error')) return false;
595
596     // Delete predefined expenses.
597     $sql = "delete from tt_predefined_expenses where group_id = $group_id";
598     $affected = $mdb2->exec($sql);
599     if (is_a($affected, 'PEAR_Error')) return false;
600
601     // Delete monthly quotas.
602     $sql = "delete from tt_monthly_quotas where group_id = $group_id";
603     $affected = $mdb2->exec($sql);
604     if (is_a($affected, 'PEAR_Error')) return false;
605
606     // Delete group.
607     $sql = "delete from tt_groups where id = $group_id";
608     $affected = $mdb2->exec($sql);
609     if (is_a($affected, 'PEAR_Error')) return false;
610
611     return true;
612   }
613
614   // The deleteTasks deletes all tasks and task binds for an inactive group.
615   static function deleteTasks($group_id) {
616     $mdb2 = getConnection();
617     $sql = "select id from tt_tasks where group_id = $group_id";
618     $res = $mdb2->query($sql);
619     if (is_a($res, 'PEAR_Error')) return false;
620
621     while ($val = $res->fetchRow()) {
622
623       // Delete task binds.
624       $task_id = $val['id'];
625       $sql = "delete from tt_project_task_binds where task_id = $task_id";
626       $affected = $mdb2->exec($sql);
627       if (is_a($affected, 'PEAR_Error')) return false;
628
629       // Delete task.
630       $sql = "delete from tt_tasks where id = $task_id";
631       $affected = $mdb2->exec($sql);
632       if (is_a($affected, 'PEAR_Error')) return false;
633     }
634
635     return true;
636   }
637
638   // The deleteCustomFields cleans up tt_custom_field_log, tt_custom_field_options and tt_custom_fields tables for an inactive group.
639   static function deleteCustomFields($group_id) {
640     $mdb2 = getConnection();
641     $sql = "select id from tt_custom_fields where group_id = $group_id";
642     $res = $mdb2->query($sql);
643     if (is_a($res, 'PEAR_Error')) return false;
644
645     while ($val = $res->fetchRow()) {
646       $field_id = $val['id'];
647
648       // Clean up tt_custom_field_log.
649       $sql = "delete from tt_custom_field_log where field_id = $field_id";
650       $affected = $mdb2->exec($sql);
651       if (is_a($affected, 'PEAR_Error')) return false;
652
653       // Clean up tt_custom_field_options.
654       $sql = "delete from tt_custom_field_options where field_id = $field_id";
655       $affected = $mdb2->exec($sql);
656       if (is_a($affected, 'PEAR_Error')) return false;
657
658       // Delete custom field.
659       $sql = "delete from tt_custom_fields where id = $field_id";
660       $affected = $mdb2->exec($sql);
661       if (is_a($affected, 'PEAR_Error')) return false;
662     }
663
664     return true;
665   }
666 }