cf455405bbd5b97ca0407d348d0a1c93826b597e
[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   // getMonthlyQuotas - obtains monthly quotas for a group.
512   static function getMonthlyQuotas($group_id) {
513     $mdb2 = getConnection();
514
515     $result = array();
516     $sql = "select year, month, minutes from tt_monthly_quotas where group_id = $group_id";
517     $res = $mdb2->query($sql);
518     $result = array();
519     if (!is_a($res, 'PEAR_Error')) {
520       while ($val = $res->fetchRow()) {
521         $result[] = $val;
522       }
523       return $result;
524     }
525     return false;
526   }
527
528   // The delete function permanently deletes all data for a group.
529   static function delete($group_id) {
530     $mdb2 = getConnection();
531
532     // Delete users.
533     $sql = "select id from tt_users where group_id = $group_id";
534     $res = $mdb2->query($sql);
535     if (is_a($res, 'PEAR_Error')) return false;
536     while ($val = $res->fetchRow()) {
537       $user_id = $val['id'];
538       if (!ttUserHelper::delete($user_id)) return false;
539     }
540
541     // Delete tasks.
542     if (!ttTeamHelper::deleteTasks($group_id)) return false;
543
544     // Delete client to project binds.
545     $sql = "delete from tt_client_project_binds where client_id in (select id from tt_clients where group_id = $group_id)";
546     $affected = $mdb2->exec($sql);
547     if (is_a($affected, 'PEAR_Error')) return false;
548
549     // Delete projects.
550     $sql = "delete from tt_projects where group_id = $group_id";
551     $affected = $mdb2->exec($sql);
552     if (is_a($affected, 'PEAR_Error')) return false;
553
554     // Delete clients.
555     $sql = "delete from tt_clients where group_id = $group_id";
556     $affected = $mdb2->exec($sql);
557     if (is_a($affected, 'PEAR_Error')) return false;
558
559     // Delete invoices.
560     $sql = "delete from tt_invoices where group_id = $group_id";
561     $affected = $mdb2->exec($sql);
562     if (is_a($affected, 'PEAR_Error')) return false;
563
564     // Delete custom fields.
565     if (!ttTeamHelper::deleteCustomFields($group_id)) return false;
566
567     // Delete roles.
568     $sql = "delete from tt_roles where group_id = $group_id";
569     $affected = $mdb2->exec($sql);
570     if (is_a($affected, 'PEAR_Error')) return false;
571
572     // Delete cron entries.
573     $sql = "delete from tt_cron where group_id = $group_id";
574     $affected = $mdb2->exec($sql);
575     if (is_a($affected, 'PEAR_Error')) return false;
576
577     // Delete predefined expenses.
578     $sql = "delete from tt_predefined_expenses where group_id = $group_id";
579     $affected = $mdb2->exec($sql);
580     if (is_a($affected, 'PEAR_Error')) return false;
581
582     // Delete monthly quotas.
583     $sql = "delete from tt_monthly_quotas where group_id = $group_id";
584     $affected = $mdb2->exec($sql);
585     if (is_a($affected, 'PEAR_Error')) return false;
586
587     // Delete group.
588     $sql = "delete from tt_groups where id = $group_id";
589     $affected = $mdb2->exec($sql);
590     if (is_a($affected, 'PEAR_Error')) return false;
591
592     return true;
593   }
594
595   // The deleteTasks deletes all tasks and task binds for an inactive group.
596   static function deleteTasks($group_id) {
597     $mdb2 = getConnection();
598     $sql = "select id from tt_tasks where group_id = $group_id";
599     $res = $mdb2->query($sql);
600     if (is_a($res, 'PEAR_Error')) return false;
601
602     while ($val = $res->fetchRow()) {
603
604       // Delete task binds.
605       $task_id = $val['id'];
606       $sql = "delete from tt_project_task_binds where task_id = $task_id";
607       $affected = $mdb2->exec($sql);
608       if (is_a($affected, 'PEAR_Error')) return false;
609
610       // Delete task.
611       $sql = "delete from tt_tasks where id = $task_id";
612       $affected = $mdb2->exec($sql);
613       if (is_a($affected, 'PEAR_Error')) return false;
614     }
615
616     return true;
617   }
618
619   // The deleteCustomFields cleans up tt_custom_field_log, tt_custom_field_options and tt_custom_fields tables for an inactive group.
620   static function deleteCustomFields($group_id) {
621     $mdb2 = getConnection();
622     $sql = "select id from tt_custom_fields where group_id = $group_id";
623     $res = $mdb2->query($sql);
624     if (is_a($res, 'PEAR_Error')) return false;
625
626     while ($val = $res->fetchRow()) {
627       $field_id = $val['id'];
628
629       // Clean up tt_custom_field_log.
630       $sql = "delete from tt_custom_field_log where field_id = $field_id";
631       $affected = $mdb2->exec($sql);
632       if (is_a($affected, 'PEAR_Error')) return false;
633
634       // Clean up tt_custom_field_options.
635       $sql = "delete from tt_custom_field_options where field_id = $field_id";
636       $affected = $mdb2->exec($sql);
637       if (is_a($affected, 'PEAR_Error')) return false;
638
639       // Delete custom field.
640       $sql = "delete from tt_custom_fields where id = $field_id";
641       $affected = $mdb2->exec($sql);
642       if (is_a($affected, 'PEAR_Error')) return false;
643     }
644
645     return true;
646   }
647 }