<?php

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

/* * *****************Billing.php**********************************
 * @product name    : Hospital Management System
 * @type            : Class
 * @class name      : Billing
 * @description     : Manage billing.
 * @author          : South Bangla IT Zone Team
 * @url             : http://hms.sbitzone.com
 * @support         : rabibd.it@gmail.com
 * @copyright       : South Bangla IT Zone Team
 * ********************************************************** */

class Billing extends MY_Controller {

    public $data = array();

    function __construct() {
        parent::__construct();
        $this->load->model('Billing_Model', 'billing', true);
        $this->data['authorized_persons'] = $this->billing->get_authorized_person_list();
        $this->data['reference_persons'] = $this->billing->get_reference_person_list();
    }

    public function set_barcode($code) {
        // Load library
        $this->load->library('zend');
        // Load in folder Zend
        $this->zend->load('Zend/Barcode');
        // Generate barcode
        Zend_Barcode::render('code128', 'image', array('text' => $code, 'drawText' => false), array());
    }

    /*****************Function index**********************************
     * @type            : Function
     * @function name   : index
     * @description     : Load "Billing List" user interface
     *
     * @param           : null
     * @return          : null
     * ********************************************************** */
    public function index() {

        check_permission(VIEW);

        $search = trim($this->input->get('search'));
        $config = array();
        $config = get_pagination(ADMIN_PER_PAGE);
        if ($search) {
            $config['base_url'] = site_url('billing/?search=' . $search);
        } else {
            $config['base_url'] = current_url();
        }
        if ($this->input->get('page')) {
            $sgm = (int) trim($this->input->get('page'));
            $offset = $config['per_page'] * ($sgm - 1);
        } else {
            $offset = 0;
        }

        $config['total_rows'] = $this->billing->get_patient_list($config['per_page'], $offset, $search, $count = TRUE);
        $this->pagination->initialize($config);
        $this->data['patients'] = $this->billing->get_patient_list($config['per_page'], $offset, $search, $count = FALSE);
        $this->data['sl_count'] = ($this->input->get('page') == 0 ? 1 : (($this->input->get('page') - 1) * $config["per_page"] + 1));
        $this->data['search'] = $search;

        $this->data['list'] = TRUE;
        $this->layout->title($this->lang->line('manage_billing') . ' | ' . $this->global_setting->brand_title);
        $this->layout->view('billing/index', $this->data);
    }

    /*****************Function search**********************************
     * @type            : Function
     * @function name   : search
     * @description     : Load "Search Test Price" user interface
     *
     * @param           : null
     * @return          : null
     * ********************************************************** */

    public function search() {
        $this->data['tubes'] = $this->billing->get_list('diagnostic_tubes', array('status' => 1), '', '', '', 'sort_by', 'ASC');
        $this->data['list'] = TRUE;
        $this->layout->title($this->lang->line('search') . ' ' . $this->lang->line('test_bill') . ' | ' . $this->global_setting->brand_title);
        $this->layout->view('billing/search', $this->data);
    }

    /*****************Function addpatient**********************************
     * @type            : Function
     * @function name   : addpatient
     * @description     : Load "Add Patient" user interface
     *
     * @param           : null
     * @return          : null
     * ********************************************************** */
    public function addpatient() {

        check_permission(ADD);

        if ($_POST) {
            $this->load->library('form_validation');
            $this->form_validation->set_error_delimiters('<div class="error-message" style="color: red;">', '</div>');
            $this->form_validation->set_rules('name', $this->lang->line('patient') . ' ' . $this->lang->line('name'), 'trim|required');
            $this->form_validation->set_rules('phone', $this->lang->line('phone'), 'trim|required|callback_phone');

            if ($this->form_validation->run() === TRUE) {
                $data['name'] = $this->input->post('name');
                $data['phone'] = $this->input->post('phone');
                $data['gender'] = $this->input->post('gender');
                $data['address'] = $this->input->post('address');
                $data['note'] = $this->input->post('note');

                // Age Calculation
                $age = abs((int) $this->input->post('age'));
                $month = abs((int) $this->input->post('month'));
                $day = abs((int) $this->input->post('day'));

                $str = date('Y-m-d');
                if ($age > 0) {
                    $str = $str . ' -' . $age . ' years';
                }
                if ($month > 0) {
                    $str = $str . ' -' . $month . ' months';
                }
                if ($day > 0) {
                    $str = $str . ' -' . ($day + 1) . ' days';
                }
                $dob = date("Y-m-d", strtotime($str));
                $data['dob'] = date('Y-m-d', strtotime($dob));
                $data['age'] = floor((time() - strtotime($data['dob'])) / 31556926);
                // End Age Calculation

                $data['discharged'] = 0;
                $data['status'] = 1;
                $data['created_at'] = date('Y-m-d H:i:s');
                $data['created_by'] = logged_in_user_id();
                // create patient_unique_id
                $data['patient_unique_id'] = $this->billing->get_custom_id('patients', '1');
                // create user
                $data['user_id'] = $this->billing->create_user();
                $insert_id = $this->billing->insert('patients', $data);
                if ($insert_id) {
                    create_log('Has been created a patient : ' . $data['name']);
                }
                $array = array('status' => 'success', 'message' => $this->lang->line('insert_success'), 'user_id' => $data['user_id']);
            } else {
                $this->data = $_POST;
                $msg = array(
                    'name' => form_error('name'),
                    'phone' => form_error('phone'),
                );
                $array = array('status' => 'failed', 'error' => $msg);
            }
            echo json_encode($array);
        }
    }

