Observe a Figura 28 - Diagrama ER Numerado.

Diagrama ER Numerado
Figura 28 - Diagrama ER Numerado

A tabela de apólices é sem dúvida a mais importante do Sistema e para que possa ser feito o cadastro de uma nova apólice inicialmente temos que possuir dados nas tabelas de clientes (tbCliente), não está numerada pois nos artigos anteriores implementamos sua funcionalidade, precisamos ter os dados já cadastrados na tabela de modelo de carros (tbModelo) [6] e a partir da apólice, gerar as parcelas [5] para o pagamento por parte do cliente.

Já em relação aos sinistros ocorridos [2] para que possa ser cadastrado, inicialmente temos que ter a apólice cadastrada [1] e também termos previamente cadastrados os tipos de danos [3] e os tipos de sinistros.

Neste artigo vamos criar as classes que representam a lógica de negócios e a respectiva camada de apresentação para as informações sobre a apólice e parcelas, nesta mesma ordem, ou seja, serão adicionadas as classes: clnApolices.cs e clnParcelas.

1) Com o aplicativo aberto adicione duas novas classes chamadas respectivamente: clnApolices.cs, clnParcelas.cs, conforme Figura 29:

Classes Adicionadas
Figura 29 - Classes Adicionadas

Vamos iniciar o detalhamento da classe clnApolices, que representa a lógica de negócios sobre as apólices de seguros no sistema. A classe é composta pelos campos privados, propriedades de acesso e funções ilustradas na Figura 30 - Classe: clnApolices.cs.

Classe: clnApolices.cs
Figura 30 - Classe: clnApolices.cs

2) Abaixo código completo da classe clnApolices.cs

using System;
using System.Collections.Generic;
using System.Text;
using System.Data;

namespace Seguros_OO.Camada_Intermediaria.Logica_Negocios
{
  public class clnApolices
  {
  //1 - Campos privados a classe
  private int idApolice;
  private int idCli;
  private int kmVeiApolice;
  private string numApolice;
  private DateTime dataApolice;
  private DateTime dataValApolice;
  private float valorApolice;
  private int idModelo;
  private bool sinistroApolice;
  private int idSinistro;

  //2 - propriedades, acesso aos campos privados
  public int IdApolice
  {
  get { return idApolice; }
  set { idApolice = value; }
  }
  public int IdCli
  {
  get { return idCli; }
  set { idCli = value; }
  }
  public int KmVeiApolice
  {
  get { return kmVeiApolice; }
  set { kmVeiApolice = value; }
  }
  public string NumApolice
  {
  get { return numApolice; }
  set { numApolice = value; }
  }
  public DateTime DataApolice
  {
  get { return dataApolice; }
  set { dataApolice = value; }
  }
  public DateTime DataValApolice
  {
  get { return dataValApolice; }
  set { dataValApolice = value; }
  }
  public int IdModelo
  {
  get { return idModelo; }
  set { idModelo = value; }
  }
  public float ValorApolice
  {
  get { return valorApolice; }
  set { valorApolice = value; }
  }
  public bool SinistroApolice
  {
  get { return sinistroApolice; }
  set { sinistroApolice = value; }
  }
  public int IdSinistro
  {
  get { return idSinistro; }
  set { idSinistro = value; }
  }
  

  //3 - métodos da classe de Negócios (clnApolices.cs)

  //3.1 Buscar dados da apolice cujo codigo foi especificado
  public void Buscar()
  {
  string csql;
  csql = "Select * From tbApolice where idApolice=" + idApolice;
  DataSet ds;
  clsDados seguros = new clsDados();
  ds = seguros.RetornarDataSet(csql);
  if (ds.Tables[0].Rows.Count > 0)
  {
  Array dados = ds.Tables[0].Rows[0].ItemArray;
  idApolice = Convert.ToInt32(dados.GetValue(0));
  idCli = Convert.ToInt32(dados.GetValue(1));
  kmVeiApolice = Convert.ToInt32(dados.GetValue(2));
  numApolice = Convert.ToString(dados.GetValue(3));
  dataApolice = Convert.ToDateTime(dados.GetValue(4));
  dataValApolice = Convert.ToDateTime(dados.GetValue(5));
  valorApolice = float.Parse(dados.GetValue(6).ToString());
  idModelo = Convert.ToInt32(dados.GetValue(7));
  sinistroApolice = Convert.ToBoolean(dados.GetValue(8));
  idSinistro = Convert.ToInt32(dados.GetValue(9));
  }
  }

  //3.2 Buscar o próximo Id Numerico para 
  //inclusao de um nova apólice.
  public int BuscarId()
  {
  string csql;
  csql = "Select Top 1 (idApolice) From tbApolice order by idApolice desc";
  int IdBuscado;
  clsDados seguros = new clsDados();
  IdBuscado = seguros.RetornarIdNumerico(csql);
  return IdBuscado;
  }

  //3.3 Método para incluir uma nova apolice no 
  //Banco de dados
  public void Gravar()
  {
  StringBuilder csql = new StringBuilder();
  //tratando float e datas:
  string floatvalor = Convert.ToString(valorApolice).Replace(",", ".");
  string vDataApolice = dataApolice.ToString("MM/dd/yyyy");
  string vDataValApolice = dataValApolice.ToString("MM/dd/yyyy");

  csql.Append("Insert into tbApolice");
  csql.Append("(");
  csql.Append("idApolice,");
  csql.Append("idCli,");
  csql.Append("kmVeiApolice,");
  csql.Append("numApolice,");
  csql.Append("dataApolice,");
  csql.Append("dataValApolice,");
  csql.Append("valorApolice,");
  csql.Append("idModelo,");
  csql.Append("sinistroApolice,");
  csql.Append("idSinistro) Values(");
  csql.Append(idApolice);
  csql.Append("," + idCli + ",");
  csql.Append(kmVeiApolice + ",");
  csql.Append("'" + numApolice + "',");
  csql.Append("'" + vDataApolice + "',");
  csql.Append("'" + vDataValApolice + "',");
  csql.Append("'" + floatvalor + "',");
  csql.Append(idModelo + ",");
  csql.Append("'" + sinistroApolice + "',");
  csql.Append(idSinistro + ")");
  clsDados seguros = new clsDados();
  seguros.ExecutarComando(csql.ToString());
  }

  //3.4 Método para atualizar (alterar um registro)
  public void Atualizar()
  {
  string vValorApolice = Convert.ToString(valorApolice).Replace(",", ".");
  string vDataApolice = dataApolice.ToString("MM/dd/yyyy");
  string vDataValApolice = dataValApolice.ToString("MM/dd/yyyy");

  StringBuilder csql = new StringBuilder();
  csql.Append("Update tbApolice ");
  csql.Append("set idApolice=");
  csql.Append(idApolice);
  csql.Append(", idcli=");
  csql.Append(idCli);
  csql.Append(", kmVeiApolice=");
  csql.Append(kmVeiApolice);
  csql.Append(", numApolice='");
  csql.Append(numApolice);
  csql.Append("', dataApolice='");
  csql.Append(vDataApolice);
  csql.Append("', dataValApolice='");
  csql.Append(vDataValApolice);
  csql.Append("', valorApolice='");
  csql.Append(vValorApolice);
  csql.Append("', idModelo=");
  csql.Append(idModelo);
  csql.Append(", idSinistro=");
  csql.Append(idSinistro);
  csql.Append(" where idApolice=");
  csql.Append(idApolice);
  clsDados seguros = new clsDados();
  seguros.ExecutarComando(csql.ToString());
  }

  //3.5 Método para excluir um cliente do 
  //Banco de dados
  public void Excluir()
  {
  StringBuilder csql = new StringBuilder();
  csql.Append("Delete From tbApolice ");
  csql.Append(" where idApolice=");
  csql.Append(idApolice);
  clsDados seguros = new clsDados();
  seguros.ExecutarComando(csql.ToString());
  }
  }
}

3) Agora, vamos montar a classe que representa a lógica de negócios do controle de parcelas pagas e a pagar do Sistema de Apólices de Seguros. Esta classe possui métodos diferentes dos implementados até o momento que vale a pena ressaltar. Primeiro vamos conhecer a estrutura da classe clnParcelas, logo em seguida serão explicadas as novidades nesta classe. Veja na Figura 31 - Classe: clnParcelas.cs.

Classe: clnParcelas.cs
Figura 31 - Classe: clnParcelas.cs

4) Código completo da classe acima representada.

using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.SqlClient;

