Este é um post disponível para assinantes MVPVideo: Rad Studio 2007-DBX4 e Firebird 2.0-Aplicação comercial de vendas do Inicio ao Fim-Parte 37-Finalizando a Venda
Nesta vídeo, utilizaremos também as classes DBX4 para verificar se a senha informada pertence a um determinado vendedor.
Título:
Tempo: 25:13 min
Mini Resumo: Desde o inicio do projeto, ainda no modelo de banco de dados nós definimos que toda venda deverá pertencer a um cliente e ser realizada por um usuário com permissão para realizar venda. Até agora em nenhum momento em nossa aplicação durante a realização de uma venda nós nos preocupamos por isso. Deixamos isso para o momento de finalizar a venda onde informaremos o Cliente e o vendedor e o momento é este.
Metodologia de desenvolvimento do exemplo: Será criada uma tela exclusiva para finalização da venda onde informaremos o cliente para qual será feita a venda. Utilizaremos também as classes DBX4 para verificar se a senha informada pertence a um vendedor. Por fim criamos a rotina para gerar a venda no banco de dados.
Tecnologias utilizadas: RadStudio 2007, FireBird2.0, DBX4
Exemplos construídos: Finalização da venda.
Palavras chaves: Delphi2007, DBX4, POO, DBXCommon, EmptyDataSet.

21 COMENTÁRIOS
Uma solução seria pedir para o usuario se logar ao abria a tela de venda, ou repassar se ale abrir de dentro do programa. Na hora da venda apenas pediriamos a senha para confirmar se é quem diz que é.
Ainda assim poderá ocorrer de alguem com a mesma senha vender. Para 100% de segurança é pedir usuario e senha mesmo, ou autenticação por biometria. Ai viajei legal ne kkkkkk.
Mas acredito que seja por ai !!!
Abs !!

Boa Tarde Rodrigo
Eu estou tentando fazer uma consulta, só que me retorna um erro, Remote Error: Missing Query, Table Name or Procedure Name.
Do lado Servidor tenho um SQLDataSet, Vazio e um DataSetProvider, e do lado Client ClientDataSet, e passo este comando.
Como posso resolver isto
procedure TLista_Clientes.DoSearch;
Var
S: TStringList;
begin
S := TStringList.Create;
S.Add('SELECT ID_ENTIDAD,ENTIDAD_TEXT,ENDERESO, ');
S.Add('N_CASA,TELEFONO,RUC,TELEFONO,RUC ');
S.Add('FROM CENTIDADES ');
if FConsulta.vIDN_CLIENTE = 'S' then //Recebe Informação do TConsulta = record
S.Add('WHERE IDN_CLIENTE = ''S''');
if FConsulta.vIDN_PROVEEDOR = 'S' then //Recebe Informação do TConsulta = record
S.Add('WHERE IDN_PROVEEDOR = ''S''');
if FConsulta.vIDN_COMPRA_GRANOS = 'S' then //Recebe Informação do TConsulta = record
S.Add('WHERE IDN_COMPRA_GRANOS = ''S''');
if FConsulta.vIDN_TRANSPORTADORA = 'S' then //Recebe Informação do TConsulta = record
S.Add('WHERE IDN_TRANSPORTADORA = ''S''');
if FConsulta.vIDN_FUNCIONARIO = 'S' then //Recebe Informação do TConsulta = record
S.Add('WHERE IDN_FUNCIONARIO = ''S''');
if FConsulta.vIDN_JURNALEIRO = 'S' then //Recebe Informação do TConsulta = record
S.Add('WHERE IDN_JURNALEIRO = ''S''');
if FConsulta.vIDN_VENDEDOR = 'S' then //Recebe Informação do TConsulta = record
S.Add('WHERE IDN_VENDEDOR = ''S''');
if Combo_Campos.ItemIndex = 0 then
S.Add('AND ENTIDAD_TEXT CONTAINING ' + QuotedStr(Texto_Procure.Text)); //Varchar - Opção do usuario
if Combo_Campos.ItemIndex = 1 then
S.Add('AND N_CEDULA = ' + QuotedStr(Texto_Procure.Text)); //DOUBLE PRECISION - Opção do usuario
if Combo_Campos.ItemIndex = 2 then
S.Add('AND RUC CONTAINING ' + QuotedStr(Texto_Procure.Text)); //Varchar
if Combo_Campos.ItemIndex = 3 then
S.Add('AND TELEFONO CONTAINING ' + QuotedStr(Texto_Procure.Text)); //Varchar - Opção do usuario
if Combo_Campos.ItemIndex = 4 then
S.Add('AND CIUDAD = ' + QuotedStr(Texto_Procure.Text)); //Integer - Opção do usuario
if Combo_Campos.ItemIndex = 5 then
S.Add('AND N_CASA CONTAINING ' + QuotedStr(Texto_Procure.Text) ); //Varchar - Opção do usuario
ListaClientes.Close;
ListaClientes.CommandText := S.Text;
ListaClientes.Open;
FreeAndNil(S);
Para passar instrução sql via ClientDataSet você precisa alterar a propriedade poAllowCommandText do data set Provider. Ele fica dentro da propriedade Options !!
Abs !!!

