Baixa de Itens

Delphi

11/05/2006

Olá amigos!!!!

Tenho uma dúvida sobre processo de baixa de itens. Eu criei duas telas, uma que faz a solicitação e a outra que faz a saída. Na tela da entrada da solicitação, não há problemas. Na saída, tenho um dbgrid que mostra todas as solicitações pendentes (tabela SOLICITACAO), e um abaixo constando os itens de cada solicitação (num esquema mestre - detalhe - tabela ITENS). Os campos que fazem parte da tabela de itens são COD_ITEM, COD_CART (cartucho), MODELO, MARCA, QTDE e STATUS.

Gostaria de saber se é possível, com uma solicitação selecionada, baixar todos os itens de uma só vez, ou seja, analisar a disponibilidade em estoque de cada item da solicitação e fazer a baixa, se o estoque for suficiente, status fica como ENVIADO, caso contrário, PENDENTE (numa outra situação, poderia até colocar um status PARCIAL, se eu solicitei 2 itens e tem apenas um no estoque, poderia enviar 1 e ficar o outro pendente, por exemplo). A única forma que encontrei foi fazer manual um a um, ou seja, eu clico no item do dbgrid e faço a baixa, mas e se tiver vários itens, fica um pouco produtivo.

Fico no aguardo e se tiverem uma sugestão melhor, será muito bem-vinda.

Estou utilizando FIREBIRD + DELPHI 2005 + CLIENTDATASET

Um abraço,


Roger1976

Roger1976

Curtidas 0

Respostas

Jonas_giron

Jonas_giron

11/05/2006

USA A FUNÇÃO WHILE... EXE

While not QrItens.Eof do begin
//...seu texto pra dar a baixa do item
QrEquipamento.Next;
end;

cada next que o sistema da ele vai executar a baixa do item que estiver setado.


GOSTEI 0
Roger1976

Roger1976

11/05/2006

Jonas, agradeço em primeiro lugar pela dica. Fiz um teste, porém, há uma outra dúvida: quando eu seleciono todos os itens da tabela um a um (com a propriedade dgmultselect do grid setada para true) ele dá a baixa no último item que eu cliquei e fica dando um loop infinito até travar a aplicação. Qdo é um item só, blz, mas se tem dois, por exemplo, dá pau...

Para testar, criei um botão chamado teste e implementei o seguinte código:

procedure TfrmAtenderSolic.Button1Click(Sender: TObject);
var
QtdeSolic, QtdeEstoque, CodigoCartucho : integer;
Mensagem : string;
begin
btnBaixarItem.Enabled := false;
CodigoCartucho := strtoint(copy(edtModelo.Text, 1, 3));
QtdeSolic := strtoint(edtQtde.Text);
QtdeEstoque := strtoint(edtQtdeEst.Text);

while not dmSolicitacao.cdsItensPend.Eof do
begin
if QtdeEstoque >= QtdeSolic then
begin
// Baixa o estoque
with dmEstoque.cdsBaixaEstoque do
begin
FetchParams;
close;
Params.ParamByName(´COD_CART´).AsSmallInt := CodigoCartucho;
Params.ParamByName(´RESULTADO´).AsSmallInt := QtdeSolic;
execute;
end;

// Atualiza o status do item para ´ENVIADO´
with dmItens.cdsStatusEnviado do
begin
FetchParams;
close;
Params.ParamByName(´COD_ITEM´).AsInteger := strtoint(lblCodItem.Caption);
execute;
dmSolicitacao.cdsSolicPend.Refresh;

end;

// Mostra a qtde. em estoque atualizada
with dmEstoque.cdsPesqQtdeCodCart do
begin
FetchParams;
close;
Params.ParamByName(´COD_CART´).AsSmallInt := CodigoCartucho;
open;
edtQtdeEst.Text := inttostr(FieldByName(´QTDE´).AsInteger);
end;
end;

dmSolicitacao.cdsItensPend.Next;

end;
end;

O que há de errado no código?

De qualquer forma, achei uma boa dica, caso tenha outra sugestão para o código acima ou queira mostrar os erros, será bem-vinda.

Obrigado amigo...


GOSTEI 0
Roger1976

Roger1976

11/05/2006

Jonas, agradeço em primeiro lugar pela dica. Fiz um teste, porém, há uma outra dúvida: quando eu seleciono todos os itens da tabela um a um (com a propriedade dgmultselect do grid setada para true) ele dá a baixa no último item que eu cliquei e fica dando um loop infinito até travar a aplicação. Qdo é um item só, blz, mas se tem dois, por exemplo, dá pau...

