Mestre Detalhe: Produto/Filial

Firebird

09/02/2007

Pessoal,
Bom dia!

Estou precisando fazer um cadastro de produto onde o sistema trabalha com varias filiais, entao montei o cadastro de produto assim:

PRODUTO
PK ID_PRODUTO
DESCRICAO


PRODUTO_FILIAL
PK ID_PRODUTO_FILIAL
ID_FILIAL
ID_PRODUTO
VALOR_CUSTO

Como não é um cadastro Mestre/Detalhe comum eu fiquei na duvida de como seria a maneira correta de montar este cadastro. Alguem que ja tenha feito algo parecido poderia me dar algumas dicas ??

Fico no aguardo!



Mmoreira

Mmoreira

Curtidas 0

Respostas

Emerson Nascimento

Emerson Nascimento

09/02/2007

eu tenho um caso igual ao seu e modelei as tabelas dessa mesma forma, pois é um relacionamento ´muitos para muitos´.


GOSTEI 0
Mmoreira

Mmoreira

09/02/2007

Emerson,
Na verdade eu medelei estas tabelas com base em alguns posts que voce respondeu aqui no forum referente a este assunto de trabalhar com mais de uma empresa ... e tenho certeza que estou no caminho certo.

Eu estava querendo uma sugestão de como montar este cadastro no Delphi .. uma vez que nao posso usar a técnica para relacionar as tabelas por ter o campo ID_FILIAL .. e mesmo porque quando o usuario logar no sistema ele informa em qual empresa ele esta entrando ... entao ele entrando no cadastro de produto as informações apresentadas ao usuario devem ser da empresa correspondente .. ou seja ai teria dois ClientDataSet que nao vao estar relacionados .. estariam indempendentes ... entao o usuario localiza um produto que ja esteja cadastrado ... eu abro o ClienteDataSet_PRODUTO e apos este abrir eu abriria o ClientDataSet_PRODUTO_FILIAL com base na filial que que usuario LOGOU e o codigo do produto que foi aberto no ClientDataSet_Produto ...
E na hora de cadastrar um novo produto ??? ... Em fim eu tenho algumas ideias de como fazer, mas nao estou bem certo se esta seria a maneira correta.

Não sei se fui bem claro na dúvida ... qualquer coisa eu tenho me explicar melhor!


GOSTEI 0
Emerson Nascimento

Emerson Nascimento

09/02/2007

você pode fazer de duas formas:

[b:3cf642b611]1. tomar como partida a tabela de relacionamento, no caso a tabela PRODUTO_FILIAL:[/b:3cf642b611]
então teria a seguinte instrução ao pesquisar os produtos:
select
  prod.*
from
  PRODUTO_FILIAL PF
inner join
  PRODUTO PROD on (PROD.ID_Produto = PF.ID_Produto)
where
  PF.ID_Filial/Filial = :Filial
  and PROD.CODIGO = :Codigo
(onde código pra mim seria o código de barras, que é único)
[list:3cf642b611][*:3cf642b611]se encontrou, ótimo. não há segredo.
[*:3cf642b611]se não encontrou pode ser por dois motivos: o produto pode não existir na base de dados ou simplesmente não ter sido associado à filial. exiba uma mensagem na tela.
[/list:u:3cf642b611]
em função de trabalhar com esses registros muitos para muitos, ao inserir, após sair do campo onde há o código único do produto, verifique se o produto existe na tabela PRODUTO:
[list:3cf642b611][*:3cf642b611]se existir, traga seus dados para visualização e o associe à filial logada
[*:3cf642b611]se não existir, permita a inclusão do produto e já o associe com a filial logada.
[/list:u:3cf642b611]
ou

[b:3cf642b611]2. tomar como partida a tabela PRODUTO:[/b:3cf642b611]
então teria a seguinte instrução ao pesquisar os produtos:
select
  prod.*, pf.ID_Filial
from
  PRODUTO PROD
