Relatório Complexo

Grupo sobre o desenvolvimento/extensão das funcionalidades do Compiere / Adempiere onde é necessário alterar o código fonte.
fgiordani
Mensagens: 9
Registrado em: Seg Jun 23, 2008 9:22 pm

Relatório Complexo

Mensagempor fgiordani » Seg Nov 17, 2008 11:35 pm

boa noite,

Tenho um relatório bastante complexo o qual precisa de consulta em várias tabelas e processamento dos dados.
Vi que para exibir o relatorio tenho algumas regras e alternativas:
-Precisarei de uma tabela com os dados.
-Posso ter uma view mais ela não seria suficiente para mim.
-Pensei em uma tabela temporaria armazenando os dados do relatório, mais como ficaria acessos simultaneos ao relatório? Tem que excluir os dados?

Numa aplicação fora do Adempiere eu criaria um DTO com os atributos que vou exibir no relatório e enviaria uma coleção desse para o jasper processar sem ter essa coleção no banco.
Qual a melhor maneira de fazer isso no Adempiere?

amontenegro
Mensagens: 7
Registrado em: Ter Nov 21, 2006 3:33 pm
Contato:

Re: Relatório Complexo

Mensagempor amontenegro » Ter Nov 18, 2008 3:01 pm

fgiordani,

Para fazer isso no ADempiere eu vejo duas alternativas.

1 - Usar uma stored procedure que faça todo o seu processamento e te retorne uma tabela da forma que você quer.

2 - Usar um processo Java mesmo, que faz o que você precisa com os dados, e após isso, joga em uma tabela temporária estes dados e mostra para o usuário.

Na segunda alternativa, você precisa pensar em uma solução para apagar estes dados temporários.

Uma das alternativas é tentar deixar uma coluna com um nome de uma Transaction que você pode criar usando as classes do próprio ADempiere, vc guarda só o nome delas em 1 das colunas, isso deve tornar os dados únicos e se outro usuário tentar entrar ao mesmo tempo, não vai ter problema.

Lembrando que a transaction foi só uma idéia de como gerar uma identificação única para cada vez que roda o relatório, tem que fechar elas.

Também creio que você pode também utilizar o seu approach do DTO, basta utilizar o processo customizado e jogar diretamente ao Jasper que está integrado ao ADempiere.

Depois se vc puder colocar um post sobre a saída que você utilizou, é um problema interessante!

Abraços.

mgrigioni
Mensagens: 483
Registrado em: Sex Jan 05, 2007 3:08 pm
Localização: Jacareí/SP

Re: Relatório Complexo

Mensagempor mgrigioni » Ter Nov 18, 2008 3:57 pm

Alvaro, na solução 2, não precisa criar uma coluna com o nome da transaction.

Basta apenas em seu código, sempre utilizar transaction no sql.

Pois se dois usuários usarem o mesmo relatório, não tem problemas, pois são transactions diferentes.

fgiordani
Mensagens: 9
Registrado em: Seg Jun 23, 2008 9:22 pm

Re: Relatório Complexo

Mensagempor fgiordani » Qua Nov 19, 2008 12:50 pm

ola amontenegro,

2 - Usar um processo Java mesmo, que faz o que você precisa com os dados, e após isso, joga em uma tabela temporária estes dados e mostra para o usuário.

Na segunda alternativa, você precisa pensar em uma solução para apagar estes dados temporários.

Uma das alternativas é tentar deixar uma coluna com um nome de uma Transaction que você pode criar usando as classes do próprio ADempiere, vc guarda só o nome delas em 1 das colunas, isso deve tornar os dados únicos e se outro usuário tentar entrar ao mesmo tempo, não vai ter problema.

Lembrando que a transaction foi só uma idéia de como gerar uma identificação única para cada vez que roda o relatório, tem que fechar elas.


Primeiramete fiz um processo java com uma tabela temporária e funcionou.
Para a tabela temporária ( T_* ) é obrigatório ter um atributo AD_PInstance_ID o qual criei com base na clase MTReport da seguinte forma:

Código: Selecionar todos

   private I_AD_PInstance getAD_PInstance() throws Exception {
      if (instance == null) {
         Class<?> clazz = MTable.getClass(I_AD_PInstance.Table_Name);
         try {
            Constructor<?> constructor = null;
            constructor = clazz.getDeclaredConstructor(new Class[] { Properties.class, int.class, String.class });
            instance  = (I_AD_PInstance) constructor.newInstance(new Object[] { getCtx(), new Integer(getAD_PInstance_ID()), get_TrxName() });
         } catch (Exception e) {
            log.log(Level.SEVERE, "(id) - Table=" + MTTRPlanoManutencao.Table_Name + ",Class=" + clazz, e);
            log.saveError("Error", "Table=" + MTTRPlanoManutencao.Table_Name + ",Class=" + clazz);
            throw e;
         }
      }
      return instance ;
   }


