AnonSec Shell
Server IP : 162.214.74.102  /  Your IP : 216.73.217.103
Web Server : Apache
System : Linux dedi-4363141.lrsys.com.br 3.10.0-1160.119.1.el7.tuxcare.els25.x86_64 #1 SMP Wed Oct 1 17:37:27 UTC 2025 x86_64
User : lrsys ( 1015)
PHP Version : 5.6.40
Disable Function : exec,passthru,shell_exec,system
MySQL : ON  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : ON  |  Sudo : ON  |  Pkexec : ON
Directory :  /home/lrsys/public_html/lrsys_apps/leve/application/plugins/module_billing/controllers/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ HOME ]     

Current File : /home/lrsys/public_html/lrsys_apps/leve/application/plugins/module_billing/controllers/billing.php
<?php

_auth();
$dir = 'module_billing';

$ui->assign('_application_menu', $dir);
$ui->assign('_title', $_L['Billing Module'] . ' - ' . $config['CompanyName']);
$action = $routes['2'];
$user = User::_info();
$ui->assign('user', $user);

switch ($action) {
    case 'expense':
        $css_arr = array(
            'modal',
            'dp/dist/datepicker.min',
            's2/css/select2.min',
            'dropzone/dropzone',
            'redactor/redactor');
        $js_arr = array(
            'redactor/redactor.min',
            's2/js/select2.min',
            'modal',
            'modal-add-contact',
            'add-contact',
            'numeric', '/../../theme/lrsys/lib/jquery.maskMoney.min',
            'dropzone/dropzone',
            'dp/dist/datepicker.min');
        $assets_css = Asset::css($css_arr);
        $assets_js = Asset::js($js_arr);
        $ui->assign('xheader', $assets_css .
                '<link rel="stylesheet" type="text/css" href="' . $_pd . '/assets/css/billing.css"/>' .
                '<link rel="stylesheet" type="text/css" href="' . $_pd . '/assets/css/modal_add.css"/>' .
                '<link rel="stylesheet" type="text/css" href="' . $_pd . '/assets/css/bottom_bar.css"/>');
        $ui->assign('xfooter', $assets_js .
                '<script type="text/javascript" src="' . $_pd . '/assets/js/billing.js"></script>' .
                '<script type="text/javascript" src="' . $_pd . '/assets/js/add-expense.js"></script>' .
                '<script type="text/javascript" src="' . $_pd . '/assets/js/add-register.js"></script>' .
                '<script type="text/javascript" src="' . $_pd . '/assets/js/reverse_transaction.js"></script>' .
                '<script type="text/javascript" src="' . $_pd . '/assets/js/delete_record.js"></script>' .
                '<script type="text/javascript" src="' . $_pd . '/assets/js/bottom_bar.js"></script>'.
                '<script type="text/javascript" src="application/lib/reports/printThis-master/printThis.js"></script>');

        $filter = array();
        $filter['items_per_page'] = 100;
        if ($_SERVER['REQUEST_METHOD'] == 'POST') {
            $filter['search'] = filter_var(_post('search'), FILTER_SANITIZE_STRING);
            $filter['period'] = filter_var(_post('period'), FILTER_SANITIZE_STRING);
            $filter['period_emission'] = filter_var(_post('period_emission'), FILTER_SANITIZE_STRING);
            $filter['situation'] = filter_var(_post('situation'), FILTER_SANITIZE_STRING);
            $filter['period_ini'] = filter_var(_post('period_ini'), FILTER_SANITIZE_STRING);
            $filter['period_end'] = filter_var(_post('period_end'), FILTER_SANITIZE_STRING);
            $filter['period_emission_ini'] = filter_var(_post('period_emission_ini'), FILTER_SANITIZE_STRING);
            $filter['period_emission_end'] = filter_var(_post('period_emission_end'), FILTER_SANITIZE_STRING);
            $filter['id_category'] = filter_var(_post('id_category'), FILTER_SANITIZE_NUMBER_INT);
            $filter['id_payment_method'] = filter_var(_post('id_payment_method'), FILTER_SANITIZE_NUMBER_INT);
            $filter['historic'] = filter_var(_post('historic'), FILTER_SANITIZE_STRING);
            $filter['items_per_page'] = filter_var(_post('items_per_page'), FILTER_SANITIZE_STRING);
        } else {
            if ($i = array_search('search', $routes))
                $filter['search'] = filter_var($routes[$i + 1], FILTER_SANITIZE_STRING);
            if ($i = array_search('period', $routes))
                $filter['period'] = filter_var($routes[$i + 1], FILTER_SANITIZE_STRING);
            
            if ($i = array_search('situation', $routes)) 
            {
                $filter['situation'] = filter_var($routes[$i + 1], FILTER_SANITIZE_STRING);
            }
            else
            {
                $filter['situation'] = 'Em aberto';
            }
                
            if ($i = array_search('period_ini', $routes))
                $filter['period_ini'] = filter_var($routes[$i + 1], FILTER_SANITIZE_STRING);
            if ($i = array_search('period_end', $routes))
                $filter['period_end'] = filter_var($routes[$i + 1], FILTER_SANITIZE_STRING);
            if ($i = array_search('id_category', $routes))
                $filter['id_category'] = filter_var($routes[$i + 1], FILTER_SANITIZE_NUMBER_INT);
            if ($i = array_search('id_payment_method', $routes))
                $filter['id_payment_method'] = filter_var($routes[$i + 1], FILTER_SANITIZE_NUMBER_INT);
            if ($i = array_search('historic', $routes))
                $filter['historic'] = filter_var($routes[$i + 1], FILTER_SANITIZE_STRING);
            if ($i = array_search('items_per_page', $routes))
                $filter['items_per_page'] = filter_var($routes[$i + 1], FILTER_SANITIZE_STRING);
        }

        $select = "SELECT
				mbr.id,
				mbr.id_account,
				mbr.historic,
				mbr.document_number,
				mbr.expiry,
				mbr.emission_date,
				mbr.value,
				mbr.balance,
				mbr.payed,
				mbr.status,
				mbr.type,
				acc.account AS account,
				(GROUP_CONCAT(st.text ORDER BY st.text ASC SEPARATOR ', ')) as markers
			FROM
				module_billing_records mbr
				LEFT JOIN module_billing_records_tags rt ON(mbr.id = rt.id_record)
				LEFT JOIN sys_tags st ON(rt.id_tag = st.id)
				INNER JOIN crm_accounts acc ON(mbr.id_account = acc.id)
			WHERE mbr.type = 'Expense'";
        $where = "";

        // Filtro pelo campo de busca
        if (isset($filter['search']) && $filter['search'] != '') {
            $where .= " AND (acc.account LIKE '%" . $filter['search'] . "%' 
			OR acc.company LIKE '%" . $filter['search'] . "%' 
			OR mbr.document_number LIKE '%" . $filter['search'] . "%')";
        }

        // Filtro por situação
        if (isset($filter['situation']) && $filter['situation'] != '') {
            if ($filter['situation'] == 'Todas')
                $where .= "AND mbr.status IS NOT NULL";
            else if ($filter['situation'] == 'Em aberto')
                $where .= "AND mbr.expiry >= '" . date('Y-m-d') . "' AND mbr.status <> 'Paga'";
            else if ($filter['situation'] == 'Atrasada')
                $where .= "AND mbr.expiry < '" . date('Y-m-d') . "' AND mbr.status <> 'Paga'";
            else
                $where .= "AND mbr.status =  '" . $filter['situation'] . "'";
        }

        // Filtro por períodos
        if (isset($filter['period']) && $filter['period'] != '') {
            if ($filter['period'] == 'all')
                $where .= " AND mbr.expiry IS NOT NULL";
            if ($filter['period'] == 'day')
                $where .= " AND mbr.expiry = '" . date('Y-m-d') . "'";
            if ($filter['period'] == 'week')
                $where .= " AND WEEK(mbr.expiry) = WEEK('" . date('Y-m-d') . "')";
            if ($filter['period'] == 'month')
                $where .= " AND mbr.expiry >= '" . date('Y-m-1') . "' AND mbr.expiry <= '" . date('Y-m-31') . "'";
            if ($filter['period'] == 'interval' && $filter['period_ini'] != '' && $filter['period_end'] != '')
                $where .= " AND mbr.expiry BETWEEN '" . implode('-', array_reverse(explode('/', $filter['period_ini']))) .
                        "' AND '" . implode('-', array_reverse(explode('/', $filter['period_end']))) . "'";
        }
        
        // Filtro por períodos de emissão
        if (isset($filter['period_emission']) && $filter['period_emission'] != '') {
            if ($filter['period_emission'] == 'all')
                $where .= " AND mbr.emission_date IS NOT NULL";
            if ($filter['period_emission'] == 'day')
                $where .= " AND mbr.emission_date = '" . date('Y-m-d') . "'";
            if ($filter['period_emission'] == 'week')
                $where .= " AND WEEK(mbr.emission_date) = WEEK('" . date('Y-m-d') . "')";
            if ($filter['period_emission'] == 'month')
                $where .= " AND mbr.emission_date >= '" . date('Y-m-1') . "' AND mbr.emission_date <= '" . date('Y-m-31') . "'";
            if ($filter['period_emission'] == 'interval' && $filter['period_emission_ini'] != '' && $filter['period_emission_end'] != '')
                $where .= " AND mbr.emission_date BETWEEN '" . implode('-', array_reverse(explode('/', $filter['period_emission_ini']))) .
                        "' AND '" . implode('-', array_reverse(explode('/', $filter['period_emission_end']))) . "'";
        }
        else
        {
//            $filter['period_emission'] = 'day';
//            $where .= " AND mbr.emission_date = '" . date('Y-m-d') . "'";
        }

        // Filtra por histórico
        if (isset($filter['historic']) && $filter['historic'] != "") {
            $where .= " AND mbr.historic LIKE '%" . $filter['historic'] . "%'";
        }

        // Filtra por categoria
        if (isset($filter['id_category']) && $filter['id_category'] != "") {
            if ($filter['id_category'] == 'without')
                $where .= " AND mbr.id_category IS NULL";
            else if ($filter['id_category'] == 'all')
                unset($filter['id_category']);
            else
                $where .= " AND mbr.id_category = '" . (int) $filter['id_category'] . "'";
        }

        // Filtra por método de pagamento
        if (isset($filter['id_payment_method']) && $filter['id_payment_method'] != "") {
            if ($filter['id_payment_method'] == 'all')
                unset($filter['id_payment_method']);
            else if ($filter['id_payment_method'] == 'unknown')
                $where .= " AND mbr.id_payment_method IS NULL";
            else
                $where .= " AND mbr.id_payment_method = '" . (int) $filter['id_payment_method'] . "'";
        }

        $group_by = " GROUP BY mbr.id ";
        $order_by = " ORDER BY mbr.expiry ASC ";

        $page = isset($routes['3']) ? $routes['3'] : 1;
        $query = $select . $where . $group_by . $order_by;

        if ($filter['items_per_page'] != 'all')
            $filter['items_per_page'] = ($filter['items_per_page'] > 0) ? $filter['items_per_page'] : 10;

        $paginator = new ModulePaginator('module_billing_records', $query, $filter);
        $records = $paginator->setItemsPerPage($filter['items_per_page'])
                ->setCurrentPageNumber($page)
                ->run();

        $ui->assign('records', $records);
        $ui->assign('paginator', $paginator);

        $categories = ORM::for_table('sys_cats')
                        ->where('type', 'Expense')->find_many();
        $ui->assign('expense_categories', $categories);

        $payment_methods = ORM::for_table('sys_pmethods')->find_many();
        $ui->assign('payment_methods', $payment_methods);
        
        $where_aux = 'mbr.type = "Expense"';
        if($where != '')
        {
            $where_aux .= ' '.$where;
        }
        $totais = ORM::for_table('module_billing_records')
                ->table_alias('mbr')
                ->select_expr("COUNT(mbr.id)", 'records')
                ->select_expr('ROUND(SUM(mbr.value), 2)', 'value')
                ->select_expr('ROUND(SUM(mbr.balance), 2)', 'balance')
                ->select_expr("ROUND(SUM(mbr.payed), 2)", 'payed')
                ->left_outer_join('module_billing_records_tags', 'mbr.id = rt.id_record', 'rt')
                ->left_outer_join('sys_tags', 'rt.id_tag = st.id', 'st')
                ->inner_join('crm_accounts', 'mbr.id_account = acc.id', 'acc')
                ->where_raw($where_aux)
                ->find_one();

        $ui->assign('bar_records', $totais->records);
        $ui->assign('bar_value', $totais->value);
        $ui->assign('bar_balance', $totais->balance);
        $ui->assign('bar_payed', $totais->payed);
        $ui->assign('type', 'Expense');

        $ui->assign('jsvar', '
			_L[\'Remove\'] = \'' . $_L['Remove'] . '\';  
			_L[\'Select\'] = \'' . $_L['Select'] . '\';  
			_L[\'Cancel\'] = \'' . $_L['Cancel'] . '\';
			_L[\'Provider is Required\'] = \'' . $_L['Provider is Required'] . '\';  
			_L[\'Expiry is Required\'] = \'' . $_L['Expiry is Required'] . '\';
			_L[\'Value is Required\'] = \'' . $_L['Value is Required'] . '\';  
			_L[\'Category is Required\'] = \'' . $_L['Category is Required'] . '\';
			_L[\'Number of installments must be greater than 1\'] = \'' . $_L['Number of installments must be greater than 1'] . '\';
			_L[\'CPF Invalid\'] = \'' . $_L['CPF Invalid'] . '\';
                        _L[\'Module Billing Please select at least one account\'] = \'' . $_L['Module Billing Please select at least one account'] . '\';
                        _L[\'Module Billing Accounts with the total\'] = \'' . $_L['Module Billing Accounts with the total'] . '\';		
');

//		$ui->assign('stored_images', []); var existingFiles = [' . '];

        $ui->assign('filter', $filter);
        $ui->assign('_st', $_L['Expense list']);
        $ui->assign('_include', $action);
        $ui->display('wrapper.tpl');

        break;

    case 'income':
        $css_arr = array(
            'modal',
            'dp/dist/datepicker.min',
            's2/css/select2.min',
            'dropzone/dropzone',
            'redactor/redactor');
        $js_arr = array(
            'redactor/redactor.min',
            's2/js/select2.min',
            'modal',
            'modal-add-contact',
            'add-contact',
            'numeric', '/../../theme/lrsys/lib/jquery.maskMoney.min',
            'dropzone/dropzone',
            'dp/dist/datepicker.min');
        $assets_css = Asset::css($css_arr);
        $assets_js = Asset::js($js_arr);
        $ui->assign('xheader', $assets_css .
                '<link rel="stylesheet" type="text/css" href="' . $_pd . '/assets/css/billing.css"/>' .
                '<link rel="stylesheet" type="text/css" href="' . $_pd . '/assets/css/modal_add.css"/>' .
                '<link rel="stylesheet" type="text/css" href="' . $_pd . '/assets/css/bottom_bar.css"/>');
        $ui->assign('xfooter', $assets_js .
                '<script type="text/javascript" src="' . $_pd . '/assets/js/billing.js"></script>' .
                '<script type="text/javascript" src="' . $_pd . '/assets/js/add-income.js"></script>' .
                '<script type="text/javascript" src="' . $_pd . '/assets/js/add-register.js"></script>' .
                '<script type="text/javascript" src="' . $_pd . '/assets/js/reverse_transaction.js"></script>' .
                '<script type="text/javascript" src="' . $_pd . '/assets/js/delete_record.js"></script>' .
                '<script type="text/javascript" src="' . $_pd . '/assets/js/bottom_bar.js"></script>'.
                '<script type="text/javascript" src="application/lib/reports/printThis-master/printThis.js"></script>');

        $filter = array();
        
        // TODO: ITEM POR PÁGINA
        // PEGAR DO CONFIG
        $filter['items_per_page'] = 100;
        
//        var_dump($_POST);exit;
        
        if ($_SERVER['REQUEST_METHOD'] == 'POST') {
            $filter['search'] = filter_var(_post('search'), FILTER_SANITIZE_STRING);
            $filter['period'] = filter_var(_post('period'), FILTER_SANITIZE_STRING);
            $filter['period_emission'] = filter_var(_post('period_emission'), FILTER_SANITIZE_STRING);
            $filter['situation'] = filter_var(_post('situation'), FILTER_SANITIZE_STRING);
            $filter['period_ini'] = filter_var(_post('period_ini'), FILTER_SANITIZE_STRING);
            $filter['period_end'] = filter_var(_post('period_end'), FILTER_SANITIZE_STRING);
            $filter['period_emission_ini'] = filter_var(_post('period_emission_ini'), FILTER_SANITIZE_STRING);
            $filter['period_emission_end'] = filter_var(_post('period_emission_end'), FILTER_SANITIZE_STRING);
            $filter['id_category'] = filter_var(_post('id_category'), FILTER_SANITIZE_NUMBER_INT);
            $filter['id_payment_method'] = filter_var(_post('id_payment_method'), FILTER_SANITIZE_NUMBER_INT);
            $filter['historic'] = filter_var(_post('historic'), FILTER_SANITIZE_STRING);
            $filter['items_per_page'] = filter_var(_post('items_per_page'), FILTER_SANITIZE_STRING);
        } else {
            if ($i = array_search('search', $routes))
                $filter['search'] = filter_var($routes[$i + 1], FILTER_SANITIZE_STRING);
            if ($i = array_search('period', $routes))
                $filter['period'] = filter_var($routes[$i + 1], FILTER_SANITIZE_STRING);
            
            if ($i = array_search('situation', $routes)) 
            {
                $filter['situation'] = filter_var($routes[$i + 1], FILTER_SANITIZE_STRING);
            }
            else
            {
                $filter['situation'] = 'Em aberto';
            }
            
            if ($i = array_search('period_ini', $routes))
                $filter['period_ini'] = filter_var($routes[$i + 1], FILTER_SANITIZE_STRING);
            if ($i = array_search('period_end', $routes))
                $filter['period_end'] = filter_var($routes[$i + 1], FILTER_SANITIZE_STRING);
            if ($i = array_search('id_category', $routes))
                $filter['id_category'] = filter_var($routes[$i + 1], FILTER_SANITIZE_NUMBER_INT);
            if ($i = array_search('id_payment_method', $routes))
                $filter['id_payment_method'] = filter_var($routes[$i + 1], FILTER_SANITIZE_NUMBER_INT);
            if ($i = array_search('historic', $routes))
                $filter['historic'] = filter_var($routes[$i + 1], FILTER_SANITIZE_STRING);
            if ($i = array_search('items_per_page', $routes))
                $filter['items_per_page'] = filter_var($routes[$i + 1], FILTER_SANITIZE_STRING);
        }

        $select = "SELECT
				mbr.id,
				mbr.id_account,
				mbr.historic,
				mbr.document_number,
				mbr.expiry,
				mbr.emission_date,
				mbr.value,
				mbr.balance,
				mbr.payed,
				mbr.status,
				mbr.type,
				acc.account AS account,
				(GROUP_CONCAT(st.text ORDER BY st.text ASC SEPARATOR ', ')) as markers
			FROM
				module_billing_records mbr
				LEFT JOIN module_billing_records_tags rt ON(mbr.id = rt.id_record)
				LEFT JOIN sys_tags st ON(rt.id_tag = st.id)
				INNER JOIN crm_accounts acc ON(mbr.id_account = acc.id)
			WHERE mbr.type = 'Income'";
        $where = "";

        // Filtro pelo campo de busca
        if (isset($filter['search']) && $filter['search'] != '') {
            $where .= " AND (acc.account LIKE '%" . $filter['search'] . "%' 
			OR acc.company LIKE '%" . $filter['search'] . "%'
			OR mbr.document_number LIKE '%" . $filter['search'] . "%')";
        }

        // Filtro por situação
        if (isset($filter['situation']) && $filter['situation'] != '') {
            if ($filter['situation'] == 'Todas')
                $where .= "AND mbr.status IS NOT NULL";
            else if ($filter['situation'] == 'Em aberto')
                $where .= "AND mbr.expiry >= '" . date('Y-m-d') . "' AND mbr.status <> 'Paga'";
            else if ($filter['situation'] == 'Atrasada')
                $where .= "AND mbr.expiry < '" . date('Y-m-d') . "' AND mbr.status <> 'Paga'";
            else
                $where .= "AND mbr.status = '" . $filter['situation'] . "'";
        }

        // Filtro por períodos
        if (isset($filter['period']) && $filter['period'] != '') {
            if ($filter['period'] == 'all')
                $where .= " AND mbr.expiry IS NOT NULL";
            if ($filter['period'] == 'day')
                $where .= " AND mbr.expiry = '" . date('Y-m-d') . "'";
            if ($filter['period'] == 'week')
                $where .= " AND WEEK(mbr.expiry) = WEEK('" . date('Y-m-d') . "')";
            if ($filter['period'] == 'month')
                $where .= " AND mbr.expiry >= '" . date('Y-m-1') . "' AND mbr.expiry <= '" . date('Y-m-31') . "'";
            if ($filter['period'] == 'interval' && $filter['period_ini'] != '' && $filter['period_end'] != '')
                $where .= " AND mbr.expiry BETWEEN '" . implode('-', array_reverse(explode('/', $filter['period_ini']))) .
                        "' AND '" . implode('-', array_reverse(explode('/', $filter['period_end']))) . "'";
        }
        
        // Filtro por períodos de emissão
        if (isset($filter['period_emission']) && $filter['period_emission'] != '') {
            if ($filter['period_emission'] == 'all')
                $where .= " AND mbr.emission_date IS NOT NULL";
            if ($filter['period_emission'] == 'day')
                $where .= " AND mbr.emission_date = '" . date('Y-m-d') . "'";
            if ($filter['period_emission'] == 'week')
                $where .= " AND WEEK(mbr.emission_date) = WEEK('" . date('Y-m-d') . "')";
            if ($filter['period_emission'] == 'month')
                $where .= " AND mbr.emission_date >= '" . date('Y-m-1') . "' AND mbr.emission_date <= '" . date('Y-m-31') . "'";
            if ($filter['period_emission'] == 'interval' && $filter['period_emission_ini'] != '' && $filter['period_emission_end'] != '')
                $where .= " AND mbr.emission_date BETWEEN '" . implode('-', array_reverse(explode('/', $filter['period_emission_ini']))) .
                        "' AND '" . implode('-', array_reverse(explode('/', $filter['period_emission_end']))) . "'";
        }
        else
        {
//            $filter['period_emission'] = 'day';
//            $where .= " AND mbr.emission_date = '" . date('Y-m-d') . "'";
        }

        // Filtra por histórico
        if (isset($filter['historic']) && $filter['historic'] != "") {
            $where .= " AND mbr.historic LIKE '%" . $filter['historic'] . "%'";
        }

        // Filtra por categoria
        if (isset($filter['id_category']) && $filter['id_category'] != "") {
            if ($filter['id_category'] == 'without')
                $where .= " AND mbr.id_category IS NULL";
            else if ($filter['id_category'] == 'all')
                unset($filter['id_category']);
            else
                $where .= " AND mbr.id_category = '" . (int) $filter['id_category'] . "'";
        }

        // Filtra por método de pagamento
        if (isset($filter['id_payment_method']) && $filter['id_payment_method'] != "") {
            if ($filter['id_payment_method'] == 'all')
                unset($filter['id_payment_method']);
            else if ($filter['id_payment_method'] == 'unknown')
                $where .= " AND mbr.id_payment_method IS NULL";
            else
                $where .= " AND mbr.id_payment_method = '" . (int) $filter['id_payment_method'] . "'";
        }

        $group_by = " GROUP BY mbr.id ";
        $order_by = " ORDER BY mbr.expiry ASC ";

        $page = isset($routes['3']) ? $routes['3'] : 1;
        $query = $select . $where . $group_by . $order_by;

        if ($filter['items_per_page'] != 'all')
            $filter['items_per_page'] = ($filter['items_per_page'] > 0) ? $filter['items_per_page'] : 100;

        $paginator = new ModulePaginator('module_billing_records', $query, $filter);
        $records = $paginator->setItemsPerPage($filter['items_per_page'])
                ->setCurrentPageNumber($page)
                ->run();

        $ui->assign('records', $records);
        $ui->assign('paginator', $paginator);

        $categories = ORM::for_table('sys_cats')
                        ->where('type', 'Income')->find_many();
        $ui->assign('income_categories', $categories);

        $payment_methods = ORM::for_table('sys_pmethods')->find_many();
        $ui->assign('payment_methods', $payment_methods);

        // Query que soma os totais das contas a pagar
//        $select_count = " SELECT COUNT(mbr.id) as records,
//                    ROUND(SUM(mbr.value), 2) as value,
//                    ROUND(SUM(mbr.balance), 2) as balance,
//                    ROUND(SUM(mbr.payed), 2) as payed
//            FROM
//                    module_billing_records mbr
//                    LEFT JOIN module_billing_records_tags rt ON(mbr.id = rt.id_record)
//                    LEFT JOIN sys_tags st ON(rt.id_tag = st.id)
//                    INNER JOIN crm_accounts acc ON(mbr.id_account = acc.id)
//            WHERE mbr.type = 'Income'";
        
        $where_aux = 'mbr.type = "Income"';
        if($where != '')
        {
            $where_aux .= ' '.$where;
        }
        $totais = ORM::for_table('module_billing_records')
                ->table_alias('mbr')
                ->select_expr("COUNT(mbr.id)", 'records')
                ->select_expr('ROUND(SUM(mbr.value), 2)', 'value')
                ->select_expr('ROUND(SUM(mbr.balance), 2)', 'balance')
                ->select_expr("ROUND(SUM(mbr.payed), 2)", 'payed')
                ->left_outer_join('module_billing_records_tags', 'mbr.id = rt.id_record', 'rt')
                ->left_outer_join('sys_tags', 'rt.id_tag = st.id', 'st')
                ->inner_join('crm_accounts', 'mbr.id_account = acc.id', 'acc')
                ->where_raw($where_aux)
                ->find_one();
        
        $ui->assign('bar_records', $totais->records);
        $ui->assign('bar_value', $totais->value);
        $ui->assign('bar_balance', $totais->balance);
        $ui->assign('bar_payed', $totais->payed);
        $ui->assign('type', 'Income');

        $ui->assign('jsvar', '
			_L[\'Remove\'] = \'' . $_L['Remove'] . '\';  
			_L[\'Select\'] = \'' . $_L['Select'] . '\';  
			_L[\'Cancel\'] = \'' . $_L['Cancel'] . '\';
			_L[\'Customer is Required\'] = \'' . $_L['Customer is Required'] . '\';  
			_L[\'Expiry is Required\'] = \'' . $_L['Expiry is Required'] . '\';
			_L[\'Value is Required\'] = \'' . $_L['Value is Required'] . '\';  
			_L[\'Category is Required\'] = \'' . $_L['Category is Required'] . '\';
			_L[\'Number of installments must be greater than 1\'] = \'' . $_L['Number of installments must be greater than 1'] . '\';
			_L[\'CPF Invalid\'] = \'' . $_L['CPF Invalid'] . '\';
                        _L[\'Module Billing Please select at least one account\'] = \'' . $_L['Module Billing Please select at least one account'] . '\';
                        _L[\'Module Billing Accounts with the total\'] = \'' . $_L['Module Billing Accounts with the total'] . '\';

		');
        $ui->assign('filter', $filter);
        $ui->assign('_st', $_L['Income list']);
        $ui->assign('_include', $action);
        $ui->display('wrapper.tpl');

        break;
        
    case 'cashier':
        $css_arr = array(
            'modal',
            'dp/dist/datepicker.min',
            's2/css/select2.min',
            'dropzone/dropzone',
            'redactor/redactor');
        $js_arr = array(
            'redactor/redactor.min',
            's2/js/select2.min',
            'modal',
            'modal-add-contact',
            'add-contact',
            'numeric', '/../../theme/lrsys/lib/jquery.maskMoney.min',
            'dropzone/dropzone',
            'dp/dist/datepicker.min');
        $assets_css = Asset::css($css_arr);
        $assets_js = Asset::js($js_arr);
        $ui->assign('xheader', $assets_css .
                '<link rel="stylesheet" type="text/css" href="' . $_pd . '/assets/css/billing.css"/>' .
                '<link rel="stylesheet" type="text/css" href="' . $_pd . '/assets/css/modal_add.css"/>' .
                '<link rel="stylesheet" type="text/css" href="' . $_pd . '/assets/css/bottom_bar.css"/>');
        $ui->assign('xfooter', $assets_js .
                '<script type="text/javascript" src="' . $_pd . '/assets/js/billing.js"></script>' .
                '<script type="text/javascript" src="' . $_pd . '/assets/js/add-income.js"></script>' .
                '<script type="text/javascript" src="' . $_pd . '/assets/js/add-register.js"></script>' .
                '<script type="text/javascript" src="' . $_pd . '/assets/js/reverse_transaction.js"></script>' .
                '<script type="text/javascript" src="' . $_pd . '/assets/js/delete_record.js"></script>' .
                '<script type="text/javascript" src="' . $_pd . '/assets/js/bottom_bar.js"></script>'.
                '<script type="text/javascript" src="application/lib/reports/printThis-master/printThis.js"></script>');

        $filter = array();
        
        // TODO: ITEM POR PÁGINA
        // PEGAR DO CONFIG
        $filter['items_per_page'] = 100;
        
        if ($_SERVER['REQUEST_METHOD'] == 'POST') {
            $filter['search'] = filter_var(_post('search'), FILTER_SANITIZE_STRING);
            $filter['period'] = filter_var(_post('period'), FILTER_SANITIZE_STRING);
            $filter['situation'] = filter_var(_post('situation'), FILTER_SANITIZE_STRING);
            $filter['period_ini'] = filter_var(_post('period_ini'), FILTER_SANITIZE_STRING);
            $filter['period_end'] = filter_var(_post('period_end'), FILTER_SANITIZE_STRING);
            $filter['id_category'] = filter_var(_post('id_category'), FILTER_SANITIZE_NUMBER_INT);
            $filter['id_payment_method'] = filter_var(_post('id_payment_method'), FILTER_SANITIZE_NUMBER_INT);
            $filter['historic'] = filter_var(_post('historic'), FILTER_SANITIZE_STRING);
            $filter['items_per_page'] = filter_var(_post('items_per_page'), FILTER_SANITIZE_STRING);
        } else {
            if ($i = array_search('search', $routes))
                $filter['search'] = filter_var($routes[$i + 1], FILTER_SANITIZE_STRING);
            if ($i = array_search('period', $routes))
                $filter['period'] = filter_var($routes[$i + 1], FILTER_SANITIZE_STRING);
            if ($i = array_search('situation', $routes))
                $filter['situation'] = filter_var($routes[$i + 1], FILTER_SANITIZE_STRING);
            if ($i = array_search('period_ini', $routes))
                $filter['period_ini'] = filter_var($routes[$i + 1], FILTER_SANITIZE_STRING);
            if ($i = array_search('period_end', $routes))
                $filter['period_end'] = filter_var($routes[$i + 1], FILTER_SANITIZE_STRING);
            if ($i = array_search('id_category', $routes))
                $filter['id_category'] = filter_var($routes[$i + 1], FILTER_SANITIZE_NUMBER_INT);
            if ($i = array_search('id_payment_method', $routes))
                $filter['id_payment_method'] = filter_var($routes[$i + 1], FILTER_SANITIZE_NUMBER_INT);
            if ($i = array_search('historic', $routes))
                $filter['historic'] = filter_var($routes[$i + 1], FILTER_SANITIZE_STRING);
            if ($i = array_search('items_per_page', $routes))
                $filter['items_per_page'] = filter_var($routes[$i + 1], FILTER_SANITIZE_STRING);
        }

        $select = "SELECT
				mbr.id,
				mbr.id_account,
				mbr.historic,
				mbr.document_number,
				mbr.expiry,
				mbr.emission_date,
				mbr.value,
				mbr.balance,
				mbr.payed,
				mbr.status,
				mbr.type,
				acc.account AS account,
				(GROUP_CONCAT(st.text ORDER BY st.text ASC SEPARATOR ', ')) as markers
			FROM
				module_billing_records mbr
				LEFT JOIN module_billing_records_tags rt ON(mbr.id = rt.id_record)
				LEFT JOIN sys_tags st ON(rt.id_tag = st.id)
				INNER JOIN crm_accounts acc ON(mbr.id_account = acc.id)
			WHERE mbr.type = 'Income'";
        $where = "";

        // Filtro pelo campo de busca
        if (isset($filter['search']) && $filter['search'] != '') {
            $where .= " AND (acc.account LIKE '%" . $filter['search'] . "%' 
			OR acc.company LIKE '%" . $filter['search'] . "%'
			OR mbr.document_number LIKE '%" . $filter['search'] . "%')";
        }

        // Filtro por situação
        if (isset($filter['situation']) && $filter['situation'] != '') {
            if ($filter['situation'] == 'Todas')
                $where .= "AND mbr.status IS NOT NULL";
            else if ($filter['situation'] == 'Em aberto')
                $where .= "AND mbr.expiry >= '" . date('Y-m-d') . "' AND mbr.status <> 'Paga'";
            else if ($filter['situation'] == 'Atrasada')
                $where .= "AND mbr.expiry < '" . date('Y-m-d') . "' AND mbr.status <> 'Paga'";
            else
                $where .= "AND mbr.status = '" . $filter['situation'] . "'";
        }

        // Filtro por períodos
        if (isset($filter['period']) && $filter['period'] != '') {
            if ($filter['period'] == 'all')
                $where .= " AND mbr.emission_date IS NOT NULL";
            if ($filter['period'] == 'day')
                $where .= " AND mbr.emission_date = '" . date('Y-m-d') . "'";
            if ($filter['period'] == 'week')
                $where .= " AND WEEK(mbr.emission_date) = WEEK('" . date('Y-m-d') . "')";
            if ($filter['period'] == 'month')
                $where .= " AND mbr.emission_date >= '" . date('Y-m-1') . "' AND mbr.emission_date <= '" . date('Y-m-31') . "'";
            if ($filter['period'] == 'interval' && $filter['period_ini'] != '' && $filter['period_end'] != '')
                $where .= " AND mbr.emission_date BETWEEN '" . implode('-', array_reverse(explode('/', $filter['period_ini']))) .
                        "' AND '" . implode('-', array_reverse(explode('/', $filter['period_end']))) . "'";
        }
        else
        {
            $filter['period'] = 'day';
            $where .= " AND mbr.emission_date = '" . date('Y-m-d') . "'";
        }


        // Filtra por categoria
        if (isset($filter['id_category']) && $filter['id_category'] != "") {
            if ($filter['id_category'] == 'without')
                $where .= " AND mbr.id_category IS NULL";
            else if ($filter['id_category'] == 'all')
                unset($filter['id_category']);
            else
                $where .= " AND mbr.id_category = '" . (int) $filter['id_category'] . "'";
        }

        // Filtra por método de pagamento
        if (isset($filter['id_payment_method']) && $filter['id_payment_method'] != "") {
            if ($filter['id_payment_method'] == 'all')
                unset($filter['id_payment_method']);
            else if ($filter['id_payment_method'] == 'unknown')
                $where .= " AND mbr.id_payment_method IS NULL";
            else
                $where .= " AND mbr.id_payment_method = '" . (int) $filter['id_payment_method'] . "'";
        }

        $filter['items_per_page'] = 'all';
        
        $where_aux = 'mbr.type = "Income"';
        if($where != '')
        {
            $where_aux .= ' '.$where;
        }
        
        $records = ORM::for_table('module_billing_records')
                ->table_alias('mbr')
                ->select('mbr.created_by', 'user_name_id')
                ->select('syu.fullname', 'user_name')
                ->select('spm.name', 'pmethod')
                ->select_expr("COUNT(mbr.id)", 'records')
                ->select_expr('ROUND(SUM(mbr.value), 2)', 'value')
                ->select_expr('ROUND(SUM(mbr.balance), 2)', 'balance')
                ->select_expr("ROUND(SUM(mbr.payed), 2)", 'payed')
                ->inner_join('crm_accounts', 'mbr.id_account = acc.id', 'acc')
                ->inner_join('sys_users', 'mbr.created_by = syu.id', 'syu')
                ->inner_join('sys_pmethods', 'mbr.id_payment_method = spm.id', 'spm')
                ->where_raw($where_aux)
                ->group_by('mbr.created_by')
                ->group_by('mbr.id_payment_method')
                ->order_by_asc('mbr.created_by')
                ->order_by_asc('mbr.id_payment_method')
                ->find_many();
        $arr_pmethods = array(); 
        foreach($records as $record)
        {
//            var_dump($record);
            if(!in_array($record['pmethod'], $arr_pmethods))
            {
                $arr_pmethods[] = $record['pmethod'];
            }
        }
//        exit;
        $ui->assign('records', $records);
        $ui->assign('arr_pmethods', $arr_pmethods);
       

        $categories = ORM::for_table('sys_cats')
                        ->where('type', 'Income')->find_many();
        $ui->assign('income_categories', $categories);

        $payment_methods = ORM::for_table('sys_pmethods')->find_many();
        $ui->assign('payment_methods', $payment_methods);
        
        
        $totais = ORM::for_table('module_billing_records')
                ->table_alias('mbr')
                ->select_expr("COUNT(mbr.id)", 'records')
                ->select_expr('ROUND(SUM(mbr.value), 2)', 'value')
                ->select_expr('ROUND(SUM(mbr.balance), 2)', 'balance')
                ->select_expr("ROUND(SUM(mbr.payed), 2)", 'payed')
                ->left_outer_join('module_billing_records_tags', 'mbr.id = rt.id_record', 'rt')
                ->left_outer_join('sys_tags', 'rt.id_tag = st.id', 'st')
                ->inner_join('crm_accounts', 'mbr.id_account = acc.id', 'acc')
                ->where_raw($where_aux)
                ->find_one();
        
        $ui->assign('bar_records', $totais->records);
        $ui->assign('bar_value', $totais->value);
        $ui->assign('bar_balance', $totais->balance);
        $ui->assign('bar_payed', $totais->payed);
        $ui->assign('type', 'Income');

        $ui->assign('jsvar', '
			_L[\'Remove\'] = \'' . $_L['Remove'] . '\';  
			_L[\'Select\'] = \'' . $_L['Select'] . '\';  
			_L[\'Cancel\'] = \'' . $_L['Cancel'] . '\';
			_L[\'Customer is Required\'] = \'' . $_L['Customer is Required'] . '\';  
			_L[\'Expiry is Required\'] = \'' . $_L['Expiry is Required'] . '\';
			_L[\'Value is Required\'] = \'' . $_L['Value is Required'] . '\';  
			_L[\'Category is Required\'] = \'' . $_L['Category is Required'] . '\';
			_L[\'Number of installments must be greater than 1\'] = \'' . $_L['Number of installments must be greater than 1'] . '\';
			_L[\'CPF Invalid\'] = \'' . $_L['CPF Invalid'] . '\';
                        _L[\'Module Billing Please select at least one account\'] = \'' . $_L['Module Billing Please select at least one account'] . '\';
                        _L[\'Module Billing Accounts with the total\'] = \'' . $_L['Module Billing Accounts with the total'] . '\';

		');
        $ui->assign('filter', $filter);
        $ui->assign('_st', $_L['Income list']);
        $ui->assign('_include', $action);
        $ui->display('wrapper.tpl');

        break;

    case 'modal_add_expense':
        $ui->assign('action', 'add');

        $id = filter_var($routes[3], FILTER_SANITIZE_NUMBER_INT);

        // Se tiver ID é edição
        if ($id != '' && $id > 0) {
            $record = ORM::for_table('module_billing_records')
                    ->table_alias('rec')
                    ->select('rec.*')
                    ->select_expr("(SELECT 
					GROUP_CONCAT(stags.text)
					FROM sys_tags stags 
					INNER JOIN module_billing_records_tags rt ON(stags.id = rt.id_tag) 
					WHERE rt.id_record = rec.id
					GROUP BY rt.id_record)", "tags")
                    ->find_one($id);
            $ui->assign('record', $record);
            $ui->assign('action', 'edit');

            $cats = ORM::for_table('sys_cats')
                    ->table_alias('st')
                    ->select('st.id')
                    ->select('st.name')
                    ->find_array();
            $ui->assign('cats', $cats);

            $markers = ORM::for_table('sys_tags')
                    ->table_alias('st')
                    ->select('st.id')
                    ->select('st.text')
                    ->where('type', 'Billing')
                    ->find_many();
            $ui->assign('markers', $markers);

            $accounts = ORM::for_table('crm_accounts')
                    ->table_alias('acc')
                    ->select('acc.id')
                    ->select('acc.account')
//                    ->select_expr("IF(acc.company = '',acc.account,CONCAT(acc.account, ' / <br>', acc.company))", 'account')
                    ->left_outer_join('crm_accounts_groups', 'acc.id = cag.crm_accounts_id', 'cag')
                    ->left_outer_join('crm_groups', 'cag.crm_group_id = cg.id', 'cg')
                    ->where_raw('cg.gname = ? OR acc.id = ?', ['Payee', $record->id_account])
                    ->find_array();
            $ui->assign('accounts', $accounts);

            $cost_center = ORM::for_table('module_billing_cost_center')
                    ->table_alias('ccent')
                    ->select('ccent.*')
                    ->order_by_asc('name')
                    ->find_array();
            $ui->assign('cost_center', $cost_center);
        }

        $ui->assign('_st', $_L['Expense add']);
        $ui->display($pl_path . 'views/modal_add_expense.tpl');

        break;

    case 'add_expense_post':
        $id = filter_var(_post('id', 0), FILTER_SANITIZE_NUMBER_INT);
        $idaccount = filter_var(_post('id_account'), FILTER_SANITIZE_STRING);
        $expiry_br = _post('expiry');
        $value = Finance::amount_fix(_post('value'));
        $emission_date = implode('-', array_reverse(explode('/', _post('emission_date'))));
        $document_number = _post('document_number');
        $historic = _post('historic');
        $idcategory = _post('id_category');
        $id_cost_center =  intval(_post('id_cost_center'));
        $occurrence = _post('occurrence');
        $occurrence_installments = _post('occurrence_installments');
        $competence = _post('competence');
        $images = _post('images');
        $type = 'Expense';
        $app_fiscal_nfe_imported_id=_post('app_fiscal_nfe_imported_id');
        $rowDuplicada=_post('row_duplicata');

        $attachment = ($images != "") ? json_encode(explode(',', $images), JSON_FORCE_OBJECT) : '';

        $expiry_date = new DateTime();
        list($year, $month, $day) = array_reverse(explode('/', $expiry_br));
        $expiry_date->setDate($year, $month, $day);

//        $value = str_replace(',', '.', str_replace('.', '', $value));
        
        //redirect, para saber se permite as validações e redirects do sistema
        $redirect=true;
       
        if(isset($routes['3'])){
            if( $routes['3']=='json'){
                $redirect=false;
            }
        }
        if($redirect){
            // Validações de Backend
            ($idaccount == '') ? r2(U . 'module_billing/billing/expense', 'e', $_L['Account is Required']) : '';
            ($expiry_br == '') ? r2(U . 'module_billing/billing/expense', 'e', $_L['Expiry is Required']) : '';
            ($value == '') ? r2(U . 'module_billing/billing/expense', 'e', $_L['Value is Required']) : '';
            ($idcategory == '') ? r2(U . 'module_billing/billing/expense', 'e', $_L['Category is Required']) : '';
        
        // Se receber o nome de um novo fornecedor ao invés de um ID,
        // cadastrar o novo fornecedor
        if (((int) $idaccount) <= 0) {
            $account_exists = ORM::for_table('crm_accounts')->where('account', $idaccount)->find_one();
            // Verifica se o fornecedor já existe
            if ($account_exists->account)
                r2(U . 'module_billing/billing/expense', 'e', $_L['Supplier already exists']);

            $account = ORM::for_table('crm_accounts')->create();
            $account->account = $idaccount;
            $account->currency = 1;
            $account->save();
            $idaccount = $account->id();
        }
        }
        // Edição
        if ($id != '' && $id > 0) {
            $record = ORM::for_table('module_billing_records')->find_one($id);
            $record->id_account = $idaccount;
            $record->expiry = $expiry_date->format('Y-m-d');
            $record->value = $value;
            $record->balance = $value;
            $record->emission_date = $emission_date;
            $record->document_number = $document_number;
            $record->historic = $historic;
            $record->id_category = $idcategory;
            if(isset($id_cost_center) && $id_cost_center>0){
                $record->id_cost_center = $id_cost_center;
            }
            $record->occurrence = $occurrence;
            $record->occurrence_expiry = $expiry_date->format('d');
            if(!empty($occurrence_installments)){
                $record->occurrence_installments = $occurrence_installments;
            }
            $record->competence = $competence;
            $record->type = $type;
            $record->status = ($expiry_date > (new DateTime('now')) ? 'Em aberto' : 'Atrasada');
//            $record->app_fiscal_nfe_imported_id=$app_fiscal_nfe_imported_id;
//            $record->row_duplicata=$rowDuplicada;
            $record->save();
            $id_record = $record->id();

            // Insere as tags na tabela N:N
            if (isset($_POST['markers']) && count($_POST['markers']) > 0) {
                foreach ($_POST['markers'] as $marker) {
                    // Deleta as tags existentes
                    ORM::for_table('module_billing_records_tags')
                            ->where("id_record", $id_record)
                            ->delete_many();

                    foreach ($_POST['markers'] as $marker) {
                        $records_tags = ORM::for_table('module_billing_records_tags')->create();
                        $records_tags->id_record = $id_record;
                        $records_tags->id_tag = $marker;
                        $records_tags->save();
                    }
                }
            }
            if($redirect){
                r2(U . 'module_billing/billing/expense', 's', $_L['Expense edited successfully']);
            }else{
                echo "OK";
            }
        }
        // Inserção
        else {
            if ($occurrence == 'Mensal') {
                $id_parent_record = null;
                for ($i = 1; $i <= 12; $i++) {
                    $record = ORM::for_table('module_billing_records')->create();
                    $record->attachment = $attachment;
                    $record->id_account = $idaccount;
                    $record->id_parent_record = $id_parent_record;
                    $record->expiry = $expiry_date->format('Y-m-d');
                    $record->value = $value;
                    $record->balance = $value;
                    $record->emission_date = $emission_date;
                    $record->document_number = $document_number;
                    $record->historic = $historic;
                    $record->id_category = $idcategory;
                    $record->id_cost_center = $id_cost_center;
                    $record->occurrence = $occurrence;
                    $record->occurrence_expiry = $expiry_date->format('d');
                    $record->occurrence_installments = $occurrence_installments;
                    $record->competence = $competence;
                    $record->type = $type;
                    $record->status = ($expiry_date > (new DateTime('now')) ? 'Em aberto' : 'Atrasada');
                    $record->save();
                    $id_record = $record->id();

                    if ($i == 1) {
                        $id_parent_record = $id_record;
                    }

                    // Insere as tags na tabela N:N
                    if (isset($_POST['markers']) && count($_POST['markers']) > 0) {
                        foreach ($_POST['markers'] as $marker) {
                            $records_tags = ORM::for_table('module_billing_records_tags')->create();
                            $records_tags->id_record = $id_record;
                            $records_tags->id_tag = $marker;
                            $records_tags->save();
                        }
                    }

                    $expiry_date->add(new DateInterval('P1M'));
                }
            }

            if ($occurrence == 'Parcelada') {
                if ($occurrence_installments > 1) {
                    $installment_value = ($value / $occurrence_installments);
                    $id_parent_record = null;
                    for ($i = 1; $i <= $occurrence_installments; $i++) {
                        $record = ORM::for_table('module_billing_records')->create();
                        $record->attachment = $attachment;
                        $record->id_account = $idaccount;
                        $record->id_parent_record = $id_parent_record;
                        $record->expiry = $expiry_date->format('Y-m-d');
                        $record->value = $installment_value;
                        $record->balance = $installment_value;
                        $record->emission_date = $emission_date;
                        $record->document_number = $document_number;
                        $record->historic = $historic . " - {$_L['Installment']} ({$i}/{$occurrence_installments})";
                        $record->id_category = $idcategory;
                        $record->id_cost_center = $id_cost_center;
                        $record->occurrence = $occurrence;
                        $record->occurrence_expiry = $expiry_date->format('d');
                        $record->occurrence_installments = $occurrence_installments;
                        $record->competence = $competence;
                        $record->type = $type;
                        $record->status = ($expiry_date > (new DateTime('now')) ? 'Em aberto' : 'Atrasada');
                        $record->save();
                        $id_record = $record->id();

                        if ($i == 1) {
                            $id_parent_record = $id_record;
                        }

                        // Insere as tags na tabela N:N
                        if (isset($_POST['markers']) && count($_POST['markers']) > 0) {
                            foreach ($_POST['markers'] as $marker) {
                                $records_tags = ORM::for_table('module_billing_records_tags')->create();
                                $records_tags->id_record = $id_record;
                                $records_tags->id_tag = $marker;
                                $records_tags->save();
                            }
                        }

                        $expiry_date->add(new DateInterval('P1M'));
                    }
                } else {
                    r2(U . 'module_billing/billing/expense', 'e', $_L['Number of installments must be greater than 1']);
                }
            }

            if ($occurrence == 'Única') {
                $record = ORM::for_table('module_billing_records')->create();
                $record->attachment = $attachment;
                $record->id_account = $idaccount;
                $record->expiry = $expiry_date->format('Y-m-d');
                $record->value = Finance::amount_fix($value);
                $record->balance = Finance::amount_fix($value);
                $record->emission_date = $emission_date;
                $record->document_number = $document_number;
                $record->historic = $historic;
                $record->id_category = $idcategory;
                $record->id_cost_center = $id_cost_center;
                $record->occurrence = $occurrence;
                $record->occurrence_expiry = $expiry_date->format('d');
                if(!empty($occurrence_installments)){
                    $record->occurrence_installments = $occurrence_installments;
                }
                $record->app_fiscal_nfe_imported_id=$app_fiscal_nfe_imported_id;
                $record->row_duplicata=$rowDuplicada;
          
                $record->competence = $competence;
                $record->type = $type;
                $record->status = ($expiry_date > (new DateTime('now')) ? 'Em aberto' : 'Atrasada');
                $record->save();
                $id_record = $record->id();

                // Insere as tags na tabela N:N
                if (isset($_POST['markers']) && count($_POST['markers']) > 0) {
                    foreach ($_POST['markers'] as $marker) {
                        $records_tags = ORM::for_table('module_billing_records_tags')->create();
                        $records_tags->id_record = $id_record;
                        $records_tags->id_tag = $marker;
                        $records_tags->save();
                    }
                }
            }
            if($redirect){
                r2(U . 'module_billing/billing/expense', 's', $_L['Expense added successfully']);
            }else{
                echo "OK";
            }
        }

        // Verifica as notificações do usuário
        $notifications = new Notifications();
        $notifications->verify(8, $user['id'], U . "module_billing/billing/expense");

        break;

    case 'modal_add_income':
        $ui->assign('action', 'add');

        $id = filter_var($routes[3], FILTER_SANITIZE_NUMBER_INT);

        // Se tiver ID é edição
        if ($id != '' && $id > 0) {
            $record = ORM::for_table('module_billing_records')
                    ->table_alias('rec')
                    ->select('rec.*')
                    ->select_expr("(SELECT 
					GROUP_CONCAT(stags.text)
					FROM sys_tags stags 
					INNER JOIN module_billing_records_tags rt ON(stags.id = rt.id_tag) 
					WHERE rt.id_record = rec.id
					GROUP BY rt.id_record)", "tags")
                    ->find_one($id);
            $ui->assign('record', $record);
            $ui->assign('action', 'edit');

            $cats = ORM::for_table('sys_cats')
                    ->table_alias('st')
                    ->select('st.id')
                    ->select('st.name')
                    ->find_array();
            $ui->assign('cats', $cats);

            $markers = ORM::for_table('sys_tags')
                    ->table_alias('st')
                    ->select('st.id')
                    ->select('st.text')
                    ->where('type', 'Billing')
                    ->find_many();
            $ui->assign('markers', $markers);

            $accounts = ORM::for_table('crm_accounts')
                    ->table_alias('acc')
                    ->select('acc.id')
                    ->select('acc.account')
//                    ->select_expr("IF(acc.company = '',acc.account,CONCAT(acc.account, ' / <br>', acc.company))", 'account')
                    ->left_outer_join('crm_accounts_groups', 'acc.id = cag.crm_accounts_id', 'cag')
                    ->left_outer_join('crm_groups', 'cag.crm_group_id = cg.id', 'cg')
                    ->where_raw('cg.gname = ? OR acc.id = ?', ['Payee', $record->id_account])
                    ->find_array();
            $ui->assign('accounts', $accounts);

            $cost_center = ORM::for_table('module_billing_cost_center')
                    ->table_alias('ccent')
                    ->select('ccent.*')
                    ->order_by_asc('name')
                    ->find_array();
            $ui->assign('cost_center', $cost_center);
        }

        $payment_methods = ORM::for_table('sys_pmethods')->find_many();
        $ui->assign('payment_methods', $payment_methods);

        $ui->assign('_st', $_L['Income add']);
        $ui->display($pl_path . 'views/modal_add_income.tpl');

        break;

    case 'add_income_post':
        $id = filter_var(_post('id', 0), FILTER_SANITIZE_NUMBER_INT);
        $idaccount = filter_var(_post('id_account'), FILTER_SANITIZE_STRING);
        $expiry_br = _post('expiry');
        $value = Finance::amount_fix(_post('value'));
        $emission_date = implode('-', array_reverse(explode('/', _post('emission_date'))));
        $document_number = _post('document_number');
        $historic = _post('historic');
        $idcategory = _post('id_category');
        $id_cost_center = _post('id_cost_center');
        $id_payment_method = _post('id_payment_method');
        $occurrence = _post('occurrence');
        $occurrence_installments = _post('occurrence_installments');
        $competence = _post('competence');
        $images = _post('images');
        $type = 'Income';

        $attachment = ($images != "") ? json_encode(explode(',', $images), JSON_FORCE_OBJECT) : '';

        $expiry_date = new DateTime();
        list($year, $month, $day) = array_reverse(explode('/', $expiry_br));
        $expiry_date->setDate($year, $month, $day);

//        $value = str_replace(',', '.', str_replace('.', '', $value));

        // Validações de Backend
        ($idaccount == '') ? r2(U . 'module_billing/billing/income', 'e', $_L['Account is Required']) : '';
        ($expiry_br == '') ? r2(U . 'module_billing/billing/income', 'e', $_L['Expiry is Required']) : '';
        ($value == '') ? r2(U . 'module_billing/billing/income', 'e', $_L['Value is Required']) : '';
        ($idcategory == '') ? r2(U . 'module_billing/billing/income', 'e', $_L['Category is Required']) : '';

        // Se o valor não for um ID, cadastrar novo fornecedor
        if (((int) $idaccount) <= 0) {
            $account_exists = ORM::for_table('crm_accounts')->where('account', $idaccount)->find_one();
            // Verifica se o fornecedor já existe
            if ($account_exists->account)
                r2(U . 'module_billing/billing/income', 'e', $_L['Supplier already exists']);

            $account = ORM::for_table('crm_accounts')->create();
            $account->account = $idaccount;
            $account->currency = 1;
            $account->save();
            $idaccount = $account->id();
        }

        // Edição
        if ($id != '' && $id > 0) {
            $record = ORM::for_table('module_billing_records')->find_one($id);
            $record->id_account = $idaccount;
            $record->expiry = $expiry_date->format('Y-m-d');
            $record->value = $value;
            $record->balance = $value;
            $record->emission_date = $emission_date;
            $record->document_number = $document_number;
            $record->historic = $historic;
            $record->id_category = $idcategory;
            $record->id_cost_center = $id_cost_center;
            $record->occurrence = $occurrence;
            $record->occurrence_expiry = $expiry_date->format('d');
            $record->occurrence_installments = $occurrence_installments;
            $record->id_payment_method = $id_payment_method;
            $record->competence = $competence;
            $record->type = $type;
            $record->status = ($expiry_date > (new DateTime('now')) ? 'Em aberto' : 'Atrasada');
            $record->save();
            $id_record = $record->id();

            // Insere as tags na tabela N:N
            if (isset($_POST['markers']) && count($_POST['markers']) > 0) {
                // Deleta as tags existentes
                ORM::for_table('module_billing_records_tags')
                        ->where("id_record", $id_record)
                        ->delete_many();

                foreach ($_POST['markers'] as $marker) {
                    $records_tags = ORM::for_table('module_billing_records_tags')->create();
                    $records_tags->id_record = $id_record;
                    $records_tags->id_tag = $marker;
                    $records_tags->save();
                }
            }

            r2(U . 'module_billing/billing/income', 's', $_L['Income edited successfully']);
        }
        // Inserção
        else {
            if ($occurrence == 'Mensal') {
                $id_parent_record = null;
                for ($i = 1; $i <= 12; $i++) {
                    $record = ORM::for_table('module_billing_records')->create();
                    $record->id_account = $idaccount;
                    $record->id_parent_record = $id_parent_record;
                    $record->expiry = $expiry_date->format('Y-m-d');
                    $record->value = $value;
                    $record->balance = $value;
                    $record->emission_date = $emission_date;
                    $record->document_number = $document_number;
                    $record->historic = $historic;
                    $record->id_category = $idcategory;
                    $record->id_cost_center = $id_cost_center;
                    $record->id_payment_method = $id_payment_method;
                    $record->occurrence = $occurrence;
                    $record->occurrence_expiry = $expiry_date->format('d');
                    $record->occurrence_installments = $occurrence_installments;
                    $record->attachment = $attachment;
                    $record->competence = $competence;
                    $record->type = $type;
                    $record->status = ($expiry_date > (new DateTime('now')) ? 'Em aberto' : 'Atrasada');
                    $record->save();
                    $id_record = $record->id();

                    if ($i == 1) {
                        $id_parent_record = $id_record;
                    }

                    if (isset($_POST['markers']) && count($_POST['markers']) > 0) {
                        foreach ($_POST['markers'] as $marker) {
                            $records_tags = ORM::for_table('module_billing_records_tags')->create();
                            $records_tags->id_record = $id_record;
                            $records_tags->id_tag = $marker;
                            $records_tags->save();
                        }
                    }

                    $expiry_date->add(new DateInterval('P1M'));
                }
            }

            if ($occurrence == 'Parcelada') {
                // TODO Estipular um limite máximo de parcelas
                if ($occurrence_installments > 1) {
                    $installment_value = ($value / $occurrence_installments);
                    $id_parent_record = null;
                    for ($i = 1; $i <= $occurrence_installments; $i++) {
                        $record = ORM::for_table('module_billing_records')->create();
                        $record->id_account = $idaccount;
                        $record->id_parent_record = $id_parent_record;
                        $record->expiry = $expiry_date->format('Y-m-d');
                        $record->value = $installment_value;
                        $record->balance = $installment_value;
                        $record->emission_date = $emission_date;
                        $record->document_number = $document_number;
                        $record->historic = $historic . " - {$_L['Installment']} ({$i}/{$occurrence_installments})";
                        $record->id_category = $idcategory;
                        $record->id_cost_center = $id_cost_center;
                        $record->id_payment_method = $id_payment_method;
                        $record->occurrence = $occurrence;
                        $record->occurrence_expiry = $expiry_date->format('d');
                        $record->occurrence_installments = $occurrence_installments;
                        $record->competence = $competence;
                        $record->attachment = $attachment;
                        $record->type = $type;
                        $record->status = ($expiry_date > (new DateTime('now')) ? 'Em aberto' : 'Atrasada');
                        $record->save();
                        $id_record = $record->id();

                        if ($i == 1) {
                            $id_parent_record = $id_record;
                        }

                        if (isset($_POST['markers']) && count($_POST['markers']) > 0) {
                            foreach ($_POST['markers'] as $marker) {
                                $records_tags = ORM::for_table('module_billing_records_tags')->create();
                                $records_tags->id_record = $id_record;
                                $records_tags->id_tag = $marker;
                                $records_tags->save();
                            }
                        }

                        $expiry_date->add(new DateInterval('P1M'));
                    }
                } else {
                    r2(U . 'module_billing/billing/income', 'e', $_L['Number of installments must be greater than 1']);
                }
            }

            if ($occurrence == 'Única') {
                $record = ORM::for_table('module_billing_records')->create();
                $record->id_account = $idaccount;
                $record->expiry = $expiry_date->format('Y-m-d');
                $record->value = $value;
                $record->balance = $value;
                $record->emission_date = $emission_date;
                $record->document_number = $document_number;
                $record->historic = $historic;
                $record->id_category = $idcategory;
                $record->id_cost_center = $id_cost_center;
                $record->id_payment_method = $id_payment_method;
                $record->occurrence = $occurrence;
                $record->occurrence_expiry = $expiry_date->format('d');
                $record->occurrence_installments = $occurrence_installments;
                $record->attachment = $attachment;
                $record->competence = $competence;
                $record->type = $type;
                $record->status = ($expiry_date > (new DateTime('now')) ? 'Em aberto' : 'Atrasada');
                $record->save();
                $id_record = $record->id();

                // Insere as tags na tabela N:N
                if (isset($_POST['markers']) && count($_POST['markers']) > 0) {
                    foreach ($_POST['markers'] as $marker) {
                        $records_tags = ORM::for_table('module_billing_records_tags')->create();
                        $records_tags->id_record = $id_record;
                        $records_tags->id_tag = $marker;
                        $records_tags->save();
                    }
                }
            }

            r2(U . 'module_billing/billing/income', 's', $_L['Income added successfully']);
        }

        // Verifica as notificações do usuário
        $notifications = new Notifications();
        $notifications->verify(9, $user['id'], U . "module_billing/billing/income");

        break;

    case 'modal_add_register':
        $id_record = (isset($routes['3']) ? $routes['3'] : 0);

        if ($id_record > 0) {
            $record = ORM::for_table('module_billing_records')
                    ->table_alias('rec')
                    ->select('rec.id')
                    ->select('rec.historic')
                    ->select('rec.expiry')
                    ->select('rec.value')
                    ->select('rec.balance')
                    ->select('rec.document_number')
                    ->select('rec.id_category')
                    ->select('rec.type')
                    ->select('rec.status')
                    ->select('rec.id_category')
                    ->select('rec.id_payment_method')
                    ->select('rec.id_cost_center')
                    ->select('cats.name')
                    ->select('acc.account')
                    ->inner_join('crm_accounts', 'rec.id_account = acc.id', 'acc')
                    ->inner_join('sys_cats', 'rec.id_category = cats.id', 'cats')
                    ->find_one($id_record);
            $ui->assign('record', $record);
        }

        $categories = ORM::for_table('sys_cats')->where('type', $record['type'])->find_many();
        $ui->assign('categories', $categories);
        
        $pmethods = ORM::for_table('sys_pmethods')->where('enabled', 1)->find_many();
        $ui->assign('pmethods', $pmethods);

        $sys_accounts = ORM::for_table('sys_accounts')
                ->select('id')
                ->select('account')
                ->select('description')
                ->select('balance')
                ->find_many();
        $ui->assign('sys_accounts', $sys_accounts);

        $ui->assign('_st', $_L['Payment register']);
        $ui->display($pl_path . 'views/modal_register.tpl');

        break;

    case 'modal_add_register_lote':
        $sys_accounts = ORM::for_table('sys_accounts')
                ->select('id')
                ->select('account')
                ->select('description')
                ->select('balance')
                ->find_many();
        $ui->assign('sys_accounts', $sys_accounts);
        
        $pmethods = ORM::for_table('sys_pmethods')->where('enabled', 1)->find_many();
        $ui->assign('pmethods', $pmethods);

        $ui->display($pl_path . 'views/modal_register_lote.tpl');
        break;

    case 'add_register_post':
        $id_record = _post('id_record');
        $id_sys_account = _post('id_sys_account');
        
        // Pego o nome da categoria
        $id_category = _post('id_category');
        $cat = ORM::for_table('sys_cats')->where('id', $id_category)->find_one();
        if($cat)
        {
            $cat = $cat['name'];
        }
        
        $id_payment_method = _post('id_payment_method');
        $id_cost_center = _post('id_cost_center');
        $date = implode('-', array_reverse(explode('/', _post('date'))));
        $historic = _post('historic');
        $type = _post('type');
        $tax = str_replace(',', '.', str_replace('.', '', _post('tax')));
        $interest = str_replace(',', '.', str_replace('.', '', _post('interest')));
        $discount = str_replace(',', '.', str_replace('.', '', _post('discount')));
        $increase = str_replace(',', '.', str_replace('.', '', _post('increase')));
        $amount_paid = str_replace(',', '.', str_replace('.', '', _post('amount_paid')));

        // Atualiza os valores da Conta
        $record = ORM::for_table('module_billing_records')->find_one($id_record);

        $balance = 0;
        if (($record->value - $amount_paid) >= 0) {
            $balance = ($record->value - ($record->payed + $amount_paid));
        }

        $status = 'Em aberto';
        if ($balance == 0)
            $status = 'Paga';
        if ($balance > 0)
            $status = 'Parcial';

        $record->balance = $balance;
        $record->tax = $tax;
        $record->interest = $interest;
        $record->discount = $discount;
        $record->increase = $increase;
        $record->payed += $amount_paid;
        $record->historic = $historic;
        $record->status = $status;
        $record->id_payment_method = $id_payment_method;
        $record->save();

        // Verifico se o registro está vinculado a alguma fatura
        $sys_invoices_id = 0;
        if ($record->sys_invoices_id) {
            $sys_invoices_id = $record->sys_invoices_id;
        }

        // Insere uma nova transação
        $transaction = ORM::for_table('sys_transactions')->create();
        $transaction->billing_id_record = $id_record;
        $transaction->billing_id_account = $id_sys_account;
        $transaction->type = $type;
        $transaction->amount = $amount_paid;
        $transaction->description = $historic;
        $transaction->date = $date;
        $transaction->tax = $tax;
        $transaction->bal = $balance;
        $transaction->iid = $sys_invoices_id;
        $transaction->sys_accounts_id = $id_sys_account;
        $transaction->pmethod_id = $id_payment_method;
        $transaction->cat_id = $id_category;
        $transaction->category = $cat;
        $transaction->billing_id_cost_center = $id_cost_center;
        
        // Atualiza o saldo do caixa
        $sys_account = ORM::for_table('sys_accounts')->find_one($id_sys_account);
        if ($type == 'Expense') {
            $transaction->account = $sys_account->account;
            $transaction->bal = ($sys_account->balance - $amount_paid);
            $transaction->dr = $amount_paid;
            $tid = $transaction->save();

            $sys_account->balance -= $amount_paid;
            $sys_account->save();

            // Verifica as notificações do usuário
            $notifications = new Notifications();
            $notifications->verify(1, $user['id'], U . "module_billing/billing/expense");
        }

        if ($type == 'Income') {
            $transaction->account = $sys_account->account;
            $transaction->bal = ($sys_account->balance + $amount_paid);
            $transaction->cr = $amount_paid;
            $tid = $transaction->save();

            $sys_account->balance += $amount_paid;
            $sys_account->save();

            // Verifica as notificações do usuário
            $notifications = new Notifications();
            $notifications->verify(16, $user['id'], U . "module_billing/billing/income");
        }

        // registro o pagamento 
        if ($sys_invoices_id > 0) {
            _log('New Deposit: ' . $historic . ' [TrID: ' . $tid . ' | Amount: ' . $amount_paid . ']', 'Admin', $user['id']);
            _msglog('s', $_L['Transaction Added Successfully']);
            //now work with invoice
            $i = ORM::for_table('sys_invoices')->find_one($sys_invoices_id);
            if ($i) {
                $pc = $i['credit'];
                $it = $i['total'];
                $dp = $it - $pc;
                if (($dp == $amount_paid) OR ( ($dp < $amount))) {
                    $i->status = 'Paid';
                } else {

                    $i->status = 'Partially Paid';
                }
                $i->credit = $pc + $amount_paid;
                $i->save();
            }
        }


        r2(U . 'module_billing/billing/' . strtolower($type) . '/', 's', $_L['Payment registered successfully']);

        break;

    case 'add_register_post_lote':
        $amount_total       = Finance::amount_fix(_post('amount_paid'));
        $type               = _post('type');
        $id_payment_method  = _post('id_payment_method');
        $selected_accounts  = _post('selected_accounts');
        $date               = implode('-', array_reverse(explode('/', _post('date'))));
        $historic_aditional = _post('historic');
        $id_sys_account     = _post('id_sys_account');
        $msg                = '';
        $records = ORM::for_table('module_billing_records')->raw_query(""
                . "SELECT * from module_billing_records where type='" . $type . "'"
                . " and status <> 'Paga' and id in(" . $selected_accounts . ") order by expiry asc, balance asc")->find_many();;
        foreach ($records as $record) {
            if($amount_total<=0){
                $msg.="<br/>".$_L['We found accounts which have not been discharged in this processing'];
                break;
            }
            if($amount_total>$record->balance ){
                $amount_paid=$record->balance;
                $amount_total=$amount_total-$record->balance;
            }else{
                $msg.="<br/>".$_L['We made a partial write-down on an account in this processing'];
                $amount_paid=$amount_total;
                $amount_total=0;
            }
            
            $historic=$record->historic." ".$historic_aditional;
                   
            $balance = 0;
            if (($record->value - $amount_paid) >= 0) {
                $balance = ($record->value - ($record->payed + $amount_paid));
            }

            $status = 'Em aberto';
            if ($balance == 0)
                $status = 'Paga';
            if ($balance > 0)
                $status = 'Parcial';

            $record->balance = $balance;
        //    $record->tax = $tax;
        //    $record->interest = $interest;
       //     $record->discount = $discount;
      //      $record->increase = $increase;
            $record->payed += $amount_paid;
            $record->historic = $historic;
            $record->status = $status;
            $record->id_payment_method = $id_payment_method;
            $record->save();

            // Verifico se o registro está vinculado a alguma fatura
            $sys_invoices_id = 0;
            if ($record->sys_invoices_id) {
                $sys_invoices_id = $record->sys_invoices_id;
            }

            // Insere uma nova transação
            $transaction = ORM::for_table('sys_transactions')->create();
            $transaction->billing_id_record = $record->id;
            $transaction->billing_id_account = $id_sys_account;
            $transaction->type = $type;
            $transaction->amount = $amount_paid;
            $transaction->description = $historic;
            $transaction->date = $date;
            //$transaction->tax = $tax;
            $transaction->bal = $balance;
            $transaction->iid = $sys_invoices_id;
            
            $transaction->sys_accounts_id = $id_sys_account;
            $transaction->pmethod_id = $id_payment_method;
            $transaction->billing_id_cost_center = $record->id_cost_center;
            
            // pego a categoria
            $id_category = $record->id_category;
            $cat = ORM::for_table('sys_cats')->where('id', $id_category)->find_one();
            if($cat)
            {
                $cat = $cat['name'];
            }
            $transaction->cat_id    = $id_category;
            $transaction->category  = $cat;

            // Atualiza o saldo do caixa
            $sys_account = ORM::for_table('sys_accounts')->find_one($id_sys_account);
            if ($type == 'Expense') {
                $transaction->account = $sys_account->account;
                $transaction->bal = ($sys_account->balance - $amount_paid);
                $transaction->dr = $amount_paid;
                $tid = $transaction->save();

                $sys_account->balance -= $amount_paid;
                $sys_account->save();

                // Verifica as notificações do usuário
                $notifications = new Notifications();
                $notifications->verify(1, $user['id'], U . "module_billing/billing/expense");
            }

            if ($type == 'Income') {
                $transaction->account = $sys_account->account;
                $transaction->bal = ($sys_account->balance + $amount_paid);
                $transaction->cr = $amount_paid;
                $tid = $transaction->save();

                $sys_account->balance += $amount_paid;
                $sys_account->save();

                // Verifica as notificações do usuário
                $notifications = new Notifications();
                $notifications->verify(16, $user['id'], U . "module_billing/billing/income");
            }

            // registro o pagamento 
            if ($sys_invoices_id > 0) {
                _log('New Deposit: ' . $historic . ' [TrID: ' . $tid . ' | Amount: ' . $amount_paid . ']', 'Admin', $user['id']);
                _msglog('s', $_L['Transaction Added Successfully']);
                //now work with invoice
                $i = ORM::for_table('sys_invoices')->find_one($sys_invoices_id);
                if ($i) {
                    $pc = $i['credit'];
                    $it = $i['total'];
                    $dp = $it - $pc;
                    if (($dp == $amount_paid) OR ( ($dp < $amount))) {
                        $i->status = 'Paid';
                    } else {

                        $i->status = 'Partially Paid';
                    }
                    $i->credit = $pc + $amount_paid;
                    $i->save();
                }
            }
        }
        r2(U . 'module_billing/billing/' . strtolower($type) . '/', 's', $_L['Payments registered successfully'].$msg);

        break;


    case 'modal_reverse':
        $id_record = $routes['3'];
        $title = $routes['4'];

        $ui->assign('id_record', $id_record);
        $ui->assign('title', $title);
        $ui->assign('_st', $_L['Reverse payment']);
        $ui->display($pl_path . 'views/modal_reverse.tpl');

        break;

    case 'reverse_post':
        $id_record = _post('id_record', 0);
        if ($id_record <= 0) {
            r2($_SERVER['HTTP_REFERER'], 'e', $_L['Invalid ID']);
        }

        $record = ORM::for_table('module_billing_records')->find_one($id_record);
        if (!$record) {
            r2($_SERVER['HTTP_REFERER'], 'e', $_L['Account not found']);
        };

        // Busca as transações relacionadas a conta
        $transactions = ORM::for_table('sys_transactions')
                ->where('billing_id_record', $record->id)
                ->find_array();

        if (count($transactions) <= 0) {
            r2(U . 'module_billing/billing/' . strtolower($record->type), 'e', $_L['This account has no transactions']);
        }

        foreach ($transactions as $transaction) {
            // Busca a conta que foi usada na transação
            $sys_account = ORM::for_table('sys_accounts')->find_one($transaction['billing_id_account']);

            if ($sys_account) {
                // No caso de despesa, volta o montante a conta
                if ($transaction['type'] == 'Expense') {
                    $sys_account->balance += floatval($transaction['amount']);
                    $sys_account->save();
                    $type = 'expense';
                }

                // No caso de receita, retira o montante da conta
                if ($transaction['type'] == 'Income') {
                    $sys_account->balance -= floatval($transaction['amount']);
                    $sys_account->save();
                    $type = 'income';
                }
            }
            // Remove a transação estornada
            ORM::for_table('sys_transactions')->find_one($transaction['id'])->delete();

            // Adiciona o log na tabela history
            $h = ORM::for_table('module_billing_history')->create();
            $h->date = date('Y-m-d H:i:s');
            $h->target = 'sys_transactions';
            $h->url = $_SERVER['HTTP_REFERER'];
            $h->user_id = $user['id'];
            $h->ip = $_SERVER['REMOTE_ADDR'];
            $h->description = json_encode(['action' => $_L['Reverse payment'], 'data' => $transaction]);
            $h->save();
        }

        // Por fim restaura os dados do record como estavam antes da transação
        $record->balance = $record->value;
        $record->tax = 0;
        $record->interest = 0;
        $record->discount = 0;
        $record->increase = 0;
        $record->payed = 0;
        $record->status = 'Em aberto';
        $record->save();

        // Verifica as notificações do usuário
        $notifications = new Notifications();
        if ($type == 'expense')
            $notifications->verify(17, $user['id'], U . "module_billing/billing/$type");
        if ($type == 'income')
            $notifications->verify(18, $user['id'], U . "module_billing/billing/$type");

        r2(U . 'module_billing/billing/' . strtolower($record->type), 's', $_L['Reversal successfully']);

        break;

    case 'modal_delete':
        $id_record = $routes['3'];
        $title = $routes['4'];

        if ($id_record <= 0) {
            r2($_SERVER['HTTP_REFERER'], 'e', $_L['Invalid ID']);
        }

        // Registro selecionado na listagem
        $record = ORM::for_table('module_billing_records')->find_one($id_record);
//        var_dump($record);exit;

        // Se for pai, traz os filhos
        $is_parent_record = ORM::for_table('module_billing_records')
                ->where('id_parent_record', $record->id)
                ->find_array();

        // Se for um registro pai e possuir filhos, é recorrente
        if ((count($is_parent_record) + count($record)) > 1) {
            $ui->assign('recurrent', true);
            $ui->assign('record', $record);
        } else {
            // Se for um registro filho, busca os relacionados
            $relatives = ORM::for_table('module_billing_records')
                    ->where('id_parent_record', $record->id_parent_record)
                    ->find_array();

            // Busca o registro pai dos relacionados
            $parent = ORM::for_table('module_billing_records')
                    ->raw_query("
					SELECT 
						* 
					FROM 
						module_billing_records 
					WHERE 
						id IN(
							SELECT 
								id_parent_record 
							FROM 
								module_billing_records 
							WHERE 
								id_parent_record = '" . $record->id_parent_record . "')")
                    ->find_array();

            // Se a soma dos registros filhos com o registro pai (se hover)
            // for maior que 1 é recorrente.
            if (count($relatives) + count($parent) > 1) {
                $ui->assign('recurrent', true);
                $ui->assign('record', $record);
            }
        }

        $ui->assign('id_record', $record->id);
        $ui->assign('title', $title);
        $ui->display($pl_path . 'views/modal_delete.tpl');

        break;

    case 'delete_post':
        $id_record = _post('id_record', 0);
        $option = _post('option', 'only-one');
        $expiry = _post('expiry');

        if ($id_record <= 0) {
            r2($_SERVER['HTTP_REFERER'], 'e', $_L['Invalid ID']);
        }

        $record = ORM::for_table('module_billing_records')
                ->where_not_equal('status', 'Paga')
                ->where_not_equal('status', 'Parcial')
                ->find_one($id_record);

        if (!$record) {
            r2($_SERVER['HTTP_REFERER'], 'e', $_L['This account can not be deleted']);
        }

        // Remove o registro selecionado e os relacionados ao ID pai e com data de vencimento
        // acima da data do registro selecionado
        if ($option == 'all-date') {
            $stmt = ORM::for_table('module_billing_records')
                    ->where_raw('id = ? OR (id_parent_record = ? AND expiry > ?)', [$record->id, $record->id_parent_record, $expiry])
                    ->where_raw('status = ? OR status = ?', ['Em aberto', 'Atrasada']);
            $records = $stmt->find_array();

            foreach ($records as $rec) {
                $r = ORM::for_table('module_billing_records')
                        ->find_one($rec['id']);

                // Adiciona o log na tabela history
                $h = ORM::for_table('module_billing_history')->create();
                $h->date = date('Y-m-d H:i:s');
                $h->target = 'module_billing_records';
                $h->url = $_SERVER['HTTP_REFERER'];
                $h->user_id = $user['id'];
                $h->ip = $_SERVER['REMOTE_ADDR'];
                $h->description = json_encode(['action' => $_L['Payment delete'], 'data' => $r->as_array()]);
                $h->save();

                $r->delete();
            }
        }

        // Remove o registro pai e os registros filhos com status
        // em aberto ou em atraso, exceto pagos ou parciais.
        if ($option == 'all-of-type') {
            $stmt = ORM::for_table('module_billing_records')
                    ->where_raw('(status = ? OR status = ?) AND (id = ? OR id_parent_record = ? OR id_parent_record = ?)', ['Em aberto', 'Atrasada', $record->id, $record->id_parent_record, $record->id]);

            $records = $stmt->find_array();

            foreach ($records as $rec) {
                $r = ORM::for_table('module_billing_records')
                        ->find_one($rec['id']);

                // Adiciona o log na tabela history
                $h = ORM::for_table('module_billing_history')->create();
                $h->date = date('Y-m-d H:i:s');
                $h->target = 'module_billing_records';
                $h->url = $_SERVER['HTTP_REFERER'];
                $h->user_id = $user['id'];
                $h->ip = $_SERVER['REMOTE_ADDR'];
                $h->description = json_encode(['action' => $_L['Payment delete'], 'data' => $r->as_array()]);
                $h->save();

                $r->delete();
            }
        }

        // Remove o record selecionado
        if ($record->status == 'Em aberto' || $record->status == 'Atrasada') {
            // Adiciona o log na tabela history
            $h = ORM::for_table('module_billing_history')->create();
            $h->date = date('Y-m-d H:i:s');
            $h->target = 'module_billing_records';
            $h->url = $_SERVER['HTTP_REFERER'];
            $h->user_id = $user['id'];
            $h->ip = $_SERVER['REMOTE_ADDR'];
            $h->description = json_encode(['action' => $_L['Payment delete'], 'data' => $record->as_array()]);
            $h->save();

            $record->delete();
        }

        // Verifica as notificações do usuário
        $notifications = new Notifications();
        $type = strtolower($record->type);
        if ($type == 'expense')
            $notifications->verify(2, $user['id'], U . "module_billing/billing/$type");
        if ($type == 'income')
            $notifications->verify(15, $user['id'], U . "module_billing/billing/$type");

        r2($_SERVER['HTTP_REFERER'], 's', $_L['Delete successfully']);

        break;

    case 'list_notifications_users':
        $ui->assign('xfooter', '<script type="text/javascript" src="' . $_pd . '/assets/js/list-notifications-users.js"></script>');

        $notifications_users = ORM::for_table('sys_notifications_types')
                ->table_alias('snt')
                ->select('snt.id')
                ->select('snt.description')
                ->select('snt.module')
                ->select('snu.method')
                ->left_outer_join('sys_notifications_users', 'snt.id = snu.id_notification_type', 'snu')
                ->where('snt.module', $dir)
                ->order_by_asc('snt.description')
                ->find_many();

        $ui->assign('notifications_users', $notifications_users);
        $ui->assign('_st', $_L['User Notifications']);
        $ui->display($_pd . '/views/list_notifications_users.tpl');

        break;

    case 'add_notifications_users_post':
        $id = (isset($_POST['id'])) ? $_POST['id'] : 0;
        $values = (isset($_POST['values'])) ? json_encode($_POST['values']) : 0;

        if ($id <= 0) {
            r2(U . 'module_billing/billing/list_notifications_users/', 'e', $_L['Invalid ID']);
        }

        $notifications_users = ORM::for_table('sys_notifications_users')
                ->where('id_notification_type', $id)
                ->find_one();

        if ($notifications_users) {
            $notifications_users->method = $values;
            $notifications_users->save();

            die('1');
        }

        $notifications_users = ORM::for_table('sys_notifications_users')->create();
        $notifications_users->id_notification_type = $id;
        $notifications_users->id_user = $user['id'];
        $notifications_users->method = $values;
        $notifications_users->save();

        die('1');

        break;

    case 'ajax_accounts':
        $term = _post('term');

        $stmt = ORM::for_table('crm_accounts')
                ->table_alias('acc')
                ->distinct('acc.id')
                ->select('acc.id')
                ->select('acc.account')
//                ->select_expr("IF((acc.company = '' OR acc.company IS NULL),acc.account,CONCAT(acc.account, ' / ', acc.company))", 'account')
                ->join('crm_accounts_groups', 'acc.id = cag.crm_accounts_id', 'cag')
                ->join('crm_groups', 'cag.crm_group_id = cg.id', 'cg')
                ->where('cg.gname', 'Payee')
                ->order_by_asc('acc.account')
                ->limit(50);

        if ($term != "") {
            $stmt->where_raw("acc.account LIKE '%" . $term . "%'");
        }

        $accounts = $stmt->find_array();

        header('Content-Type: application/json');
        echo json_encode($accounts);

        break;

    case 'ajax_customers':
        $term = _post('term');
        $stmt = ORM::for_table('crm_accounts')
                ->table_alias('acc')
                ->distinct('acc.id')
                ->select('acc.id')
                ->select('acc.account')
//                ->select_expr("IF((acc.company = '' OR acc.company is null),acc.account,CONCAT(acc.account, ' / ', acc.company))", 'account')
                ->left_outer_join('crm_accounts_groups', 'acc.id = cag.crm_accounts_id', 'cag')
                ->left_outer_join('crm_groups', 'cag.crm_group_id = cg.id', 'cg')
                ->where('cg.gname', 'Customer')
                ->order_by_asc('acc.account')
                ->limit(50);

        if ($term != "") {
            $stmt->where_raw("acc.account LIKE '%" . $term . "%'");
        }

        $accounts = $stmt->find_array();

        header('Content-Type: application/json');
        echo json_encode($accounts);

        break;

    case 'ajax_markers':
        $term = _post('term');
        $stmt = ORM::for_table('sys_tags')
                ->table_alias('st')
                ->select('st.id')
                ->select('st.text')
                ->where('type', 'Billing');

        if ($term != "") {
            $stmt->where_like('text', '%' . $term . '%');
        }

        $tags = $stmt->find_array();

        header('Content-Type: application/json');
        echo json_encode($tags);

        break;

    case 'ajax_category':
        $type = _post('type');
        $term = _post('term');
        $stmt = ORM::for_table('sys_cats')
                ->table_alias('st')
                ->select('st.id')
                ->select('st.name')
                ->where('type', $type);

        if ($term != "") {
            $stmt->where_like('name', '%' . $term . '%');
        }

        $cats = $stmt->find_array();

        header('Content-Type: application/json');
        echo json_encode($cats);

        break;

    case 'ajax_images':
        $id = filter_var($routes[3], FILTER_SANITIZE_NUMBER_INT);

        $images = '';
        $stored_images = '';

        // Se tiver ID é edição
        if ($id != '' && $id > 0) {
            $record = ORM::for_table('module_billing_records')->find_one($id);

            // Se tiver anexos
            if ($record->attachment != '') {
                $attachment = json_decode($record->attachment, true);
                foreach ($attachment as $image) {
                    $images .= ' { "name": "' . $image . '", "size": 100,"url":"' . APP_URL
                            . '/application/storage/billing/records/img/' . $image . '" },';
                    $stored_images .= "," . $image;
                }
            }
        }

        echo '[' . substr($images, 0, -1) . ']';

        break;

    case 'billing_add_image':
        $id = '';
        if (isset($routes[3]) && $routes[3] > 0) {
            $id = $routes[3];
        }

        $uploader = new Uploader();
        $uploader->setDir('application/storage/billing/records/img/');
        $uploader->sameName(false);
        $uploader->setExtensions(array('jpg', 'jpeg', 'png', 'gif', 'pdf'));

        if ($uploader->uploadFile('file')) {
            $uploaded = $uploader->getUploadName();
            $file = $uploaded;
            $msg = $_L['Uploaded Successfully'];
            $success = 'Yes';

            if ($id > 0) {
                $record = ORM::for_table('module_billing_records')->find_one($id);
                $attachments = json_decode($record->attachment, true);
                $attachments[] = $file;
                $record->attachment = json_encode($attachments, JSON_FORCE_OBJECT);;
                $record->save();
                $id_record = $record->id();
            }

            list($width, $height, $type, $attr) = getimagesize('application/storage/billing/records/img/' . $uploaded);
            $image = new Image();
            $image->source_path = 'application/storage/billing/records/img/' . $uploaded;
            $image->target_path = 'application/storage/billing/records/img/' . $uploaded;

            if ($width > $height && $width > 1200) {
                $image->resize(1200);
            } else if ($height > $width && $height > 1200) {
                $image->resize(null, 1200);
            }
        } else {
            $file = '';
            $msg = $uploader->getMessage();
            $success = 'No';
            $id = '';
        }

        $response = array(
            'success' => $success,
            'msg' => $msg,
            'file' => $file,
            'url' => $uploader->destinationPath.'/'.$file,
            'id' => '' // $id_record
        );

        header('Content-Type: application/json');
        echo json_encode($response);

        break;

    case 'billing_remove_image':
        $name = filter_var(_post('name'), FILTER_SANITIZE_STRING);
        $scheduling_id = _post('id');
        $records = ORM::for_table('module_billing_records')
                    ->where_raw("attachment LIKE '%" . $name . "%'")
                    ->find_many();

        $msg = $_L['Not found'];
        $status = 'ERROR';
        $attachment = null;
        if (count($records) > 0) {
            foreach ($records as $record) {
                $attachments = json_decode($record->attachment, true);
                
                foreach ($attachments as $key => $value)
                {
                    if ($name == $value) 
                    {
                        $file = 'application/storage/billing/records/img/' . $name;
                        if (file_exists($file)) {
                            unlink($file);
                        }
                        unset($attachments[$key]);

                        $r = ORM::for_table('module_billing_records')->find_one($record->id);
                        $r->attachment = json_encode($attachments, JSON_FORCE_OBJECT);
                        $r->save();

                        $msg = $_L['Image Deleted Successfully'];
                        $status = 'OK';
                    }
                }
                
            }
        } else if ($name != '' && file_exists('application/storage/billing/records/img/' . $name)) {
            unlink('application/storage/billing/records/img/' . $name);
            $msg = $_L['Image Deleted Successfully'];
            $status = 'OK';
        }

        $response = array(
            'msg' => $msg,
            'status' => $status,
            'name' => $name
        );

        header('Content-Type: application/json');
        echo json_encode($response);

        break;

    case 'modal_add_tag':
        $ui->assign('_st', $_L['Add Marker']);
        $ui->display($pl_path . 'views/modal_add_tag.tpl');

        break;

    case 'modal_add_category':
        $ui->assign('_st', $_L['Add Category']);
        $ui->display($pl_path . 'views/modal_add_category.tpl');

        break;

    case 'modal_add_contact':
        $ui->assign('_st', $_L['Add Contact']);
        $ui->display('modal_add_contact.tpl');

        break;

    case 'history':
        $filter = array();
        $filter['items_per_page'] = 50;

        $select = "
			SELECT
				mbh.*,
				su.username
			FROM
				module_billing_history mbh
				LEFT JOIN sys_users su ON(mbh.user_id = su.id)";

        $order_by = " ORDER BY mbh.id";

        $page = isset($routes['3']) ? $routes['3'] : 1;
        $query = $select . $order_by;

        if ($filter['items_per_page'] != 'all')
            $filter['items_per_page'] = ($filter['items_per_page'] > 0) ? $filter['items_per_page'] : 50;

        $paginator = new ModulePaginator('module_billing_history', $query, $filter);
        $history = $paginator->setItemsPerPage($filter['items_per_page'])
                ->setCurrentPageNumber($page)
                ->run();

        $ui->assign('history', $history);
        $ui->assign('paginator', $paginator);

        $ui->assign('_st', $_L['History']);
        $ui->assign('_include', 'history');
        $ui->display('wrapper.tpl');

        break;

    case 'history-view':
        if (!isset($routes['3']))
            r2(U . 'module_billing/billing/history/', 'e', $_L['Invalid ID']);

        $ui->assign('xheader', '<link rel="stylesheet" type="text/css" href="'
                . $_pd . '/assets/css/billing.css"/>');

        $id = filter_var($routes['3'], FILTER_SANITIZE_NUMBER_INT);
        $history = ORM::for_table('module_billing_history')
                ->table_alias('mbh')
                ->select('mbh.*')
                ->select('su.username')
                ->left_outer_join('sys_users', 'mbh.user_id = su.id', 'su')
                ->find_one($id);
        $ui->assign('history', $history);

        $description = json_decode($history->description, true);
        $action = $description['action'];
        $data = $description['data'];
        $ui->assign('description_action', $action);
        $ui->assign('description_data', $data);

        $ui->assign('_st', $_L['History Details']);
        $ui->assign('_include', 'history-view');
        $ui->display('wrapper.tpl');

        break;

    default:
        echo 'action not defined';
}

Anon7 - 2022
AnonSec Team