    /*****************Function addemployee**********************************
     * @type            : Function
     * @function name   : addemployee
     * @description     : Load "Add Employee" user interface
     *
     * @param           : null
     * @return          : null
     * ********************************************************** */
    public function addemployee() {

        check_permission(ADD);

        if ($_POST) {
            $this->load->library('form_validation');
            $this->form_validation->set_error_delimiters('<div class="error-message" style="color: red;">', '</div>');
            $this->form_validation->set_rules('name', $this->lang->line('name') . ' ' . $this->lang->line('type'), 'trim|required|callback_commission_phone');
            $this->form_validation->set_rules('phone', $this->lang->line('phone'), 'trim|required');

            if ($this->form_validation->run() === TRUE) {
                $data['name'] = $this->input->post('name');
                $data['phone'] = $this->input->post('phone');
                $data['commission_type'] = $this->input->post('commission_type');

                $data['status'] = 1;
                $data['created_at'] = date('Y-m-d H:i:s');
                $data['created_by'] = logged_in_user_id();
                // create user
                $data['user_id'] = $this->billing->create_user();

                $insert_id = $this->billing->insert('employees', $data);
                if ($insert_id) {
                    create_log('Has been created a employee : ' . $data['name']);
                }
                $array = array('status' => 'success', 'message' => $this->lang->line('insert_success'), 'user_id' => $data['user_id']);
            } else {
                $this->data = $_POST;
                $msg = array(
                    'name' => form_error('name'),
                    'phone' => form_error('phone'),
                );
                $array = array('status' => 'failed', 'error' => $msg);
            }
            echo json_encode($array);
        }
    }

    /*****************Function commission_phone**********************************
     * @type            : Function
     * @function name   : commission_phone
     * @description     : Unique check for "Commission Phone" data/value
     *
     * @param           : null
     * @return          : boolean true/false
     * ********************************************************** */
    public function commission_phone() {
        if ($this->input->post('id') == '') {
            $commission = $this->billing->duplicate_check_commission_phone($this->input->post('phone'));
            if ($commission) {
                $this->form_validation->set_message('commission_phone', $this->lang->line('phone_already_exist'));
                return FALSE;
            } else {
                return TRUE;
            }
        } else if ($this->input->post('id') != '') {
            $commission = $this->billing->duplicate_check_commission_phone($this->input->post('phone'), $this->input->post('id'));
            if ($commission) {
                $this->form_validation->set_message('commission_phone',  $this->lang->line('phone_already_exist'));
                return FALSE;
            } else {
                return TRUE;
            }
        } else {
            return TRUE;
        }
    }

    /*****************Function phone**********************************
     * @type            : Function
     * @function name   : phone
     * @description     : Unique check for "Patient Phone" data/value
     *
     * @param           : null
     * @return          : boolean true/false
     * ********************************************************** */
    public function phone() {
        if ($this->input->post('id') == '') {
            $patient = $this->billing->duplicate_check($this->input->post('name'), $this->input->post('phone'));
            if ($patient) {
                $this->form_validation->set_message('phone', $this->lang->line('phone_already_exist'));
                return FALSE;
            } else {
                return TRUE;
            }
        } else if ($this->input->post('id') != '') {
            $patient = $this->billing->duplicate_check($this->input->post('name'), $this->input->post('phone'), $this->input->post('id'));
            if ($patient) {
                $this->form_validation->set_message('phone',  $this->lang->line('phone_already_exist'));
                return FALSE;
            } else {
                return TRUE;
            }
        } else {
            return TRUE;
        }
    }

    /*****************Function index**********************************
     * @type            : Function
     * @function name   : index
     * @description     : Load "Billing List" user interface
     *
     * @param           : null
     * @return          : null
     * ********************************************************** */

    public function create() {

        check_permission(ADD);

        $ipd_doctor = $this->billing->get_ipd_patient_by_ref_dr($this->uri->segment(3, 0));
        $opd_doctor = $this->billing->get_opd_patient_by_ref_dr($this->uri->segment(3, 0));

        if (isset($ipd_doctor) && !empty($ipd_doctor)) {
            $this->data['doctor'] = $ipd_doctor;
        } else {
            $this->data['doctor'] = $opd_doctor;
        }

        $this->data['created'] = $this->billing->get_single('invoices', array('id' => $this->input->get('invoice')));
        $this->data['patient'] = $this->billing->get_single('patients', array('user_id' => $this->uri->segment(3, 0)));
        $this->data['reference'] = $this->billing->get_patient_by_reference($this->uri->segment(3, 0));
        $this->data['employees'] = $this->billing->get_employee_list();
        $this->data['authorized_person'] = $this->billing->get_authorized_person_list();
        $this->data['reference_emp'] = $this->billing->get_reference_emp($this->uri->segment(3, 0));
        $this->data['tubes'] = $this->billing->get_list('diagnostic_tubes', array('status' => 1), '', '', '', 'sort_by', 'ASC');

        $this->data['add'] = TRUE;
        $this->layout->title($this->lang->line('create') . ' ' . $this->lang->line('billing') . ' | ' . $this->global_setting->brand_title);
        $this->layout->view('billing/create', $this->data);
    }