Para testar, criei um botão chamado teste e implementei o seguinte código:

procedure TfrmAtenderSolic.Button1Click(Sender: TObject);
var
QtdeSolic, QtdeEstoque, CodigoCartucho : integer;
Mensagem : string;
begin
btnBaixarItem.Enabled := false;
CodigoCartucho := strtoint(copy(edtModelo.Text, 1, 3));
QtdeSolic := strtoint(edtQtde.Text);
QtdeEstoque := strtoint(edtQtdeEst.Text);

while not dmSolicitacao.cdsItensPend.Eof do
begin
if QtdeEstoque >= QtdeSolic then
begin
// Baixa o estoque
with dmEstoque.cdsBaixaEstoque do
begin
FetchParams;
close;
Params.ParamByName(´COD_CART´).AsSmallInt := CodigoCartucho;
Params.ParamByName(´RESULTADO´).AsSmallInt := QtdeSolic;
execute;
end;

// Atualiza o status do item para ´ENVIADO´
with dmItens.cdsStatusEnviado do
begin
FetchParams;
close;
Params.ParamByName(´COD_ITEM´).AsInteger := strtoint(lblCodItem.Caption);
execute;
dmSolicitacao.cdsSolicPend.Refresh;

end;

// Mostra a qtde. em estoque atualizada
with dmEstoque.cdsPesqQtdeCodCart do
begin
FetchParams;
close;
Params.ParamByName(´COD_CART´).AsSmallInt := CodigoCartucho;
open;
edtQtdeEst.Text := inttostr(FieldByName(´QTDE´).AsInteger);
end;
end;

dmSolicitacao.cdsItensPend.Next;

end;
end;

O que há de errado no código?

De qualquer forma, achei uma boa dica, caso tenha outra sugestão para o código acima ou queira mostrar os erros, será bem-vinda.

Obrigado amigo...


GOSTEI 0
Jonas_giron

Jonas_giron

11/05/2006

Deixa eu ver se Entendi... vc tem um Grid com todos os lançamentos...certo????...com todos os dados da tabela... ai vc seleciona os itens que vc que dar as baixas e manda executar a rotina... veja só a função while que vc colocou ai ela corre a tabela toda... vc teria que passar uma select em outra Query pegando somente os dados que estão selecionados no Grid e depois mandar executar o while nessa query.


GOSTEI 0
Emerson Nascimento

Emerson Nascimento

11/05/2006

procedure TfrmAtenderSolic.Button1Click(Sender: TObject); 
var 
  QtdeSolic, QtdeEstoque, CodigoCartucho : integer; 
  Mensagem : string; 
begin 
  btnBaixarItem.Enabled := false; 

{
  // creio que essas variáveis sejam desnecessárias aqui
  // ----------------------------------------------
  CodigoCartucho := strtoint(copy(edtModelo.Text, 1, 3)); 
  QtdeSolic := strtoint(edtQtde.Text); 
  QtdeEstoque := strtoint(edtQtdeEst.Text); 
}
  // se as tabelas são ligadas no esquema mestre/detalhe não
  // haverá problema em executar o First
  dmSolicitacao.cdsItensPend.First;

  with dmSolicitacao do
  while not cdsItensPend.Eof do 
  begin 
    QtdeEstoque := strtointdef(edtQtdeEst.Text,0); 
    // pegue a quantidade do item posicionado
    QtdeSolic := cdsItensPendQUANTIDADE.AsInteger;
    // pegue o código do item posicionado
    CodigoCartucho := strtoint(copy(cdsItensPendMODELO.AsString, 1, 3)); 

    // aqui, ao invés de QtdeSolic, poderia ser
    // um campo saldo, para que você não perca o
    // valor original 
    if QtdeEstoque >= QtdeSolic then 
    begin 
      // Baixa o estoque 
      with dmEstoque.cdsBaixaEstoque do 
      begin 
        FetchParams; 
        close; 
        Params.ParamByName(´COD_CART´).AsSmallInt := CodigoCartucho; 
        Params.ParamByName(´RESULTADO´).AsSmallInt := QtdeSolic; 
        execute; 
      end; 

      // Atualiza o status do item para "ENVIADO" 
      with dmItens.cdsStatusEnviado do 
      begin 
        FetchParams; 
        close; 
        Params.ParamByName(´COD_ITEM´).AsInteger := strtoint(lblCodItem.Caption); 
        execute;
        //não execute o refresh. isso reposiciona o 
        //ponteiro de registros 
        //cdsSolicPend.Refresh; 
      end; 

      // Mostra a qtde. em estoque atualizada 
      with dmEstoque.cdsPesqQtdeCodCart do 
      begin 
        FetchParams; 
        close; 
        Params.ParamByName(´COD_CART´).AsSmallInt := CodigoCartucho; 
        open; 
        edtQtdeEst.Text := inttostr(FieldByName(´QTDE´).AsInteger); 
      end; 
    end; 

    cdsItensPend.Next; 
  end;

  dmSolicitacao.cdsSolicPend.Refresh;
 