namespace Seguros_OO.Camada_Intermediaria.Logica_Negocios
{
  public class clnParcelas
  {
  //1 - Campos privados a classe
  private int nroParcela;
  private int idApolice;
  private DateTime dataVenParcela;
  private float valParcela;
  private bool quitadaParcela;
  private DateTime quitadaData;

  //2 - propriedades, acesso aos campos privados
  public int NroParcela
  {
  get { return nroParcela; }
  set { nroParcela = value; }
  }
  public int IdApolice
  {
  get { return idApolice; }
  set { idApolice = value; }
  }
  public DateTime DataVenParcela
  {
  get { return dataVenParcela; }
  set { dataVenParcela = value; }
  }
  public float ValParcela
  {
  get { return valParcela; }
  set { valParcela = value; }
  }
  public bool QuitadaParcela
  {
  get { return quitadaParcela; }
  set { quitadaParcela = value; }
  }
  public DateTime QuitadaData
  {
  get { return quitadaData; }
  set { quitadaData = value; }
  }

  //3 - métodos da classe de Negócios (clnParcelas.cs)

  //3.1 Buscar dados da Parcela da Apolice cujo codigo foi especificado
  public DataSet Buscar()
  {
  string csql;
  //note que aqui estamos filtrando pelo número idApolice
  csql = "Select * From tbParcela where idApolice=" + idApolice;
  DataSet ds;
  clsDados seguros = new clsDados();
  //Essa Busca retorna um objeto dataset
  //que vai preencer o grid de parcelas
  ds = seguros.RetornarDataSet(csql);
  return ds;
  }

  //3.2 Método para incluir uma parcela
  public void Gravar()
  {
  string floatvalor = Convert.ToString(valParcela).Replace(",", ".");
  string vDataVenParcela = dataVenParcela.ToString("MM/dd/yyyy");
  string vQuidataData = quitadaData.ToString("MM/dd/yyyy");
  if (vQuidataData.Trim() == "01/01/0001") vQuidataData = "";
  StringBuilder csql = new StringBuilder();
  csql.Append("Insert into tbParcela");
  csql.Append("(");
  csql.Append("nroParc,");
  csql.Append("idApolice,");
  csql.Append("dataVenParcela,");
  csql.Append("valParcela,");
  csql.Append("quitadaParcela,");
  csql.Append("quitadaData) Values(");
  csql.Append(nroParcela);
  csql.Append("," + idApolice + ",");
  csql.Append("'" + vDataVenParcela + "',");
  csql.Append("'" + floatvalor + "',");
  csql.Append("'" + quitadaParcela + "',");
  csql.Append("'" + vQuidataData + "')");
  clsDados seguros = new clsDados();
  seguros.ExecutarComando(csql.ToString());
  }

  //3.3 Método para atualizar (alterar um registro)
  public void Atualizar()
  {
  string vQuidataData = quitadaData.ToString("MM/dd/yyyy");
  string vdataVenParcela = dataVenParcela.ToString("MM/dd/yyyy");
  StringBuilder csql = new StringBuilder();
  csql.Append("Update tbParcela ");
  csql.Append("set nroParc=");
  csql.Append(nroParcela);
  csql.Append(", idApolice=");
  csql.Append(idApolice);
  csql.Append(", dataVenParcela='");
  csql.Append(vdataVenParcela);
  csql.Append("', valParcela='");
  csql.Append(valParcela.ToString().Replace(",","."));
  csql.Append("', quitadaParcela='");
  csql.Append(quitadaParcela);
  csql.Append("', quitadaData='");
  csql.Append(vQuidataData);
  csql.Append("' where (idApolice=");
  csql.Append(idApolice);
  csql.Append(" and nroParc=");
  csql.Append(nroParcela);
  csql.Append(")");
  clsDados seguros = new clsDados();
  seguros.ExecutarComando(csql.ToString());
  }

  //3.4 Método para excluir uma parcela
  public void Excluir()
  {
  StringBuilder csql = new StringBuilder();
  csql.Append("Delete From tbParcela ");
  csql.Append(" where nr0Pac=");
  csql.Append(nroParcela + " and ");
  csql.Append(" idApolice=" + idApolice);
  clsDados seguros = new clsDados();
  seguros.ExecutarComando(csql.ToString());
  }
  //3.5 Novo Método para Busca Específica de Parcela
  public void BuscarParcEspec()
  {
  string csql;
  csql = "Select * From tbParcela where idApolice=" + idApolice +
  " and nroParc=" + nroParcela;
  DataSet ds;
  clsDados seguros = new clsDados();
  ds = seguros.RetornarDataSet(csql);
  if (ds.Tables[0].Rows.Count > 0)
  {
  Array dados = ds.Tables[0].Rows[0].ItemArray;
  nroParcela = Convert.ToInt32(dados.GetValue(0));
  idApolice = Convert.ToInt32(dados.GetValue(1));
  dataVenParcela = Convert.ToDateTime(dados.GetValue(2));
  valParcela = float.Parse(dados.GetValue(3).ToString());
  quitadaParcela = Convert.ToBoolean(dados.GetValue(4));
  quitadaData = Convert.ToDateTime(dados.GetValue(5));
  }
  }
  }
}

Camada de Apresentação

5) Uma vez montadas as classes, vamos alternar para a camada de apresentação e acrescentar dois novos formulários tipo Winforms, chamados respectivamente: FrmApolices.cs e FrmParcelas.cs. Veja a Figura 33 - Novos Formulários.

Novos Formulários
Figura 33- Novos Formulários

6) O primeiro formulário FrmApolices.cs deve possuir sua aparência conforme mostra a Figura 34 - Manutenção de Apólices.

Manutenção de Apólices
Figura 34 - Manutenção de Apólices

Explicando o funcionamento do Formulário de Manutenção de Apólices

Nesta tela o usuário poderá incluir novas apólices, consultar apólices existentes, excluir e alterar dados das apólices. Funcionalidades estas, que já foram explicadas nos artigos anteriores. Apesar disso, como este formulário pode ser considerado como um dos principais da aplicação, iremos comentar o código na seqüência da execução das ações por parte do usuário do sistema.

Detalhando

Quando o formulário for carregado ficarão apenas habilitados os botões Procurar, Parcelas, Sair e Ver Sinistro. Então modifique as propriedades enabled dos outros botões para false.

Quando o usuário digitar o Código da Apólice no Sistema, no momento em que o campo perder o foco, será executado uma busca no sistema que trará os dados de apólice cadastrado ou apresentará a indicação que indica um número automático para a nova apólice.

1) Abaixo o código que representa esse procedimento, txtidApolice_Leave(...):

  private void txtidApolice_Leave(object sender, EventArgs e)
  {
  int vidApolice=0;
  if (txtidApolice.Text.Trim() != "")
  {
  vidApolice = int.Parse(txtidApolice.Text);
  }
  clnApolices apolice = new clnApolices();
  apolice.IdApolice = vidApolice;
  apolice.Buscar();
  if (apolice.IdCli == 0)
  {
  //preparando para inclusao
  LimparTxt(groupBox1);
  txtidApolice.Text = "";
  txtidApolice.Enabled = false;
  btnIncluir.Enabled = true;
  btnCancelar.Enabled = true;
  }
  else
  {
  //preparando para alteracao
  LimparTxt(groupBox1);
  txtidApolice.Enabled = false;
  txtidApolice.Text = Convert.ToString(apolice.IdApolice);
  txtidCli.Text = Convert.ToString(apolice.IdCli);
  txtkmVeiApolice.Text = Convert.ToString(apolice.KmVeiApolice);
  txtnumApolice.Text = Convert.ToString(apolice.NumApolice);
  txtdataApolice.Text = apolice.DataApolice.ToShortDateString();
  txtdataValApolice.Text = apolice.DataValApolice.ToShortDateString();
  txtvalorApolice.Text = Convert.ToString(apolice.ValorApolice);
  txtidModelo.Text = Convert.ToString(apolice.IdModelo);
  if (apolice.SinistroApolice == true)
  optSim.Checked = true;
  else
  optNao.Checked = true;
  txtidSinistro.Text = Convert.ToString(apolice.IdSinistro);

  btnAtualizar.Enabled = true;
  btnCancelar.Enabled = true;
  btnExcluir.Enabled = true;
  }
  }

O próximo código que é explicado agora, trata da busca do dado: nome na tabela: clientes, assim que for digitado um código para este. Quando ocorre uma mudança (TextChanged) na caixa de texto txtidCli é instanciado um objeto cliente e feito a procura do nome, retornando-o para o label lblnomeCli ou deixando este vazio.