    public function get_authorized_person() {
        $authorized_person = $this->billing->get_single_authorized_person($this->input->post('authorized_person'));
        echo json_encode($authorized_person);
    }

    /*****************Function add**********************************
     * @type            : Function
     * @function name   : add
     * @description     : Load "add Billing" user interface
     *
     * @param           : null
     * @return          : null
     * ********************************************************** */

    public function add() {

        check_permission(ADD);

        if ($_POST) {
            // Check Discount
            $total_bill = 0;
            $total_special_discount = 0;
            foreach ($this->input->post('tests') as $tid => $qty) {
                $test_details = (array) $this->billing->get_single('diagnostic_tests', array('id' => $tid));
                if ($test_details) {
                    $total_bill += ($test_details['rate'] * $qty);
                    $total_special_discount += ($test_details['special_discount'] * $qty);
                }
            }

            if ($this->input->post('authorized_person')) {
                $authorized_person = $this->billing->get_single_authorized_person($this->input->post('authorized_person'));
                if ($authorized_person->role_id == MANAGER) {
                    $is_discount = ($this->global_setting->is_manager_discount / 100) * ($total_bill - $total_special_discount);
                } elseif ($authorized_person->role_id == RECEPTIONIST) {
                    $is_discount = ($this->global_setting->is_discount / 100) * ($total_bill - $total_special_discount);
                } else {
                    $is_discount = (100 / 100) * ($total_bill - $total_special_discount);
                }
                if ($this->input->post('discount') > $is_discount) {
                    $array = array('status' => 'failed', 'error' => "Warning! Attention Please!!! <br> Discount amount is not more than " . $is_discount);
                    echo json_encode($array);
                    exit();
                }
            } else {
                $is_discount = ($this->global_setting->is_discount / 100) * ($total_bill - $total_special_discount);
                if ($this->input->post('discount') > $is_discount) {
                    $array = array('status' => 'failed', 'error' => "Warning! Attention Please!!! <br> Discount amount is not more than " . $is_discount);
                    echo json_encode($array);
                    exit();
                }
            }
            // End Check Discount

            if (!$this->input->post('self') && !$this->input->post('doctor_id')) {
                $array = array('status' => 'failed', 'error' => "Doctor or Self must be select");
                echo json_encode($array);
                exit();
            }
            if (count($this->input->post('tests')) == 0) {
                $this->data = $_POST;
                $array = array('status' => 'failed', 'error' => "No test selected");
                echo json_encode($array);
                exit();
            }

            $data['custom_invoice_id'] = get_datewise_custom_invoice_id('invoices', 'INV-', date('Y'), date('m'), date('d'));
            $data['invoice_type'] = 'investigation';
            $data['patient_id'] = $this->input->post('patient_id');

            // Ref By Doctor Query
            $doctor_id = explode('-', $this->input->post('doctor_id'));
            $ref_dr_id = $this->billing->get_single('employees', array('user_id' =>  $doctor_id[0]));
            if ($this->input->post('self') == 1) {
                $data['self'] = '1';
                $data['ref_dr_id'] = NULL;
                $data['ref_dr_name'] = NULL;
            } else {
                if (isset($ref_dr_id->user_id)) {
                    $data['ref_dr_id'] = $doctor_id[0];
                } else {
                    $data['ref_dr_name'] = $this->input->post('doctor_id');
                }
            }
            $commission_user_id = explode('-', $this->input->post('commission_user_id'));
            $coms = $this->billing->get_single('employees', array('id' =>  $commission_user_id[0]));

            if (isset($coms->user_id)) {
                $data['commission_user_id'] = $coms->user_id;
            } else {
                $data['commission_name'] = $this->input->post('commission_user_id');
            }

            // reference_person
            $reference_person = explode('-', $this->input->post('reference_person'));
            $emps = $this->billing->get_single('employees', array('id' =>  $reference_person[0]));

            if (isset($emps->user_id)) {
                $data['reference_person'] = $emps->user_id;
            } else {
                $data['reference_person'] = null;
            }

            $data['bill_date'] = date('Y-m-d H:i:s', strtotime($this->input->post('bill_date')));
            $data['delivery_status'] = 'normal';
            $data['is_ipd'] = $this->input->post('is_ipd') ? $this->input->post('is_ipd') : 0;

            $tube_sum = 0;
            if ($this->input->post('tubes')) {
                foreach ($this->input->post('tubes') as $tube_id => $qty) {
                    $tube = $this->billing->get_single('diagnostic_tubes', array('id' => $tube_id));
                    $tube_sum += ($tube->price * $qty);
                }
            }

            // Under Construction
            $data['total_bill'] = $tube_sum; //
            $data['commission_amount'] = '0.00'; //
            $data['special_discount'] = '0.00'; //
            $data['prev_invoice_id'] = $this->input->post('prev_invoice_id') ?? null; //


            $data['discount'] = $this->input->post('discount') > 0 ? $this->input->post('discount') : '0.00';
            $data['advanced'] = $this->input->post('advanced') > 0 ? $this->input->post('advanced') : '0.00';
            $data['payable_commission'] = $this->input->post('commission') > 0 ? $this->input->post('commission') : '0.00';
            foreach ($this->input->post('tests') as $tid => $qty) {
                $test_details = (array) $this->billing->get_single('diagnostic_tests', array('id' => $tid));
                if ($test_details) {
                    $data['total_bill'] += ($test_details['rate'] * $qty);
                    if ($coms) {
                        $data['commission_amount'] += ($test_details[$coms->commission_type] * $qty);
                    }
                }
            }
            if ($coms) {
                $data['commission_amount'] = $data['total_bill'] - ($data['commission_amount'] + $tube_sum);
            } else {
                $data['commission_amount'] = 0;
            }
            $data['net_payable'] = $data['total_bill'];
            $data['paid_status'] = 'unpaid';
            if ($data['discount'] > 0) {
                $data['net_payable'] -=  $data['discount'];
            }
            $data['due_amount'] = $data['net_payable'];
            if ($data['advanced'] > 0) {
                $data['due_amount'] -=  $data['advanced'];
            }
            if ($data['due_amount'] <= 0) {
                $data['paid_status'] = 'paid'; //
            }


            $data['date'] = date('Y-m-d', strtotime($this->input->post('bill_date')));
            $data['month'] = date('m', strtotime($this->input->post('bill_date')));
            $data['year'] = date('Y', strtotime($this->input->post('bill_date')));
            $data['note'] = $this->input->post('note') ? $this->input->post('note') : null;

            $data['status'] = 1;
            $data['authorized_person'] = $this->input->post('authorized_person') ? $this->input->post('authorized_person') : null;
            $data['created_at'] = date('Y-m-d H:i:s');
            if ($this->input->post('created_by') > 0 && !empty($this->input->post('created_by'))) {
                $data['created_by'] = $this->input->post('created_by');
            } else {
                $data['created_by'] = logged_in_user_id();
            }

            $this->db->trans_start();
            $insert_id = $this->billing->insert('invoices', $data);
            // Insert Test for Invoice Details
            $tests = $this->input->post('tests');

            if (isset($tests) && !empty($tests)) {
                foreach ($this->input->post('tests') as $tid => $qty) {
                    $test_details = $this->billing->get_single('diagnostic_tests', array('id' => $tid));
                    $testdata['invoice_id'] = $insert_id;
                    $testdata['investagation_id'] = $test_details->id;
                    $testdata['unit'] = $qty; //
                    $testdata['rate'] = $test_details->rate;
                    $testdata['total_rate'] = ($testdata['unit'] * $testdata['rate']);

                    $testdata['discount'] = $test_details->special_discount;
                    $testdata['total_discount'] = ($testdata['unit'] * $test_details->special_discount);

                    $testdata['status'] = 1;
                    $testdata['created_at'] = date('Y-m-d H:i:s');
                    if ($this->input->post('created_by') > 0 && !empty($this->input->post('created_by'))) {
                        $testdata['created_by'] = $this->input->post('created_by');
                    } else {
                        $testdata['created_by'] = logged_in_user_id();
                    }

                    if ($testdata['total_discount'] > 0) {
                        $data['special_discount'] += $testdata['total_discount'];
                    }

                    $this->billing->insert('invoice_details', $testdata);
                }

                if ($data['special_discount'] > 0) {
                    $data['paid_status'] = 'unpaid';
                    $data['net_payable'] -= $data['special_discount'];
                    $data['due_amount'] -= $data['special_discount'];
                    if ($data['due_amount'] <= 0) {
                        $data['paid_status'] = 'paid'; //
                        $data['due_amount'] = 0; //
                    }
                    $this->billing->update('invoices', array(
                        'special_discount' => $data['special_discount'],
                        'due_amount' => $data['due_amount'],
                        'net_payable' => $data['net_payable'],
                        'paid_status' => $data['paid_status']
                    ), array('id' => $insert_id));
                }
            }


            // Tube Details

            $tubes = $this->input->post('tubes');
            if (isset($tubes) && !empty($tubes)) {
                foreach ($this->input->post('tubes') as $tube_id => $qty) {
                    $tube_details = $this->billing->get_single('diagnostic_tubes', array('id' => $tube_id));
                    $tubedata['invoice_id'] = $insert_id;
                    $tubedata['tube_id'] = $tube_id;
                    $tubedata['quantity'] = $qty;
                    $tubedata['rate'] = $tube_details->price;
                    $tubedata['total_rate'] = ($tubedata['quantity'] * $tubedata['rate']);
                    $tubedata['status'] = 1;
                    $tubedata['created_at'] = date('Y-m-d H:i:s');
                    if ($this->input->post('created_by') > 0 && !empty($this->input->post('created_by'))) {
                        $tubedata['created_by'] = $this->input->post('created_by');
                    } else {
                        $tubedata['created_by'] = logged_in_user_id();
                    }
                    $this->billing->insert('invoice_tube_details', $tubedata);
                }
            }


            // Payment Invoice Data

            $paymentdata['invoice_id'] = $insert_id;
            $paymentdata['collection_type'] = '1';
            $paymentdata['payment_date'] = date('Y-m-d H:i:s', strtotime($this->input->post('bill_date')));
            $data['date'] = date('Y-m-d', strtotime($this->input->post('bill_date')));
            $data['month'] = date('m', strtotime($this->input->post('bill_date')));
            $data['year'] = date('Y', strtotime($this->input->post('bill_date')));
            $paymentdata['amount'] = $this->input->post('advanced') ? $this->input->post('advanced') : '0.00';
            $paymentdata['status'] = 1;
            $paymentdata['created_at'] = date('Y-m-d H:i:s');
            if ($this->input->post('created_by') > 0 && !empty($this->input->post('created_by'))) {
                $paymentdata['created_by'] = $this->input->post('created_by');
            } else {
                $paymentdata['created_by'] = logged_in_user_id();
            }

            $this->billing->insert('invoice_payments', $paymentdata);

            // Send SMS
            if (has_permission(ADD, 'billing', 'billing_sms')) {
                send_sms('billing_sms', $insert_id);
            }

            $this->db->trans_complete();
            if ($this->db->trans_status() === FALSE) {
                $array = array('status' => 'failled', 'message' => $this->lang->line('insert_success'));
                echo json_encode($array);
                die;
            }

            if ($insert_id) {
                create_log('Has been created a invoice : ' . $data['custom_invoice_id']);
            }
            $array = array('status' => 'success', 'message' => $this->lang->line('insert_success'), 'id' => $insert_id);

            echo json_encode($array);
        }
    }

