Autor Tópico: Atualizar valores de tabelas pai x filho  (Lida 4902 vezes)

thiago.reis

  • Novato
  • *
  • Mensagens: 30
    • Email
Re:Atualizar valores de tabelas pai x filho
« Responder #30 Online: Janeiro 24, 2014, 08:05:38 pm »
Mas é possivel fazer os calculos na consulta?

Eu pensei que o SC tinha alguma opção nativa pra facilitar esse tipo de operação

Meus sinceros agradecimentos.

Haroldo

  • Expert
  • *****
  • Mensagens: 6293
  • Conhecimento diminui limitações.△TFA△
    • Infinitus Web Gestão Empresarial/Gestão ITIL/Consultoria Scriptcase
Re:Atualizar valores de tabelas pai x filho (EXEMPLO FUNCIONAL PARTE 1)
« Responder #31 Online: Janeiro 25, 2014, 11:52:49 pm »
Como prometido, segue exemplo completo e funcional explicando a praticidade e segurança das triggers.

PARTE 1 : MODELAGEM

CREATE DATABASE  IF NOT EXISTS `treino` /*!40100 DEFAULT CHARACTER SET utf8 */;
USE `treino`;
-- MySQL dump 10.13  Distrib 5.6.13, for Win32 (x86)
--
-- Host: 192.168.25.7    Database: treino
-- ------------------------------------------------------
-- Server version   5.1.61

/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;

--
-- Table structure for table `mat_prima`
--

DROP TABLE IF EXISTS `mat_prima`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `mat_prima` (
  `id_materia_prima` int(11) NOT NULL AUTO_INCREMENT,
  `desc_materia_prima` varchar(100) DEFAULT NULL,
  `genero_materia_prima` varchar(45) DEFAULT NULL,
  `preco_compra_mp` decimal(10,3) DEFAULT NULL,
  `icms_mp` decimal(10,2) DEFAULT NULL,
  `pis_mp` decimal(10,2) DEFAULT NULL,
  `cofins_mp` decimal(10,2) DEFAULT NULL,
  `ipi_mp` decimal(10,2) DEFAULT NULL,
  `ii_mp` decimal(10,2) DEFAULT NULL,
  `frete_mp` decimal(10,2) DEFAULT NULL,
  `comissao_mp` decimal(10,2) DEFAULT NULL,
  `preco_final_mp` decimal(10,3) DEFAULT NULL,
  PRIMARY KEY (`id_materia_prima`)
) ENGINE=MyISAM AUTO_INCREMENT=10 DEFAULT CHARSET=utf8;

/*!50003 SET sql_mode              = @saved_sql_mode */ ;
/*!50003 SET character_set_client  = @saved_cs_client */ ;
/*!50003 SET character_set_results = @saved_cs_results */ ;
/*!50003 SET collation_connection  = @saved_col_connection */ ;
/*!50003 SET @saved_cs_client      = @@character_set_client */ ;
/*!50003 SET @saved_cs_results     = @@character_set_results */ ;
/*!50003 SET @saved_col_connection = @@collation_connection */ ;
/*!50003 SET character_set_client  = utf8 */ ;
/*!50003 SET character_set_results = utf8 */ ;
/*!50003 SET collation_connection  = utf8_general_ci */ ;
/*!50003 SET @saved_sql_mode       = @@sql_mode */ ;
/*!50003 SET sql_mode              = '' */ ;
DELIMITER ;;
/*!50003 CREATE*/ /*!50017 DEFINER=`root`@`%`*/ /*!50003 TRIGGER `mat_prima_AUPD` AFTER UPDATE ON `mat_prima` FOR EACH ROW
begin
   UPDATE prod_matprima SET total_pf=per_pf*NEW.preco_final_mp WHERE id_mat_prima=NEW.id_materia_prima;
END */;;
DELIMITER ;
/*!50003 SET sql_mode              = @saved_sql_mode */ ;
/*!50003 SET character_set_client  = @saved_cs_client */ ;
/*!50003 SET character_set_results = @saved_cs_results */ ;
/*!50003 SET collation_connection  = @saved_col_connection */ ;

--
-- Table structure for table `prod_acabado`
--