2) Código do evento TextChanged do txtidCli abaixo:

 private void txtidCli_TextChanged(object sender, EventArgs e)
  {
  clnClientes cliente = new clnClientes();
  if (txtidCli.Text.Trim() == "")
  { 
  lblnomeCli.Text = "";
  return;
  } 
  cliente.IdCli = int.Parse(txtidCli.Text);
  cliente.Buscar();
  if (cliente.NomeCli != null)
  lblnomeCli.Text = cliente.NomeCli;
  else
  lblnomeCli.Text = "";
  }

Da mesma forma ocorre quando a caixa de texto txtidModelo é alterada.

3) Abaixo código TextChanged da caixa de texto txtidModelo.

private void txtidModelo_TextChanged(object sender, EventArgs e)
  {
  clnModelos modelo = new clnModelos();
  if (txtidModelo.Text.Trim() == "")
  {
  lbldescModelo.Text = "";
  return;
  }
  modelo.IdModelo = int.Parse(txtidModelo.Text);
  modelo.Buscar();
  if (modelo.DescModelo != null)
  lbldescModelo.Text = modelo.DescModelo;
  else
  lbldescModelo.Text = "";
  }

Você deve ter percebido os botões com este texto “[...]”. Estes botões tem como finalidade chamar o formulário de pesquisa genérico que criamos (artigos anteriores) passando o nome da tabela na propriedade tag, que já foi também explicado.

4) Abaixo código do evento Click no botão btnBuscaCli.

private void btnBuscaCli_Click(object sender, EventArgs e)
  {
  FrmPesquisa f = new FrmPesquisa();
  f.Text = "Consulta dados dos clientes";
  f.Tag = "tbCliente"; //nome da tabela (macete) :)
  f.ShowDialog();
  }

5) Abaixo código do evento Click no botão btnBuscaMod.

private void btnBuscaMod_Click(object sender, EventArgs e)
  {
  FrmPesquisa f = new FrmPesquisa();
  f.Text = "Consulta dados de Modelos Cadastrados";
  f.Tag = "tbModelo"; //nome da tabela (macete) :)
  f.ShowDialog();
  }

6) Abaixo código do botão btnIncluir. Evento click.

 private void btnIncluir_Click(object sender, EventArgs e)
  {
  try
  {
  clnApolices apolice = new clnApolices();
  //Dispara o método para buscar o idApolice
  apolice.IdApolice = apolice.BuscarId();
  apolice.IdCli = int.Parse(txtidCli.Text);
  apolice.KmVeiApolice = int.Parse(txtkmVeiApolice.Text);
  apolice.NumApolice = txtnumApolice.Text;
  apolice.DataApolice =Convert.ToDateTime(txtdataApolice.Text);
  apolice.DataValApolice = Convert.ToDateTime(txtdataValApolice.Text);
  apolice.ValorApolice = float.Parse(txtvalorApolice.Text);
  apolice.IdModelo = int.Parse(txtidModelo.Text);
  if (optSim.Checked == true)
  apolice.SinistroApolice = true;
  if (optNao.Checked == true)
  apolice.SinistroApolice = false;
  if (txtidSinistro.Text.Trim()!="") apolice.IdSinistro = int.Parse(txtidSinistro.Text);
  apolice.Gravar();
  string mensagem = "Registro Apólice: " +
  apolice.IdApolice + "\nNome: " + lblnomeCli.Text +
  "\nGravado com sucesso";
  MessageBox.Show(mensagem, "Sucesso",
  MessageBoxButtons.OK,
  MessageBoxIcon.Information);
  LimparTxt(groupBox1);
  btnIncluir.Enabled = false;
  btnCancelar.Enabled = false;
  txtidApolice.Enabled = true;
  txtidApolice.Focus();
  }
  catch (Exception ex)
  {
  MessageBox.Show("Aconteu o erro: " + ex.Message, "Erro");
  }

  }

7) Abaixo código do botão btnAtualizar. Evento click.

private void btnAtualizar_Click(object sender, EventArgs e)
  {
  try
  {
  clnApolices apolice = new clnApolices();
  apolice.IdApolice = int.Parse(txtidApolice.Text);
  apolice.IdCli = int.Parse(txtidCli.Text);
  apolice.KmVeiApolice = int.Parse(txtkmVeiApolice.Text);
  apolice.NumApolice = txtnumApolice.Text;
  apolice.DataApolice = DateTime.Parse(txtdataApolice.Text);
  apolice.DataValApolice = DateTime.Parse(txtdataValApolice.Text);
  apolice.ValorApolice = float.Parse(txtvalorApolice.Text);
  apolice.IdModelo = int.Parse(txtidModelo.Text);
  if (optSim.Checked == true)
  apolice.SinistroApolice = true;
  else
  apolice.SinistroApolice = false;
  if (txtidSinistro.Text.Trim() != "")
  apolice.IdSinistro = int.Parse(txtidSinistro.Text);
  apolice.Atualizar();
  string mensagem = "Registro Apólice: " +
  apolice.IdApolice + "\nApolice: " +
  apolice.NumApolice + "\nNome: " +
  lblnomeCli.Text +
  "\nAlterada com sucesso";
  MessageBox.Show(mensagem, "Sucesso",
  MessageBoxButtons.OK,
  MessageBoxIcon.Information);
  LimparTxt(groupBox1);
  btnAtualizar.Enabled = false;
  btnCancelar.Enabled = false;
  btnExcluir.Enabled = false;
  txtidApolice.Enabled = true;
  txtidApolice.Focus();
  }
  catch (Exception ex)
  {
  MessageBox.Show("Aconteu o erro: " + ex.Message, "Erro");
  }
  }

8) Abaixo código do botão btnExcluir. Evento click.

private void btnExcluir_Click(object sender, EventArgs e)
  {
  string pergunta;
  pergunta = "Deseja excluir a apolice de: \n" +
  lblnomeCli.Text + " N Registro: " + txtidApolice.Text +
  " ?";
  int ret = Convert.ToInt16(MessageBox.Show(pergunta, "Atenção",
  MessageBoxButtons.YesNo,
  MessageBoxIcon.Question));
  if (ret == 6)
  {
  clnApolices apolice = new clnApolices();
  apolice.IdApolice = int.Parse(txtidApolice.Text);
  apolice.Excluir();
  string mensagem = "Registro Apólice de: " +
  lblnomeCli.Text + "\nN registro: " + apolice.IdApolice +
  "\nExcluído com sucesso";
  MessageBox.Show(mensagem, "Sucesso",
  MessageBoxButtons.OK,
  MessageBoxIcon.Information);
  LimparTxt(groupBox1);
  btnAtualizar.Enabled = false;
  btnCancelar.Enabled = false;
  btnExcluir.Enabled = false;
  txtidApolice.Enabled = true;
  txtidApolice.Focus();
  }
  else
  {
  MessageBox.Show("Operação Cancelada",
  "Cancelada", MessageBoxButtons.OK,
  MessageBoxIcon.Information);
  }

  }

9) Abaixo código do botão btnCancelar. Evento click.

private void btnCancelar_Click(object sender, EventArgs e)
  {
  LimparTxt(groupBox1);
  btnIncluir.Enabled = false;
  btnAtualizar.Enabled = false;
  btnCancelar.Enabled = false;
  btnExcluir.Enabled = false;
  txtidApolice.Enabled = true;
  txtidApolice.Focus();
  }

10) Abaixo código do botão btnSair. Evento click.

private void btnSair_Click(object sender, EventArgs e)
  {
  this.Close();
  }

11) Abaixo código do botão btnProcurar. Evento click.

private void btnProcurar_Click(object sender, EventArgs e)
  {
  FrmPesquisa f = new FrmPesquisa();
  f.Text = "Consulta dados de Apolices";
  f.Tag = "tbApolice"; //nome da tabela (macete) :)
  f.ShowDialog();
  }

Já o evento do botão btnParcelas, merece alguns comentários. Primeiramente é instanciado uma variável objeto que chamamos de parcela, a qual recebe o número da apólice digitada pelo usuário na caixa de texto txtidApolice. É instanciado um novo formulário e passado alguns valores para objetos pertencentes ao formulário, que ainda criaremos, que é o FrmParcelas.cs. Importante: você só terá acesso aos objetos do formulário instanciados se o modificador de acesso estiver como público, ou seja, a propriedade Modifiers de cada objeto deve estar como Public no formulário FrmParcelas.