    /*****************Function bill**********************************
     * @type            : Function
     * @function name   : bill
     * @description     : Load "Billing List" user interface
     *
     * @param           : null
     * @return          : null
     * ********************************************************** */

    public function bill() {

        check_permission(VIEW);

        if ($_GET && $this->input->get('date')) {
            $type = $this->input->get('type');
            $date = $this->input->get('date');
            $exp = explode('-', $date);
            $form_date = date('Y-m-d', strtotime($exp[0]));
            $to_date = date('Y-m-d', strtotime($exp[1]));
            $search = trim($this->input->get('search'));
            $config = array();
            $config = get_pagination(ADMIN_PER_PAGE);
            $config['base_url'] = site_url('billing/bill/?type=' . $type . '&date=' . $date . '&search=' . $search);
            if ($this->input->get('page')) {
                $sgm = (int) trim($this->input->get('page'));
                $offset = $config['per_page'] * ($sgm - 1);
            } else {
                $offset = 0;
            }

            $config['total_rows'] = $this->billing->get_bill_list($config['per_page'], $offset, $type, $form_date, $to_date, $search, $count = TRUE);
            $this->pagination->initialize($config);
            $this->data['bills'] = $this->billing->get_bill_list($config['per_page'], $offset, $type, $form_date, $to_date, $search, $count = FALSE);
            $this->data['sl_count'] = ($this->input->get('page') == 0 ? 1 : (($this->input->get('page') - 1) * $config["per_page"] + 1));
            $this->data['search'] = $search;
            $this->data['date'] = $date;
            $this->data['type'] = $type;
        } else {
            $config = array();
            $config = get_pagination(ADMIN_PER_PAGE);
            $config['base_url'] = current_url();
            if ($this->input->get('page')) {
                $sgm = (int) trim($this->input->get('page'));
                $offset = $config['per_page'] * ($sgm - 1);
            } else {
                $offset = 0;
            }

            $config['total_rows'] = $this->billing->get_bill_list($config['per_page'], $offset, null, date('Y-m-d'), date('Y-m-d'), null, $count = TRUE);
            $this->pagination->initialize($config);
            $this->data['bills'] = $this->billing->get_bill_list($config['per_page'], $offset, null, date('Y-m-d'), date('Y-m-d'), null, $count = FALSE);
            $this->data['sl_count'] = ($this->input->get('page') == 0 ? 1 : (($this->input->get('page') - 1) * $config["per_page"] + 1));
        }
        $this->data['bill'] = TRUE;
        $this->layout->title($this->lang->line('bill') . ' ' . $this->lang->line('list') . ' | ' . $this->global_setting->brand_title);
        $this->layout->view('billing/bill', $this->data);
    }

