<?php

if (!defined('BASEPATH'))
	exit('No direct script access allowed');

class Projects extends Admin_Controller
{

	public function __construct()
	{
		parent::__construct();
		$this->load->model('invoice_model');
		$this->load->model('estimates_model');
		$this->load->model('credit_note_model');
		$this->load->model('purchase_model');
		$this->load->model('common_model');
		$this->load->model('project_model');
		$this->load->model('items_model');
		$this->load->model('finance_report_model');
	}

	public function all_projects_state_report()
	{
		if (!$this->input->is_ajax_request()) {
			redirect('admin/dashboard');
		}
		$data = array();
		$pathonor_jonno['all_projects_state_report_div'] = $this->load->view("admin/projects/all_projects_state_report", $data, true);
		echo json_encode($pathonor_jonno);
		exit;
	}

	public function index()
	{
		$this->load->driver('cache', ['adapter' => 'file']);
		$data['active'] = 1;
		$data['tab'] = 'projects';
		$data['title'] = lang('all_project');
		$data['page_title'] = lang('projects');
		$data['page_description'] = 'Portfolio, delivery status, and ownership at a glance.';
		$data['datatable'] = true;



		$cache_ttl = 300;
		$cache_key = 'projects_kpi_stats_' . $this->session->userdata('user_type') . '_' . $this->session->userdata('user_id');
		$kpi_stats = $this->cache->get($cache_key);
		if ($kpi_stats === false) {
			$kpi_stats = $this->project_model->get_dashboard_kpi();
			$this->cache->save($cache_key, $kpi_stats, $cache_ttl);
		}
		$data['kpi_stats'] = $kpi_stats;
		$data['all_customer_group'] =  $this->project_model->select_data('tbl_customer_group', 'customer_group_id', 'customer_group', array('type' => 'projects'));
		$data['all_client'] = $this->project_model->get_permission('tbl_client');
		$data['assign_user'] = $this->project_model->allowed_user('57');
		$data['header_filter_extras_html'] = '';

		$data['header_filters'] = array(
			array(
				'label' => 'Filters',
				'icon' => 'sliders-horizontal',
				'selected_label' => lang('all'),
				'attrs' => array(
					'id' => 'projects-header-status-filter',
				),
				'items' => array(
					array(
						'label' => lang('all'),
						'active' => true,
						'attrs' => array(
							'data-project-filter-action' => '1',
							'data-project-filter' => '',
							'data-project-search' => 'status',
							'data-project-filter-label' => lang('all'),
						),
					),
					array(
						'label' => lang('started'),
						'attrs' => array(
							'data-project-filter-action' => '1',
							'data-project-filter' => 'started',
							'data-project-search' => 'status',
							'data-project-filter-label' => lang('started'),
						),
					),
					array(
						'label' => lang('in_progress'),
						'attrs' => array(
							'data-project-filter-action' => '1',
							'data-project-filter' => 'in_progress',
							'data-project-search' => 'status',
							'data-project-filter-label' => lang('in_progress'),
						),
					),
					array(
						'label' => lang('on_hold'),
						'attrs' => array(
							'data-project-filter-action' => '1',
							'data-project-filter' => 'on_hold',
							'data-project-search' => 'status',
							'data-project-filter-label' => lang('on_hold'),
						),
					),
					array(
						'label' => lang('cancel'),
						'attrs' => array(
							'data-project-filter-action' => '1',
							'data-project-filter' => 'cancel',
							'data-project-search' => 'status',
							'data-project-filter-label' => lang('cancel'),
						),
					),
					array(
						'label' => lang('completed'),
						'attrs' => array(
							'data-project-filter-action' => '1',
							'data-project-filter' => 'completed',
							'data-project-search' => 'status',
							'data-project-filter-label' => lang('completed'),
						),
					),
					array(
						'label' => lang('overdue'),
						'attrs' => array(
							'data-project-filter-action' => '1',
							'data-project-filter' => 'overdue',
							'data-project-search' => 'status',
							'data-project-filter-label' => lang('overdue'),
						),
					),
					array(
						'label' => lang('client'),
						'icon' => 'users',
						'divider_before' => true,
						'items' => array(
							array(
								'label' => lang('all') . ' ' . lang('clients'),
								'attrs' => array(
									'data-project-filter-action' => '1',
									'data-project-filter' => '',
									'data-project-search' => 'by_client',
									'data-project-filter-label' => lang('all') . ' ' . lang('clients'),
								),
							),
						),
						'lookup' => array(
							'endpoint' => base_url('admin/common/client_lookup'),
							'limit' => 12,
							'min_length' => 0,
							'action_attrs' => array(
								'data-project-filter-action' => '1',
								'data-project-search' => 'by_client',
							),
							'filter_attr' => 'data-project-filter',
							'label_attr' => 'data-project-filter-label',
							'label_prefix' => lang('client') . ': ',
							'placeholder' => lang('search') . ' ' . lang('client'),
							'cache_key' => 'projects_client_lookup',
						),
					),
					array(
						'label' => lang('staff'),
						'icon' => 'user',
						'items' => array(
							array(
								'label' => lang('all') . ' ' . lang('staff'),
								'attrs' => array(
									'data-project-filter-action' => '1',
									'data-project-filter' => '',
									'data-project-search' => 'by_staff',
									'data-project-filter-label' => lang('all') . ' ' . lang('staff'),
								),
							),
							array(
								'label' => lang('everyone'),
								'attrs' => array(
									'data-project-filter-action' => '1',
									'data-project-filter' => 'everyone',
									'data-project-search' => 'by_staff',
									'data-project-filter-label' => lang('staff') . ': ' . lang('everyone'),
								),
							),
						),
						'lookup' => array(
							'endpoint' => base_url('admin/common/staff_lookup'),
							'limit' => 12,
							'min_length' => 0,
							'action_attrs' => array(
								'data-project-filter-action' => '1',
								'data-project-search' => 'by_staff',
							),
							'filter_attr' => 'data-project-filter',
							'label_attr' => 'data-project-filter-label',
							'label_prefix' => lang('staff') . ': ',
							'placeholder' => lang('search') . ' ' . lang('staff'),
							'cache_key' => 'projects_staff_lookup',
						),
					),
					array(
						'label' => lang('categories'),
						'icon' => 'tag',
						'items' => array(
							array(
								'label' => lang('all') . ' ' . lang('categories'),
								'attrs' => array(
									'data-project-filter-action' => '1',
									'data-project-filter' => '',
									'data-project-search' => 'by_category',
									'data-project-filter-label' => lang('all') . ' ' . lang('categories'),
								),
							),
						),
						'lookup' => array(
							'endpoint' => base_url('admin/common/category_lookup'),
							'limit' => 12,
							'min_length' => 0,
							'extra' => array('type' => 'projects'),
							'action_attrs' => array(
								'data-project-filter-action' => '1',
								'data-project-search' => 'by_category',
							),
							'filter_attr' => 'data-project-filter',
							'label_attr' => 'data-project-filter-label',
							'label_prefix' => lang('categories') . ': ',
							'placeholder' => lang('search') . ' ' . lang('categories'),
							'cache_key' => 'projects_category_lookup',
						),
					),
				),
			),
		);
		$data['header_actions'] = array();
		if (!empty(can_action('57', 'created'))) {
			$data['header_actions'][] = array(
				'label' => lang('new_project'),
				'icon' => 'plus',
				'href' => base_url('admin/projects/create'),
				'style' => 'primary',
			);
			$data['header_actions'][] = array(
				'label' => lang('import') . ' ' . lang('project'),
				'icon' => 'upload',
				'href' => base_url('admin/projects/import'),
				'style' => 'info',
			);
		}
		$preload_cache_key = 'projects_list_preload_' . $this->session->userdata('user_id');
		$data['datatable_preload'] = $this->cache->get($preload_cache_key);
		if ($data['datatable_preload'] === false) {
			$data['datatable_preload'] = $this->build_projects_list_response();
			$this->cache->save($preload_cache_key, $data['datatable_preload'], 30);
		}
		$data['subview'] = $this->load->view('admin/projects/all_project', $data, TRUE);
		$this->load->view('admin/_layout_main', $data); //page load
	}

	public function create($id = NULL)
	{
		$edited = can_action('57', 'edited');
		$data['title'] = lang('all_project');
		// get permission user by menu id
		$data['assign_user'] = $this->project_model->allowed_user('57');
		if (!empty($id)) {
			if (is_numeric($id)) {
				$data['active'] = 2;
				$can_edit = $this->project_model->can_action('tbl_project', 'edit', array('project_id' => $id));
				if (!empty($can_edit) && !empty($edited)) {
					$data['project_info'] = $this->project_model->check_by(array('project_id' => $id), 'tbl_project');
				}
				$data['tab'] = 'projects';
			} else {
				if ($id == 'client_project') {
					$data['active'] = 2;
					$data['client_id'] = $this->uri->segment(5);
				} else if ($id == 'new') {
					$data['active'] = 2;
				} else {
					$data['active'] = $this->uri->segment(4);
				}
				$data['tab'] = $id;
			}
		} else {
			$data['active'] = 2;
			$data['tab'] = 'projects';
		}
		$data['subview'] = $this->load->view('admin/projects/create', $data, TRUE);
		$this->load->view('admin/_layout_main', $data); //page load
	}

	public function projectList($filterBy = null, $search_by = null)
	{
		if ($this->input->is_ajax_request()) {
			echo json_encode($this->build_projects_list_response($filterBy, $search_by));
			exit();
		} else {
			redirect('admin/dashboard');
		}
	}

	private function build_projects_list_response($filterBy = null, $search_by = null)
	{
		$this->load->model('datatables');
		$this->load->driver('cache', ['adapter' => 'file']);
		$original_post = $_POST;
		if (!isset($_POST['length'])) {
			$_POST['length'] = config_item('tables_pagination_limit') ?: 10;
		}
		if (!isset($_POST['start'])) {
			$_POST['start'] = 0;
		}
		if (!isset($_POST['draw'])) {
			$_POST['draw'] = 1;
		}
		if (!isset($_POST['search'])) {
			$_POST['search'] = array('value' => '', 'regex' => 'false');
		}

		$this->datatables->table = 'tbl_project';
		$this->datatables->join_table = array('tbl_client', 'tbl_customer_group');
		$this->datatables->join_where = array('tbl_project.client_id=tbl_client.client_id', 'tbl_project.category_id=tbl_customer_group.customer_group_id');
		$this->datatables->select = 'tbl_project.*,tbl_client.name,tbl_customer_group.customer_group';

		$custom_field = $this->cache->get('project_custom_fields_4');
		if ($custom_field === false) {
			$custom_field = custom_form_table_search(4);
			$this->cache->save('project_custom_fields_4', $custom_field, 300);
		}
		$main_column = array('tbl_project.project_name', 'tbl_customer_group.customer_group', 'tbl_project.tags', 'tbl_client.name', 'tbl_project.end_date', 'tbl_project.permission', 'tbl_project.project_status');
		$action_array = array('tbl_project.project_id');
		$result = array_merge($main_column, $custom_field, $action_array);
		$this->datatables->column_order = $result;
		$this->datatables->column_search = $result;
		$this->datatables->order = array('tbl_project.project_id' => 'desc');
		$where = array();
		$project_end_date_sql = "COALESCE(STR_TO_DATE(tbl_project.end_date, '%Y-%m-%d'), STR_TO_DATE(tbl_project.end_date, '%d-%b-%Y'))";
		if (!empty($search_by)) {
			if ($search_by == 'by_client') {
				$where = array('tbl_project.client_id' => $filterBy);
			}
			if ($search_by == 'by_category') {
				$where = array('tbl_project.category_id' => $filterBy);
			}
			if ($search_by == 'by_staff') {
				if ($filterBy == 'everyone') {
					$where = array('tbl_project.permission' => 'all');
				} else {
					$where = 'permission_user:' . (int) $filterBy;
				}
			}
		} else {
			if ($filterBy == 'overdue') {
				$where = array(
					'tbl_project.project_status !=' => 'completed',
					'__raw_where' => $project_end_date_sql . ' < ' . $this->db->escape(date('Y-m-d')),
				);
			} elseif (!empty($filterBy)) {
				$where = array('tbl_project.project_status' => $filterBy);
			}
		}
		$fetch_data = $this->datatables->get_datatable_permission($where);

		$data = array();
		$edited = can_action('57', 'edited');
		$deleted = can_action('57', 'deleted');
		$projects_status = $this->project_model->get_statuses();
		$current_user_type = (int) $this->session->userdata('user_type');
		$current_user_id = (int) $this->session->userdata('user_id');

		$permission_user_ids = array();
		foreach ($fetch_data as $row) {
			if (!empty($row->permission) && $row->permission !== 'all') {
				$perm = json_decode($row->permission, true);
				if (is_array($perm)) {
					$permission_user_ids = array_merge($permission_user_ids, array_keys($perm));
				}
			}
		}
		$permission_users = array();
		$permission_user_ids = array_unique(array_filter($permission_user_ids));
		if (!empty($permission_user_ids)) {
			$rows = $this->db
				->select('tbl_users.user_id, tbl_users.role_id, tbl_account_details.fullname, tbl_account_details.avatar')
				->from('tbl_users')
				->join('tbl_account_details', 'tbl_account_details.user_id = tbl_users.user_id', 'left')
				->where_in('tbl_users.user_id', $permission_user_ids)
				->get()
				->result();
			foreach ($rows as $u) {
				$permission_users[$u->user_id] = $u;
			}
		}

		$project_ids = array();
		if (!empty($fetch_data)) {
			foreach ($fetch_data as $project_row) {
				if (!empty($project_row->project_id)) {
					$project_ids[] = (int) $project_row->project_id;
				}
			}
		}
		$custom_field_map = $this->project_model->get_custom_table_values_map(4, $project_ids);
		$progress_map = $this->project_model->get_project_progress_map($fetch_data);

		foreach ($fetch_data as $key => $v_project) {
			if (!empty($v_project)) {
				$action = null;
				$progress = isset($progress_map[$v_project->project_id]) ? $progress_map[$v_project->project_id] : (float) $this->project_model->get_project_progress($v_project->project_id);

				$can_edit = false;
				$can_delete = false;
				if ($current_user_type === 1 || $v_project->permission === 'all') {
					$can_edit = true;
					$can_delete = true;
				} elseif (!empty($v_project->permission)) {
					$row_permission = json_decode($v_project->permission, true);
					if (!empty($row_permission[$current_user_id]) && is_array($row_permission[$current_user_id])) {
						$can_edit = in_array('edit', $row_permission[$current_user_id], true);
						$can_delete = in_array('delete', $row_permission[$current_user_id], true);
					}
				}

				$sub_array = array();
				if (!empty($deleted)) {
					$sub_array[] = '<div class="checkbox c-checkbox" ><label class="needsclick"> <input value="' . $v_project->project_id . '" type="checkbox"></label></div>';
				}
				$name = null;
				$name .= '<a class="text-blue-600 hover:text-blue-900 dark:text-blue-400 dark:hover:text-blue-300" href="' . base_url() . 'admin/projects/project_details/' . $v_project->project_id . '">' . $v_project->project_name . '</a>';
				if (safe_strtotime(date('Y-m-d')) > safe_strtotime($v_project->end_date) && $progress < 100 && $v_project->project_status != 'cancel') {
					$name .= '<span class="inline-flex items-center gap-1 ml-1 rounded-full bg-rose-100 px-2 py-1 text-xs font-semibold text-rose-700"><i data-lucide="alert-circle" class="h-3 w-3"></i>' . lang("overdue") . '</span>';
				}
				$name .= '<div class="progress progress-xs progress-striped active"><div class="progress-bar progress-bar-' . (($progress <= 100) ? "success" : "primary") . '"data-toggle = "tooltip" data-original-title = "' . $progress . '%" style = "width:' . $progress . '%" ></div></div>';
				$sub_array[] = $name;
				$category = !empty($v_project->category_id) ? '<span class="tags">' . $v_project->customer_group . '</span>' : '';
				$sub_array[] = $category;
				$sub_array[] = get_tags($v_project->tags, true);
				$sub_array[] = !empty($v_project->name) ? $v_project->name : lang('undefined_client');
				$sub_array[] = display_date($v_project->end_date);
				$sub_array[] = $this->render_project_assigned_html($v_project, $permission_users);
				$statusss = null;
				if (!empty($v_project->project_status)) {
					$statusss = "<span class='inline-flex items-center rounded-full px-2.5 py-1 text-xs font-semibold {$projects_status[array_search($v_project->project_status, array_column($projects_status, 'value'))]['class']}'>" . lang($v_project->project_status) . "</span>";
				}
				$change_status = null;
				if (!empty($can_edit) && !empty($edited)) {
					$ch_url = base_url() . 'admin/projects/change_status/';
					$items = '';
					foreach ($projects_status as $v_status) {
						$status_key = $v_status['value'];
						$status_label = lang($v_status['value']);
						$is_active = ($v_project->project_status == $status_key);
						$active_class = $is_active
							? 'bg-slate-100 font-medium text-slate-900 dark:bg-gray-700 dark:text-white'
							: 'text-slate-700 dark:text-gray-300';
						$items .= '<li><a class="block px-3 py-2 ' . $active_class . ' hover:bg-slate-50 dark:hover:bg-gray-700 " href="' . $ch_url . $v_project->project_id . '/' . $status_key . '">' . $status_label . '</a></li>';
					}
					$change_status = '<details class="relative inline-flex --">
						<summary class="inline-flex cursor-pointer list-none items-center justify-center gap-1 rounded-md border border-slate-200 bg-white px-2 py-1 text-slate-500 shadow-sm transition-colors hover:bg-slate-50 hover:text-slate-900 dark:border-gray-700 dark:bg-gray-800 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-gray-200">
							<i data-lucide="chevron-down" class="h-3 w-3"></i>
						</summary>
						<ul class="absolute right-0 top-full z-50 mt-1 min-w-[160px] overflow-hidden rounded-lg border border-slate-200 bg-white py-1 text-xs shadow-lg dark:border-gray-700 dark:bg-gray-800">'
						. $items .
						'</ul>
					</details>';
				}
				$sub_array[] = $statusss . ' ' . $change_status;
				$custom_form_table = isset($custom_field_map[$v_project->project_id]) ? $custom_field_map[$v_project->project_id] : array();
				if (!empty($custom_form_table)) {
					foreach ($custom_form_table as $c_label => $v_fields) {
						$sub_array[] = $v_fields;
					}
				}
				$action .= btn_view('admin/projects/project_details/' . $v_project->project_id) . ' ';
				if (!empty($can_edit) && !empty($edited)) {
					$action .= btn_modal('admin/projects/clone_project/' . $v_project->project_id, '', lang('clone_project'), 'md', 'copy', ['class' => 'btn btn-success btn-xs h-7 mb-1 ',]);
					$action .= btn_edit('admin/projects/create/' . $v_project->project_id) . ' ';
				}
				if (!empty($can_delete) && !empty($deleted)) {
					$action .= ajax_anchor(base_url("admin/projects/delete_project/$v_project->project_id"), '', array("class" => "", "title" => lang('delete'), "data-fade-out-on-success" => "#table_" . $key)) . ' ';
				}
				$sub_array[] = '<div class="erp-table-actions">' . $action . '</div>';
				$data[] = $sub_array;
			}
		}

		$output = build_table_output($data, $where);
		$_POST = $original_post;
		return $output;
	}

