Gravar dados Tabela X Tabela Chave Estrangeira
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:
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:
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
Curtidas 0
Melhor post
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
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.
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
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.
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
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
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