12) Abaixo código do evento click desse botão.

 private void btnParcelas_Click(object sender, EventArgs e)
  {
  clnApolices apolice = new clnApolices();
  if (txtidApolice.Text == "")
  {
  MessageBox.Show("Selecione uma Apólice");
  return;
  }
  apolice.IdApolice = int.Parse(txtidApolice.Text);
  apolice.Buscar();
  FrmParcelas f = new FrmParcelas();
  f.txtdataApolice.Text = apolice.DataApolice.ToShortDateString();
  f.txtidApolice.Text = Convert.ToString(apolice.IdApolice);
  f.txtnomeCli.Text = Convert.ToString(lblnomeCli.Text);
  f.ShowDialog();
  }

Bom, terminamos o formulário FrmApolices.cs. Antes de continuarmos, vou deixar o código completo aqui para facilitar, caso você queira copiá-lo todo. Lembre-se depois de instanciar os eventos, caso contrário dá erro.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Seguros_OO.Camada_Intermediaria.Logica_Negocios;

namespace Seguros_OO.Camada_Apresentacao
{
  public partial class FrmApolices : Form
  {
  public FrmApolices()
  {
  InitializeComponent();
  }

  //Método público para limpar caixas de texto
  public void LimparTxt(Control controles)
  {
  foreach (Control ctl in controles.Controls)
  {
  if (ctl is TextBox) ctl.Text = "";
  }
  }


  private void txtidApolice_Leave(object sender, EventArgs e)
  {
  int vidApolice=0;
  if (txtidApolice.Text.Trim() != "")
  {
  vidApolice = int.Parse(txtidApolice.Text);
  }
  clnApolices apolice = new clnApolices();
  apolice.IdApolice = vidApolice;
  apolice.Buscar();
  if (apolice.IdCli == 0)
  {
  //preparando para inclusao
  LimparTxt(groupBox1);
  txtidApolice.Text = "";
  txtidApolice.Enabled = false;
  btnIncluir.Enabled = true;
  btnCancelar.Enabled = true;
  }
  else
  {
  //preparando para alteracao
  LimparTxt(groupBox1);
  txtidApolice.Enabled = false;
  txtidApolice.Text = Convert.ToString(apolice.IdApolice);
  txtidCli.Text = Convert.ToString(apolice.IdCli);
  txtkmVeiApolice.Text = Convert.ToString(apolice.KmVeiApolice);
  txtnumApolice.Text = Convert.ToString(apolice.NumApolice);
  txtdataApolice.Text = apolice.DataApolice.ToShortDateString();
  txtdataValApolice.Text = apolice.DataValApolice.ToShortDateString();
  txtvalorApolice.Text = Convert.ToString(apolice.ValorApolice);
  txtidModelo.Text = Convert.ToString(apolice.IdModelo);
  if (apolice.SinistroApolice == true)
  optSim.Checked = true;
  else
  optNao.Checked = true;
  txtidSinistro.Text = Convert.ToString(apolice.IdSinistro);

  btnAtualizar.Enabled = true;
  btnCancelar.Enabled = true;
  btnExcluir.Enabled = true;
  }
  }

  private void btnIncluir_Click(object sender, EventArgs e)
  {
  try
  {
  clnApolices apolice = new clnApolices();
  //Dispara o método para buscar o idApolice
  apolice.IdApolice = apolice.BuscarId();
  apolice.IdCli = int.Parse(txtidCli.Text);
  apolice.KmVeiApolice = int.Parse(txtkmVeiApolice.Text);
  apolice.NumApolice = txtnumApolice.Text;
  apolice.DataApolice =Convert.ToDateTime(txtdataApolice.Text);
  apolice.DataValApolice = Convert.ToDateTime(txtdataValApolice.Text);
  apolice.ValorApolice = float.Parse(txtvalorApolice.Text);
  apolice.IdModelo = int.Parse(txtidModelo.Text);
  if (optSim.Checked == true)
  apolice.SinistroApolice = true;
  if (optNao.Checked == true)
  apolice.SinistroApolice = false;
  if (txtidSinistro.Text.Trim()!="") apolice.IdSinistro = int.Parse(txtidSinistro.Text);
  apolice.Gravar();
  string mensagem = "Registro Apólice: " +
  apolice.IdApolice + "\nNome: " + lblnomeCli.Text +
  "\nGravado com sucesso";
  MessageBox.Show(mensagem, "Sucesso",
  MessageBoxButtons.OK,
  MessageBoxIcon.Information);
  LimparTxt(groupBox1);
  btnIncluir.Enabled = false;
  btnCancelar.Enabled = false;
  txtidApolice.Enabled = true;
  txtidApolice.Focus();
  }
  catch (Exception ex)
  {
  MessageBox.Show("Aconteu o erro: " + ex.Message, "Erro");
  }

  }

  private void btnAtualizar_Click(object sender, EventArgs e)
  {
  try
  {
  clnApolices apolice = new clnApolices();
  apolice.IdApolice = int.Parse(txtidApolice.Text);
  apolice.IdCli = int.Parse(txtidCli.Text);
  apolice.KmVeiApolice = int.Parse(txtkmVeiApolice.Text);
  apolice.NumApolice = txtnumApolice.Text;
  apolice.DataApolice = DateTime.Parse(txtdataApolice.Text);
  apolice.DataValApolice = DateTime.Parse(txtdataValApolice.Text);
  apolice.ValorApolice = float.Parse(txtvalorApolice.Text);
  apolice.IdModelo = int.Parse(txtidModelo.Text);
  if (optSim.Checked == true)
  apolice.SinistroApolice = true;
  else
  apolice.SinistroApolice = false;
  if (txtidSinistro.Text.Trim() != "")
  apolice.IdSinistro = int.Parse(txtidSinistro.Text);
  apolice.Atualizar();
  string mensagem = "Registro Apólice: " +
  apolice.IdApolice + "\nApolice: " +
  apolice.NumApolice + "\nNome: " +
  lblnomeCli.Text +
  "\nAlterada com sucesso";
  MessageBox.Show(mensagem, "Sucesso",
  MessageBoxButtons.OK,
  MessageBoxIcon.Information);
  LimparTxt(groupBox1);
  btnAtualizar.Enabled = false;
  btnCancelar.Enabled = false;
  btnExcluir.Enabled = false;
  txtidApolice.Enabled = true;
  txtidApolice.Focus();
  }
  catch (Exception ex)
  {
  MessageBox.Show("Aconteu o erro: " + ex.Message, "Erro");
  }


  }

  private void btnExcluir_Click(object sender, EventArgs e)
  {
  string pergunta;
  pergunta = "Deseja excluir a apolice de: \n" +
  lblnomeCli.Text + " N Registro: " + txtidApolice.Text +
  " ?";
  int ret = Convert.ToInt16(MessageBox.Show(pergunta, "Atenção",
  MessageBoxButtons.YesNo,
  MessageBoxIcon.Question));
  if (ret == 6)
  {
  clnApolices apolice = new clnApolices();
  apolice.IdApolice = int.Parse(txtidApolice.Text);
  apolice.Excluir();
  string mensagem = "Registro Apólice de: " +
  lblnomeCli.Text + "\nN registro: " + apolice.IdApolice +
  "\nExcluído com sucesso";
  MessageBox.Show(mensagem, "Sucesso",
  MessageBoxButtons.OK,
  MessageBoxIcon.Information);
  LimparTxt(groupBox1);
  btnAtualizar.Enabled = false;
  btnCancelar.Enabled = false;
  btnExcluir.Enabled = false;
  txtidApolice.Enabled = true;
  txtidApolice.Focus();
  }
  else
  {
  MessageBox.Show("Operação Cancelada",
  "Cancelada", MessageBoxButtons.OK,
  MessageBoxIcon.Information);
  }

  }

  private void btnCancelar_Click(object sender, EventArgs e)
  {
  LimparTxt(groupBox1);
  btnIncluir.Enabled = false;
  btnAtualizar.Enabled = false;
  btnCancelar.Enabled = false;
  btnExcluir.Enabled = false;
  txtidApolice.Enabled = true;
  txtidApolice.Focus();

  }

  private void btnSair_Click(object sender, EventArgs e)
  {
  this.Close();
  }

  private void btnProcurar_Click(object sender, EventArgs e)
  {
  FrmPesquisa f = new FrmPesquisa();
  f.Text = "Consulta dados de Apolices";
  f.Tag = "tbApolice"; //nome da tabela (macete) :)
  f.ShowDialog();
  }

