AnonSec Shell
Server IP : 162.214.74.102  /  Your IP : 216.73.216.59
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/www/lrsys_apps/regional/application/plugins/module_billing/controllers/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ HOME ]     

Current File : /home/lrsys/www/lrsys_apps/regional/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>');

		$filter = array();
		$filter['items_per_page'] = 10;
		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.value,
				mbr.balance,
				mbr.payed,
				mbr.status,
				mbr.type,
				IF(acc.company = '',acc.account,CONCAT(acc.account, ' / <br>', acc.company)) 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 MONTH(mbr.expiry) = MONTH('" . date('Y-m-d') . "')";
			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']))). "'";
		}

		// 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);

		// Query que soma os totais das contas a pagar
		$totais = ORM::for_table('module_billing_records')
			->select_expr("(SELECT COUNT(id) FROM module_billing_records WHERE status <> 'Paga' AND type = 'Expense')", 'records')
			->select_expr('ROUND(SUM(value), 2)', 'value')
			->select_expr('ROUND(SUM(balance), 2)', 'balance')
			->select_expr("ROUND(SUM(payed), 2)", 'payed')
			->where('type', 'Expense')
			->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'] . '\';
		');
//		$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>');

		$filter = array();
		$filter['items_per_page'] = 10;
		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.value,
				mbr.balance,
				mbr.payed,
				mbr.status,
				mbr.type,
				IF(acc.company = '',acc.account,CONCAT(acc.account, ' / <br>', acc.company)) 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 MONTH(mbr.expiry) = MONTH('" . date('Y-m-d') . "')";
			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']))). "'";
		}

		// 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', '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
		$totais = ORM::for_table('module_billing_records')
			->select_expr("(SELECT COUNT(id) FROM module_billing_records WHERE status <> 'Paga' AND type = 'Income')", 'records')
			->select_expr('ROUND(SUM(value), 2)', 'value')
			->select_expr('ROUND(SUM(balance), 2)', 'balance')
			->select_expr("ROUND(SUM(payed), 2)", 'payed')
			->where('type', 'Income')
			->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'] . '\';
		');

		$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_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 = _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');
		$occurrence = _post('occurrence');
		$occurrence_installments = _post('occurrence_installments');
		$competence = _post('competence');
		$images = _post('images');
		$type = 'Expense';

		$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/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;
			$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();

			// 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();
					}
				}
			}

			r2(U . 'module_billing/billing/expense', 's', $_L['Expense 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->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 = $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();

				// 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/expense', 's', $_L['Expense added successfully']);
		}

		// 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_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 = _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('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')->find_many();
		$ui->assign('categories', $categories);

		$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 'add_register_post':
		$id_record = _post('id_record');
		$id_sys_account = _post('id_sys_account');
		$id_category = _post('id_category');
		$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->save();

		// 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;

		// 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;
			$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;
			$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");
		}

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

		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);

		// 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()
			->select('acc.id')
			->select_expr("IF(acc.company = '',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');

		if($term != "") {
			$stmt->where_raw("acc.account LIKE '%" . $term . "%' OR acc.company 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_expr("IF(acc.company = '',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');

		if($term != "") {
			$stmt->where_raw("acc.account LIKE '%" . $term . "%' OR acc.company 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);
				$record->attachment = $uploaded;
				$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 > 800) {
				$image->resize(800);
			} else if ($height > $width && $height > 800) {
				$image->resize(null, 800);
			}
		}
		else {
			$file = '';
			$msg = $uploader->getMessage();
			$success = 'No';
			$id = '';
		}

		$response = array(
			'success' => $success,
			'msg' => $msg,
			'file' => $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);
		$records = ORM::for_table('module_billing_records')
			->where_raw("attachment LIKE '%" . $name . "%'")
			->find_many();

		$msg = $_L['Not found'];
		$status = 'ERROR';

		if(count($records) > 0) {
			foreach($records as $record) {
				$attachment = json_decode($record->attachment, true);
				if($needle = array_search($name, $attachment)) {
					$file = 'application/storage/billing/records/img/' . $attachment[$needle];
					if(file_exists($file)) {
						unlink($file);
					}
					unset($attachment[$needle]);

					$r = ORM::for_table('module_billing_records')->find_one($record->id);
					$r->attachment = json_encode($attachment, 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
		);

		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