<?php

class Employee extends Person {
    /*
      Determines if a given person_id is an employee
     */

    function exists($person_id)
    {
        $this->db->from('employees');
        $this->db->join('people', 'people.person_id = employees.person_id');
        $this->db->where('employees.person_id', $person_id);
        $query = $this->db->get();

        return ($query->num_rows() == 1);
    }

    /*
      Returns all the employees
     */

    function get_all($limit = 10000, $offset = 0, $search = "", $order = array())
    {
        $user_id = $this->Employee->get_logged_in_employee_info()->person_id;
        $sorter = array("employees.person_id", "employees.person_id", "last_name", "first_name", "email", "phone_number");

        $this->db->from('employees');
        $this->db->join('people', 'employees.person_id=people.person_id');
        $this->db->where('deleted', 0);

        if ($search !== "")
        {
            $this->db->where('first_name LIKE ', '%' . $search . '%');
            $this->db->or_where('last_name LIKE', '%' . $search . '%');
            $this->db->or_where('email LIKE', '%' . $search . '%');
            $this->db->or_where('phone_number LIKE', '%' . $search . '%');
        }

        if (isset($_GET['employee_id']) && $_GET['employee_id'] > 0)
        {
            $user_id = $_GET['employee_id'];
        }
        
        if ($user_id !== '1')
        {
            $this->db->where('employees.added_by', $user_id);
        }

        if (count($order) > 0 && $order['index'] < count($sorter))
        {
            $this->db->order_by($sorter[$order['index']], $order['direction']);
        }
        else
        {
            $this->db->order_by("employees.person_id", "desc");
        }

        $this->db->limit($limit);
        $this->db->offset($offset);
        return $this->db->get();
    }

    function count_all()
    {
        $this->db->from('employees');
        $this->db->where('deleted', 0);
        return $this->db->count_all_results();
    }

    /*
      Gets information about a particular employee
     */

    function get_info($employee_id)
    {
        $this->db->from('employees');
        $this->db->join('people', 'people.person_id = employees.person_id');
        $this->db->where('employees.person_id', $employee_id);
        $query = $this->db->get();

        if ($query->num_rows() == 1)
        {
            return $query->row();
        }
        else
        {
            //Get empty base parent object, as $employee_id is NOT an employee
            $person_obj = parent::get_info(-1);

            //Get all the fields from employee table
            $fields = $this->db->list_fields('employees');

            //append those fields to base parent object, we we have a complete empty object
            foreach ($fields as $field)
            {
                $person_obj->$field = '';
            }

            return $person_obj;
        }
    }

    /*
      Gets information about multiple employees
     */

    function get_multiple_info($employee_ids)
    {
        $this->db->from('employees');
        $this->db->join('people', 'people.person_id = employees.person_id');
        $this->db->where_in('employees.person_id', $employee_ids);
        $this->db->order_by("last_name", "asc");
        return $this->db->get();
    }

    /*
      Inserts or updates an employee
     */

    function save(&$person_data, &$employee_data = [], $employee_id = false, &$grants_data = [])
    {
        $success = false;

        //Run these queries as a transaction, we want to make sure we do all or nothing
        $this->db->trans_start();

        if (parent::save($person_data, $employee_data, $employee_id))
        {
            $employee_data["added_by"] = $this->Employee->get_logged_in_employee_info()->person_id;            
            if (!$employee_id || ! $this->exists($employee_id))
            {
                $employee_data['person_id'] = $employee_id = $person_data['person_id'];
                $success = $this->db->insert('employees', $employee_data);
            }
            else
            {
                $this->db->where('person_id', $employee_id);
                $success = $this->db->update('employees', $employee_data);
            }

            //We have either inserted or updated a new employee, now lets set permissions. 
            if ($success)
            {
                //First lets clear out any grants the employee currently has.
                $success = $this->db->delete('grants', array('person_id' => $employee_id));

                //Now insert the new grants
                if ($success)
                {
                    foreach ($grants_data as $permission_id)
                    {
                        $this->db->where("module_id", $permission_id);
                        $query = $this->db->get("modules");
                        
                        if ($query->num_rows() > 0)
                        {
                            $success = $this->db->insert('grants', array(
                                'permission_id' => $permission_id,
                                'person_id' => $employee_id));
                        }
                    }
                }
            }
        }

        $this->db->trans_complete();
        return $success;
    }