  private void txtidCli_TextChanged(object sender, EventArgs e)
  {
  clnClientes cliente = new clnClientes();
  if (txtidCli.Text.Trim() == "")
  { 
  lblnomeCli.Text = "";
  return;
  } 
  cliente.IdCli = int.Parse(txtidCli.Text);
  cliente.Buscar();
  if (cliente.NomeCli != null)
  lblnomeCli.Text = cliente.NomeCli;
  else
  lblnomeCli.Text = "";
  }

  private void btnBuscaCli_Click(object sender, EventArgs e)
  {
  FrmPesquisa f = new FrmPesquisa();
  f.Text = "Consulta dados dos clientes";
  f.Tag = "tbCliente"; //nome da tabela (macete) :)
  f.ShowDialog();
  }

  private void btnBuscaMod_Click(object sender, EventArgs e)
  {
  FrmPesquisa f = new FrmPesquisa();
  f.Text = "Consulta dados de Modelos Cadastrados";
  f.Tag = "tbModelo"; //nome da tabela (macete) :)
  f.ShowDialog();
  }

  private void txtidModelo_TextChanged(object sender, EventArgs e)
  {
  clnModelos modelo = new clnModelos();
  if (txtidModelo.Text.Trim() == "")
  {
  lbldescModelo.Text = "";
  return;
  }
  modelo.IdModelo = int.Parse(txtidModelo.Text);
  modelo.Buscar();
  if (modelo.DescModelo != null)
  lbldescModelo.Text = modelo.DescModelo;
  else
  lbldescModelo.Text = "";
  }

  private void btnParcelas_Click(object sender, EventArgs e)
  {
  clnApolices apolice = new clnApolices();
  if (txtidApolice.Text == "")
  {
  MessageBox.Show("Selecione uma Apólice");
  return;
  }
  apolice.IdApolice = int.Parse(txtidApolice.Text);
  apolice.Buscar();
  FrmParcelas f = new FrmParcelas();
  f.txtdataApolice.Text = apolice.DataApolice.ToShortDateString();
  f.txtidApolice.Text = Convert.ToString(apolice.IdApolice);
  f.txtnomeCli.Text = Convert.ToString(lblnomeCli.Text);
  f.ShowDialog();
  }
  }
}

Explicando o funcionamento do Formulário de Manutenção de Parcelas.

1) O formulário FrmParcelas.cs deve possuir a aparência conforme mostra a Figura 35 - Manutenção de Parcelas.

Manutenção de Parcelas
Figura 35 - Manutenção de Parcelas

2) Altere as propriedades enabled dos controles txtparcquit, dtDataQuit e btnOk, para false, ou seja, esses controles estarão desabilitados, a não ser que trate-se de uma quitação de parcelas. Fato que ocorrerá quando o usuário clicar no botão btnQuitar.

O formulário será carregado quando o usuário clicar no botão Parcelas do formulário FrmApolices.cs. Ao ser carregado, ele recebe os valores passados através do outro form, como também vimos anteriormente. Estes valores recebidos, são tratados logo no evento Load do formulário.

3) Abaixo o código do evento Load do FrmParcelas.cs.

private void FrmParcelas_Load(object sender, EventArgs e)
  {
  clnParcelas parcela = new clnParcelas();
  parcela.IdApolice = int.Parse(txtidApolice.Text);
  this.dgParcelas.DataSource = parcela.Buscar().Tables[0];
  int cont = this.dgParcelas.Rows.Count;
  if (cont == 0)
  {
  btnGerar.Enabled = true;
  btnQuitar.Enabled = false;
  }
  else
  {
  btnGerar.Enabled = false;
  btnQuitar.Enabled = true;
  txtnumGerar.Enabled = false;
  txtValorParcela.Enabled = false;
  txtVcto.Enabled = false;
  }

O Bloco if acima (cont==0), será executado quando não houver parcelas ainda cadastradas para a apólice recuperada. Tratamos os botões gerar e quitar respectivamente para ambos os casos, ou seja, se não houver parcelas cadastradas o botão gerar será habilitado e o quitar desabilitado, caso contrário, ocorre o oposto.

4) Evento click do botão btnGerar.

 private void btnGerar_Click(object sender, EventArgs e)
  {
  clnParcelas parcela = new clnParcelas();
  int numParcGerar = int.Parse(txtnumGerar.Text);
  if ((numParcGerar <= 0) || (numParcGerar > 12))
  {
  MessageBox.Show("Número de parcelas entre 1 e 12");
  return;
  }
  if(float.Parse(txtValorParcela.Text.Replace(",",".")) <= 0)
  {
  MessageBox.Show("Valor de Parcela Inválido");
  return;
  }
  try
  {
  DateTime data = Convert.ToDateTime(txtVcto.Text);
  string Mensagem;
  Mensagem = "Serão geradas " + txtnumGerar.Text +
  " parcelas, com a primeira data de vencimento " +
  "em " + data.ToShortDateString();
  MessageBox.Show(Mensagem);
  //gerando parcelas.
  int i = 0;
  for (i = 0; i < numParcGerar; i++)
  {
  parcela.NroParcela = i + 1;
  parcela.IdApolice = int.Parse(txtidApolice.Text);
  parcela.DataVenParcela = data;
  data = data.AddDays(30);
  parcela.ValParcela = float.Parse(txtValorParcela.Text);
  parcela.Gravar();
  }
  this.dgParcelas.DataSource = parcela.Buscar().Tables[0];
  }

  catch (Exception ex)
  {
  MessageBox.Show("Ocorreu o erro: " + ex.Message);
  }
  }

Alguns comentários sobre esse evento. Inicialmente instanciamos a parcela. Verificamos se o número de parcelas está dentro da faixa possível entre 1 e o número de parcelas que existir. E também verificamos se já não está quitada. Se as condições para gerar as parcelas forem atendidas, o bloco for é responsável pela inserção de novas parcelas na tbParcela. E mais abaixo a propriedade DataSource do dgParcelas é atualizada com as parcelas geradas sendo assim exibidas no grid.

5) Agora vamos ao código que responderá ao evento click no botão btnQuitar.

 private void btnQuitar_Click(object sender, EventArgs e)
  {
  this.txtparcquit.Enabled = true;
  this.dtDataQuit.Enabled = true;
  this.dtDataQuit.Value= DateTime.Now;
  btnOk.Enabled = true;
  this.txtparcquit.Focus();
  this.btnQuitar.Enabled = false;
  }

Esse código é simples, apenas habilita os controles acima do grid para a digitação do número da parcela a quitar e a data respectiva da quitação.

6) Agora o código que executa o lançamento de quitação de parcelas manualmente pelo usuário. Evento click do botão btnOk.

private void btnOk_Click(object sender, EventArgs e)
  {
  try
  {
  int vnumParc = int.Parse(txtparcquit.Text);
  if (vnumParc > dgParcelas.Rows.Count || vnumParc<=0)
  {
  MessageBox.Show("Parcela Inválida");
  return;
  }
  clnParcelas parcela = new clnParcelas();
  parcela.IdApolice = int.Parse(txtidApolice.Text);
  parcela.NroParcela = vnumParc;
  parcela.BuscarParcEspec();
  if (parcela.QuitadaParcela == true)
  {
  MessageBox.Show("Parcela já quitada");
  return;
  }
  parcela.QuitadaParcela = true;
  parcela.QuitadaData = dtDataQuit.Value;
  parcela.Atualizar();
  //atualiza o grid
  this.dgParcelas.DataSource = parcela.Buscar().Tables[0];
  this.txtparcquit.Enabled = false;
  this.dtDataQuit.Enabled = false;
  btnOk.Enabled = false;
  this.btnQuitar.Enabled = true;
  MessageBox.Show("Quitação Registrada");
  }
  catch (Exception ex)
  {
  MessageBox.Show("Ocorreu o erro: " + ex.Message);
  }
  }

Abaixo todo o código desse formulário:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Seguros_OO.Camada_Intermediaria.Logica_Negocios;