	private function render_project_assigned_html($project, $permission_users = null)
	{
		$edited = can_action('57', 'edited');
		$current_user_type = (int) $this->session->userdata('user_type');
		$current_user_id = (int) $this->session->userdata('user_id');
		$can_edit = false;

		if ($current_user_type === 1 || $project->permission === 'all') {
			$can_edit = true;
		} elseif (!empty($project->permission)) {
			$row_permission = json_decode($project->permission, true);
			if (!empty($row_permission[$current_user_id]) && is_array($row_permission[$current_user_id])) {
				$can_edit = in_array('edit', $row_permission[$current_user_id], true);
			}
		}

		if ($permission_users === null) {
			$permission_users = array();
			if (!empty($project->permission) && $project->permission !== 'all') {
				$get_permission = json_decode($project->permission, true);
				$user_ids = is_array($get_permission) ? array_keys($get_permission) : array();
				if (!empty($user_ids)) {
					$rows = $this->db
						->select('tbl_users.user_id, tbl_users.role_id, tbl_account_details.fullname, tbl_account_details.avatar')
						->from('tbl_users')
						->join('tbl_account_details', 'tbl_account_details.user_id = tbl_users.user_id', 'left')
						->where_in('tbl_users.user_id', $user_ids)
						->get()
						->result();
					foreach ($rows as $user) {
						$permission_users[$user->user_id] = $user;
					}
				}
			}
		}

		$assigned = '<div class="flex items-center" data-project-member-cell-content="' . (int) $project->project_id . '">';
		if ($project->permission != 'all') {
			$get_permission = json_decode($project->permission, true);
			if (!empty($get_permission)) {
				foreach ($get_permission as $permission => $v_permission) {
					$user_info = isset($permission_users[$permission]) ? $permission_users[$permission] : null;
					if (!empty($user_info)) {
						$ring = ($user_info->role_id == 1) ? 'ring-rose-500' : 'ring-emerald-500';
						$avatar = !empty($user_info->avatar) ? $user_info->avatar : 'assets/img/user/default_avatar.jpg';
						$name = !empty($user_info->fullname) ? $user_info->fullname : lang('undefined_user');
						$assigned .= '<span class="relative inline-flex items-center" data-tooltip="' . html_escape($name) . '">
							<img src="' . base_url() . $avatar . '" class="h-7 w-7 rounded-full ring-2 ring-white dark:ring-slate-900 ' . $ring . '" alt="' . html_escape($name) . '">
						</span>';
					}
				}
			}
		} else {
			$assigned .= '<span class="inline-flex items-center gap-1 ml-0 rounded-full bg-slate-100 px-2 py-1 text-xs font-semibold text-slate-700"><i data-lucide="users" class="h-4 w-4"></i>' . lang("everyone") . '</span>';
		}
		if (!empty($can_edit) && !empty($edited)) {
			$assigned .= btn_modal(
				'admin/projects/update_users/' . $project->project_id,
				null,
				lang('assigned_to'),
				'md',
				'user-plus'
			);
		}
		$assigned .= '</div>';

		return $assigned;
	}

	public function import()
	{
		$data['title'] = lang('import') . ' ' . lang('project');
		$data['assign_user'] = $this->project_model->allowed_user('57');
		$data['subview'] = $this->load->view('admin/projects/import_project', $data, TRUE);
		$this->load->view('admin/_layout_main', $data); //page load
	}

	public function save_imported()
	{
		$created = can_action('57', 'created');
		if (!empty($created)) {
			//load the excel library
			$this->load->library('excel');
			$files = $this->excel->import($_FILES['upload_file']['tmp_name']);

			if (!empty($files['message'])) {
				set_message('error', $files['message']);
				redirect('admin/projects/import');
			}

			$my_data = array();
			foreach ($files as $key => $value) {
				if (!empty($value[0])) {
					$projects = '';
					$data = $this->project_model->array_from_post(array('client_id'));
					if (empty(config_item('projects_number_format'))) {
						$projects .= config_item('projects_prefix');
					}
					$projects .= $this->project_model->generate_projects_number();
					$data['project_no'] = $projects;
					$data['project_name'] = trim($value[0]);
					$data['progress'] = trim($value[1]);
					$data['start_date'] = date('Y-m-d', safe_strtotime($value[2]));
					$data['end_date'] = date('Y-m-d', safe_strtotime($value[3]));
					$data['project_status'] = trim($value[4]);
					$data['project_cost'] = trim($value[5]);
					$data['demo_url'] = trim($value[6]);
					$data['description'] = trim($value[7]);
					$data['estimate_hours'] = '0:00';
					$data['project_settings'] = json_encode(array('show_team_members', 'show_milestones', 'show_project_tasks', 'show_project_attachments', 'show_timesheets', 'show_project_bugs', 'show_project_history', 'show_project_calendar', 'show_project_comments', 'show_gantt_chart', 'show_project_hours', 'comment_on_project_tasks', 'show_project_tasks_attachments', 'show_tasks_hours', 'show_finance_overview'));
					$permission = $this->input->post('permission', true);
					if (!empty($permission)) {
						if ($permission == 'everyone') {
							$assigned = 'all';
						} else {
							$assigned_to = $this->project_model->array_from_post(array('assigned_to'));
							if (!empty($assigned_to['assigned_to'])) {
								foreach ($assigned_to['assigned_to'] as $assign_user) {
									$assigned[$assign_user] = $this->input->post('action_' . $assign_user, true);
								}
							}
						}
						if (!empty($assigned)) {
							if ($assigned != 'all') {
								$assigned = json_encode($assigned);
							}
						} else {
							$assigned = 'all';
						}
						$data['permission'] = $assigned;
					}
					$this->project_model->_table_name = 'tbl_project';
					$this->project_model->_primary_key = 'project_id';
					$id = $this->project_model->save($data);
					// $my_data[]=$data;
				}
			}
			//save data into table.
			$action = 'activity_save_project';
			$msg = lang('save_project');

			// save into activities
			$activity = array(
				'user' => $this->session->userdata('user_id'),
				'module' => 'projects',
				'module_field_id' => $id,
				'activity' => $action,
				'icon' => 'fa-folder-open-o',
				'link' => 'admin/projects/project_details/' . $id,
				'value1' => $data['project_name']
			);
			$this->project_model->_table_name = 'tbl_activities';
			$this->project_model->_primary_key = 'activities_id';
			$this->project_model->save($activity);

			$type = "success";
			$message = $msg;


			set_message($type, $message);
			if (empty($_SERVER['HTTP_REFERER'])) {
				redirect('admin/projects');
			} else {
				redirect($_SERVER['HTTP_REFERER']);
			}
		} else {
			set_message('error', lang('there_in_no_value'));
			redirect('admin/projects');
		}
	}

	// make a dummy function for saving 1200 dymmy project data for testing purpose
	public function save_dummy_projects()
	{
		$batch_size = 1000;
		$batache_arr = array();

		for ($i = 1; $i <= $batch_size; $i++) {
			$projects = '';
			if (empty(config_item('projects_number_format'))) {
				$projects .= config_item('projects_prefix');
			}
			$projects .= $this->project_model->generate_projects_number();
			$data = array(
				'project_no' => $projects,
				'project_name' => 'Dummy Project ' . $i,
				'client_id' => 1,
				'progress' => rand(0, 100),
				'calculate_progress' => 'through_tasks',
				'start_date' => date('Y-m-d'),
				'end_date' => date('Y-m-d', safe_strtotime('+ ' . rand(10, 100) . ' days')),
				'billing_type' => 'fixed_rate',
				'project_cost' => rand(1000, 10000),
				'hourly_rate' => rand(10, 100),
				'project_status' => array_rand(array('started', 'in_progress', 'on_hold', 'cancel', 'completed')),
				'estimate_hours' => '0:00',
				'demo_url' => '',
				'description' => 'This is a dummy project for testing purposes.',
				'permission' => 'all',
				'project_settings' => json_encode(array('show_team_members', 'show_milestones', 'show_project_tasks', 'show_project_attachments', 'show_timesheets', 'show_project_bugs', 'show_project_history', 'show_project_calendar', 'show_project_comments', 'show_gantt_chart', 'show_project_hours', 'comment_on_project_tasks', 'show_project_tasks_attachments', 'show_tasks_hours', 'show_finance_overview')),
			);
			$batache_arr[] = $data;
		}
		$this->db->insert_batch('tbl_project', $batache_arr);
		echo 'Inserted ' . $batch_size . ' dummy projects successfully.';
		// show execution time
		echo '<br>Execution Time: ' . (microtime(true) - $_SERVER["REQUEST_TIME_FLOAT"]) . ' seconds.';
		exit();
	}

	public function saved_project($id = NULL)
	{
		$created = can_action('57', 'created');
		$edited = can_action('57', 'edited');
		if (!empty($created) || !empty($edited) && !empty($id)) {
			$this->project_model->_table_name = 'tbl_project';
			$this->project_model->_primary_key = 'project_id';

			$data = $this->project_model->array_from_post(array('project_no', 'project_name', 'tags', 'category_id', 'client_id', 'progress', 'calculate_progress', 'start_date', 'end_date', 'billing_type', 'project_cost', 'hourly_rate', 'project_status', 'demo_url', 'description'));
			$data['tags'] = normalize_and_sync_tags($data['tags']);

			if (empty($data['project_cost'])) {
				$data['project_cost'] = '0';
			}
			if (empty($data['hourly_rate'])) {
				$data['hourly_rate'] = '0';
			}
			if ($data['project_status'] == 'completed') {
				$data['progress'] = 100;
			}
			if ($data['progress'] == 100) {
				$data['project_status'] = 'completed';
			}

			$estimate_hours = $this->input->post('estimate_hours', true);
			$check_flot = explode('.', $estimate_hours);
			if (!empty($check_flot[0])) {
				if (!empty($check_flot[1])) {
					$data['estimate_hours'] = $check_flot[0] . ':' . $check_flot[1];
				} else {
					$data['estimate_hours'] = $check_flot[0] . ':00';
				}
			} else {
				$data['estimate_hours'] = '0:00';
			}

			$project_permissions = $this->db->get('tbl_project_settings')->result();
			$psdata = project_settings_post($project_permissions);
			if (!empty($psdata)) {
				$data['project_settings'] = json_encode($psdata);
			} else {
				$data['project_settings'] = null;
			}
			$data['permission'] = permission_post();

			if (!empty($id)) {
				$can_edit = $this->project_model->can_action('tbl_project', 'edit', array('project_id' => $id));
				if (!empty($can_edit)) {
					$return_id = $this->project_model->save($data, $id);
				} else {
					set_message('error', lang('there_in_no_value'));
					redirect('admin/projects');
				}
			} else {
				$return_id = $this->project_model->save($data);
			}

			if ($data['permission'] == 'all') {
				$assigned_to['assigned_to'] = $this->project_model->allowed_user_id('57');
			}
			if (!empty($id)) {
				$id = $id;
				$action = 'activity_update_project';
				$msg = lang('update_project');
			} else {
				$id = $return_id;
				$action = 'activity_save_project';
				$msg = lang('save_project');
				$projects_email = config_item('projects_email');
				if (!empty($projects_email) && $projects_email == 1) {
					$this->send_project_notify_client($return_id);
					$this->send_project_notify_assign_user($return_id, $assigned_to['assigned_to']);
				}
			}

			save_custom_field(4, $id);

			$activity = array(
				'user' => $this->session->userdata('user_id'),
				'module' => 'projects',
				'module_field_id' => $id,
				'activity' => $action,
				'icon' => 'fa-folder-open-o',
				'link' => 'admin/projects/project_details/' . $id,
				'value1' => $data['project_name']
			);
			$this->project_model->_table_name = 'tbl_activities';
			$this->project_model->_primary_key = 'activities_id';
			$this->project_model->save($activity);

			$this->project_model->set_progress($id);
			// messages for user
			$type = "success";
			if ($this->input->post('progress') == '100') {
				$projects_email = config_item('projects_email');
				if (!empty($projects_email) && $projects_email == 1) {
					$this->send_project_notify_client($id, true);
				}
			}
			$message = $msg;
			set_message($type, $message);
			redirect('admin/projects/project_details/' . $id);
		} else {
			redirect('admin/projects');
		}
	}

	// add_milestone
	public function add_milestone($project_id, $id = null)
	{
		$data['title'] = lang('add_milestone');
		if (!empty($id)) {
			$data['milestone_info'] = $this->project_model->check_by(array('milestones_id' => $id), 'tbl_milestones');
		}
		$data['project_id'] = $project_id;
		$this->load->view('admin/projects/project_details/add_milestone', $data);
	}

	public function clone_project($project_id)
	{
		$edited = can_action('57', 'edited');
		$can_edit = $this->project_model->can_action('tbl_project', 'edit', array('project_id' => $project_id));
		if (!empty($can_edit) && !empty($edited)) {
			$data['project_info'] = $this->invoice_model->check_by(array('project_id' => $project_id), 'tbl_project');
			$data['milestone_info'] = $this->invoice_model->check_by(array('project_id' => $project_id), 'tbl_milestones');
			$data['task_info'] = $this->invoice_model->check_by(array('project_id' => $project_id), 'tbl_task');
			// get all client
			$this->invoice_model->_table_name = 'tbl_client';
			$this->invoice_model->_order_by = 'client_id';
			$data['all_client'] = $this->invoice_model->get();

			$data['modal_subview'] = $this->load->view('admin/projects/clone_project', $data, FALSE);
		} else {
			set_message('error', lang('there_in_no_value'));
			if (empty($_SERVER['HTTP_REFERER'])) {
				redirect('admin/projects');
			} else {
				redirect($_SERVER['HTTP_REFERER']);
			}
		}
	}

	public function cloned_project($id)
	{
		$created = can_action('57', 'created');
		$edited = can_action('57', 'edited');
		$type = 'error';
		$message = lang('there_in_no_value');
		$new_project_id = null;
		if (!empty($created) || !empty($edited) && !empty($id)) {
			$this->project_model->_table_name = "tbl_project"; //table name
			$this->project_model->_order_by = "project_id";
			$project_info = $this->project_model->get_by(array('project_id' => $id), TRUE);
			if (empty($project_info)) {
				if ($this->input->is_ajax_request()) {
					echo json_encode(array("status" => $type, 'message' => $message));
					exit();
				}
				set_message($type, $message);
				redirect('admin/projects');
			}

			$projects = '';
			if (empty(config_item('projects_number_format'))) {
				$projects .= config_item('projects_prefix');
			}
			$projects .= $this->project_model->generate_projects_number();
			$new_project = array(
				'project_no' => $projects,
				'project_name' => $project_info->project_name,
				'client_id' => $this->input->post('client_id', true),
				'progress' => $project_info->progress,
				'calculate_progress' => $project_info->calculate_progress,
				'start_date' => $this->input->post('start_date', true),
				'end_date' => $this->input->post('end_date', true),
				'billing_type' => $project_info->billing_type,
				'project_cost' => $project_info->project_cost,
				'hourly_rate' => $project_info->hourly_rate,
				'project_status' => $project_info->project_status,
				'estimate_hours' => $project_info->estimate_hours,
				'demo_url' => $project_info->demo_url,
				'tags' => $project_info->tags,
				'description' => $project_info->description,
				'permission' => $project_info->permission,
				'project_settings' => $project_info->project_settings,
			);

			$this->project_model->_table_name = "tbl_project"; //table name
			$this->project_model->_primary_key = "project_id";
			$new_project_id = $this->project_model->save($new_project);
			$milestones = $this->input->post('milestones', true);
			if (!empty($milestones)) {
				//get milestones info by project id
				$this->project_model->_table_name = "tbl_milestones"; //table name
				$this->project_model->_order_by = "project_id";
				$milestones_info = $this->project_model->get_by(array('project_id' => $id), FALSE);

				if (!empty($milestones_info)) {
					foreach ($milestones_info as $v_milestone) {
						$milestone = array(
							'milestone_name' => $v_milestone->milestone_name,
							'description' => $v_milestone->description,
							'project_id' => $new_project_id,
							'user_id' => $v_milestone->user_id,
							'start_date' => $v_milestone->start_date,
							'end_date' => $v_milestone->end_date
						);
						$this->project_model->_table_name = "tbl_milestones"; //table name
						$this->project_model->_primary_key = "milestones_id";
						$this->project_model->save($milestone);
					}
				}
			}

			$tasks = $this->input->post('tasks', true);
			if (!empty($tasks)) {
				//get tasks info by project id
				$this->project_model->_table_name = "tbl_task"; //table name
				$this->project_model->_order_by = "project_id";
				$takse_info = $this->project_model->get_by(array('project_id' => $id), FALSE);
				if (!empty($takse_info)) {
					foreach ($takse_info as $v_task) {
						$task = array(
							'task_name' => $v_task->task_name,
							'project_id' => $new_project_id,
							'milestones_id' => $v_task->milestones_id,
							'permission' => $v_task->permission,
							'task_description' => $v_task->task_description,
							'task_start_date' => $v_task->task_start_date,
							'due_date' => $v_task->due_date,
							'task_created_date' => $v_task->task_created_date,
							'task_status' => $v_task->task_status,
							'task_progress' => $v_task->task_progress,
							'task_hour' => $v_task->task_hour,
							'tasks_notes' => $v_task->tasks_notes,
							'timer_status' => $v_task->timer_status,
							'client_visible' => $v_task->client_visible,
							'timer_started_by' => $v_task->timer_started_by,
							'start_time' => $v_task->start_time,
							'logged_time' => $v_task->logged_time,
							'created_by' => $v_task->created_by
						);
						$this->project_model->_table_name = "tbl_task"; //table name
						$this->project_model->_primary_key = "task_id";
						$this->project_model->save($task);
					}
				}
			}
			// save into activities
			$activities = array(
				'user' => $this->session->userdata('user_id'),
				'module' => 'projects',
				'module_field_id' => $id,
				'activity' => lang('activity_copied_project'),
				'icon' => 'fa-folder-open-o',
				'link' => 'admin/projects/project_details/' . $id,
				'value1' => $project_info->project_name,
			);
			// Update into tbl_project
			$this->project_model->_table_name = "tbl_activities"; //table name
			$this->project_model->_primary_key = "activities_id";
			$this->project_model->save($activities);

			// messages for user
			$type = "success";
			$message = lang('copied_project');
			set_message($type, $message);

			$this->load->driver('cache', ['adapter' => 'file']);
			$this->cache->delete('projects_list_preload_' . $this->session->userdata('user_id'));
		}
		if ($this->input->is_ajax_request()) {
			echo json_encode(array(
				"status" => $type,
				'message' => $message,
				'project_id' => $new_project_id,
				'reload_page' => $type === 'success',
			));
			exit();
		}
		if ($type === 'success' && !empty($new_project_id)) {
			redirect('admin/projects/project_details/' . $new_project_id);
		}
		redirect('admin/projects');
	}