    /*****************Function getInvoiceId**********************************
     * @type            : Function
     * @function name   : getInvoiceId
     * @description     : Load "getInvoiceId" user interface
     *
     * @param           : null
     * @return          : null
     * ********************************************************** */

    public function getInvoiceId($id) {
        $invoice = $this->billing->get_single('invoices', array('id' =>  $id));
        echo json_encode($invoice);
    }
    /*****************Function payment_status**********************************
     * @type            : Function
     * @function name   : payment_status
     * @description     : Load "payment_status" user interface
     *
     * @param           : null
     * @return          : null
     * ********************************************************** */

    public function payment_status() {

        check_permission(EDIT);

        if ($_POST) {
            $this->load->library('form_validation');
            $this->form_validation->set_error_delimiters('<div class="error-message" style="color: red;">', '</div>');
            $this->form_validation->set_rules('payment_status', $this->lang->line('payment') . ' ' . $this->lang->line('status'), 'trim|required');

            if ($this->form_validation->run() === TRUE) {
                $data['payment_status'] = $this->input->post('payment_status');
                $data['note'] = $this->input->post('note');

                $data['modified_at'] = date('Y-m-d H:i:s');
                $data['modified_by'] = logged_in_user_id();

                $updated_id = $this->billing->update('invoices', $data, array('id' => $this->input->post('invoice_id')));
                if ($updated_id) {
                    create_log('Has been update a invoice : ' . $this->input->post('invoice_id'));
                }
                $array = array('status' => 'success', 'message' => $this->lang->line('update_success'));
            } else {
                $this->data = $_POST;
                $msg = array(
                    'payment_status' => form_error('payment_status')
                );
                $array = array('status' => 'failed', 'error' => $msg);
            }
            echo json_encode($array);
        }
    }