    /*
      Deletes one employee
     */

    function delete($employee_id)
    {
        $success = false;

        //Don't let employee delete their self
        if ($employee_id == $this->get_logged_in_employee_info()->person_id)
            return false;

        //Run these queries as a transaction, we want to make sure we do all or nothing
        $this->db->trans_start();

        //Delete permissions
        if ($this->db->delete('grants', array('person_id' => $employee_id)))
        {
            $this->db->where('person_id', $employee_id);
            $success = $this->db->update('employees', array('deleted' => 1));
        }
        $this->db->trans_complete();
        return $success;
    }

    /*
      Deletes a list of employees
     */

    function delete_list($employee_ids)
    {
        $success = false;

        //Don't let employee delete their self
        if (in_array($this->get_logged_in_employee_info()->person_id, $employee_ids))
            return false;

        //Run these queries as a transaction, we want to make sure we do all or nothing
        $this->db->trans_start();

        $this->db->where_in('person_id', $employee_ids);
        //Delete permissions
        if ($this->db->delete('grants'))
        {
            //delete from employee table
            $this->db->where_in('person_id', $employee_ids);
            $success = $this->db->update('employees', array('deleted' => 1));
        }
        $this->db->trans_complete();
        return $success;
    }

    /*
      Get search suggestions to find employees
     */

    function get_search_suggestions($search, $limit = 5)
    {
        $suggestions = array();

        $this->db->from('employees');
        $this->db->join('people', 'employees.person_id=people.person_id');
        $this->db->where("(first_name LIKE '%" . $this->db->escape_like_str($search) . "%' or 
		last_name LIKE '%" . $this->db->escape_like_str($search) . "%' or 
		CONCAT(`first_name`,' ',`last_name`) LIKE '%" . $this->db->escape_like_str($search) . "%') and deleted=0");
        $this->db->order_by("last_name", "asc");
        $by_name = $this->db->get();
        foreach ($by_name->result() as $row)
        {
            $suggestions[] = $row->first_name . ' ' . $row->last_name;
        }

        $this->db->from('employees');
        $this->db->join('people', 'employees.person_id=people.person_id');
        $this->db->where('deleted', 0);
        $this->db->like("email", $search);
        $this->db->order_by("email", "asc");
        $by_email = $this->db->get();
        foreach ($by_email->result() as $row)
        {
            $suggestions[] = $row->email;
        }

        $this->db->from('employees');
        $this->db->join('people', 'employees.person_id=people.person_id');
        $this->db->where('deleted', 0);
        $this->db->like("username", $search);
        $this->db->order_by("username", "asc");
        $by_username = $this->db->get();
        foreach ($by_username->result() as $row)
        {
            $suggestions[] = $row->username;
        }


        $this->db->from('employees');
        $this->db->join('people', 'employees.person_id=people.person_id');
        $this->db->where('deleted', 0);
        $this->db->like("phone_number", $search);
        $this->db->order_by("phone_number", "asc");
        $by_phone = $this->db->get();
        foreach ($by_phone->result() as $row)
        {
            $suggestions[] = $row->phone_number;
        }


        //only return $limit suggestions
        if (count($suggestions > $limit))
        {
            $suggestions = array_slice($suggestions, 0, $limit);
        }
        return $suggestions;
    }

    /*
      Preform a search on employees
     */

    function search($search)
    {
        $this->db->from('employees');
        $this->db->join('people', 'employees.person_id=people.person_id');
        $this->db->where("(first_name LIKE '%" . $this->db->escape_like_str($search) . "%' or 
		last_name LIKE '%" . $this->db->escape_like_str($search) . "%' or 
		email LIKE '%" . $this->db->escape_like_str($search) . "%' or 
		phone_number LIKE '%" . $this->db->escape_like_str($search) . "%' or 
		username LIKE '%" . $this->db->escape_like_str($search) . "%' or 
		CONCAT(`first_name`,' ',`last_name`) LIKE '%" . $this->db->escape_like_str($search) . "%') and deleted=0");
        $this->db->order_by("last_name", "asc");

        return $this->db->get();
    }

    /*
      Attempts to login employee and set session. Returns boolean based on outcome.
     */