	public function update_settings($id)
	{
		$edited = can_action('57', 'edited');
		$can_edit = $this->project_model->can_action('tbl_project', 'edit', array('project_id' => $id));
		if (!empty($can_edit) && !empty($edited) && !empty($id)) {
			$project_info = $this->project_model->check_by(array('project_id' => $id), 'tbl_project');
			$project_permissions = $this->db->get('tbl_project_settings')->result();
			$psdata = project_settings_post($project_permissions);
			$data['project_settings'] = json_encode($psdata);

			$this->project_model->_table_name = 'tbl_project';
			$this->project_model->_primary_key = 'project_id';
			$this->project_model->save($data, $id);

			$action = 'activity_update_project';
			$msg = lang('update_project');

			$activity = array(
				'user' => $this->session->userdata('user_id'),
				'module' => 'projects',
				'module_field_id' => $id,
				'activity' => $action,
				'icon' => 'fa-folder-open-o',
				'link' => 'admin/projects/project_details/' . $id,
				'value1' => $project_info->project_name
			);
			$this->project_model->_table_name = 'tbl_activities';
			$this->project_model->_primary_key = 'activities_id';
			$this->project_model->save($activity);

			// messages for user
			$type = "success";
			$message = $msg;
			set_message($type, $message);
			redirect('admin/projects/project_details/' . $id);
		} else {
			set_message('error', lang('there_in_no_value'));
			redirect('admin/projects');
		}
	}

	public function send_project_notify_assign_user($project_id, $users)
	{

		$project_info = $this->project_model->check_by(array('project_id' => $project_id), 'tbl_project');
		$email_template = email_templates(array('email_group' => 'assigned_project'), $project_info->client_id);
		$message = $email_template->template_body;

		$subject = $email_template->subject;

		$project_name = str_replace("{PROJECT_NAME}", $project_info->project_name, $message);

		$assigned_by = str_replace("{ASSIGNED_BY}", ucfirst($this->session->userdata('name')), $project_name);
		$Link = str_replace("{PROJECT_URL}", base_url() . 'admin/projects/project_details/' . $project_id, $assigned_by);
		$message = str_replace("{SITE_NAME}", config_item('company_name'), $Link);

		$data['message'] = $message;
		$message = $this->load->view('email_template', $data, TRUE);

		$params['subject'] = $subject;
		$params['message'] = $message;
		$params['resourceed_file'] = '';
		if (!empty($users)) {
			foreach ($users as $v_user) {
				$login_info = $this->project_model->check_by(array('user_id' => $v_user), 'tbl_users');
				$params['recipient'] = $login_info->email;
				$this->project_model->send_email($params);

				if ($v_user != $this->session->userdata('user_id')) {
					add_notification(array(
						'to_user_id' => $v_user,
						'from_user_id' => true,
						'description' => 'assign_to_you_the_project',
						'link' => 'admin/projects/project_details/' . $project_id,
						'value' => $project_info->project_name,
					));
				}
			}
			show_notification($users);
		}
	}

	public function send_project_notify_client($project_id, $complete = NULL)
	{
		$project_info = $this->project_model->check_by(array('project_id' => $project_id), 'tbl_project');
		if (!empty($complete)) {
			$email_template = email_templates(array('email_group' => 'complete_projects'), $project_info->client_id);
			$description = 'not_completed';
		} else {
			$email_template = email_templates(array('email_group' => 'client_notification'), $project_info->client_id);
			$description = 'not_new_project_created';
		}
		$client_info = $this->project_model->check_by(array('client_id' => $project_info->client_id), 'tbl_client');
		$message = $email_template->template_body;
		$subject = $email_template->subject;

		$clientName = str_replace("{CLIENT_NAME}", $client_info->name, $message);
		$project_name = str_replace("{PROJECT_NAME}", $project_info->project_name, $clientName);

		$Link = str_replace("{PROJECT_LINK}", base_url() . 'admin/projects/project_details/' . $project_id, $project_name);
		$message = str_replace("{SITE_NAME}", config_item('company_name'), $Link);

		$data['message'] = $message;
		$message = $this->load->view('email_template', $data, TRUE);

		$params['subject'] = $subject;
		$params['message'] = $message;
		$params['resourceed_file'] = '';

		$params['recipient'] = $client_info->email;
		$this->project_model->send_email($params);

		if (!empty($client_info->primary_contact)) {
			$notifyUser = array($client_info->primary_contact);
		} else {
			$user_info = $this->project_model->check_by(array('company' => $project_info->client_id), 'tbl_account_details');
			if (!empty($user_info)) {
				$notifyUser = array($user_info->user_id);
			}
		}
		if (!empty($notifyUser)) {
			foreach ($notifyUser as $v_user) {
				if ($v_user != $this->session->userdata('user_id')) {
					add_notification(array(
						'to_user_id' => $v_user,
						'from_user_id' => true,
						'description' => $description,
						'link' => 'client/projects/project_details/' . $project_id,
						'value' => $project_info->project_name,
					));
				}
			}
			show_notification($notifyUser);
		}
	}

	public function invoice($id)
	{
		$data['project_info'] = $this->project_model->check_by(array('project_id' => $id), 'tbl_project');

		$sbtn = $this->input->post('submit', true);

		if (!empty($sbtn)) {
			if (config_item('increment_invoice_number') == 'FALSE') {
				$this->load->helper('string');
				$reference_no = config_item('invoice_prefix') . ' ' . random_string('nozero', 6);
			} else {
				$reference_no = $this->project_model->generate_invoice_number();
			}

			$this->project_model->_table_name = "tbl_project"; //table name
			$this->project_model->_order_by = "project_id";
			$project_info = $this->project_model->get_by(array('project_id' => $id), TRUE);

			$currency = $this->project_model->client_currency_symbol($project_info->client_id);
			if (!empty($currency->code)) {
				$curr = $currency->code;
			} else {
				$curr = config_item('default_currency');
			}
			// save into invoice table
			$new_invoice = array(
				'reference_no' => $reference_no,
				'client_id' => $project_info->client_id,
				'currency' => $curr,
				'due_date' => $project_info->end_date,
			);
			$this->project_model->_table_name = "tbl_invoices"; //table name
			$this->project_model->_primary_key = "invoices_id";
			$new_invoice_id = $this->project_model->save($new_invoice);

			$items = array(
				'invoices_id' => $new_invoice_id,
				'item_name' => $project_info->project_name,
				'item_desc' => $project_info->description,
				'unit_cost' => $project_info->project_cost,
				'quantity' => 1,
				'total_cost' => $project_info->project_cost,
			);
			$this->project_model->_table_name = "tbl_items"; //table name
			$this->project_model->_primary_key = "items_id";
			$this->project_model->save($items);

			// save into activities
			$activities = array(
				'user' => $this->session->userdata('user_id'),
				'module' => 'invoice',
				'module_field_id' => $new_invoice_id,
				'activity' => lang('activity_new_invoice_form_project'),
				'icon' => 'fa-shopping-cart',
				'link' => 'admin/invoice/manage_invoice/invoice_details/' . $new_invoice_id,
				'value1' => $reference_no,
			);
			// Update into tbl_project
			$this->project_model->_table_name = "tbl_activities"; //table name
			$this->project_model->_primary_key = "activities_id";
			$this->project_model->save($activities);

			// messages for user
			$type = "success";
			$message = lang('invoice_created');
			set_message($type, $message);
			redirect('admin/invoice/manage_invoice/invoice_details/' . $new_invoice_id);
		} else {
			// get all assign_user
			$data['modal_subview'] = $this->load->view('admin/projects/project_invoice', $data, FALSE);
		}
	}

	public function preview_invoice($id)
	{
		$data['project_info'] = $this->project_model->check_by(array('project_id' => $id), 'tbl_project');
		if (!empty($data['project_info'])) {

			$data['title'] = lang('preview_invoice');
			$data['items_name'] = $this->input->post('items_name', true);
			if ($data['items_name'] != 'single_line') {
				$data['tasks'] = $this->input->post('tasks', true);
			}
			$data['expense'] = $this->input->post('expense', true);
			$data['permission_user'] = $this->project_model->all_permission_user('13');
			// get all client
			$data['all_client'] = $this->db->get('tbl_client')->result();
			$data['subview'] = $this->load->view('admin/projects/preview_invoice', $data, TRUE);
			$this->load->view('admin/_layout_main', $data); //page load
		} else {
			set_message('error', lang('there_in_no_value'));
			redirect('admin/projects');
		}
	}

	function save_invoice($project_id = null)
	{
		$created = can_action('13', 'created');
		$edited = can_action('13', 'edited');
		if (!empty($created) || !empty($edited) && !empty($project_id)) {
			$save_as_draft = $this->input->post('save_as_draft', true);
			$update = $this->input->post('create', true);

			if (!empty($save_as_draft) || !empty($update)) {
				$data = $this->invoice_model->array_from_post(array('reference_no', 'client_id', 'project_id', 'warehouse_id', 'discount_type', 'discount_percent', 'user_id', 'adjustment', 'discount_total', 'show_quantity_as'));

				$all_payment = get_result('tbl_online_payment');
				foreach ($all_payment as $payment) {
					$allow_gateway = 'allow_' . slug_it(strtolower($payment->gateway_name));
					$gateway_status = slug_it(strtolower($payment->gateway_name)) . '_status';
					if (config_item($gateway_status) == 'active') {
						$data[$allow_gateway] = ($this->input->post($allow_gateway) == 'Yes') ? 'Yes' : 'No';
					}
				}

				$data['client_visible'] = ($this->input->post('client_visible') == 'Yes') ? 'Yes' : 'No';
				$data['invoice_date'] = date('Y-m-d', safe_strtotime($this->input->post('invoice_date', TRUE)));
				if (empty($data['invoice_date'])) {
					$data['invoice_date'] = date('Y-m-d');
				}
				$data['invoice_year'] = date('Y', safe_strtotime($this->input->post('invoice_date', TRUE)));
				$data['invoice_month'] = date('Y-m', safe_strtotime($this->input->post('invoice_date', TRUE)));
				$data['due_date'] = date('Y-m-d', safe_strtotime($this->input->post('due_date', TRUE)));
				$data['notes'] = $this->input->post('notes', TRUE);
				$tax['tax_name'] = $this->input->post('total_tax_name', TRUE);
				$tax['total_tax'] = $this->input->post('total_tax', TRUE);
				$data['total_tax'] = json_encode($tax);
				$i_tax = 0;
				if (!empty($tax['total_tax'])) {
					foreach ($tax['total_tax'] as $v_tax) {
						$i_tax += $v_tax;
					}
				}
				$data['tax'] = $i_tax;
				$save_as_draft = $this->input->post('save_as_draft', TRUE);
				if (!empty($save_as_draft)) {
					$data['status'] = 'draft';
				}

				$currency = $this->invoice_model->client_currency_symbol($data['client_id']);
				if (!empty($currency->code)) {
					$curren = $currency->code;
				} else {
					$curren = config_item('default_currency');
				}
				$data['currency'] = $curren;

				$data['permission'] = permission_post();
				$this->db->trans_begin();
				$stock_ok = true;
				$stock_error = lang('stock_update_failed');
				// get all client
				$this->project_model->_table_name = 'tbl_invoices';
				$this->project_model->_primary_key = 'invoices_id';
				$invoice_id = $this->project_model->save($data);
				$project_info = $this->project_model->check_by(array('project_id' => $data['project_id']), 'tbl_project');
				if (!empty($project_info->client_id)) {
					$client_info = $this->project_model->check_by(array('client_id' => $project_info->client_id), 'tbl_client');
					if (!empty($client_info->primary_contact)) {
						$notifyUser = array($client_info->primary_contact);
					}
				} else {
					$user_info = $this->project_model->check_by(array('company' => $project_info->client_id), 'tbl_account_details');
					if (!empty($user_info)) {
						$notifyUser = array($user_info->user_id);
					}
				}

				if (!empty($notifyUser)) {
					foreach ($notifyUser as $v_user) {
						if ($v_user != $this->session->userdata('user_id')) {
							add_notification(array(
								'to_user_id' => $v_user,
								'icon' => 'shopping-cart',
								'description' => 'not_invoice_created',
								'link' => 'client/invoice/manage_invoice/invoice_details/' . $invoice_id,
								'value' => $data['reference_no'],
							));
						}
					}
					show_notification($notifyUser);
				}
				save_custom_field(9, $invoice_id);

				$recuring_frequency = $this->input->post('recuring_frequency', TRUE);
				if (!empty($recuring_frequency) && $recuring_frequency != 'none') {
					$recur_data = $this->project_model->array_from_post(array('recur_start_date', 'recur_end_date'));
					$recur_data['recuring_frequency'] = $recuring_frequency;
					$this->get_recuring_frequency($invoice_id, $recur_data); // set recurring
				}
				$qty_calculation = config_item('qty_calculation_from_items');
				// save items
				$invoices_to_merge = $this->input->post('invoices_to_merge', TRUE);
				$cancel_merged_invoices = $this->input->post('cancel_merged_invoices', TRUE);
				if (!empty($invoices_to_merge)) {
					foreach ($invoices_to_merge as $inv_id) {
						if (empty($cancel_merged_invoices)) {
							if (!empty($qty_calculation) && $qty_calculation == 'Yes') {
								$all_items_info = $this->db->where('invoices_id', $inv_id)->get('tbl_items')->result();
								if (!empty($all_items_info)) {
									foreach ($all_items_info as $v_items) {
										if (!empty($data['warehouse_id']) && !empty($v_items->saved_items_id) && is_numeric($v_items->saved_items_id) && !$this->invoice_model->return_items($v_items->saved_items_id, $v_items->quantity, $data['warehouse_id'])) {
											$stock_ok = false;
											break;
										}
									}
								}
								if (!$stock_ok) {
									break;
								}
							}
							$this->db->where('invoices_id', $inv_id);
							$this->db->delete('tbl_invoices');

							$this->db->where('invoices_id', $inv_id);
							$this->db->delete('tbl_items');
						} else {
							$mdata = array('status' => 'Cancelled');
							$this->invoice_model->_table_name = 'tbl_invoices';
							$this->invoice_model->_primary_key = 'invoices_id';
							$this->invoice_model->save($mdata, $inv_id);
						}
					}
					if (!$stock_ok) {
						$this->db->trans_rollback();
						set_message('error', $stock_error);
						redirect($_SERVER['HTTP_REFERER']);
					}
				}

				$removed_items = $this->input->post('removed_items', TRUE);
				if (!empty($removed_items)) {
					foreach ($removed_items as $r_id) {
						if ($r_id != 'undefined') {
							if (!empty($qty_calculation) && $qty_calculation == 'Yes') {
								$itemInfo = get_row('tbl_items', array('items_id' => $r_id));
								if (!empty($data['warehouse_id']) && !empty($itemInfo->saved_items_id) && is_numeric($itemInfo->saved_items_id) && !$this->invoice_model->return_items($itemInfo->saved_items_id, $itemInfo->quantity, $data['warehouse_id'])) {
									$stock_ok = false;
									break;
								}
							}

							$this->db->where('items_id', $r_id);
							$this->db->delete('tbl_items');
						}
					}
				}
				if (!$stock_ok) {
					$this->db->trans_rollback();
					set_message('error', $stock_error);
					redirect($_SERVER['HTTP_REFERER']);
				}

				$itemsid = $this->input->post('items_id', TRUE);
				$items_data = $this->input->post('items', true);

				if (!empty($items_data)) {
					$index = 0;
					foreach ($items_data as $items) {
						$items['invoices_id'] = $invoice_id;
						$tax = 0;
						if (!empty($items['taxname'])) {
							foreach ($items['taxname'] as $tax_name) {
								$tax_rate = explode("|", $tax_name);
								$tax += $tax_rate[1];
							}
							$items['item_tax_name'] = $items['taxname'];
							unset($items['taxname']);
							$items['item_tax_name'] = json_encode($items['item_tax_name']);
						}
						if (empty($items['saved_items_id'])) {
							$items['saved_items_id'] = 0;
						}
						if (!empty($qty_calculation) && $qty_calculation == 'Yes') {
							if (!empty($data['warehouse_id']) && !empty($items['saved_items_id']) && is_numeric($items['saved_items_id'])) {
								if (!$this->invoice_model->reduce_items($items['saved_items_id'], $items['quantity'], $data['warehouse_id'])) {
									$stock_ok = false;
									break;
								}
							}
						}
						$price = $items['quantity'] * $items['unit_cost'];
						$items['item_tax_total'] = ($price / 100 * $tax);
						$items['total_cost'] = $price;
						// get all client
						$this->invoice_model->_table_name = 'tbl_items';
						$this->invoice_model->_primary_key = 'items_id';
						$this->invoice_model->save($items);
						if (!empty($items['items_id'])) {
							$items_id = $items['items_id'];
							if (!empty($qty_calculation) && $qty_calculation == 'Yes') {
								if (!$this->check_existing_qty($items_id, $items['quantity'], $data['warehouse_id'])) {
									$stock_ok = false;
									break;
								}
							}
						}
						$index++;
					}
				}
				if (!$stock_ok || $this->db->trans_status() === FALSE) {
					$this->db->trans_rollback();
					set_message('error', $stock_error);
					redirect($_SERVER['HTTP_REFERER']);
				}
				if (!empty($data['user_id'])) {
					$notifiedUsers = array($data['user_id']);
					foreach ($notifiedUsers as $users) {
						if ($users != $this->session->userdata('user_id')) {
							$r = true;
							add_notification(array(
								'to_user_id' => $users,
								'description' => 'project_to_invoice_generated',
								'icon' => 'shopping-cart',
								'link' => 'admin/invoice/manage_invoice/invoice_details/' . $invoice_id,
								'value' => lang('project') . ': ' . $project_info->project_name . ' ' . lang('invoice') . ': ' . $data['reference_no'],
							));
						}
					}
					if (!empty($r)) {
						show_notification($notifiedUsers);
					}
				}

				$task_id = $this->input->post('task_id', true);
				if (!empty($task_id)) {
					foreach ($task_id as $task) {
						$tdata['task_progress'] = 100;
						$tdata['task_status'] = 'completed';
						update('tbl_task', array('task_id' => $task), $tdata);
					}
				}
				// send notification to client

				if (!empty($project_info->client_id)) {
					$client_info = $this->project_model->check_by(array('client_id' => $project_info->client_id), 'tbl_client');
					if (!empty($client_info->primary_contact)) {
						$notifyUser = array($client_info->primary_contact);
					}
				} else {
					$user_info = $this->project_model->check_by(array('company' => $project_info->client_id), 'tbl_account_details');
					if (!empty($user_info)) {
						$notifyUser = array($user_info->user_id);
					}
				}
				if (!empty($notifyUser)) {
					foreach ($notifyUser as $v_user) {
						if ($v_user != $this->session->userdata('user_id')) {
							add_notification(array(
								'to_user_id' => $v_user,
								'icon' => 'shopping-cart',
								'description' => 'not_invoice_created',
								'link' => 'client/invoice/manage_invoice/invoice_details/' . $invoice_id,
								'value' => $data['reference_no'],
							));
						}
					}
					show_notification($notifyUser);
				}

				$activity = array(
					'user' => $this->session->userdata('user_id'),
					'module' => 'invoice',
					'module_field_id' => $invoice_id,
					'activity' => 'activity_project_invoice_generated',
					'icon' => 'fa-shopping-cart',
					'link' => 'admin/invoice/manage_invoice/invoice_details/' . $invoice_id,
					'value1' => lang('project') . ': ' . $project_info->project_name . lang('invoice') . ' ' . ': ' . $data['reference_no'],
				);
				$this->project_model->_table_name = 'tbl_activities';
				$this->project_model->_primary_key = 'activities_id';
				$this->project_model->save($activity);

				$transactions_id = $this->input->post('transactions_id', true);
				if (!empty($transactions_id)) {
					if (!finance_guard_accounting_period($data['invoice_date'], lang('project') . ' ' . lang('invoice'))) {
						$this->db->trans_rollback();
						set_message('error', lang('accounting_period_closed'));
						redirect('admin/invoice/manage_invoice/invoice_details/' . $invoice_id);
						return;
					}
					$tr_data['invoices_id'] = $invoice_id;
				$this->invoice_model->_table_name = "tbl_transactions"; //table name
				$this->invoice_model->_primary_key = "transactions_id";
				$this->invoice_model->save($tr_data, $transactions_id);
				finance_sync_model()->sync_transaction_by_id($transactions_id);
			}
			}
			$this->db->trans_commit();
			$type = "success";
			$message = lang('project_invoice_generated');
			set_message($type, $message);
			redirect('admin/invoice/manage_invoice/invoice_details/' . $invoice_id);
		} else {
			if (empty($_SERVER['HTTP_REFERER'])) {
				redirect('admin/projects');
			} else {
				redirect($_SERVER['HTTP_REFERER']);
			}
		}
	}