    /*****************Function due**********************************
     * @type            : Function
     * @function name   : due
     * @description     : Load "Due Billing List" user interface
     *
     * @param           : null
     * @return          : null
     * ********************************************************** */

    public function due() {

        check_permission(VIEW);

        if ($_GET) {
            $search = $this->input->get('search');
            $exp = explode('-', $search);
            $formDate = date('Y-m-d', strtotime($exp[0]));
            $toDate = date('Y-m-d', strtotime($exp[1]));

            $config = array();
            $config = get_pagination(ADMIN_PER_PAGE);
            if ($search) {
                $config['base_url'] = site_url('billing/due/?search=') . $search;
            } else {
                $config['base_url'] = current_url();
            }
            if ($this->input->get('page')) {
                $sgm = (int) trim($this->input->get('page'));
                $offset = $config['per_page'] * ($sgm - 1);
            } else {
                $offset = 0;
            }

            $config['total_rows'] = $this->billing->get_due_bill_list($config['per_page'], $offset, $formDate, $toDate, $count = TRUE);
            $this->pagination->initialize($config);
            $this->data['dues'] = $this->billing->get_due_bill_list($config['per_page'], $offset, $formDate, $toDate, $count = FALSE);

            $this->data['sl_count'] = ($this->input->get('page') == 0 ? 1 : (($this->input->get('page') - 1) * $config["per_page"] + 1));
            $this->data['form_date'] = $formDate;
            $this->data['to_date'] = $toDate;
            $this->data['search'] = $search;
        }
        $this->layout->title($this->lang->line('due') . ' ' . $this->lang->line('billing') . ' | ' . $this->global_setting->brand_title);
        $this->layout->view('billing/due', $this->data);
    }

    /*****************Function paid**********************************
     * @type            : Function
     * @function name   : paid
     * @description     : Load "Paid Billing List" user interface
     *
     * @param           : null
     * @return          : null
     * ********************************************************** */

    public function paid() {

        check_permission(VIEW);

        if ($_GET) {
            $search = $this->input->get('search');
            $exp = explode('-', $search);
            $formDate = date('Y-m-d', strtotime($exp[0]));
            $toDate = date('Y-m-d', strtotime($exp[1]));

            $config = array();
            $config = get_pagination(ADMIN_PER_PAGE);
            if ($search) {
                $config['base_url'] = site_url('billing/paid/?search=') . $search;
            } else {
                $config['base_url'] = current_url();
            }
            if ($this->input->get('page')) {
                $sgm = (int) trim($this->input->get('page'));
                $offset = $config['per_page'] * ($sgm - 1);
            } else {
                $offset = 0;
            }

            $config['total_rows'] = $this->billing->get_paid_bill_list($config['per_page'], $offset, $formDate, $toDate, $count = TRUE);
            $this->pagination->initialize($config);
            $this->data['paids'] = $this->billing->get_paid_bill_list($config['per_page'], $offset, $formDate, $toDate, $count = FALSE);

            $this->data['sl_count'] = ($this->input->get('page') == 0 ? 1 : (($this->input->get('page') - 1) * $config["per_page"] + 1));
            $this->data['search'] = $search;
        }
        $this->layout->title($this->lang->line('paid') . ' ' . $this->lang->line('billing') . ' | ' . $this->global_setting->brand_title);
        $this->layout->view('billing/paid', $this->data);
    }

    /*****************Function invoice**********************************
     * @type            : Function
     * @function name   : invoice
     * @description     : Load "InvoiceList" user interface
     *
     * @param           : null
     * @return          : null
     * ********************************************************** */

    public function invoice() {

        check_permission(VIEW);

        $this->data['patient'] = $this->billing->get_patient_invoice($this->uri->segment(3, 0));
        $this->data['tests'] = $this->billing->get_patient_invoice_test($this->uri->segment(3, 0));
        $this->data['tubes'] = $this->billing->get_invoice_tube_list($this->uri->segment(3, 0));
        $this->data['invoice'] = $this->billing->get_single('invoices', array('id' => $this->uri->segment(3, 0)));
        $this->layout->title($this->lang->line('invoice') . ' ' . $this->lang->line('list') . ' | ' . $this->global_setting->brand_title);
        $this->layout->view('billing/invoice', $this->data);
    }

    /*****************Function print**********************************
     * @type            : Function
     * @function name   : print
     * @description     : Load "print" user interface
     *
     * @param           : null
     * @return          : null
     * ********************************************************** */

    public function print() {
        $this->load->library('Numbertowords');
        $this->data['patient'] = $this->billing->get_patient_invoice($this->input->post('id'));
        $this->data['ipd_patient'] = $this->billing->get_ipd_patient_info($this->input->post('id'));
        $this->data['tests'] = $this->billing->get_patient_invoice_test($this->input->post('id'));
        $this->data['tubes'] = $this->billing->get_invoice_tube_list($this->input->post('id'));
        $this->data['total_department'] = $this->billing->get_total_department($this->input->post('id'));
        $this->data['invoice'] = $this->billing->get_single('invoices', array('id' => $this->input->post('id')));
        $this->data['rooms'] = $this->billing->get_room_list($this->input->post('id'));
        $this->load->view('billing/print', $this->data);
    }

