{ *******************************************************************************
Title: T2Ti ERP
Description: Janela de Recebimento das Parcelas

The MIT License

Copyright: Copyright (C) 2016 T2Ti.COM

Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

The author may be contacted at:
t2ti.com@gmail.com</p>

@author Albert Eije
@version 2.0
******************************************************************************* }
unit UFinParcelaRecebimento;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Atributos,
  Dialogs, UTelaCadastro, DB, DBClient, Menus, StdCtrls, ExtCtrls, Buttons, Grids,
  DBGrids, JvExDBGrids, JvDBGrid, JvDBUltimGrid, ComCtrls, ViewFinLancamentoReceberVO,
  ViewFinLancamentoReceberController, Tipos, Constantes, LabeledCtrls,
  ActnList, RibbonSilverStyleActnCtrls, ActnMan, Mask, JvExMask, JvToolEdit,
  JvExStdCtrls, JvEdit, JvValidateEdit, ToolWin, ActnCtrls, JvBaseEdits,
  Generics.Collections, Biblioteca, RTTI, FinChequeRecebidoVO, AdmParametroVO,
  System.Actions, Controller;

type
  [TFormDescription(TConstantes.MODULO_CONTAS_RECEBER, 'Recebimento')]

  TFFinParcelaRecebimento = class(TFTelaCadastro)
    BevelEdits: TBevel;
    PanelEditsInterno: TPanel;
    EditDataRecebimento: TLabeledDateEdit;
    EditTaxaJuro: TLabeledCalcEdit;
    EditValorJuro: TLabeledCalcEdit;
    EditValorMulta: TLabeledCalcEdit;
    EditValorDesconto: TLabeledCalcEdit;
    EditTaxaDesconto: TLabeledCalcEdit;
    EditTaxaMulta: TLabeledCalcEdit;
    MemoHistorico: TLabeledMemo;
    ActionManager: TActionManager;
    ActionBaixarParcela: TAction;
    DSParcelaRecebimento: TDataSource;
    CDSParcelaRecebimento: TClientDataSet;
    EditIdTipoRecebimento: TLabeledCalcEdit;
    EditCodigoTipoRecebimento: TLabeledEdit;
    EditTipoRecebimento: TLabeledEdit;
    EditIdContaCaixa: TLabeledCalcEdit;
    EditContaCaixa: TLabeledEdit;
    EditValorRecebido: TLabeledCalcEdit;
    EditValorAReceber: TLabeledCalcEdit;
    EditDataVencimento: TLabeledDateEdit;
    GroupBox1: TGroupBox;
    Label1: TLabel;
    EditDataInicio: TLabeledDateEdit;
    EditDataFim: TLabeledDateEdit;
    PanelParcelaPaga: TPanel;
    GridRecebimentos: TJvDBUltimGrid;
    ActionToolBar1: TActionToolBar;
    ComboBoxTipoBaixa: TLabeledComboBox;
    PanelTotaisPagos: TPanel;
    CDSParcelaRecebimentoID: TIntegerField;
    CDSParcelaRecebimentoID_FIN_PARCELA_RECEBER: TIntegerField;
    CDSParcelaRecebimentoID_FIN_CHEQUE_RECEBIDO: TIntegerField;
    CDSParcelaRecebimentoID_FIN_TIPO_RECEBIMENTO: TIntegerField;
    CDSParcelaRecebimentoID_CONTA_CAIXA: TIntegerField;
    CDSParcelaRecebimentoDATA_RECEBIMENTO: TDateField;
    CDSParcelaRecebimentoTAXA_JURO: TFMTBCDField;
    CDSParcelaRecebimentoTAXA_MULTA: TFMTBCDField;
    CDSParcelaRecebimentoTAXA_DESCONTO: TFMTBCDField;
    CDSParcelaRecebimentoVALOR_JURO: TFMTBCDField;
    CDSParcelaRecebimentoVALOR_MULTA: TFMTBCDField;
    CDSParcelaRecebimentoVALOR_DESCONTO: TFMTBCDField;
    CDSParcelaRecebimentoVALOR_RECEBIDO: TFMTBCDField;
    CDSParcelaRecebimentoCONTA_CAIXANOME: TStringField;
    CDSParcelaRecebimentoTIPO_RECEBIMENTODESCRICAO: TStringField;
    CDSParcelaRecebimentoCHEQUENUMERO: TIntegerField;
    CDSParcelaRecebimentoHISTORICO: TStringField;
    ActionExcluirParcela: TAction;
    procedure FormCreate(Sender: TObject);
    procedure ActionBaixarParcelaExecute(Sender: TObject);
    procedure CalcularTotalPago(Sender: TObject);
    procedure BotaoConsultarClick(Sender: TObject);
    procedure BotaoSalvarClick(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure BaixarParcela;
    procedure BaixarParcelaCheque;
    procedure CalcularTotais;
    procedure GridCellClick(Column: TColumn);
    procedure GridDrawColumnCell(Sender: TObject; const Rect: TRect; DataCol: Integer; Column: TColumn; State: TGridDrawState);
    function VerificarPacoteRecebimentoCheque: Boolean;
    procedure ActionExcluirParcelaExecute(Sender: TObject);
    procedure EditIdTipoRecebimentoKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
    procedure EditIdContaCaixaKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
  private
    { Private declarations }
  public
    { Public declarations }
    procedure GridParaEdits; override;
    procedure ControlaBotoes; override;
    procedure ControlaPopupMenu; override;
    procedure LimparCampos; override;
    function MontaFiltro: string; override;

    // Controles CRUD
    function DoEditar: Boolean; override;
  end;

var
  FFinParcelaRecebimento: TFFinParcelaRecebimento;
  ChequeRecebido: TFinChequeRecebidoVO;
  SomaCheque: Extended;
  AdmParametroVO: TAdmParametroVO;

implementation

uses
  FinParcelaRecebimentoVO, FinParcelaRecebimentoController, FinParcelaReceberVO,
  FinParcelaReceberController, FinTipoRecebimentoVO, FinTipoRecebimentoController,
  ContaCaixaVO, ContaCaixaController, UTela, USelecionaCheque, UDataModule,
  AdmParametroController;

{$R *.dfm}

{$REGION 'Infra'}
procedure TFFinParcelaRecebimento.FormCreate(Sender: TObject);
var
  Filtro: String;
begin
  ClasseObjetoGridVO := TViewFinLancamentoReceberVO;
  ObjetoController := TViewFinLancamentoReceberController.Create;

  inherited;

  Filtro := 'ID_EMPRESA = ' + IntToStr(Sessao.Empresa.Id);
  AdmParametroVO := TAdmParametroVO(TController.BuscarObjeto('AdmParametroController.TAdmParametroController', 'ConsultaObjeto', [Filtro], 'GET'));
end;

procedure TFFinParcelaRecebimento.FormShow(Sender: TObject);
begin
  inherited;
  EditDataInicio.Date := Now;
  EditDataFim.Date := Now;
end;

procedure TFFinParcelaRecebimento.ControlaBotoes;
begin
  inherited;

  BotaoInserir.Visible := False;
  BotaoExcluir.Visible := False;
  BotaoCancelar.Visible := False;
  BotaoAlterar.Caption := 'Confirmar [F3]';
  BotaoSalvar.Caption := 'Retornar [F12]';
end;

procedure TFFinParcelaRecebimento.ControlaPopupMenu;
begin
  inherited;

  MenuInserir.Visible := False;
  MenuExcluir.Visible := False;
  MenuCancelar.Visible := False;
  MenuAlterar.Caption := 'Confirmar [F3]';
  menuSalvar.Caption := 'Retornar [F12]';
end;

procedure TFFinParcelaRecebimento.LimparCampos;
var
  DataInicioInformada, DataFimInformada: TDateTime;
begin
  DataInicioInformada := EditDataInicio.Date;
  DataFimInformada := EditDataFim.Date;
  inherited;
  CDSParcelaRecebimento.EmptyDataSet;
  EditDataInicio.Date := DataInicioInformada;
  EditDataFim.Date := DataFimInformada;
end;
{$ENDREGION}

{$REGION 'Controles CRUD'}
function TFFinParcelaRecebimento.DoEditar: Boolean;
begin
  if not CDSGrid.IsEmpty then
  begin

    if CDSGrid.FieldByName('SITUACAO_PARCELA').AsString = '02' then
    begin
      Application.MessageBox('Procedimento não permitido. Parcela já quitada.', 'Mensagem do Sistema', MB_OK + MB_ICONINFORMATION);
      Exit;
    end;

    if VerificarPacoteRecebimentoCheque then
    begin
      ChequeRecebido := TFinChequeRecebidoVO.Create;

      Application.CreateForm(TFSelecionaCheque, FSelecionaCheque);
      FSelecionaCheque.EditValorCheque.Value := SomaCheque;
      FSelecionaCheque.EditDataEmissao.Date := Now;

      FSelecionaCheque.ShowModal;

      if FSelecionaCheque.Confirmou then
      begin
        ChequeRecebido.IdPessoa := FSelecionaCheque.EditIdPessoa.AsInteger;
        ChequeRecebido.Nome := FSelecionaCheque.EditPessoa.Text;
        ChequeRecebido.CpfCnpj := FSelecionaCheque.EditCpfCnpj.Text;
        ChequeRecebido.CodigoBanco := FSelecionaCheque.EditCodigoBanco.Text;
        ChequeRecebido.CodigoAgencia := FSelecionaCheque.EditCodigoAgencia.Text;
        ChequeRecebido.Conta := FSelecionaCheque.EditNumeroConta.Text;
        ChequeRecebido.Numero := FSelecionaCheque.EditNumeroCheque.AsInteger;
        ChequeRecebido.DataEmissao := FSelecionaCheque.EditDataEmissao.Date;
        ChequeRecebido.Valor := FSelecionaCheque.EditValorCheque.Value;
        ChequeRecebido.BomPara := FSelecionaCheque.EditBomPara.Date;
        BaixarParcelaCheque;
        FreeAndNil(FSelecionaCheque);
      end;
    end
    else
    begin
      Result := inherited DoEditar;

      if Result then
      begin
        ComboBoxTipoBaixa.SetFocus;
      end;
    end;
  end;
end;

function TFFinParcelaRecebimento.VerificarPacoteRecebimentoCheque: Boolean;
var
  LinhaAtual: TBookMark;
  ParcelasVencidas: Boolean;
begin
  Result := False;
  ParcelasVencidas := False;
  LinhaAtual := CDSGrid.GetBookmark;
  SomaCheque := 0;

  CDSGrid.DisableControls;
  CDSGrid.First;
  while not CDSGrid.Eof do
  begin
    if CDSGrid.FieldByName('EmitirCheque').AsString = 'S' then
      SomaCheque := SomaCheque + CDSGrid.FieldByName('VALOR_PARCELA').AsFloat;
    ParcelasVencidas := CDSGrid.FieldByName('DATA_VENCIMENTO').AsDateTime < Date;
    CDSGrid.Next;
  end;

  if CDSGrid.BookmarkValid(LinhaAtual) then
  begin
    CDSGrid.GotoBookmark(LinhaAtual);
    CDSGrid.FreeBookmark(LinhaAtual);
  end;
  CDSGrid.EnableControls;

  if SomaCheque = 0 then
    Exit;

  if ParcelasVencidas then
  begin
    Application.MessageBox('Procedimento não permitido. Parcela sem valores ou vencidas.', 'Mensagem do Sistema', MB_OK + MB_ICONINFORMATION);
    CDSGrid.EnableControls;
    Exit;
  end;

  Result := True;
end;
{$ENDREGION}

{$REGION 'Campos Transientes'}
procedure TFFinParcelaRecebimento.EditIdTipoRecebimentoKeyUp(Sender: TObject;  var Key: Word; Shift: TShiftState);
var
  Filtro: String;
begin
  if Key = VK_F1 then
  begin
    if EditIdTipoRecebimento.Value <> 0 then
      Filtro := 'ID = ' + EditIdTipoRecebimento.Text
    else
      Filtro := 'ID=0';

    try
      EditIdTipoRecebimento.Clear;
      EditCodigoTipoRecebimento.Clear;
      EditTipoRecebimento.Clear;
      if not PopulaCamposTransientes(Filtro, TFinTipoRecebimentoVO, TFinTipoRecebimentoController) then
        PopulaCamposTransientesLookup(TFinTipoRecebimentoVO, TFinTipoRecebimentoController);
      if CDSTransiente.RecordCount > 0 then
      begin
        EditIdTipoRecebimento.Text := CDSTransiente.FieldByName('ID').AsString;
        EditCodigoTipoRecebimento.Text := CDSTransiente.FieldByName('TIPO').AsString;
        EditTipoRecebimento.Text := CDSTransiente.FieldByName('DESCRICAO').AsString;
      end
      else
      begin
        Exit;
        EditIdContaCaixa.SetFocus;
      end;
    finally
      CDSTransiente.Close;
    end;
  end;
end;

procedure TFFinParcelaRecebimento.EditIdContaCaixaKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
var
  Filtro: String;
begin
  if Key = VK_F1 then
  begin
    if EditIdContaCaixa.Value <> 0 then
      Filtro := 'ID = ' + EditIdContaCaixa.Text
    else
      Filtro := 'ID=0';

    try
      EditIdContaCaixa.Clear;
      EditContaCaixa.Clear;
      if not PopulaCamposTransientes(Filtro, TContaCaixaVO, TContaCaixaController) then
        PopulaCamposTransientesLookup(TContaCaixaVO, TContaCaixaController);
      if CDSTransiente.RecordCount > 0 then
      begin
        EditIdContaCaixa.Text := CDSTransiente.FieldByName('ID').AsString;
        EditContaCaixa.Text := CDSTransiente.FieldByName('NOME').AsString;
      end
      else
      begin
        Exit;
        EditDataVencimento.SetFocus;
      end;
    finally
      CDSTransiente.Close;
    end;
  end;
end;
{$ENDREGION}

{$REGION 'Controle de Grid'}
procedure TFFinParcelaRecebimento.GridCellClick(Column: TColumn);
begin
  if Column.Index = 0 then
  begin
    if CDSGrid.FieldByName('SITUACAO_PARCELA').AsString = '02' then
    begin
      Application.MessageBox('Procedimento não permitido. Parcela já quitada.', 'Mensagem do Sistema', MB_OK + MB_ICONINFORMATION);
    end
    else
    begin
      CDSGrid.Edit;
      if CDSGrid.FieldByName('EmitirCheque').AsString = '' then
        CDSGrid.FieldByName('EmitirCheque').AsString := 'S'
      else
        CDSGrid.FieldByName('EmitirCheque').AsString := '';
      CDSGrid.Post;
    end;
  end;
end;

procedure TFFinParcelaRecebimento.GridDrawColumnCell(Sender: TObject; const Rect: TRect; DataCol: Integer; Column: TColumn; State: TGridDrawState);
var
  lIcone : TBitmap;
  lRect: TRect;
begin
  lRect := Rect;
  lIcone := TBitmap.Create;

  if Column.Index = 0 then
  begin
    if Grid.Columns[0].Width <> 32 then
      Grid.Columns[0].Width := 32;

    try
      if Grid.Columns[1].Field.Value = '' then
      begin
        FDataModule.ImagensCheck.GetBitmap(0, lIcone);
        Grid.Canvas.Draw(Rect.Left+8 ,Rect.Top+1, lIcone);
      end
      else if Grid.Columns[1].Field.Value = 'S' then
      begin
        FDataModule.ImagensCheck.GetBitmap(1, lIcone);
        Grid.Canvas.Draw(Rect.Left+8,Rect.Top+1, lIcone);
      end
    finally
      lIcone.Free;
    end;
  end;
end;

procedure TFFinParcelaRecebimento.GridParaEdits;
var
  Filtro: String;
begin
  inherited;

  if not CDSGrid.IsEmpty then
  begin
    ObjetoVO := TViewFinLancamentoReceberVO(TController.BuscarObjeto('ViewFinLancamentoReceberController.TViewFinLancamentoReceberController', 'ConsultaObjeto', ['ID=' + IdRegistroSelecionado.ToString], 'GET'));
  end;

  if Assigned(ObjetoVO) then
  begin
    EditIdContaCaixa.AsInteger := TViewFinLancamentoReceberVO(ObjetoVO).IdContaCaixa;
    EditContaCaixa.Text := TViewFinLancamentoReceberVO(ObjetoVO).NomeContaCaixa;
    EditDataVencimento.Date := TViewFinLancamentoReceberVO(ObjetoVO).DataVencimento;
    EditValorAReceber.Value := TViewFinLancamentoReceberVO(ObjetoVO).ValorParcela;
    EditTaxaJuro.Value := TViewFinLancamentoReceberVO(ObjetoVO).TaxaJuro;
    EditValorJuro.Value := TViewFinLancamentoReceberVO(ObjetoVO).ValorJuro;
    EditTaxaMulta.Value := TViewFinLancamentoReceberVO(ObjetoVO).TaxaMulta;
    EditValorMulta.Value := TViewFinLancamentoReceberVO(ObjetoVO).ValorMulta;
    EditTaxaDesconto.Value := TViewFinLancamentoReceberVO(ObjetoVO).TaxaDesconto;
    EditValorDesconto.Value := TViewFinLancamentoReceberVO(ObjetoVO).ValorDesconto;
    CalcularTotalPago(nil);

    TFinParcelaRecebimentoController.SetDataSet(CDSParcelaRecebimento);
    Filtro := 'ID_FIN_PARCELA_RECEBER=' + QuotedStr(IntToStr(CDSGrid.FieldByName('ID_PARCELA_RECEBER').AsInteger));
    TController.ExecutarMetodo('FinParcelaRecebimentoController.TFinParcelaRecebimentoController', 'Consulta', [Filtro, '0', False], 'GET', 'Lista');

    CalcularTotais;
  end;
end;
{$ENDREGION}

{$REGION 'Actions'}
procedure TFFinParcelaRecebimento.ActionBaixarParcelaExecute(Sender: TObject);
begin
  if EditIdTipoRecebimento.AsInteger <= 0 then
  begin
    Application.MessageBox('É necessário informar o tipo de Recebimento.', 'Mensagem do Sistema', MB_OK + MB_ICONINFORMATION);
    EditIdTipoRecebimento.SetFocus;
    Exit;
  end;
  if EditIdContaCaixa.AsInteger <= 0 then
  begin
    Application.MessageBox('É necessário informar a conta caixa.', 'Mensagem do Sistema', MB_OK + MB_ICONINFORMATION);
    EditIdContaCaixa.SetFocus;
    Exit;
  end;

  ChequeRecebido := TFinChequeRecebidoVO.Create;

  if EditCodigoTipoRecebimento.Text = '02' then
  begin
    Application.CreateForm(TFSelecionaCheque, FSelecionaCheque);
    FSelecionaCheque.EditDataEmissao.Date := Now;
    FSelecionaCheque.EditBomPara.Date := EditDataRecebimento.Date;
    FSelecionaCheque.EditValorCheque.Value := EditValorRecebido.Value;
    FSelecionaCheque.MemoHistorico.Text := MemoHistorico.Text;
    FSelecionaCheque.EditIdContaCaixa.AsInteger := EditIdContaCaixa.AsInteger;
    FSelecionaCheque.EditContaCaixa.Text := EditContaCaixa.Text;
    FSelecionaCheque.ShowModal;

    if FSelecionaCheque.Confirmou then
    begin
      ChequeRecebido.IdPessoa := FSelecionaCheque.EditIdPessoa.AsInteger;
      ChequeRecebido.Nome := FSelecionaCheque.EditPessoa.Text;
      ChequeRecebido.CpfCnpj := FSelecionaCheque.EditCpfCnpj.Text;
      ChequeRecebido.CodigoBanco := FSelecionaCheque.EditCodigoBanco.Text;
      ChequeRecebido.CodigoAgencia := FSelecionaCheque.EditCodigoAgencia.Text;
      ChequeRecebido.Conta := FSelecionaCheque.EditNumeroConta.Text;
      ChequeRecebido.Numero := FSelecionaCheque.EditNumeroCheque.AsInteger;
      ChequeRecebido.DataEmissao := FSelecionaCheque.EditDataEmissao.Date;
      ChequeRecebido.Valor := FSelecionaCheque.EditValorCheque.Value;
      ChequeRecebido.BomPara := FSelecionaCheque.EditBomPara.Date;
      BaixarParcela;
      FreeAndNil(FSelecionaCheque);
    end;
  end
  else
    BaixarParcela;
end;

procedure TFFinParcelaRecebimento.ActionExcluirParcelaExecute(Sender: TObject);
var
  ParcelaReceber, ParcelaReceberOld: TFinParcelaReceberVO;
begin
  /// EXERCICIO: VERIFIQUE SE A IMPLEMENTAÇÃO ESTÁ CORRETA. CORRIJA O QUE FOR NECESSÁRIO.

  if CDSParcelaRecebimentoID.AsInteger > 0 then
    TFinParcelaRecebimentoController.Exclui(CDSParcelaRecebimentoID.AsInteger);
  CDSParcelaRecebimento.Delete;

  if CDSParcelaRecebimento.IsEmpty then
  begin
    ParcelaReceber := TFinParcelaReceberVO(TController.BuscarObjeto('FinParcelaReceberController.TFinParcelaReceberController', 'ConsultaObjeto', ['ID=' + CDSGrid.FieldByName('ID_PARCELA_RECEBER').AsString], 'GET'));
    ParcelaReceber.IdFinStatusParcela := AdmParametroVO.FinParcelaAberto;
    TController.ExecutarMetodo('FinParcelaReceberController.TFinParcelaReceberController', 'Altera', [ParcelaReceber], 'POST', 'Boolean');
  end;
  CalcularTotais;
end;

procedure TFFinParcelaRecebimento.BaixarParcela;
var
  ParcelaReceber: TFinParcelaReceberVO;
begin
  ParcelaReceber := TFinParcelaReceberVO(TController.BuscarObjeto('FinParcelaReceberController.TFinParcelaReceberController', 'ConsultaObjeto', ['ID=' + CDSGrid.FieldByName('ID_PARCELA_RECEBER').AsString], 'GET'));

  if ComboBoxTipoBaixa.ItemIndex = 0 then
    ParcelaReceber.IdFinStatusParcela := AdmParametroVO.FinParcelaQuitado
  else if ComboBoxTipoBaixa.ItemIndex = 1 then
    ParcelaReceber.IdFinStatusParcela := AdmParametroVO.FinParcelaQuitadoParcial;

  ParcelaReceber.FinParcelaRecebimentoVO := TFinParcelaRecebimentoVO.Create;

  ParcelaReceber.FinParcelaRecebimentoVO.IdFinTipoRecebimento := EditIdTipoRecebimento.AsInteger;
  ParcelaReceber.FinParcelaRecebimentoVO.IdFinParcelaReceber := ParcelaReceber.Id;
  ParcelaReceber.FinParcelaRecebimentoVO.IdContaCaixa := EditIdContaCaixa.AsInteger;
  ParcelaReceber.FinParcelaRecebimentoVO.DataRecebimento := EditDataRecebimento.Date;
  ParcelaReceber.FinParcelaRecebimentoVO.TaxaJuro := EditTaxaJuro.Value;
  ParcelaReceber.FinParcelaRecebimentoVO.ValorJuro := EditValorJuro.Value;
  ParcelaReceber.FinParcelaRecebimentoVO.TaxaMulta := EditTaxaMulta.Value;
  ParcelaReceber.FinParcelaRecebimentoVO.ValorMulta := EditValorMulta.Value;
  ParcelaReceber.FinParcelaRecebimentoVO.TaxaDesconto := EditTaxaDesconto.Value;
  ParcelaReceber.FinParcelaRecebimentoVO.ValorDesconto := EditValorDesconto.Value;
  ParcelaReceber.FinParcelaRecebimentoVO.Historico := Trim(MemoHistorico.Text);
  ParcelaReceber.FinParcelaRecebimentoVO.ValorRecebido := EditValorRecebido.Value;

  ParcelaReceber.FinChequeRecebidoVO := ChequeRecebido;

  TController.ExecutarMetodo('FinParcelaReceberController.TFinParcelaReceberController', 'Altera', [ParcelaReceber], 'POST', 'Boolean');
  TFinParcelaRecebimentoController.SetDataSet(CDSParcelaRecebimento);
  Filtro := 'ID_FIN_PARCELA_RECEBER=' + QuotedStr(IntToStr(CDSGrid.FieldByName('ID_PARCELA_RECEBER').AsInteger));
  TController.ExecutarMetodo('FinParcelaRecebimentoController.TFinParcelaRecebimentoController', 'Consulta', [Filtro, '0', False], 'GET', 'Lista');
  CalcularTotais;
end;

procedure TFFinParcelaRecebimento.BaixarParcelaCheque;
var
  ParcelaReceber, ObjetoPersistencia: TFinParcelaReceberVO;
  ParcelaRecebimento: TFinParcelaRecebimentoVO;
  ListaParcelaReceber: TObjectList<TFinParcelaReceberVO>;
  ListaParcelaRecebimento: TObjectList<TFinParcelaRecebimentoVO>;
begin
  try
    ListaParcelaReceber := TObjectList<TFinParcelaReceberVO>.Create;
    ListaParcelaRecebimento := TObjectList<TFinParcelaRecebimentoVO>.Create;

    CDSGrid.DisableControls;
    CDSGrid.First;
    while not CDSGrid.Eof do
    begin
      if CDSGrid.FieldByName('EmitirCheque').AsString = 'S' then
      begin
        ParcelaReceber := TFinParcelaReceberVO(TController.BuscarObjeto('FinParcelaReceberController.TFinParcelaReceberController', 'ConsultaObjeto', ['ID=' + CDSGrid.FieldByName('ID_PARCELA_RECEBER').AsString], 'GET'));
        ParcelaReceber.IdFinStatusParcela := AdmParametroVO.FinParcelaQuitado;

        ParcelaRecebimento := TFinParcelaRecebimentoVO.Create;
        ParcelaRecebimento.IdFinTipoRecebimento := AdmParametroVO.FinTipoRecebimentoEdi;
        ParcelaRecebimento.IdFinParcelaReceber := ParcelaReceber.Id;
        ParcelaRecebimento.IdContaCaixa := FSelecionaCheque.EditIdContaCaixa.AsInteger;
        ParcelaRecebimento.DataRecebimento := FSelecionaCheque.EditBomPara.Date;
        ParcelaRecebimento.Historico := FSelecionaCheque.MemoHistorico.Text;
        ParcelaRecebimento.ValorRecebido := ParcelaReceber.Valor;

        ListaParcelaReceber.Add(ParcelaReceber);
        ListaParcelaRecebimento.Add(ParcelaRecebimento);
      end;
      CDSGrid.Next;
    end;
    CDSGrid.First;
    CDSGrid.EnableControls;

    ObjetoPersistencia := TFinParcelaReceberVO.Create;
    ObjetoPersistencia.ListaParcelaReceberVO := ListaParcelaReceber;
    ObjetoPersistencia.ListaParcelaRecebimentoVO := ListaParcelaRecebimento;
    ObjetoPersistencia.FinChequeRecebidoVO := ChequeRecebido;

    TController.ExecutarMetodo('FinParcelaReceberController.TFinParcelaReceberController', 'BaixarParcelaCheque', [ObjetoPersistencia], 'POST', 'Boolean');

    BotaoConsultar.Click;
  finally
  end;
end;

procedure TFFinParcelaRecebimento.BotaoConsultarClick(Sender: TObject);
var
  Contexto: TRttiContext;
  Tipo: TRttiType;
  NomeClasseController: String;
begin
  Filtro := MontaFiltro;

  if Filtro <> 'ERRO' then
  begin
    Pagina := 0;
    Contexto := TRttiContext.Create;
    try
      Tipo := Contexto.GetType(ObjetoController.ClassType);
      ObjetoController.SetDataSet(CDSGrid);

      NomeClasseController := ObjetoController.UnitName + '.' + ObjetoController.ClassName;
      TController.ExecutarMetodo(NomeClasseController, 'Consulta', [Trim(Filtro), Pagina.ToString, False], 'GET', 'Lista');

      ControlaBotoesNavegacaoPagina;
    finally
      Contexto.Free;
    end;

    if not CDSGrid.IsEmpty then
      Grid.SetFocus;
  end
  else
    EditCriterioRapido.SetFocus;
end;

procedure TFFinParcelaRecebimento.BotaoSalvarClick(Sender: TObject);
begin
  inherited;
  BotaoConsultar.Click;
end;

/// EXERCICIO: LEVE EM CONSIDERACAO O STATUS DA PARCELA

function TFFinParcelaRecebimento.MontaFiltro: string;
var
  Item: TItemComboBox;
  Idx: Integer;
  DataSetField: TField;
  DataSet: TClientDataSet;
begin
  DataSet := CDSGrid;
  if ComboBoxCampos.ItemIndex <> -1 then
  begin
    if Trim(EditCriterioRapido.Text) = '' then
      EditCriterioRapido.Text := '*';

    Idx := ComboBoxCampos.ItemIndex;
    Item := TItemComboBox(ComboBoxCampos.Items.Objects[Idx]);
    DataSetField := DataSet.FindField(Item.Campo);
    if DataSetField.DataType = ftDateTime then
    begin
      try
        Result := '[' + Item.Campo + '] IN ' + '(' + QuotedStr(FormatDateTime('yyyy-mm-dd', StrToDate(EditCriterioRapido.Text))) + ')';
      except
        Application.MessageBox('Data informada inválida.', 'Erro', MB_OK + MB_ICONERROR);
        Result := 'ERRO';
      end;
    end
    else
      Result := '([DATA_VENCIMENTO] between ' + QuotedStr(DataParaTexto(EditDataInicio.Date)) + ' and ' + QuotedStr(DataParaTexto(EditDataFim.Date)) + ') and [' + Item.Campo + '] LIKE ' + QuotedStr('%' + EditCriterioRapido.Text + '%');
  end
  else
  begin
    Result := ' 1=1 ';
  end;
end;

procedure TFFinParcelaRecebimento.CalcularTotalPago(Sender: TObject);
begin
  EditValorJuro.Value := (EditValorAReceber.Value * (EditTaxaJuro.Value / 30) / 100) * (Now - EditDataVencimento.Date);
  EditValorMulta.Value := EditValorAReceber.Value * (EditTaxaMulta.Value / 100);
  EditValorDesconto.Value := EditValorAReceber.Value * (EditTaxaDesconto.Value / 100);
  EditValorRecebido.Value := EditValorAReceber.Value + EditValorJuro.Value + EditValorMulta.Value - EditValorDesconto.Value;
end;

procedure TFFinParcelaRecebimento.CalcularTotais;
var
  Juro, Multa, Desconto, Total, Saldo: Extended;
begin
  Juro := 0;
  Multa := 0;
  Desconto := 0;
  Total := 0;
  Saldo := 0;
  //
  CDSParcelaRecebimento.DisableControls;
  CDSParcelaRecebimento.First;
  while not CDSParcelaRecebimento.Eof do
  begin
    Juro := Juro + CDSParcelaRecebimento.FieldByName('VALOR_JURO').AsExtended;
    Multa := Multa + CDSParcelaRecebimento.FieldByName('VALOR_MULTA').AsExtended;
    Desconto := Desconto + CDSParcelaRecebimento.FieldByName('VALOR_DESCONTO').AsExtended;
    Total := Total + CDSParcelaRecebimento.FieldByName('VALOR_RECEBIDO').AsExtended;
    CDSParcelaRecebimento.Next;
  end;
  CDSParcelaRecebimento.First;
  CDSParcelaRecebimento.EnableControls;
  //
  PanelTotaisPagos.Caption := '|      Juros: ' +  FloatToStrF(Juro, ffCurrency, 15, 2) +
                        '      |      Multa: ' +   FloatToStrF(Multa, ffCurrency, 15, 2) +
                        '      |      Desconto: ' +   FloatToStrF(Desconto, ffCurrency, 15, 2) +
                        '      |      Total Recebido: ' +   FloatToStrF(Total, ffCurrency, 15, 2) +
                        '      |      Saldo: ' +   FloatToStrF(Total - EditValorAReceber.Value, ffCurrency, 15, 2) + '      |';
end;
{$ENDREGION}

end.