	function check_existing_qty($items_id, $qty, $warehouseId)
	{
		$items_info = $this->db->where('items_id', $items_id)->get('tbl_items')->row();
		if ($items_info->quantity != $qty) {
			if ($qty > $items_info->quantity) {
				$reduce_qty = $qty - $items_info->quantity;
				if (!empty($warehouseId) && !empty($items_info->saved_items_id) && is_numeric($items_info->saved_items_id)) {
					if (!$this->invoice_model->reduce_items($items_info->saved_items_id, $reduce_qty, $warehouseId)) {
						return false;
					}
				}
			}
			if ($qty < $items_info->quantity) {
				$return_qty = $items_info->quantity - $qty;
				if (!empty($warehouseId) && !empty($items_info->saved_items_id) && is_numeric($items_info->saved_items_id)) {
					if (!$this->invoice_model->return_items($items_info->saved_items_id, $return_qty, $warehouseId)) {
						return false;
					}
				}
			}
		}
		return true;
	}

	public function add_item($id = null)
	{
		$data = $this->project_model->array_from_post(array('invoices_id', 'item_order'));
		$quantity = $this->input->post('quantity', TRUE);
		$array_data = $this->project_model->array_from_post(array('item_name', 'item_desc', 'item_tax_rate', 'unit_cost'));
		if (!empty($quantity)) {
			foreach ($quantity as $key => $value) {
				$data['quantity'] = $value;
				$data['item_name'] = $array_data['item_name'][$key];
				$data['item_desc'] = $array_data['item_desc'][$key];
				$data['unit_cost'] = $array_data['unit_cost'][$key];
				$data['item_tax_rate'] = $array_data['item_tax_rate'][$key];
				$sub_total = $data['unit_cost'] * $data['quantity'];

				$data['item_tax_total'] = ($data['item_tax_rate'] / 100) * $sub_total;
				$data['total_cost'] = $sub_total + $data['item_tax_total'];

				// get all client
				$this->project_model->_table_name = 'tbl_items';
				$this->project_model->_primary_key = 'items_id';
				if (!empty($id)) {
					$items_id = $id;
					$this->project_model->save($data, $id);
					$action = lang('activity_invoice_items_updated');
					$msg = lang('invoice_item_updated');
				} else {
					$items_id = $this->project_model->save($data);
					$action = lang('activity_invoice_items_added');
					$msg = lang('invoice_item_added');
				}
				$activity = array(
					'user' => $this->session->userdata('user_id'),
					'module' => 'invoice',
					'module_field_id' => $items_id,
					'activity' => $action,
					'icon' => 'fa-circle-o',
					'value1' => $data['item_name']
				);
				$this->project_model->_table_name = 'tbl_activities';
				$this->project_model->_primary_key = 'activities_id';
				$this->project_model->save($activity);
			}
		}
		$type = "success";
		$message = $msg;
		set_message($type, $message);
		redirect('admin/invoice/manage_invoice/invoice_details/' . $data['invoices_id']);
	}

	function get_recuring_frequency($invoices_id, $recur_data)
	{
		$recur_days = $this->get_calculate_recurring_days($recur_data['recuring_frequency']);
		$due_date = $this->project_model->get_table_field('tbl_invoices', array('invoices_id' => $invoices_id), 'due_date');

		$next_date = date("Y-m-d", safe_strtotime($due_date . "+ " . $recur_days . " days"));

		if ($recur_data['recur_end_date'] == '') {
			$recur_end_date = '0000-00-00';
		} else {
			$recur_end_date = date('Y-m-d', safe_strtotime($recur_data['recur_end_date']));
		}
		$update_invoice = array(
			'recurring' => 'Yes',
			'recuring_frequency' => $recur_days,
			'recur_frequency' => $recur_data['recuring_frequency'],
			'recur_start_date' => date('Y-m-d', safe_strtotime($recur_data['recur_start_date'])),
			'recur_end_date' => $recur_end_date,
			'recur_next_date' => $next_date
		);
		$this->project_model->_table_name = 'tbl_invoices';
		$this->project_model->_primary_key = 'invoices_id';
		$this->project_model->save($update_invoice, $invoices_id);
		return TRUE;
	}

	function get_calculate_recurring_days($recuring_frequency)
	{
		switch ($recuring_frequency) {
			case '7D':
				return 7;
				break;
			case '1M':
				return 31;
				break;
			case '3M':
				return 90;
				break;
			case '6M':
				return 182;
				break;
			case '1Y':
				return 365;
				break;
		}
	}

	public function project_details($id, $action = NULL, $op_id = NULL)
	{
		$data['title'] = lang('project_details');
		$data['dropzone'] = true;
		$data['project_details'] = $this->project_model->get_project($id);
		if (empty($data['project_details'])) {
			set_message('error', lang('no_record_found'));
			redirect('admin/projects');
		}
		if (empty($action)) {
			$data['active'] = 'project_details';
		} else if (!is_numeric($action)) {
			$data['active'] = $action;
		} else {
			$legacy_tabs = array(
				'3' => 'comments',
				'4' => 'attachments',
				'5' => 'milestones',
				'6' => 'tasks',
				'7' => 'bugs',
				'8' => 'gantt',
				'10' => 'expense',
			);
			$data['active'] = isset($legacy_tabs[(string) $action]) ? $legacy_tabs[(string) $action] : 'project_details';
		}
		$data['id'] = $id;
		$data['name'] = $data['project_details']->project_name;
		$data['module'] = 'projects';
		$data['perm'] = '57';
		$data['redirect'] = 'projects/project_details';
		$data['table'] = 'tbl_project';
		$data['project_participants'] = $this->project_model->get_project_participants($data['project_details']->permission);
		$data['project_timer_on'] = timer_status('projects', $data['project_details']->project_id, 'on');
		if (!empty($data['project_details']->client_id)) {
			$data['project_currency'] = $this->project_model->client_currency_symbol($data['project_details']->client_id);
		} else {
			$data['project_currency'] = $this->db->where('code', config_item('default_currency'))->get('tbl_currencies')->row();
		}
		$project_details_style = config_item('project_details_style');
		if (empty($project_details_style)) {
			$project_details_style = 'style_one';
		}
		if (is_numeric($project_details_style)) {
			$style_map = array('1' => 'style_one', '2' => 'style_two', '3' => 'style_three');
			$project_details_style = isset($style_map[$project_details_style]) ? $style_map[$project_details_style] : 'style_one';
		}
		$data['project_details_style'] = $project_details_style;
		$data['page_title'] = $data['project_details']->project_name;
		$project_code = !empty($data['project_details']->project_no) ? $data['project_details']->project_no : ('#' . $id);
		$project_client = !empty($data['project_details']->client_name) ? $data['project_details']->client_name : lang('undefined_client');
		$project_category = !empty($data['project_details']->category_name) ? $data['project_details']->category_name : lang('uncategorized');
		$data['page_description'] = $project_client . ' . ' . $project_category . ' . ' . display_date($data['project_details']->start_date) . ' -> ' . display_date($data['project_details']->end_date);
		$data['header_badge'] = array(
			'label' => $project_code,
			'tone' => $data['project_details']->project_status === 'completed' ? 'success' : 'primary',
		);
		$can_edit = $this->project_model->can_action('tbl_project', 'edit', array('project_id' => $data['project_details']->project_id));
		$edited = can_action('57', 'edited');
		$deleted = can_action('57', 'deleted');
		$data['header_actions'] = array();
		if (!empty($can_edit) && !empty($edited)) {
			$data['header_actions'][] = array(
				'label' => lang('invoice'),
				'icon' => 'receipt',
				'style' => 'primary',
				'attrs' => array(
					'data-modal-url' => base_url('admin/projects/invoice/' . $data['project_details']->project_id),
					'data-modal-title' => lang('invoice'),
					'data-modal-size' => 'lg',
				),
			);
		}
		if (timer_status('projects', $data['project_details']->project_id, 'on')) {
			$data['header_actions'][] = array(
				'label' => lang('stop_timer'),
				'icon' => 'square',
				'href' => base_url('admin/projects/tasks_timer/off/' . $data['project_details']->project_id),
				'style' => 'danger',
			);
		} else {
			$data['header_actions'][] = array(
				'label' => lang('start_timer'),
				'icon' => 'clock-3',
				'href' => base_url('admin/projects/tasks_timer/on/' . $data['project_details']->project_id),
				'style' => 'success',
			);
		}
		if (!empty($can_edit) && !empty($edited)) {
			$data['header_actions'][] = array(
				'label' => lang('edit'),
				'icon' => 'pencil',
				'href' => base_url('admin/projects/create/' . $data['project_details']->project_id),
				'style' => 'info',
			);
		}
		if (!empty($can_edit) && !empty($deleted)) {
			$data['header_actions'][] = array(
				'label' => lang('delete'),
				'icon' => 'trash-2',
				'href' => base_url('admin/projects/delete_project/' . $data['project_details']->project_id),
				'style' => 'danger',
				'attrs' => array(
					'onclick' => "return confirm('" . lang('delete_alert') . "');",
				),
			);
		}
		$data['header_filters'] = array(
			array(
				'label' => lang('more_actions'),
				'icon' => 'ellipsis',
				'active' => true,
				'items' => array_merge(
					array(
						array(
							'label' => $can_edit && !empty($edited) ? lang('clone_project') : lang('export_report'),
							'icon' => $can_edit && !empty($edited) ? 'copy' : 'file-text',
							'attrs' => $can_edit && !empty($edited) ? array(
								'data-modal-url' => base_url('admin/projects/clone_project/' . $data['project_details']->project_id),
								'data-modal-title' => lang('clone_project'),
								'data-modal-size' => 'lg',
							) : array(),
							'href' => $can_edit && !empty($edited) ? '' : base_url('admin/projects/export_project/' . $data['project_details']->project_id),
						),
						array(
							'label' => lang('export_report'),
							'icon' => 'file-text',
							'href' => base_url('admin/projects/export_project/' . $data['project_details']->project_id),
						),
						array(
							'label' => $this->session->userdata('user_id') && $data['project_details']->project_id ? $this->lang->line('pin') ?: 'Pin' : 'Pin',
							'icon' => 'pin',
							'href' => base_url('admin/projects/' . (!empty($this->project_model->check_by(array('user_id' => $this->session->userdata('user_id'), 'module_id' => $data['project_details']->project_id, 'module_name' => 'project'), 'tbl_pinaction')) ? 'remove_todo/' . $this->project_model->check_by(array('user_id' => $this->session->userdata('user_id'), 'module_id' => $data['project_details']->project_id, 'module_name' => 'project'), 'tbl_pinaction')->pinaction_id : 'add_todo_list/project/' . $data['project_details']->project_id)),
							'divider_before' => true,
						),
					),
					array_map(function ($status) use ($data) {
						return array(
							'label' => lang('mark_as_' . $status),
							'icon' => 'check-circle',
							'href' => base_url('admin/projects/change_status/' . $data['project_details']->project_id . '/' . $status),
						);
					}, array('started', 'in_progress', 'on_hold', 'completed', 'cancel'))
				),
			),
		);
		$data['project_overview'] = ($data['active'] === 'project_details')
			? $this->project_model->get_project_overview($data['project_details'])
			: array();
		$data['project_tab_counts'] = $this->project_model->get_project_tab_counts($id);
		$data['project_finance_summary'] = $this->finance_report_model->get_project_expense_summary($data['project_details']->project_id);
		$data['project_billed_expense_total'] = $this->finance_report_model->get_project_billed_expense_total($data['project_details']->project_id);
		$data['project_invoice_summary'] = $this->finance_report_model->get_project_invoice_summary($data['project_details']->project_id, $data['project_details']->client_id);
		$data['project_milestones_data'] = ($data['active'] === 'milestones')
			? $this->project_model->get_project_milestones_data($data['project_details'])
			: array();
		$data['project_gantt_data'] = ($data['active'] === 'gantt')
			? $this->project_model->get_project_gantt_data($data['project_details'])
			: array();
		$data['project_calendar_events'] = ($data['active'] === 'calender')
			? $this->project_model->get_project_calendar_events($data['project_details'])
			: array();
		$data['project_tickets_info'] = ($data['active'] === 'tickets')
			? $this->project_model->get_project_tickets_data($id)
			: array();
		$data['project_bugs_info'] = ($data['active'] === 'bugs')
			? $this->project_model->get_project_bugs_data($id)
			: array();
		$data['project_invoice_data'] = ($data['active'] === 'invoice')
			? $this->get_project_invoice_data($data['project_details'])
			: array();
		$expense_filter_type = ($data['active'] === 'expense') ? $this->uri->segment(6) : null;
		$expense_category_id = ($data['active'] === 'expense') ? $this->uri->segment(7) : null;
		$data['expense_filter_type'] = $expense_filter_type;
		$data['expense_category_id'] = $expense_category_id;
		$data['project_expense_data'] = ($data['active'] === 'expense')
			? $this->project_model->get_project_expense_data($data['project_details'], $expense_filter_type, $expense_category_id)
			: array();

		// $data['project_details_style'] = 'style_two';
		$data['all_tabs'] = projects_details_tabs($id, '5', $data['active'], $data['project_tab_counts']);
		$data['subview'] = $this->load->view('admin/projects/project_details', $data, TRUE);
		$this->load->view('admin/_layout_main', $data);
	}

	private function get_project_invoice_data($project_details)
	{
		$project_id = !empty($project_details->project_id) ? (int) $project_details->project_id : 0;
		if (empty($project_id)) {
			return array();
		}
		return $this->finance_report_model->get_project_invoice_summary($project_id, $project_details->client_id);
	}

	public function new_timesheet($projId = null, $id = null)
	{
		$data['title'] = lang('timesheet'); //Page title
		if (!empty($id)) {
			$edited = can_action('100', 'edited');
			if (!empty($edited)) {
				$data['project_timer_info'] = $this->db->where('tasks_timer_id', $id)->get('tbl_tasks_timer')->row();
			}
			if (empty($data['project_timer_info'])) {
				$type = "error";
				$message = lang("no_record_found");
				set_message($type, $message);
				redirect('admin/projects/project_details/' . $projId);
			}
		}
		$data['projId'] = $projId;

		$this->load->view('admin/projects/project_details/create_timesheet', $data, FALSE);
	}

