Don't you speak portuguese? Translate this site with Google Translator

Pensamento do Dia

A prática é um professor excepcional. (Plínio, o Jovem, escritor romano)

13.5 - Aplicativo Finanças Pessoais

13.5 - Aplicativo Finanças Pessoais

Cada um de nós tem um fogo no coração para alguma coisa. É nossa meta na vida encontrá-lo e mantê-lo aceso. (Mary Lou Retton)


Este aplicativo tem como objetivo principal efetuar operações entre os elementos do MVC (Controller, Model e View) para um simplificada aplicação de controle de receitas e despesas pessoais.

Procurarei simplificar outras operações, focando apenas na codificação.

Versão com CakePHP 3.6.1

- Criar um Aplicativo com o CakePHP 3.6.1
- Para gerenciamento de finanças pessoais.
- Apenas com as tabelas despesas e receitas

Importante: este código customizado funciona apenas no CakePHP 3.6 ou superior
Criando behaviors para executar o código da camada de negócios nos models
Criando components para executar o código da camada de negócios nos controllers

- Criar o aplicativo

cd /var/www/html
composer create-project --prefer-dist cakephp/app financas

- Criar o banco de dados

Usaremos como SGBD o MySQL

Criar o banco financas contendo:

CREATE TABLE `despesas` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `descricao` varchar(100) COLLATE utf8_unicode_ci DEFAULT NULL,
  `valor` int(11) DEFAULT NULL,
  `mes` char(8) COLLATE utf8_unicode_ci DEFAULT NULL,
  `created` date DEFAULT NULL,
  `modified` date DEFAULT NULL,
  `receita_id` int(11) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

INSERT INTO `despesas` (`id`, `descricao`, `valor`, `mes`, `created`, `modified`, `receita_id`) VALUES
(1,	'Mercantil',	500,	'05/2017',	'2017-05-11',	'2017-05-15',	1),
(2,	'Condomínio',	100,	'05/2017',	'2017-05-11',	'2017-05-15',	1),
(3,	'Teste',	300,	'06/2017',	'2017-05-11',	'2017-05-11',	2);

CREATE TABLE `receitas` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `descricao` varchar(100) COLLATE utf8_unicode_ci DEFAULT NULL,
  `mes` char(7) COLLATE utf8_unicode_ci DEFAULT NULL,
  `valor` int(11) DEFAULT NULL,
  `created` date DEFAULT NULL,
  `modified` date DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

INSERT INTO `receitas` (`id`, `descricao`, `mes`, `valor`, `created`, `modified`) VALUES
(1,	'Salário',	'05/2017',	3000,	'2017-05-11',	'2017-05-15'),
(2,	'Extra',	'05/2017',	100,	'2017-05-11',	'2017-05-15');

Observe acima que o mês é tipo texto para que seja inserido algo com mes/ano

- Configurar o banco de dados em config/app.php
e o
config/routes.php para Despesas/index


Gerar o código dos dois CRUDs com o Bake

cd /var/www/html/financas
bin/cake bake all despesas
bin/cake bake all receitas


Veja pelo navegador

http://localhost/financas

Já temos um CRUD básico para as despesas e para as receitas

Mas o importante de um aplicativo deste tipo são o código personalidado, chamado de lógica de negócio, que é por exemplo somar todas as despesas de um mês e subtrair as receitas do mês do total de despesas. Isso o CakePHP não faz e precisamos fazer. Também precisamos criar código nos tempaltes adicionando um formulário


Agora a parte interessante

O código da camada de negócios
Observe que o mês tem um formato próprio, texto sendo dia/ano (dd/aaaa).


Vamos criar uma função em DespesasTable.php, que retorne a soma das despesas do mês:

Adicionar ao início:

use Cake\ORM\TableRegistry;

Adicionar:

	public function despesasMes($mes){

		$despesas = TableRegistry::get('Despesas')->find();
		$res = $despesas->select(['total_sum' =>$despesas->func()->sum('Despesas.valor')])
		->where(['Despesas.mes' => $mes])->first();
		$total = $res->total_sum;

		return $total;
	}

Criar duas funções no DespesasController.php, que retornem o resultado das funções acima:

Adicionar ao início do DespesasController

use Cake\ORM\TableRegistry;

Mais abaixo

	public function despesasMes()
	{
		$mes = $this->request->data('mes');
		$despesas = TableRegistry::get('Despesas');
		$total = $despesas->despesasMes($mes);
		$this->set('total',$total); 
		$this->set('mes',$mes);
	}

	public function saldoMes()
	{
		$mes = $this->request->data('mes');
		$this->LoadModel('Receitas');
		$receitas = $this->Receitas->receitaMes($mes);

		$despesas = TableRegistry::get('Despesas');
		$total = $despesas->despesasMes($mes);

		$saldo = $receitas - $total;
		$this->set('saldo',$saldo); 
		$this->set('mes',$mes);
	}


