1<?php
2
3/**
4 * OrangeHRM is a comprehensive Human Resource Management (HRM) System that captures
5 * all the essential functionalities required for any enterprise.
6 * Copyright (C) 2006 OrangeHRM Inc., http://www.orangehrm.com
7 *
8 * OrangeHRM is free software; you can redistribute it and/or modify it under the terms of
9 * the GNU General Public License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
11 *
12 * OrangeHRM is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
13 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14 * See the GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along with this program;
17 * if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA  02110-1301, USA
19 */
20
21/**
22 * Service used to generate left menu for PIM
23 */
24class PIMLeftMenuService {
25
26    const PIM_LEFTMENU_SESSION_KEY = 'pim.leftMenu.cache';
27    const PIM_LEFTMENU_TAXMENU_ENABLED = 'pim.leftMenu.isTaxMenuEnabled';
28
29    private $user;
30    private $employeeService;
31    private $userRoleManager;
32
33    private $availableActions = array(
34        'viewPersonalDetails' => array(
35            'module' => 'pim',
36            'data_groups' => array('personal_information', 'personal_attachment', 'personal_custom_fields'),
37            'label' => "Personal Details"),
38        'contactDetails' => array(
39            'module' => 'pim',
40            'data_groups' => array('contact_details', 'contact_attachment', 'contact_custom_fields'),
41            'label' => 'Contact Details'),
42        'viewEmergencyContacts' => array(
43            'module' => 'pim',
44            'data_groups' => array('emergency_contacts', 'emergency_attachment', 'emergency_custom_fields'),
45            'label' => 'Emergency Contacts'),
46        'viewDependents' => array(
47            'module' => 'pim',
48            'data_groups' => array('dependents', 'dependents_attachment', 'dependents_custom_fields'),
49            'label' => 'Dependents'),
50        'viewImmigration' => array(
51            'module' => 'pim',
52            'data_groups' => array('immigration', 'immigration_attachment', 'immigration_custom_fields'),
53            'label' => 'Immigration'),
54        'viewJobDetails' => array(
55            'module' => 'pim',
56            'data_groups' => array('job_details', 'job_attachment', 'job_custom_fields'),
57            'label' => 'Job'),
58        'viewSalaryList' => array(
59            'module' => 'pim',
60            'data_groups' => array('salary_details', 'salary_attachment', 'salary_custom_fields'),
61            'label' => 'Salary'),
62        'viewUsTaxExemptions' => array(
63            'module' => 'pim',
64            'data_groups' => array('tax_exemptions', 'tax_attachment', 'tax_custom_fields'),
65            'label' => 'Tax Exemptions'),
66        'viewReportToDetails' => array(
67            'module' => 'pim',
68            'data_groups' => array('supervisor', 'subordinates', 'report-to_attachment', 'report-to_custom_fields'),
69            'actions' => array(),
70            'label' => 'Report-to'),
71        'viewQualifications' => array(
72            'module' => 'pim',
73            'data_groups' => array('qualification_work', 'qualification_education', 'qualification_skills', 'qualification_languages', 'qualification_license', 'qualifications_attachment', 'qualifications_custom_fields'),
74            'label' => 'Qualifications'),
75        'viewMemberships' => array(
76            'module' => 'pim',
77            'data_groups' => array('membership', 'membership_attachment', 'membership_custom_fields'),
78            'label' => 'Memberships')
79    );
80
81    /**
82     * Get EmployeeService
83     * @returns EmployeeService
84     */
85    public function getEmployeeService() {
86        if (is_null($this->employeeService)) {
87            $this->employeeService = new EmployeeService();
88            $this->employeeService->setEmployeeDao(new EmployeeDao());
89        }
90        return $this->employeeService;
91    }
92
93    /**
94     * Set EmployeeService
95     * @param EmployeeService $employeeService
96     */
97    public function setEmployeeService(EmployeeService $employeeService) {
98        $this->employeeService = $employeeService;
99    }
100
101    /**
102     * Get UserRoleManager
103     * @returns AbstractUserRoleManager
104     */
105    public function getUserRoleManager() {
106        if (is_null($this->userRoleManager)) {
107            $this->userRoleManager = UserRoleManagerFactory::getUserRoleManager();;
108        }
109        return $this->userRoleManager;
110    }
111
112    /**
113     * Set UserRoleManager
114     * @param AbstractUserRoleManager $userRoleManager
115     */
116    public function setUserRoleManager(AbstractUserRoleManager $userRoleManager) {
117        $this->userRoleManager = $userRoleManager;
118    }
119
120    /**
121     * Get symfony's sfUser representing the logged in user
122     *
123     * @return sfUser
124     */
125    public function getUser() {
126        if (empty($this->user)) {
127            $this->user = sfContext::getInstance()->getUser();
128        }
129        return $this->user;
130    }
131
132    /**
133     * Set symfony sfUser
134     *
135     * @param sfUser $user
136     */
137    public function setUser($user) {
138        $this->user = $user;
139    }
140
141    /**
142     * Returns PIM left menu items in when looking at the given employee.
143     *
144     * @param int $empNumber Employee Number
145     * @param int $self If true, indicates menu when user is looking at his own info
146     * @return array Array of menu items.
147     */
148    public function getMenuItems($empNumber, $self) {
149
150        $menu = $this->getMenuFromCache($empNumber, $self);
151
152        if (empty($menu)) {
153            $menu = $this->generateMenuItems($empNumber, $self);
154            $this->saveMenuInCache($empNumber, $menu);
155        }
156        return $menu;
157    }
158
159
160    /**
161     * Clears cached PIM menu for given employee
162     *
163     * If employee is null, all cached menu items are cleared.
164     *
165     * @param int $empNumber Employee Number (or null)
166     */
167    public function clearCachedMenu($empNumber = null) {
168        $user = $this->getUser();
169        $cache = $user->getAttribute(self::PIM_LEFTMENU_SESSION_KEY, array());
170        if (empty($empNumber)) {
171            $cache = array();
172        } else {
173            unset($cache[$empNumber]);
174        }
175
176        $user->setAttribute(self::PIM_LEFTMENU_SESSION_KEY, $cache);
177    }
178
179    public function isPimAccessible($empNumber, $self) {
180        $menu = $this->getMenuItems($empNumber, $self);
181
182        return count($menu) > 0;
183    }
184
185    protected function generateMenuItems($empNumber, $self) {
186
187        $menu = array();
188        $entities = array();
189
190        if (!empty($empNumber)) {
191            $entities = array('Employee' => $empNumber);
192        }
193
194        $availableActions = $this->getAvailableActions();
195
196        $userRoleManager = $this->getUserRoleManager();
197
198        foreach ($availableActions as $action => $properties) {
199            $dataGroupPermission = $userRoleManager->getDataGroupPermissions($properties['data_groups'], array(), array(), $self, $entities);
200            if ($dataGroupPermission->canRead()) {
201                $menu[$action] = $properties;
202            } else if ($action == 'viewJobDetails' && $this->isEmployeeWorkflowActionsAllowed($empNumber)) {
203                $menu[$action] = $properties;
204            }
205        }
206
207        return $menu;
208    }
209
210    protected function isEmployeeWorkflowActionsAllowed($empNumber) {
211
212        $userRoleManager = $this->getUserRoleManager();
213
214        $employeeState = Null;
215
216        if (!empty($empNumber)) {
217            $employee = $this->getEmployeeService()->getEmployee($empNumber);
218            if ($employee instanceof Employee) {
219                $employeeState = $employee->getState();
220            }
221        }
222
223        $actionableStates = $userRoleManager->getActionableStates(WorkflowStateMachine::FLOW_EMPLOYEE,
224                array(WorkflowStateMachine::EMPLOYEE_ACTION_TERMINATE,
225                    WorkflowStateMachine::EMPLOYEE_ACTION_REACTIVE));
226
227        // If employee state not allowed, allow if can act on at least one state
228        if (is_null($employeeState)) {
229            $allowed = empty($actionableStates)?false:true;
230        } else {
231            $allowed = in_array($employeeState, $actionableStates);
232        }
233
234        return $allowed;
235    }
236
237    /**
238     * Get PIM left menu for given employee from session cache (if available)
239     *
240     * @param int $empNumber Employee Number
241     * @return array Menu array (or an empty array if not available in cache)
242     */
243    protected function getMenuFromCache($empNumber) {
244        $user = $this->getUser();
245        $cache = $user->getAttribute(self::PIM_LEFTMENU_SESSION_KEY, array());
246        $key = empty($empNumber) ? 'default' : $empNumber;
247        $menu = isset($cache[$key]) ? $cache[$key] : array();
248
249        return $menu;
250    }
251
252    /**
253     * Store menu for the given employee in the session cache.
254     *
255     * @param int $empNumber Employee Number
256     * @param array $menu Menu array
257     */
258    protected function saveMenuInCache($empNumber, $menu) {
259        $user = $this->getUser();
260        $cache = $user->getAttribute(self::PIM_LEFTMENU_SESSION_KEY, array());
261        $key = empty($empNumber) ? 'default' : $empNumber;
262        $cache[$key] = $menu;
263        $user->setAttribute(self::PIM_LEFTMENU_SESSION_KEY, $cache);
264    }
265
266    protected function getAvailableActions() {
267        $availableActions = $this->availableActions;
268        if (!$this->isTaxMenuEnabled()) {
269            unset($availableActions['viewUsTaxExemptions']);
270        }
271
272        return $availableActions;
273    }
274
275    /**
276     * Check if tax menu is enabled
277     *
278     * @return boolean true if enabled, false if not
279     */
280    protected function isTaxMenuEnabled() {
281
282        $sfUser = $this->getUser();
283
284        if (!$sfUser->hasAttribute(self::PIM_LEFTMENU_TAXMENU_ENABLED)) {
285            $isTaxMenuEnabled = OrangeConfig::getInstance()->getAppConfValue(ConfigService::KEY_PIM_SHOW_TAX_EXEMPTIONS);
286            $sfUser->setAttribute(self::PIM_LEFTMENU_TAXMENU_ENABLED, $isTaxMenuEnabled);
287        }
288
289        return $sfUser->getAttribute(self::PIM_LEFTMENU_TAXMENU_ENABLED);
290    }
291}
292
293