Fórum Aplicação Multicamadas #407130

26/08/2011

0

Pessoal,     vou começar uma nova aplicação que deverá ser multicamadas e estou com algumas dúvidas.   1) Quero utilizar o mínimo possível de recursos do banco de dados para evitar o acoplamento da aplicação com o banco, mas ainda não aprendi a fazer certas operações via aplicação servidora. Exemplo: Ao realizar uma venda é necessário que faça automaticamente um lançamento de saída na tabela de movimentações de estoque. Atualmente faço isso através de trigger, porém isso cria um vínculo muito forte entre a aplicação e o banco, o que dificulta uma possível migração de um banco para outro. Nos testes que estou fazendo criei um DataModule (descendente de TDSServerModule) no servidor e nele ficará tudo que é relativo a vendas. Nele tenho alguns SQLDataSet's, dentre os quais sdsVenda, sdsVendaItens. Na aplicação cliente, na tela de vendas, tenho os ClientDataSet's para venda e itens da venda. O que não sei fazer é que ao salvar uma venda na aplicação cliente através do ClientDataSet o servidor deverá disparar um método que verifique a disponibilidade de estoque dos itens vendidos, caso haja disponibilidade a venda será confirmada e salva, caso não haja disponibilidade a venda não poderá ser salva e deverá ser emitido um aviso para o usuário. Alguém sabe como fazer esse tipo procedimento?     2) Em relação às regras de negócio, como separar o que deve ficar no lado servidor e o que deve ficar no lado cliente? Exemplo, o cálculo de total do ítem da venda (quantidade * unitario), a validação de CPF/CNPJ deverá ficar em qual aplicação?
Rogerio Corgozinho

Rogerio Corgozinho

Responder

Posts

26/08/2011

Marco Salles



1)
O que não sei fazer é que ao salvar uma venda na aplicação cliente através do ClientDataSet o servidor deverá disparar um método que verifique a disponibilidade de estoque dos itens vendidos, caso haja disponibilidade a venda será confirmada e salva, caso não haja disponibilidade a venda não poderá ser salva e deverá ser emitido um aviso para o usuário. Alguém sabe como fazer esse tipo procedimento?

 
Codifique o evento BeforeUpdateRecor do TDataSetProvider , e gere uma exceção quando este valor for negativo

A codificação vai depender da normalização de seu banco de dados . Saldo esta e qual tabela , tabela Produtos , tabela Venda , tabela Item da Vendas ??? .. Enfim , vc pode analogicamente ao que vc faz na trigues utilizando oldValue e NewValue efetuar
a Regra de negocio..
Vc tem ainda a possibilidade de utilizar o evento onUpdateRecord onde vc recebe o Delta que contem todos os dados
Alterados e Não alterados

Sugiro olhar com carinho este dois eventos seus parametros e partir para esta linha de raciocineo que ha meu ver é a mais indicada neste tipo de arquitetura.



 2) Em relação às regras de negócio, como separar o que deve ficar no lado servidor e o que deve ficar no lado cliente? Exemplo, o cálculo de total do ítem da venda (quantidade * unitario), a validação de CPF/CNPJ deverá ficar em qual aplicação?


O que fica no lado do servidor é algo que pode varia com o tempo , e algo sucessivel a mudança. Validar Cnpj , Validar CPF a regra de negocio é fixa , nunca ou dificilemente modificara. para que ocupar o Servidor com estes tipo de calculos ?? ( alem de que são calculos simples que qualquer cliente Magro tem plena condiçoes de fazer ). O mesmo valoe para cálculo de total do ítem da venda (quantidade * unitario), será sempre assim e pode ser feito num campo InternalCalc no lado cliente
Responder

Gostei + 0

10/09/2011

Rogerio Corgozinho

  Marco Antonio, obrigado pelas dicas, já estou trabalhando em meu projeto. Agora estou com um pequeno problema, se puder me ajudar.

  É o seguinte, preciso salvar no campo CHAVE da tabela de usuários uma combinação de valores que garantirá a autenticidade do mesmo. Para isso coloquei na aplicação servidora o método abaixo, que é disparado sempre que se cadastre ou altere um usuário pela aplicação cliente. O problema é que quando é uma alteração de registro a propriedade NewValue somente é preenchida se houver alterações no respectivo campo. No meu caso, preciso pegar o valor que  está no registro afetado pelo ClientDataSet, independentemente de ter sido alterado ou não. Tentei usar Value, AsString e outros mais, porém se o campo não foi alterado todas estas propriedades vem como null.


procedure TsmCadastros.dspUsuariosBeforeUpdateRecord(Sender: TObject;
  SourceDS: TDataSet; DeltaDS: TCustomClientDataSet; UpdateKind: TUpdateKind;
  var Applied: Boolean);

  var Chave : String;
begin
  Chave :=  DeltaDS.FieldByName('LOGIN').NewValue
          + DeltaDS.FieldByName('SENHA').NewValue
          + DeltaDS.FieldByName('BLOQUEADO').NewValue
          + IntToStr(DeltaDS.FieldByName('TIPO').NewValue);

  Chave := Chave + DigitoVerificador (Chave);

  DeltaDS.FieldByName('CHAVE').NewValue := dmPrincipal.Criptografia.EncodeString(uConsts.ChaveUsuario, chave);

end;


Sabe como posso fazer isso?
Responder

Gostei + 0

11/09/2011

Marco Salles

Antes de prosseguir , acreidito que esta regra de negocio deve ser testada no Client ..

Finalmente ao comoparar com o digito Verificador , se tudo ocorrer de acordo com a sua lógica proseguir

Afinal essas combinações com Digito Verificador , não são alterados e modificados a Vera


Responder

Gostei + 0

11/09/2011

Rogerio Corgozinho

Neste caso acho que a regra pode ficar no servidor, pois o usuário não fará nada com ela e deverá ser gerada automaticamente de acordo com as informações de seu cadastro. Este código que postei é para gerar esta chave que deverá ser testada no momento em que for feito o login, caso o sistema encontre alguma inconsistência não permitirá que o usuário prossiga.
Ainda assim, caso esta regra fique no cliente preciso aprender a recuperar os valores do registro corrente (independentemente de terem sido alterados) para usar em outros regras de negócios que obrigatoriamente ficarão no servidor.

Obrigado pela atenção
Responder

Gostei + 0

12/09/2011

Marco Salles

Bem, vc diz:

" O problema é que quando é uma alteração de registro a propriedade NewValue somente é preenchida se houver alterações"

Teste a propriedade UpdateKind , caso se trate de uma  alteração de registro a utilize o oldValue , caso se trate de uma inserção

utilize a propriedade NewValue 
Responder

Gostei + 0

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar