<?php

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

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

class Sale extends MY_Controller {

    public $data = array();

    function __construct() {
        parent::__construct();
        $this->load->model('Sale_Model', 'sale', true);
    }

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

        check_permission(VIEW);

        if ($_GET && $this->input->get('date')) {
            $keyword = trim($this->input->get('keyword'));
            $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]));
            $created_by = $this->input->get('created_by');

            $config = array();
            $config = get_pagination(ADMIN_PER_PAGE);
            $config['base_url'] = site_url('pharmacy/sale/?keyword=' . $keyword . '&type=' . $type . '&date=' . $date . '&created_by=' . $created_by);
            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->sale->get_sale_invoice_list($config['per_page'], $offset, $keyword, $type, $form_date, $to_date, $created_by, $count = TRUE);
            $this->pagination->initialize($config);
            $this->data['sales'] = $this->sale->get_sale_invoice_list($config['per_page'], $offset, $keyword, $type, $form_date, $to_date, $created_by, $count = FALSE);
            $this->data['sl_count'] = ($this->input->get('page') == 0 ? 1 : (($this->input->get('page') - 1) * $config["per_page"] + 1));
            $this->data['keyword'] = $keyword;
            $this->data['type'] = $type;
            $this->data['date'] = $date;
            $this->data['created_by'] = $created_by;
        } 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->sale->get_sale_invoice_list($config['per_page'], $offset, null, null, date('Y-m-d'), date('Y-m-d'), null, $count = TRUE);
            $this->pagination->initialize($config);
            $this->data['sales'] = $this->sale->get_sale_invoice_list($config['per_page'], $offset, null, 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['employees'] = $this->sale->get_employee_list();
        $this->data['list'] = TRUE;
        $this->layout->title($this->lang->line('manage_sale') . ' | ' . $this->global_setting->brand_title);
        $this->layout->view('sale/index', $this->data);
    }

    /*****************Function medicine_search**********************************
     * @type            : Function
     * @function name   : medicine_search
     * @description     : Load "Medicine Search List" user interface
     *
     * @param           : null
     * @return          : null
     * ********************************************************** */
    public function medicine_search() {
        $search = $this->sale->get_medicine_search($this->input->post('medicine_name'));
        echo json_encode($search);
    }

    /*****************Function customer_search**********************************
     * @type            : Function
     * @function name   : customer_search
     * @description     : Load "Customer Search List" user interface
     *
     * @param           : null
     * @return          : null
     * ********************************************************** */
    public function customer_search() {
        $search = $this->sale->get_customer_search($this->input->post('customer'));
        echo json_encode($search);
    }

    /*****************Function stock_search**********************************
     * @type            : Function
     * @function name   : stock_search
     * @description     : Load "Medicine Stock Search List" user interface
     *
     * @param           : null
     * @return          : null
     * ********************************************************** */
    public function stock_search() {
        $search = $this->sale->get_customer_search($this->input->post('customer'));
        echo json_encode($search);
    }

    /*****************Function add**********************************
     * @type            : Function
     * @function name   : add
     * @description     : Load "Add new sale" user interface
     *                    and process to store "sales" into database
     * @param           : null
     * @return          : null
     * ********************************************************** */
    public function add() {

        check_permission(ADD);

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

    /*****************Function addpatient**********************************
     * @type            : Function
     * @function name   : addpatient
     * @description     : Load "Add Patient" user interface
     *
     * @param           : null
     * @return          : null
     * ********************************************************** */
    public function addpatient() {
        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');

                $data['dob'] = date('Y-m-d', strtotime($this->input->post('dob')));
                $data['age'] = floor((time() - strtotime($data['dob'])) / 31556926);

                $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->sale->get_custom_id('patients', '1');
                // create user
                $data['user_id'] = $this->sale->create_user();

                $insert_id = $this->sale->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 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->sale->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->sale->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 add_sale**********************************
     * @type            : Function
     * @function name   : add_sale
     * @description     : Load "Add new sale" user interface
     *                    and process to store "sales" into database
     * @param           : null
     * @return          : null
     * ********************************************************** */
    public function add_sale() {

        check_permission(ADD);

        if ($_POST) {

            if (!$this->input->post('walking') && !$this->input->post('customer_id')) {
                $array = array('status' => 'failed', 'error' => "Customer or Walking Check 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_custom_id('medicine_invoices', 'INV-', date('Y'), date('m'));
            $data['prev_invoice_id'] = $this->input->post('prev_invoice_id') ?? null;
            $data['invoice_type'] = 'sale';
            // Customer Query
            $customer_id = explode('-', $this->input->post('customer_id'));
            $customer = $this->sale->get_single('patients', array('patient_unique_id' =>  $customer_id[0]));

            if ($this->input->post('walking') == 1) {
                $data['walking'] = '1';
                $data['customer_id'] = NULL;
                $data['customer_name'] = NULL;
            } else {
                if (isset($customer->user_id)) {
                    $data['customer_id'] = $customer->user_id;
                } else {
                    $data['customer_name'] = $this->input->post('customer_id');
                }
            }
            $data['payment_type'] = $this->input->post('payment_type');
            $data['bill_date'] = date('Y-m-d H:i:s', strtotime($this->input->post('bill_date')));

            $data['total_bill'] = '0.00';
            $data['special_discount'] = '0.00';
            $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';

            foreach ($this->input->post('tests') as $mid => $item) {
                $qty = explode('__',$item)[0] ?? 1;
                $medicine_details = $this->sale->get_single('medicines', array('id' => $mid));
                if ($medicine_details) {
                    $data['total_bill'] += ($medicine_details->sell_price * $qty);
                }
            }
            $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['payment_status'] = 'complete';
            $data['note'] = $this->input->post('note') ? $this->input->post('note') : null;

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

            $this->db->trans_start();
            $insert_id = $this->sale->insert('medicine_invoices', $data);

            // Insert Medicine for Invoice Details
            $tests = $this->input->post('tests');
            if (isset($tests) && !empty($tests)) {
                foreach ($this->input->post('tests') as $mid => $item) {
                    $qty = explode('__',$item)[0] ?? 1;
                    $medicine = $this->sale->get_single('medicines', array('id' => $mid));
                    $medicinedata['invoice_id'] = $insert_id;
                    $medicinedata['medicine_id'] = $medicine->id;
                    $medicinedata['batch_no'] = explode('__',$item)[1] ?? '';
                    $medicinedata['quantity'] = $qty;
                    $medicinedata['rate'] = $medicine->sell_price;
                    $medicinedata['total_rate'] = ($medicinedata['quantity'] * $medicinedata['rate']);

                    $medicinedata['status'] = 1;
                    $medicinedata['created_at'] = date('Y-m-d H:i:s');
                    $medicinedata['created_by'] = logged_in_user_id();
                    $this->sale->insert('medicine_invoice_details', $medicinedata);
                }
            }

            // Medicine 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')));
            $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');
            $paymentdata['created_by'] = logged_in_user_id();

            $this->sale->insert('medicine_invoice_payments', $paymentdata);
            $this->db->trans_complete();

            if ($this->db->trans_status() === FALSE) {
                $array = array('status' => 'failled', 'message' => $this->lang->line('unexpected_error'));
                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 invoice**********************************
     * @type            : Function
     * @function name   : invoice
     * @description     : Load "Invoice List" user interface
     *
     * @param           : null
     * @return          : null
     * ********************************************************** */
    public function invoice() {

        check_permission(VIEW);

        $this->data['invoice'] = $this->sale->get_single('medicine_invoices', array('id' => $this->uri->segment(4, 0)));
        $this->data['customer'] = $this->sale->get_single('patients', array('user_id' => $this->data['invoice']->customer_id));
        $this->data['details'] = $this->sale->get_medicine_invoice_list($this->uri->segment(4, 0));

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


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

    public function print() {

        check_permission(VIEW);

        $this->load->library('Numbertowords');
        $this->data['invoice'] = $this->sale->get_single('medicine_invoices', array('id' => $this->input->post('id')));
        $this->data['customer'] = $this->sale->get_single('patients', array('user_id' => $this->data['invoice']->customer_id));
        $this->data['employee'] = $this->sale->get_single('employees', array('user_id' => $this->data['invoice']->created_by));
        $this->data['details'] = $this->sale->get_medicine_invoice_list($this->input->post('id'));
        $this->load->view('pharmacy/sale/print', $this->data);
    }

    /*****************Function history**********************************
     * @type            : Function
     * @function name   : history
     * @description     : Load "Sale payment History List" user interface
     *
     * @param           : null
     * @return          : null
     * ********************************************************** */

    public function history() {

        check_permission(VIEW);

        $this->data['invoice'] = $this->sale->get_single('medicine_invoices', array('id' => $this->uri->segment(4, 0)));
        $this->data['customer'] = $this->sale->get_single('patients', array('user_id' => $this->data['invoice']->customer_id));
        $this->data['payments'] = $this->sale->get_medicine_sale_payment_list($this->uri->segment(4, 0));

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


    /*****************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->sale->get_single('medicine_invoices', array('id' => $this->uri->segment(4, 0)));
        $amount = array('amount' => $invoice->due_amount);
        echo json_encode($amount);
    }

    /*****************Function add_payment**********************************
     * @type            : Function
     * @function name   : add_payment
     * @description     : Load "Payment Amount" user interface
     *
     * @param           : null
     * @return          : null
     * ********************************************************** */
    public function add_payment() {

        check_permission(ADD);

        if ($_POST) {
            $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'] = $this->input->post('amount');
            $data['second_less'] = $this->input->post('second_less');
            $data['note'] = $this->input->post('note');

            if ($this->input->post('amount') > 0) {
                $due = $this->sale->get_single('medicine_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';
                }
                $this->sale->update('medicine_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();

            $this->sale->insert('medicine_invoice_payments', $data);
            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 getInvoiceId**********************************
     * @type            : Function
     * @function name   : getInvoiceId
     * @description     : Load "Payment Amount" user interface
     *
     * @param           : null
     * @return          : null
     * ********************************************************** */

    public function getInvoiceId() {
        $invoice = $this->sale->get_single('medicine_invoices', array('id' => $this->uri->segment(4, 0)));
        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(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('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->sale->update('medicine_invoices', $data, array('id' => $this->input->post('invoice_id')));
                if ($updated_id) {
                    create_log('Has been update a medicine sale 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 gui**********************************
     * @type            : Function
     * @function name   : gui
     * @description     : Load "Add new GUI POS sale" user interface
     *                    and process to store "sales" into database
     * @param           : null
     * @return          : null
     * ********************************************************** */
    public function gui() {

        check_permission(ADD);

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

    /*****************Function delete**********************************
     * @type            : Function
     * @function name   : delete
     * @description     : delete "Sale" data from database
     *
     * @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('pharmacy/sale');
        }

        $sale = $this->sale->get_single('medicine_invoices', array('id' => $id));

        if ($this->sale->delete('medicine_invoices', array('id' => $id))) {
            $this->sale->delete('medicine_invoice_details', array('invoice_id' => $sale->id));
            $this->sale->delete('medicine_invoice_payments', array('invoice_id ' => $sale->id));
            create_log('Has been deleted a medicine sale : ' . $sale->custom_invoice_id);
            success($this->lang->line('delete_success'));
        } else {
            error($this->lang->line('delete_failed'));
        }
        redirect($_SERVER['HTTP_REFERER']);
    }
}