Bom dia
Eu já tinha feito isto poAllowCommandText para = True, Mais mesmo assim não da certo.
Depois consegui, resolver o problema, tem que por o ListaClientes.Execute; antes do Open (DataSnap 2009)
ListaClientes.Close;
ListaClientes.CommandText := S.Text;
ListaClientes.Execute;
ListaClientes.Open;
Voce não havia citado que era no D2009. Temos muitas coisas diferentes agora. E dependendo da arquitetura que a gente montar, com ServerMethod ou não, Com proxy ou não, a coisa muda de figura.
Mas legal, o importante e resolver.
Abs!!

1º) Acess Violation pode esta relacionado a vários processos mas que no final se resume a: O objeto não foi criado, ou já foi destruido. Agora isso tem suas variantes, por exemplo dar um open num ClientDataSet que esta num data module que e criado depois do Form. Nesse caso objeto(DM) não criado, resultado AcessVioletion.
No seu caso revise a video passo - a - passo. Pode ter passado um delatlhe como registrar a classe, etc.
2ª) Esse segundo caso e totalmente anormal kkkkkkkkkkkk, pode ser um delay de tela, problema no componente. Verifique a autalização do Delphi para saber se esta com a verão mais recente.
abs !
Abs!!

Grande Rodrigo!!
var
H:HMODULE;
PForm : TFormClass;
Form : TForm;
begin
if FileExists('Vendas.bpl') then
begin
H := LoadPackage('Vendas.bpl');
if H > 0 then
begin
PForm := TFormClass(GetClass('TFrmVendas'));
if Assigned(PForm) = true then
begin
Form := PForm.Create(nil);
Form.ShowModal;
FreeAndNil(Form);
UnloadPackage(H);
end
else
ShowMessage('Erro ao carregar classe');
end
else
ShowMessage('Erro ao carregar pacote');
end
else
begin
MessageDlg('Recurso Nâo disponivel nesta versão',mtWarning,[mbOK],0);
end;
Este erro ocorre quando o metodo GetClass('TFrmVendas') nao retorna o ponteiro da classe. Isso pode ser duas coisas principais, mas nao somente elas:
1) Verificar se no Form TfrmVendas tem o codigo no initialization RegisterClass(TFrmVendas); Atentem para o nome das suas classes pois o getclass passamos um string. Observe GetClass('TFrmVendas') Se eu registrar TVendas nao posso dar um GetClass('TFrmVendas') tenho que fazer GetClass('TVendas').
2) Abra o projeto comercial va em project options e verifique se o projeto esta marcado para trabalhar com pacotes.
Qualquer coisa estamos as ordens !!
Abs !!
Abraço.
Alessandre.