    function login($username, $password)
    {
        $query = $this->db->get_where('employees', array('username' => $username, 'password' => md5($password), 'deleted' => 0), 1);
        if ($query->num_rows() == 1)
        {
            $row = $query->row();
            $this->session->set_userdata('person_id', $row->person_id);
            return true;
        }
        return false;
    }

    /*
      Logs out a user by destorying all session data and redirect to login
     */

    function logout()
    {
        $this->session->sess_destroy();
        redirect('login');
    }

    /*
      Determins if a employee is logged in
     */

    function is_logged_in()
    {
        return $this->session->userdata('person_id') != false;
    }

    /*
      Gets information about the currently logged in employee.
     */

    function get_logged_in_employee_info()
    {
        if ($this->is_logged_in())
        {
            return $this->get_info($this->session->userdata('person_id'));
        }

        return false;
    }

    /*
     * Determines whether the employee has access to at least one submodule
     */

    function has_module_grant($permission_id, $person_id)
    {
        $this->db->from('grants');
        $this->db->like('permission_id', $permission_id, 'after');
        $this->db->where('person_id', $person_id);
        $result = $this->db->get();
        $result_count = $result->num_rows();

        if ($result_count != 1)
        {
            return $result_count != 0;
        }
        return $this->has_subpermissions($permission_id);
    }

    function has_subpermissions($permission_id)
    {
        $this->db->from('permissions');
        $this->db->like('permission_id', $permission_id . '_', 'after');
        $result = $this->db->get();
        return $result->num_rows() == 0;
    }

    /*
      Determines whether the employee specified employee has access the specific module.
     */

    function has_grant($permission_id, $person_id)
    {
        //if no module_id is null, allow access
        if ($permission_id == null)
        {
            return true;
        }

        $query = $this->db->get_where('grants', array('person_id' => $person_id, 'permission_id' => $permission_id), 1);
        return ($query->num_rows() == 1);
    }

    function get_employee_grants($person_id)
    {
        $this->db->from('grants');
        $this->db->where('person_id', $person_id);
        return $this->db->get()->result_array();
    }

    function hasLowerLevel()
    {
        $user = $this->Employee->get_logged_in_employee_info();
        if ($user->person_id === 1)
        {
            return true;
        }
        $this->db->where("role_id", $user->role_id);
        $query = $this->db->get('roles');
        if (isset($query->row()->low_level) && $query->row()->low_level !== "false")
            return true;
        return false;
    }
    
    function getLowerLevels()
    {
        $employee_id = $this->session->userdata('person_id');
        
        $role_id = $this->Employee->get_logged_in_employee_info()->role_id;
        
        $this->db->where("role_id", $role_id);
        $query = $this->db->get("roles");
        $res = $query->row();
        $low_levels = false;
        if (isset($res->low_level) && is_array(json_decode($res->low_level, TRUE)))
        {
            $low_levels = json_decode($res->low_level, TRUE);
        }
        
        
        if ($low_levels)
        {
            $this->db->where_in("role_id", $low_levels);
            $this->db->where("employees.added_by", $employee_id);
            $this->db->where("deleted", 0);
            $this->db->join("employees", "employees.person_id=people.person_id");
            $query = $this->db->get("people");
            return $query->result();
        }
            
        return false;
    }

    /*
      Get search suggestions to find customers
     */

    function get_employee_search_suggestions($search, $limit = 25)
    {
        $suggestions = array();

        $user_id = $this->Employee->get_logged_in_employee_info()->person_id;
        $add_where = '';
        if ($user_id > 1)
        {
            $add_where = " and added_by = " . $user_id . " ";
        }

        $this->db->from('employees');
        $this->db->join('people', 'employees.person_id=people.person_id');
        $this->db->where("(first_name LIKE '%" . $this->db->escape_like_str($search) . "%' or 
		last_name LIKE '%" . $this->db->escape_like_str($search) . "%' or 
		CONCAT(`first_name`,' ',`last_name`) LIKE '%" . $this->db->escape_like_str($search) . "%') and deleted=0
                    " . $add_where . "
                    ");
        $this->db->order_by("last_name", "asc");
        $by_name = $this->db->get();
        foreach ($by_name->result() as $row)
        {
            $suggestions[] = $row->person_id . '|' . $row->first_name . ' ' . $row->last_name . '|' . $row->email;
        }
       
        return $suggestions;
    }
}

?>