namespace Seguros_OO.Camada_Apresentacao
{
  public partial class FrmParcelas : Form
  {
  public FrmParcelas()
  {
  InitializeComponent();
  }
  private void btnGerar_Click(object sender, EventArgs e)
  {
  clnParcelas parcela = new clnParcelas();
  int numParcGerar = int.Parse(txtnumGerar.Text);
  if ((numParcGerar <= 0) || (numParcGerar > 12))
  {
  MessageBox.Show("Número de parcelas entre 1 e 12");
  return;
  }
  if(float.Parse(txtValorParcela.Text.Replace(",",".")) <= 0)
  {
  MessageBox.Show("Valor de Parcela Inválido");
  return;
  }
  try
  {
  DateTime data = Convert.ToDateTime(txtVcto.Text);
  string Mensagem;
  Mensagem = "Serão geradas " + txtnumGerar.Text +
  " parcelas, com a primeira data de vencimento " +
  "em " + data.ToShortDateString();
  MessageBox.Show(Mensagem);
  //gerando parcelas.
  int i = 0;
  for (i = 0; i < numParcGerar; i++)
  {
  parcela.NroParcela = i + 1;
  parcela.IdApolice = int.Parse(txtidApolice.Text);
  parcela.DataVenParcela = data;
  data = data.AddDays(30);
  parcela.ValParcela = float.Parse(txtValorParcela.Text);
  parcela.Gravar();
  }
  this.dgParcelas.DataSource = parcela.Buscar().Tables[0];
  }

  catch (Exception ex)
  {
  MessageBox.Show("Ocorreu o erro: " + ex.Message);
  }
  }

  private void FrmParcelas_Load(object sender, EventArgs e)
  {
  clnParcelas parcela = new clnParcelas();
  parcela.IdApolice = int.Parse(txtidApolice.Text);
  this.dgParcelas.DataSource = parcela.Buscar().Tables[0];
  int cont = this.dgParcelas.Rows.Count;
  if (cont == 0)
  {
  btnGerar.Enabled = true;
  btnQuitar.Enabled = false;
  }
  else
  {
  btnGerar.Enabled = false;
  btnQuitar.Enabled = true;
  txtnumGerar.Enabled = false;
  txtValorParcela.Enabled = false;
  txtVcto.Enabled = false;
  }

  
  }
  private void btnQuitar_Click(object sender, EventArgs e)
  {
  this.txtparcquit.Enabled = true;
  this.dtDataQuit.Enabled = true;
  this.dtDataQuit.Value= DateTime.Now;
  btnOk.Enabled = true;
  this.txtparcquit.Focus();
  this.btnQuitar.Enabled = false;
  }
  private void btnOk_Click(object sender, EventArgs e)
  {
  try
  {
  int vnumParc = int.Parse(txtparcquit.Text);
  if (vnumParc > dgParcelas.Rows.Count || vnumParc<=0)
  {
  MessageBox.Show("Parcela Inválida");
  return;
  }
  clnParcelas parcela = new clnParcelas();
  parcela.IdApolice = int.Parse(txtidApolice.Text);
  parcela.NroParcela = vnumParc;
  parcela.BuscarParcEspec();
  if (parcela.QuitadaParcela == true)
  {
  MessageBox.Show("Parcela já quitada");
  return;
  }
  parcela.QuitadaParcela = true;
  parcela.QuitadaData = dtDataQuit.Value;
  parcela.Atualizar();
  //atualiza o grid
  this.dgParcelas.DataSource = parcela.Buscar().Tables[0];
  this.txtparcquit.Enabled = false;
  this.dtDataQuit.Enabled = false;
  btnOk.Enabled = false;
  this.btnQuitar.Enabled = true;
  MessageBox.Show("Quitação Registrada");
  }
  catch (Exception ex)
  {
  MessageBox.Show("Ocorreu o erro: " + ex.Message);
  }
  }
  }
}

Com isso criamos as classes que representam a lógica de negócios e a respectiva camada de apresentação para as informações sobre a apólice e parcelas, nesta mesma ordem, ou seja, foram adicionadas as novas classes: clnApolices.cs e clnParcelas e criados dois novos formulários o FrmApolices.cs e o FrmParcelas.cs

Vamos relembrar o Diagrama ER Numerado (Figura 36) .

Diagrama ER Numerado
Figura 36- Diagrama ER Numerado

A tabela de apólices é sem dúvida a mais importante do Sistema e para que possa ser feito o cadastro de uma nova apólice inicialmente temos que possuir dados nas tabelas de clientes (tbCliente), não está numerada pois nos artigos anteriores implementamos sua funcionalidade. Precisamos ter os dados já cadastrados na tabela de modelo de carros (tbModelo) [6] e a partir da apólice gerar as parcelas [5] para o pagamento por parte do cliente.

Já em relação aos sinistros ocorridos [2] para que possa ser cadastrado, inicialmente temos que ter a apólice cadastrada [1] e termos também previamente cadastrados os tipos de danos [3] e os tipos de sinistros já cadastrados.

Agora vamos criar a classe que representa a lógica de negócio e a respectiva camada de apresentação para as informações sobre sinistros, ou seja, será adicionada a classe: clnSinistros.

Também adicionaremos um formulário de splash e um formulário principal na camada de apresentação.

1) Com o aplicativo aberto adicione uma nova classe chamada clnSinistros.cs, como mostra a Figura 37.

clnSinistros.cs
Figura 37- clnSinistros.cs

2) Abaixo código da classe clnSinistro.cs, se você tem acompanhado os artigos, não há funcionalidades difirentes das já implementadas.

using System;
using System.Collections.Generic;
using System.Text;
using System.Data;

namespace Seguros_OO.Camada_Intermediaria.Logica_Negocios
{
    public class clnSinistros
    {
        //1 - Campos privados a classe
        private int idSinistro;
        private DateTime dataSinistro;
        private int idTipo;
        private int idDano;
        private string descSinistro;

        //2 - propriedades, acesso aos campos privados
        public int IdSinistro
        {
            get { return idSinistro; }
            set { idSinistro = value; }
        }
        public DateTime DataSinistro
        {
            get { return dataSinistro; }
            set { dataSinistro = value; }
        }
        public int IdTipo
        {
            get { return idTipo; }
            set { idTipo = value; }
        }
        public int IdDano
        {
            get { return idDano; }
            set { idDano = value; }
        }
        public string DescSinistro
        {
            get { return descSinistro; }
            set { descSinistro = value; }
        }
        //3 - métodos da classe de Negócios (clnSinistro.cs)

  
              //3.1 Buscar dados cujo codigo foi especificado
        public void Buscar()
        {
            string csql;
            csql = "Select * From tbSinistro where idSinistro=" + idSinistro;
            DataSet ds;
            clsDados seguros = new clsDados();
            ds = seguros.RetornarDataSet(csql);
            if (ds.Tables[0].Rows.Count > 0)
            {
                Array dados = ds.Tables[0].Rows[0].ItemArray;
                idSinistro = Convert.ToInt16(dados.GetValue(0));
                dataSinistro = Convert.ToDateTime(dados.GetValue(1));
                descSinistro = Convert.ToString(dados.GetValue(2));
                idTipo = Convert.ToInt16(dados.GetValue(3));
                idDano = Convert.ToInt16(dados.GetValue(4));
            }
        }

        //3.2 Buscar o próximo Id Numerico para 
        //inclusao de um novo sinistro.
        public int BuscarId()
        {
            string csql;
            csql = "Select Top 1 (idSinistro) From tbSinistro order by idSinistro desc";
            int IdBuscado;
            clsDados seguros = new clsDados();
            IdBuscado = seguros.RetornarIdNumerico(csql);
            return IdBuscado;
        }

        //3.3 Método para incluir um novo sinistro no 
        //Banco de dados
        public void Gravar()
        {
            string vdatasinistro = dataSinistro.ToString("MM/dd/yyyy");
            StringBuilder csql = new StringBuilder();
            csql.Append("Insert into tbSinistro");
            csql.Append("(");
            csql.Append("idSinistro,");
            csql.Append("dataSinistro,");
            csql.Append("descSinistro,");
            csql.Append("idTipo,");
            csql.Append("idDano");
            csql.Append(") Values(");
            csql.Append(idSinistro);
            csql.Append(",'" + vdatasinistro + "',");
            csql.Append("'" + descSinistro + "',");
            csql.Append(idTipo + ",");
            csql.Append(idDano + ")");
            clsDados seguros = new clsDados();
            seguros.ExecutarComando(csql.ToString());
        }

        //3.4 Método para atualizar (alterar um registro)
        public void Atualizar()
        {
            string vdatasinistro = dataSinistro.ToString("MM/dd/yyyy");
            StringBuilder csql = new StringBuilder();
            csql.Append("Update tbSinistro ");
            csql.Append("set idSinistro=");
            csql.Append(idSinistro);
            csql.Append(", dataSinistro='");
            csql.Append(vdatasinistro);
            csql.Append("', descSinistro='");
            csql.Append(descSinistro);
            csql.Append("', idTipo=");
            csql.Append(idTipo);
            csql.Append(", idDano=");
            csql.Append(idDano);
            csql.Append(" where idSinistro=");
            csql.Append(idSinistro);
            clsDados seguros = new clsDados();
            seguros.ExecutarComando(csql.ToString());
        }