Quando eu finalizo a venda no formulário de finalização de vendas, ocorre um erro bem na hora que eu tento acessar o frmVendas, geralmente antes de percorrer o CDS itens da venda no formulário das Vendas. Nesta linha:
frmVendas.cdsItensVenda.First;
while not frmVendas.cdsItensVenda.Eof do
...
Tanto em uma quanto na outra ocorre um erro de acesso de violação.
Então fui debugando, e quando cheguei nestas linhas, o frmVendas estava com o valor nil, dai percebi que o formulário de vendas é criado lá no frmPrincipal lembra ?
Então quando agente tenta acessar lá de dentro do pacote o frmVendas (Apesar de estarem no mesmo pacote) o frmVendas ta como nil porque foi criado la no principal.
Não sei como resolver isso, fiquei tentando criar uma rotina pra armazenar o objeto criado la no principal do formulario de vendas pra dai passar pro frmVendas e ai pegar do frmFinalizaVenda, mas nao to conseguindo, e nem sei se isso vai resolver, alguém pode me ajudar ?
Olhá o código do botão finalizar Venda no formulário frmFinalizaVenda:
var
DBConn: TDBXConnection;
DBCommand: TDBXCommand;
Reader: TDBXReader;
login: string;
vendedor: AnsiString;
usuario: integer;
begin
if (edtSenhaVendedor.Text = EmptyStr) or (edtLoginUsuario.Text = EmptyStr) then
begin
Application.MessageBox('Verifique os campos login e senha do usuário', 'Campo vazio', MB_OK + MB_ICONINFORMATION);
Exit;
end;
DBConn := TDBXConnectionFactory.GetConnectionFactory.GetConnection('FBCONNECTION1', 'SYSDBA', 'masterkey');
DBCommand := DBConn.CreateCommand;
DBCommand.Text := 'SELECT vendedor, login, usuarioid FROM usuarios WHERE senha = ' + QuotedStr(edtSenhaVendedor.Text) +
' AND login = ' + QuotedStr(edtLoginUsuario.Text);
Reader := DBCommand.ExecuteQuery;
if Reader.Next then
begin
login := Reader.Value[Reader.GetOrdinal('login')].GetAnsiString;
vendedor := Reader.Value[Reader.GetOrdinal('vendedor')].GetAnsiString;
usuario := Reader.Value[Reader.GetOrdinal('usuarioid')].GetInt32;
if not (vendedor = 'S') and (login = edtLoginUsuario.Text) then
begin
Application.MessageBox('O usuário foi encontrado, porém, não é um vendedor e não poderá realizar a venda',
'Venda não realizada', MB_OK + MB_ICONINFORMATION);
edtLoginUsuario.SelectAll;
edtLoginUsuario.SetFocus;
Exit;
end
else if cdsClienteItem.IsEmpty then
begin
Application.MessageBox('Selecione algum cliente para realizar a venda.' + #13 +
'Para selecionar algum cliente, basta entrar na caixa de texto acima ' + '''' + 'Digite o nome de um cliente' + '''' +
' e digitar o nome de um cliente.', 'Cliente não encontrado', MB_OK + MB_ICONINFORMATION);
edtCliente.SelectAll;
edtCliente.SetFocus;
Exit;
end
else if (vendedor = 'S') and (login = edtLoginUsuario.Text) and not (cdsClienteItem.IsEmpty) then
begin
with DMComercial do
begin
try
cdsVendas.Open;
cdsVendas.Append;
cdsVendasCLIENTEID.Value := cdsClienteItemCLIENTEID.Value;
cdsVendasUSUARIOID.Value := usuario;
cdsVendasDATA.Value := Date;
frmVendas := TfrmVendas.Create(nil);
frmVendas.cdsItens.First;
while not frmVendas.cdsItens.Eof do //Cds do frmVenda
begin
cdsVendaItem.Append; // cds do DataModule
cdsVendaItemPRODUTOID.Value := frmVendas.cdsItensCodigo.Value;
cdsVendaItemQTD.Value := frmVendas.cdsItensquantidade.AsBCD;
cdsVendaItemPRECO.Value := frmVendas.cdsItenspreco.AsBCD;
cdsVendaItem.Post;
end;
cdsVendas.ApplyUpdates(0);
Application.MessageBox('Venda realizada com sucesso', 'Sucesso', MB_OK + MB_ICONINFORMATION);
cdsVendas.Close;
frmVendas.cdsItens.EmptyDataSet;
frmVendas.cdsItens.Close;
ModalResult := mrOk;
except
On Ex : Exception do
MessageDlg('Ocorreu um erro durante a transação da venda ao banco' + #13#13 +
'Descrição do erro: ' + Ex.Message + #13#13 +
'Contate o fabricante do sistema para verificar o erro', mtError, [mbOk], 0);
end;
end;
end;
end
else
begin
Application.MessageBox('O login do usuário não foi encontrado, verifique o campo login do usuário.' + #13 +
'Verifique se o login do usuário tem a primeira maíuscula ou se foi digitado alguma coisa incorretamente.' + #13 +
'Por exemplo: João é diferente de joão.', 'Usuário não encontrado', MB_OK + MB_ICONINFORMATION);
edtLoginUsuario.SelectAll;
edtLoginUsuario.SetFocus;
end;
end;
Analizando o código que postou, vi que esta recriando o frmvendas neste ponto:
frmVendas := TfrmVendas.Create(nil);
Observe no desenrolar do vídeo, que não tem esta instrução. Acredito que este seja o problema. Teste aí pra ver.
Abs.!
mas se eu remover essa linha, não adianta nada
Testei nos códigos aqui e não apresentou problema algum, e o erro que você relatou num comentário anterior (erro de violação) esta relacionado ao fato de estar criando um objeto já criado. O formvenda é quem chama o de fechamento sendo assim se criar o mesmo dentro do fechamento da o erro informado. Peque o código que esta disponibilizado junto com o vídeo e faça um teste sem nenhuma alteração pra ver.
Abs.!

Grande Abraço!
Rodrigo Mourão
Curso(s):
Space do autor

download

4
0
