Gravar dados Tabela X Tabela Chave Estrangeira

MySQL

Delphi

01/11/2017

Bom dia, inicialmente a ideia era gravar as parcelas em uma mesma tabela onde deveria ter os dados do produto e parcela, este é o proposto no curso, mais como achei que iria ficar uma bagunça e não concordei em ter uma parcela com os mesmos valores sempre, dando diferença se realiza-se o processo inverso de multiplicar o valor das parcelas pela quantidade de parcelas por menor que seja, acho um erro.
Ex:
1000 / 6 = 166,6666666666667

Se considera-se o arredondamento para mais por ser maior que 5 ou seja 6 parcelas de 166,67 total de 1000,02, fiz uma rotina onde ele pegaria os valores após a virgula e colocaria na primeira parcela 1º 170,00 + 5 parcelas de 166,00 total de 1000,00. Desta forma ficou melhor, só que estou colocando a mesma em uma DBGRiD onde ele me mostra o valor das parcelas e como ficaria.
Só que ainda não sou bom em programar e não estou conseguindo colocar a tabela de TBCONTAS_PAGAR onde tem os dados da venda e qtde de parcelas que descrevo abaixo, e a outra tabela TBCONTAS_PAGAR_PAGAMENTO:
As tabelas estão desta forma:
TBCONTAS_PAGAR        -                  TBCONTAS_PAGAR_PAGAMENTO
ID                                      -                  ID
NUMERO_DOC               -                   ID_CONTAS_PAGAR (CHAVE ESTRANGEIRA)
DESCRICAO                    -                  PARCELAS 
DATA_COMPRA               -                  DATA_VENCIMENTO
VLR_COMPRA                 -                  VLR_PARCELA
TIPO_VENCIMENTO       -                  DATA_PAGAMENTO
DIA_VENCIMENTO          -                  VLR_PAGAMENTO
QTDE_PARCELAS           -                 STATUS
VLR_ABATIDO -
DATA_CADASTRO -


Ele está gravando corretamente na primeira tabela, só que não estou conseguindo gravar os dados na segunda tabela, abaixo os dados do botão salvar:

procedure TfrmCadastro_Contas_a_Pagar.acSalvarExecute(Sender: TObject);
var I : Integer;
begin

  if Trim(lbledtNumero_Doc.Text) = '' then
    begin

      Application.MessageBox('Preencha o Campo Numero Documento!', 'Atenção...', MB_OK + MB_ICONWARNING);
      lbledtNumero_Doc.SetFocus;
      Abort;

    end;

  if Trim(lbledtDescricao.Text) = '' then
    begin

      Application.MessageBox('Preencha o Campo Descrição!', 'Atenção...', MB_OK + MB_ICONWARNING);
      lbledtDescricao.SetFocus;
      Abort;

    end;

  if Trim(edtqtde_parcelas.Text) = '' then
    begin

      Application.MessageBox('Preencha o Campo Qtde Parcelas!', 'Atenção...', MB_OK + MB_ICONWARNING);
      edtqtde_parcelas.SetFocus;
      Abort;

    end;

  if (StrToInt(edtqtde_parcelas.Text) = 0) then
    begin

      Application.MessageBox('O Campo tem que ser maior que 0 (ZERO)!', 'Atenção...', MB_OK + MB_ICONWARNING);
      edtqtde_parcelas.SetFocus;
      Abort;

    end;

  if (rgrpData_Vencimento.ItemIndex = -1) then
    begin

      Application.MessageBox('Preencha o Campo Data de Vencimento!', 'Atenção...', MB_OK + MB_ICONWARNING);
      Abort;

    end;

  if edtDia_Vencimento.Enabled = true then
    begin

      if Trim (edtDia_Vencimento.Text) = '' then
        begin

          Application.MessageBox('Preencha o Campo Dia Vencimento, o mesmo não pode ser em branco!', 'Atenção...', MB_OK + MB_ICONWARNING);
          edtDia_Vencimento.SetFocus;
          Abort;

        end;

    end;

  if StrtoFloat(edtDia_Vencimento.Text) = 0 then
    begin

      Application.MessageBox('Preencha o Campo Dia Vencimento, o mesmo não pode ser 0 (ZERO)!', 'Atenção...', MB_OK + MB_ICONWARNING);
      edtDia_Vencimento.SetFocus;
      Abort;

    end;

   if dsTabela.State in [dsInsert,dsedit] then
    begin

      //dmBanco.fdqrycontas_pagarid.AsInteger := GetID ('ID','TBCONTAS_PAGAR');
      dmBanco.fdqrycontas_pagarnumero_doc.AsString := Trim(lbledtNumero_Doc.Text);
      dmBanco.fdqrycontas_pagardescricao.AsString := (lbledtDescricao.Text);
      dmBanco.fdqrycontas_pagarvlr_compra.AsCurrency := StringParaFloat(edtValor_Compra.Text);

      case rgrpData_Vencimento.ItemIndex of

        0 : dmBanco.fdqrycontas_pagartipo_vencimento.AsInteger := 0;
        1 : dmBanco.fdqrycontas_pagartipo_vencimento.AsInteger := 1;
        2 : dmBanco.fdqrycontas_pagartipo_vencimento.AsInteger := 2;
        3 : dmBanco.fdqrycontas_pagartipo_vencimento.AsInteger := 3;

      end;

      if chkA_Vista.Checked = true then
        dmBanco.fdqrycontas_pagartipo_vencimento_a_vista.AsString := 'S'
      else
        dmBanco.fdqrycontas_pagartipo_vencimento_a_vista.AsString := 'N';


      dmBanco.fdqrycontas_pagarDia_vencimento.AsInteger := StrToInt(edtDia_Vencimento.Text);
      dmBanco.fdqrycontas_pagarqtde_parcelas.AsInteger := StrToInt(edtQtde_Parcelas.Text);
      dmBanco.fdqrycontas_pagarvlr_abatido.AsCurrency := 0.00;
      dmBanco.fdqrycontas_pagardata_compra.AsDateTime := StrToDate(edtData_Compra.Text);
      dmBanco.fdqrycontas_pagardata_cadastro.AsDateTime := Now;
      dmBanco.fdqrycontas_pagarstatus.AsString := 'A';

        //Está linha só foi acrescentada por causa da tabela Filha
      //if not TClientDataSet(dsPagamento.DataSet).Active then
        //TClientDataSet(dsPagamento.DataSet).Open;
        //TClientDataSet(dsPagamento.DataSet).Insert;

      For I:=1 to StrToInt(edtQtde_Parcelas.Text) do

      begin

        if dsPagamento.State in [dsInsert,dsedit] then
          begin

            //Salvar as Parcelas no Banco de Dados TBCONTAS_PAGAR_PAGAMENTO
            //dmBanco.fdqrycontas_pagarid.AsInteger := GetID ('ID','TBCONTAS_PAGAR')
            dmBanco.fdqryContas_pagar_pagamentoparcelas.AsInteger := cdsParcelasParcelas.AsInteger;
            dmBanco.fdqryContas_pagar_pagamentodata_vencimento.AsDateTime := cdsParcelasVencimento.AsDateTime;
            dmBanco.fdqryContas_pagar_pagamentovlr_parcela.AsCurrency := cdsParcelasValor.AsCurrency;
            dmBanco.fdqryContas_pagar_pagamentodata_pagamento.AsDateTime := cdsParcelasdata_pagamento.AsDateTime;
            dmBanco.fdqryContas_pagar_pagamentovlr_pagamento.AsCurrency := cdsParcelasvalor_pagamento.AsCurrency;
            dmBanco.fdqryContas_pagar_pagamentoStatus.AsString := 'A';

          end;

      end;



    end;

  inherited;

end;
Marcelo Duarte

Marcelo Duarte

Curtidas 0

Melhor post

Marcelo Duarte

Marcelo Duarte

29/11/2017

Bom dia, alguém saberia me dizer como fazer o SQL do banco acima? Não consigo gravar os dados na tabela da chave estrangeira, ainda estou aprendendo SQL e não consigo fazer está instrução de puderem me auxiliar agradeço, obrigado.
GOSTEI 1

Mais Respostas

Luiz Vichiatto

Luiz Vichiatto

01/11/2017

Olá Marcelo!