	public
	function update_project_timer($id = NULL, $action = NULL)
	{
		if (!empty($action)) {
			$t_data['project_id'] = $this->db->where(array('tasks_timer_id' => $id))->get('tbl_tasks_timer')->row()->project_id;
			$activity = 'activity_delete_tasks_timesheet';
			$msg = lang('delete_timesheet');
		} else {
			$activity = ('activity_update_task_timesheet');
			$msg = lang('timer_update');
		}
		if ($action != 'delete_task_timmer') {
			$t_data = $this->project_model->array_from_post(array('project_id', 'start_datetime', 'end_datetime', 'start_date', 'start_time', 'end_date', 'end_time'));
			$start_datetime = !empty($t_data['start_datetime'])
				? $t_data['start_datetime']
				: ((!empty($t_data['start_date']) ? $t_data['start_date'] : date('Y-m-d')) . ' ' . (!empty($t_data['start_time']) ? $t_data['start_time'] : date('H:i')));
			$end_datetime = !empty($t_data['end_datetime'])
				? $t_data['end_datetime']
				: ((!empty($t_data['end_date']) ? $t_data['end_date'] : date('Y-m-d')) . ' ' . (!empty($t_data['end_time']) ? $t_data['end_time'] : date('H:i')));

			$data['start_time'] = safe_strtotime($start_datetime);
			$data['end_time'] = safe_strtotime($end_datetime);

			$data['reason'] = $this->input->post('reason', TRUE);
			$data['edited_by'] = $this->session->userdata('user_id');

			$data['project_id'] = $t_data['project_id'];
			$data['user_id'] = $this->session->userdata('user_id');

			$this->project_model->_table_name = "tbl_tasks_timer"; //table name
			$this->project_model->_primary_key = "tasks_timer_id";
			if (!empty($id)) {
				$id = $this->project_model->save($data, $id);
			} else {
				$existing_timer = $this->db
					->where(array(
						'project_id' => $data['project_id'],
						'user_id' => $data['user_id'],
						'start_time' => $data['start_time'],
						'end_time' => $data['end_time'],
					))
					->order_by('tasks_timer_id', 'DESC')
					->get('tbl_tasks_timer')
					->row();
				if (!empty($existing_timer)) {
					$id = $existing_timer->tasks_timer_id;
				} else {
					$id = $this->project_model->save($data);
				}
			}
			$task_start = $this->project_model->check_by(array('project_id' => $data['project_id']), 'tbl_project');
			$estimate_hours = $task_start->estimate_hours;

			$percentage = $this->project_model->get_estime_time($estimate_hours);
			$logged_hour = $this->project_model->calculate_project('project_hours', $task_start->project_id);
			if ($percentage != 0) {
				$progress = round(($logged_hour / $percentage) * 100);
				if ($progress > 100) {
					$progress = 100;
				}
				$p_data = array(
					'progress' => $progress,
				);
				$this->project_model->_table_name = "tbl_project"; //table name
				$this->project_model->_primary_key = "project_id";
				$this->project_model->save($p_data, $data['project_id']);
			}
		} else {
			$this->project_model->set_progress($t_data['project_id']);

			$project_info = $this->project_model->check_by(array('project_id' => $t_data['project_id']), 'tbl_project');

			$notifiedUsers = array();
			if (!empty($project_info->permission) && $project_info->permission != 'all') {
				$permissionUsers = json_decode($project_info->permission);
				foreach ($permissionUsers as $user => $v_permission) {
					array_push($notifiedUsers, $user);
				}
			} else {
				$notifiedUsers = $this->project_model->allowed_user_id('57');
			}
			if (!empty($notifiedUsers)) {
				foreach ($notifiedUsers as $users) {
					if ($users != $this->session->userdata('user_id')) {
						add_notification(array(
							'to_user_id' => $users,
							'from_user_id' => true,
							'description' => 'not_update_timer',
							'link' => 'admin/projects/project_details/' . $t_data['project_id'] . '/timesheet',
							'value' => lang('project') . ' ' . $project_info->project_name,
						));
					}
				}
			}
			show_notification($notifiedUsers);
			// save into activities
			$activities = array(
				'user' => $this->session->userdata('user_id'),
				'module' => 'projects',
				'module_field_id' => $id,
				'activity' => $activity,
				'icon' => 'fa-folder-open-o',
				'link' => 'admin/projects/project_details/' . $t_data['project_id'] . '/timesheet',
				'value1' => $project_info->project_name,
			);
			$this->project_model->_table_name = "tbl_activities"; //table name
			$this->project_model->_primary_key = "activities_id";
			$this->project_model->save($activities);

			$this->project_model->_table_name = "tbl_tasks_timer"; //table name
			$this->project_model->_primary_key = "tasks_timer_id";
			$this->project_model->delete($id);
		}
		$project_id = !empty($t_data['project_id']) ? (int) $t_data['project_id'] : 0;
		$patch = $this->project_timesheet_patch($project_id);
		if ($action == 'delete_task_timmer') {
			echo json_encode(array("status" => 'success', 'message' => $msg, 'patch' => $patch));
			exit();
		} else {
			$type = "success";
			$message = $msg;
			set_message($type, $message);
			echo json_encode(array("status" => 'success', 'message' => $msg, 'patch' => $patch));
			exit();
			// redirect('admin/projects/project_details/' . $t_data['project_id'] . '/timesheet');
		}
	}

	private function project_timesheet_patch($project_id)
	{
		$project_id = (int) $project_id;
		if (empty($project_id)) {
			return array();
		}
		$project_details = $this->project_model->check_by(array('project_id' => $project_id), 'tbl_project');
		if (empty($project_details)) {
			return array();
		}
		return array(array(
			'selector' => '[data-project-timesheet-panel="' . $project_id . '"]',
			'mode' => 'replace',
			'html' => $this->load->view('admin/projects/project_details/timesheet', array(
				'project_details' => $project_details,
			), true),
		));
	}

	public function update_users($id)
	{
		$edited = can_action('57', 'edited');
		$can_edit = $this->project_model->can_action('tbl_project', 'edit', array('project_id' => $id));
		if (!empty($can_edit) && !empty($edited)) {
			// get all assign_user
			$data['assign_user'] = $this->project_model->allowed_user('57');
			$data['project_info'] = $this->project_model->check_by(array('project_id' => $id), 'tbl_project');
			if ($this->input->is_ajax_request()) {
				echo $this->load->view('admin/projects/_modal_users', $data, TRUE);
				return;
			}
		} else {
			set_message('error', lang('there_in_no_value'));
			if (empty($_SERVER['HTTP_REFERER'])) {
				redirect('admin/projects');
			} else {
				redirect($_SERVER['HTTP_REFERER']);
			}
		}
	}

	public function update_member($id)
	{
		$edited = can_action('57', 'edited');
		$can_edit = $this->project_model->can_action('tbl_project', 'edit', array('project_id' => $id));
		if (!empty($can_edit) && !empty($edited)) {
			$project_info = $this->project_model->check_by(array('project_id' => $id), 'tbl_project');

			$data['permission'] = permission_post();
			if ($data['permission'] == 'all') {
				$assigned_to['assigned_to'] = $this->project_model->allowed_user_id('57');
			}
			//save data into table.
			$this->project_model->_table_name = "tbl_project"; // table name
			$this->project_model->_primary_key = "project_id"; // $id
			$this->project_model->save($data, $id);

			$msg = lang('update_project');
			$activity = 'activity_update_project';
			$projects_email = config_item('projects_email');
			if (!empty($projects_email) && $projects_email == 1) {
				if (!empty($assigned_to['assigned_to'])) {
					$this->send_project_notify_assign_user($id, $assigned_to['assigned_to']);
				}
			}

			// save into activities
			$activities = array(
				'user' => $this->session->userdata('user_id'),
				'module' => 'projects',
				'module_field_id' => $id,
				'activity' => $activity,
				'icon' => 'fa-folder-open-o',
				'link' => 'admin/projects/project_details/' . $id,
				'value1' => $project_info->project_name,
			);
			// Update into tbl_project
			$this->project_model->_table_name = "tbl_activities"; //table name
			$this->project_model->_primary_key = "activities_id";
			$this->project_model->save($activities);

			$type = "success";
			$message = $msg;
			set_message($type, $message);
		} else {
			$type = 'error';
			$message = lang('there_in_no_value');
			set_message('error', $message);
		}
		if ($this->input->is_ajax_request()) {
			$status = ($type === 'success') ? 'success' : 'error';
			$updated_project = $status === 'success' ? $this->project_model->check_by(array('project_id' => $id), 'tbl_project') : null;
			echo json_encode(array(
				'status' => $status,
				'message' => $message,
				'project_id' => (int) $id,
				'assigned_html' => !empty($updated_project) ? $this->render_project_assigned_html($updated_project) : '',
			));
			exit();
		}
		if (empty($_SERVER['HTTP_REFERER'])) {
			redirect('admin/projects');
		} else {
			redirect($_SERVER['HTTP_REFERER']);
		}
	}

	public function change_status($project_id, $status)
	{
		$edited = can_action('57', 'edited');
		$can_edit = $this->project_model->can_action('tbl_project', 'edit', array('project_id' => $project_id));

		if (!empty($can_edit) && !empty($edited)) {
			$project_info = $this->project_model->check_by(array('project_id' => $project_id), 'tbl_project');
			$notifiedUsers = array();
			if (!empty($project_info->permission) && $project_info->permission != 'all') {
				$permissionUsers = json_decode($project_info->permission);
				foreach ($permissionUsers as $user => $v_permission) {
					array_push($notifiedUsers, $user);
				}
			} else {
				$notifiedUsers = $this->project_model->allowed_user_id('57');
			}
			if (!empty($notifiedUsers)) {
				foreach ($notifiedUsers as $users) {
					if ($users != $this->session->userdata('user_id')) {
						add_notification(array(
							'to_user_id' => $users,
							'from_user_id' => true,
							'description' => 'not_changed_status',
							'link' => 'admin/projects/project_details/' . $project_id,
							'value' => lang('status') . ' : ' . lang($project_info->project_status) . ' to ' . lang($status),
						));
					}
				}
			}
			show_notification($notifiedUsers);


			$client_info = $this->project_model->check_by(array('client_id' => $project_info->client_id), 'tbl_client');
			if (!empty($client_info->primary_contact)) {
				$notifyUser = array($client_info->primary_contact);
			} else {
				$user_info = $this->project_model->check_by(array('company' => $project_info->client_id), 'tbl_account_details');
				if (!empty($user_info)) {
					$notifyUser = array($user_info->user_id);
				}
			}
			if (!empty($notifyUser)) {
				foreach ($notifyUser as $v_user) {
					if ($v_user != $this->session->userdata('user_id')) {
						add_notification(array(
							'to_user_id' => $v_user,
							'from_user_id' => true,
							'description' => 'not_changed_status',
							'link' => 'client/projects/project_details/' . $project_id,
							'value' => lang('status') . ' : ' . lang($project_info->project_status) . ' to ' . lang($status),
						));
					}
				}
				show_notification($notifyUser);
			}

			$data['project_status'] = $status;
			if ($data['project_status'] == 'completed') {
				$data['progress'] = 100;
				$this->tasks_timer('off', $project_id, true);
			}
			if (!empty($data['progress']) && $data['progress'] == 100) {
				$data['project_status'] = 'completed';
			}
			$this->project_model->_table_name = 'tbl_project';
			$this->project_model->_primary_key = 'project_id';
			$this->project_model->save($data, $project_id);
			// messages for user
			$type = "success";
			$message = lang('change_status');
			set_message($type, $message);
		}
		if (empty($_SERVER['HTTP_REFERER'])) {
			redirect('admin/projects');
		} else {
			redirect($_SERVER['HTTP_REFERER']);
		}
	}

	public function save_comments()
	{
		$data['project_id'] = $this->input->post('project_id');
		$data['comment'] = $this->input->post('description');

		$files = $this->input->post("files", true);
		$target_path = getcwd() . "/uploads/";
		//process the fiiles which has been uploaded by dropzone
		if (!empty($files) && is_array($files)) {
			foreach ($files as $key => $file) {
				if (!empty($file)) {
					$file_name = $this->input->post('file_name_' . $file, true);
					$new_file_name = move_temp_file($file_name, $target_path);
					$file_ext = explode(".", $new_file_name);
					$is_image = check_image_extension($new_file_name);
					$size = $this->input->post('file_size_' . $file, true) / 1000;
					if ($new_file_name) {
						$up_data[] = array(
							"fileName" => $new_file_name,
							"path" => "uploads/" . $new_file_name,
							"fullPath" => getcwd() . "/uploads/" . $new_file_name,
							"ext" => '.' . end($file_ext),
							"size" => round($size, 2),
							"is_image" => $is_image,
						);
						$success = true;
					} else {
						$success = false;
					}
				}
			}
		}
		//process the files which has been submitted manually
		if ($_FILES) {
			$files = $_FILES['manualFiles'];
			if ($files && count(array($files)) > 0) {
				$comment = $this->input->post('comment', true);
				foreach ($files["tmp_name"] as $key => $file) {
					$temp_file = $file;
					$file_name = $files["name"][$key];
					$file_size = $files["size"][$key];
					$new_file_name = move_temp_file($file_name, $target_path, "", $temp_file);
					if ($new_file_name) {
						$file_ext = explode(".", $new_file_name);
						$is_image = check_image_extension($new_file_name);
						$up_data[] = array(
							"fileName" => $new_file_name,
							"path" => "uploads/" . $new_file_name,
							"fullPath" => getcwd() . "/uploads/" . $new_file_name,
							"ext" => '.' . end($file_ext),
							"size" => round($file_size, 2),
							"is_image" => $is_image,
						);
					}
				}
			}
		}
		if (!empty($up_data)) {
			$data['comments_attachment'] = json_encode($up_data);
		}
		$data['user_id'] = $this->session->userdata('user_id');

		//save data into table.
		$this->project_model->_table_name = "tbl_task_comment"; // table name
		$this->project_model->_primary_key = "task_comment_id"; // $id
		$comment_id = $this->project_model->save($data);
		if (!empty($comment_id)) {
			$project_info = $this->project_model->check_by(array('project_id' => $data['project_id']), 'tbl_project');
			$notifiedUsers = array();
			if (!empty($project_info->permission) && $project_info->permission != 'all') {
				$permissionUsers = json_decode($project_info->permission);
				foreach ($permissionUsers as $user => $v_permission) {
					array_push($notifiedUsers, $user);
				}
			} else {
				$notifiedUsers = $this->project_model->allowed_user_id('57');
			}
			if (!empty($notifiedUsers)) {
				foreach ($notifiedUsers as $users) {
					if ($users != $this->session->userdata('user_id')) {
						add_notification(array(
							'to_user_id' => $users,
							'from_user_id' => true,
							'description' => 'not_new_comment',
							'link' => 'admin/projects/project_details/' . $project_info->project_id . '/3',
							'value' => lang('project') . ' ' . $project_info->project_name,
						));
					}
				}
			}
			show_notification($notifiedUsers);

			// save into activities
			$activities = array(
				'user' => $this->session->userdata('user_id'),
				'module' => 'projects',
				'module_field_id' => $data['project_id'],
				'activity' => 'activity_new_project_comment',
				'icon' => 'fa-folder-open-o',
				'link' => 'admin/projects/project_details/' . $data['project_id'] . '/3',
				'value1' => $data['comment'],
			);
			// Update into tbl_project
			$this->project_model->_table_name = "tbl_activities"; //table name
			$this->project_model->_primary_key = "activities_id";
			$this->project_model->save($activities);

			// send notification
			$projects_email = config_item('projects_email');
			if (!empty($projects_email) && $projects_email == 1) {
				$this->notify_comments_project($comment_id);
			}
			$response_data = "";
			$view_data['comment_details'] = $this->db->where(array('task_comment_id' => $comment_id))->order_by('comment_datetime', 'DESC')->get('tbl_task_comment')->result();
			$response_data = $this->load->view("admin/projects/comments_list", $view_data, true);
			echo json_encode(array("status" => 'success', "data" => $response_data, 'message' => lang('project_comment_save')));
			exit();
			//            $type = "success";
			//            $message = lang('project_comment_save');
			//            set_message($type, $message);
		} else {
			echo json_encode(array("status" => 'error', 'message' => lang('error_occurred')));
			exit();
		}
	}

	public function save_attachment_comments()
	{
		$attachments_id = $this->input->post('attachments_id', true);
		if (!empty($attachments_id)) {
			$data['attachments_id'] = $attachments_id;
		} else {
			$data['uploaded_files_id'] = $this->input->post('uploaded_files_id', true);
		}
		$data['project_id'] = $this->input->post('project_id', true);
		$data['comment'] = $this->input->post('description', true);

		$files = $this->input->post("files", true);
		$target_path = getcwd() . "/uploads/";
		//process the fiiles which has been uploaded by dropzone
		if (!empty($files) && is_array($files)) {
			foreach ($files as $key => $file) {
				if (!empty($file)) {
					$file_name = $this->input->post('file_name_' . $file, true);
					$new_file_name = move_temp_file($file_name, $target_path);
					$file_ext = explode(".", $new_file_name);
					$is_image = check_image_extension($new_file_name);
					$size = $this->input->post('file_size_' . $file, true) / 1000;
					if ($new_file_name) {
						$up_data[] = array(
							"fileName" => $new_file_name,
							"path" => "uploads/" . $new_file_name,
							"fullPath" => getcwd() . "/uploads/" . $new_file_name,
							"ext" => '.' . end($file_ext),
							"size" => round($size, 2),
							"is_image" => $is_image,
						);
						$success = true;
					} else {
						$success = false;
					}
				}
			}
		}
		//process the files which has been submitted manually
		if ($_FILES) {
			$files = $_FILES['manualFiles'];
			if ($files && count(array($files)) > 0) {
				$comment = $this->input->post('comment', true);
				foreach ($files["tmp_name"] as $key => $file) {
					$temp_file = $file;
					$file_name = $files["name"][$key];
					$file_size = $files["size"][$key];
					$new_file_name = move_temp_file($file_name, $target_path, "", $temp_file);
					if ($new_file_name) {
						$file_ext = explode(".", $new_file_name);
						$is_image = check_image_extension($new_file_name);
						$up_data[] = array(
							"fileName" => $new_file_name,
							"path" => "uploads/" . $new_file_name,
							"fullPath" => getcwd() . "/uploads/" . $new_file_name,
							"ext" => '.' . end($file_ext),
							"size" => round($file_size, 2),
							"is_image" => $is_image,
						);
					}
				}
			}
		}
		if (!empty($up_data)) {
			$data['comments_attachment'] = json_encode($up_data);
		}
		$data['user_id'] = $this->session->userdata('user_id');

		//save data into table.
		$this->project_model->_table_name = "tbl_task_comment"; // table name
		$this->project_model->_primary_key = "task_comment_id"; // $id
		$comment_id = $this->project_model->save($data);
		if (!empty($comment_id)) {
			$project_info = $this->project_model->check_by(array('project_id' => $data['project_id']), 'tbl_project');
			$notifiedUsers = array();
			if (!empty($project_info->permission) && $project_info->permission != 'all') {
				$permissionUsers = json_decode($project_info->permission);
				foreach ($permissionUsers as $user => $v_permission) {
					array_push($notifiedUsers, $user);
				}
			} else {
				$notifiedUsers = $this->project_model->allowed_user_id('57');
			}
			if (!empty($notifiedUsers)) {
				foreach ($notifiedUsers as $users) {
					if ($users != $this->session->userdata('user_id')) {
						add_notification(array(
							'to_user_id' => $users,
							'from_user_id' => true,
							'description' => 'not_new_comment',
							'link' => 'admin/projects/project_details/' . $project_info->project_id . '/3',
							'value' => lang('project') . ' ' . $project_info->project_name,
						));
					}
				}
			}
			show_notification($notifiedUsers);

			// save into activities
			$activities = array(
				'user' => $this->session->userdata('user_id'),
				'module' => 'projects',
				'module_field_id' => $data['project_id'],
				'activity' => 'activity_new_project_comment',
				'icon' => 'fa-folder-open-o',
				'link' => 'admin/projects/project_details/' . $data['project_id'] . '/3',
				'value1' => $data['comment'],
			);
			// Update into tbl_project
			$this->project_model->_table_name = "tbl_activities"; //table name
			$this->project_model->_primary_key = "activities_id";
			$this->project_model->save($activities);

			// send notification
			$projects_email = config_item('projects_email');
			if (!empty($projects_email) && $projects_email == 1) {
				$this->notify_comments_project($comment_id, true);
			}
			$response_data = "";
			$view_data['comment_details'] = $this->db->where(array('task_comment_id' => $comment_id))->order_by('comment_datetime', 'DESC')->get('tbl_task_comment')->result();
			$response_data = $this->load->view("admin/projects/comments_list", $view_data, true);
			echo json_encode(array("status" => 'success', "data" => $response_data, 'message' => lang('projects_comment_save')));
			exit();
			//            $type = "success";
			//            $message = lang('project_comment_save');
			//            set_message($type, $message);
		} else {
			echo json_encode(array("status" => 'error', 'message' => lang('error_occurred')));
			exit();
		}
	}

