Update balance with revenue and expense

0

I have an application, where there is an option to register an ACCOUNT with initial balance equal to zero and two options to register REVENUE and EXPENSES.

When registering a REVENUE, the account balance updates according to the value recorded in the revenue.

If an EXPENSE is entered, the same amount as the account balance is subtracted

  

Scenario:
  RECIPE = 80,00
  ACCOUNT BALANCE = 80.00

     

EXPENSE = 30,00
  BALANCE OF ACCOUNT = 50.00

So far so good (working properly) The problem is that I do not know how to update the BALANCE when editing or deleting a RECIPE or EXPENSE.

Example:
When I edit the amount of a REVENUE I want the balance to be updated. When I edit the amount of an EXPENSE I want the balance to be updated. When I delete an EXPENSE I want the amount of EXPENSE, add to the balance.
When I delete a RECIPE I want the value of the RECIPE to subtract from the balance.

Can you help me with this function and query?

The table where the RECIPE and EXPENDITURE are registered has the following columns:

CREATE TABLE IF NOT EXISTS 'lancamentos' (
  'idLancamentos' INT(11) NOT NULL AUTO_INCREMENT,
  'descricao' VARCHAR(255) NULL DEFAULT NULL,
  'valor' VARCHAR(15) NOT NULL,
  'data_vencimento' DATE NOT NULL,
  'categoria_id' INT(11) NULL DEFAULT NULL,
  'conta_id' INT(11) NULL DEFAULT NULL,
  'data_pagamento' DATE NULL DEFAULT NULL,
  'baixado' TINYINT(1) NULL DEFAULT NULL,
  'cliente_fornecedor' VARCHAR(255) NULL DEFAULT NULL,
  'forma_pgto' VARCHAR(100) NULL DEFAULT NULL,
  'tipo' VARCHAR(45) NULL DEFAULT NULL,
  'anexo' VARCHAR(250) NULL,
  'clientes_id' INT(11) NULL DEFAULT NULL,
  PRIMARY KEY ('idLancamentos'),
  INDEX 'fk_lancamentos_clientes1' ('clientes_id' ASC),
  CONSTRAINT 'fk_lancamentos_clientes1'
    FOREIGN KEY ('clientes_id')
    REFERENCES 'clientes' ('idClientes')
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
ENGINE = InnoDB
DEFAULT CHARACTER SET = latin1;

The table where the categories are registered has the following columns:

//1 para RECEITA
//0 para DESPESA

CREATE TABLE IF NOT EXISTS 'categorias' (
  'idCategoria' INT(11) NOT NULL AUTO_INCREMENT,
  'nome_categoria' VARCHAR(45) NOT NULL,
  'tipo_categoria' TINYINT(1) NOT NULL,
  'status_categoria' TINYINT(1) NOT NULL,
  'data_cadastro_categoria' DATE NULL DEFAULT NULL,
  PRIMARY KEY ('idCategoria'))
ENGINE = InnoDB
AUTO_INCREMENT = 1
DEFAULT CHARACTER SET = latin1;

The table where the accounts and balances are registered has the following columns:

 CREATE TABLE IF NOT EXISTS 'contas' (
  'idConta' INT(11) NOT NULL AUTO_INCREMENT,
  'conta' VARCHAR(45) NOT NULL,
  'banco' VARCHAR(45) NOT NULL,
  'numero' VARCHAR(45) NOT NULL,
  'saldo' DECIMAL(10,2) NOT NULL,
  'status' TINYINT(1) NOT NULL,
  'data_cadastro' DATE NULL DEFAULT NULL,
  PRIMARY KEY (idConta))
ENGINE = InnoDB
AUTO_INCREMENT = 1
DEFAULT CHARACTER SET = latin1;

To add EXPENSE, I'm using the function:

function adicionarDespesa() {

    if(!$this->permission->checkPermission($this->session->userdata('permissao'),'aLancamento')){
       $this->session->set_flashdata('error','Você não tem permissão para adicionar lançamentos.');
       redirect(base_url());
    }

    $this->load->library('form_validation');
    $this->data['custom_error'] = '';
    $urlAtual = $this->input->post('urlAtual');
    if ($this->form_validation->run('despesa') == false) {
        $this->data['custom_error'] = (validation_errors() ? '<div class="form_error">' . validation_errors() . '</div>' : false);
    } else {

        $vencimento = $this->input->post('vencimento');
        $pagamento = $this->input->post('pagamento');
        $valor = $this->input->post('valor');
        $conta = $this->input->post('conta_id');

        if($pagamento != null){
            $pagamento = explode('/', $pagamento);
            $pagamento = $pagamento[2].'-'.$pagamento[1].'-'.$pagamento[0];
        }

        if($vencimento == null){
            $vencimento = date('d/m/Y');
        }

        try {

            $vencimento = explode('/', $vencimento);
            $vencimento = $vencimento[2].'-'.$vencimento[1].'-'.$vencimento[0];

        } catch (Exception $e) {
           $vencimento = date('Y/m/d'); 
        }

        $data = array(
            'descricao' => set_value('descricao'),
            //'valor' => set_value('valor'),
            'valor' => $valor,
            'data_vencimento' => $vencimento,
            'categoria_id' => $this->input->post('categoria_id'),
            'conta_id'=> $conta,
            //'conta_id' => $this->input->post('conta_id'),
            'baixado' => $this->input->post('pago'),
            'data_pagamento' => $pagamento != null ? $pagamento : date('Y-m-d'),
            'baixado' => $this->input->post('pago'),
            'cliente_fornecedor' => set_value('fornecedor'),
            'forma_pgto' => $this->input->post('formaPgto'),
            'tipo' => set_value('tipo')
        );

        if ($this->financeiro_model->add('lancamentos',$data) == TRUE) {

            $sql = "UPDATE contas set saldo = saldo - ? WHERE idConta = ?";
            $this->db->query($sql, array($valor, $conta));
            echo json_encode(array('result'=> true));

            $this->session->set_flashdata('success','Despesa adicionada com sucesso!');
            redirect($urlAtual);
        } else {
            $this->session->set_flashdata('error','Ocorreu um erro ao tentar adicionar despesa!');
            echo json_encode(array('result'=> false));
            redirect($urlAtual);
        }
    }

    $this->session->set_flashdata('error','Ocorreu um erro ao tentar adicionar despesa.');
    redirect($urlAtual);


}

To add RECIPE, I'm using the function:

    function adicionarReceita() {

    if(!$this->permission->checkPermission($this->session->userdata('permissao'),'aLancamento')){
       $this->session->set_flashdata('error','Você não tem permissão para adicionar lançamentos.');
       redirect(base_url());
    }

    $this->load->library('form_validation');
    $this->data['custom_error'] = '';
    $urlAtual = $this->input->post('urlAtual');

    if ($this->form_validation->run('receita') == false) {
        $this->data['custom_error'] = (validation_errors() ? '<div class="form_error">' . validation_errors() . '</div>' : false);
    } else {


        $valor = $this->input->post('valor');
        $vencimento = $this->input->post('vencimento');
        $recebimento = $this->input->post('recebimento');
        $conta = $this->input->post('conta_id');

        if($recebimento != null){
            $recebimento = explode('/', $recebimento);
            $recebimento = $recebimento[2].'-'.$recebimento[1].'-'.$recebimento[0];
        }

        if($vencimento == null){
            $vencimento = date('d/m/Y');
        }

        try {

            $vencimento = explode('/', $vencimento);
            $vencimento = $vencimento[2].'-'.$vencimento[1].'-'.$vencimento[0];   

        } catch (Exception $e) {
           $vencimento = date('Y/m/d'); 
        }

        $data = array(
            'descricao' => set_value('descricao'),
            //'valor' => set_value('valor'),
            'valor' => $valor,
            'data_vencimento' => $vencimento,
            'data_pagamento' => $recebimento != null ? $recebimento : date('Y-m-d'),
            'categoria_id' => $this->input->post('categoria_id'),
            'conta_id'=> $conta,
            //'conta_id' => $this->input->post('conta_id'),
            'baixado' => $this->input->post('recebido'),
            'cliente_fornecedor' => set_value('cliente'),
            'forma_pgto' => $this->input->post('formaPgto'),
            'tipo' => set_value('tipo')
        );

        if ($this->financeiro_model->add('lancamentos',$data) == TRUE) {

            $sql = "UPDATE contas set saldo = saldo + ? WHERE idConta = ?";
            $this->db->query($sql, array($valor, $conta));
            echo json_encode(array('result'=> true));

            $this->session->set_flashdata('success','Receita adicionada com sucesso!');
            redirect($urlAtual);

        } else {
            $this->data['custom_error'] = '<div class="form_error"><p>Ocorreu um erro.</p></div>';

            echo json_encode(array('result'=> false));
        }
    }

    $this->session->set_flashdata('error','Ocorreu um erro ao tentar adicionar receita.');
    redirect($urlAtual);

}

To edit REVENUE and DEPENDENCE, I am using the function:

    public function editar(){   
    if(!$this->permission->checkPermission($this->session->userdata('permissao'),'eLancamento')){
       $this->session->set_flashdata('error','Você não tem permissão para editar lançamentos.');
       redirect(base_url());
    }

    $this->load->library('form_validation');
    $this->data['custom_error'] = '';
    $urlAtual = $this->input->post('urlAtual');

    $this->form_validation->set_rules('descricao', '', 'trim|required|xss_clean');
    $this->form_validation->set_rules('fornecedor', '', 'trim|required|xss_clean');
    $this->form_validation->set_rules('valor', '', 'trim|required|xss_clean');
    $this->form_validation->set_rules('vencimento', '', 'trim|required|xss_clean');
    $this->form_validation->set_rules('pagamento', '', 'trim|xss_clean');

    if ($this->form_validation->run() == false) {
        $this->data['custom_error'] = (validation_errors() ? '<div class="form_error">' . validation_errors() . '</div>' : false);
    } else {

        $vencimento = $this->input->post('vencimento');
        $pagamento = $this->input->post('pagamento');
        $valor = $this->input->post('valor');
        $conta = $this->input->post('conta_id');

        try {

            $vencimento = explode('/', $vencimento);
            $vencimento = $vencimento[2].'-'.$vencimento[1].'-'.$vencimento[0];

            $pagamento = explode('/', $pagamento);
            $pagamento = $pagamento[2].'-'.$pagamento[1].'-'.$pagamento[0];

        } catch (Exception $e) {
           $vencimento = date('Y/m/d'); 
        }

        $data = array(
            'descricao' => $this->input->post('descricao'),
            //'valor' => $this->input->post('valor'),
            'valor' => $valor,
            'categoria_id' => $this->input->post('categoria_id'),
            'conta_id'=> $conta,
            'data_vencimento' => $vencimento,
            'data_pagamento' => $pagamento,
            'baixado' => $this->input->post('pago'),
            'cliente_fornecedor' => $this->input->post('fornecedor'),
            'forma_pgto' => $this->input->post('formaPgto'),
            'tipo' => $this->input->post('tipo')
        );

        if ($this->financeiro_model->edit('lancamentos',$data,'idLancamentos',$this->input->post('id')) == TRUE) {


            $sql = "UPDATE contas set saldo = saldo - ? WHERE idConta = ?";
            $this->db->query($sql, array($valor, $conta));
            echo json_encode(array('result'=> true));

            $this->session->set_flashdata('success','lançamento editado com sucesso!');
            redirect($urlAtual);
        } else {

            $this->session->set_flashdata('error','Ocorreu um erro ao tentar editar lançamento!');
            echo json_encode(array('result'=> false));
            redirect($urlAtual);
        }

        $sql = "UPDATE contas set saldo = saldo + ? WHERE idConta = ?";
            $this->db->query($sql, array($valor, $conta));
            echo json_encode(array('result'=> true));
    }

    $this->session->set_flashdata('error','Ocorreu um erro ao tentar editar lançamento.');
    echo json_encode(array('result'=> false));
    redirect($urlAtual);

    $data = array(
            'descricao' => $this->input->post('descricao'),
            //'valor' => $this->input->post('valor'),
            'valor' => $valor,
            'categoria_id' => $this->input->post('categoria_id'),
            'conta_id'=> $conta,
            'data_vencimento' => $this->input->post('vencimento'),
            'data_pagamento' => $this->input->post('pagamento'),
            'baixado' => $this->input->post('pago'),
            'cliente_fornecedor' => set_value('fornecedor'),
            'forma_pgto' => $this->input->post('formaPgto'),
            'tipo' => $this->input->post('tipo')
        );
    print_r($data);

}

To exclude RECIPE and DEPENDENCE, I am using the function:

    public function excluirLancamento(){   

    if(!$this->permission->checkPermission($this->session->userdata('permissao'),'dLancamento')){
       $this->session->set_flashdata('error','Você não tem permissão para excluir lançamentos.');
       redirect(base_url());
    }

    $id = $this->input->post('id');

    if($id == null || ! is_numeric($id)){
        $json = array('result'=>  false);
        echo json_encode($json);
    }
    else{

        $result = $this->financeiro_model->delete('lancamentos','idLancamentos',$id); 
        if($result){
            $json = array('result'=>  true);
            echo json_encode($json);
        }
        else{
            $json = array('result'=>  false);
            echo json_encode($json);
        }

    }
}

FINANCIAL MODEL

function get($table,$fields,$where='',$perpage=0,$start=0,$one=false,$array='array'){

    $this->db->select($fields);
    $this->db->from($table);
    $this->db->order_by('data_vencimento', 'asc');
    $this->db->limit($perpage,$start);
    if($where){
        $this->db->where($where);
    }

    $query = $this->db->get();

    $result =  !$one  ? $query->result() : $query->row();
    return $result;
}


function getById($id){
    $this->db->where('idClientes',$id);
    $this->db->limit(1);
    return $this->db->get('clientes')->row();
}

function add($table,$data){
    $this->db->insert($table, $data);         
    if ($this->db->affected_rows() == '1')
    {
        return TRUE;
    }

    return FALSE;       
}

function edit($table,$data,$fieldID,$ID){
    $this->db->where($fieldID,$ID);
    $this->db->update($table, $data);

    if ($this->db->affected_rows() >= 0)
    {
        return TRUE;
    }

    return FALSE;       
}

function delete($table,$fieldID,$ID){
    $this->db->where($fieldID,$ID);
    $this->db->delete($table);
    if ($this->db->affected_rows() == '1')
    {
        return TRUE;
    }

    return FALSE;        
}

function count($table, $where) {

    $this->db->from($table);
    if($where){
        $this->db->where($where);
    }
    return $this->db->count_all_results();
}
    
asked by anonymous 14.09.2016 / 16:22

2 answers

1

In this case you can work with TRIGGERS, which are triggers set in a table, which execute a query whenever a record is inserted, updated or deleted.

Documentation: link

Example:

CREATE TRIGGER trg_lancamentos_ai AFTER INSERT ON lancamentos
    FOR EACH ROW
    BEGIN
        UPDATE contas SET
            saldo = (
              CASE NEW.tipo
                WHEN '1' THEN saldo + NEW.valor
                WHEN '0' THEN saldo - NEW.valor
                ELSE saldo
              END
            )
        WHERE
            (idConta = NEW.conta_id);
    END;

CREATE TRIGGER trg_lancamentos_au AFTER UPDATE ON lancamentos
    FOR EACH ROW
    BEGIN
        UPDATE contas SET
            saldo = (
              CASE NEW.tipo
                WHEN '1' THEN saldo - OLD.valor + NEW.valor
                WHEN '0' THEN saldo + OLD.valor - NEW.valor
                ELSE saldo
              END
            )
        WHERE
            (idConta = NEW.conta_id);
    END;

CREATE TRIGGER trg_lancamentos_ad AFTER DELETE ON lancamentos
    FOR EACH ROW
    BEGIN
        UPDATE contas SET
            saldo = (
              CASE OLD.tipo
                WHEN '1' THEN saldo - OLD.valor
                WHEN '0' THEN saldo + OLD.valor
                ELSE saldo
              END
            )
        WHERE
            (idConta = OLD.conta_id);
    END;

Fiddle with the example in action: link

    
17.08.2017 / 00:29
0

Instead of registering the expense with the value 10, for example, register as -10. In addition to saving a column from the database, it contributes to a better understanding. Return the sum of everything with the command SUM , example:

The table value column is populated with the following values:

150 -10 -30 180 -500

With querry: SELECT SUM(valor) FROM tabela is returned the sum number of all values, profit (in this case is -210)

    
14.09.2016 / 19:41