Na sua modelagem a PK (primary key) da tabela TBCONTAS_PAGAR_PAGAMENTO é ID apenas?
Neste caso não há problemas, basta criar a trigger para a tabela e adicionar o TBCONTAS_PAGAR_PAGAMENTO.ID deve funcionar.

Para o caso de você ter indicado a chave estrangeira como sendo Primary Key, isso está errado. Chave estrangeira não pode ser chave principal, ela pode compor uma chave principal.

Verifique o seu modelo novamente, ou poste o script que cria as tabelas, assim poderemos auxilia-lo.
GOSTEI 0
Luiz Vichiatto

Luiz Vichiatto

01/11/2017

Outra situação é a sua divisão de parcelamento, quando ao arredondamento, nos sistemas que desenvolvo sempre eu faço a redução no parcelamento, pegando seu exemplo:
1000 / 6 = 166,6666666666667 o que resultaria em parcelas de 166,67 então ficaria
Valor_parcela Numero_parcela resto_a_parcelar
166,67 1 833,33
166,67 2 666,66
166,67 3 499,99
166,67 4 333,32
166,67 5 166,65
166,65 6 0

Isso, em qualquer consulta resultaria no valor correto da soma, sem problemas, não precisando de qualquer tipo de ajuste em valores para consulta.
GOSTEI 0
Marcelo Duarte

Marcelo Duarte

01/11/2017

Bom dia, desculpe a demora em responder, criei um campo ID para todas as tabelas, a unica até o momento que precisei fazer a chave estrangeira que estou seguindo com o curso até o momento seria este , já que no curso o que é proposto acho que seria os dados guardados em uma tabela da forma do valor total e os números das parcelas, por minha conta fiz está alteração mais curso on-line tem alguns empecilhos como este, ainda estou aprendendo banco de dados e delphi então algumas duvidas acontecerão.
A tabela de tbcontas_pagar está deste jeito:
CREATE TABLE `tbcontas_pagar` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`numero_doc` VARCHAR(20) NOT NULL,
`descricao` VARCHAR(200) NOT NULL,
`data_compra` DATE NOT NULL,
`vlr_compra` DECIMAL(18,2) NOT NULL,
`tipo_vencimento` INT(11) NOT NULL,
`tipo_vencimento_a_vista` CHAR(1) NOT NULL,
`Dia_vencimento` INT(11) NULL DEFAULT NULL,
`qtde_parcelas` INT(11) NOT NULL,
`vlr_abatido` DECIMAL(18,2) NOT NULL,
`data_cadastro` DATE NOT NULL,
`status` CHAR(1) NOT NULL,
PRIMARY KEY (`id`)
)
COLLATE='latin1_swedish_ci'
ENGINE=InnoDB
AUTO_INCREMENT=3
;

e a tabela de contas_pagar_pagamento
CREATE TABLE `tbcontas_pagar_pagamento` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`id_contas_pagar` INT(11) NOT NULL DEFAULT '0',
`parcelas` INT(11) NOT NULL DEFAULT '0',
`data_vencimento` DATE NOT NULL,
`vlr_parcela` DECIMAL(18,2) NOT NULL DEFAULT '0.00',
`data_pagamento` DATE NULL DEFAULT NULL,
`vlr_pagamento` DECIMAL(18,2) NULL DEFAULT NULL,
`Status` CHAR(1) NULL DEFAULT NULL,
PRIMARY KEY (`id`),
INDEX `FK_TBContas_Pagar` (`id_contas_pagar`),
CONSTRAINT `FK_TBContas_Pagar` FOREIGN KEY (`ID_CONTAS_PAGAR`) REFERENCES `tbcontas_pagar` (`id`) ON UPDATE CASCADE
)
COLLATE='latin1_swedish_ci'
ENGINE=InnoDB
AUTO_INCREMENT=9
;

Sobre a forma como foi feito o parcelamento, fiz da seguinte forma. Calculei todas as parcelas sem casas decimais, e depois inseri a diferença da somatória de todas as parcelas com o valor total e somei está diferença na primeira parcela.

Abaixo segue o projeto da forma como está até o momento.
https://mega.nz/#!EQRSjLZI!dqE2waSCTj9A8zl0miJ7tEfvUniCr3uPByo6diAbmro
GOSTEI 0
POSTAR