	public function save_comments_reply($task_comment_id)
	{
		$data['project_id'] = $this->input->post('project_id', TRUE);
		$data['comment'] = $this->input->post('reply_comments', TRUE);
		$data['user_id'] = $this->session->userdata('user_id');
		$data['comments_reply_id'] = $task_comment_id;
		//save data into table.
		$this->project_model->_table_name = "tbl_task_comment"; // table name
		$this->project_model->_primary_key = "task_comment_id"; // $id
		$comment_id = $this->project_model->save($data);
		if (!empty($comment_id)) {
			$comments_info = $this->project_model->check_by(array('task_comment_id' => $task_comment_id), 'tbl_task_comment');
			$user = $this->project_model->check_by(array('user_id' => $comments_info->user_id), 'tbl_users');
			if ($user->role_id == 2) {
				$url = 'client/';
			} else {
				$url = 'admin/';
			}
			$project_info = $this->project_model->check_by(array('project_id' => $data['project_id']), 'tbl_project');
			$notifiedUsers = array($comments_info->user_id);
			if (!empty($notifiedUsers)) {
				foreach ($notifiedUsers as $users) {
					if ($users != $this->session->userdata('user_id')) {
						add_notification(array(
							'to_user_id' => $users,
							'from_user_id' => true,
							'description' => 'not_comment_reply',
							'link' => $url . 'projects/project_details/' . $project_info->project_id . '/3',
							'value' => lang('project') . ' ' . $project_info->project_name,
						));
					}
				}
			}
			show_notification($notifiedUsers);

			// save into activities
			$activities = array(
				'user' => $this->session->userdata('user_id'),
				'module' => 'projects',
				'module_field_id' => $data['project_id'],
				'activity' => 'activity_new_comment_reply',
				'icon' => 'fa-folder-open-o',
				'link' => $url . 'projects/project_details/' . $data['project_id'] . '/3',
				'value1' => $this->db->where('task_comment_id', $task_comment_id)->get('tbl_task_comment')->row()->comment,
				'value2' => $data['comment'],
			);
			// Update into tbl_project
			$this->project_model->_table_name = "tbl_activities"; //table name
			$this->project_model->_primary_key = "activities_id";
			$this->project_model->save($activities);

			// send notification
			$projects_email = config_item('projects_email');
			if (!empty($projects_email) && $projects_email == 1) {
				$this->notify_comments_project($comment_id);
			}
			$response_data = "";
			$view_data['comment_reply_details'] = $this->db->where(array('task_comment_id' => $comment_id))->order_by('comment_datetime', 'ASC')->get('tbl_task_comment')->result();
			$response_data = $this->load->view("admin/projects/comments_reply", $view_data, true);
			echo json_encode(array("status" => 'success', "data" => $response_data, 'message' => lang('projects_comment_save')));
			exit();
			//
			//            $type = "success";
			//            $message = lang('project_comment_save');
			//            set_message($type, $message);
		} else {
			echo json_encode(array("status" => 'error', 'message' => lang('error_occurred')));
			exit();
		}
	}

	function notify_comments_project($comment_id, $attachment = null)
	{

		$comment_info = $this->project_model->check_by(array('task_comment_id' => $comment_id), 'tbl_task_comment');
		$project_info = $this->project_model->check_by(array('project_id' => $comment_info->project_id), 'tbl_project');
		$email_template = email_templates(array('email_group' => 'project_comments'), $project_info->client_id);
		$user = $this->project_model->check_by(array('user_id' => $comment_info->user_id), 'tbl_users');
		if ($user->role_id == 2) {
			$url = 'client/';
		} else {
			$url = 'admin/';
		}

		$message = $email_template->template_body;

		$subject = $email_template->subject;

		$projectName = str_replace("{PROJECT_NAME}", $project_info->project_name, $message);
		$assigned_by = str_replace("{POSTED_BY}", ucfirst($this->session->userdata('name')), $projectName);
		$Link = str_replace("{COMMENT_URL}", base_url() . $url . 'projects/project_details/' . $project_info->project_id . '/3', $assigned_by);
		$comments = str_replace("{COMMENT_MESSAGE}", $comment_info->comment, $Link);
		$message = str_replace("{SITE_NAME}", config_item('company_name'), $comments);

		$data['message'] = $message;
		$message = $this->load->view('email_template', $data, TRUE);

		$params['subject'] = $subject;
		$params['message'] = $message;
		$params['resourceed_file'] = '';

		if (!empty($project_info->permission) && $project_info->permission != 'all') {
			$user = json_decode($project_info->permission);
			foreach ($user as $key => $v_user) {
				$allowed_user[] = $key;
			}
		} else {
			$allowed_user = $this->project_model->allowed_user_id('57');
		}
		if (!empty($allowed_user)) {
			foreach ($allowed_user as $v_user) {
				$login_info = $this->project_model->check_by(array('user_id' => $v_user), 'tbl_users');
				$params['recipient'] = $login_info->email;
				$this->project_model->send_email($params);
			}
		}
	}

	public function delete_comments($task_comment_id)
	{
		$comments_info = $this->project_model->check_by(array('task_comment_id' => $task_comment_id), 'tbl_task_comment');
		if (empty($comments_info)) {
			$type = "error";
			$message = "No Record Found";
			echo json_encode(array("status" => $type, 'message' => $message));
			exit();
		}
		if (!empty($comments_info->comments_attachment)) {
			$attachment = json_decode($comments_info->comments_attachment);
			foreach ($attachment as $v_file) {
				remove_files($v_file->fileName);
			}
		}
		// save into activities
		$activities = array(
			'user' => $this->session->userdata('user_id'),
			'module' => 'projects',
			'module_field_id' => $comments_info->project_id,
			'activity' => 'activity_comment_deleted',
			'icon' => 'fa-folder-open-o',
			'link' => 'admin/projects/project_details/' . $comments_info->project_id . '/3',
			'value1' => $comments_info->comment,
		);
		// Update into tbl_project
		$this->project_model->_table_name = "tbl_activities"; //table name
		$this->project_model->_primary_key = "activities_id";
		$this->project_model->save($activities);


		$this->project_model->_table_name = "tbl_task_comment"; // table name
		$this->project_model->_primary_key = "task_comment_id"; // $id
		$this->project_model->delete($task_comment_id);

		//save data into table.
		$this->project_model->_table_name = "tbl_task_comment"; // table name
		$this->project_model->delete_multiple(array('comments_reply_id' => $task_comment_id));

		echo json_encode(array("status" => 'success', 'message' => lang('task_comment_deleted')));
		exit();
	}

	public function new_attachment($id)
	{
		$data['dropzone'] = true;
		$data['project_info'] = $this->project_model->check_by(array('project_id' => $id), 'tbl_project');
		$data['modal_subview'] = $this->load->view('admin/projects/new_attachment', $data, FALSE);
	}

	public function attachment_details($type, $id)
	{
		$data['type'] = $type;
		$data['attachment_info'] = $this->project_model->check_by(array('attachments_id' => $id), 'tbl_attachments');
		$data['modal_subview'] = $this->load->view('admin/projects/attachment_details', $data, FALSE);
	}

	public function save_attachment($attachments_id = NULL)
	{

		$data = $this->project_model->array_from_post(array('title', 'description', 'project_id'));
		$data['user_id'] = $this->session->userdata('user_id');

		// save and update into tbl_files
		$this->project_model->_table_name = "tbl_attachments"; //table name
		$this->project_model->_primary_key = "attachments_id";
		if (!empty($attachments_id)) {
			$id = $attachments_id;
			$this->project_model->save($data, $id);
			$msg = lang('project_file_updated');
		} else {
			$id = $this->project_model->save($data);
			$msg = lang('project_file_added');
		}
		$files = $this->input->post("files", true);

		$target_path = getcwd() . "/uploads/";
		//process the fiiles which has been uploaded by dropzone
		if (!empty($files) && is_array($files)) {
			foreach ($files as $key => $file) {
				if (!empty($file)) {
					$file_name = $this->input->post('file_name_' . $file, true);
					$new_file_name = move_temp_file($file_name, $target_path);
					$file_ext = explode(".", $new_file_name);
					$is_image = check_image_extension($new_file_name);

					if ($new_file_name) {
						$up_data = array(
							"files" => "uploads/" . $new_file_name,
							"uploaded_path" => getcwd() . "/uploads/" . $new_file_name,
							"file_name" => $new_file_name,
							"size" => $this->input->post('file_size_' . $file, true),
							"ext" => end($file_ext),
							"is_image" => $is_image,
							"image_width" => 0,
							"image_height" => 0,
							"attachments_id" => $id
						);
						$this->project_model->_table_name = "tbl_attachments_files"; // table name
						$this->project_model->_primary_key = "uploaded_files_id"; // $id
						$uploaded_files_id = $this->project_model->save($up_data);

						// saved into comments
						$comment = $this->input->post('comment_' . $file, true);
						$u_cdata = array(
							"comment" => $comment,
							"user_id" => $this->session->userdata('user_id'),
							"project_id" => $data['project_id'],
							"uploaded_files_id" => $uploaded_files_id,
						);
						$this->project_model->_table_name = "tbl_task_comment"; // table name
						$this->project_model->_primary_key = "task_comment_id"; // $id
						$this->project_model->save($u_cdata);
						$success = true;
					} else {
						$success = false;
					}
				}
			}
		}
		//process the files which has been submitted manually
		if ($_FILES) {
			$files = $_FILES['manualFiles'];
			if ($files && count(array($files)) > 0) {
				$comment = $this->input->post('comment', true);
				foreach ($files["tmp_name"] as $key => $file) {
					$temp_file = $file;
					$file_name = $files["name"][$key];
					$file_size = $files["size"][$key];
					$new_file_name = move_temp_file($file_name, $target_path, "", $temp_file);
					if ($new_file_name) {
						$file_ext = explode(".", $new_file_name);
						$is_image = check_image_extension($new_file_name);
						$up_data = array(
							"files" => "uploads/" . $new_file_name,
							"uploaded_path" => getcwd() . "/uploads/" . $new_file_name,
							"file_name" => $new_file_name,
							"size" => $file_size,
							"ext" => end($file_ext),
							"is_image" => $is_image,
							"image_width" => 0,
							"image_height" => 0,
							"attachments_id" => $id
						);
						$this->project_model->_table_name = "tbl_attachments_files"; // table name
						$this->project_model->_primary_key = "uploaded_files_id"; // $id
						$uploaded_files_id = $this->project_model->save($up_data);

						// saved into comments
						if (!empty($comment[$key])) {
							$u_cdata = array(
								"comment" => $comment[$key],
								"user_id" => $this->session->userdata('user_id'),
								"uploaded_files_id" => $uploaded_files_id,
							);
							$this->project_model->_table_name = "tbl_task_comment"; // table name
							$this->project_model->_primary_key = "task_comment_id"; // $id
							$this->project_model->save($u_cdata);
						}
					}
				}
			}
		}

		// save into activities
		$activities = array(
			'user' => $this->session->userdata('user_id'),
			'module' => 'projects',
			'module_field_id' => $data['project_id'],
			'activity' => 'activity_new_project_attachment',
			'icon' => 'fa-folder-open-o',
			'link' => 'admin/projects/project_details/' . $data['project_id'] . '/4',
			'value1' => $data['title'],
		);
		// Update into tbl_project
		$this->project_model->_table_name = "tbl_activities"; //table name
		$this->project_model->_primary_key = "activities_id";
		$this->project_model->save($activities);
		// send notification message
		$projects_email = config_item('projects_email');
		if (!empty($projects_email) && $projects_email == 1) {
			$this->notify_attchemnt_project($id);
		}
		// messages for user
		$type = "success";
		$message = $msg;
		set_message($type, $message);
		redirect('admin/projects/project_details/' . $data['project_id'] . '/' . '4');
	}

	function notify_attchemnt_project($attachments_id)
	{
		$comment_info = $this->project_model->check_by(array('attachments_id' => $attachments_id), 'tbl_attachments');
		$project_info = $this->project_model->check_by(array('project_id' => $comment_info->project_id), 'tbl_project');
		$email_template = email_templates(array('email_group' => 'project_attachment'), $project_info->client_id);

		$message = $email_template->template_body;

		$subject = $email_template->subject;
		$projectName = str_replace("{PROJECT_NAME}", $project_info->project_name, $message);
		$assigned_by = str_replace("{UPLOADED_BY}", ucfirst($this->session->userdata('name')), $projectName);
		$Link = str_replace("{PROJECT_URL}", base_url() . 'admin/projects/project_details/' . $comment_info->project_id . '/' . $data['active'] = 4, $assigned_by);
		$message = str_replace("{SITE_NAME}", config_item('company_name'), $Link);

		$data['message'] = $message;
		$message = $this->load->view('email_template', $data, TRUE);

		$params['subject'] = $subject;
		$params['message'] = $message;
		$params['resourceed_file'] = '';
		if (!empty($project_info->permission) && $project_info->permission != 'all') {
			$user = json_decode($project_info->permission);
			foreach ($user as $key => $v_user) {
				$allowed_user[] = $key;
			}
		} else {
			$allowed_user = $this->project_model->allowed_user_id('57');
		}
		if (!empty($allowed_user)) {
			foreach ($allowed_user as $v_user) {
				$login_info = $this->project_model->check_by(array('user_id' => $v_user), 'tbl_users');
				$params['recipient'] = $login_info->email;
				$this->project_model->send_email($params);

				if ($v_user != $this->session->userdata('user_id')) {
					add_notification(array(
						'to_user_id' => $v_user,
						'from_user_id' => true,
						'description' => 'not_uploaded_attachment',
						'link' => 'admin/projects/project_details/' . $project_info->project_id . '/4',
						'value' => lang('project') . ' ' . $project_info->project_name,
					));
				}
			}
			show_notification($allowed_user);
		}
	}

	public function delete_files($attachments_id)
	{
		$file_info = $this->project_model->check_by(array('attachments_id' => $attachments_id), 'tbl_attachments');
		if (empty($file_info)) {
			$type = "error";
			$message = "No Record Found";
			echo json_encode(array("status" => $type, 'message' => $message));
			exit();
		}
		// save into activities
		$activities = array(
			'user' => $this->session->userdata('user_id'),
			'module' => 'projects',
			'module_field_id' => $file_info->project_id,
			'activity' => 'activity_project_attachfile_deleted',
			'icon' => 'fa-folder-open-o',
			'link' => 'admin/projects/project_details/' . $file_info->project_id . '/4',
			'value1' => $file_info->title,
		);
		// Update into tbl_project
		$this->project_model->_table_name = "tbl_activities"; //table name
		$this->project_model->_primary_key = "activities_id";
		$this->project_model->save($activities);

		//save data into table.
		$this->project_model->_table_name = "tbl_attachments"; // table name
		$this->project_model->delete_multiple(array('attachments_id' => $attachments_id));

		$uploadFileinfo = $this->db->where('attachments_id', $attachments_id)->get('tbl_attachments_files')->result();
		if (!empty($uploadFileinfo)) {
			foreach ($uploadFileinfo as $Fileinfo) {
				remove_files($Fileinfo->file_name);
			}
		}
		//save data into table.
		$this->project_model->_table_name = "tbl_attachments_files"; // table name
		$this->project_model->delete_multiple(array('attachments_id' => $attachments_id));

		echo json_encode(array("status" => 'success', 'message' => lang('project_attachment_file_deleted')));
		exit();
	}

	public function save_milestones($project_id, $milestones_id = NULL)
	{
		$data = $this->project_model->array_from_post(array('milestone_name', 'description', 'start_date', 'end_date', 'user_id', 'client_visible'));
		// Update into tbl_project
		$this->project_model->_table_name = "tbl_milestones"; //table name
		$this->project_model->_primary_key = "milestones_id";
		if (!empty($milestones_id)) {
			$id = $milestones_id;
			$this->project_model->save($data, $milestones_id);
			$action = ('activity_updated_milestones');
			$msg = lang('update_milestone');
		} else {
			// if user id is empty assign to current user
			if (empty($data['user_id'])) {
				$data['user_id'] = $this->session->userdata('user_id');
			}
			$data['project_id'] = $project_id;
			$id = $this->project_model->save($data);
			$action = 'activity_added_new_milestones';
			$msg = lang('create_milestone');
		}
		// save into activities
		$activities = array(
			'user' => $this->session->userdata('user_id'),
			'module' => 'projects',
			'module_field_id' => $id,
			'activity' => $action,
			'icon' => 'fa-folder-open-o',
			'link' => 'admin/projects/project_details/' . $id . '/milestones',
			'value1' => $data['milestone_name'],
		);
		// Update into tbl_project
		$this->project_model->_table_name = "tbl_activities"; //table name
		$this->project_model->_primary_key = "activities_id";
		$this->project_model->save($activities);
		$projects_email = config_item('projects_email');
		if (!empty($projects_email) && $projects_email == 1) {
			$this->send_project_notify_milestone($id);
		}

		// messages for user
		$type = "success";
		$message = $msg;
		set_message($type, $message);
		$url = 'admin/projects/project_details/' . $project_id . '/' . 'milestones';
		echo json_encode(array("status" => 'success', 'message' => $message, 'url' => $url));
		exit();
	}