        //3.5 Método para excluir um cliente do 
        //Banco de dados
        public void Excluir()
        {
            StringBuilder csql = new StringBuilder();
            csql.Append("Delete From tbSinistro ");
            csql.Append(" where idSinistro=");
            csql.Append(idSinistro);
            clsDados seguros = new clsDados();
            seguros.ExecutarComando(csql.ToString());
        }
    }
}

3 ) Agora, alterne para a camada de apresentação, inclua um novo formulário com o nome FrmSinistro.cs, como mostra a Figura 38.

FrmSinistros.cs
Figura 38 - FrmSinistros.cs

4) Acrescente os controles no formulário e altere as propriedades conforme Figura 39:

Formulários (FrmSinistros)
Figura 39 - Formulários (FrmSinistros)

5) Altere as propriedades de todos os botões para enabled = false.

6) Declare os namespace. Conforme abaixo:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Seguros_OO.Camada_Intermediaria.Logica_Negocios;

7) Inclua o método para limpar as caixas de textos.

 //Método público para limpar caixas de texto
        public void LimparTxt(Control controles)
        {
            foreach (Control ctl in controles.Controls)
            {
                if (ctl is TextBox) ctl.Text = "";
            }
        }

8) Acrescente um método publico sem retorno (void) chamado cancelar( ).

 private void cancelar()
        {
            groupBox2.Enabled = false;
            groupBox1.Enabled = true;
            txtidApolice.Text = "";
            txtidApolice.Enabled = true;
            txtidApolice.Focus();
            btnAtualizar.Enabled = false;
            btnIncluir.Enabled = false;
            btnExcluir.Enabled = false;
            btnCancelar.Enabled = false;
        }

9) Evento para o formulário Load, assim que o formulário for carregado, realizaremos duas tarefas. Instanciamos o objeto dadosDanos a partir da classe clnDanos( ) e o objeto dadosTipo a partir da classe clnTipos. Disparamos o método BuscarTodos( ) com a finalidade de “amarrar” os combos, ou seja, o usuário terá no campo visual o conteúdo do campo descDano e descTipo respectivamente, mas o valor di item são os dipostos na propriedade DisplayMember de cada uma. Abaixo código comentado.

 Private void FrmSinistros_Load(object sender, EventArgs e)
        {
            clnDanos dadosDanos = new clnDanos();
            clnTipos dadosTipo = new clnTipos();
            DataSet dsDanos = dadosDanos.BuscarTodos();
            DataSet dsTipos = dadosTipo.BuscarTodos();
            //amarrando os combos.
            //Exibindos descrições porém atrelamos o código
            //para gravação.
            cmbTipoDano.DataSource = dsDanos.Tables[0];
            cmbTipoDano.DisplayMember = “descDano”;
            cmbTipoDano.ValueMember= “idDano”;
            cmbTipoSinistro.DataSource = dsTipos.Tables[0];
            cmbTipoSinistro.DisplayMember = “descTipo”;
            cmbTipoSinistro.ValueMember = “idTipo”;
        }

10) Evento TexChanged do campo txtidApolice. Ao alterar o contéudo do campo, instanciamos o objeto apolice a partir da classe clnApolices( ) e o objeto cliente a partir da classe clnClientes. A finalidade do código é preencher os campos do tipo label.

 private void txtidApolice_TextChanged(object sender, EventArgs e)
        {
            clnApolices apolice = new clnApolices();
            if (txtidApolice.Text.Trim() == "")
            {
                lblnomeCli.Text = "";
                lbldescModelo.Text = "";
                return;
            }
            apolice.IdApolice = int.Parse(txtidApolice.Text);
            apolice.Buscar();
            clnClientes cliente = new clnClientes();
            cliente.IdCli = apolice.IdCli;
            cliente.Buscar();
            lblnomeCli.Text = cliente.NomeCli;
            clnModelos modelo = new clnModelos();
            modelo.IdModelo = apolice.IdModelo;
            modelo.Buscar();
            lbldescModelo.Text = modelo.DescModelo;
            if (lblnomeCli.Text == "")
                btnSinistro.Enabled = false;
            else
                btnSinistro.Enabled = true;
        }

11) Evento click do botão btnBuscar.

 private void btnBuscar_Click(object sender, EventArgs e)
        {
            FrmPesquisa f = new FrmPesquisa();
            f.Text = "Consulta dados das Apólices";
            f.Tag = "tbApolice"; //nome da tabela (macete)  :)
            f.ShowDialog();
        }

12) Evento click do botão btnSinistro.

 private void btnSinistro_Click(object sender, EventArgs e)
        {
            groupBox2.Enabled = true;
            clnApolices apolice = new clnApolices();
            apolice.IdApolice = int.Parse(txtidApolice.Text);
            apolice.Buscar();
            if (apolice.IdSinistro != 0)
            {
                MessageBox.Show("Cliente já possui apólice, \n" +
                    "Você só poderá alterar esses dados", "Aviso");
                clnSinistros sinistro = new clnSinistros();
                sinistro.IdSinistro = apolice.IdSinistro;
                sinistro.Buscar();
                txtidSinistro.Text = Convert.ToString(sinistro.IdSinistro);
                txtdataSinistro.Text = sinistro.DataSinistro.ToString("dd/MM/yyyy");
                txtdescSinistro.Text = sinistro.DescSinistro;
                clnDanos dano = new clnDanos();
                dano.IdDano = sinistro.IdDano;
                dano.Buscar();
                cmbTipoDano.Text = dano.DescDano;
                clnTipos tipo = new clnTipos();
                tipo.IdTipo = sinistro.IdTipo;
                tipo.Buscar();
                cmbTipoSinistro.Text = tipo.DescTipo;
                txtidSinistro.Enabled = false;
                txtdataSinistro.Focus();
                btnAtualizar.Enabled = true;
                btnIncluir.Enabled = false;
                btnExcluir.Enabled = true;
                btnCancelar.Enabled = true;
            }
            else
            { 
                txtidSinistro.Text = "";
                txtdataSinistro.Text = "";
                txtdescSinistro.Text = "";
                txtidSinistro.Enabled = false;
                txtdataSinistro.Focus();
                btnAtualizar.Enabled = false;
                btnIncluir.Enabled = true;
                btnExcluir.Enabled = false;
                btnCancelar.Enabled = true;
            }
            groupBox1.Enabled = false;
        }

No código acima, vamos por parte. A primeira coisa que fizemos foi habilitar o groupbox2, conteiner onde se encontram os controles do cadastro de sinistros. Em seguida instanciamos um objeto apolice a partir da classe clnApolices( ), com a finalidade de verificar se houve sinistro para a apólice em questão. Se o valor do campo idSinistro for diferente de zero, indica que o cliente já possui apólice, sendo assim informamos ao mesmo que essa apólice só pode ser alterada, na verdade ela pode ser excluída, mas isso, não nos cabe orientá-lo (usuário do sistema). Instanciamos o objeto dano e o objeto tipo para alimentar os campos combo com a descrição do sinistro localizado. O restante do código já está bastante explorado.

13) Evento click do botão incluir.

 private void btnIncluir_Click(object sender, EventArgs e)
        {
            try
            {
                clnSinistros sinistro = new clnSinistros();
                sinistro.IdSinistro = sinistro.BuscarId();
                sinistro.DataSinistro = Convert.ToDateTime(txtdataSinistro.Text);
                sinistro.DescSinistro = txtdescSinistro.Text;
                sinistro.IdTipo = Convert.ToInt16(cmbTipoSinistro.SelectedValue);
                sinistro.IdDano = Convert.ToInt16(cmbTipoDano.SelectedValue);
                sinistro.Gravar();
                //atualizar a tabela de apólice com o número do sinistro
                //e checar a apolice para sinistrada.
                clnApolices apolice = new clnApolices();
                apolice.IdApolice = int.Parse(txtidApolice.Text);
                apolice.Buscar();
                apolice.SinistroApolice = true;
                apolice.IdSinistro = sinistro.IdSinistro;
                apolice.Atualizar();
                //mostra mensagem
                string mensagem = "Sinistro: " +
                    sinistro.IdSinistro + "\nCliente: " + lblnomeCli.Text +
                    "\nGravado com sucesso";
                MessageBox.Show(mensagem, "Sucesso",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Information);
                //chamar metodo cancelar (apenas desabilita os botões)
                cancelar();
                LimparTxt(groupBox2);
            }
            catch (Exception ex)
            {
                MessageBox.Show("Aconteu o erro: " + ex.Message, "Erro");
            }
        }