    /*****************Function print**********************************
     * @type            : Function
     * @function name   : print
     * @description     : Load "print" user interface
     *
     * @param           : null
     * @return          : null
     * ********************************************************** */

    public function printOffice() {
        $this->load->library('Numbertowords');
        $this->data['patient'] = $this->billing->get_patient_invoice($this->input->post('id'));
        $this->data['ipd_patient'] = $this->billing->get_ipd_patient_info($this->input->post('id'));
        $this->data['tests'] = $this->billing->get_patient_invoice_test($this->input->post('id'));
        $this->data['tubes'] = $this->billing->get_invoice_tube_list($this->input->post('id'));
        $this->data['total_department'] = $this->billing->get_total_department($this->input->post('id'));
        $this->data['invoice'] = $this->billing->get_single('invoices', array('id' => $this->input->post('id')));
        $this->data['rooms'] = $this->billing->get_room_list($this->input->post('id'));
        $this->load->view('billing/print-office', $this->data);
    }

    /*****************Function history**********************************
     * @type            : Function
     * @function name   : history
     * @description     : Load "Invoice history user interface
     *
     * @param           : null
     * @return          : null
     * ********************************************************** */

    public function history() {
        $this->data['patient'] = $this->billing->get_patient_invoice($this->uri->segment(3, 0));
        $this->data['invoice'] = $this->billing->get_single('invoices', array('id' => $this->uri->segment(3, 0)));
        $this->data['invoice_payments'] = $this->billing->get_patient_payment_history($this->uri->segment(3, 0));

        $this->layout->title($this->lang->line('invoice') . ' ' . $this->lang->line('history') . ' | ' . $this->global_setting->brand_title);
        $this->layout->view('billing/history', $this->data);
    }

    /*****************Function print_history**********************************
     * @type            : Function
     * @function name   : print_history
     * @description     : Load "print_history" user interface
     *
     * @param           : null
     * @return          : null
     * ********************************************************** */

    public function print_history() {
        $this->data['patient'] = $this->billing->get_patient_invoice($this->input->post('id'));
        $this->data['invoice'] = $this->billing->get_single('invoices', array('id' => $this->input->post('id')));
        $this->data['invoice_payments'] = $this->billing->get_patient_payment_history($this->input->post('id'));
        $this->load->view('billing/print_history', $this->data);
    }

    public function add_payment() {

        check_permission(ADD);

        if ($_POST) {

            // Check Discount
            $invoice =  $this->billing->get_single('invoices', array('id' => $this->input->post('invoice_id')));
            $total_bill = $invoice->total_bill;
            $second_less = $this->input->post('second_less') ? $this->input->post('second_less') : 0;
            $amount = $this->input->post('amount') ? $this->input->post('amount') : 0;
            $total_discount = ($invoice->discount + $second_less);

            if ($this->input->post('authorized_person')) {
                $authorized_person = $this->billing->get_single_authorized_person($this->input->post('authorized_person'));
                if ($authorized_person->role_id == MANAGER) {
                    $is_discount = ($this->global_setting->is_manager_discount / 100) * ($total_bill);
                } elseif ($authorized_person->role_id == RECEPTIONIST) {
                    $is_discount = ($this->global_setting->is_discount / 100) * ($total_bill);
                } else {
                    $is_discount = (100 / 100) * ($total_bill);
                }
                if ($total_discount > $is_discount) {
                    $array = array('status' => 'failed', 'error' => "Warning! Attention Please!!! <br> Second less amount is not more than " . ($is_discount - $invoice->discount));
                    echo json_encode($array);
                    exit();
                }
            } else {
                if ($second_less > 0) {
                    $is_discount = ($this->global_setting->is_discount / 100) * ($total_bill);
                    if ($total_discount > $is_discount) {
                        $array = array('status' => 'failed', 'error' => "Warning! Attention Please!!! <br> Second less amount is not more than " . ($is_discount - $invoice->discount));
                        echo json_encode($array);
                        exit();
                    }
                }
            }
            // End Check Discount

            if ($second_less > $invoice->due_amount) {
                $array = array('status' => 'failed', 'error' => "Warning! Attention Please!!! <br>Second Less amount is not more than " . $invoice->due_amount);
                echo json_encode($array);
                exit();
            }

            if ($amount +  $second_less > $invoice->due_amount) {
                $array = array('status' => 'failed', 'error' => "Warning! Attention Please!!! <br>Total amount is not more than " . $invoice->due_amount);
                echo json_encode($array);
                exit();
            }

            if ($amount > $invoice->due_amount) {
                $array = array('status' => 'failed', 'error' => "Warning! Attention Please!!! <br>Payment amount is not more than " . $invoice->due_amount);
                echo json_encode($array);
                exit();
            }

            $data['invoice_id'] = $this->input->post('invoice_id');
            $data['collection_type'] = '2';
            $data['payment_date'] = $this->input->post('date') ? date('Y-m-d H:i:s', strtotime($this->input->post('date'))) : NULL;
            $data['amount'] = $amount;
            $data['second_less'] = $second_less;
            $data['note'] = $this->input->post('note');

            if ($data['amount'] > 0) {
                $due = $this->billing->get_single('invoices', array('id' => $data['invoice_id']));

                if ($data['second_less'] > 0) {
                    $data_payment['net_payable'] =   $due->net_payable - $data['second_less'];
                }
                $data_payment['due_amount'] =   $due->due_amount - ($data['amount'] + $data['second_less']);
                $data_payment['advanced'] =   $due->advanced + $data['amount'];
                $data_payment['discount'] =   $due->discount + $data['second_less'];

                if ($data_payment['due_amount'] <= 0) {
                    $data_payment['paid_status'] = 'paid';
                }
                if ($this->input->post('authorized_person')) {
                    $data_payment['authorized_person'] = $this->input->post('authorized_person');
                }
                $this->billing->update('invoices', $data_payment, array('id' =>  $data['invoice_id']));
            }

            $data['status'] = 1;
            $data['created_at'] = date('Y-m-d H:i:s');
            $data['created_by'] = logged_in_user_id();

            $insert_id =  $this->billing->insert('invoice_payments', $data);

            // Send SMS
            if (has_permission(ADD, 'billing', 'billing_payment_sms')) {
                send_sms('billing_payment_sms', $insert_id);
            }

            create_log('Has been created a payment : ' . $data['invoice_id']);
            $array = array('status' => 'success', 'error' => '', 'message' => $this->lang->line('insert_success'));
        } else {
            $msg = array(
                'amount' => form_error('amount'),
            );
            $array = array('status' => 'failed', 'error' => $msg, 'message' => '');
        }

        echo json_encode($array);
    }