	public function send_project_notify_milestone($milestones_id)
	{

		$milestone_info = $this->project_model->check_by(array('milestones_id' => $milestones_id), 'tbl_milestones');
		$project_info = $this->project_model->check_by(array('project_id' => $milestone_info->project_id), 'tbl_project');
		$email_template = email_templates(array('email_group' => 'responsible_milestone'), $milestone_info->user_id, true);
		$user_info = $this->project_model->check_by(array('user_id' => $milestone_info->user_id), 'tbl_users');
		$message = $email_template->template_body;

		$subject = $email_template->subject;

		$milestone = str_replace("{MILESTONE_NAME}", $milestone_info->milestone_name, $message);
		$assigned_by = str_replace("{ASSIGNED_BY}", ucfirst($this->session->userdata('name')), $milestone);
		$project_name = str_replace("{PROJECT_NAME}", $project_info->project_name, $assigned_by);

		$Link = str_replace("{PROJECT_URL}", base_url() . 'admin/projects/project_details/' . $milestone_info->project_id . '/' . $data['active'] = 5, $project_name);
		$message = str_replace("{SITE_NAME}", config_item('company_name'), $Link);

		$data['message'] = $message;
		$message = $this->load->view('email_template', $data, TRUE);

		$params['subject'] = $subject;
		$params['message'] = $message;
		$params['resourceed_file'] = '';
		if (!empty($user_info)) {
			$params['recipient'] = $user_info->email;
			$this->project_model->send_email($params);
			$project_info = $this->project_model->check_by(array('project_id' => $milestone_info->project_id), 'tbl_project');

			if ($user_info->user_id != $this->session->userdata('user_id')) {
				add_notification(array(
					'to_user_id' => $user_info->user_id,
					'from_user_id' => true,
					'description' => 'not_responsible_milestone',
					'link' => 'admin/projects/project_details/' . $project_info->project_id . '/4',
					'value' => lang('project') . ' ' . $project_info->project_name,
				));
			}
			show_notification(array($user_info->user_id));
		}
	}

	public function delete_milestones($project_id, $milestones_id)
	{

		$this->project_model->_table_name = "tbl_milestones"; //table name
		$this->project_model->_order_by = "milestones_id";
		$milestones_info = $this->project_model->get_by(array('milestones_id' => $milestones_id), TRUE);
		if (empty($milestones_info)) {
			$type = "error";
			$message = "No Record Found";
			echo json_encode(array("status" => $type, 'message' => $message));
			exit();
		}
		// save into activities
		$activities = array(
			'user' => $this->session->userdata('user_id'),
			'module' => 'projects',
			'module_field_id' => $project_id,
			'activity' => lang('activity_delete_milestones'),
			'icon' => 'fa-folder-open-o',
			'link' => 'admin/projects/project_details/' . $project_id . '/5',
			'value1' => $milestones_info->milestone_name,
		);
		// Update into tbl_project
		$this->project_model->_table_name = "tbl_activities"; //table name
		$this->project_model->_primary_key = "activities_id";
		$this->project_model->save($activities);

		//save data into table.
		$this->project_model->_table_name = "tbl_milestones"; // table name
		$this->project_model->delete_multiple(array('milestones_id' => $milestones_id));

		// delete into tbl_milestones
		$this->project_model->_table_name = "tbl_milestones"; //table name
		$this->project_model->_primary_key = "milestones_id";
		$this->project_model->delete($milestones_id);
		// Update into tbl_tasks

		$this->project_model->_table_name = "tbl_task"; //table name
		$this->project_model->delete_multiple(array('milestones_id' => $milestones_id));

		echo json_encode(array("status" => 'success', 'message' => lang('delete_milestone')));
		exit();
	}

	public function change_milestones($milestone_id)
	{
		$task_id = $this->input->post('task_id', true);
		//        $task_id[] = 2;

		if ($task_id) {
			foreach ($task_id as $key => $id) {
				$data['milestones_id'] = $milestone_id;
				$data['milestones_order'] = $key + 1;
				//save data into table.
				$this->project_model->_table_name = "tbl_task"; // table name
				$this->project_model->_primary_key = "task_id"; // $id
				$id = $this->project_model->save($data, $id);
			}
		}
		$m_info = $this->db->where('milestones_id', $milestone_id)->get('tbl_milestones')->row();
		if (!empty($m_info)) {
			$m_catagory = $m_info->milestone_name;
		} else {
			$m_catagory = lang('uncategorized');
		}
		// save into activities
		$activities = array(
			'user' => $this->session->userdata('user_id'),
			'module' => 'tasks',
			'module_field_id' => $milestone_id,
			'activity' => 'activity_updated_milestones',
			'icon' => 'fa-tasks',
			'value1' => $m_catagory,
		);
		// Update into tbl_project
		$this->project_model->_table_name = "tbl_activities"; //table name
		$this->project_model->_primary_key = "activities_id";
		$this->project_model->save($activities);
		$type = "success";
		$message = lang('update_milestone');
		echo json_encode(array("status" => $type, "message" => $message));
		exit();
	}

	public function load_milestone_tasks($project_id, $milestone_id)
	{
		$limit = (int) $this->input->post('limit', true);
		$offset = (int) $this->input->post('offset', true);
		if ($limit <= 0 || $limit > 50) {
			$limit = 6;
		}
		if ($offset < 0) {
			$offset = 0;
		}

		$tasks = $this->project_model->get_project_tasks_with_meta((int) $project_id, array(
			'milestone_id' => (int) $milestone_id,
			'limit' => $limit,
			'offset' => $offset,
		));
		$items = array();
		if (!empty($tasks)) {
			foreach ($tasks as $task) {
				$items[] = $this->project_model->format_project_task_card($task, (string) $milestone_id);
			}
		}

		$count_query = $this->db
			->select('COUNT(*) AS total', false)
			->from('tbl_task')
			->where('tbl_task.project_id', (int) $project_id);

		if ((int) $milestone_id === 0) {
			$this->db->group_start();
			$this->db->where('tbl_task.milestones_id', null);
			$this->db->or_where('tbl_task.milestones_id', 0);
			$this->db->group_end();
		} else {
			$this->db->where('tbl_task.milestones_id', (int) $milestone_id);
		}

		if (!empty($this->project_model)) {
			$this->project_model->staff_query('tbl_task');
		}

		$total_row = $count_query->get()->row();
		$total = !empty($total_row) ? (int) $total_row->total : 0;

		echo json_encode(array('items' => $items, 'total' => $total));
		exit();
	}

	public function bulk_delete()
	{
		$selected_id = $this->input->post('ids', true);
		if (!empty($selected_id)) {
			foreach ($selected_id as $id) {
				$result[] = $this->delete_project($id, true);
			}
			echo json_encode($result);
			exit();
		} else {
			$type = "error";
			$message = lang('you_need_select_to_delete');
			echo json_encode(array("status" => $type, 'message' => $message));
			exit();
		}
	}

	public function delete_project($id, $bulk = null)
	{
		$id = (int) $id;
		$deleted = can_action('57', 'deleted');
		if (empty($deleted)) {
			$type = "error";
			$message = lang('access_denied');
			if (empty($message)) {
				$message = "Permission denied";
			}
			if (!empty($bulk)) {
				return (array("status" => $type, 'message' => $message));
			}
			if (!$this->input->is_ajax_request()) {
				set_message($type, $message);
				redirect('admin/projects');
				return;
			}
			echo json_encode(array("status" => $type, 'message' => $message));
			exit();
		}

		$project_info = $this->project_model->check_by(array('project_id' => $id), 'tbl_project');
		if (empty($project_info)) {
			$type = "success";
			$message = lang('project_deleted');
			if (empty($message)) {
				$message = "Project already deleted";
			}
			if (!empty($bulk)) {
				return (array("status" => $type, 'message' => $message));
			}
			if (!$this->input->is_ajax_request()) {
				set_message($type, $message);
				redirect('admin/projects');
				return;
			}
			echo json_encode(array("status" => $type, 'message' => $message));
			exit();
		}

		$can_delete = $this->project_model->can_action('tbl_project', 'delete', array('project_id' => $id));
		if (empty($can_delete)) {
			$type = "error";
			$message = lang('access_denied');
			if (empty($message)) {
				$message = "Permission denied";
			}
			if (!empty($bulk)) {
				return (array("status" => $type, 'message' => $message));
			}
			if (!$this->input->is_ajax_request()) {
				set_message($type, $message);
				redirect('admin/projects');
				return;
			}
			echo json_encode(array("status" => $type, 'message' => $message));
			exit();
		}

		if (!empty($deleted) && !empty($can_delete)) {
			if (!empty($project_info)) {
				$activity = array(
					'user' => $this->session->userdata('user_id'),
					'module' => 'projects',
					'module_field_id' => $id,
					'activity' => 'activity_project_deleted',
					'icon' => 'fa-folder-open-o',
					'value1' => $project_info->project_name
				);
				$this->project_model->_table_name = 'tbl_activities';
				$this->project_model->_primary_key = 'activities_id';
				$this->project_model->save($activity);

				$pwhere = array('module' => 'projects', 'module_field_id' => $id);
				// deleted project comments with file
				$all_comments_info = $this->db->where($pwhere)->get('tbl_task_comment')->result();
				if (!empty($all_comments_info)) {
					foreach ($all_comments_info as $comments_info) {
						if (!empty($comments_info->comments_attachment)) {
							$attachment = json_decode($comments_info->comments_attachment);
							foreach ($attachment as $v_file) {
								remove_files($v_file->fileName);
							}
						}
					}
				}
				//delete data into table.
				$this->project_model->_table_name = "tbl_task_comment"; // table name
				$this->project_model->delete_multiple($pwhere);

				// deleted project attachment with file
				$this->project_model->_table_name = "tbl_attachments"; //table name
				$this->project_model->_order_by = "module_field_id";
				$files_info = $this->project_model->get_by($pwhere, FALSE);
				if (!empty($files_info)) {
					foreach ($files_info as $v_files) {
						$uploadFileinfo = $this->db->where('attachments_id', $v_files->attachments_id)->get('tbl_attachments_files')->result();
						if (!empty($uploadFileinfo)) {
							foreach ($uploadFileinfo as $Fileinfo) {
								remove_files($Fileinfo->file_name);
							}
						}
						//save data into table.
						$this->project_model->_table_name = "tbl_attachments_files"; // table name
						$this->project_model->delete_multiple(array('attachments_id' => $v_files->attachments_id));
					}
				}
				$this->project_model->_table_name = "tbl_attachments"; // table name
				$this->project_model->delete_multiple($pwhere);

				// deleted project milestone
				$this->project_model->_table_name = "tbl_milestones"; // table name
				$this->project_model->delete_multiple(array('project_id' => $id));

				// deleted project tasks and task comments , attachments,timer
				$project_tasks = $this->db->where('project_id', $id)->get('tbl_task')->result();
				if (!empty($project_tasks)) {
					foreach ($project_tasks as $v_taks) {
						$twhere = array('module' => 'tasks', 'module_field_id' => $v_taks->task_id);
						$all_comments_info = $this->db->where($twhere)->get('tbl_task_comment')->result();
						if (!empty($all_comments_info)) {
							foreach ($all_comments_info as $comments_info) {
								if (!empty($comments_info->comments_attachment)) {
									$attachment = json_decode($comments_info->comments_attachment);
									foreach ($attachment as $v_file) {
										remove_files($v_file->fileName);
									}
								}
							}
						}
						//delete data into table.
						$this->project_model->_table_name = "tbl_task_comment"; // table name
						$this->project_model->delete_multiple($twhere);

						$this->project_model->_table_name = "tbl_attachments"; //table name
						$this->project_model->_order_by = "module_field_id";
						$files_info = $this->project_model->get_by($twhere, FALSE);
						if (!empty($files_info)) {
							foreach ($files_info as $t_v_files) {
								$uploadFileinfo = $this->db->where('attachments_id', $t_v_files->attachments_id)->get('tbl_attachments_files')->result();
								if (!empty($uploadFileinfo)) {
									foreach ($uploadFileinfo as $Fileinfo) {
										remove_files($Fileinfo->file_name);
									}
								}
								$this->project_model->_table_name = "tbl_attachments_files"; //table name
								$this->project_model->delete_multiple(array('attachments_id' => $t_v_files->attachments_id));
							}
						}
						//delete into table.
						$this->project_model->_table_name = "tbl_attachments"; // table name
						$this->project_model->delete_multiple($twhere);

						//delete into table.
						$this->project_model->_table_name = "tbl_tasks_timer"; // table name
						$this->project_model->delete_multiple(array('task_id' => $v_taks->task_id));

						$pin_info = $this->project_model->check_by(array('module_name' => 'tasks', 'module_id' => $v_taks->task_id), 'tbl_pinaction');
						if (!empty($pin_info)) {
							$this->project_model->_table_name = 'tbl_pinaction';
							$this->project_model->delete_multiple(array('module_name' => 'tasks', 'module_id' => $v_taks->task_id));
						}
					}
				}

				$this->project_model->_table_name = "tbl_task"; // table name
				$this->project_model->delete_multiple(array('project_id' => $id));

				// deleted project bugs and bug comments , attachments,bug taks and everything
				$project_bugs = $this->db->where('project_id', $id)->get('tbl_bug')->result();
				if (!empty($project_bugs)) {
					foreach ($project_bugs as $v_bugs) {
						$bwhere = array('module' => 'bugs', 'module_field_id' => $v_bugs->bug_id);
						$all_comments_info = $this->db->where($bwhere)->get('tbl_task_comment')->result();
						if (!empty($all_comments_info)) {
							foreach ($all_comments_info as $comments_info) {
								if (!empty($comments_info->comments_attachment)) {
									$attachment = json_decode($comments_info->comments_attachment);
									foreach ($attachment as $v_file) {
										remove_files($v_file->fileName);
									}
								}
							}
						}

						//delete data into table.
						$this->bugs_model->_table_name = "tbl_task_comment"; // table name
						$this->bugs_model->delete_multiple($bwhere);


						$this->bugs_model->_table_name = "tbl_attachments"; //table name
						$this->bugs_model->_order_by = "module_field_id";
						$files_info = $this->bugs_model->get_by($bwhere, FALSE);

						foreach ($files_info as $b_v_files) {
							$uploadFileinfo = $this->db->where('attachments_id', $b_v_files->attachments_id)->get('tbl_attachments_files')->result();
							if (!empty($uploadFileinfo)) {
								foreach ($uploadFileinfo as $Fileinfo) {
									remove_files($Fileinfo->file_name);
								}
							}
							$this->bugs_model->_table_name = "tbl_attachments_files"; //table name
							$this->bugs_model->delete_multiple(array('attachments_id' => $b_v_files->attachments_id));
						}
						//delete into table.
						$this->bugs_model->_table_name = "tbl_attachments"; // table name
						$this->bugs_model->delete_multiple($bwhere);

						$this->bugs_model->_table_name = 'tbl_pinaction';
						$this->bugs_model->delete_multiple(array('module_name' => 'bugs', 'module_id' => $v_bugs->bug_id));

						$bug_tasks = $this->db->where('bug_id', $v_bugs->bug_id)->get('tbl_task')->result();
						if (!empty($bug_tasks)) {
							foreach ($bug_tasks as $tasks_bugs) {
								$twhere = array('module' => 'tasks', 'module_field_id' => $tasks_bugs->bug_id);
								$all_comments_info = $this->db->where($twhere)->get('tbl_task_comment')->result();
								if (!empty($all_comments_info)) {
									foreach ($all_comments_info as $comments_info) {
										if (!empty($comments_info->comments_attachment)) {
											$attachment = json_decode($comments_info->comments_attachment);
											foreach ($attachment as $v_file) {
												remove_files($v_file->fileName);
											}
										}
									}
								}
								//delete data into table.
								$this->project_model->_table_name = "tbl_task_comment"; // table name
								$this->project_model->delete_multiple($twhere);

								$this->project_model->_table_name = "tbl_attachments"; //table name
								$this->project_model->_order_by = "module_field_id";
								$files_info = $this->project_model->get_by($twhere, FALSE);
								if (!empty($files_info)) {
									foreach ($files_info as $t_v_files) {
										$uploadFileinfo = $this->db->where('attachments_id', $t_v_files->attachments_id)->get('tbl_attachments_files')->result();
										if (!empty($uploadFileinfo)) {
											foreach ($uploadFileinfo as $Fileinfo) {
												remove_files($Fileinfo->file_name);
											}
										}
										$this->project_model->_table_name = "tbl_attachments_files"; //table name
										$this->project_model->delete_multiple(array('attachments_id' => $v_files->attachments_id));
									}
								}
								//delete into table.
								$this->project_model->_table_name = "tbl_attachments"; // table name
								$this->project_model->delete_multiple($twhere);

								$pin_info = $this->project_model->check_by(array('module_name' => 'tasks', 'module_id' => $tasks_bugs->task_id), 'tbl_pinaction');
								if (!empty($pin_info)) {
									$this->project_model->_table_name = 'tbl_pinaction';
									$this->project_model->delete_multiple(array('module_name' => 'tasks', 'module_id' => $tasks_bugs->task_id));
								}
							}
						}
						//save data into table.
						$this->project_model->_table_name = "tbl_task"; // table name
						$this->project_model->delete_multiple(array('bug_id' => $v_bugs->bug_id));
					}
				}

				//delete the bugs
				$this->project_model->_table_name = "tbl_bug"; // table name
				$this->project_model->delete_multiple(array('project_id' => $id));

				// delete all project tickets ans tikcets reply with attachment
				$project_tickets = $this->db->where('project_id', $id)->get('tbl_tickets')->result();
				// deleted project comments with file
				if (!empty($project_tickets)) {
					foreach ($project_tickets as $v_tickets) {

						$tickets_reply = $this->db->where('tickets_id', $v_tickets->tickets_id)->get('tbl_tickets_replies')->result();
						if (!empty($tickets_reply)) {
							foreach ($tickets_reply as $v_ti_reply) {
								if (!empty($v_ti_reply->attachment)) {
									$attachment = json_decode($v_ti_reply->attachment);
									foreach ($attachment as $v_file) {
										remove_files($v_file->fileName);
									}
								}
							}
							//delete data into table.
							$this->project_model->_table_name = "tbl_tickets_replies"; // table name
							$this->project_model->delete_multiple(array('tickets_id' => $v_tickets->tickets_id));
						}

						if (!empty($v_tickets->upload_file)) {
							$attachment = json_decode($v_tickets->upload_file);
							foreach ($attachment as $v_file) {
								remove_files($v_file->fileName);
							}
						}
					}
					//delete data into table.
					$this->project_model->_table_name = "tbl_tickets"; // table name
					$this->project_model->delete_multiple(array('project_id' => $id));
				}

				// delete all invoice and invoice items
				$project_invoice = $this->db->where('project_id', $id)->get('tbl_invoices')->result();
				if (!empty($project_invoice)) {
					foreach ($project_invoice as $vp_invoice) {
						$this->project_model->_table_name = "tbl_items"; // table name
						$this->project_model->delete_multiple(array('invoices_id' => $vp_invoice->invoices_id));
					}
					$this->project_model->_table_name = "tbl_invoices"; // table name
					$this->project_model->delete_multiple(array('project_id' => $id));
				}

				// delete all estimates and estimates items
				$project_estimate = $this->db->where('project_id', $id)->get('tbl_estimates')->result();
				if (!empty($project_estimate)) {
					foreach ($project_estimate as $vp_estimate) {
						$this->project_model->_table_name = "tbl_estimate_items"; // table name
						$this->project_model->delete_multiple(array('estimates_id' => $vp_estimate->estimates_id));
					}
					$this->project_model->_table_name = "tbl_estimates"; // table name
					$this->project_model->delete_multiple(array('project_id' => $id));
				}
				// delete all estimates and estimates items
				$project_expense = $this->db->where('project_id', $id)->get('tbl_transactions')->result();
				if (!empty($project_expense)) {
					foreach ($project_expense as $vp_expense) {
						if (!finance_guard_accounting_period($vp_expense->date, lang('expense'))) {
							$this->db->trans_rollback();
							set_message('error', lang('accounting_period_closed'));
							redirect('admin/projects');
							return;
						}
						$account_info = $this->project_model->check_by(array('account_id' => $vp_expense->account_id), 'tbl_accounts');

						$ac_data['balance'] = $account_info->balance + $vp_expense->amount;
						$this->project_model->_table_name = "tbl_accounts"; //table name
						$this->project_model->_primary_key = "account_id";
						$this->project_model->save($ac_data, $account_info->account_id);

						$this->project_model->_table_name = "tbl_transactions"; //table name
						$this->project_model->_primary_key = "transactions_id";
						finance_sync_model()->delete_transaction_by_id($vp_expense->transactions_id);
						$this->project_model->delete($vp_expense->transactions_id);
					}
				}

				//delete the timer from tbl_tasks_timer
				$this->project_model->_table_name = "tbl_tasks_timer"; // table name
				$this->project_model->delete_multiple(array('project_id' => $id));

				$this->project_model->_table_name = 'tbl_pinaction';
				$this->project_model->delete_multiple(array('module_name' => 'project', 'module_id' => $id));

				$this->project_model->_table_name = 'tbl_project';
				$this->project_model->_primary_key = 'project_id';
				$this->project_model->delete($id);

				$type = 'success';
				$message = lang('project_deleted');
			} else {
				$type = 'error';
				$message = lang('error_occurred');
			}
			if (!empty($bulk)) {
				return (array("status" => $type, 'message' => $message));
			}
			if (!$this->input->is_ajax_request()) {
				set_message($type, $message);
				redirect('admin/projects');
				return;
			}
			echo json_encode(array("status" => $type, 'message' => $message));
		}
		exit();
	}