DROP TABLE IF EXISTS `prod_acabado`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `prod_acabado` (
  `id_produto_final` int(11) NOT NULL AUTO_INCREMENT,
  `desc_pf` varchar(60) DEFAULT NULL,
  `genero_pf` varchar(45) DEFAULT NULL,
  `custo_total_pf` decimal(10,2) DEFAULT NULL,
  PRIMARY KEY (`id_produto_final`)
) ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;

--
-- Table structure for table `prod_matprima`
--

DROP TABLE IF EXISTS `prod_matprima`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `prod_matprima` (
  `id_prod_acabado` int(11) NOT NULL,
  `id_mat_prima` varchar(45) NOT NULL,
  `per_pf` decimal(10,4) DEFAULT NULL,
  `total_pf` decimal(10,2) DEFAULT NULL,
  PRIMARY KEY (`id_prod_acabado`,`id_mat_prima`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
/*!50003 SET @saved_cs_client      = @@character_set_client */ ;
/*!50003 SET @saved_cs_results     = @@character_set_results */ ;
/*!50003 SET @saved_col_connection = @@collation_connection */ ;
/*!50003 SET character_set_client  = utf8 */ ;
/*!50003 SET character_set_results = utf8 */ ;
/*!50003 SET collation_connection  = utf8_general_ci */ ;
/*!50003 SET @saved_sql_mode       = @@sql_mode */ ;
/*!50003 SET sql_mode              = '' */ ;
DELIMITER ;;
/*!50003 CREATE*/ /*!50017 DEFINER=`root`@`%`*/ /*!50003 TRIGGER `prod_matprima_AINS` AFTER INSERT ON `prod_matprima` FOR EACH ROW
begin
 UPDATE prod_acabado
   SET custo_total_pf=
      (SELECT SUM(total_pf)
      FROM prod_matprima
      WHERE id_prod_acabado=NEW.id_prod_acabado)
   WHERE id_produto_final=NEW.id_prod_acabado;
end */;;
DELIMITER ;
/*!50003 SET sql_mode              = @saved_sql_mode */ ;
/*!50003 SET character_set_client  = @saved_cs_client */ ;
/*!50003 SET character_set_results = @saved_cs_results */ ;
/*!50003 SET collation_connection  = @saved_col_connection */ ;
/*!50003 SET @saved_cs_client      = @@character_set_client */ ;
/*!50003 SET @saved_cs_results     = @@character_set_results */ ;
/*!50003 SET @saved_col_connection = @@collation_connection */ ;
/*!50003 SET character_set_client  = utf8 */ ;
/*!50003 SET character_set_results = utf8 */ ;
/*!50003 SET collation_connection  = utf8_general_ci */ ;
/*!50003 SET @saved_sql_mode       = @@sql_mode */ ;
/*!50003 SET sql_mode              = '' */ ;
DELIMITER ;;
/*!50003 CREATE*/ /*!50017 DEFINER=`root`@`%`*/ /*!50003 TRIGGER `prod_matprima_AUPD` AFTER UPDATE ON `prod_matprima` FOR EACH ROW
begin
 UPDATE prod_acabado
   SET custo_total_pf=
      (SELECT SUM(total_pf)
      FROM prod_matprima
      WHERE id_prod_acabado=NEW.id_prod_acabado)
   WHERE id_produto_final=NEW.id_prod_acabado;
end */;;
DELIMITER ;
/*!50003 SET sql_mode              = @saved_sql_mode */ ;
/*!50003 SET character_set_client  = @saved_cs_client */ ;
/*!50003 SET character_set_results = @saved_cs_results */ ;
/*!50003 SET collation_connection  = @saved_col_connection */ ;
/*!50003 SET @saved_cs_client      = @@character_set_client */ ;
/*!50003 SET @saved_cs_results     = @@character_set_results */ ;
/*!50003 SET @saved_col_connection = @@collation_connection */ ;
/*!50003 SET character_set_client  = utf8 */ ;
/*!50003 SET character_set_results = utf8 */ ;
/*!50003 SET collation_connection  = utf8_general_ci */ ;
/*!50003 SET @saved_sql_mode       = @@sql_mode */ ;
/*!50003 SET sql_mode              = '' */ ;
DELIMITER ;;
/*!50003 CREATE*/ /*!50017 DEFINER=`root`@`%`*/ /*!50003 TRIGGER `prod_matprima_ADEL` AFTER DELETE ON `prod_matprima` FOR EACH ROW
begin
 UPDATE prod_acabado
   SET custo_total_pf=
      (SELECT SUM(total_pf)
      FROM prod_matprima
      WHERE id_prod_acabado=OLD.id_prod_acabado)
   WHERE id_produto_final=OLD.id_prod_acabado;
end */;;
DELIMITER ;
/*!50003 SET sql_mode              = @saved_sql_mode */ ;
/*!50003 SET character_set_client  = @saved_cs_client */ ;
/*!50003 SET character_set_results = @saved_cs_results */ ;
/*!50003 SET collation_connection  = @saved_col_connection */ ;

--
-- Dumping events for database 'treino'
--

--
-- Dumping routines for database 'treino'
--
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;

/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;

-- Dump completed on 2014-01-26  0:37:51
« Última modificação: Janeiro 26, 2014, 10:10:42 am por Haroldo »

Haroldo

  • Expert
  • *****
  • Mensagens: 6293
  • Conhecimento diminui limitações.△TFA△
    • Infinitus Web Gestão Empresarial/Gestão ITIL/Consultoria Scriptcase
Re:Atualizar valores de tabelas pai x filho (EXEMPLO FUNCIONAL PARTE 2)
« Responder #32 Online: Janeiro 26, 2014, 12:04:15 am »
Para Download das aplicações (Importe como aplicações em um projeto já existente):

http://iw.servehttp.com:86/ftp/sc_201401260043_bkp_Treino.zip


* Nota: O dwnload do exemplo não estará disponível por muito tempo.


Acessando o exemplo:

http://iw.servehttp.com:86/sc/7.1/app/Treino/form_prod_acabado

Tela do exemplo:

« Última modificação: Janeiro 26, 2014, 10:44:34 am por Haroldo »

Haroldo

  • Expert
  • *****
  • Mensagens: 6293
  • Conhecimento diminui limitações.△TFA△
    • Infinitus Web Gestão Empresarial/Gestão ITIL/Consultoria Scriptcase
Re:Atualizar valores de tabelas pai x filho (EXEMPLO FUNCIONAL PARTE 3)
« Responder #33 Online: Janeiro 26, 2014, 12:32:25 am »
Explicação:


Triggers:

Tabela prod_matprima (tabela de ligação das matérias primas ao produto).
Gatilho 1:
Após Inserir, alterar  ou excluir é executado um update em produtos baseado em um select sum em todas as matérias primas relacionadas a esse produto.

Tabela materia_prima
Gatilho 2:
Após alterar é executado um update em prod_matprima de todos registros relacionados a essa matéria prima recalculando  o custo_total. O update em prod_matprima aciona o gatilho 1 que por sua vez atualiza o custo final do produto. (Encadeamento de gatilhos).


Aplicação  form_mat_prima

Evento Onvalidate:
- Verifica se for deleção e se a matéria prima está em uso, não permite excluir.


Aplicação form_produto_acabado (Mestre/Detalhe):
Possui um detalhe apontando para form_prod_matprima utilizando o id do produto como referência de filtro de registros para o detalhe.

Aplicação form_prod_matprima (Detalhe do cadastro de produtos):
Evento Ajax no campo quantidade:
- Busca o custo da matéria prima para sua unidade padrão e calcula pela quantidade o  custo de utilização dessa matéria no produto corrente.

Método PHP AtualizaProduto:
-Busca o custo final do produto e apresenta na janela relacionada do formulário mestre.

Evento OnLoadRecord:
-Executa AtualizaProduto quando da inserção ou alteração da linha detalhe.

Evento OnAfterDelete:
- Executa AtualizaProduto quando da deleção da linha detalhe

O exemplo levou 1,5 horas para ser confeccionado,  e demonstra como eh simples e prático usar triggers num processo de atualizações que são disparados automaticamente,  ganhando performance no processo, pois as atualizações são disparadas pelo próprio banco de dados, não trafegando dados entre o php e o banco, ganha-se  segurança e integridade das informações, facilita manutenção e pode-se aplicar outras plataformas (tipo apps mobile) que os procedimentos serão os mesmos ganhando reprogramação.

O Exemplo é uma demonstração e não sei se vai ser utilizado exatamente como está para atender ao nosso colega criador desse tópico, pois houve dúvidas quanto a estrutura de dados, cálculos a executar e na imagem da tela postada aqui, mas acredito que estudando o exemplo facilmente chegará ao resultado esperado quando aplicar o conceito em seu projeto.

***Nota:  O custo do produto que usei como exemplo, foi calculado em cima das matérias primas cujos os preços e unidades de medição foram pesquisados no site do Pão de Açúcar, e representa o custo real aproximado para confecção de um BOLO DE CENOURA.

Links de Ajuda

http://www.tudogostoso.com.br/receita/23-bolo-de-cenoura.html

http://www.paodeacucar.com.br/

http://pt.wikipedia.org/wiki/Pesos_e_medidas_culin%C3%A1rias
« Última modificação: Janeiro 26, 2014, 10:08:31 am por Haroldo »

thiago.reis

  • Novato
  • *
  • Mensagens: 30
    • Email
Re:Atualizar valores de tabelas pai x filho
« Responder #34 Online: Janeiro 27, 2014, 11:00:53 am »
Haroldo,  primeiramente agradeço a sua ajuda!  Ficou muito bom seu exemplo.

Realmente é isso que estou precisando...  já estou modificando algumas coisas a partir do seu modelo para incluir em meu projeto.

Só peço por gentileza aos moderadores para não fechar o tópico, eu vou fazer os testes e retorno o mais breve possível.


Novamente agradeço.

Haroldo

  • Expert
  • *****
  • Mensagens: 6293
  • Conhecimento diminui limitações.△TFA△
    • Infinitus Web Gestão Empresarial/Gestão ITIL/Consultoria Scriptcase
Re:Atualizar valores de tabelas pai x filho
« Responder #35 Online: Janeiro 27, 2014, 04:19:48 pm »
Não se preocupe, um tópico nunca eh fechado aqui. O que pedimos e que retorne com sua experiência quanto a solução aplicada e se seu problema foi resolvido.


thiago.reis

  • Novato
  • *
  • Mensagens: 30
    • Email
Re:Atualizar valores de tabelas pai x filho
« Responder #36 Online: Janeiro 28, 2014, 01:20:03 pm »
Haroldo.

Fiz as adaptações para o meu projeto... e esta funcionando parcialmente.

Estou com problema na Trigger da matéria prima, ao ser acionada ela altera o valor final dos produtos acabados, deixando todos com os mesmos valores...

Eu segui a risca suas dicas, ontem e hoje, já tentei de tudo antes de recorrer a ti.... mas não estou conseguindo... fazer isso funcionar...
o restante esta tudo ok....

Por favor, me ajude



Trigger para atualizar materias primas

UPDATE prod_mat
SET total_pf=per_pf*NEW.preco_final_mp
WHERE id_mat_prima=NEW.id_materia_prima



Gratidão!


Haroldo

  • Expert
  • *****
  • Mensagens: 6293
  • Conhecimento diminui limitações.△TFA△
    • Infinitus Web Gestão Empresarial/Gestão ITIL/Consultoria Scriptcase
Re:Atualizar valores de tabelas pai x filho
« Responder #37 Online: Janeiro 28, 2014, 02:48:30 pm »
Qual o nome da coluna id da tabela materia_prima?

thiago.reis

  • Novato
  • *
  • Mensagens: 30
    • Email
Re:Atualizar valores de tabelas pai x filho
« Responder #38 Online: Janeiro 28, 2014, 03:04:52 pm »
id_materia_prima




Haroldo

  • Expert
  • *****
  • Mensagens: 6293
  • Conhecimento diminui limitações.△TFA△
    • Infinitus Web Gestão Empresarial/Gestão ITIL/Consultoria Scriptcase
Re:Atualizar valores de tabelas pai x filho
« Responder #39 Online: Janeiro 28, 2014, 03:13:38 pm »
Se fez como demonstrei no exemplo tem que funcionar igual.

Você deve ter feito algo diferente.

thiago.reis

  • Novato
  • *
  • Mensagens: 30
    • Email
Re:Atualizar valores de tabelas pai x filho
« Responder #40 Online: Janeiro 28, 2014, 03:20:03 pm »
Eu já revisei o projeto diversas vezes esta do mesmo modo que voce ensinou...

O problema esta mesmo na Trigger da Materia Prima   ele atualiza todos os produtos mas com o mesmo preço.

As demais Triggers funcionam normalmente.

Bom vou da um tempo...  e vou tentar refazer tudo pra ver se acerto.

Agradeço!

Haroldo

  • Expert
  • *****
  • Mensagens: 6293
  • Conhecimento diminui limitações.△TFA△
    • Infinitus Web Gestão Empresarial/Gestão ITIL/Consultoria Scriptcase
Re:Atualizar valores de tabelas pai x filho
« Responder #41 Online: Janeiro 28, 2014, 03:29:41 pm »
Al alterar um registro de matéria prima, esta aciona a trigger after update que por si recalcula (faz update) em todos os registos cujo oid seja dessa materia prima em prod_mat,

Alterar materia prima não executa update em produto.

Reveja a trigger after update em prod_mat eh essa que executa a alteração nos produtos.

thiago.reis

  • Novato
  • *
  • Mensagens: 30
    • Email
Re:Atualizar valores de tabelas pai x filho
« Responder #42 Online: Janeiro 29, 2014, 03:22:31 pm »
Haroldo.

Meus sinceros agradecimentos.

Agora esta funcionando ok.... realmente o problema era na Trigger After Update ( tabela: mat_prod )


Surgiu uma duvida em relação a tela de cadastro de produto acabado, por favor preciso de mais uma ajuda....


Ao cadastrar um produto acabado, esse produto vai em uma determinada embalagem.  (1 para muitos)


Eu fiz o cadastro de embalagem do modo que você me ensinou aqui, pois cada embalagem esta vinculada a N matérias primas...
esta funcionando perfeitamente.


Minha duvida é a seguinte.

Na tela de cadastro de produto acabado, eu fiz um mestre / detalhe para as embalagens....

Pergunta: É possível retornar as embalagens cadastradas com checkbox?     
Ao selecionar uma embalagem, o sistema deve fazer o seguinte calculo automatico, semelhante a Trigger   materia prima....

custo_total_produto_acabado * volume_da_embalagem + preco_embalagem_selecionada



Caso ajude segue imagem.

Antes: http://lucheti.com.br/cadastro_pf_01.jpg
(feito através de iframe , porem era necessario clicar em calcular)

Depois: http://lucheti.com.br/cadastro_pf_02.jpg


Devo um favor a ti!

Gratidão.
« Última modificação: Janeiro 29, 2014, 04:00:58 pm por thiago.reis »

Haroldo

  • Expert
  • *****
  • Mensagens: 6293
  • Conhecimento diminui limitações.△TFA△
    • Infinitus Web Gestão Empresarial/Gestão ITIL/Consultoria Scriptcase
Re:Atualizar valores de tabelas pai x filho
« Responder #43 Online: Janeiro 29, 2014, 04:24:04 pm »
AI tem que mexer novamente na modelagem.
em produtos acabados você deve ter:

custo_total_materias_primas (esse será o calculados pelas triggers)

Se for apenas uma embalagem por produto:

criar id_embalagem na tabela de produtos.

Na app form de produtos, criar um checkbox para o campo id_embalagem e em lookup automatico jogar o select.

criar campo custo_final_produto.

em onbeforeinsert e update, fazer sc_lookup e pegar o vaor da embalagem e somar calcular custo_final_produto = custo_total_materias_primas + custo_embalagem.

criar trigger para embalagens, quando alterar produto fazer update em produto baseado no calculo anterior.

nas triigger prod_mat prever o calculo anterior.

você aprendendo o conceito das triggers conseguirá ir em frente.

thiago.reis

  • Novato
  • *
  • Mensagens: 30
    • Email
Re:Atualizar valores de tabelas pai x filho
« Responder #44 Online: Janeiro 29, 2014, 04:38:12 pm »
Haroldo.

Eu entendi parcialmente a sua solução....  só não ficou claro como vou salvar o valor de cada embalagem selecionada?

Na imagem abaixo, eu fiz um select e a cada linha o código criava um campo de texto dinamicamente...
http://lucheti.com.br/cadastro_pf_01.jpg

São N embalagens para 1 produto.

No caso eu devo criar um id_embalagem na tabela PRODUTOS  e também o campo custo_embalagem  (para salvar o valor) ?

« Última modificação: Janeiro 29, 2014, 04:42:05 pm por thiago.reis »