left join
  PRODUTO_FILIAL PF on (PF.ID_Produto = PROD.ID_Produto and PF.ID_Filial = :Filial)
where
  PROD.CODIGO = :Codigo
(onde código pra mim seria o código de barras, que é único)

dessa forma é até possível exibir a msg com uma informação mais precisa.

verifico se a tabela está vazia.
1. se estiver vazia, o produto NÃO existe. crio o produto e já associo com a filial
2. se NÃO estiver vazia, o produto existe. então verifico o campo ID_Filial:[list:3cf642b611][*:3cf642b611]se ID_Filial for diferente de nulo, tudo certo, basta exibir na tela
[*:3cf642b611]se estiver nulo, o produto EXISTE mas não há associação com a filial. basta fazer a associação.
[/list:u:3cf642b611]

ajudei ou compliquei?


GOSTEI 0
Mmoreira

Mmoreira

09/02/2007

Emerson,
As idéias já começaram a clarear aqui na cabeça.
No meu caso eu trabalho com os controles DataWare então ao fazer uma consulta para abrir meu CdsProduto caso a consulta me retorne algum registro eu teria que abrir meu CdsProduto_Filial no braço? Ou será que existe alguma outra maneira de fazer isso?
Mas minha maior duvida é na hora de cadastrar um novo produto que ainda não tenha registro na tabela PRODUTO

Se for assim no braço como estou imaginando seria mais ou menos assim então:

CADASTRAR NOVO PRODUTO (Supondo que o mesmo não existe em Filial alguma)

No click do botão novo eu:

1 – Fecharia o CdsProduto
2 – Fecharia o CdsProduto_Filial (Que no caso não teria amarração nenhuma do tipo Mestre/Detalhe)
3 – Código do botão Novo:
CdsProduto.Close;
CdsProduto.Params[0].AsInteger := -1;
CdsProduto.Open;
CdsProduto.Append;
CdsProdutoID_PRODUTO := Função_Retorna_Id_Produto;


// Aqui eu já poderia fazer o mesmo para o CdsProduto_Filial ???
CdsProduto_Filial.Close;
CdsProduto_Filial.Params[0].AsInteger := -1;
CdsProduto_Filial.Params[1].AsInteger := -1;
CdsProduto_Filial.Open;
CdsProduto_Filial.Append;
CdsProduto_FilialID_PRODUDUTO := CdsProdutoID_PRODUTO;
CdsProduto_FilialID_FILIAL := FrmPrincipal.ID_FILIAL;


Depois quando fosse salvar ou cancelar a operação teria que aplicar a mesma regra para os dois ClientDataSet.

Seria isso ou estou no caminho errado?


GOSTEI 0
Emerson Nascimento

Emerson Nascimento

09/02/2007

na verdade eu não trabalho com relacionamento do tipo mestre/detalhe. eu trabalho com aninhamento de datasets (estou tentando terminar um artigo sobre isso para publicar, mas não encontro tempo :( ), o que torna esse tipo de solução muito mais fácil de implementar.

mas vamos à sua questão...

se o método [i:550e4bae4f]Função_Retorna_Id_Produto[/i:550e4bae4f] já retornar o ID final do produto, o que você sugeriu está correto.

se não, para gravar o PRODUTO_FILIAL, você precisará trabalhar com a informação retornada pelo banco após o ApplyUpdates da tabela PRODUTO. para isso você terá de recorrer ao método BeforeUpdateRecord do dataset.


GOSTEI 0
Mmoreira

Mmoreira

09/02/2007

Emerson,

No caso sim o meu metodo:

Função_Retorna_Id_Produto

Faz um incremento no Generator da tabela PRODUTO e me retorna este novo ID_PRODUTO

Bom acho que vou seguir esta linha de raciocinio para terminar este cadastro.

Mais uma vez muito obrigado pela ajuda e vou ficar no aguardo do seu artigo pois nao tenho conhecimento desta técnica que voce falou.

Um abraço.


GOSTEI 0
POSTAR