Agora criaremos uma função no ReceitasTable.php, que retorne a soma das receitas do mês:

Adicionar ao início:

use Cake\ORM\TableRegistry;

Mais abaixo:

	public function receitaMes($mes){
		$receitas = TableRegistry::get('Receitas')->find();
		$res = $receitas->select(['total_sum' =>$receitas->func()->sum('Receitas.valor')])
		->where(['Receitas.mes' => $mes])
		->first(); //perform the sum operation 
		$total = $res->total_sum;

		return $total;
	}

Veja que existe grande semelhança entre esta e a das despesas.


Vamos customizar a src/Template/Despesas e criar duas views novas:

src/Template/Despesas/despesas_mes.ctp:

<?php ?>
<nav class="large-3 medium-4 columns" id="actions-sidebar">
    <ul class="side-nav">
    <h3><?= __('Despesas') ?></h3>
<?php
print '<b>Mês: </b>'.$mes. '<br><b>Total: </b>'. $total;
?>
<br>
<br>
<br>
<li><?= $this->Html->link(__('Voltar'), ['action' => 'index']) ?></li>

</nav>

src/Template/Despesas/saldo_mes.ctp:

<?php ?>
<nav class="large-3 medium-4 columns" id="actions-sidebar">
    <ul class="side-nav">
    <h3><?= __('Despesas') ?></h3>
<?php
print '<b>Mês: </b>'.$mes. '<br><b>Saldol: </b>'. $saldo;
?>
<br>
<br>
<br>
<li><?= $this->Html->link(__('Voltar'), ['action' => 'index']) ?></li>
</nav>

Agora vejamos a customização do index.ctp

Logo abaixo da linha:

<li><?= $this->Html->link(__('New Receita'), ['controller' => 'Receitas', 'action' => 'add']) ?></li>

Adicione os dois pequenos forms:

        <b>Despesas de um mês</b>
        <?php
           echo $this->Form->create("Despesas",['url'=>'/despesas/despesas_mes']);
           echo $this->Form->input('mes');
           echo $this->Form->button('Submit');
           echo $this->Form->end();
        ?>
        <b>Saldo de um mês</b>
        <?php
           echo $this->Form->create("Saldo",['url'=>'/despesas/saldo_mes']);
           echo $this->Form->input('mes');
           echo $this->Form->button('Submit');
           echo $this->Form->end();
        ?>

Depois de pronto podemos efetuar as operações através dos pequenos forms.

- O form chama o action do controller
- O controller chama o model para que devolva o resultado de uma função
- Recebendo o resultado o controller devolve para a view/template respectiva


Testando

Agora acesse pela web
http://localhost/financas

Pesquise o total das despesas do mês de 05/2017 ou outro que você tenha cadastrado.
Pesquise qual o saldo de um mês

Isso dá para começar a mexer no código e ir em frente.



Fluxo das informações

- O usuário acessa o aplicativo pela URL:
http://localhost/financas
- Então ele cai em (pela configuração do routes):
http://localhost/financas/despesas/index

- Na view Despesas/index.ctp ele consulta a despesa total de um certo mês pelo formulário Despesas de um mês

- Este form o direciona para o action DespesasController/despesasMes() através do comando do form: $this->Form->create("Despesas",['url'=>'/despesas/despesas_mes'])

- O controller então registra o DespesasTable e chama através do seu método despesasMes() para saber o total das despesas do referido mês

- O DespesasTable, através do seu método despesasMes() prepara uma consulta e a envia ao banco de dados.

- O banco de dados retorna o resultado para o método despesasMes() do DespesasTable.

- O método do DespesasTable retorna o valor para o DespesasController, em seu método despesasMes()

- O método despesasMes() do DespesasController envia através do método set() o mês e o total de despesas do referido mês para a view com o mesmo nome dele, que é a Despesas/despesas_mes.ctp

- Finalmente o usuário é redirecionado para a view despesas_mes.ctp onde recebe o resultado de sua consulta
http://localhost/financas/despesas/despesas_mes

 

Comments fornecido por CComment

Novo Testamento

E ele olhava em redor, para ver a que isto fizera.
(Mc, 5:32)

Rotas no Mapa do Google

© 2015 Ribamar FS. All Rights Reserved. Designed By JoomShaper