No código acima, também atualizamos a tabela de apólices com as informações da ocorrência de sinistro. Mais tarde alteraremos o código do botão btnVer no formulário de apólices que abrirá o formulário de sinistro para que possa ser verificado os dados do sinistro.

14) Evento do botão Atualizar.

 private void btnAtualizar_Click(object sender, EventArgs e)
        {
            try
            {
                clnSinistros sinistro = new clnSinistros();
                sinistro.IdSinistro= int.Parse(txtidSinistro.Text);
                sinistro.DataSinistro = Convert.ToDateTime(txtdataSinistro.Text);
                sinistro.DescSinistro = txtdescSinistro.Text;
                sinistro.IdTipo = Convert.ToInt16(cmbTipoSinistro.SelectedValue);
                sinistro.IdDano = Convert.ToInt16(cmbTipoDano.SelectedValue);
                sinistro.Atualizar();
                string mensagem = "Registro Sinsitro: " +
                    sinistro.IdSinistro + "\nNome: " + lblnomeCli.Text +
                    "\nAlterado com sucesso";
                MessageBox.Show(mensagem, "Sucesso",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Information);
                LimparTxt(groupBox2);
                cancelar();
            }
            catch (Exception ex)
            {
                MessageBox.Show("Aconteu o erro: " + ex.Message, "Erro");
            }
}

15) Evento do botão excluir.

 private void btnExcluir_Click(object sender, EventArgs e)
        {
            string pergunta;
            pergunta = "Deseja excluir o Sinistro: " +
                txtidSinistro.Text + ", do cliente: " + lblnomeCli.Text +
                "\ndo Cadastro Atual. ?" +
                "\n\n\nLembre-se essa ação deverá ocorrer " +
                "\nsomente em caso de ESTORNO";
            int ret = Convert.ToInt16(MessageBox.Show(pergunta, "Atenção",
                MessageBoxButtons.YesNo,
                MessageBoxIcon.Question));
            if (ret == 6)
            {
                //primeiro devemos fazer a atualização na
                //tabela de apolice.
                clnApolices apolice = new clnApolices();
                apolice.IdApolice = int.Parse(txtidApolice.Text);
                apolice.Buscar();
                apolice.SinistroApolice = false;
                apolice.IdSinistro = 0;
                apolice.Atualizar();
                //agora excluir da tabela de sinistro
                clnSinistros sinistro = new clnSinistros();
                sinistro.IdSinistro = int.Parse(txtidSinistro.Text);
                sinistro.Excluir();
                string mensagem = "Registro Sinistro: " +
                    sinistro.IdSinistro + "\nNome: " + lblnomeCli.Text +
                    "\nExcluído com sucesso";
                MessageBox.Show(mensagem, "Sucesso",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Information);
                LimparTxt(groupBox2);
                cancelar();
            }
            else
            {
                MessageBox.Show("Operação Cancelada",
                    "Cancelada", MessageBoxButtons.OK,
                    MessageBoxIcon.Information);
            }
        }

No código do evento excluir também atualizamos a tabela de apólices alterando os campos sinistroApolice para falso, indicando que não houve sinistro. Esta função deverá ser realizada no caso de estorno. Não é nossa intenção implementar outras regras para exclusão de sinistros, mas em um caso real, com certeza teria que ser ampliada estes conjunto de regras.

16) Evento do botão cancelar.

 private void btnCancelar_Click(object sender, EventArgs e)
        {
            LimparTxt(groupBox2);
            cancelar();
        }

17) Evento do botão procurar.

 private void btnProcurar_Click(object sender, EventArgs e)
        {
            FrmPesquisa f = new FrmPesquisa();
            f.Text = "Consulta Sinistros";
            f.Tag = "tbSinistro"; //nome da tabela (macete)  :)
            f.ShowDialog();
        }

18) Evento do botão sair.

 private void btnSair_Click(object sender, EventArgs e)
        {
            this.Close();
        }

19) Altere a propriedade modifiers do controle txtidApolice para public.

20) Agora alterne para o formulário de Apólices (FrmApolices.cs) para que possamos codificar o botão btnVer. Abaixo o código para o evento click do botão.

 private void btnVer_Click(object sender, EventArgs e)
        {
            FrmSinistros f = new FrmSinistros();
            f.txtidApolice.Text = this.txtidApolice.Text;
            f.ShowDialog();
            txtidApolice_Leave(sender, e); //método deve ser public 
        }

Camada de Apresentação: Finalizando

A intenção aqui não é criar formulários cheios de detalhes, pelo contrário serão simples apenas para finalizar o nosso exemplo. Você poderá melhorá-los assim como todo o projeto.

FrmSplash

1) Adicione na Camada de Apresentação um novo Formulário do tipo splash chamado FrmSplash. Clique com o botão direito do mouse sobre o nome do projeto e escolha ADD >> New Item >> WindowsForm dê o nome FrmSplash.cs.

2) Altere as propriedades do formulário FrmSplash conforme abaixo:

  • FormBorderStyle = none;
  • Size = 553; 379

3) Coloque um controle picture e acrescente uma imagem de fundo com o tamanho acima, como mostra a Figura 40.

FrmSplash.cs
Figura 40 - FrmSplash.cs

4) Adicione agora os seguintes controles, conforme mostra a Figura 41:

  • 01 progressbar;
  • 01 timer.
Controles Adicionados
Figura 41 - Controles Adicionados

Aqui, depois adicionaremos o código.

5 ) Agora acrescente um novo formulário chamado FrmPrincipal. Esse formulário deverá conter um menu conforme a Figura 42.

FrmPrincipal.cs
Figura 42 - FrmPrincipal.cs

6) Altere a propriedade WindowState do formulário para Maximized.

Funcionamento

Colocaremos o nosso projeto para ser iniciado pelo formulário de splash, e em três segundo será disparado o formulário principal, para que possamos acessar os formulários anteriormente criados.

1) Para isso no Solution Explorer dê um duplo clique no arquivo Program.cs para acessar essa classe e faça a alteração conforme a Figura 43:

Arquivo Program.cs
Figura 43 -Arquivo Program.cs

2) Agora alterne para o formulário FrmSplash, defina a propriedade enabled do timer para true. Em seguida coloque o código abaixo para o evento.

private void timer1_Tick(object sender, EventArgs e)
        {
            if (progressBar1.Value >= 100)
            {
                timer1.Enabled = false;
                FrmPrincipal f = new FrmPrincipal();
                this.Hide();
                f.ShowDialog();
                this.Close();
            }
            else 
            {
                progressBar1.Value += 10;
            }
        }

3) Assim que a barra de progressão ter o seu valor maior ou igual a 100, o formulário é oculto (hide), disparamos o formulário principal, e quando este for fechado a aplicação será encerrada.

Para finalizar essa aplicação, basta acrescentar os códigos nos menus para chamar os formulários que criamos. Altere a propriedade IsMdiConteiner do FrmPrincipal para true, assim podemos acessar os formulários internos dentro do form principal. Veja a aparência até o momento na Figura 44.

Aparência final
Figura 44. Aparência final

Vou incluir a funcionalidade para chamar o cadastro de clientes. As demais, é só você seguir este exemplo:

private void clientesToolStripMenuItem_Click(object sender, EventArgs e)
        {
            FrmClientes f = new FrmClientes();
            //indicamos que a janela pai é o form atual
            f.MdiParent = this;
            //Carregamos o formuladio dentro do form pai.
            f.Show();
        }

Note que essa parte final, não tem uma “linda” aparência pois não era o intuito do artigo, mas você com certeza consegue melhorar a aplicação como um todo.

Referências Bibliográficas:

(Deitel et al, 2002) - DEITEL, H, M, DEITEL, P, J, LITSFIELD, J, A et all, “C#: How to program”, Prentice Hall, (2002). (Guedes, 2006) - GUEDES, GILLEANES T. A. – “UML - Uma Abordagem Prática”, Novatec, (2006). v\:* {behavior:url(#default#VML);} o\:* {behavior:url(#default#VML);} w\:* {behavior:url(#default#VML);} .shape {behavior:url(#default#VML);} st1\:*{behavior:url(#ieooui) }