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

class Transactions extends Admin_Controller
{

    public function __construct()
    {
        parent::__construct();
        $this->load->model('transactions_model');
        $this->load->model('finance_report_model');
        $this->load->model('invoice_model');
        $this->load->model('items_model');
    }

    private function build_select_options($table, $id_field, $label_field, $order_field = null, $order_dir = 'DESC')
    {
        $order_field = $order_field ?: $id_field;
        $rows = $this->db->order_by($order_field, $order_dir)->get($table)->result();
        $options = array();
        if (!empty($rows)) {
            foreach ($rows as $row) {
                $options[$row->{$id_field}] = $row->{$label_field};
            }
        }
        return $options;
    }

    private function get_balance_sheet_summary()
    {
        $summary_cache_key = 'transactions_balance_sheet_summary_v1';
        $summary = function_exists('helper_cache_get') ? helper_cache_get($summary_cache_key) : false;

        if ($summary !== false) {
            return $summary;
        }

        $summary_row = $this->db
            ->select('COUNT(*) AS total_accounts, COALESCE(SUM(balance),0) AS total_amount, SUM(CASE WHEN balance >= 0 THEN 1 ELSE 0 END) AS positive_accounts, SUM(CASE WHEN balance < 0 THEN 1 ELSE 0 END) AS negative_accounts', false)
            ->get('tbl_accounts')
            ->row();

        $top_account = $this->db
            ->select('account_id, account_name, balance')
            ->order_by('balance', 'DESC')
            ->limit(1)
            ->get('tbl_accounts')
            ->row();

        $lowest_account = $this->db
            ->select('account_id, account_name, balance')
            ->order_by('balance', 'ASC')
            ->limit(1)
            ->get('tbl_accounts')
            ->row();

        $summary = array(
            'currency_symbol' => default_currency(),
            'total_accounts' => !empty($summary_row->total_accounts) ? (int) $summary_row->total_accounts : 0,
            'total_amount' => !empty($summary_row->total_amount) ? (float) $summary_row->total_amount : 0,
            'positive_accounts' => !empty($summary_row->positive_accounts) ? (int) $summary_row->positive_accounts : 0,
            'negative_accounts' => !empty($summary_row->negative_accounts) ? (int) $summary_row->negative_accounts : 0,
            'top_account' => $top_account,
            'lowest_account' => $lowest_account,
        );

        if (function_exists('helper_cache_save')) {
            helper_cache_save($summary_cache_key, $summary, 300);
        }

        return $summary;
    }