Dessa forma atribui o código da instancia para cada registro da tabela temporária.
Depois de processar a classe é montada a query para a tabela temporária. O Adempiere adiciona automaticamente no where o código da instancia criada (Ainda tenho que ver como ele faz no código fonte).
Obs.: Não achei muitas referências sobre como funciona ou como deveria ser aplicada essa tabela (AD_PInstance) a não ser o que vi no código fonte, mas funcionou.

O problema é que o mesmo parâmetro que passo para o processo para montar a tabela temporária é aplicado a consulta e nao atende ao meu requisito. Quero que tudo o que foi criado seja retornado sem aplicar critério algum.

1 - Usar uma stored procedure que faça todo o seu processamento e te retorne uma tabela da forma que você quer.

Seria minha segunda alternativa, e inicialmente achei que funcionasse da seguinte forma:

Código: Selecionar todos

  CallableStatement cs = con.prepareCall("{funcao_procedure}"); 
  ResultSet rs = cs.executeQuery(); 


,mais ele apenas executa sem pegar o retorno, e dessa forma não vai funcionar ja só vai mudar a maneira de montar a tabela temporaria e o critério que mencionei anteriormente continuaria sendo adicionado ao where.
Obs.: Com a procedure tbem da para utilizar o recurso da tabela AD_PInstance.

Também creio que você pode também utilizar o seu approach do DTO, basta utilizar o processo customizado e jogar diretamente ao Jasper que está integrado ao ADempiere.

Por fim acho que essa é a minha solução, mais não estou achando documentação.
Qual seria o procedimento para fazer esse processo? (Criar processo/relatorio, criar classe com implementacao especifica, estender alguma classe, ....)

Agradeço sua atenção

ArthurMelo
Mensagens: 13
Registrado em: Qui Mar 01, 2012 3:36 am

Re: Relatório Complexo

Mensagempor ArthurMelo » Sex Out 19, 2012 8:18 am

fgiordani escreveu:ola amontenegro,

2 - Usar um processo Java mesmo, que faz o que você precisa com os dados, e após isso, joga em uma tabela temporária estes dados e mostra para o usuário.

Na segunda alternativa, você precisa pensar em uma solução para apagar estes dados temporários.

Uma das alternativas é tentar deixar uma coluna com um nome de uma Transaction que você pode criar usando as classes do próprio ADempiere, vc guarda só o nome delas em 1 das colunas, isso deve tornar os dados únicos e se outro usuário tentar entrar ao mesmo tempo, não vai ter problema.

Lembrando que a transaction foi só uma idéia de como gerar uma identificação única para cada vez que roda o relatório, tem que fechar elas.


Primeiramete fiz um processo java com uma tabela temporária e funcionou.
Para a tabela temporária ( T_* ) é obrigatório ter um atributo AD_PInstance_ID o qual criei com base na clase MTReport da seguinte forma:

Código: Selecionar todos

   private I_AD_PInstance getAD_PInstance() throws Exception {
      if (instance == null) {
         Class<?> clazz = MTable.getClass(I_AD_PInstance.Table_Name);
         try {
            Constructor<?> constructor = null;
            constructor = clazz.getDeclaredConstructor(new Class[] { Properties.class, int.class, String.class });
            instance  = (I_AD_PInstance) constructor.newInstance(new Object[] { getCtx(), new Integer(getAD_PInstance_ID()), get_TrxName() });
         } catch (Exception e) {
            log.log(Level.SEVERE, "(id) - Table=" + MTTRPlanoManutencao.Table_Name + ",Class=" + clazz, e);
            log.saveError("Error", "Table=" + MTTRPlanoManutencao.Table_Name + ",Class=" + clazz);
            throw e;
         }
      }
      return instance ;
   }


Dessa forma atribui o código da instancia para cada registro da tabela temporária.
Depois de processar a classe é montada a query para a tabela temporária. O Adempiere adiciona automaticamente no where o código da instancia criada (Ainda tenho que ver como ele faz no código fonte).
Obs.: Não achei muitas referências sobre como funciona ou como deveria ser aplicada essa tabela (AD_PInstance) a não ser o que vi no código fonte, mas funcionou.

O problema é que o mesmo parâmetro que passo para o processo para montar a tabela temporária é aplicado a consulta e nao atende ao meu requisito. Quero que tudo o que foi criado seja retornado sem aplicar critério algum.

1 - Usar uma stored procedure que faça todo o seu processamento e te retorne uma tabela da forma que você quer.



Bom dia pessoal.
Este topico obteve alguma solucao ?
estou com o mesmo problema
Att,

Arthur Oliveira de Melo
Engenheiro de Software
Sistema de Gestão de Recursos – ADP
aomelo@live.com
(62) 85630555


Voltar para “Desenvolvimento - Java”

Quem está online

Usuários neste fórum: Nenhum usuário registrado e 1 visitante