	public function save_project_notes($id)
	{

		$data = $this->project_model->array_from_post(array('notes'));

		//save data into table.
		$this->project_model->_table_name = 'tbl_project';
		$this->project_model->_primary_key = 'project_id';
		$id = $this->project_model->save($data, $id);
		// save into activities
		$activities = array(
			'user' => $this->session->userdata('user_id'),
			'module' => 'projects',
			'module_field_id' => $id,
			'activity' => 'activity_update_notes',
			'icon' => 'fa-folder-open-o',
			'link' => 'admin/projects/project_details/' . $id . '/8',
			'value1' => $data['notes'],
		);
		// Update into tbl_project
		$this->project_model->_table_name = "tbl_activities"; //table name
		$this->project_model->_primary_key = "activities_id";
		$this->project_model->save($activities);

		$type = "success";
		$message = lang('update_task');
		set_message($type, $message);
		redirect('admin/projects/project_details/' . $id . '/' . 'notes');
	}



	public
	function tasks_timer($status, $project_id, $inline = null)
	{
		$task_start = $this->project_model->check_by(array('project_id' => $project_id), 'tbl_project');
		$project_info = $this->project_model->check_by(array('project_id' => $project_id), 'tbl_project');
		$notifiedUsers = array();
		if (!empty($project_info->permission) && $project_info->permission != 'all') {
			$permissionUsers = json_decode($project_info->permission);
			foreach ($permissionUsers as $user => $v_permission) {
				array_push($notifiedUsers, $user);
			}
		} else {
			$notifiedUsers = $this->project_model->allowed_user_id('57');
		}
		if ($status == 'off') {
			// check this user start time or this user is admin
			// if true then off time
			// else do not off time
			$check_user = $this->timer_started_by($project_id);

			if ($check_user == TRUE) {
				$tasks_timer_id = timer_status('projects', $project_id, 'on', true);
				$active_timer = null;
				if (!empty($tasks_timer_id)) {
					$active_timer = $this->db->where('tasks_timer_id', $tasks_timer_id)->get('tbl_tasks_timer')->row();
				} elseif ((int) $this->session->userdata('user_type') === 1) {
					$active_timer = $this->db
						->where(array('project_id' => $project_id, 'timer_status' => 'on'))
						->order_by('tasks_timer_id', 'DESC')
						->get('tbl_tasks_timer')
						->row();
					if (!empty($active_timer)) {
						$tasks_timer_id = $active_timer->tasks_timer_id;
					}
				}

				if (empty($tasks_timer_id)) {
					$type = "error";
					$message = lang('no_data_found');
					set_message($type, $message);
					redirect('admin/projects/project_details/' . $project_id . '/timesheet');
				}

				$task_logged_time = $this->project_model->task_spent_time_by_id($project_id, true);

				$time_logged = (time() - $task_start->start_time) + $task_logged_time; //time already logged

				$data = array(
					'timer_status' => $status,
					'logged_time' => $time_logged,
					'start_time' => ''
				);
				// Update into tbl_task
				$this->project_model->_table_name = "tbl_project"; //table name
				$this->project_model->_primary_key = "project_id";
				$this->project_model->save($data, $project_id);
				// save into tbl_task_timer
				$t_data = array(
					'project_id' => $project_id,
					'user_id' => !empty($active_timer->user_id) ? $active_timer->user_id : $this->session->userdata('user_id'),
					'timer_status' => $status,
					'end_time' => time()
				);
				// insert into tbl_task_timer
				$this->project_model->_table_name = "tbl_tasks_timer"; //table name
				$this->project_model->_primary_key = "tasks_timer_id";
				$this->project_model->save($t_data, $tasks_timer_id);

				// save into activities
				$activities = array(
					'user' => $this->session->userdata('user_id'),
					'module' => 'projects',
					'module_field_id' => $project_id,
					'activity' => ('activity_tasks_timer_off'),
					'icon' => 'fa-folder-open-o',
					'link' => 'admin/projects/project_details/' . $project_id . '/timesheet',
					'value1' => $task_start->project_name,
				);
				// Update into tbl_project
				$this->project_model->_table_name = "tbl_activities"; //table name
				$this->project_model->_primary_key = "activities_id";
				$this->project_model->save($activities);

				$task_start = $this->project_model->check_by(array('project_id' => $project_id), 'tbl_project');
				$estimate_hours = $task_start->estimate_hours;

				$percentage = $this->project_model->get_estime_time($estimate_hours);
				$logged_hour = $this->project_model->calculate_project('project_hours', $task_start->project_id);
				$progress = 0;
				if ($percentage != 0) {
					$progress = round(($logged_hour / $percentage) * 100);
					if ($progress > 100) {
						$progress = 100;
					}
					$p_data = array(
						'progress' => $progress,
					);
					$this->project_model->_table_name = "tbl_project"; //table name
					$this->project_model->_primary_key = "project_id";
					$this->project_model->save($p_data, $project_id);
				}

				if (!empty($notifiedUsers)) {
					foreach ($notifiedUsers as $users) {
						if ($users != $this->session->userdata('user_id')) {
							add_notification(array(
								'to_user_id' => $users,
								'from_user_id' => true,
								'description' => 'not_timer_stop',
								'link' => 'admin/projects/project_details/' . $project_info->project_id . '/timesheet',
								'value' => lang('project') . ' ' . $project_info->project_name . ' ' . lang('progress') . ' ' . $progress,
							));
						}
					}
					show_notification($notifiedUsers);
				}
				$this->project_model->set_progress($t_data['project_id']);
			} else {
				$type = "error";
				$message = lang('no_data_found');
				set_message($type, $message);
				redirect('admin/projects/project_details/' . $project_id . '/timesheet');
			}
		} else {
			$data = array(
				'timer_status' => $status,
				'timer_started_by' => $this->session->userdata('user_id'),
				'start_time' => time()
			);

			// save into activities
			$activities = array(
				'user' => $this->session->userdata('user_id'),
				'module' => 'projects',
				'module_field_id' => $project_id,
				'activity' => 'activity_tasks_timer_on',
				'icon' => 'fa-folder-open-o',
				'link' => 'admin/projects/project_details/' . $project_id . '/timesheet',
				'value1' => $task_start->project_name,
			);
			// Update into tbl_project
			$this->project_model->_table_name = "tbl_activities"; //table name
			$this->project_model->_primary_key = "activities_id";
			$this->project_model->save($activities);

			// Update into tbl_task
			$this->project_model->_table_name = "tbl_project"; //table name
			$this->project_model->_primary_key = "project_id";
			$this->project_model->save($data, $project_id);

			// save into tbl_task_timer
			$t_data = array(
				'project_id' => $project_id,
				'timer_status' => $status,
				'user_id' => $this->session->userdata('user_id'),
				'start_time' => time()
			);
			// insert into tbl_task_timer
			$this->project_model->_table_name = "tbl_tasks_timer"; //table name
			$this->project_model->_primary_key = "tasks_timer_id";
			$this->project_model->save($t_data);

			if (!empty($notifiedUsers)) {
				foreach ($notifiedUsers as $users) {
					if ($users != $this->session->userdata('user_id')) {
						add_notification(array(
							'to_user_id' => $users,
							'from_user_id' => true,
							'description' => 'not_timer_start',
							'link' => 'admin/projects/project_details/' . $project_info->project_id . '/timesheet',
							'value' => lang('project') . ' ' . $project_info->project_name,
						));
					}
				}
				show_notification($notifiedUsers);
			}
		}
		// messages for user
		if (!empty($inline)) {
			return true;
		} else {
			$type = "success";
			$message = lang('task_timer_' . $status);
			set_message($type, $message);
			$fallback = '/admin/projects/project_details/' . $project_info->project_id . '/timesheet';
			header('Location: ' . $fallback, true, 302);
			exit;
		}
	}

	public
	function timer_started_by($task_id)
	{
		$user_id = $this->session->userdata('user_id');
		//        $user_info = $this->project_model->check_by(array('user_id' => $user_id), 'tbl_users');
		$timer_started_info = $this->project_model->check_by(array('project_id' => $task_id), 'tbl_project');
		if (!empty($timer_started_info->timer_started_by) && $timer_started_info->timer_started_by == $user_id) {
			return TRUE;
		}
		$this->db->where(array('project_id' => $task_id, 'timer_status' => 'on'));
		if ((int) $this->session->userdata('user_type') !== 1) {
			$this->db->where('user_id', $user_id);
		}
		$active_timer = $this->db->get('tbl_tasks_timer')->row();
		if (!empty($active_timer)) {
			return TRUE;
		} else {
			return FALSE;
		}
	}

	public
	function download_files($uploaded_files_id, $comments = null)
	{

		$this->load->helper('download');
		if (!empty($comments)) {
			if ($uploaded_files_id) {
				$down_data = file_get_contents('uploads/' . $uploaded_files_id); // Read the file's contents
				force_download($uploaded_files_id, $down_data);
			} else {
				echo json_encode(array("status" => 'error', 'message' => lang('error_occurred')));
			}
		} else {
			$uploaded_files_info = $this->project_model->check_by(array('uploaded_files_id' => $uploaded_files_id), 'tbl_attachments_files');
			if (!empty($uploaded_files_info->uploaded_path)) {
				$data = file_get_contents($uploaded_files_info->uploaded_path); // Read the file's contents
				if (!empty($data)) {
					force_download($uploaded_files_info->file_name, $data);
				} else {
					echo json_encode(array("status" => 'error', 'message' => lang('error_occurred')));
				}
			} else {
				echo json_encode(array("status" => 'error', 'message' => lang('error_occurred')));
			}
		}
	}

	public
	function download_all_files($attachment_id)
	{
		$uploaded_files_info = $this->db->where('attachments_id', $attachment_id)->get('tbl_attachments_files')->result();

		$attachment_info = $this->db->where('attachments_id', $attachment_id)->get('tbl_attachments')->row();
		$this->load->library('zip');
		if (!empty($uploaded_files_info)) {
			$filename = slug_it($attachment_info->title);
			foreach ($uploaded_files_info as $v_files) {
				$down_data = ($v_files->files); // Read the file's contents
				$this->zip->read_file($down_data);
			}
			$this->zip->download($filename . '.zip');
		} else {
			$type = "error";
			$message = lang('operation_failed');
			set_message($type, $message);
			redirect('admin/projects/project_details/' . $attachment_info->project_id . '/4');
		}
	}

	public
	function add_todo_list($module, $id)
	{
		$where = array('user_id' => $this->session->userdata('user_id'), 'module_id' => $id, 'module_name' => $module);
		$already_pinned = $this->project_model->check_by($where, 'tbl_pinaction');
		if (empty($already_pinned)) {
			$this->project_model->_table_name = "tbl_pinaction"; //table name
			$this->project_model->_primary_key = "pinaction_id";
			$this->project_model->save($where);
		}
		redirect($this->resolve_todo_redirect($module, $id));
	}

	public
	function remove_todo($id)
	{
		$pinned_info = $this->project_model->check_by(array('pinaction_id' => $id), 'tbl_pinaction');
		// Update into tbl_pinaction
		$this->project_model->_table_name = "tbl_pinaction"; //table name
		$this->project_model->_primary_key = "pinaction_id";
		$this->project_model->delete($id);
		$module = !empty($pinned_info->module_name) ? $pinned_info->module_name : null;
		$module_id = !empty($pinned_info->module_id) ? $pinned_info->module_id : null;
		redirect($this->resolve_todo_redirect($module, $module_id));
	}

	protected function resolve_todo_redirect($module = null, $id = null)
	{
		$module_routes = array(
			'leads' => 'admin/leads/leads_details/',
			'project' => 'admin/projects/project_details/',
			'tasks' => 'admin/tasks/details/',
			'tickets' => 'admin/tickets/tickets_details/',
			'invoice' => 'admin/invoice/manage_invoice/invoice_details/',
			'estimates' => 'admin/estimates/create/estimates_details/',
			'credit_note' => 'admin/credit_note/index/credit_note_details/',
			'bugs' => 'admin/bugs/details/',
		);

		if (!empty($module) && !empty($id) && isset($module_routes[$module])) {
			return $module_routes[$module] . $id;
		}

		$referer = $this->input->server('HTTP_REFERER', true);
		if (!empty($referer)) {
			$base_url = rtrim(base_url(), '/');
			if (strpos($referer, $base_url) === 0) {
				$relative_path = ltrim(substr($referer, strlen($base_url)), '/');
				if (!empty($relative_path)) {
					return $relative_path;
				}
			}
		}

		return 'admin/dashboard';
	}

	public
	function export_project($id)
	{
		$data['title'] = lang('export_report');
		$data['project_details'] = $this->project_model->check_by(array('project_id' => $id), 'tbl_project');
		$data['project_finance_summary'] = $this->finance_report_model->get_project_expense_summary($data['project_details']->project_id);
		$viewfile = $this->load->view('admin/projects/export_project', $data, TRUE);
		//        echo "<pre>";
		//        print_r($viewfile);
		//        exit();
		//        $data['subview'] = $viewfile;
		$this->load->helper('dompdf');
		pdf_create($viewfile, slug_it($data['project_details']->project_name . '-' . lang('details')), 1, 1);
		//        $this->load->view('admin/_layout_main', $data); //page load
	}

	public function new_category()
	{
		if ($this->input->is_ajax_request()) {
			$data['title'] = lang('new') . ' ' . lang('categories');
			$data['type'] = 'projects';
			$this->load->view('admin/projects/new_category', $data);
		} else {
			redirect('admin/projects');
		}
	}

	public function update_category($id = null)
	{
		$this->project_model->_table_name = 'tbl_customer_group';
		$this->project_model->_primary_key = 'customer_group_id';

		$cate_data['customer_group'] = $this->input->post('category_name', TRUE);
		$cate_data['description'] = $this->input->post('description', TRUE);
		$type = $this->input->post('type', TRUE);
		if (!empty($type)) {
			$cate_data['type'] = $type;
		} else {
			$cate_data['type'] = 'client';
		}
		// update root category
		$where = array('type' => $cate_data['type'], 'customer_group' => $cate_data['customer_group']);
		// duplicate value check in DB
		if (!empty($id)) { // if id exist in db update data
			$customer_group_id = array('customer_group_id !=' => $id);
		} else { // if id is not exist then set id as null
			$customer_group_id = null;
		}
		// check whether this input data already exist or not
		$check_category = $this->project_model->check_update('tbl_customer_group', $where, $customer_group_id);
		if (!empty($check_category)) { // if input data already exist show error alert
			// massage for user
			$type = 'error';
			$msg = "<strong style='color:#000'>" . $cate_data['customer_group'] . '</strong>  ' . lang('already_exist');
		} else { // save and update query
			$id = $this->project_model->save($cate_data, $id);

			$activity = array(
				'user' => $this->session->userdata('user_id'),
				'module' => 'settings',
				'module_field_id' => $id,
				'activity' => ('customer_group_added'),
				'value1' => $cate_data['customer_group']
			);
			$this->project_model->_table_name = 'tbl_activities';
			$this->project_model->_primary_key = 'activities_id';
			$this->project_model->save($activity);

			// messages for user
			$type = "success";
			$msg = lang('category_added');
		}
		if (!empty($id)) {
			$result = array(
				'id' => $id,
				'group' => $cate_data['customer_group'],
				'status' => $type,
				'message' => $msg,
			);
		} else {
			$result = array(
				'status' => $type,
				'message' => $msg,
			);
		}
		echo json_encode($result);
		exit();
	}
}