    public function deposit($id = NULL)
    {
        $data['title'] = lang('all_deposit');        // get permission user by menu id
        $data['page_title'] = lang('all_deposit');
        $data['page_description'] = lang('manage') . ' ' . lang('deposit');
        $data['header_actions'] = array();
        if (!empty(can_action('30', 'created')) || !empty(can_action('30', 'edited'))) {
            $data['header_actions'] =  array(
				array(
					'label' => lang('new') . ' ' . lang('deposit'),
					'icon' => 'plus',
					'href' => base_url('admin/transactions/create_deposit'),
					'style' => 'primary',
				),
				array(
					'label' => lang('import') . ' ' . lang('deposit'),
					'icon' => 'upload',
					'href' => base_url('admin/transactions/import/Income'),
					'style' => 'info',
				)
            );
        }
        $data['header_filters'] = array();
		$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('account'),
						'icon' => 'wallet',
						'items' => array(
							array(
								'label' => lang('all') . ' ' . lang('account'),
								'attrs' => array(
									'data-payment-filter-action' => '1',
									'data-payment-filter' => '',
									'data-payment-search' => 'by_account',
									'data-payment-filter-label' => lang('all') . ' ' . lang('account'),
								),
							),
						),
						'lookup' => array(
							'endpoint' => base_url('admin/common/account_lookup'),
							'limit' => 12,
							'min_length' => 0,
							'action_attrs' => array('data-payment-filter-action' => '1', 'data-payment-search' => 'by_account'),
							'filter_attr' => 'data-payment-filter',
							'label_attr' => 'data-payment-filter-label',
							'label_prefix' => lang('account') . ': ',
							'placeholder' => lang('search') . ' ' . lang('account'),
							'cache_key' => 'payments_account_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/income_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' => 'income_category_lookup',
						),
					),
				),
			),
		);
        $data['active'] = 1;
		$data['datatable'] = true;
        $data['subview'] = $this->load->view('admin/transactions/deposit', $data, TRUE);
        $this->load->view('admin/_layout_main', $data); //page load
    }

    public function create_deposit($id = NULL)
    {
        $data['title'] = lang('all_deposit');
        $deposit_info = null;
        // get permission user by menu id
        $data['permission_user'] = $this->transactions_model->all_permission_user('30');
        $data['income_category_options'] = $this->build_select_options('tbl_income_category', 'income_category_id', 'income_category');
        $data['payment_method_options'] = $this->build_select_options('tbl_payment_methods', 'payment_methods_id', 'method_name');
        if (!empty($id)) {
            $data['active'] = 2;
            if (is_numeric($id)) {
                $deposit_info = $this->transactions_model->check_by(array('transactions_id' => $id), 'tbl_transactions');
                if (!empty($deposit_info))
                    $can_edit = $this->transactions_model->can_action('tbl_transactions', 'edit', array('transactions_id' => $id));
                if (!empty($can_edit)) {
                    $data['deposit_info'] = $deposit_info;
                }
            } else {
                $data['active'] = 1;
                if ($id == 'project_deposit') {
                    $data['active'] = 2;
                    $project_id = $this->uri->segment(5);
                    $project_info = get_row('tbl_project', array('project_id' => $project_id));
                    if (!empty($project_info)) {
                        if ($project_info->permission == 'all') {
                            $data['permission_user'] = $this->transactions_model->allowed_user('57');
                        } else {
                            $data['permission_user'] = $this->transactions_model->permitted_allowed_user($project_info->permission);
                        }
                    }
                } elseif ($id == 'client_deposit') {
                    $data['active'] = 2;
                    $data['selected_paid_by_id'] = $this->uri->segment(5);
                }
            }
        }
        $data['selected_paid_by_id'] = !empty($deposit_info->paid_by) ? $deposit_info->paid_by : (!empty($data['selected_paid_by_id']) ? $data['selected_paid_by_id'] : '');
        $data['selected_paid_by_label'] = '';
        if (!empty($data['selected_paid_by_id'])) {
            $paid_by = $this->db->where('client_id', $data['selected_paid_by_id'])->get('tbl_client')->row();
            $data['selected_paid_by_label'] = !empty($paid_by->name) ? $paid_by->name : '';
        }
        $data['selected_project_id'] = !empty($deposit_info->project_id) ? $deposit_info->project_id : ($id == 'project_deposit' ? ($this->uri->segment(5) ?? '') : '');
        $data['selected_project_label'] = '';
        if (!empty($data['selected_project_id']) && is_numeric($data['selected_project_id'])) {
            $project = $this->db->where('project_id', $data['selected_project_id'])->get('tbl_project')->row();
            $data['selected_project_label'] = !empty($project->project_name) ? $project->project_name : '';
            if (!empty($project->client_id)) {
                $client = $this->db->where('client_id', $project->client_id)->get('tbl_client')->row();
                if (!empty($client)) {
                    $data['project_client_id'] = $project->client_id;
                    $data['project_client_label'] = $client->name;
                }
            }
        }
        $data['selected_account_label'] = '';
        if (!empty($deposit_info->account_id)) {
            $account = $this->db->where('account_id', $deposit_info->account_id)->get('tbl_accounts')->row();
            $data['selected_account_label'] = !empty($account->account_name) ? $account->account_name : '';
        }
        if (empty($deposit_info)) {
            $this->load->helper('string');
            $prefix = '';
            if (empty(config_item('deposit_number_format'))) {
                $prefix = (string) config_item('deposit_prefix') . random_string('nozero', 6);
            }
            $data['transaction_prefix_default'] = $prefix . $this->transactions_model->generate_transactions_number('Income');
        }
        $data['active'] = 2;
        $data['dropzone'] = true;
        $data['subview'] = $this->load->view('admin/transactions/create_deposit', $data, TRUE);
        $this->load->view('admin/_layout_main', $data); //page load
    }

    public function depositList($filterBy = null, $type = null)
    {
        if ($this->input->is_ajax_request()) {
            $this->load->model('datatables');
            $this->datatables->table = 'tbl_transactions';
            $this->datatables->join_table = array('tbl_accounts', 'tbl_client');
            $this->datatables->join_where = array('tbl_accounts.account_id=tbl_transactions.account_id', 'tbl_transactions.paid_by=tbl_client.client_id');

            $custom_field = custom_form_table_search(1);
            $action_array = array('transactions_id');
            $main_column = array('transactions_id', 'transaction_prefix', 'tbl_transactions.name', 'tbl_transactions.date', 'tbl_accounts.account_name', 'amount', 'tags', 'tbl_client.name', 'reference');
            $result = array_merge($main_column, $custom_field, $action_array);
            $this->datatables->column_order = $result;
            $this->datatables->column_search = $result;

            $this->datatables->order = array('transactions_id' => 'desc');

            $where = null;
            if (empty($type)) {
                $where = array('type' => 'Income');
            }
            if ($type == 'by_account') {
                $where = array('type' => 'Income', 'tbl_transactions.account_id' => $filterBy);
            } else if ($type == 'by_category') {
                $where = array('type' => 'Income', 'category_id' => $filterBy);
            }
            // get all invoice
            $fetch_data = $this->datatables->get_deposit($filterBy, $type);

            $data = array();
            $edited = can_action('30', 'edited');
            $deleted = can_action('30', 'deleted');
            foreach ($fetch_data as $_key => $v_deposit) {
                if (!empty($v_deposit)) {
                    $action = null;
                    $can_edit = $this->transactions_model->can_action('tbl_transactions', 'edit', array('transactions_id' => $v_deposit->transactions_id));
                    $can_delete = $this->transactions_model->can_action('tbl_transactions', 'delete', array('transactions_id' => $v_deposit->transactions_id));

                    $account_info = $this->transactions_model->check_by(array('account_id' => $v_deposit->account_id), 'tbl_accounts');
                    $client_info = $this->transactions_model->check_by(array('client_id' => $v_deposit->paid_by), 'tbl_client');
                    $category_info = $this->transactions_model->check_by(array('income_category_id' => $v_deposit->category_id), 'tbl_income_category');
                    if (!empty($client_info)) {
                        $client_name = $client_info->name;
                    } else {
                        $client_name = '-';
                    }

                    $sub_array = array();
                if (!empty($edited) || !empty($deleted)) {
                    $sub_array[] = '<div class="checkbox c-checkbox" ><label class="needsclick"> <input value="' . $v_deposit->transactions_id . '" type="checkbox"></label></div>';
                }
                    $transaction_prefix = null;
                    $transaction_prefix .= '<a class="text-blue-600 hover:text-blue-900 dark:text-blue-400 dark:hover:text-blue-300" href="' . base_url() . 'admin/transactions/view_details/' . $v_deposit->transactions_id . '">' . (!empty($v_deposit->transaction_prefix) ? $v_deposit->transaction_prefix : ' ') . '</a>';
                    $sub_array[] = $transaction_prefix;

                    $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/transactions/view_details/' . $v_deposit->transactions_id . '">' . (!empty($v_deposit->name) ? $v_deposit->name : '-') . '</a>';
                    $sub_array[] = $name;

                    $date = null;
                    $date .= '<a class="text-blue-600 hover:text-blue-900 dark:text-blue-400 dark:hover:text-blue-300" href="' . base_url() . 'admin/transactions/view_details/' . $v_deposit->transactions_id . '">' . display_date($v_deposit->date) . '</a>';
                    $sub_array[] = $date;

                    $account_label = !empty($account_info->account_name) ? $account_info->account_name : '-';
                    $sub_array[] = '<span class="inline-flex items-center rounded-full border border-border px-2 py-0.5 text-xs font-semibold text-foreground">' . html_escape($account_label) . '</span>';

                    $sub_array[] = '<span class="inline-flex items-center rounded-full border border-border px-2 py-0.5 text-xs font-semibold text-foreground">' . html_escape($client_name) . '</span>';
                    $sub_array[] = get_tags($v_deposit->tags, true);

                    $sub_array[] = display_money($v_deposit->amount, default_currency());
                    $sub_array[] = display_money($v_deposit->total_balance, default_currency());

                    $custom_form_table = custom_form_table(1, $v_deposit->transactions_id);
                    if (!empty($custom_form_table)) {
                        foreach ($custom_form_table as $c_label => $v_fields) {
                            $sub_array[] = $v_fields;
                        }
                    }
                    $attachment = null;
                    $attachment_info = !empty($v_deposit->attachement) ? json_decode($v_deposit->attachement) : array();
                    if (!empty($attachment_info)) {
                        $attachment = '<a href="' . base_url() . 'admin/transactions/download/' . $v_deposit->transactions_id . '">' . lang('download') . '</a>';
                    }
                    $sub_array[] = $attachment;

                if (!empty($edited) || !empty($deleted)) {
                    $action .= '<a class="btn btn-info btn-xs inline-flex h-7 w-8 items-center justify-center rounded-lg border-0 p-0 shadow-sm transition hover:opacity-90 focus:outline-none focus:ring-2 focus:ring-sky-400 focus:ring-offset-1" href="' . base_url() . 'admin/transactions/view_details/' . $v_deposit->transactions_id . '"><span data-lucide="list" class="h-4 w-4"></span></a>' . ' ';
                    if (!empty($can_edit) && !empty($edited)) {
                        $action .= btn_edit('admin/transactions/create_deposit/' . $v_deposit->transactions_id) . ' ';
                    }
                    if (!empty($can_delete) && !empty($deleted)) {
                        $action .= ajax_anchor(base_url("admin/transactions/delete_deposit/$v_deposit->transactions_id"), '', array("data-fade-out-on-success" => "#table_" . $_key)) . ' ';
                    }
                    $sub_array[] = $action;
                }
                $data[] = $sub_array;
            }
            }

            render_table($data, $where);
        } else {
            redirect('admin/dashboard');
        }
    }


    public function transaction_deposit_state_report()
    {
        if (!$this->input->is_ajax_request()) {
            redirect('admin/dashboard');
        }
        $mdate = date('Y-m-d');
        $last_7_days = date('Y-m-d', safe_strtotime('today - 7 days'));
        $data['daily_series'] = $this->finance_report_model->get_transaction_daily_series('Income', $last_7_days, $mdate);
        $pathonor_jonno['transaction_deposit_state_report_div'] = $this->load->view("admin/transactions/transaction_deposit_state_report", $data, true);
        echo json_encode($pathonor_jonno);
        exit;
    }


    public function import($type)
    {
        if ($type == 'Income') {
            $header = lang('deposit');
        } else {
            $header = lang('expense');
        }
        $data['title'] = lang('import') . ' ' . $header;
        $data['permission_user'] = $this->transactions_model->all_permission_user($type == 'Income' ? '30' : '31');
        $data['type'] = $type;
        $data['payment_method_options'] = $this->build_select_options('tbl_payment_methods', 'payment_methods_id', 'method_name');
        if ($type == 'Income') {
            $data['category_options'] = $this->build_select_options('tbl_income_category', 'income_category_id', 'income_category');
            $data['category_label'] = lang('deposit_category');
        } else {
            $data['category_options'] = $this->build_select_options('tbl_expense_category', 'expense_category_id', 'expense_category');
            $data['category_label'] = lang('expense_category');
        }
        $data['subview'] = $this->load->view('admin/transactions/import', $data, TRUE);
        $this->load->view('admin/_layout_main', $data); //page load
    }

    public function save_imported()
    {
        $import_type = $this->input->post('type', true);
        if (empty($_FILES['upload_file']['tmp_name'])) {
            set_message('error', lang('choose_file') . ' Field is required');
            redirect('admin/transactions/import/' . (!empty($import_type) ? $import_type : 'Expense'));
            return;
        }

        //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/transactions/import/' . (!empty($import_type) ? $import_type : 'Expense'));
            return;
        }
        if (empty($files)) {
            set_message('error', lang('no_data_available'));
            redirect('admin/transactions/import/' . (!empty($import_type) ? $import_type : 'Expense'));
            return;
        }
        $import_rows = array();
        foreach ($files as $key => $value) {
            if (!empty($value)) {
                $value = array_pad((array)$value, 4, '');
                $data = $this->transactions_model->array_from_post(array('name', 'account_id', 'type', 'category_id', 'paid_by', 'payment_methods_id'));
                $date = date('Y-m-d', safe_strtotime($value[0]));
                if (!finance_guard_accounting_period($date, lang('import') . ' ' . lang('transaction'))) {
                    redirect('admin/transactions/import/' . $data['type']);
                    return;
                }
                $import_rows[] = array(
                    'date' => trim($date),
                    'amount' => trim($value[1]),
                    'notes' => trim($value[2]),
                    'reference' => trim($value[3]),
                    'account_id' => $data['account_id'],
                    'type' => $data['type'],
                    'category_id' => $data['category_id'],
                    'paid_by' => $data['paid_by'],
                    'payment_methods_id' => $data['payment_methods_id'],
                );
            }
        }

        $assigned_permission = permission_post();
        if (empty($assigned_permission)) {
            return;
        }
        foreach ($import_rows as $row) {
            $data = array(
                'name' => $this->input->post('name', true),
                'account_id' => $row['account_id'],
                'type' => $row['type'],
                'category_id' => $row['category_id'],
                'paid_by' => $row['paid_by'],
                'payment_methods_id' => $row['payment_methods_id'],
                'date' => $row['date'],
                'amount' => $row['amount'],
                'notes' => $row['notes'],
                'reference' => $row['reference'],
            );

            $data['amount'] = (float)preg_replace('/[^0-9.\-]/', '', str_replace(',', '.', (string)$data['amount']));
            if ($data['amount'] <= 0) {
                continue;
            }

            $account_info = $this->transactions_model->check_by(array('account_id' => $data['account_id']), 'tbl_accounts');
            if (empty($account_info)) {
                continue;
            }
            $account_balance = (float)$account_info->balance;
            if ($data['type'] == 'Income') {
                $ac_data['balance'] = $account_balance + $data['amount'];
            } else {
                $ac_data['balance'] = $account_balance - $data['amount'];
            }
            $this->transactions_model->_table_name = "tbl_accounts"; //table name
            $this->transactions_model->_primary_key = "account_id";
            $this->transactions_model->save($ac_data, $account_info->account_id);
            finance_sync_model()->sync_account_by_id($account_info->account_id);

            if (!empty($_FILES['attachement']['name']['0'])) {
                $old_path_info = $this->input->post('upload_path', true);
                if (!empty($old_path_info)) {
                    foreach ($old_path_info as $old_path) {
                        unlink($old_path);
                    }
                }
                $mul_val = $this->transactions_model->multi_uploadAllType('attachement');
                $data['attachement'] = json_encode($mul_val);
            }

            $data['permission'] = $assigned_permission;
            $this->transactions_model->_table_name = "tbl_transactions"; //table name
            $this->transactions_model->_primary_key = "transactions_id";
            $transaction_id = $this->transactions_model->save($data);
            if (!empty($transaction_id)) {
                finance_sync_model()->sync_transaction_by_id($transaction_id);
            }
        }
        $type = 'success';
        if ($data['type'] == 'Income') {
            $message = lang('save_new_deposit');
            $redirect = 'deposit';
        } else {
            $message = lang('save_new_expense');
            $redirect = 'expense';
        }

        set_message($type, $message);
        if (empty($_SERVER['HTTP_REFERER'])) {
            if (empty($redirect)) {
                $redirect = 'dashboard';
            } else {
                $redirect = 'transactions/' . $redirect;
            }
            redirect('admin/' . $redirect);
        } else {
            redirect($_SERVER['HTTP_REFERER']);
        }
    }

    public function save_deposit($id = NULL)
    {

        $created = can_action('30', 'created');
        $edited = can_action('30', 'edited');
        if (!empty($created) || !empty($edited) && !empty($id)) {
            $data = $this->transactions_model->array_from_post(array('transaction_prefix', 'name', 'account_id', 'date', 'tags', 'notes', 'category_id', 'paid_by', 'payment_methods_id', 'reference', 'project_id'));
            $data['tags'] = normalize_and_sync_tags($data['tags']);

            $data['type'] = 'Income';
            $data['amount'] = $this->input->post('amount', TRUE);
            $account_info = $this->transactions_model->check_by(array('account_id' => $data['account_id']), 'tbl_accounts');
            if (!empty($account_info)) {
                $account_info = $account_info;
            } else {
                $account_info = $this->db->get('tbl_accounts')->row();
            }
            if (!empty($data['amount'])) {
                if (!finance_guard_accounting_period($data['date'], lang('deposit'))) {
                    redirect('admin/transactions/deposit/' . $id);
                    return;
                }
                if (!empty($id)) {
                    $data['account_id'] = $this->input->post('old_account_id', TRUE);
                } else {
                    $data['amount'] = $this->input->post('amount', TRUE);
                    $data['credit'] = $this->input->post('amount', TRUE);
                    $ac_data['balance'] = $account_info->balance + $data['amount'];

                    $this->transactions_model->_table_name = "tbl_accounts"; //table name
                    $this->transactions_model->_primary_key = "account_id";
                    $this->transactions_model->save($ac_data, $account_info->account_id);
                    finance_sync_model()->sync_account_by_id($account_info->account_id);
                }
                $account_info = $this->transactions_model->check_by(array('account_id' => $data['account_id']), 'tbl_accounts');
                if (!empty($account_info)) {
                    $account_info = $account_info;
                } else {
                    $account_info = $this->db->get('tbl_accounts')->row();
                }
                $data['total_balance'] = $account_info->balance;

                $upload_file = array();

                $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,
                                );
                                array_push($upload_file, $up_data);
                            }
                        }
                    }
                }

                $fileName = $this->input->post('fileName', true);
                $path = $this->input->post('path', true);
                $fullPath = $this->input->post('fullPath', true);
                $size = $this->input->post('size', true);
                $is_image = $this->input->post('is_image', true);

                if (!empty($fileName)) {
                    foreach ($fileName as $key => $name) {
                        $old['fileName'] = $name;
                        $old['path'] = $path[$key];
                        $old['fullPath'] = $fullPath[$key];
                        $old['size'] = $size[$key];
                        $old['is_image'] = $is_image[$key];

                        array_push($upload_file, $old);
                    }
                }
                if (!empty($upload_file)) {
                    $data['attachement'] = json_encode($upload_file);
                } else {
                    $data['attachement'] = null;
                }

                $permission = $this->input->post('permission', true);
                if (!empty($permission)) {
                    if ($permission == 'everyone') {
                        $assigned = 'all';
                    } else {
                        $assigned_to = $this->transactions_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->transactions_model->_table_name = "tbl_transactions"; //table name
                $this->transactions_model->_primary_key = "transactions_id";


                if (!empty($id)) {
                    $this->transactions_model->save($data, $id);
                    finance_sync_model()->sync_transaction_by_id($id);
                    $activity = ('activity_update_deposit');
                    $msg = lang('update_a_deposit');
                    $description = 'not_deposit_update';
                    $not_value = lang('title') . ' ' . $data['name'] . ' ' . lang('date') . ' ' . display_date($data['date']);
                } else {
                    $id = $this->transactions_model->save($data);
                    finance_sync_model()->sync_transaction_by_id($id);
                    $activity = ('activity_new_deposit');
                    $description = 'not_deposit_saved';
                    $not_value = lang('account') . ' ' . $account_info->account_name . ' ' . lang('amount') . ' ' . display_money($data['amount']);
                    $msg = lang('save_new_deposit');
                    // send sms
                    $this->send_transactions_sms('deposit', $id);
                }
                save_custom_field(1, $id);

                // save into activities
                $activities = array(
                    'user' => $this->session->userdata('user_id'),
                    'module' => 'transactions',
                    'module_field_id' => $id,
                    'activity' => $activity,
                    'icon' => 'fa-building-o',
                    'link' => 'admin/transactions/view_details/' . $id,
                    'value1' => $account_info->account_name,
                );
                // Update into tbl_project
                $this->transactions_model->_table_name = "tbl_activities"; //table name
                $this->transactions_model->_primary_key = "activities_id";
                $this->transactions_model->save($activities);

                $designation_id = $this->session->userdata('designations_id');
                if (!empty($designation_id)) {
                    $designation_info = $this->transactions_model->check_by(array('designations_id' => $this->session->userdata('designations_id')), 'tbl_designations');
                }
                if (!empty($designation_info)) {
                    $dept_head = $this->transactions_model->check_by(array('departments_id' => $designation_info->departments_id), 'tbl_departments');
                }

                $check_head = $this->db->where('department_head_id', $this->session->userdata('user_id'))->get('tbl_departments')->row();
                $role = $this->session->userdata('user_type');
                if ($role == 3 && empty($check_head)) {
                    $this->deposit_email($data, $id);
                }

                // get departments head by departments id
                $all_admin = $this->db->where('role_id', 1)->get('tbl_users')->result();
                if (!empty($dept_head)) {
                    $head = $this->db->where('user_id', $dept_head->department_head_id)->get('tbl_users')->row();
                    array_push($all_admin, $head);
                }
                $notifyUser = array();
                if (!empty($all_admin)) {
                    foreach ($all_admin as $v_user) {
                        if (!empty($v_user)) {
                            if ($v_user->user_id != $this->session->userdata('user_id')) {
                                array_push($notifyUser, $v_user->user_id);
                                add_notification(array(
                                    'to_user_id' => $v_user->user_id,
                                    'icon' => 'building-o',
                                    'description' => $description,
                                    'link' => 'admin/transactions/view_details/' . $id,
                                    'value' => $not_value,
                                ));
                            }
                        }
                    }
                }
                if (!empty($notifyUser)) {
                    show_notification($notifyUser);
                }

                $type = 'success';
            } else {
                $type = 'error';
                $msg = 'please enter the amount';
            }
            set_message($type, $msg);
        }
        $project_id = $this->input->post('project_id', true);
        if (!empty($project_id) && is_numeric($project_id)) {
            redirect('admin/projects/project_details/' . $project_id . '/deposit');
        }
        redirect('admin/transactions/deposit/');
    }

    public function send_transactions_sms($type, $transaction_id)
    {
        $mobile = can_received_sms('transaction_record_sms_number');
        if (!empty($mobile)) {
            $merge_fields = [];
            $merge_fields = array_merge($merge_fields, merge_transactions_template($type, $transaction_id));
            $this->sms->send(SMS_TRANSACTION_RECORD, $mobile, $merge_fields);
        }
        return true;
    }

    public function bulk_delete_deposit()
    {
        $selected_id = $this->input->post('ids', true);
        if (!empty($selected_id)) {
            foreach ($selected_id as $id) {
                $result[] = $this->delete_deposit($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_deposit($id, $bulk = null)
    {
        $deleted = can_action('30', 'deleted');
        $can_delete = $this->transactions_model->can_action('tbl_transactions', 'delete', array('transactions_id' => $id));
        $deposit_info = $this->transactions_model->check_by(array('transactions_id' => $id), 'tbl_transactions');
        if (!empty($deposit_info)) {
            if (!empty($deleted) && !empty($can_delete)) {
                if (!finance_guard_accounting_period($deposit_info->date, lang('deposit'))) {
                    $type = 'error';
                    $msg = lang('accounting_period_closed');
                    if (!empty($bulk)) {
                        return array("status" => $type, 'message' => $msg);
                    }
                    echo json_encode(array("status" => $type, 'message' => $msg));
                    exit();
                }
                $account_info = $this->transactions_model->check_by(array('account_id' => $deposit_info->account_id), 'tbl_accounts');

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

                $activity = ('activity_delete_deposit');
                $msg = lang('delete_deposit');
                // save into activities
                $activities = array(
                    'user' => $this->session->userdata('user_id'),
                    'module' => 'transactions',
                    'module_field_id' => $id,
                    'activity' => $activity,
                    'icon' => 'fa-building-o',
                    'link' => 'admin/transactions/view_details/' . $id,
                    'value1' => $account_info->account_name,
                    'value2' => $deposit_info->amount,
                );
                // Update into tbl_project
                $this->transactions_model->_table_name = "tbl_activities"; //table name
                $this->transactions_model->_primary_key = "activities_id";
                $this->transactions_model->save($activities);

                $comments_info = $this->transactions_model->check_by(array('transactions_id' => $id), 'tbl_transactions');
                if (!empty($comments_info->attachment)) {
                    $attachment = json_decode($comments_info->attachment);
                    foreach ($attachment as $v_file) {
                        remove_files($v_file->fileName);
                    }
                }

                $this->transactions_model->_table_name = "tbl_transactions"; //table name
                $this->transactions_model->_primary_key = "transactions_id";
                $this->transactions_model->delete($id);
                finance_sync_model()->delete_transaction_by_id($id);

                $type = 'success';
            } else {
                $type = 'error';
                $msg = lang('there_in_no_value');
            }
        } else {
            $type = 'error';
            $msg = lang('there_in_no_value');
        }
        if (!empty($bulk)) {
            return (array("status" => $type, 'message' => $msg));
        }
        echo json_encode(array("status" => $type, 'message' => $msg));
        exit();
    }

    public function expense()
    {
        $data['title'] = lang('all_expense');
        $data['page_title'] = lang('all_expense');
        $data['page_description'] = lang('manage') . ' ' . lang('expense');
        $data['header_actions'] = array();
        if (!empty(can_action('31', 'created')) || !empty(can_action('31', 'edited'))) {
            $data['header_actions'][] = array(
                'label' => lang('new') . ' ' . lang('expense'),
                'icon' => 'plus',
                'href' => base_url('admin/transactions/create_expense'),
                'style' => 'primary',
            );
            $data['header_actions'][] = array(
                'label' => lang('import') . ' ' . lang('expense'),
                'icon' => 'upload',
                'href' => base_url('admin/transactions/import/Expense'),
                'style' => 'info',
            );
        }
        $expense_filter_items = array(
            array(
                'label' => lang('all') . ' ' . lang('expense'),
                'icon' => 'list-filter',
                'active' => true,
                'attrs' => array(
                    'data-expense-filter-action' => '1',
                    'data-expense-filter' => '',
                    'data-expense-search' => '',
                    'data-expense-filter-label' => lang('all') . ' ' . lang('expense'),
                ),
            ),
            array(
                'label' => lang('account'),
                'icon' => 'wallet',
                'divider_before' => true,
                'items' => array(
                    array(
                        'label' => lang('all') . ' ' . lang('account'),
                        'attrs' => array(
                            'data-expense-filter-action' => '1',
                            'data-expense-filter' => '',
                            'data-expense-search' => 'by_account',
                            'data-expense-filter-label' => lang('all') . ' ' . lang('account'),
                        ),
                    ),
                ),
                'lookup' => array(
                    'endpoint' => base_url('admin/common/account_lookup'),
                    'limit' => 12,
                    'min_length' => 0,
                    'action_attrs' => array(
                        'data-expense-filter-action' => '1',
                        'data-expense-search' => 'by_account',
                    ),
                    'filter_attr' => 'data-expense-filter',
                    'label_attr' => 'data-expense-filter-label',
                    'label_prefix' => lang('account') . ': ',
                    'placeholder' => lang('search') . ' ' . lang('account'),
                    'cache_key' => 'expense_account_lookup',
                ),
            ),
            array(
                'label' => lang('categories'),
                'icon' => 'tag',
                'items' => array(
                    array(
                        'label' => lang('all') . ' ' . lang('categories'),
                        'attrs' => array(
                            'data-expense-filter-action' => '1',
                            'data-expense-filter' => '',
                            'data-expense-search' => 'by_category',
                            'data-expense-filter-label' => lang('all') . ' ' . lang('categories'),
                        ),
                    ),
                ),
                'lookup' => array(
                    'endpoint' => base_url('admin/common/expense_category_lookup'),
                    'limit' => 12,
                    'min_length' => 0,
                    'action_attrs' => array(
                        'data-expense-filter-action' => '1',
                        'data-expense-search' => 'by_category',
                    ),
                    'filter_attr' => 'data-expense-filter',
                    'label_attr' => 'data-expense-filter-label',
                    'label_prefix' => lang('categories') . ': ',
                    'placeholder' => lang('search') . ' ' . lang('categories'),
                    'cache_key' => 'expense_category_lookup',
                ),
            ),
        );
        $data['header_filters'] = array(
            array(
                'label' => 'Filters',
                'icon' => 'sliders-horizontal',
                'selected_label' => lang('all'),
                'attrs' => array('id' => 'expense-header-filter'),
                'items' => $expense_filter_items,
            ),
        );
        $data['datatable_preload'] = $this->capture_datatable_preload(function () {
            $this->expenseList();
        });
        // get permission user by menu id
        $data['permission_user'] = $this->transactions_model->all_permission_user('31');
        $data['datatable'] = true;
        $data['active'] = 1;
        $data['subview'] = $this->load->view('admin/transactions/expense', $data, TRUE);
        $this->load->view('admin/_layout_main', $data); //page load
    }

    public function create_expense($id = NULL)
    {
        $data['title'] = lang('all_expense');
        $expense_info = null;
        // get permission user by menu id
        $data['permission_user'] = $this->transactions_model->all_permission_user('31');
        $data['expense_category_options'] = $this->build_select_options('tbl_expense_category', 'expense_category_id', 'expense_category');
        $data['payment_method_options'] = $this->build_select_options('tbl_payment_methods', 'payment_methods_id', 'method_name');
    

        if (!empty($id)) {
            $data['active'] = 2;
            if (is_numeric($id)) {
                $expense_info = $this->transactions_model->check_by(array('transactions_id' => $id), 'tbl_transactions');
                $can_edit = $this->transactions_model->can_action('tbl_transactions', 'edit', array('transactions_id' => $id));
                if (!empty($expense_info) && !empty($can_edit)) {
                    $data['expense_info'] = $expense_info;
                }
            } else {
                $data['active'] = 1;
                if ($id == 'project_expense') {
                    $data['active'] = 2;
                    $project_id = $this->uri->segment(5);
                    $project_info = get_row('tbl_project', array('project_id' => $project_id));
                    if ($project_info->permission == 'all') {
                        $data['permission_user'] = $this->transactions_model->allowed_user('57');
                    } else {
                        $data['permission_user'] = $this->transactions_model->permitted_allowed_user($project_info->permission);
                    }
                } elseif ($id == 'client_expense') {
                    $data['active'] = 2;
                    $data['selected_paid_by_id'] = $this->uri->segment(5);
                }
            }
        } else {
            $data['active'] = 2;
        }
        $data['selected_paid_by_id'] = !empty($expense_info->paid_by) ? $expense_info->paid_by : (!empty($data['selected_paid_by_id']) ? $data['selected_paid_by_id'] : '');
        $data['selected_paid_by_label'] = '';
        if (!empty($data['selected_paid_by_id'])) {
            $paid_by = $this->db->where('client_id', $data['selected_paid_by_id'])->get('tbl_client')->row();
            $data['selected_paid_by_label'] = !empty($paid_by->name) ? $paid_by->name : '';
        }
        $data['selected_project_id'] = !empty($expense_info->project_id) ? $expense_info->project_id : ($id == 'project_expense' ? ($this->uri->segment(5) ?? '') : '');
        $data['selected_project_label'] = '';
        if (!empty($data['selected_project_id'])) {
            $project = $this->db->where('project_id', $data['selected_project_id'])->get('tbl_project')->row();
            $data['selected_project_label'] = !empty($project->project_name) ? $project->project_name : '';
            if (!empty($project->client_id)) {
                $client = $this->db->where('client_id', $project->client_id)->get('tbl_client')->row();
                if (!empty($client)) {
                    $data['project_client_id'] = $project->client_id;
                    $data['project_client_label'] = $client->name;
                }
            }
        }
        $data['selected_account_label'] = '';
        if (!empty($expense_info->account_id)) {
            $account = $this->db->where('account_id', $expense_info->account_id)->get('tbl_accounts')->row();
            $data['selected_account_label'] = !empty($account->account_name) ? $account->account_name : '';
        }
        if (empty($expense_info)) {
            $this->load->helper('string');
            $prefix = '';
            if (empty(config_item('expense_number_format'))) {
                $prefix = (string) config_item('expense_prefix') . random_string('nozero', 6);
            }
            $data['transaction_prefix_default'] = $prefix . $this->transactions_model->generate_transactions_number('Expense');
        }
        $data['dropzone'] = true;        
        $data['subview'] = $this->load->view('admin/transactions/create_expense', $data, TRUE);
        $this->load->view('admin/_layout_main', $data); //page load
    }


    public function expenseList($filterBy = null, $type = null)
    {
        if ($this->input->is_ajax_request()) {
            $this->load->model('datatables');
            $this->datatables->table = 'tbl_transactions';
            $this->datatables->join_table = array('tbl_accounts');
            $this->datatables->join_where = array('tbl_accounts.account_id=tbl_transactions.account_id');
            $custom_field = custom_form_table_search(2);
            $action_array = array('transactions_id');
            $main_column = array('transactions_id', 'transaction_prefix', 'tbl_transactions.name', 'date', 'amount', 'notes', 'tbl_accounts.account_name', 'tags', 'status', 'reference');
            $result = array_merge($main_column, $custom_field, $action_array);
            $this->datatables->column_order = $result;
            $this->datatables->column_search = $result;

            $this->datatables->order = array('transactions_id' => 'desc');
            $where = null;
            if (empty($type)) {
                $where = array('type' => 'Expense');
            }
            if ($type == 'by_account') {
                $where = array('type' => 'Expense', 'tbl_transactions.account_id' => $filterBy);
            } else if ($type == 'by_category') {
                $where = array('type' => 'Expense', 'category_id' => $filterBy);
            }
            // get all invoice
            $fetch_data = $this->datatables->get_expense($filterBy, $type);

            $data = array();

            $edited = can_action('31', 'edited');
            $deleted = can_action('31', 'deleted');
            foreach ($fetch_data as $_key => $v_expense) {
                $action = null;
                $can_edit = $this->transactions_model->can_action('tbl_transactions', 'edit', array('transactions_id' => $v_expense->transactions_id));
                $can_delete = $this->transactions_model->can_action('tbl_transactions', 'delete', array('transactions_id' => $v_expense->transactions_id));
                $account_info = $this->transactions_model->check_by(array('account_id' => $v_expense->account_id), 'tbl_accounts');
                $recurring = null;
                if ($v_expense->recurring == 'Yes') {
                    $recurring = '<span data-toggle="tooltip" data-placement="top"
                                                              title="' . lang("recurring") . '"
                                                              class="label label-primary"><i
                                                                data-lucide="repeat"></i></span>';
                }
                $sub_array = array();
                if (!empty($edited) || !empty($deleted)) {
                    $sub_array[] = '<div class="checkbox c-checkbox" ><label class="needsclick"> <input value="' . $v_expense->transactions_id . '" type="checkbox"></label></div>';
                }
                $transaction_prefix = null;
                $transaction_prefix .= '<a class="text-blue-600 hover:text-blue-900 dark:text-blue-400 dark:hover:text-blue-300" href="' . base_url() . 'admin/transactions/view_details/' . $v_expense->transactions_id . '">' . (!empty($v_expense->transaction_prefix) ? $v_expense->transaction_prefix : ' ') . '</a>';
                $sub_array[] = $transaction_prefix;

                $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/transactions/view_details/' . $v_expense->transactions_id . '">' . (!empty($v_expense->name) ? $v_expense->name : '-') . '</a>';
                $sub_array[] = $name;

                $date = null;
                $date .= '<a class="text-blue-600 hover:text-blue-900 dark:text-blue-400 dark:hover:text-blue-300" href="' . base_url() . 'admin/transactions/view_details/' . $v_expense->transactions_id . '">' . display_date($v_expense->date) . '</a>';
                $sub_array[] = $date;

                $account_label = !empty($account_info->account_name) ? $account_info->account_name : '-';
                $sub_array[] = '<span class="inline-flex items-center rounded-full border border-border px-2 py-0.5 text-xs font-semibold text-foreground">' . html_escape($account_label) . '</span>';
                $sub_array[] = display_money($v_expense->amount, default_currency());
                $sub_array[] = get_tags($v_expense->tags, true);
                $status = $v_expense->status;
                $text = '';
                if ($v_expense->project_id != 0) {
                    if ($v_expense->billable == 'No') {
                        $status = 'not_billable';
                        $label = 'primary';
                        $title = lang('not_billable');
                        $e_action = '';
                    } else {
                        $status = 'billable';
                        $label = 'success';
                        $title = lang('billable');
                        $e_action = '';
                        if ($v_expense->invoices_id != 0 && !empty(get_row('tbl_invoices', array('invoices_id' => $v_expense->invoices_id)))) {
                            $payment_status = $this->invoice_model->get_payment_status($v_expense->invoices_id);
                            $text = '<a href="' . base_url() . 'admin/invoice/manage_invoice/invoice_details/' . $v_expense->invoices_id . '"> <p class="text-sm m0 p0"><span class="text-dark">' . lang('invoiced') . '</span><span class="text-danger">' . ' ' . $payment_status . '</span></p></a>';
                        } else {
                            $text = '<p class="text-sm m0 p0"><span class="text-danger">' . lang('not_invoiced') . '</span></p>';
                        }
                    }
                } else {
                    if ($v_expense->status == 'non_approved') {
                        $label = 'danger';
                        $title = lang('get_approved');
                        $e_action = 'approved';
                    } elseif ($v_expense->status == 'unpaid') {
                        $label = 'warning';
                        $title = lang('get_paid');
                        $e_action = 'paid';
                    } else {
                        $label = 'success';
                        $title = '';
                        $e_action = '';
                    }
                }
                $check_head = $this->db->where('department_head_id', $this->session->userdata('user_id'))->get('tbl_departments')->row();
                $role = $this->session->userdata('user_type');
                $status_map = array(
                    'success' => 'bg-emerald-100 text-emerald-700',
                    'warning' => 'bg-amber-100 text-amber-700',
                    'danger' => 'bg-rose-100 text-rose-700',
                    'primary' => 'bg-sky-100 text-sky-700',
                    'default' => 'bg-slate-100 text-slate-700',
                );
                $badge_class = isset($status_map[$label]) ? $status_map[$label] : $status_map['default'];
                $badge = '<span class="inline-flex items-center rounded-full px-2 py-0.5 text-xs font-semibold ' . $badge_class . '">' . lang($status) . '</span>';
                if (!empty($recurring)) {
                    $badge .= ' <span class="ml-2 inline-flex items-center rounded-full border border-border px-2 py-0.5 text-xs font-semibold text-muted-foreground">' . $recurring . '</span>';
                }
                if (!empty($text)) {
                    $badge .= '<div class="mt-1 text-xs text-muted-foreground">' . $text . '</div>';
                }
                if ($role == 1 || !empty($check_head)) {
                    $status_link = !empty($e_action) ? base_url() . 'admin/transactions/set_status/' . $e_action . '/' . $v_expense->transactions_id : '#';
                    $sub_array[] = '<a data-toggle="tooltip" data-placement="top" title="' . $title . '" class="inline-flex items-center" href="' . $status_link . '">' . $badge . '</a>';
                } else {
                    $sub_array[] = $badge;
                }

                $custom_form_table = custom_form_table(2, $v_expense->transactions_id);
                if (!empty($custom_form_table)) {
                    foreach ($custom_form_table as $c_label => $v_fields) {
                        $sub_array[] = $v_fields;
                    }
                }
                $attachment = null;
                $attachment_info = !empty($v_expense->attachement) ? json_decode($v_expense->attachement) : array();
                if (!empty($attachment_info)) {
                    $attachment = '<a href="' . base_url() . 'admin/transactions/download/' . $v_expense->transactions_id . '">' . lang('download') . '</a>';
                }
                $sub_array[] = $attachment;

                $action .= '<a class="btn btn-info btn-xs inline-flex h-7 w-8 items-center justify-center rounded-lg border-0 p-0 shadow-sm transition hover:opacity-90 focus:outline-none focus:ring-2 focus:ring-sky-400 focus:ring-offset-1"  href="' . base_url() . 'admin/transactions/view_details/' . $v_expense->transactions_id . '"><span data-lucide="list" class="h-4 w-4"></span></a>' . ' ';
                if (!empty($edited)) {
                    $action .= btn_edit('admin/transactions/create_expense/' . $v_expense->transactions_id) . ' ';
                }
                if (!empty($deleted)) {
                    $action .= ajax_anchor(base_url("admin/transactions/delete_expense/$v_expense->transactions_id"), lang('delete'), array("class" => "", "title" => lang('delete'), "data-fade-out-on-success" => "#table_" . $_key)) . ' ';
                }
                $sub_array[] = $action;
                $data[] = $sub_array;
            }
            render_table($data, $where);
        } else {
            redirect('admin/dashboard');
        }
    }


    public function transactions_state_report()
    {
        if (!$this->input->is_ajax_request()) {
            redirect('admin/dashboard');
        }
        $mdate = date('Y-m-d');
        $last_7_days = date('Y-m-d', safe_strtotime('today - 7 days'));
        $data['daily_series'] = $this->finance_report_model->get_transaction_daily_series('Expense', $last_7_days, $mdate);
        $pathonor_jonno['transactions_state_report_div'] = $this->load->view("admin/transactions/transactions_state_report", $data, true);
        echo json_encode($pathonor_jonno);
        exit;
    }

    public function save_expense($id = NULL)
    {
        $created = can_action('31', 'created');
        $edited = can_action('31', 'edited');
        if (!empty($created) || !empty($edited) && !empty($id)) {
            $data = $this->transactions_model->array_from_post(array(
                'transaction_prefix', 'name', 'date', 'notes', 'category_id', 'paid_by', 'tags', 'payment_methods_id', 'reference', 'project_id', 'billable', 'client_visible',
                'repeat_every', 'total_cycles', 'done_cycles'
            ));
            $data['tags'] = normalize_and_sync_tags($data['tags']);
            if (empty($data['repeat_every'])) {
                $data['repeat_every'] = null;
            }
            $repeat_every_custom = $this->input->post('repeat_every_custom', true);
            $repeat_type_custom = $this->input->post('repeat_type_custom', true);
            // Recurring expense set to NO, Cancelled
            if ($data['repeat_every'] == '') {
                $data['total_cycles'] = 0;
                $data['done_cycles'] = 0;
                $data['last_recurring_date'] = null;
            }
            if (isset($data['repeat_every']) && $data['repeat_every'] != '') {
                $data['recurring'] = 'Yes';
                if ($data['repeat_every'] == 'custom') {
                    $data['repeat_every'] = $repeat_every_custom;
                    $data['recurring_type'] = $repeat_type_custom;
                    $data['custom_recurring'] = 1;
                } else {
                    $_temp = explode('_', $data['repeat_every']);
                    $data['recurring_type'] = $_temp[1];
                    $data['repeat_every'] = $_temp[0];
                    $data['custom_recurring'] = 0;
                }
            } else {
                $data['recurring'] = 'No';
            }
            $data['total_cycles'] = !isset($data['total_cycles']) || $data['recurring'] == 'No' ? 0 : $data['total_cycles'];

            $data['type'] = 'Expense';
            if (empty($data['client_visible'])) {
                $data['client_visible'] = 'No';
            }
            if (empty($data['billable'])) {
                $data['billable'] = 'No';
            }
            $data['account_id'] = $this->input->post('account_id', TRUE);

            $account_info = $this->transactions_model->check_by(array('account_id' => $data['account_id']), 'tbl_accounts');
            if (!empty($account_info)) {
                $account_info = $account_info;
            } else {
                $account_info = $this->db->get('tbl_accounts')->row();
            }
            save_custom_field(2, $id);
            if (!finance_guard_accounting_period($data['date'], lang('expense'))) {
                redirect('admin/transactions/expense/' . $id);
                return;
            }

            $data['amount'] = $this->input->post('amount', TRUE);

            if (!empty($data['amount'])) {
                $check_head = $this->db->where('department_head_id', $this->session->userdata('user_id'))->get('tbl_departments')->row();
                $role = $this->session->userdata('user_type');
                if ($role == 1 || !empty($check_head)) {
                    if (!empty($id)) {
                        $data['account_id'] = $this->input->post('old_account_id', TRUE);
                    } else {
                        $data['amount'] = $this->input->post('amount', TRUE);
                        $data['debit'] = $this->input->post('amount', TRUE);

                        $ac_data['balance'] = $account_info->balance - $data['amount'];
                        $this->transactions_model->_table_name = "tbl_accounts"; //table name
                        $this->transactions_model->_primary_key = "account_id";
                        $this->transactions_model->save($ac_data, $account_info->account_id);
                        finance_sync_model()->sync_account_by_id($account_info->account_id);
                    }

                    $account_info = $this->transactions_model->check_by(array('account_id' => $data['account_id']), 'tbl_accounts');
                    if (!empty($account_info)) {
                        $account_info = $account_info;
                    } else {
                        $account_info = $this->db->get('tbl_accounts')->row();
                    }
                    $data['total_balance'] = $account_info->balance;
                    $data['status'] = 'paid';
                }

                $upload_file = array();
                $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,
                                );
                                array_push($upload_file, $up_data);
                            }
                        }
                    }
                }

                $fileName = $this->input->post('fileName', true);
                $path = $this->input->post('path', true);
                $fullPath = $this->input->post('fullPath', true);
                $size = $this->input->post('size', true);
                $is_image = $this->input->post('is_image', true);

                if (!empty($fileName)) {
                    foreach ($fileName as $key => $name) {
                        $old['fileName'] = $name;
                        $old['path'] = $path[$key];
                        $old['fullPath'] = $fullPath[$key];
                        $old['size'] = $size[$key];
                        $old['is_image'] = $is_image[$key];

                        array_push($upload_file, $old);
                    }
                }
                if (!empty($upload_file)) {
                    $data['attachement'] = json_encode($upload_file);
                } else {
                    $data['attachement'] = null;
                }

                $permission = $this->input->post('permission', true);
                if (!empty($permission)) {
                    if ($permission == 'everyone') {
                        $assigned = 'all';
                    } else {
                        $assigned_to = $this->transactions_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;
                } else {
                    set_message('error', lang('assigned_to') . ' Field is required');
                    if (empty($_SERVER['HTTP_REFERER'])) {
                        redirect('admin/transactions/expense');
                    } else {
                        redirect($_SERVER['HTTP_REFERER']);
                    }
                }


                $this->transactions_model->_table_name = "tbl_transactions"; //table name
                $this->transactions_model->_primary_key = "transactions_id";


                if (!empty($id)) {
                    $this->transactions_model->save($data, $id);
                    finance_sync_model()->sync_transaction_by_id($id);
                    $activity = ('activity_update_expense');
                    $msg = lang('update_a_expense');
                    $description = 'not_expense_update';
                    $not_value = lang('title') . ' ' . $data['name'] . ' ' . lang('date') . ' ' . display_date($data['date']);
                } else {
                    $data['added_by'] = $this->session->userdata('user_id');
                    $id = $this->transactions_model->save($data);
                    finance_sync_model()->sync_transaction_by_id($id);
                    // send sms
                    $this->send_transactions_sms('expense', $id);
                    $activity = ('activity_new_expense');
                    $msg = lang('save_new_expense');
                    $description = 'not_expense_saved';
                    $not_value = lang('account') . ': ' . $account_info->account_name . ' ' . lang('amount') . ': ' . display_money($data['amount']);
                }
                save_custom_field(2, $id);
                // save into activities
                $activities = array(
                    'user' => $this->session->userdata('user_id'),
                    'module' => 'transactions',
                    'module_field_id' => $id,
                    'activity' => $activity,
                    'icon' => 'fa-building-o',
                    'link' => 'admin/transactions/view_details/' . $id,
                    'value1' => $account_info->account_name,
                    'value2' => $data['amount'],
                );
                // Update into tbl_project
                $this->transactions_model->_table_name = "tbl_activities"; //table name
                $this->transactions_model->_primary_key = "activities_id";
                $this->transactions_model->save($activities);
                $type = 'success';
                if ($role == 3 && empty($check_head)) {
                    $this->expense_request_email($data, $id);
                }
                $designation_id = $this->session->userdata('designations_id');
                if (!empty($designation_id)) {
                    $designation_info = $this->transactions_model->check_by(array('designations_id' => $this->session->userdata('designations_id')), 'tbl_designations');
                }
                if (!empty($designation_info)) {
                    $dept_head = $this->transactions_model->check_by(array('departments_id' => $designation_info->departments_id), 'tbl_departments');
                }
                // get departments head by departments id
                $all_admin = $this->db->where('role_id', 1)->get('tbl_users')->result();
                if (!empty($dept_head)) {
                    $head = $this->db->where('user_id', $dept_head->department_head_id)->get('tbl_users')->row();
                    array_push($all_admin, $head);
                }

                $notifyUser = array();
                if (!empty($all_admin)) {
                    foreach ($all_admin as $v_user) {
                        if (!empty($v_user)) {
                            if ($v_user->user_id != $this->session->userdata('user_id')) {
                                array_push($notifyUser, $v_user->user_id);
                                add_notification(array(
                                    'to_user_id' => $v_user->user_id,
                                    'icon' => 'building-o',
                                    'description' => $description,
                                    'link' => 'admin/transactions/view_details/' . $id,
                                    'value' => $not_value,
                                ));
                            }
                        }
                    }
                }
                if (!empty($notifyUser)) {
                    show_notification($notifyUser);
                }
            } else {
                $type = 'error';
                $msg = 'please enter the amount';
            }
            $message = $msg;
            set_message($type, $message);
        }
        if (!empty($data['project_id']) && is_numeric($data['project_id'])) {
            redirect('admin/projects/project_details/' . $data['project_id'] . '/' . 'expense');
        } else {
            redirect('admin/transactions/expense');
        }
    }

    public function categories($type = null)
    {
        $data['title'] = lang('categories');
        if ($type == 'income') {
            $data['category'] = 'income_category';
        } else {
            $data['category'] = 'expense_category';
        }
        $data['type'] = $type;
        $data['subview'] = $this->load->view('admin/transactions/categories', $data, FALSE);
    }

    public function update_categories($type)
    {
        if ($type == 'income') {
            $category = 'income_category';
        } else {
            $category = 'expense_category';
        }
        $this->transactions_model->_table_name = 'tbl_' . $category;
        $this->transactions_model->_primary_key = $category . '_id';


        $cate_data[$category] = $this->input->post('categories', TRUE);
        $cate_data['description'] = $this->input->post('description', TRUE);

        // update root category
        $where = array($category => $cate_data[$category]);
        // duplicate value check in DB
        if (!empty($id)) { // if id exist in db update data
            $expense_category_id = array($category . '_id !=' => $id);
        } else { // if id is not exist then set id as null
            $expense_category_id = null;
        }
        // check whether this input data already exist or not
        $check_category = $this->transactions_model->check_update('tbl_' . $category, $where, $expense_category_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[$category] . '</strong>  ' . lang('already_exist');
        } else { // save and update query
            $id = $this->transactions_model->save($cate_data);

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

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

    public function view_expense($id)
    {
        $data['expense_info'] = $this->db->where('transactions_id', $id)->get('tbl_transactions')->row();

        if (!empty($data['expense_info']) && $data['expense_info']->type == 'Income') {
            $type = lang('deposit');
            $data['permission_user'] = $this->transactions_model->all_permission_user('30');
            $subview = 'view_deposit';
            $data['title'] = $type . ' ' . lang('details');
            $data['subview'] = $this->load->view('admin/transactions/' . $subview, $data, FALSE);
        } else {
            $type = lang('expense');
            $data['permission_user'] = $this->transactions_model->all_permission_user('31');
            $subview = 'view_expense';
            $data['module'] = 'transactions';
            if (empty($active)) {
                $data['active'] = 'details';
            } else {
                $data['active'] = $active;
            }
            $data['id'] = $id;
            $data['all_tabs'] = transactions_details_tabs($id);
            $data['title'] = $type . ' ' . lang('details');
            $data['subview'] = $this->load->view('admin/common/tab_view', $data, TRUE);
            $this->load->view('admin/_layout_main', $data);
        }
    }

    public function view_details($id, $active = null)
    {
        $data['expense_info'] = $this->db->where('transactions_id', $id)->get('tbl_transactions')->row();
        // $data['title'] = $type . ' ' . lang('details');
        $data['title'] = lang('transactions');

        if (empty($active)) {
            $data['active'] = 'details';
        } else {
            $data['active'] = $active;
        }
        $data['all_tabs'] = transactions_details_tabs($id);
        $data['module'] = 'transactions';
        $data['id'] = $id;
        $is_income = !empty($data['expense_info']->type) && $data['expense_info']->type === 'Income';
        $is_transfer = !empty($data['expense_info']->type) && $data['expense_info']->type === 'Transfer';
        $transaction_label = $is_transfer ? lang('transfer') : ($is_income ? lang('deposit') : lang('expense'));
        $transaction_reference = !empty($data['expense_info']->reference) ? $data['expense_info']->reference : (!empty($data['expense_info']->transaction_prefix) ? $data['expense_info']->transaction_prefix : ('#' . $id));
        $data['page_title'] = !empty($data['expense_info']->name) ? $data['expense_info']->name : ($transaction_label . ' ' . lang('details'));
        $data['page_description'] = $transaction_label . ' . ' . display_date($data['expense_info']->date) . ' . ' . lang('amount') . ': ' . display_money($data['expense_info']->amount, default_currency());
        $data['header_badge'] = array(
            'label' => $transaction_reference,
            'tone' => $is_income ? 'success' : ($is_transfer ? 'warning' : 'primary'),
        );
        $data['header_actions'] = array();
        if ($is_transfer) {
            $data['header_actions'][] = array(
                'label' => lang('edit'),
                'icon' => 'pencil',
                'href' => base_url('admin/transactions/create_transfer/' . $data['expense_info']->transfer_id),
            );
        } else {
            $data['header_actions'][] = array(
                'label' => lang('edit'),
                'icon' => 'pencil',
                'href' => base_url($is_income ? 'admin/transactions/create_deposit/' . $data['expense_info']->transactions_id : 'admin/transactions/create_expense/' . $data['expense_info']->transactions_id),
            );
        }
        if (!$is_income && $data['expense_info']->billable == 'Yes' && $data['expense_info']->project_id != 0 && $data['expense_info']->invoices_id == 0) {
            $confirm_message = 'Are you sure to ' . lang('convert') . ' This ' . (!empty($data['expense_info']->name) ? $data['expense_info']->name : '-') . ' ?';
            $data['header_actions'][] = array(
                'label' => lang('convert_to_invoice'),
                'icon' => 'file-up',
                'href' => base_url('admin/transactions/convert/' . $data['expense_info']->transactions_id),
                'style' => 'success',
                'attrs' => array(
                    'onclick' => 'return confirm(' . json_encode($confirm_message) . ')',
                ),
            );
        }
        $data['header_actions'][] = array(
            'label' => lang('pdf'),
            'icon' => 'file-text',
            'href' => base_url('admin/transactions/download_pdf/' . $data['expense_info']->transactions_id),
        );
        $transaction_tab_labels = array(
            'details' => lang('details'),
            'tasks' => lang('tasks'),
            'reminder' => lang('reminder'),
        );
        $transaction_filter_items = array();
        foreach ($data['all_tabs'] as $tab) {
            if (empty($tab['name']) || empty($tab['url'])) {
                continue;
            }
            $transaction_filter_items[] = array(
                'label' => isset($transaction_tab_labels[$tab['name']]) ? $transaction_tab_labels[$tab['name']] : ucfirst(str_replace('_', ' ', $tab['name'])),
                'icon' => !empty($tab['icon']) ? $tab['icon'] : 'chevron-right',
                'href' => base_url($tab['url']),
                'active' => $data['active'] === $tab['name'],
                'meta' => isset($tab['count']) && $tab['count'] !== '' ? (string) $tab['count'] : null,
            );
        }
        $data['header_filters'] = array(
            array(
                'label' => lang('more_actions'),
                'icon' => 'ellipsis',
                'active' => true,
                'items' => $transaction_filter_items,
            ),
        );
        $data['subview'] = $this->load->view('admin/common/tab_view', $data, TRUE);
        $this->load->view('admin/_layout_main', $data);
    }

    function deposit_email($data, $id)
    {
        // get departments head user id
        $designation_info = $this->transactions_model->check_by(array('designations_id' => $this->session->userdata('designations_id')), 'tbl_designations');
        // get departments head by departments id
        $dept_head = $this->transactions_model->check_by(array('departments_id' => $designation_info->departments_id), 'tbl_departments');
        $all_admin = $this->db->where('role_id', 1)->get('tbl_users')->result();
        $head = $this->db->where('user_id', $dept_head->department_head_id)->get('tbl_users')->row();
        $account_info = $this->transactions_model->check_by(array('account_id' => $data['account_id']), 'tbl_accounts');

        if (!empty($dept_head->department_head_id) || !empty($all_admin)) {
            $deposit_email = config_item('deposit_email');
            if (!empty($deposit_email) && $deposit_email == 1) {
                $email_template = email_templates(array('email_group' => 'deposit_email'));
                if (!empty($email_template)) {
                    $message = $email_template->template_body;
                    $subject = $email_template->subject;
                    $username = str_replace("{NAME}", $this->session->userdata('name'), $message);
                    $amount = str_replace("{AMOUNT}", $data['amount'], $username);
                    $account = str_replace("{ACCOUNT}", $account_info->account_name, $amount);
                    $balance = str_replace("{BALANCE}", $account_info->balance, $account);
                    $Link = str_replace("{URL}", base_url() . 'admin/transactions/view_details/' . $id, $balance);
                    $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($all_admin)) {
                        foreach ($all_admin as $v_admin) {
                            if (!empty($v_admin)) {
                                $params['recipient'] = $v_admin->email;
                                $this->transactions_model->send_email($params);
                                if (!empty($dept_head->department_head_id)) {
                                    if ($dept_head->department_head_id == $v_admin->user_id) {
                                        $already_send = 1;
                                    }
                                }
                            }
                        }
                    }
                    if (empty($already_send) && !empty($head->email)) {
                        $params['recipient'] = $head->email;
                        $this->transactions_model->send_email($params);
                    }
                }
            } else {
                return true;
            }
        }
    }

    function expense_request_email($data, $id)
    {
        // get departments head user id
        $designation_info = $this->transactions_model->check_by(array('designations_id' => $this->session->userdata('designations_id')), 'tbl_designations');
        // get departments head by departments id
        if (!empty($designation_info)) {
            $dept_head = $this->transactions_model->check_by(array('departments_id' => $designation_info->departments_id), 'tbl_departments');
            $head = $this->db->where('user_id', $dept_head->department_head_id)->get('tbl_users')->row();
        }
        $all_admin = $this->db->where('role_id', 1)->get('tbl_users')->result();

        if (!empty($dept_head->department_head_id) || !empty($all_admin)) {
            $expense_email = config_item('expense_email');
            if (!empty($expense_email) && $expense_email == 1) {
                $email_template = email_templates(array('email_group' => 'expense_request_email'));
                if (!empty($email_template)) {
                    $message = $email_template->template_body;
                    $subject = $email_template->subject;
                    $username = str_replace("{NAME}", $this->session->userdata('name'), $message);
                    $amount = str_replace("{AMOUNT}", $data['amount'], $username);
                    $Link = str_replace("{URL}", base_url() . 'admin/transactions/view_details/' . $id, $amount);
                    $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($all_admin)) {
                        foreach ($all_admin as $v_admin) {
                            if (!empty($v_admin)) {
                                $params['recipient'] = $v_admin->email;
                                $this->transactions_model->send_email($params);
                                if (!empty($dept_head->department_head_id)) {
                                    if ($dept_head->department_head_id == $v_admin->user_id) {
                                        $already_send = 1;
                                    }
                                }
                            }
                        }
                    }
                    if (empty($already_send) && !empty($head->email)) {
                        $params['recipient'] = $head->email;
                        $this->transactions_model->send_email($params);
                    }
                }
            } else {
                return true;
            }
        }
    }

    public function bulk_delete_expense()
    {
        $selected_id = $this->input->post('ids', true);
        if (!empty($selected_id)) {
            foreach ($selected_id as $id) {
                $result[] = $this->delete_expense($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_expense($id, $bulk = null)
    {
        $deleted = can_action('31', 'deleted');
        $expense_info = $this->transactions_model->check_by(array('transactions_id' => $id), 'tbl_transactions');
        if (!empty($expense_info))
            $can_delete = $this->transactions_model->can_action('tbl_transactions', 'delete', array('transactions_id' => $id));
        if (!empty($deleted) && !empty($can_delete)) {
            if (!finance_guard_accounting_period($expense_info->date, lang('expense'))) {
                $type = 'error';
                $msg = lang('accounting_period_closed');
                if (!empty($bulk)) {
                    return array("status" => $type, 'message' => $msg);
                }
                echo json_encode(array("status" => $type, 'message' => $msg));
                exit();
            }
            $account_info = $this->transactions_model->check_by(array('account_id' => $expense_info->account_id), 'tbl_accounts');

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

            $activity = ('activity_delete_expense');
            $msg = lang('delete_expense');
            // save into activities
            $activities = array(
                'user' => $this->session->userdata('user_id'),
                'module' => 'transactions',
                'module_field_id' => $id,
                'activity' => $activity,
                'icon' => 'fa-building-o',
                'link' => 'admin/transactions/view_details/' . $id,
                'value1' => $account_info->account_name,
                'value2' => $expense_info->amount,
            );
            // Update into tbl_project
            $this->transactions_model->_table_name = "tbl_activities"; //table name
            $this->transactions_model->_primary_key = "activities_id";
            $this->transactions_model->save($activities);

            $comments_info = $this->transactions_model->check_by(array('transactions_id' => $id), 'tbl_transactions');
            if (!empty($comments_info->attachment)) {
                $attachment = json_decode($comments_info->attachment);
                foreach ($attachment as $v_file) {
                    remove_files($v_file->fileName);
                }
            }
            $this->transactions_model->_table_name = "tbl_transactions"; //table name
            $this->transactions_model->_primary_key = "transactions_id";
            $this->transactions_model->delete($id);
            finance_sync_model()->delete_transaction_by_id($id);


            $type = 'success';
        } else {
            $type = 'error';
            $msg = lang('there_in_no_value');
        }
        if (!empty($bulk)) {
            return (array("status" => $type, 'message' => $msg));
        }
        echo json_encode(array("status" => $type, 'message' => $msg));
        exit();
    }


    public function transfer($id = NULL)
    {
        $data['title'] = lang('transfer');
		$data['page_title'] = lang('transfer');
		$data['page_description'] = lang('manage') . ' ' . lang('transfer');
		$data['header_actions'] = array();
		if (!empty(can_action('30', 'created')) || !empty(can_action('30', 'edited'))) {
			$data['header_actions'][] = array(
				'label' => lang('new') . ' ' . lang('transfer'),
				'icon' => 'plus',
				'href' => base_url('admin/transactions/create_transfer'),
				'style' => 'primary',
			);
			$data['header_actions'][] = array(
				'label' => lang('import') . ' ' . lang('transfer'),
				'icon' => 'upload',
				'href' => base_url('admin/transactions/import/Transfer'),
				'style' => 'info',
			);
		}
		$transfer_filter_items = array(
			array(
				'label' => lang('all') . ' ' . lang('transfer'),
				'icon' => 'list-filter',
				'active' => true,
				'attrs' => array(
					'data-transfer-filter-action' => '1',
					'data-transfer-filter' => '',
					'data-transfer-search' => '',
					'data-transfer-filter-label' => lang('all') . ' ' . lang('transfer'),
				),
			),
			array(
				'label' => lang('from_account'),
				'icon' => 'arrow-up-right',
				'divider_before' => true,
				'items' => array(
					array(
						'label' => lang('all') . ' ' . lang('from_account'),
						'attrs' => array(
							'data-transfer-filter-action' => '1',
							'data-transfer-filter' => '',
							'data-transfer-search' => 'from_account',
							'data-transfer-filter-label' => lang('all') . ' ' . lang('from_account'),
						),
					),
				),
				'lookup' => array(
					'endpoint' => base_url('admin/common/account_lookup'),
					'limit' => 12,
					'min_length' => 0,
					'action_attrs' => array(
						'data-transfer-filter-action' => '1',
						'data-transfer-search' => 'from_account',
					),
					'filter_attr' => 'data-transfer-filter',
					'label_attr' => 'data-transfer-filter-label',
					'label_prefix' => lang('from_account') . ': ',
					'placeholder' => lang('search') . ' ' . lang('from_account'),
					'cache_key' => 'transfer_from_account_lookup',
				),
			),
			array(
				'label' => lang('to_account'),
				'icon' => 'arrow-down-left',
				'items' => array(
					array(
						'label' => lang('all') . ' ' . lang('to_account'),
						'attrs' => array(
							'data-transfer-filter-action' => '1',
							'data-transfer-filter' => '',
							'data-transfer-search' => 'to_account',
							'data-transfer-filter-label' => lang('all') . ' ' . lang('to_account'),
						),
					),
				),
				'lookup' => array(
					'endpoint' => base_url('admin/common/account_lookup'),
					'limit' => 12,
					'min_length' => 0,
					'action_attrs' => array(
						'data-transfer-filter-action' => '1',
						'data-transfer-search' => 'to_account',
					),
					'filter_attr' => 'data-transfer-filter',
					'label_attr' => 'data-transfer-filter-label',
					'label_prefix' => lang('to_account') . ': ',
					'placeholder' => lang('search') . ' ' . lang('to_account'),
					'cache_key' => 'transfer_to_account_lookup',
				),
			),
		);
		$data['header_filters'] = array(
			array(
				'label' => 'Filters',
				'icon' => 'sliders-horizontal',
				'selected_label' => lang('all'),
				'attrs' => array('id' => 'transfer-header-filter'),
				'items' => $transfer_filter_items,
			),
		);
		$data['dataTables'] = true;
        $transfer_info = null;
        // get permission user by menu id
        $data['permission_user'] = $this->transactions_model->all_permission_user('32');
        $data['payment_method_options'] = $this->build_select_options('tbl_payment_methods', 'payment_methods_id', 'method_name');
        if (!empty($id)) {
            $transfer_info = $this->transactions_model->check_by(array('transfer_id' => $id), 'tbl_transfer');
            if (!empty($transfer_info))
                $can_edit = $this->transactions_model->can_action('tbl_transfer', 'edit', array('transfer_id' => $id));
            $data['active'] = 2;
            if (!empty($can_edit)) {
                $data['transfer_info'] = $transfer_info;
            }
        } else {
            $data['active'] = 1;
        }
        $data['selected_from_account_label'] = '';
        $data['selected_to_account_label'] = '';
        if (!empty($transfer_info->from_account_id)) {
            $from_account = $this->db->where('account_id', $transfer_info->from_account_id)->get('tbl_accounts')->row();
            $data['selected_from_account_label'] = !empty($from_account->account_name) ? $from_account->account_name : '';
        }
        if (!empty($transfer_info->to_account_id)) {
            $to_account = $this->db->where('account_id', $transfer_info->to_account_id)->get('tbl_accounts')->row();
            $data['selected_to_account_label'] = !empty($to_account->account_name) ? $to_account->account_name : '';
        }
        $data['dropzone'] = true;
        $data['subview'] = $this->load->view('admin/transactions/transfer', $data, TRUE);
        $this->load->view('admin/_layout_main', $data); //page load
    }

    public function create_transfer($id = NULL)
    {
        $data['title'] = lang('transfer');
        $transfer_info = null;
        // get permission user by menu id
        $data['permission_user'] = $this->transactions_model->all_permission_user('32');
        $data['payment_method_options'] = $this->build_select_options('tbl_payment_methods', 'payment_methods_id', 'method_name');
        if (!empty($id)) {
            $transfer_info = $this->transactions_model->check_by(array('transfer_id' => $id), 'tbl_transfer');
            if (!empty($transfer_info))
                $can_edit = $this->transactions_model->can_action('tbl_transfer', 'edit', array('transfer_id' => $id));
            $data['active'] = 2;
            if (!empty($can_edit)) {
                $data['transfer_info'] = $transfer_info;
            }
        }
        $data['active'] = 2;
        $data['selected_from_account_label'] = '';
        $data['selected_to_account_label'] = '';
        if (!empty($transfer_info->from_account_id)) {
            $from_account = $this->db->where('account_id', $transfer_info->from_account_id)->get('tbl_accounts')->row();
            $data['selected_from_account_label'] = !empty($from_account->account_name) ? $from_account->account_name : '';
        }
        if (!empty($transfer_info->to_account_id)) {
            $to_account = $this->db->where('account_id', $transfer_info->to_account_id)->get('tbl_accounts')->row();
            $data['selected_to_account_label'] = !empty($to_account->account_name) ? $to_account->account_name : '';
        }
        $data['dropzone'] = true;
        $data['subview'] = $this->load->view('admin/transactions/create_transfer', $data, TRUE);
        $this->load->view('admin/_layout_main', $data); //page load
    }

    public function transferList($filterBy = null, $type = null)
    {
        if ($this->input->is_ajax_request()) {
            $this->load->model('datatables');
            $this->datatables->table = 'tbl_transfer';
            $this->datatables->join_table = array('tbl_accounts');
            $this->datatables->join_where = array('tbl_accounts.account_id=tbl_transfer.from_account_id');
            $this->datatables->column_order = array('tbl_accounts.account_name', 'date', 'amount', 'payment_methods_id');
            $this->datatables->column_search = array('tbl_accounts.account_name', 'tbl_accounts.account_name', 'amount', 'date', 'payment_methods_id');
            $this->datatables->order = array('transfer_id' => 'desc');

            $where = null;
            if ($type == 'to_account') {
                $where = array('to_account_id' => $filterBy);
            } else if ($type == 'from_account') {
                $where = array('from_account_id' => $filterBy);
            }
            $fetch_data = make_datatables($where);

            $data = array();

            $edited = can_action('30', 'edited');
            $deleted = can_action('30', 'deleted');
            foreach ($fetch_data as $_key => $v_transfer) {
                $action = null;
                $can_edit = $this->transactions_model->can_action('tbl_transfer', 'edit', array('transfer_id' => $v_transfer->transfer_id));
                $can_delete = $this->transactions_model->can_action('tbl_transfer', 'delete', array('transfer_id' => $v_transfer->transfer_id));

                $to_account_info = $this->transactions_model->check_by(array('account_id' => $v_transfer->to_account_id), 'tbl_accounts');
                $from_account_info = $this->transactions_model->check_by(array('account_id' => $v_transfer->from_account_id), 'tbl_accounts');

                $sub_array = array();
                $from_label = !empty($from_account_info->account_name) ? $from_account_info->account_name : '-';
                $to_label = !empty($to_account_info->account_name) ? $to_account_info->account_name : '-';
                $sub_array[] = '<span class="inline-flex items-center rounded-full border border-border px-2 py-0.5 text-xs font-semibold text-foreground">' . html_escape($from_label) . '</span>';
                $sub_array[] = '<span class="inline-flex items-center rounded-full border border-border px-2 py-0.5 text-xs font-semibold text-foreground">' . html_escape($to_label) . '</span>';

                $sub_array[] = display_money($v_transfer->amount, default_currency());

                $sub_array[] = display_date($v_transfer->date);

                $attachment = null;
                $attachment_info = !empty($v_transfer->attachement) ? json_decode($v_transfer->attachement) : null;
                if (!empty($attachment_info)) {
                    $attachment = '<a href="' . base_url() . 'admin/transactions/download_transfer/' . $v_transfer->transfer_id . '">' . lang('download') . '</a>';
                }
                $sub_array[] = $attachment;

                if (!empty($can_edit) && !empty($edited)) {
                    $action .= btn_edit('admin/transactions/create_transfer/' . $v_transfer->transfer_id) . ' ';
                }
                if (!empty($can_delete) && !empty($deleted)) {
                    $action .= ajax_anchor(base_url("admin/transactions/delete_transfer/$v_transfer->transfer_id"), lang('delete'), array("class" => "", "title" => lang('delete'), "data-fade-out-on-success" => "#table_" . $_key)) . ' ';
                }
                $sub_array[] = $action;
                $data[] = $sub_array;
            }
            render_table($data, $where);
        } else {
            redirect('admin/dashboard');
        }
    }

    public function save_transfer($id = NULL)
    {
        $created = can_action('32', 'created');
        $edited = can_action('32', 'edited');
        if (!empty($created) || !empty($edited) && !empty($id)) {
            if (!empty($id)) {
                $to_account_id = $this->input->post('old_to_account_id', TRUE);
                $from_account_id = $this->input->post('old_from_account_id', TRUE);
                $amount = $this->input->post('old_amount', TRUE);
                $transaction_id = $this->db->select('transactions_id')->where(array('transfer_id' => $id))->get('tbl_transactions')->result();
            } else {
                $to_account_id = $this->input->post('to_account_id', TRUE);
                $from_account_id = $this->input->post('from_account_id', TRUE);
                $amount = $this->input->post('amount', TRUE);
            }
            if (!empty($transaction_id[0]->transactions_id)) {
                $transaction_id_1 = $transaction_id[0]->transactions_id;
            } else {
                $transaction_id_1 = null;
            }
            if (!empty($transaction_id[1]->transactions_id)) {
                $transaction_id_2 = $transaction_id[1]->transactions_id;
            } else {
                $transaction_id_2 = null;
            }
            if ($to_account_id == $from_account_id) {
                $type = 'error';
                $msg = lang('same_account_error');
            } else {
                $from_acc_info = $this->transactions_model->check_by(array('account_id' => $from_account_id), 'tbl_accounts');
                $to_acc_info = $this->transactions_model->check_by(array('account_id' => $to_account_id), 'tbl_accounts');
                //                if ($amount > $from_acc_info->balance) {
                //                    $type = 'error';
                //                    $msg = lang('amount_exceed_error') . ' <strong style=color:#000> ' . $from_acc_info->balance . '</strong> !';
                //                } else {
                $transfer_data = $this->transactions_model->array_from_post(array('date', 'notes', 'payment_methods_id', 'reference'));
                if (!finance_guard_accounting_period($transfer_data['date'], lang('transfer'))) {
                    redirect('admin/transactions/transfer/' . $id);
                    return;
                }
                if (empty($id)) {
                    $ac_data['balance'] = $from_acc_info->balance - $amount;

                    $this->transactions_model->_table_name = "tbl_accounts"; //table name
                    $this->transactions_model->_primary_key = "account_id";
                    $this->transactions_model->save($ac_data, $from_acc_info->account_id);
                    finance_sync_model()->sync_account_by_id($from_acc_info->account_id);

                    $froma_data['balance'] = $to_acc_info->balance + $amount;
                    $this->transactions_model->_table_name = "tbl_accounts"; //table name
                    $this->transactions_model->_primary_key = "account_id";
                    $this->transactions_model->save($froma_data, $to_acc_info->account_id);
                    finance_sync_model()->sync_account_by_id($to_acc_info->account_id);

                    $transfer_data['to_account_id'] = $to_account_id;
                    $transfer_data['from_account_id'] = $from_account_id;
                    $transfer_data['amount'] = $amount;
                }

                // save into tbl_transfer
                $transfer_data['type'] = 'Transfer';

                $upload_file = array();
                $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,
                                );
                                array_push($upload_file, $up_data);
                            }
                        }
                    }
                }

                $fileName = $this->input->post('fileName', true);
                $path = $this->input->post('path', true);
                $fullPath = $this->input->post('fullPath', true);
                $size = $this->input->post('size', true);
                $is_image = $this->input->post('is_image', true);

                if (!empty($fileName)) {
                    foreach ($fileName as $key => $name) {
                        $old['fileName'] = $name;
                        $old['path'] = $path[$key];
                        $old['fullPath'] = $fullPath[$key];
                        $old['size'] = $size[$key];
                        $old['is_image'] = $is_image[$key];

                        array_push($upload_file, $old);
                    }
                }
                if (!empty($upload_file)) {
                    $transfer_data['attachement'] = json_encode($upload_file);
                } else {
                    $transfer_data['attachement'] = null;
                }

                $permission = $this->input->post('permission', true);
                if (!empty($permission)) {
                    if ($permission == 'everyone') {
                        $assigned = 'all';
                    } else {
                        $assigned_to = $this->transactions_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';
                    }
                    $transfer_data['permission'] = $assigned;
                } else {
                    set_message('error', lang('assigned_to') . ' Field is required');
                    if (empty($_SERVER['HTTP_REFERER'])) {
                        redirect('admin/transactions/transfer');
                    } else {
                        redirect($_SERVER['HTTP_REFERER']);
                    }
                }

                $this->transactions_model->_table_name = "tbl_transfer"; //table name
                $this->transactions_model->_primary_key = "transfer_id";
                $transfer_id = $this->transactions_model->save($transfer_data, $id);
                finance_sync_model()->sync_transfer_by_id($transfer_id);

                $from_acc_info = $this->transactions_model->check_by(array('account_id' => $from_account_id), 'tbl_accounts');
                $to_acc_info = $this->transactions_model->check_by(array('account_id' => $to_account_id), 'tbl_accounts');

                // save into tbl_tansactions
                $to_data = $this->transactions_model->array_from_post(array('date', 'notes', 'payment_methods_id', 'reference'));
                $to_data['type'] = 'Transfer';
                if (empty($id)) {
                    $to_data['account_id'] = $to_account_id;
                    $to_data['amount'] = $amount;
                    $to_data['credit'] = $amount;
                    $to_data['total_balance'] = $to_acc_info->balance;
                }
                $to_data['transfer_id'] = $transfer_id;

                $this->transactions_model->_table_name = "tbl_transactions"; //table name
                $this->transactions_model->_primary_key = "transactions_id";
                $this->transactions_model->save($to_data, $transaction_id_1);
                if (!empty($transaction_id_1)) {
                    finance_sync_model()->sync_transaction_by_id($transaction_id_1);
                }

                // save into tbl_tansactions
                $from_data = $this->transactions_model->array_from_post(array('date', 'notes', 'payment_methods_id', 'reference'));
                $from_data['type'] = 'Transfer';
                $from_data['account_id'] = $from_account_id;
                if (empty($id)) {
                    $from_data['amount'] = $amount;
                    $from_data['debit'] = $amount;
                    $from_data['total_balance'] = $from_acc_info->balance;
                }
                $from_data['transfer_id'] = $transfer_id;

                $this->transactions_model->_table_name = "tbl_transactions"; //table name
                $this->transactions_model->_primary_key = "transactions_id";
                $this->transactions_model->save($from_data, $transaction_id_2);
                if (!empty($transaction_id_2)) {
                    finance_sync_model()->sync_transaction_by_id($transaction_id_2);
                }

                $type = 'success';
                if (!empty($id)) {
                    $activity = ('activity_update_transfer');
                    $msg = lang('update_a_transfer');
                    $description = 'not_update_transfer';
                } else {
                    // send sms
                    $this->send_transactions_sms('transfer', $id);
                    $activity = ('activity_new_transfer');
                    $msg = lang('save_new_transfer');
                    $description = 'not_new_transfer';
                }
                // save into activities
                $activities = array(
                    'user' => $this->session->userdata('user_id'),
                    'module' => 'transactions',
                    'module_field_id' => $id,
                    'activity' => $activity,
                    'icon' => 'fa-building-o',
                    'link' => 'admin/transactions/transfer',
                    'value1' => $from_acc_info->account_name,
                    'value2' => $to_acc_info->account_name,
                );
                // Update into tbl_project
                $this->transactions_model->_table_name = "tbl_activities"; //table name
                $this->transactions_model->_primary_key = "activities_id";
                $this->transactions_model->save($activities);


                // get departments head user id
                $designation_info = $this->transactions_model->check_by(array('designations_id' => $this->session->userdata('designations_id')), 'tbl_designations');
                if (!empty($designation_info)) {
                    $dept_head = $this->transactions_model->check_by(array('departments_id' => $designation_info->departments_id), 'tbl_departments');
                }
                // get departments head by departments id
                $all_admin = $this->db->where('role_id', 1)->get('tbl_users')->result();
                if (!empty($dept_head)) {
                    $head = $this->db->where('user_id', $dept_head->department_head_id)->get('tbl_users')->row();
                    array_push($all_admin, $head);
                }
                $notifyUser = array();
                if (!empty($all_admin)) {
                    foreach ($all_admin as $v_user) {
                        if (!empty($v_user)) {
                            if ($v_user->user_id != $this->session->userdata('user_id')) {
                                array_push($notifyUser, $v_user->user_id);
                                add_notification(array(
                                    'to_user_id' => $v_user->user_id,
                                    'icon' => 'building-o',
                                    'description' => $description,
                                    'link' => 'admin/transactions/transfer',
                                    'value' => lang('amount') . ' ' . display_money($amount) . ' ' . lang('from_account') . $from_acc_info->account_name . ' ' . lang('to_account') . ' ' . $to_acc_info->account_name,
                                ));
                            }
                        }
                    }
                }
                if (!empty($notifyUser)) {
                    show_notification($notifyUser);
                }
                //                }
            }

            $message = $msg;
            set_message($type, $message);
        }
        redirect('admin/transactions/transfer');
    }

    public function delete_transfer($id)
    {
        $deleted = can_action('31', 'deleted');
        $can_delete = $this->transactions_model->can_action('tbl_transfer', 'delete', array('transfer_id' => $id));
        if (!empty($deleted) && !empty($can_delete)) {
            $transfer_info = $this->transactions_model->check_by(array('transfer_id' => $id), 'tbl_transfer');
            if (!finance_guard_accounting_period($transfer_info->date, lang('transfer'))) {
                $type = 'error';
                $msg = lang('accounting_period_closed');
                echo json_encode(array("status" => $type, 'message' => $msg));
                exit();
            }
            $from_acc_info = $this->transactions_model->check_by(array('account_id' => $transfer_info->to_account_id), 'tbl_accounts');
            $to_acc_info = $this->transactions_model->check_by(array('account_id' => $transfer_info->from_account_id), 'tbl_accounts');

            $ac_data['balance'] = $from_acc_info->balance - $transfer_info->amount;
            $this->transactions_model->_table_name = "tbl_accounts"; //table name
            $this->transactions_model->_primary_key = "account_id";
            $this->transactions_model->save($ac_data, $from_acc_info->account_id);

            $froma_data['balance'] = $to_acc_info->balance + $transfer_info->amount;
            $this->transactions_model->_table_name = "tbl_accounts"; //table name
            $this->transactions_model->_primary_key = "account_id";
            $this->transactions_model->save($froma_data, $to_acc_info->account_id);

            $comments_info = $this->transactions_model->check_by(array('transactions_id' => $id), 'tbl_transactions');
            if (!empty($comments_info->attachment)) {
                $attachment = json_decode($comments_info->attachment);
                foreach ($attachment as $v_file) {
                    remove_files($v_file->fileName);
                }
            }

            $this->transactions_model->_table_name = "tbl_transfer"; //table name
            $this->transactions_model->_primary_key = "transfer_id";
            $this->transactions_model->delete($id);
            finance_sync_model()->delete_transfer_by_id($id);

            $this->transactions_model->_table_name = "tbl_transactions"; //table name
            $this->transactions_model->delete_multiple(array('transfer_id' => $id));

            $activity = ('activity_delete_transfer');
            $msg = lang('delete_transfer');

            // save into activities
            $activities = array(
                'user' => $this->session->userdata('user_id'),
                'module' => 'transactions',
                'module_field_id' => $id,
                'activity' => $activity,
                'icon' => 'fa-building-o',
                'value1' => $from_acc_info->account_name,
                'value2' => $to_acc_info->account_name,
            );
            // Update into tbl_project
            $this->transactions_model->_table_name = "tbl_activities"; //table name
            $this->transactions_model->_primary_key = "activities_id";
            $this->transactions_model->save($activities);

            $type = 'success';
        } else {
            $type = 'error';
            $msg = lang('there_in_no_value');
        }
        echo json_encode(array("status" => $type, 'message' => $msg));
        exit();
        //        $message = $msg;
        //        set_message($type, $message);
        //        redirect('admin/transactions/transfer/');
    }

    public function transactions_report($id = null)
    {
		$data['dataTables'] = true;
        $data['title'] = lang('transactions_report');
        $data['page_title'] = lang('transactions_report');
        $data['page_description'] = lang('manage') . ' ' . lang('transactions_report');
        $data['header_actions'] = array(
            array(
                'label' => lang('pdf'),
                'icon' => 'file-text',
                'href' => base_url('admin/transactions/transactions_report_pdf'),
                'style' => 'info',
            ),
            array(
                'label' => lang('print'),
                'icon' => 'printer',
                'style' => 'primary',
                'attrs' => array(
                    'onclick' => "print_sales_report('printReport')",
                ),
            ),
        );
        $data['header_filters'] = array(
            array(
                'label' => 'Filters',
                'icon' => 'sliders-horizontal',
                'selected_label' => lang('all'),
                'attrs' => array('id' => 'transactions-report-header-filter'),
                'items' => array(
                    array(
                        'label' => lang('all') . ' ' . lang('account'),
                        'icon' => 'wallet',
                        'active' => true,
                        'attrs' => array(
                            'data-transactions-report-filter-action' => '1',
                            'data-transactions-report-filter' => '',
                            'data-transactions-report-filter-label' => lang('all') . ' ' . lang('account'),
                        ),
                    ),
                    array(
                        'label' => lang('account'),
                        'icon' => 'wallet',
                        'divider_before' => true,
                        'items' => array(
                            array(
                                'label' => lang('all') . ' ' . lang('account'),
                                'attrs' => array(
                                    'data-transactions-report-filter-action' => '1',
                                    'data-transactions-report-filter' => '',
                                    'data-transactions-report-filter-label' => lang('all') . ' ' . lang('account'),
                                ),
                            ),
                        ),
                        'lookup' => array(
                            'endpoint' => base_url('admin/common/account_lookup'),
                            'limit' => 12,
                            'min_length' => 0,
                            'action_attrs' => array(
                                'data-transactions-report-filter-action' => '1',
                            ),
                            'filter_attr' => 'data-transactions-report-filter',
                            'label_attr' => 'data-transactions-report-filter-label',
                            'label_prefix' => lang('account') . ': ',
                            'placeholder' => lang('search') . ' ' . lang('account'),
                            'cache_key' => 'transactions_report_account_lookup',
                        ),
                    ),
                ),
            ),
        );
        $data['transactions_report'] = $this->get_transactions_report();
        $data['transactions_report_print_html'] = $this->load->view('admin/transactions/transactions_report_pdf', $data, TRUE);
        $data['subview'] = $this->load->view('admin/transactions/transactions_report', $data, TRUE);
        $this->load->view('admin/_layout_main', $data); //page load
    }

    public function transactions_reportList($filterBy = null)
    {
        if ($this->input->is_ajax_request()) {
            $this->load->model('datatables');
            $this->datatables->table = 'tbl_transactions';
            $this->datatables->join_table = array('tbl_accounts');
            $this->datatables->join_where = array('tbl_accounts.account_id=tbl_transactions.account_id');
            $this->datatables->column_order = array('date', 'tbl_accounts.account_name', 'journal_id', 'type', 'name', 'amount', 'credit', 'debit', 'total_balance');
            $this->datatables->column_search = array('date', 'tbl_accounts.account_name', 'journal_id', 'type', 'name', 'amount', 'credit', 'debit', 'total_balance');
            $this->datatables->order = array('transactions_id' => 'desc');
            $where = null;
            if (!empty($filterBy)) {
                $where = array('tbl_transactions.account_id' => $filterBy);
            }
            // get all invoice
            $fetch_data = $this->datatables->get_transactions_report($filterBy);

            $data = array();

            $total_amount = 0;
            $total_debit = 0;
            $total_credit = 0;
            $total_balance = 0;
            foreach ($fetch_data as $_key => $v_transaction) {
                $action = null;
                $account_info = $this->transactions_model->check_by(array('account_id' => $v_transaction->account_id), 'tbl_accounts');

                $sub_array = array();
                $sub_array[] = display_date($v_transaction->date);
                $sub_array[] = (!empty($account_info->account_name) ? $account_info->account_name : '-');
                $sub_array[] = !empty($v_transaction->journal_id) ? '<a href="' . base_url('admin/accounting/view_journal_entry/' . $v_transaction->journal_id) . '" class="text-primary hover:underline">' . html_escape($v_transaction->journal_id) . '</a>' : '-';
                $sub_array[] = lang($v_transaction->type);
                $sub_array[] = (!empty($v_transaction->name) ? $v_transaction->name : '-');

                $sub_array[] = display_money($v_transaction->amount, default_currency());
                $sub_array[] = display_money($v_transaction->credit, default_currency());
                $sub_array[] = display_money($v_transaction->debit, default_currency());
                $sub_array[] = display_money($v_transaction->total_balance, default_currency());

                $data[] = $sub_array;

                $total_amount += $v_transaction->amount;
                $total_credit += $v_transaction->credit;
                $total_debit += $v_transaction->debit;
            }
            render_table($data, $where);
        } else {
            redirect('admin/dashboard');
        }
    }

    public function get_transactions_report()
    { // this function is to create get monthy recap report
        $month = date('Y-m');
        $start_date = $month . '-01';
        $end_date = date('Y-m-t');
        $num = (int) date('t');
        $transaction_report = array_fill(1, $num, array());
        $rows = $this->db
            ->where('date >=', $start_date)
            ->where('date <=', $end_date)
            ->order_by('transactions_id', 'DESC')
            ->get('tbl_transactions')
            ->result();

        foreach ($rows as $row) {
            $day = (int) date('j', safe_strtotime($row->date));
            $transaction_report[$day][] = $row;
        }
        return $transaction_report; // return the result
    }

    public function transactions_report_pdf()
    {
        $data['title'] = lang('transactions_report');
        $this->load->helper('dompdf');
        $viewfile = $this->load->view('admin/transactions/transactions_report_pdf', $data, TRUE);
        pdf_create($viewfile, slug_it(lang('transactions_report')));
    }

    public function transfer_report()
    {
		$data['dataTables'] = true;
        $data['title'] = lang('transfer_report');
        $data['page_title'] = lang('transfer_report');
        $data['page_description'] = lang('manage') . ' ' . lang('transfer_report');
        $data['header_actions'] = array(
            array(
                'label' => lang('pdf'),
                'icon' => 'file-text',
                'href' => base_url('admin/transactions/transfer_report_pdf'),
                'style' => 'info',
            ),
            array(
                'label' => lang('print'),
                'icon' => 'printer',
                'style' => 'primary',
                'attrs' => array(
                    'onclick' => "print_sales_report('printReport')",
                ),
            ),
        );
        $data['header_filters'] = array(
            array(
                'label' => 'Filters',
                'icon' => 'sliders-horizontal',
                'selected_label' => lang('all'),
                'attrs' => array('id' => 'transfer-report-header-filter'),
                'items' => array(
                    array(
                        'label' => lang('all') . ' ' . lang('transfer'),
                        'icon' => 'arrow-right-left',
                        'active' => true,
                        'attrs' => array(
                            'data-transfer-report-filter-action' => '1',
                            'data-transfer-report-filter' => '',
                            'data-transfer-report-search' => '',
                            'data-transfer-report-filter-label' => lang('all') . ' ' . lang('transfer'),
                        ),
                    ),
                    array(
                        'label' => lang('from_account'),
                        'icon' => 'arrow-up-right',
                        'divider_before' => true,
                        'items' => array(
                            array(
                                'label' => lang('all') . ' ' . lang('from_account'),
                                'attrs' => array(
                                    'data-transfer-report-filter-action' => '1',
                                    'data-transfer-report-filter' => '',
                                    'data-transfer-report-search' => 'from_account',
                                    'data-transfer-report-filter-label' => lang('all') . ' ' . lang('from_account'),
                                ),
                            ),
                        ),
                        'lookup' => array(
                            'endpoint' => base_url('admin/common/account_lookup'),
                            'limit' => 12,
                            'min_length' => 0,
                            'action_attrs' => array(
                                'data-transfer-report-filter-action' => '1',
                                'data-transfer-report-search' => 'from_account',
                            ),
                            'filter_attr' => 'data-transfer-report-filter',
                            'label_attr' => 'data-transfer-report-filter-label',
                            'label_prefix' => lang('from_account') . ': ',
                            'placeholder' => lang('search') . ' ' . lang('from_account'),
                            'cache_key' => 'transfer_report_from_account_lookup',
                        ),
                    ),
                    array(
                        'label' => lang('to_account'),
                        'icon' => 'arrow-down-left',
                        'items' => array(
                            array(
                                'label' => lang('all') . ' ' . lang('to_account'),
                                'attrs' => array(
                                    'data-transfer-report-filter-action' => '1',
                                    'data-transfer-report-filter' => '',
                                    'data-transfer-report-search' => 'to_account',
                                    'data-transfer-report-filter-label' => lang('all') . ' ' . lang('to_account'),
                                ),
                            ),
                        ),
                        'lookup' => array(
                            'endpoint' => base_url('admin/common/account_lookup'),
                            'limit' => 12,
                            'min_length' => 0,
                            'action_attrs' => array(
                                'data-transfer-report-filter-action' => '1',
                                'data-transfer-report-search' => 'to_account',
                            ),
                            'filter_attr' => 'data-transfer-report-filter',
                            'label_attr' => 'data-transfer-report-filter-label',
                            'label_prefix' => lang('to_account') . ': ',
                            'placeholder' => lang('search') . ' ' . lang('to_account'),
                            'cache_key' => 'transfer_report_to_account_lookup',
                        ),
                    ),
                ),
            ),
        );
        $data['transfer_report_print_html'] = $this->load->view('admin/transactions/transfer_report_pdf', $data, TRUE);
        $data['subview'] = $this->load->view('admin/transactions/transfer_report', $data, TRUE);
        $this->load->view('admin/_layout_main', $data); //page load
    }

    public function transfer_reportList($filterBy = null, $type = null)
    {
        if ($this->input->is_ajax_request()) {
            $this->load->model('datatables');
            $this->datatables->table = 'tbl_transfer';
            $this->datatables->join_table = array('tbl_accounts');
            $this->datatables->join_where = array('tbl_accounts.account_id=tbl_transfer.from_account_id');
            $this->datatables->column_order = array('tbl_accounts.account_name', 'date', 'amount', 'payment_methods_id');
            $this->datatables->column_search = array('tbl_accounts.account_name', 'date', 'amount', 'payment_methods_id');
            $this->datatables->order = array('transfer_id' => 'desc');
            $where = null;
            if ($type == 'to_account') {
                $where = array('to_account_id' => $filterBy);
            } else if ($type == 'from_account') {
                $where = array('from_account_id' => $filterBy);
            }
            // get all invoice
            $fetch_data = $this->datatables->get_transfer($filterBy, $type);

            $data = array();

            $edited = can_action('30', 'edited');
            $deleted = can_action('30', 'deleted');
            foreach ($fetch_data as $_key => $v_transfer) {
                $action = null;
                $can_edit = $this->transactions_model->can_action('tbl_transfer', 'edit', array('transfer_id' => $v_transfer->transfer_id));
                $can_delete = $this->transactions_model->can_action('tbl_transfer', 'delete', array('transfer_id' => $v_transfer->transfer_id));

                $to_account_info = $this->transactions_model->check_by(array('account_id' => $v_transfer->to_account_id), 'tbl_accounts');
                $from_account_info = $this->transactions_model->check_by(array('account_id' => $v_transfer->from_account_id), 'tbl_accounts');

                $sub_array = array();
                $sub_array[] = display_date($v_transfer->date);
                $sub_array[] = (!empty($from_account_info->account_name) ? $from_account_info->account_name : '-');
                $sub_array[] = (!empty($from_account_info->account_name) ? $to_account_info->account_name : '-');
                $sub_array[] = $v_transfer->type;

                $sub_array[] = display_money($v_transfer->amount, default_currency());

                $data[] = $sub_array;
            }
            render_table($data, $where);
        } else {
            redirect('admin/dashboard');
        }
    }

    public function transfer_report_pdf()
    {
        $data['title'] = lang('transfer_report');
        $this->load->helper('dompdf');
        $viewfile = $this->load->view('admin/transactions/transfer_report_pdf', $data, TRUE);
        pdf_create($viewfile, slug_it(lang('transfer_report')));
    }

    public function balance_sheet()
    {
        $data['title'] = lang('balance_sheet');
        $data['page_title'] = lang('balance_sheet');
        $data['page_description'] = lang('manage') . ' ' . lang('balance_sheet');
        $data['header_actions'] = array(
            array(
                'label' => lang('pdf'),
                'icon' => 'file-text',
                'href' => base_url('admin/transactions/balance_sheet_pdf'),
                'style' => 'info',
            ),
            array(
                'label' => lang('print'),
                'icon' => 'printer',
                'style' => 'primary',
                'attrs' => array(
                    'onclick' => "print_sales_report('printReport')",
                ),
            ),
        );
        $data['header_filters'] = array();
        $data['datatable'] = true;
        $data = array_merge($data, $this->get_balance_sheet_summary());
        $data = array_merge($data, $this->get_balance_sheet_pdf_data());
        $data['balance_sheet_print_html'] = $this->load->view('admin/transactions/balance_sheet_pdf', $data, TRUE);
        $data['subview'] = $this->load->view('admin/transactions/balance_sheet', $data, TRUE);
        $this->load->view('admin/_layout_main', $data); //page load
    }

    public function balance_sheet_list()
    {
        if (!$this->input->is_ajax_request()) {
            redirect('admin/dashboard');
        }

        $this->load->model('datatables');
        $this->datatables->table = 'tbl_accounts';
        $this->datatables->column_order = array('account_name', 'balance', null);
        $this->datatables->column_search = array('account_name');
        $this->datatables->order = array('account_name' => 'ASC');

        $length = (int) $this->input->post('length', true);
        $start = (int) $this->input->post('start', true);
        $draw = (int) $this->input->post('draw', true);
        $search = $this->input->post('search');
        $search_value = is_array($search) && isset($search['value']) ? trim($search['value']) : '';

        if ($length <= 0) {
            $length = 25;
        }

        $fetch_data = $this->datatables->get_rows(null, null, $length, $start);
        $records_total = $this->datatables->count_all();
        $records_filtered = $search_value === '' ? $records_total : $this->datatables->count_filtered();

        $currency_symbol = default_currency();
        $data = array();
        foreach ($fetch_data as $row) {
            $balance = (float) $row->balance;
            $status_class = $balance >= 0
                ? 'bg-emerald-500/10 text-emerald-600 dark:text-emerald-300'
                : 'bg-rose-500/10 text-rose-600 dark:text-rose-300';

            $data[] = array(
                '<div class="font-medium text-foreground">' . html_escape($row->account_name) . '</div>',
                '<div class="text-right font-semibold text-foreground">' . display_money($balance, $currency_symbol) . '</div>',
                '<div class="text-right"><span class="inline-flex items-center rounded-full px-2.5 py-1 text-[11px] font-semibold ' . $status_class . '">' . ($balance >= 0 ? 'Positive' : 'Negative') . '</span></div>',
            );
        }

        echo json_encode(array(
            'draw' => $draw ?: 1,
            'recordsTotal' => $records_total,
            'recordsFiltered' => $records_filtered,
            'data' => $data,
        ));
        exit();
    }

    public function balance_sheet_pdf()
    {
        $data['title'] = lang('balance_sheet') . ' ' . lang('pdf');
        $data = array_merge($data, $this->get_balance_sheet_summary());
        $data = array_merge($data, $this->get_balance_sheet_pdf_data());
        $this->load->helper('dompdf');
        $viewfile = $this->load->view('admin/transactions/balance_sheet_pdf', $data, TRUE);
        pdf_create($viewfile, slug_it(lang('balance_sheet')));
    }

    private function get_balance_sheet_pdf_data()
    {
        $pdf_account_limit = 600;
        $total_accounts = (int) $this->db->count_all('tbl_accounts');
        $pdf_truncated = $total_accounts > $pdf_account_limit;

        if ($pdf_truncated) {
            $all_account = $this->db
                ->select('account_name, balance')
                ->order_by('ABS(balance)', 'DESC', false)
                ->limit($pdf_account_limit)
                ->get('tbl_accounts')
                ->result();
        } else {
            $all_account = $this->db
                ->select('account_name, balance')
                ->order_by('account_name', 'ASC')
                ->get('tbl_accounts')
                ->result();
        }

        return array(
            'all_account' => $all_account,
            'pdf_account_limit' => $pdf_account_limit,
            'pdf_truncated' => $pdf_truncated,
        );
    }

    public function download($id, $fileName = null)
    {
        $file_info = $this->transactions_model->check_by(array('transactions_id' => $id), 'tbl_transactions');
        if (!empty($fileName)) {
            $attachment = json_decode($file_info->attachement);

            // get array value from $attachment array
            $values = array_values((array)$attachment);
            // get file name from array value
            $file_name = $values[$fileName];
            $path = $file_name->path;
            // check file is exist or not
            if (file_exists('./' . $path)) {
                $data = file_get_contents('./' . $path); // Read the file's contents
                force_download($file_name->fileName, $data);
            } else {
                $type = 'error';
                $message = lang('operation_failed');
                set_message($type, $message);
                redirect($_SERVER['HTTP_REFERER']);
            }
        } else {
            $this->load->library('zip');


            $attachement_info = json_decode($file_info->attachement);
            if (!empty($attachement_info)) {
                $total = count(array($attachement_info));
                foreach ($attachement_info as $attachement) {
                    if ($total == 1) {
                        $this->load->helper('download');
                        $down_data = file_get_contents('uploads/' . $attachement->fileName); // Read the file's contents
                        force_download($attachement->fileName, $down_data);
                    } else {
                        $multiple = true;
                        $down_data = ('uploads/' . $attachement->fileName); // Read the file's contents
                        $this->zip->read_file($down_data);
                    }
                }
                if (!empty($multiple)) {
                    $file_name = $file_info->date . ' ' . $file_info->type;
                    $this->zip->download($file_name . '.zip');
                }
            } else {
                $type = "error";
                $message = 'Operation Fieled !';
                set_message($type, $message);
                if (empty($_SERVER['HTTP_REFERER'])) {
                    redirect('admin/dashboard');
                } else {
                    redirect($_SERVER['HTTP_REFERER']);
                }
            }
        }
    }

    public function download_transfer($id)
    {
        $this->load->library('zip');

        $file_info = $this->transactions_model->check_by(array('transfer_id' => $id), 'tbl_transfer');

        $attachement_info = json_decode($file_info->attachement);
        if (!empty($attachement_info)) {
            $total = count(array($attachement_info));
            foreach ($attachement_info as $attachement) {
                if ($total == 1) {
                    $this->load->helper('download');
                    $down_data = file_get_contents('uploads/' . $attachement->fileName); // Read the file's contents
                    force_download($attachement->fileName, $down_data);
                } else {
                    $multiple = true;
                    $down_data = ('uploads/' . $attachement->fileName); // Read the file's contents
                    $this->zip->read_file($down_data);
                }
            }
            if (!empty($multiple)) {
                $file_name = $file_info->date . ' ' . $file_info->type;
                $this->zip->download($file_name . '.zip');
            }
        } else {
            $type = "error";
            $message = 'Operation Fieled !';
            set_message($type, $message);
            if (empty($_SERVER['HTTP_REFERER'])) {
                redirect('admin/dashboard');
            } else {
                redirect($_SERVER['HTTP_REFERER']);
            }
        }
    }

    public function set_status($action, $id)
    {
        $transaction_info = $this->db->where('transactions_id', $id)->get('tbl_transactions')->row();
        $account_info = $this->transactions_model->check_by(array('account_id' => $transaction_info->account_id), 'tbl_accounts');

        if ($action == 'approved') {
            $status = 'unpaid';
            $activity = 'activity_approved_expense';
        }

        if ($action == 'paid') {
            $status = 'paid';

            $data['amount'] = $transaction_info->amount;
            $data['debit'] = $transaction_info->amount;
            $ac_data['balance'] = $account_info->balance - $data['amount'];

            $this->transactions_model->_table_name = "tbl_accounts"; //table name
            $this->transactions_model->_primary_key = "account_id";
            $this->transactions_model->save($ac_data, $transaction_info->account_id);


            $data['total_balance'] = $account_info->balance;
            $activity = 'activity_paid_expense';
        }
        $data['status'] = $status;
        $this->transactions_model->_table_name = "tbl_transactions"; //table name
        $this->transactions_model->_primary_key = "transactions_id";

        $this->transactions_model->save($data, $id);

        // save into activities
        $activities = array(
            'user' => $this->session->userdata('user_id'),
            'module' => 'transactions',
            'module_field_id' => $id,
            'activity' => $activity,
            'icon' => 'fa-building-o',
            'link' => 'admin/transactions/view_details/' . $id,
            'value1' => $account_info->account_name . ' ' . lang('amount') . $transaction_info->amount,
            'value2' => 'By ' . $this->session->userdata('name'),
        );
        // Update into tbl_project
        $this->transactions_model->_table_name = "tbl_activities"; //table name
        $this->transactions_model->_primary_key = "activities_id";
        $this->transactions_model->save($activities);
        $type = 'success';

        $this->expense_confirmation_email($id, $action);

        $message = lang('update_a_expense');
        set_message($type, $message);
        if (empty($_SERVER['HTTP_REFERER'])) {
            redirect('admin/dashboard');
        } else {
            redirect($_SERVER['HTTP_REFERER']);
        }
    }

    function expense_confirmation_email($id, $action)
    {
        $transaction_info = $this->db->where('transactions_id', $id)->get('tbl_transactions')->row();
        $added_info = $this->db->where('user_id', $transaction_info->added_by)->get('tbl_users')->row();

        // send confirmation to this employee
        if ($action == 'approved') {

            $expense_email = config_item('expense_email');
            if (!empty($expense_email) && $expense_email == 1) {
                $email_template = email_templates(array('email_group' => 'expense_approved_email'));

                $message = $email_template->template_body;
                $subject = $email_template->subject;
                $username = str_replace("{NAME}", $added_info->username, $message);
                $amount = str_replace("{AMOUNT}", $transaction_info->amount, $username);
                $message = str_replace("{SITE_NAME}", config_item('company_name'), $amount);
                $data['message'] = $message;
                $message = $this->load->view('email_template', $data, TRUE);

                $params['subject'] = $subject;
                $params['message'] = $message;
                $params['resourceed_file'] = '';
                $params['recipient'] = $added_info->email;
                $this->transactions_model->send_email($params);


                if (!empty($added_info->user_id)) {
                    $notifiedUsers = array($added_info->user_id);
                    foreach ($notifiedUsers as $users) {
                        if ($users != $this->session->userdata('user_id')) {
                            add_notification(array(
                                'to_user_id' => $users,
                                'description' => 'not_expense_approve',
                                'icon' => 'building-o',
                                'link' => 'admin/transactions/view_details/' . $id,
                                'value' => lang('name') . ' ' . $transaction_info->name . ' ' . lang('amount') . display_money($transaction_info->amount),
                            ));
                        }
                    }
                    show_notification($notifiedUsers);
                }
            }
        }
        if ($action == 'paid') {
            // get departments head user id
            $designation_info = $this->transactions_model->check_by(array('designations_id' => $this->session->userdata('designations_id')), 'tbl_designations');
            $all_admin = $this->db->where('role_id', 1)->get('tbl_users')->result();
            if (!empty($designation_info)) {
                // get departments head by departments id
                $dept_head = $this->transactions_model->check_by(array('departments_id' => $designation_info->departments_id), 'tbl_departments');
                $head = $this->db->where('user_id', $dept_head->department_head_id)->get('tbl_users')->row();
                array_push($all_admin, $head);
            }

            if (!empty($dept_head->department_head_id) || !empty($all_admin)) {
                $expense_email = config_item('expense_email');
                if (!empty($expense_email) && $expense_email == 1) {
                    $email_template = email_templates(array('email_group' => 'expense_paid_email'));

                    $message = $email_template->template_body;
                    $subject = $email_template->subject;
                    $username = str_replace("{NAME}", $added_info->username, $message);
                    $amount = str_replace("{AMOUNT}", $transaction_info->amount, $username);
                    $PAID_BY = str_replace("{PAID_BY}", $this->session->userdata('name'), $amount);
                    $Link = str_replace("{URL}", base_url() . 'admin/transactions/view_details/' . $id, $PAID_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'] = '';
                    $notifyUser = array();
                    if (!empty($all_admin)) {
                        foreach ($all_admin as $v_admin) {
                            if (!empty($v_admin)) {
                                array_push($notifyUser, $v_admin->user_id);
                                $params['recipient'] = $v_admin->email;
                                $this->transactions_model->send_email($params);
                                if (!empty($dept_head->department_head_id)) {
                                    if ($dept_head->department_head_id == $v_admin->user_id) {
                                        $already_send = 1;
                                    }
                                }
                                if ($v_admin->user_id != $this->session->userdata('user_id')) {
                                    add_notification(array(
                                        'to_user_id' => $v_admin->user_id,
                                        'description' => 'not_expense_paid',
                                        'icon' => 'building-o',
                                        'link' => 'admin/transactions/view_details/' . $id,
                                        'value' => lang('name') . ' ' . $transaction_info->name . ' ' . lang('amount') . display_money($transaction_info->amount),
                                    ));
                                }
                            }
                        }
                    }

                    if (!empty($notifyUser)) {
                        show_notification($notifyUser);
                    }

                    if (empty($already_send)) {
                        $params['recipient'] = $head->email;
                        $this->transactions_model->send_email($params);
                    }
                }
            }
        }
        return true;
    }

    public function download_pdf($id)
    {
        $this->load->helper('dompdf');
        $data['expense_info'] = $this->db->where('transactions_id', $id)->get('tbl_transactions')->row();
        if (!empty($data['expense_info']) && $data['expense_info']->type == 'Income') {
            $type = lang('deposit');
        } else {
            $type = lang('expense');
        }
        $data['title'] = $type . ' ' . lang('details');
        $viewfile = $this->load->view('admin/transactions/download_pdf', $data, TRUE);
        if (!empty($data['expense_info']->reference)) {
            $reference = $data['expense_info']->reference;
        } else {
            $reference = null;
        }
        pdf_create($viewfile, slug_it($type . ' ' . lang('details') . $reference));
    }

    public function convert($id)
    {
        // get permission user
        $data['expense_info'] = $this->db->where('transactions_id', $id)->get('tbl_transactions')->row();
        if ($data['expense_info']->project_id != 0 && $data['expense_info']->invoices_id == 0) {
            $data['title'] = lang('convert_to_invoice');
            $data['permission_user'] = $this->invoice_model->all_permission_user('13');
            $data['subview'] = $this->load->view('admin/transactions/invoice_preview', $data, TRUE);
            $this->load->view('admin/_layout_main', $data); //page load
        } else {
            set_message('error', lang('there_in_no_value'));
            redirect('admin/transactions/expense');
        }
    }


}
