source: trunk/workflow/inc/class.so_orgchart.inc.php @ 7712

Revision 7712, 59.1 KB checked in by douglasz, 11 years ago (diff)

Ticket #3236 - Revisao das Melhorias de performance no codigo do Expresso.

  • Property svn:executable set to *
Line 
1<?php
2/**************************************************************************\
3* eGroupWare                                                               *
4* http://www.egroupware.org                                                *
5* --------------------------------------------                             *
6*  This program is free software; you can redistribute it and/or modify it *
7*  under the terms of the GNU General Public License as published by the   *
8*  Free Software Foundation; either version 2 of the License, or (at your  *
9*  option) any later version.                                              *
10\**************************************************************************/
11
12/**
13 * Camada Model do Organograma.
14 * @package Workflow
15 * @author Sidnei Augusto Drovetto Jr. - drovetto@gmail.com
16 * @license http://www.gnu.org/copyleft/gpl.html GPL
17 */
18class so_orgchart
19{
20        /**
21         * @var bool True se o usuário for administrador do expresso.
22         * @access private
23         */
24        private $isAdmin;
25
26        /**
27         * @var int ID do usuário logado no Expresso
28         * @access private
29         */
30        private $userID;
31
32        /**
33         * @var object Link para a ACL do Workflow.
34         * @access private
35         */
36        private $acl;
37
38        /**
39         * @var object Link para o Banco de Dados do Workflow.
40         * @access private
41         */
42        private $db;
43
44        /**
45         * @var bool Indica se alguns métodos desta classe poderão ser chamados por métodos externos
46         * @access private
47         */
48        private $externalCalls = false;
49
50        /**
51         * Checa se o usuário possui acesso ao Organograma ou permissão para modificar determinada organização.
52         * @param int $organizationID O ID da organização do Orgranograma.
53         * @param bool $checkType Indica se a checagem não depende do ID da organização.
54         * @param bool $safeMethod Indica que a checagem pode ser ignorada quando chamada por outras partes do módulo Workflow
55         * @return void
56         * @access private
57         */
58        private function _checkAccess($organizationID = null, $checkType = false, $safeMethod = false)
59        {
60                /* the user is an administrator */
61                if ($this->isAdmin)
62                        return true;
63
64                if ($safeMethod)
65                        if ($this->externalCalls)
66                                return true;
67
68                $authorized = false;
69                if ($checkType)
70                        $authorized = $this->acl->checkUserGroupAccessToType('ORG', $this->userID);
71                else
72                {
73                        if (!is_numeric($organizationID))
74                                $authorized = false;
75                        else
76                                $authorized = $this->acl->checkUserGroupAccessToResource('ORG', $this->userID, (int) $organizationID);
77                }
78
79                if (!$authorized)
80                        $this->endExecution("Você não tem permissão para executar este procedimento!");
81        }
82
83        /**
84         * Finaliza a execução e envia uma mensagem serializada (para ser exibida no retorno do Ajax).
85         * @param mixed A mensagem que será exibida. Pode ser uma array de mensagens ou uma string.
86         * @return void
87         * @access private
88         */
89        private function endExecution($message)
90        {
91                if (!is_array($message))
92                        $message = array($message);
93
94                die(serialize(implode("\n", $message)));
95        }
96
97        /**
98         * Define que alguns métodos desta classe poderão ser chamados.
99         * @param bool $satus O status. true para permitir e false para restringir.
100         * @return void
101         * @access public
102         */
103        public function setExternalCalls($status)
104        {
105                $this->externalCalls = ($status === true);
106        }
107
108        /**
109         * Verifica se houve erro em alguma query do Banco de Dados.
110         * @param object $result O resultado de alguma query
111         * @return void
112         * @access private
113         */
114        private function _checkError($result)
115        {
116                if ($result === false)
117                        die(serialize("Ocorreu um erro ao se tentar executar a operação solicitada."));
118        }
119
120        /**
121         * Construtor da classe so_orgchart
122         * @return object
123         */
124        function so_orgchart()
125        {
126                $this->userID = $_SESSION['phpgw_info']['workflow']['account_id'];
127                $this->isAdmin = $_SESSION['phpgw_info']['workflow']['user_is_admin'];
128                $this->acl = &$GLOBALS['ajax']->acl;
129                $this->db = &Factory::getInstance('WorkflowObjects')->getDBWorkflow()->Link_ID;
130                $this->db->SetFetchMode(ADODB_FETCH_ASSOC);
131        }
132
133        /**
134         * Lista todas as organizações do Organograma.
135         * @return array Lista de organizações.
136         * @access public
137         */
138        function getOrganizations()
139        {
140                $this->_checkAccess(null, true);
141
142                if ($this->isAdmin)
143                        $query = "SELECT organizacao_id, nome, descricao, ativa, url_imagem, sitio FROM organizacao ORDER BY nome";
144                else
145                {
146                        $organizations = $this->acl->getUserGroupPermissions("ORG", $this->userID, 0);
147                        $organizations[] = -1;
148                        $query = "SELECT organizacao_id, nome, descricao, ativa, url_imagem, sitio FROM organizacao WHERE (organizacao_id IN (" . implode(',', $organizations)  . ")) ORDER BY nome";
149                }
150                $result = $this->db->query($query);
151                $this->_checkError($result);
152
153                $output = $result->GetArray(-1);
154
155                for ($i = 0; $i < count($output); ++$i)
156                        for ($j = 0; $j < $result->_numOfFields; ++$j)
157                                unset($output[$i][$j]);
158
159                return $output;
160        }
161
162        /**
163         * Adiciona uma organização.
164         * @param string $name O nome da organização.
165         * @param string $description A descrição da organização.
166         * @param string $imageURL O caminho da imagem que representa o organograma da organização.
167         * @param char $active 'S' se a organização estiver ativa e 'N' caso contrário.
168         * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário.
169         * @access public
170         */
171        function addOrganization($name, $description, $imageURL, $active, $siteURL)
172        {
173                $this->_checkAccess(null, true);
174
175                $query = "INSERT INTO organizacao(nome, descricao, url_imagem, ativa, sitio) VALUES(?, ?, ?, ?, ?)";
176                $result = $this->db->query($query, array($name, $description, $imageURL, $active, $siteURL));
177                $this->_checkError($result);
178
179                return (($result === false) ? false : true);
180        }
181
182        /**
183         * Atualiza as informações sobre uma organização.
184         * @param string $name O nome da organização.
185         * @param string $description A descrição da organização.
186         * @param string $imageURL O caminho da imagem que representa o organograma da organização.
187         * @param char $active 'S' se a organização estiver ativa e 'N' caso contrário.
188         * @param int $organizationID O ID da organização do Orgranograma.
189         * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário.
190         * @access public
191         */
192        function updateOrganization($name, $description, $imageURL, $active, $organizationID, $siteURL)
193        {
194                $this->_checkAccess($organizationID);
195
196                $query = "UPDATE organizacao SET nome = ?, descricao = ?, url_imagem = ?, ativa = ?, sitio = ? WHERE (organizacao_id = ?)";
197                $result = $this->db->query($query, array($name, $description, $imageURL, $active, $siteURL, $organizationID));
198                $this->_checkError($result);
199
200                return (($result === false) ? false : true);
201        }
202
203        /**
204         * Remove uma organização.
205         * @param int $organizationID O ID da organização do Orgranograma.
206         * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário.
207         * @access public
208         */
209        function removeOrganization($organizationID)
210        {
211                $this->_checkAccess($organizationID);
212
213                $query = "DELETE FROM organizacao WHERE (organizacao_id = ?)";
214                $result = $this->db->query($query, array($organizationID));
215                $this->_checkError($result);
216
217                return (($result === false) ? false : true);
218        }
219
220        /**
221         * Lista os possíveis status dos funcionários.
222         * @param int $organizationID O ID da organização do Orgranograma.
223         * @return array Lista dos possíveis status dos empregados.
224         * @access public
225         */
226        function getEmployeeStatus($organizationID)
227        {
228                $this->_checkAccess($organizationID);
229
230                $query = "SELECT funcionario_status_id, descricao, exibir, organizacao_id FROM funcionario_status WHERE (organizacao_id = ?) ORDER BY descricao";
231                $result = $this->db->query($query, array($organizationID));
232                $this->_checkError($result);
233
234                $output = $result->GetArray(-1);
235
236                return $output;
237        }
238
239        /**
240         * Adiciona um Status de funcionário.
241         * @param int $organizationID O ID da organização do Orgranograma.
242         * @param string $description A descrição do status.
243         * @param char $show 'S' se o funcionário será exibido na interface de organograma do usuário ou 'N' caso contrário.
244         * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário.
245         * @access public
246         */
247        function addEmployeeStatus($organizationID, $description, $show)
248        {
249                $this->_checkAccess($organizationID);
250
251                $query = "INSERT INTO funcionario_status(organizacao_id, descricao, exibir) VALUES(?, ?, ?)";
252                $result = $this->db->query($query, array($organizationID, $description, $show));
253                $this->_checkError($result);
254
255                return (($result === false) ? false : true);
256        }
257
258        /**
259         * Atualiza um Status de funcionário.
260         * @param int $employeeStatusID O ID do status de funcionário.
261         * @param int $organizationID O ID da organização do Orgranograma.
262         * @param string $description A descrição do status.
263         * @param char $show 'S' se o funcionário será exibido na interface de organograma do usuário ou 'N' caso contrário.
264         * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário.
265         * @access public
266         */
267        function updateEmployeeStatus($employeeStatusID, $organizationID, $description, $show)
268        {
269                $this->_checkAccess($organizationID);
270
271                $query = "UPDATE funcionario_status SET descricao = ?, exibir = ? WHERE (funcionario_status_id = ?) AND (organizacao_id = ?)";
272                $result = $this->db->query($query, array($description, $show, $employeeStatusID, $organizationID));
273                $this->_checkError($result);
274
275                return (($result === false) ? false : true);
276        }
277
278        /**
279         * Remove um Status de funcionário.
280         * @param int $employeeStatusID O ID do status de funcionário.
281         * @param int $organizationID O ID da organização do Orgranograma.
282         * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário.
283         * @access public
284         */
285        function removeEmployeeStatus($employeeStatusID, $organizationID)
286        {
287                $this->_checkAccess($organizationID);
288
289                $query = "DELETE FROM funcionario_status WHERE (funcionario_status_id = ?) AND (organizacao_id = ?)";
290                $result = $this->db->query($query, array($employeeStatusID, $organizationID));
291                $this->_checkError($result);
292
293                return (($result === false) ? false : true);
294        }
295
296        /**
297         * Lista as possíveis categorias de uma organização.
298         * @param int $organizationID O ID da organização.
299         * @return array Lista das possíveis categorias de uma organização.
300         * @access public
301         */
302        function getEmployeeCategory($organizationID)
303        {
304                $this->_checkAccess($organizationID);
305
306                $query = "SELECT funcionario_categoria_id, organizacao_id, descricao FROM funcionario_categoria WHERE (organizacao_id = ?) ORDER BY descricao";
307                $result = $this->db->query($query, array($organizationID));
308                $this->_checkError($result);
309
310                $output = $result->GetArray(-1);
311                for ($i = 0; $i < count($output); ++$i)
312                        for ($j = 0; $j < $result->_numOfFields; ++$j)
313                                unset($output[$i][$j]);
314
315                return $output;
316        }
317
318        /**
319         * Adiciona uma categoria.
320         * @param int $organizationID O ID da organização.
321         * @param string $description A descrição da categoria.
322         * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário.
323         * @access public
324         */
325        function addEmployeeCategory($organizationID, $description)
326        {
327                $this->_checkAccess($organizationID);
328
329                $query = "INSERT INTO funcionario_categoria(organizacao_id, descricao) VALUES(?, ?)";
330                $result = $this->db->query($query, array($organizationID, $description));
331                $this->_checkError($result);
332
333                return (($result === false) ? false : true);
334        }
335
336        /**
337         * Atualiza uma categoria.
338         * @param int $employeeCategoryID O ID da categoria.
339         * @param int $organizationID O ID da organização.
340         * @param string $description A descrição da categoria.
341         * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário.
342         * @access public
343         */
344        function updateEmployeeCategory($employeeCategoryID, $organizationID, $description)
345        {
346                $this->_checkAccess($organizationID);
347
348                $query = "UPDATE funcionario_categoria SET descricao = ? WHERE (funcionario_categoria_id = ?) AND (organizacao_id = ?)";
349                $result = $this->db->query($query, array($description, $employeeCategoryID, $organizationID));
350                $this->_checkError($result);
351
352                return (($result === false) ? false : true);
353        }
354
355        /**
356         * Remove uma categoria.
357         * @param int $employeeCategoryID O ID da categoria.
358         * @param int $organizationID O ID da organização.
359         * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário.
360         * @access public
361         */
362        function removeEmployeeCategory($employeeCategoryID, $organizationID)
363        {
364                $this->_checkAccess($organizationID);
365
366                $query = "DELETE FROM funcionario_categoria WHERE (funcionario_categoria_id = ?) AND (organizacao_id = ?)";
367                $result = $this->db->query($query, array($employeeCategoryID, $organizationID));
368                $this->_checkError($result);
369
370                return (($result === false) ? false : true);
371        }
372
373        /**
374         * Lista os possíveis cargos de uma organização.
375         * @param int $organizationID O ID da organização.
376         * @return array Lista dos possíveis cargos de uma organização.
377         * @access public
378         */
379        function getJobTitle($organizationID)
380        {
381                $this->_checkAccess($organizationID);
382
383                $query = "SELECT cargo_id, organizacao_id, descricao FROM cargo WHERE (organizacao_id = ?) ORDER BY descricao";
384                $result = $this->db->query($query, array($organizationID));
385                $this->_checkError($result);
386
387                $output = $result->GetArray(-1);
388
389                for ($i = 0; $i < count($output); ++$i)
390                        for ($j = 0; $j < $result->_numOfFields; ++$j)
391                                unset($output[$i][$j]);
392
393                return $output;
394        }
395
396        /**
397         * Adiciona um cargo.
398         * @param int $organizationID O ID da organização.
399         * @param string $description A descrição do cargo.
400         * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário.
401         * @access public
402         */
403        function addJobTitle($organizationID, $description)
404        {
405                $this->_checkAccess($organizationID);
406
407                $query = "INSERT INTO cargo(organizacao_id, descricao) VALUES(?, ?)";
408                $result = $this->db->query($query, array($organizationID, $description));
409                $this->_checkError($result);
410
411                return (($result === false) ? false : true);
412        }
413
414        /**
415         * Atualiza um cargo.
416         * @param int $jobTitleID O ID do cargo.
417         * @param int $organizationID O ID da organização.
418         * @param string $description A descrição do cargo.
419         * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário.
420         * @access public
421         */
422        function updateJobTitle($jobTitleID, $organizationID, $description)
423        {
424                $this->_checkAccess($organizationID);
425
426                $query = "UPDATE cargo SET descricao = ? WHERE (cargo_id = ?) AND (organizacao_id = ?)";
427                $result = $this->db->query($query, array($description, $jobTitleID, $organizationID));
428                $this->_checkError($result);
429
430                return (($result === false) ? false : true);
431        }
432
433        /**
434         * Remove um cargo.
435         * @param int $jobTitleID O ID do cargo.
436         * @param int $organizationID O ID da organização.
437         * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário.
438         * @access public
439         */
440        function removeJobTitle($jobTitleID, $organizationID)
441        {
442                $this->_checkAccess($organizationID);
443
444                $query = "DELETE FROM cargo WHERE (cargo_id = ?) AND (organizacao_id = ?)";
445                $result = $this->db->query($query, array($jobTitleID, $organizationID));
446                $this->_checkError($result);
447
448                return (($result === false) ? false : true);
449        }
450
451        /**
452         * Lista os possíveis status das áreas de uma organização.
453         * @param int $organizationID O ID da organização.
454         * @return array Lista dos possíveis status das áreas de uma organização.
455         * @access public
456         */
457        function getAreaStatus($organizationID)
458        {
459                $this->_checkAccess($organizationID);
460
461                $query = "SELECT area_status_id, organizacao_id, descricao, nivel FROM area_status WHERE organizacao_id = ? ORDER BY descricao";
462                $result = $this->db->query($query, array($organizationID));
463                $this->_checkError($result);
464
465                $output = $result->GetArray(-1);
466
467                for ($i = 0; $i < count($output); ++$i)
468                        for ($j = 0; $j < $result->_numOfFields; ++$j)
469                                unset($output[$i][$j]);
470
471                return $output;
472        }
473
474        /**
475         * Adiciona um status de área.
476         * @param int $organizationID O ID da organização.
477         * @param string $description A descrição do status.
478         * @param int $level O nível do status.
479         * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário.
480         * @access public
481         */
482        function addAreaStatus($organizationID, $description, $level)
483        {
484                $this->_checkAccess($organizationID);
485
486                $query = "INSERT INTO area_status(organizacao_id, descricao, nivel) VALUES(?, ?, ?)";
487                $result = $this->db->query($query, array($organizationID, $description, $level));
488                $this->_checkError($result);
489
490                return (($result === false) ? false : true);
491        }
492
493        /**
494         * Atualiza um status de área.
495         * @param int $areaStatusID O ID do status da área.
496         * @param int $organizationID O ID da organização.
497         * @param string $description A descrição do status.
498         * @param int $level O nível do status.
499         * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário.
500         * @access public
501         */
502        function updateAreaStatus($areaStatusID, $organizationID, $description, $level)
503        {
504                $this->_checkAccess($organizationID);
505
506                $query = "UPDATE area_status SET descricao = ?, nivel = ? WHERE (area_status_id = ?) AND (organizacao_id = ?)";
507                $result = $this->db->query($query, array($description, $level, $areaStatusID, $organizationID));
508                $this->_checkError($result);
509
510                return (($result === false) ? false : true);
511        }
512
513        /**
514         * Remove um status de área.
515         * @param int $areaStatusID O ID do status da área.
516         * @param int $organizationID O ID da organização.
517         * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário.
518         * @access public
519         */
520        function removeAreaStatus($areaStatusID, $organizationID)
521        {
522                $this->_checkAccess($organizationID);
523
524                $query = "DELETE FROM area_status WHERE (area_status_id = ?) AND (organizacao_id = ?)";
525                $result = $this->db->query($query, array($areaStatusID, $organizationID));
526                $this->_checkError($result);
527
528                return (($result === false) ? false : true);
529        }
530
531        /**
532         * Lista os centros de custo de uma organização.
533         * @param int $organizationID O ID da organização.
534         * @return array Lista dos centros de custo de uma organização.
535         * @access public
536         */
537        function getCostCenter($organizationID)
538        {
539                $this->_checkAccess($organizationID);
540
541                $query = "SELECT organizacao_id, centro_custo_id, nm_centro_custo, descricao, grupo FROM centro_custo WHERE organizacao_id = ? ORDER BY descricao";
542                $result = $this->db->query($query, array($organizationID));
543                $this->_checkError($result);
544
545                $output = $result->GetArray(-1);
546
547                for ($i = 0; $i < count($output); ++$i)
548                        for ($j = 0; $j < $result->_numOfFields; ++$j)
549                                unset($output[$i][$j]);
550
551                return $output;
552        }
553
554        /**
555         * Adiciona um centro de custo.
556         * @param int $organizationID O ID da organização.
557         * @param int $number O número do centro de custo.
558         * @param string $description A descrição do centro de custo.
559         * @param string $group O grupo do centro de custo.
560         * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário.
561         * @access public
562         */
563        function addCostCenter($organizationID, $number, $description, $group)
564        {
565                $this->_checkAccess($organizationID);
566
567                $query = "INSERT INTO centro_custo(organizacao_id, nm_centro_custo, descricao, grupo) VALUES(?, ?, ?, ?)";
568                $result = $this->db->query($query, array($organizationID, $number, $description, $group));
569                $this->_checkError($result);
570
571                return (($result === false) ? false : true);
572        }
573
574        /**
575         * Atualiza um centro de custo.
576         * @param int $organizationID O ID da organização.
577         * @param int $number O número do centro de custo.
578         * @param string $description A descrição do centro de custo.
579         * @param string $group O grupo do centro de custo.
580         * @param int $costCenterID O ID do centro de custo.
581         * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário.
582         * @access public
583         */
584        function updateCostCenter($organizationID, $number, $description, $group, $costCenterID)
585        {
586                $this->_checkAccess($organizationID);
587
588                $query = "UPDATE centro_custo SET organizacao_id = ?, nm_centro_custo = ?, descricao = ?, grupo = ? WHERE (centro_custo_id = ?)";
589                $result = $this->db->query($query, array($organizationID, $number, $description, $group, $costCenterID));
590                $this->_checkError($result);
591
592                return (($result === false) ? false : true);
593        }
594
595        /**
596         * Remove um centro de custo.
597         * @param int $costCenterID O ID do centro de custo.
598         * @param int $organizationID O ID da organização.
599         * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário.
600         * @access public
601         */
602        function removeCostCenter($costCenterID, $organizationID)
603        {
604                $this->_checkAccess($organizationID);
605
606                $query = "DELETE FROM centro_custo WHERE (centro_custo_id = ?) AND (organizacao_id = ?)";
607                $result = $this->db->query($query, array($costCenterID, $organizationID));
608                $this->_checkError($result);
609
610                return (($result === false) ? false : true);
611        }
612
613        /**
614         * Lista as localidade de uma organização.
615         * @param int $organizationID O ID da organização.
616         * @return array Lista das localidades de uma organização.
617         * @access public
618         */
619        function getLocal($organizationID)
620        {
621                $this->_checkAccess($organizationID);
622
623                $query_fields = 'organizacao_id, localidade_id, centro_custo_id, descricao, empresa, endereco, complemento, cep, bairro, cidade, uf, externa';
624                $query = "SELECT {$query_fields} FROM localidade WHERE organizacao_id = ? ORDER BY descricao";
625                $result = $this->db->query($query, array($organizationID));
626                $this->_checkError($result);
627
628                $output = $result->GetArray(-1);
629
630                for ($i = 0; $i < count($output); ++$i){
631                        for ($j = 0; $j < $result->_numOfFields; ++$j)
632                                unset($output[$i][$j]);
633                        $output[$i]['centro_custo_id'] = empty($output[$i]['centro_custo_id']) ? 'NULL' : $output[$i]['centro_custo_id'];
634                }
635
636                return $output;
637        }
638
639        /**
640         * Adiciona uma localidade.
641         * @param int $organizationID O ID da organização.
642         * @param int $costCenterID O ID do centro de custo.
643         * @param string $description A descrição da localidade.
644         * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário.
645         * @access public
646         */
647        function addLocal($organizationID, $costCenter, $description, $company, $address, $complement, $zipCode, $neighborhood, $city, $state, $external )
648        {
649                $this->_checkAccess($organizationID);
650
651                $query = "INSERT INTO localidade(organizacao_id, centro_custo_id, descricao, empresa, endereco, complemento, cep, bairro, cidade, uf, externa) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
652                $result = $this->db->query($query, array($organizationID, $costCenter, $description, $company, $address, $complement, $zipCode, $neighborhood, $city, $state, $external ));
653                $this->_checkError($result);
654
655                return (($result === false) ? false : true);
656        }
657
658        /**
659         * Atualiza uma localidade.
660         * @param int $organizationID O ID da organização.
661         * @param int $costCenterID O ID do centro de custo.
662         * @param string $description A descrição da localidade.
663         * @param int $localID O ID da localidade.
664         * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário.
665         * @access public
666         */
667        function updateLocal($organizationID, $costCenter, $description, $localID, $company, $address, $complement, $zipCode, $neighborhood, $city, $state, $external )
668        {
669                $this->_checkAccess($organizationID);
670
671                $query = "UPDATE localidade SET organizacao_id = ?, centro_custo_id = ?, descricao = ?, empresa = ?, endereco = ?, complemento = ?, cep = ?, bairro = ?, cidade = ?, uf = ?, externa = ? WHERE (localidade_id = ?)";
672                $result = $this->db->query($query, array($organizationID, $costCenter, $description, $company, $address, $complement, $zipCode, $neighborhood, $city, $state, $external, $localID) );
673                $this->_checkError($result);
674
675                return (($result === false) ? false : true);
676        }
677
678        /**
679         * Remove uma localidade.
680         * @param int $organizationID O ID da organização.
681         * @param int $localID O ID da localidade.
682         * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário.
683         * @access public
684         */
685        function removeLocal($localID, $organizationID)
686        {
687                $this->_checkAccess($organizationID);
688
689                $query = "DELETE FROM localidade WHERE (localidade_id = ?) AND (organizacao_id = ?)";
690                $result = $this->db->query($query, array($localID, $organizationID));
691                $this->_checkError($result);
692
693                return (($result === false) ? false : true);
694        }
695
696        /**
697         * Lista os funcionários de uma determinada área da organização.
698         * @param int $areaID O ID da área.
699         * @param int $organizationID O ID da organização.
700         * @return array Lista dos funcionários de uma determinada área da organização.
701         * @access public
702         */
703        function getAreaEmployee($areaID, $organizationID)
704        {
705                $this->_checkAccess($organizationID);
706
707                /* gather some info from the area */
708                $areaInfo = $this->db->query('SELECT COALESCE(a.titular_funcionario_id, -1) AS titular_funcionario_id, COALESCE(s.funcionario_id, -1) AS substituto_funcionario_id FROM area a LEFT OUTER JOIN substituicao s ON ((a.area_id = s.area_id) AND (CURRENT_DATE BETWEEN s.data_inicio AND s.data_fim)) WHERE (a.organizacao_id = ?) AND (a.area_id = ?)', array($organizationID, $areaID))->GetArray(-1);
709                if (empty($areaInfo))
710                        return false;
711                $areaInfo = $areaInfo[0];
712                $supervisors = '{' . implode(', ', $areaInfo) . '}';
713
714                $query = "SELECT funcionario_id, funcionario_status_id, centro_custo_id, localidade_id, organizacao_id, area_id, cargo_id, nivel, funcionario_categoria_id, titulo, funcao, to_char(data_admissao,'DD/MM/YYYY') as data_admissao, apelido FROM funcionario WHERE ((area_id = ?) AND (organizacao_id = ?)) OR (funcionario_id = ANY (?))";
715                $result = $this->db->query($query, array($areaID, $organizationID, $supervisors));
716                $this->_checkError($result);
717
718                $output = $result->GetArray(-1);
719                $cachedLDAP = Factory::newInstance('CachedLDAP');
720                $cachedLDAP->setOperationMode($cachedLDAP->OPERATION_MODE_LDAP_DATABASE);
721        $output_count = count($output);
722                for ($i = 0; $i < $output_count; ++$i)
723                {
724                        $output[$i]['funcionario_id_desc'] = '';
725                        $output[$i]['uid'] = '';
726
727                        if (in_array($output[$i]['funcionario_id'], $areaInfo))
728                                $output[$i]['chief'] = ($output[$i]['funcionario_id'] == $areaInfo['titular_funcionario_id']) ? 1 : 2;
729
730                        if (($entry = $cachedLDAP->getEntryByID($output[$i]['funcionario_id'])))
731                        {
732                                $output[$i]['funcionario_id_desc'] = $entry['cn'];
733                                $output[$i]['uid'] = $entry['uid'];
734                                $output[$i]['removed'] = is_null($entry['last_update']);
735                        }
736                }
737
738                usort($output, create_function('$a,$b', 'return strcasecmp($a[\'funcionario_id_desc\'],$b[\'funcionario_id_desc\']);'));
739                return $output;
740        }
741
742        /**
743         * Procura por funcionários de acordo com um termo de busca.
744         * @param string $searchTerm O termo de busca. Pode ser referente ao ID do funcionário ou ao nome do mesmo.
745         * @param int $organizationID O ID da organização.
746         * @return array Lista dos funcionários que satisfazem o critério de busca.
747         * @access public
748         */
749        function searchEmployee($searchTerm, $organizationID)
750        {
751                $organizationID = (int) $organizationID;
752                $this->_checkAccess($organizationID);
753
754                /* initialize some variables */
755                $output = array();
756                $unifiedResult = array();
757
758                /* FIXME - this piece of code should use the new CacheLdap class */
759                if (is_numeric($searchTerm))
760                {
761                        $searchTerm = (int) $searchTerm;
762                        $ldapSearch = "(&(|(employeenumber={$searchTerm})(uidnumber={$searchTerm}))(phpgwaccounttype=u))";
763                        $DBSearch = "SELECT uidnumber, cn, uid, last_update FROM egw_wf_user_cache WHERE (employeenumber = ?) OR (uidnumber = ?)";
764                        $DBValues = array($searchTerm, $searchTerm);
765                }
766                else
767                {
768                        $ldapSearch = "(&(cn=*{$searchTerm}*)(phpgwaccounttype=u))";
769                        $DBSearch = "SELECT uidnumber, cn, uid, last_update FROM egw_wf_user_cache WHERE (cn ILIKE ?)";
770                        $DBValues = array("%{$searchTerm}%");
771                }
772
773                /* search for the $searchTerm in the LDAP */
774                $ldap = &Factory::getInstance('WorkflowObjects')->getLDAP();
775                $list = @ldap_search($ldap, Factory::getInstance('WorkflowLDAP')->getLDAPContext(), $ldapSearch, array('uidnumber', 'cn', 'uid'));
776                if ($list === false)
777                        die(serialize("O sistema de busca não pode ser utilizado nesta organização."));
778                $entries = ldap_get_entries($ldap, $list);
779                for ($i=0; $i < $entries['count']; ++$i)
780                        $unifiedResult[$entries[$i]['uidnumber'][0]] = array('name' => $entries[$i]['cn'][0], 'uid' => $entries[$i]['uid'][0], 'removed' => false);
781
782                /* search for the $searchTerm in the DB */
783                $resultSet = Factory::getInstance('WorkflowObjects')->getDBGalaxia()->Link_ID->query($DBSearch, $DBValues)->GetArray(-1);
784                foreach ($resultSet as $row)
785                        if (!isset($unifiedResult[$row['uidnumber']]))
786                                $unifiedResult[$row['uidnumber']] = array('name' => $row['cn'], 'uid' => $row['uid'], 'removed' => is_null($row['last_update']));
787
788                /* check if any result was found */
789                if (count($unifiedResult) < 1)
790                        return $output;
791
792                /* load employee information */
793                $query = "SELECT f.funcionario_id, f.funcionario_status_id, f.centro_custo_id, f.localidade_id, f.organizacao_id, f.area_id, f.cargo_id, f.nivel, f.funcionario_categoria_id, f.titulo, f.apelido, f.funcao, to_char(f.data_admissao, 'DD/MM/YYYY') as data_admissao, a.sigla AS area_sigla FROM funcionario f, area a WHERE (f.area_id = a.area_id) AND (f.organizacao_id = $organizationID) AND (f.funcionario_id IN (" . implode(',', array_keys($unifiedResult))  ."))";
794                $result = $this->db->query($query);
795                $this->_checkError($result);
796
797                $output = $result->GetArray(-1);
798
799                for ($i = 0; $i < count($output); ++$i)
800                {
801                        for ($j = 0; $j < $result->_numOfFields; ++$j)
802                                unset($output[$i][$j]);
803                        $output[$i]['funcionario_id_desc'] = $unifiedResult[$output[$i]['funcionario_id']]['name'];
804                        $output[$i]['uid'] = $unifiedResult[$output[$i]['funcionario_id']]['uid'];
805                        $output[$i]['removed'] = $unifiedResult[$output[$i]['funcionario_id']]['removed'];
806                }
807
808                return $output;
809        }
810
811
812        /**
813         * Valida se o formato da data está correto..
814         * @param $date data a ser validada.
815         **/
816
817        function validateDate($date)
818        {
819                $date_pattern = '/^(0[1-9]|[12][0-9]|3[01])\/(0[1-9]|1[0-2])\/[12][0-9]{3}$/';
820
821                if (!preg_match($date_pattern, $date))
822                        $this->endExecution("Formato inválido para data (dd/mm/aaaa).");
823        }
824
825        /**
826         * Adiciona um funcionário.
827         * @param int $employeeID O ID do funcionário.
828         * @param int $organizationID O ID da organização.
829         * @param int $areaID O ID da área.
830         * @param int $costCenterID O ID do centro de custo.
831         * @param int $localID O ID da localidade.
832         * @param int $employeeStatusID O ID do status do funcionário.
833         * @param int $jobTitleID O ID do cargo do funcionário.
834         * @param int $level O nível do cargo do funcionário.
835         * @param int $title O título do funcionário.
836         * @param int $nickname O apelido do funcionário.
837         * @param int $jobDesc A descrição do cargo (função).
838         * @param int $admDate Data de admissão do funcionário.
839         * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário.
840         * @access public
841         */
842        function addEmployee($employeeID, $organizationID, $areaID, $costCenterID, $localID, $employeeStatusID, $jobTitleID, $level, $employeeCategoryID, $title, $nickname, $jobDesc, $admDate)
843        {
844                $this->_checkAccess($organizationID);
845                if ($admDate!='')
846                {
847                        $this->validateDate($admDate);
848                        $admission_date = implode('-', array_reverse(explode('/', $admDate)));
849                }
850                else
851                {
852                        $admission_date=NULL;
853                }
854
855                $query = 'SELECT area.sigla FROM funcionario, area WHERE (funcionario.area_id = area.area_id) AND (funcionario.funcionario_id = ?)';
856                if (($row = $this->db->query($query, $employeeID)->fetchRow()))
857                {
858                        $errors = array(
859                                "O funcionário \"" . Factory::getInstance('WorkflowLDAP')->getName($employeeID) . "\" já pertença à área \"{$row['sigla']}\".",
860                                '-----------------',
861                                'Caso você queira colocá-lo na área selecionada, siga o procedimento: faça uma busca por seu nome, clique para editá-lo e, troque pela área desejada.'
862                        );
863                        $this->endExecution($errors);
864                }
865
866                $query = "INSERT INTO funcionario(funcionario_id, organizacao_id, area_id, centro_custo_id, localidade_id, funcionario_status_id, cargo_id, nivel, funcionario_categoria_id, titulo, apelido, funcao, data_admissao) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
867                $result = $this->db->query($query, array($employeeID, $organizationID, $areaID, $costCenterID, $localID, $employeeStatusID, $jobTitleID, $level, $employeeCategoryID, $title, $nickname, $jobDesc, $admission_date));
868                $this->_checkError($result);
869
870                return (($result === false) ? false : true);
871        }
872
873        /**
874         * Atualiza o funcionário.
875         * @param int $employeeID O ID do funcionário.
876         * @param int $organizationID O ID da organização.
877         * @param int $areaID O ID da área.
878         * @param int $costCenterID O ID do centro de custo.
879         * @param int $localID O ID da localidade.
880         * @param int $employeeStatusID O ID do status do funcionário.
881         * @param int $jobTitleID O ID do cargo do funcionário.
882         * @param int $level O nível do cargo do funcionário.
883         * @param int $employeeCategoryID O ID da categoria do funcionário.
884         * @param int $title O título do funcionário.
885         * @param int $nickname O apelido do funcionário.
886         * @param int $jobDesc A descrição do cargo (função).
887         * @param int $admDate Data de admissão do funcionário.
888         * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário.
889         * @access public
890         */
891        function updateEmployee($employeeID, $organizationID, $areaID, $costCenterID, $localID, $employeeStatusID, $jobTitleID, $level, $employeeCategoryID, $title, $nickname, $jobDesc, $admDate)
892        {
893                $this->_checkAccess($organizationID);
894                if ($admDate!='')
895                {
896                        $this->validateDate($admDate);
897                        $admission_date = implode('-', array_reverse(explode('/', $admDate)));
898                }
899                else
900                {
901                        $admission_date=NULL;
902                }
903
904                $query = "UPDATE funcionario SET area_id = ?, centro_custo_id = ?, localidade_id = ?, funcionario_status_id = ?, cargo_id = ?, nivel = ?, funcionario_categoria_id = ?, titulo = ?, apelido = ?, funcao = ?, data_admissao =? WHERE (funcionario_id = ?) AND (organizacao_id = ?)";
905                       
906                $result = $this->db->query($query, array($areaID, $costCenterID, $localID, $employeeStatusID, $jobTitleID, $level, $employeeCategoryID, $title,$nickname, $jobDesc, $admission_date, $employeeID, $organizationID));
907               
908                $this->_checkError($result);
909               
910                return (($result === false) ? false : true);
911        }
912
913        /**
914         * Remove um funcionário.
915         * @param int $employeeID O ID do funcionário.
916         * @param int $organizationID O ID da organização.
917         * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário.
918         * @access public
919         */
920        function removeEmployee($employeeID, $organizationID)
921        {
922                $this->_checkAccess($organizationID);
923
924                $query = 'SELECT DISTINCT(a.sigla) FROM area a LEFT OUTER JOIN substituicao s USING (area_id) WHERE (? IN (a.titular_funcionario_id, s.funcionario_id, a.auxiliar_funcionario_id))';
925                $areas = array();
926                $resultSet = $this->db->query($query, $employeeID);
927                while (($row = $resultSet->fetchRow()))
928                        $areas[] = $row['sigla'];
929                if (count($areas) > 0)
930                {
931                        $errors = array(
932                                "O funcionário \"" . Factory::getInstance('WorkflowLDAP')->getName($employeeID) . "\" é titular, substituto, já participou de substituição ou é auxiliar administrativo das seguintes áreas: " . implode(", ", $areas),
933                                '-----------------',
934                                'Se você quiser excluir este funcionário, precisa removê-lo dos "cargos" que ele possui nas áreas citadas.'
935                        );
936                        $this->endExecution($errors);
937                }
938
939                $query = "DELETE FROM funcionario WHERE (funcionario_id = ?) AND (organizacao_id = ?)";
940                $result = $this->db->query($query, array($employeeID, $organizationID));
941                $this->_checkError($result);
942
943                return (($result === false) ? false : true);
944        }
945
946        /**
947         * Lista as áreas de uma organização.
948         * @param int $organizationID O ID da organização.
949         * @return array Lista das áreas de uma organização.
950         * @access public
951         */
952        function getArea($organizationID, $areaID = -1)
953        {
954                $this->_checkAccess($organizationID);
955
956                $output = array();
957                $values = array($organizationID);
958
959                // if we are looking for a specific area
960                $area_condition = "";
961                if (($areaID != -1) && !empty($areaID)) {
962                        $area_condition = " AND a.area_id = ? ";
963                        $values[]= $areaID;
964                }
965
966                $query = "SELECT a.area_id, a.centro_custo_id, a.organizacao_id, a.area_status_id, a.titular_funcionario_id, a.superior_area_id, a.sigla, a.descricao, a.ativa, a.auxiliar_funcionario_id, s.funcionario_id as substituto_funcionario_id FROM area a LEFT OUTER JOIN substituicao s ON ((a.area_id = s.area_id) AND (CURRENT_DATE BETWEEN s.data_inicio AND s.data_fim)) WHERE organizacao_id = ? " . $area_condition . " ORDER BY sigla";
967                $result = $this->db->query($query, $values);
968                $this->_checkError($result);
969
970                $ldap = &Factory::getInstance('WorkflowLDAP');
971                while ($row = $result->fetchRow(DB_FETCHMODE_ASSOC))
972                {
973                        for ($j = 0; $j < $result->_numOfFields; ++$j)
974                                unset($row[$j]);
975                        $row['substituto_funcionario_id_desc'] = ($row['substituto_funcionario_id'] != '') ? $ldap->getName($row['substituto_funcionario_id']) : '';
976                        $row['titular_funcionario_id_desc'] = ($row['titular_funcionario_id'] != '') ? $ldap->getName($row['titular_funcionario_id']) : '';
977                        $row['auxiliar_funcionario_id_desc'] = ($row['auxiliar_funcionario_id'] != '') ? $ldap->getName($row['auxiliar_funcionario_id']) : '';
978                        $row['superior_area_id'] = empty($row['superior_area_id']) ? 'NULL' : $row['superior_area_id'];
979                        $output[] = $row;
980                }
981
982                return $output;
983        }
984
985        /**
986         * Lista, hierarquicamente, as áreas de uma organização.
987         * @param int $organizationID O ID da organização.
988         * @param int $parent O ID da área superior (ou NULL para buscar todas as áreas).
989         * @param int $depth O nível hierárquico da área (profundidade do nó na árvore do Organograma).
990         * @return array Lista hierárquica das áreas de uma organização.
991         * @access public
992         */
993        function getHierarchicalArea($organizationID, $parent, $depth)
994        {
995                $this->_checkAccess($organizationID);
996
997                if (is_null($parent)){
998                        $query = "SELECT a.area_id, a.sigla, a.titular_funcionario_id FROM area a";
999                        $query .=" INNER JOIN area_status a_s ON (a_s.area_status_id = a.area_status_id)";
1000                        $query .=" WHERE (a.superior_area_id IS NULL) AND (a.organizacao_id = ?) AND (a.ativa = 'S') ORDER BY a_s.nivel, a.sigla";
1001                        $result = $this->db->query($query, array($organizationID));
1002                } else {
1003                        $query = "SELECT a.area_id, a.sigla, a.titular_funcionario_id FROM area a";
1004                        $query .=" INNER JOIN area_status a_s ON (a_s.area_status_id = a.area_status_id)";
1005                        $query .=" WHERE (a.superior_area_id = ?) AND (a.ativa = 'S') ORDER BY a_s.nivel, a.sigla";
1006                        $result = $this->db->query($query, array($parent));
1007                }
1008
1009                $this->_checkError($result);
1010
1011                $output = $result->GetArray(-1);
1012
1013                for ($i = 0; $i < count($output); ++$i)
1014                {
1015                        for ($j = 0; $j < $result->_numOfFields; ++$j)
1016                                unset($output[$i][$j]);
1017
1018                        $output[$i]['children'] = $this->getHierarchicalArea($organizationID, $output[$i]['area_id'], $depth + 1);
1019                        $output[$i]['depth'] = $depth;
1020                }
1021
1022                return $output;
1023        }
1024
1025        /**
1026         * Adiciona uma área em uma organização.
1027         * @param int $costCenterID O ID do centro de custo.
1028         * @param int $organizationID O ID da organização.
1029         * @param int $areaStatusID O ID do status da área.
1030         * @param int $supervisorID O ID do funcionário que é superior da área.
1031         * @param int $superiorAreaID O ID da área que é superior a que está sendo adicionada (NULL caso não possua área superior).
1032         * @param string $acronym A sigla da área.
1033         * @param string $description A descrição da área.
1034         * @param char $active 'S' se a área estiver ativa e 'N' caso contrário.
1035         * @param int $assistantID O ID do funcionário que está auxiliando o superior da área.
1036         * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário.
1037         * @access public
1038         */
1039        function addArea($costCenterID, $organizationID, $areaStatusID, $supervisorID, $superiorAreaID, $acronym, $description, $active, $assistantID)
1040        {
1041                $this->_checkAccess($organizationID);
1042
1043                $checkEmployees = array($supervisorID, $assistantID);
1044                $errors = array();
1045                foreach ($checkEmployees as $checkEmployee)
1046                {
1047                        if (is_null($checkEmployee))
1048                                continue;
1049
1050                        $query = 'SELECT 1 FROM funcionario WHERE (funcionario_id = ?)';
1051                        if (!$this->db->query($query, $checkEmployee)->fetchRow())
1052                                $errors[] = "O funcionário \"" . Factory::getInstance('WorkflowLDAP')->getName($checkEmployee) . "\" não está vinculado a uma área.";
1053                }
1054
1055                if (count($errors) > 0)
1056                {
1057                        $errors[] = '-----------------';
1058                        $errors[] = 'Se você está iniciando a construção de um organograma, crie as áreas sem titulares/substitutos/auxiliares administrativos e, adicione os funcionários a elas. Só então, adicione os titulares, substitutos, etc. A razão disto, é que estes "cargos" só podem ser ocupados por pessoas que estão vinculadas a alguma área.';
1059                        $this->endExecution($errors);
1060                }
1061
1062                $query = "INSERT INTO area(centro_custo_id, organizacao_id, area_status_id, titular_funcionario_id, superior_area_id, sigla, descricao, ativa, auxiliar_funcionario_id) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)";
1063                $result = $this->db->query($query, array($costCenterID, $organizationID, $areaStatusID, $supervisorID, $superiorAreaID, $acronym, $description, $active, $assistantID));
1064                $this->_checkError($result);
1065
1066                return (($result === false) ? false : true);
1067        }
1068
1069        /**
1070         * Atualiza a área de uma organização.
1071         * @param int $costCenterID O ID do centro de custo.
1072         * @param int $organizationID O ID da organização.
1073         * @param int $areaStatusID O ID do status da área.
1074         * @param int $supervisorID O ID do funcionário que é superior da área.
1075         * @param int $superiorAreaID O ID da área que é superior a que está sendo atualizada (NULL caso não possua área superior).
1076         * @param string $acronym A sigla da área.
1077         * @param string $description A descrição da área.
1078         * @param char $active 'S' se a área estiver ativa e 'N' caso contrário.
1079         * @param int $areaID O ID da área.
1080         * @param int $assistantID O ID do funcionário que está auxiliando o superior da área.
1081         * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário.
1082         * @access public
1083         */
1084        function updateArea($costCenterID, $organizationID, $areaStatusID, $supervisorID, $superiorAreaID, $acronym, $description, $active, $assistantID, $areaID)
1085        {
1086                $this->_checkAccess($organizationID);
1087
1088                $checkEmployees = array($supervisorID, $assistantID);
1089                $errors = array();
1090                foreach ($checkEmployees as $checkEmployee)
1091                {
1092                        if (is_null($checkEmployee))
1093                                continue;
1094
1095                        $query = 'SELECT 1 FROM funcionario WHERE (funcionario_id = ?)';
1096                        if (!$this->db->query($query, $checkEmployee)->fetchRow())
1097                                $errors[] = "O funcionário \"" . Factory::getInstance('WorkflowLDAP')->getName($checkEmployee) . "\" não está vinculado a uma área.";
1098                }
1099
1100                if (count($errors) > 0)
1101                {
1102                        $errors[] = '-----------------';
1103                        $errors[] = 'Somente funcionários que estão vinculados a alguma área podem ser colocados na posição de titular ou auxiliar administrativo.';
1104                        $this->endExecution($errors);
1105                }
1106
1107                $query = "UPDATE area SET centro_custo_id = ?, organizacao_id = ?, area_status_id = ?, titular_funcionario_id = ?, superior_area_id = ?, sigla = ?, descricao = ?, ativa = ?, auxiliar_funcionario_id = ? WHERE (area_id = ?)";
1108                $result = $this->db->query($query, array($costCenterID, $organizationID, $areaStatusID, $supervisorID, $superiorAreaID, $acronym, $description, $active, $assistantID, $areaID));
1109                $this->_checkError($result);
1110
1111                return (($result === false) ? false : true);
1112        }
1113
1114        /**
1115         * Remove a área de uma organização.
1116         * @param int $areaID O ID da área.
1117         * @param int $organizationID O ID da organização.
1118         * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário.
1119         * @access public
1120         */
1121        function removeArea($areaID, $organizationID)
1122        {
1123                $this->_checkAccess($organizationID);
1124
1125                $query = "DELETE FROM area WHERE (area_id = ?) AND (organizacao_id = ?)";
1126                $result = $this->db->query($query, array($areaID, $organizationID));
1127                $this->_checkError($result);
1128
1129                return (($result === false) ? false : true);
1130        }
1131
1132        /**
1133         * Busca informações sobre um funcionário.
1134         * @param array $params Uma array contendo o ID do funcionário cujas informações serão extraídas e de sua organização (Ajax).
1135         * @param int $employeeID O ID do funcionário.
1136         * @param int $organizationID O ID da organização.
1137         * @return array Informações sobre o funcionário.
1138         * @access public
1139         */
1140        function getEmployeeInfo($employeeID, $organizationID)
1141        {
1142                $this->_checkAccess($organizationID, false, true);
1143
1144                /**
1145                 * This is so wrong.. We should always use the factory to
1146                 * instantiate stuff. Besides, module class should not
1147                 * use process classes; the correct is to do the inverse.
1148                 */
1149                require_once dirname(__FILE__) . '/local/classes/class.wf_orgchart.php';
1150                $orgchart = new wf_orgchart();
1151
1152                $outputInfo = array();
1153
1154                $cachedLDAP = Factory::newInstance('CachedLDAP');
1155                $cachedLDAP->setOperationMode($cachedLDAP->OPERATION_MODE_LDAP_DATABASE);
1156
1157                /* here we need fresh information. Let's access ldap first */
1158                $employeeEntry = $cachedLDAP->getEntryByID($employeeID);
1159
1160                if ($entry === false)
1161                        return array('error' => 'Funcionário não encontrado.');
1162
1163                $employeeInfo                           = $orgchart->getEmployee($employeeID);
1164                $employeeStatusInfo                     = $orgchart->getEmployeeStatus($employeeInfo['funcionario_status_id']);
1165                $account_id                                     = $_SESSION['phpgw_info']['workflow']['account_id'];
1166
1167                $mobile         = '';
1168                $homePhone  = '';
1169               
1170                /*
1171                 * Check if the current user can view the mobile and homePhone of the employee
1172                 * This condition is true if the current user is the same user that's being retrieved
1173                 */
1174                $authorized = $this->acl->checkUserGroupAccessToResource('ORG', $account_id, (int) $organizationID, 1);
1175                if (($account_id == $employeeID) || ($authorized)) {
1176                        $mobile         = $employeeEntry['mobile'];
1177                        $homePhone      = $employeeEntry['homephone'];
1178                }
1179
1180                $outputInfo[] = array(
1181                        'name' => 'Mobile',
1182                        'value' => ( ! empty( $mobile ) ? $mobile : '' ) );
1183
1184                $outputInfo[] = array(
1185                        'name' => 'homePhone',
1186                        'value' => ( ! empty( $homePhone ) ? $homePhone : '' ) );
1187
1188
1189                $outputInfo[] = array(
1190                        'name' => 'Nome',
1191                        'value' => $employeeEntry['cn']);
1192
1193                $outputInfo[] = array(
1194                        'name' => 'Telefone',
1195                        'value' => ( ! empty( $employeeEntry['telephonenumber'] ) ? $employeeEntry['telephonenumber'] : '' ) );
1196
1197                if (!empty($employeeEntry['employeenumber']))
1198                {
1199                        $outputInfo[] = array(
1200                                'name' => 'Matrícula',
1201                                'value' => $employeeEntry['employeenumber']);
1202                }
1203
1204                $outputInfo[] = array(
1205                        'name' => 'UIDNumber',
1206                        'value' => $employeeID);
1207
1208                $outputInfo[] = array(
1209                        'name' => 'Status',
1210                        'value' => $employeeStatusInfo['descricao']);
1211
1212                if (!empty($employeeInfo['funcionario_categoria_id']))
1213                {
1214                        $categoryInfo = $orgchart->getEmployeeCategory($employeeInfo['funcionario_categoria_id']);
1215                        $outputInfo[] = array(
1216                                'name' => 'Vínculo',
1217                                'value' => $categoryInfo['descricao']);
1218                }
1219
1220                $titulo = NULL;
1221                if ( !empty( $employeeInfo['titulo'] ) )
1222                {
1223                        $titulo = $employeeInfo['titulo'];
1224                }
1225
1226                $outputInfo[] = array(
1227                        'name' => 'Título',
1228                        'value' => ( $titulo ? $titulo : '' )
1229                );
1230
1231                $cargo = NULL;
1232                if ( !empty($employeeInfo['cargo_id']) )
1233                {
1234                        $jobTitleInfo = $orgchart->getJobTitle($employeeInfo['cargo_id']);
1235                        $cargo = $jobTitleInfo['descricao'];
1236                }
1237
1238                $outputInfo[] = array(
1239                        'name' => 'Cargo',
1240                        'value' => ( $cargo ? $cargo : '' )
1241                );
1242
1243                $nivel = NULL;
1244                if ( !empty($employeeInfo['nivel']) )
1245                {
1246                        $nivel = $employeeInfo['nivel'];
1247                }
1248
1249                $outputInfo[] = array(
1250                        'name' => 'Nível',
1251                        'value' => ( $nivel ? $nivel : '' )
1252                );
1253
1254                $areaInfo = $orgchart->getArea($employeeInfo['area_id']);
1255                $outputInfo[] = array(
1256                        'name' => 'Área',
1257                        'value' => $areaInfo['sigla']);
1258
1259                $outputInfo[] = array(
1260                        'name' => 'ÁreaID',
1261                        'value' => $employeeInfo['area_id']);
1262
1263                $localInfo = $orgchart->getLocal($employeeInfo['localidade_id']);
1264                $outputInfo[] = array(
1265                        'name' => 'Localidade',
1266                        'value' => $localInfo['descricao']);
1267
1268                $outputInfo[] = array(
1269                        'name' => 'Empresa',
1270                        'value' => ( ! empty( $localInfo['empresa'] ) ? $localInfo['empresa'] : '') );;
1271
1272                $outputInfo[] = array(
1273                        'name' => 'Endereço',
1274                        'value' => ( ! empty( $localInfo['endereco'] ) ? $localInfo['endereco'] : '') );
1275
1276                $outputInfo[] = array(
1277                        'name' => 'Complemento',
1278                        'value' => ( ! empty( $localInfo['complemento'] ) ? $localInfo['complemento'] : '') );;
1279
1280                $outputInfo[] = array(
1281                        'name' => 'Cep',
1282                        'value' => ( ! empty( $localInfo['cep'] ) ? $localInfo['cep'] : '') );
1283
1284                $outputInfo[] = array(
1285                        'name' => 'Bairro',
1286                        'value' => ( ! empty( $localInfo['bairro'] ) ? $localInfo['bairro'] : '') );
1287
1288                $outputInfo[] = array(
1289                        'name' => 'Cidade',
1290                        'value' => ( ! empty( $localInfo['cidade'] ) ? $localInfo['cidade'] : '') );
1291
1292                $outputInfo[] = array(
1293                        'name' => 'UF',
1294                        'value' => ( ! empty( $localInfo['uf'] ) ? $localInfo['uf'] : '') );
1295
1296                if (!empty($employeeInfo['centro_custo_id']))
1297                        $costCenterInfo = $orgchart->getCostCenter($employeeInfo['centro_custo_id']);
1298                else
1299                        $costCenterInfo = $orgchart->getCostCenter($areaInfo['centro_custo_id']);
1300                $outputInfo[] = array(
1301                        'name' => 'Centro de Custo',
1302                        'value' => $costCenterInfo['descricao']);
1303
1304                $outputInfo[] = array(
1305                        'name' => 'e-mail',
1306                        'value' => $employeeEntry['mail']);
1307
1308                $organizationInfo = $orgchart->getOrganization( $employeeInfo['organizacao_id'] );
1309
1310                $outputInfo[] = array(
1311                        'name' => 'sitio',
1312                        'value' => $organizationInfo['sitio']);
1313
1314                return array('info' => $outputInfo);
1315        }
1316
1317        /**
1318         * Busca informações sobre uma área.
1319         * @param array $params Uma array contendo o ID da área cujas informações serão extraídas e de sua organização (Ajax).
1320         * @param int $areaID O ID da área.
1321         * @param int $organizationID O ID da organização.
1322         * @return array Informações sobre o funcionário.
1323         * @access public
1324         */
1325        function getAreaInfo($areaID, $organizationID)
1326        {
1327                $this->_checkAccess($organizationID, false, true);
1328
1329                $areaID = (int) $areaID;
1330                $organizationID = (int) $organizationID;
1331
1332                require_once dirname(__FILE__) . '/local/classes/class.wf_orgchart.php';
1333                $orgchart = new wf_orgchart();
1334
1335                $outputInfo = array();
1336                $areaInfo = $orgchart->getArea($areaID);
1337
1338                $outputInfo[] = array(
1339                        'name' => 'Nome',
1340                        'value' => $areaInfo['descricao']
1341                );
1342
1343                $cachedLDAP = Factory::newInstance('CachedLDAP');
1344                $cachedLDAP->setOperationMode($cachedLDAP->OPERATION_MODE_LDAP_DATABASE);
1345                if (!empty($areaInfo['titular_funcionario_id']))
1346                {
1347                        $employeeInfo = $cachedLDAP->getEntryByID($areaInfo['titular_funcionario_id']);
1348                        $outputInfo[] = array(
1349                                'name' => 'Titular',
1350                                'value' => $employeeInfo['cn']
1351                        );
1352                }
1353
1354                if (!empty($areaInfo['substituto_funcionario_id']))
1355                {
1356                        $employeeInfo = $cachedLDAP->getEntryByID($areaInfo['substituto_funcionario_id']);
1357                        $outputInfo[] = array(
1358                                'name' => 'Substituto',
1359                                'value' => $employeeInfo['cn']
1360                        );
1361                }
1362
1363                if (!empty($areaInfo['auxiliar_funcionario_id']))
1364                {
1365                        $employeeInfo = $cachedLDAP->getEntryByID($areaInfo['auxiliar_funcionario_id']);
1366                        $outputInfo[] = array(
1367                                'name' => 'Auxiliar Administrativo',
1368                                'value' => $employeeInfo['cn']
1369                        );
1370                }
1371
1372                $outputInfo[] = array(
1373                        'name' => 'No. de Funcionários',
1374                        'value' => $this->db->GetOne("SELECT COUNT(*) FROM funcionario f, funcionario_status s WHERE (s.funcionario_status_id = f.funcionario_status_id) AND (s.exibir = 'S') AND (f.area_id = ?) AND (f.organizacao_id = ?)", array($areaID, $organizationID))
1375                );
1376
1377                return array('info' => $outputInfo);
1378        }
1379
1380        /**
1381         * Lista todos os telefones da organização.
1382         * @return array Lista de telefones da organização.
1383         * @access public
1384         */
1385        function getTelephones( $organizationID )
1386        {
1387                $this -> _checkAccess( $organizationID );
1388
1389                $query = "SELECT organizacao_id, telefone_id, descricao, numero FROM telefone WHERE organizacao_id = ? ORDER BY descricao";
1390                $result = $this -> db -> query( $query, array( $organizationID ) );
1391                $this -> _checkError( $result );
1392
1393                $output = $result->GetArray(-1);
1394
1395                for ($i = 0; $i < count($output); ++$i)
1396                        for ($j = 0; $j < $result->_numOfFields; ++$j)
1397                                unset($output[$i][$j]);
1398
1399                return $output;
1400        }
1401
1402        /**
1403         * Adiciona um telefone a uma organização.
1404         * @param int $organizationID O ID da organização.
1405         * @param string $description A descrição da localidade.
1406         * @param string $number String com os números de telefones.
1407         * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário.
1408         * @access public
1409         */
1410        function addTelephone( $organizationID, $description, $number )
1411        {
1412                $this->_checkAccess( $organizationID );
1413
1414                $query = "INSERT INTO telefone( organizacao_id, descricao, numero ) VALUES( ?, ?, ? )";
1415                $result = $this -> db -> query( $query, array( $organizationID, $description, $number ) );
1416                $this -> _checkError( $result );
1417
1418                return (($result === false) ? false : true);
1419        }
1420
1421        /**
1422         * Remove um telefone.
1423         * @param int $organizationID O ID da organização.
1424         * @param int $telephoneID O ID do telefone.
1425         * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário.
1426         * @access public
1427         */
1428        function removeTelephone( $organizationID, $telephoneID )
1429        {
1430                $this->_checkAccess( $organizationID );
1431
1432                $query = "DELETE FROM telefone WHERE (telefone_id = ?) AND (organizacao_id = ?)";
1433                $result = $this -> db -> query( $query, array( $telephoneID, $organizationID ) );
1434                $this -> _checkError( $result );
1435
1436                return ( ( $result === false ) ? false : true );
1437        }
1438
1439        /**
1440         * Atualiza um telefone.
1441         * @param int $organizationID O ID da organização.
1442         * @param int $telephoneID O ID do telefone.
1443         * @param string $description A descrição do telefone.
1444         * @param string $number String com os números de telefones.
1445         * @return bool TRUE se a ação foi concluída com êxito e FALSE caso contrário.
1446         * @access public
1447         */
1448        function updateTelephone( $organizationID, $telephoneID, $description, $number )
1449        {
1450                $this->_checkAccess( $organizationID );
1451
1452                $query = "UPDATE telefone SET descricao = ?, numero = ? WHERE (telefone_id = ?)";
1453                $result = $this -> db -> query( $query, array( $description, $number, $telephoneID ) );
1454                $this->_checkError( $result );
1455
1456                return ( ( $result === false ) ? false : true );
1457        }
1458
1459        /**
1460         * Validate start and end dates for a substitution
1461         * @param int $areaID Area's ID.
1462         * @param string $date_start Substitution's start date.
1463         * @param string $date_start Substitution's end date.
1464         * @return bool
1465         * @access private
1466         */
1467        function validateSubstitutionDates($areaID, $date_start, $date_end, $substitutionID = -1)
1468        {
1469                /* TODO
1470                * I'm not supose to be here.. (date validations speaking)
1471                * move me to some validation class!
1472                */
1473
1474                /* validating dates */
1475                $date_pattern = '/^(0[1-9]|[12][0-9]|3[01])\/(0[1-9]|1[0-2])\/[12][0-9]{3}$/';
1476
1477                if (!preg_match($date_pattern, $date_start))
1478                        $this->endExecution("Formato inválido para data de início.");
1479                if (!preg_match($date_pattern, $date_end))
1480                        $this->endExecution("Formato inválido para data de término. ");
1481
1482                $date_start_arr = explode('/', $date_start);
1483                $date_end_arr = explode('/', $date_end);
1484
1485                /* is it a gregorian date? */
1486                if (!checkdate($date_start_arr[1], $date_start_arr[0], $date_start_arr[2]))
1487                        $this->endExecution("Data de início inválida.");
1488                if (!checkdate($date_end_arr[1], $date_end_arr[0], $date_end_arr[2]))
1489                        $this->endExecution("Data de término inválida. ");
1490
1491                /* is date_end greater then date_start? */
1492                if (mktime(0,0,0, $date_start_arr[1], $date_start_arr[0], $date_start_arr[2]) >= mktime(0,0,0, $date_end_arr[1], $date_end_arr[0], $date_end_arr[2]))
1493                        $this->endExecution("A data de término deve ser maior que a data de início.");
1494
1495                /* preparing dates to database */
1496                $date_start = implode('-', array_reverse($date_start_arr));
1497                $date_end = implode('-', array_reverse($date_end_arr));
1498
1499                /* checking if there is a substitution in conflict with these dates */
1500                $query  = "SELECT * FROM substituicao WHERE ";
1501                $query .= "     area_id = ? ";
1502                $query .= " AND ";
1503                $query .= "     substituicao_id != ? ";
1504                $query .= " AND ";
1505                $query .= "     (";
1506                $query .= "             (? BETWEEN data_inicio AND data_fim) ";
1507                $query .= "     OR ";
1508                $query .= "             (? BETWEEN data_inicio AND data_fim)";
1509                $query .= "     OR ";
1510                $query .= "             (data_inicio BETWEEN ? AND ?)";
1511                $query .= "     ) ";
1512
1513                // raise an error if there is any record
1514                if ($row = $this->db->query($query, array( $areaID, $substitutionID, $date_start, $date_end, $date_start, $date_end ))->fetchRow())
1515                {
1516                        $row['data_inicio'] = implode('/', array_reverse(explode('-', $row['data_inicio'])));
1517                        $row['data_fim'] = implode('/', array_reverse(explode('-', $row['data_fim'])));
1518                        $this->endExecution('Já existe uma substituição no período de '. $row['data_inicio'] . ' a ' . $row['data_fim']);
1519                }
1520                return true;
1521        }
1522
1523        /**
1524         * Add a substitution.
1525         * @param int $organizationID Organization's ID.
1526         * @param int $areaID Area's ID.
1527         * @param int $substituteID Substitute's employee ID.
1528         * @param string $date_start Substitution's start date.
1529         * @param string $date_start Substitution's end date.
1530         * @return bool
1531         * @access public
1532         */
1533        function addSubstitution( $organizationID, $areaID, $substituteID, $date_start, $date_end )
1534        {
1535                $this->_checkAccess( $organizationID );
1536
1537                if (!$this->validateSubstitutionDates($areaID, $date_start, $date_end))
1538                        return false;
1539
1540                /* formating dates */
1541                $date_start = implode('-', array_reverse(explode('/', $date_start)));
1542                $date_end = implode('-', array_reverse(explode('/', $date_end)));
1543
1544                $query = "INSERT INTO substituicao (area_id, funcionario_id, data_inicio, data_fim) VALUES (?, ?, ?, ?)";
1545                $result = $this -> db -> query( $query, array( $areaID, $substituteID, $date_start, $date_end ) );
1546                $this->_checkError( $result );
1547
1548                return ( ( $result === false ) ? false : true );
1549        }
1550
1551        /**
1552         * Update a substitution.
1553         * @param int $organizationID Organization's ID.
1554         * @param int $areaID Area's ID.
1555         * @param int $substituteID Substitute's employee ID.
1556         * @param string $date_start Substitution's start date.
1557         * @param string $date_start Substitution's end date.
1558         * @return bool
1559         * @access public
1560         */
1561        function updateSubstitution( $organizationID, $areaID, $substituteID, $date_start, $date_end, $substitutionID )
1562        {
1563                $this->_checkAccess( $organizationID );
1564
1565                if (!$this->validateSubstitutionDates($areaID, $date_start, $date_end, $substitutionID))
1566                        return false;
1567
1568                /* formating dates */
1569                $date_start = implode('-', array_reverse(explode('/', $date_start)));
1570                $date_end = implode('-', array_reverse(explode('/', $date_end)));
1571
1572                $query = "UPDATE substituicao SET funcionario_id = ?, data_inicio = ?, data_fim = ? WHERE substituicao_id = ?";
1573                $result = $this -> db -> query( $query, array( $substituteID, $date_start, $date_end, $substitutionID ) );
1574                $this->_checkError( $result );
1575
1576                return ( ( $result === false ) ? false : true );
1577        }
1578
1579        /**
1580         * List all the substituions for a given area
1581         * @return array List of the substitutions
1582         * @access public
1583         */
1584        function getSubstitutions( $organizationID, $areaID )
1585        {
1586                $this -> _checkAccess( $organizationID );
1587
1588                /* we must join area table to get organizacao_id */
1589                $query = "SELECT s.*, a.organizacao_id FROM substituicao s INNER JOIN area a USING(area_id) WHERE area_id = ? ORDER BY data_inicio DESC";
1590                $result = $this -> db -> query( $query, array( $areaID ) );
1591                $this -> _checkError( $result );
1592
1593                /* we must query ldap to get full user names. In workflow db we just store uids */
1594                $cachedLDAP = Factory::getInstance('CachedLDAP');
1595
1596                $output = $result->GetArray(-1);
1597
1598                for ($i = 0; $i < count($output); ++$i) {
1599                        for ($j = 0; $j < $result->_numOfFields; ++$j)
1600                                unset($output[$i][$j]);
1601
1602                        /* including substitute full name */
1603                        $ldap_result = $cachedLDAP->getEntryByID($output[$i]['funcionario_id']);
1604                        $output[$i]['substituto_funcionario_id'] = $output[$i]['funcionario_id'];
1605                        $output[$i]['substituto_funcionario_id_desc'] = $ldap_result['cn'];
1606
1607                        /* formating dates */
1608                        $output[$i]['data_inicio'] = implode('/', array_reverse(explode('-', $output[$i]['data_inicio'])));
1609                        $output[$i]['data_fim'] = implode('/', array_reverse(explode('-', $output[$i]['data_fim'])));
1610                }
1611                return $output;
1612        }
1613
1614        /**
1615         * Remove a substitution
1616         * @param int $organizationID Organization's ID
1617         * @param int $telephoneID Substitution's ID
1618         * @return bool
1619         * @access public
1620         */
1621        function removeSubstitution( $organizationID, $substitutionID )
1622        {
1623                $this->_checkAccess( $organizationID );
1624
1625                $query = "DELETE FROM substituicao WHERE substituicao_id = ?";
1626                $result = $this -> db -> query( $query, array( $substitutionID ) );
1627                $this -> _checkError( $result );
1628
1629                return ( ( $result === false ) ? false : true );
1630        }
1631}
1632?>
Note: See TracBrowser for help on using the repository browser.