end;


acho que assim pode funcionar...


GOSTEI 0
Roger1976

Roger1976

11/05/2006

jonas, seria interessante se eu postasse aqui o print da tela, mas eu ainda não sei como faz. Para vc ter uma idéia, a tela tem dois grids e alguns speedbuttons. Tem um speedbutton que, ao ser clicado, mostra as solicitações pendentes no dbgrid DBGRDSOLIC e os itens dno dbgrid DBGRDITENS. À medida que clico numa solicitação no dbgrdsolic, mostra os itens referentes a ela no dbgrditens. Aí eu ainda não decidi se crio um botão para selecionar os itens pendentes e outro para dar a baixa, ou se crio um botão que faz toda a rotina.

Emerson, fiz o teste de acordo com o código que vc sugeriu, mas a baixa está sendo feita somente qdo clico no item que está no dbgritens, neste caso, teria que fazer isso um a um.

Jonas, Emerson, obrigado mais uma vez pela ajuda.


GOSTEI 0
Jonas_giron

Jonas_giron

11/05/2006

Deixa eu dar uma pensada.. te darei um retorno


GOSTEI 0
Jonas_giron

Jonas_giron

11/05/2006

a tabela que esta ligada no Grid é a mesma do DataModule???


GOSTEI 0
Roger1976

Roger1976

11/05/2006

Jonas, eu fiz algumas alterações, a sugestão do Emerson me ajudou, e o código ficou dessa maneira (farei os comentários):

procedure TfrmAtenderSolic.btnBaixarItensClick(Sender: TObject);
var
QtdeSolic, QtdeEstoque, CodigoCartucho : integer;
StatusItem : string;
begin
btnBaixarItens.Enabled := false;
btnFinalizarSolic.Enabled := true;

with dmSolicitacao do
begin
cdsItensPend.First;
while not cdsItensPend.Eof do
begin
QtdeEstoque := strtoint(edtQtdeEst.Text);
QtdeSolic := strtoint(edtQtde.Text);
CodigoCartucho := strtoint(copy(edtModelo.Text, 1, 3));
StatusItem := cdsItensPend.FieldByName(´STATUS´).AsString;

if QtdeEstoque >= QtdeSolic then
begin
// Faz a verificação do STATUS do item
// se estiver como PENDENTE, realiza a baixa no estoque
// e muda o status para ENVIADO
if StatusItem = ´PENDENTE´ then // essa foi uma mudança que eu fiz, onde verificasse os itens que estão com o status pendente e faz a baixa
begin
// Baixa o estoque
with dmEstoque.cdsBaixaEstoque do
begin
FetchParams;
close;
Params.ParamByName(´COD_CART´).AsSmallInt := CodigoCartucho;
Params.ParamByName(´RESULTADO´).AsSmallInt := QtdeSolic;
execute;
end;

// Atualiza o status do item para ´ENVIADO´
with dmItens.cdsStatusEnviado do
begin
FetchParams;
close;
Params.ParamByName(´COD_ITEM´).AsInteger := strtoint(lblCodItem.Caption);
execute;
end;

// Mostra a qtde. em estoque atualizada
with dmEstoque.cdsPesqQtdeCodCart do
begin
FetchParams;
close;
Params.ParamByName(´COD_CART´).AsSmallInt := CodigoCartucho;
open;
edtQtdeEst.Text := inttostr(FieldByName(´QTDE´).AsInteger);
end;
end;
end;
cdsItensPend.Next;
// Mostra os dados nos edits/combo
dbgrdItensCellClick(dbgrdItens.Columns.Items[1]); // outra mudança, onde garante a seleção do próximo item
end;
dmSolicitacao.cdsSolicPend.Refresh;
end;
end;

Em relação a sua pergunta, eu tenho um datamodule onde há um esquema master-detail, da tabela de SOLICITACOES com a de ITENS, e os dois dbgrids estão relacionados a este DM.

De qualquer forma, agora está funcionando da maneira que eu quero.

Agradeço muito a vc e ao Emerson pelas dicas, que foram muito importantes para a minha solução.

Abraço,

Rogério


GOSTEI 0
POSTAR