    /*****************Function get_payment_data**********************************
     * @type            : Function
     * @function name   : get_payment_data
     * @description     : Load "Payment Amount" user interface
     *
     * @param           : null
     * @return          : null
     * ********************************************************** */

    public function get_payment_data() {
        $invoice = $this->billing->get_single('invoices', array('id' => $this->uri->segment(3, 0)));
        $amount = array('amount' => $invoice->due_amount, 0);
        echo json_encode($amount);
    }

    public function test_search() {
        $search = $this->billing->get_test_search($this->input->post('name'));
        echo json_encode($search);
    }

    public function doctor_search() {
        $search = $this->billing->get_doctor_search($this->input->post('name'));
        echo json_encode($search);
    }

    public function commission_search() {
        $search = $this->billing->get_commission_search($this->input->post('name'));
        echo json_encode($search);
    }

    public function employee_search() {
        $search = $this->billing->get_employee_search($this->input->post('name'));
        echo json_encode($search);
    }

    public function get_invoice($invoice_id) {
        $search = $this->billing->get_single('invoices', array('id' => $invoice_id));
        $doctor_name = $search->ref_dr_name;
        $doctor = null;
        if ($search->ref_dr_id) {
            $doctor = $this->billing->get_single('employees', array('user_id' => $search->ref_dr_id));
        }

        $com_name = $search->commission_name;
        $commission = null;
        if ($search->commission_user_id) {
            $commission = $this->billing->get_single('employees', array('user_id' => $search->commission_user_id));
        }
        $test = $this->billing->get_list('invoice_details', array('invoice_id' => $invoice_id));
        $investagations = [];
        foreach ($test as $item) {
            $singe_test = $this->billing->get_single('diagnostic_tests', array('id' => $item->investagation_id));
            $singe_test->quantity = $item->unit;
            array_push($investagations, $singe_test);
        }
        $tube = $this->billing->get_list('invoice_tube_details', array('invoice_id' => $invoice_id));
        $tubes = [];
        foreach ($tube as $item) {
            $singe_tube = $this->billing->get_single('diagnostic_tubes', array('id' => $item->tube_id));
            $singe_tube->quantity = $item->quantity;
            $singe_tube->rate = $item->rate;
            array_push($tubes, $singe_tube);
        }
        echo json_encode([
            'invoice' => $search,
            'tests' => $investagations,
            'tubes' => $tubes,
            'doctor_name' => $doctor_name,
            'doctor' => $doctor,
            'com_name' => $com_name,
            'commission' => $commission
        ]);
    }

    /*     * ***************Function delete**********************************
     * @type            : Function
     * @function name   : delete
     * @description     : delete "Invoice Delete" data from database
     *                     and unlink all information server
     * @param           : $id integer value
     * @return          : null
     * ********************************************************** */

    public function delete($id = null) {

        check_permission(DELETE);

        if (!is_numeric($id)) {
            error($this->lang->line('unexpected_error'));
            redirect('billing/bill');
        }

        $invoice = $this->billing->get_single('invoices', array('id' => $id));
        if (!empty($invoice)) {

            // delete invoice data
            $this->billing->delete('invoices', array('id' => $id));
            // delete invoice details data
            $this->billing->delete('invoice_details', array('invoice_id' => $invoice->id));

            // delete invoice payment data
            $this->billing->delete('invoice_payments', array('invoice_id' => $invoice->id));

            create_log('Has been deleted a invoice : ' . $invoice->id . '-> [' . $invoice->custom_invoice_id . ']');
            success($this->lang->line('delete_success'));
        } else {
            error($this->lang->line('delete_failed'));
        }
        redirect('billing/bill');
    }

    public function billing_sms($id = null) {
        check_permission(VIEW);
        if ($id) {
            send_sms('billing_sms', $id);
        }
    }
}
