View Javadoc

1   /*
2    * Created on 29/10/2004
3    */
4   package ecar.dao;
5   
6   import java.io.BufferedReader;
7   import java.io.File;
8   import java.io.FileOutputStream;
9   import java.io.FileReader;
10  import java.math.BigDecimal;
11  import java.text.DecimalFormat;
12  import java.text.SimpleDateFormat;
13  import java.util.ArrayList;
14  import java.util.Date;
15  import java.util.Iterator;
16  import java.util.List;
17  
18  import javax.servlet.http.HttpServletRequest;
19  
20  import org.apache.log4j.Logger;
21  import org.hibernate.HibernateException;
22  import org.hibernate.Query;
23  import org.hibernate.Transaction;
24  
25  import comum.database.Dao;
26  import comum.util.Data;
27  import comum.util.Util;
28  
29  import ecar.enumerator.TipoOcorrencia;
30  import ecar.exception.ECARException;
31  import ecar.login.SegurancaECAR;
32  import ecar.pojo.ConfigExecFinanCef;
33  import ecar.pojo.ConfigSisExecFinanCsef;
34  import ecar.pojo.ConfigSisExecFinanCsefv;
35  import ecar.pojo.ConfiguracaoCfg;
36  import ecar.pojo.EfIettFonteTotEfieft;
37  import ecar.pojo.EfIettFonteTotEfieftPK;
38  import ecar.pojo.EfImportOcorrenciasEfio;
39  import ecar.pojo.EfItemEstContaEfiec;
40  import ecar.pojo.EfItemEstPrevisaoEfiep;
41  import ecar.pojo.EfItemEstPrevisaoEfiepPK;
42  import ecar.pojo.EfItemEstRealizadoEfier;
43  import ecar.pojo.EspecieEsp;
44  import ecar.pojo.ExercicioExe;
45  import ecar.pojo.FonteFon;
46  import ecar.pojo.FonteRecursoFonr;
47  import ecar.pojo.ImportacaoImp;
48  import ecar.pojo.ItemEstruturaIett;
49  import ecar.pojo.RecursoRec;
50  import ecar.pojo.UsuarioUsu;
51  import ecar.util.Dominios;
52  
53  /**
54   * @author evandro, aleixo
55   */
56  public class ConfigSisExecFinanDao extends Dao {
57  
58    private static final int TAMANHO_CONTA_CONTABIL = 255;
59    private static final int TAMANHO_SIGLA_SISTEMA = 6;
60    private static final int TAMANHO_VALORES = 14;
61    private static final int TAMANHO_QTDE_REGISTROS = 6;
62    private static final String TR_HEADER = "00";
63    private static final String TR_REGISTRO = "01";
64    private static final String TR_REGISTRO_NAO_REVISTO = "02";
65    private static final String TR_TRAILER = "99";
66    private static final String FORMATO_DATAHORA = "ddMMyyyyHHmmss";
67    private static final int TAMANHO_DATAHORA = 14;
68  
69    /**
70     * Construtor. Chama o Session factory do Hibernate
71     */
72    public ConfigSisExecFinanDao(HttpServletRequest request) {
73      super();
74      this.request = request;
75    }
76  
77    /**
78     * Retorna uma lista dos sistemas cadastrados em ConfigSisExecFinanCsef que
79     * são ativos e possuem versão.
80     * @return List
81     * @throws ECARException
82     */
83    public List getSistemasAtivos() throws ECARException {
84      ConfigSisExecFinanCsefvDao versaoDao = new ConfigSisExecFinanCsefvDao(null);
85  
86      List retorno = new ArrayList();
87  
88      List versoes = versaoDao.getCsefvOrderBySistema();
89  
90      if (versoes != null && !versoes.isEmpty()) {
91        Iterator itVersoes = versoes.iterator();
92        while (itVersoes.hasNext()) {
93          ConfigSisExecFinanCsefv versao = (ConfigSisExecFinanCsefv) itVersoes.next();
94  
95          if (!retorno.contains(versao.getConfigSisExecFinanCsef())) {
96            retorno.add(versao.getConfigSisExecFinanCsef());
97          }
98        }
99      }
100 
101     return retorno;
102   }
103 
104   /**
105    * Gera o arquivo de exportação para integração financeira
106    * @param nomeArquivo
107    * @param codSistema
108    * @param mesAnoIni
109    * @param mesAnoFim
110    * @param configuracao
111    * @return String[]: posicao 0 --> caminho do arquivo gravado no servidor
112    *         posicao 1 --> nome do arquivo gerado
113    * @throws ECARException
114    */
115   public String[] gerarArquivoExportacaoTxt(String nomeArquivo, String codSistema, String mesAnoIni, String mesAnoFim, ConfiguracaoCfg configuracao) throws ECARException {
116     ItemEstruturaContaOrcamentoDao itemEstContaDao = new ItemEstruturaContaOrcamentoDao(null);
117     // nomeArquivo = Util.trocarEspacoPorCaracter(nomeArquivo, "_");
118     String caminho = configuracao.getRaizUpload() + configuracao.getUploadIntegracao();
119 
120     if (!caminho.endsWith("/"))
121       caminho = caminho + "/";
122 
123     String caminhoCompleto = "";
124     try {
125       String formato = "ddMMyyyyHHmmssSSS";
126       SimpleDateFormat formatter = new SimpleDateFormat(formato);
127       ConfigSisExecFinanCsef sistema = (ConfigSisExecFinanCsef) this.buscar(ConfigSisExecFinanCsef.class, Long.valueOf(codSistema));
128 
129       nomeArquivo += "_" + sistema.getSiglaCsef() + "_" + formatter.format(new Date()) + "_export.txt";
130       caminhoCompleto = caminho + nomeArquivo;
131 
132       File diretorio = new File(caminho);
133 
134       if (!diretorio.isDirectory())
135         diretorio.mkdirs();
136 
137       FileOutputStream arquivo = new FileOutputStream(caminhoCompleto);
138 
139       String siglaSistema = sistema.getSiglaCsef();
140       int tam = siglaSistema.length();
141       for (int i = tam; i < TAMANHO_SIGLA_SISTEMA; i++) {
142         siglaSistema += " ";
143       }
144       String maIni[] = mesAnoIni.split("/");
145       String maFim[] = mesAnoFim.split("/");
146       String dataHoraGeracao = (new SimpleDateFormat(FORMATO_DATAHORA)).format(new Date());
147 
148       /* Gravar o HEADER - TR00 - no arquivo */
149       String header = TR_HEADER + siglaSistema + maIni[0] + maIni[1] + maFim[0] + maFim[1] + dataHoraGeracao + "\n";
150       arquivo.write(header.getBytes());
151       arquivo.flush();
152 
153       double[] totais = new double[6];
154 
155       for (int i = 0; i < 6; i++) {
156         totais[i] = 0;
157       }
158 
159       long qtdeReg = 2; // TR00 e TR99 já contam!!!
160       /* Verificar se existem contas em EfItemEstRealizadoEfier */
161       List contasEfiec = itemEstContaDao.getContasParaExportacao(maIni[0], maIni[1], maFim[0], maFim[1]);
162 
163       if (!contasEfiec.isEmpty()) {
164         Iterator itContas = contasEfiec.iterator();
165         while (itContas.hasNext()) {
166           EfItemEstContaEfiec conta = (EfItemEstContaEfiec) itContas.next();
167           String contaContabil = conta.getContaSistemaOrcEfiec();
168 
169           if (contaContabil != null && !"".equals(contaContabil)) {
170             tam = contaContabil.length();
171             for (int i = tam; i < TAMANHO_CONTA_CONTABIL; i++) {
172               contaContabil += " ";
173             }
174 
175             /*
176              * Registrar no arquivo um TR da conta para cada mes/ano do
177              * intervalo selecionado. Ou seja, se foi selecionado de 01/2006 a
178              * 05/2006, para cada conta deve-se escrever no arquivo um: 01Conta1
179              * ... 012006 01Conta1 ... 022006 ... 01Conta1 ... 052006 01Conta2
180              * ... 012006 01Conta2 ... 022006 ... 01Conta2 ... 052006 . . .
181              * 01ContaN ... 012006 01ContaN ... 022006 ... 01ContaN ... 052006
182              */
183 
184             int mes = Integer.parseInt(maIni[0]);
185             int ano = Integer.parseInt(maIni[1]);
186             int mesFim = Integer.parseInt(maFim[0]);
187             int anoFim = Integer.parseInt(maFim[1]);
188 
189             /*
190              * Existe uma validação na tela que não permite gerar este arquivo
191              * com uma data final menor que a data inicial, portanto basta
192              * testar considerando que a data inicial é menor ou igual a data
193              * final.
194              */
195 
196             while (ano <= anoFim) {
197               if (ano < anoFim) {
198                 while (mes <= 12) {
199                   qtdeReg++;
200                   String registro = TR_REGISTRO + contaContabil + ((mes < 10) ? "0" + String.valueOf(mes) : String.valueOf(mes)) + ano + "\n";
201                   arquivo.write(registro.getBytes());
202                   arquivo.flush();
203                   mes++;
204                 }
205                 mes = 1;
206                 ano++;
207               }
208               else if (ano == anoFim) {
209                 while (mes <= mesFim) {
210                   qtdeReg++;
211                   String registro = TR_REGISTRO + contaContabil + ((mes < 10) ? "0" + String.valueOf(mes) : String.valueOf(mes)) + ano + "\n";
212                   arquivo.write(registro.getBytes());
213                   arquivo.flush();
214                   mes++;
215                 }
216                 break; // Como ano == anoFim, quando terminar o loop dos meses,
217                        // deve sair do loop mais externo.
218               }
219             }
220           }
221         }
222       }
223 
224       /* Gravar TRAILER - TR99 - para totalização */
225       String qtdeRegistros = Util.completarZerosEsquerda(Long.valueOf(qtdeReg), TAMANHO_QTDE_REGISTROS);
226       String totVal1 = Util.formataNumeroDecimalParaExportacao(totais[0], TAMANHO_VALORES);
227       String totVal2 = Util.formataNumeroDecimalParaExportacao(totais[1], TAMANHO_VALORES);
228       String totVal3 = Util.formataNumeroDecimalParaExportacao(totais[2], TAMANHO_VALORES);
229       String totVal4 = Util.formataNumeroDecimalParaExportacao(totais[3], TAMANHO_VALORES);
230       String totVal5 = Util.formataNumeroDecimalParaExportacao(totais[4], TAMANHO_VALORES);
231       String totVal6 = Util.formataNumeroDecimalParaExportacao(totais[5], TAMANHO_VALORES);
232 
233       String total = TR_TRAILER + qtdeRegistros + totVal1 + totVal2 + totVal3 + totVal4 + totVal5 + totVal6 + "\n";
234       arquivo.write(total.getBytes());
235       arquivo.flush();
236 
237       arquivo.close();
238     } catch (Exception e) {
239       Logger logger = Logger.getLogger(this.getClass());
240       logger.error(e);
241     }
242 
243     String[] retorno = { caminhoCompleto, nomeArquivo };
244 
245     return retorno;
246   }
247 
248   /**
249    * Verifica, segundo Anexo 1 do pacote de Integração Financeira, o arquivo
250    * conforme regras estabelecidas neste anexo.
251    * @param arquivoGravado
252    * @return List[]: Posição 0 --> form-beans dos registros válidos. Posição 1
253    *         --> ocorrências (EfImportOcorrenciasEfio) encontrados na crítica.
254    */
255   public List[] criticaArquivoImportado(File arquivoGravado, ConfiguracaoCfg configuracao, UsuarioUsu usuarioLogado, HttpServletRequest request) throws ECARException, Exception {
256 
257     ItemEstruturaContaOrcamentoDao itemEstContaDao = new ItemEstruturaContaOrcamentoDao(null);
258     ConfigSisExecFinanCsefvDao versaoDao = new ConfigSisExecFinanCsefvDao(null);
259 
260     // Dados Importacao
261     ImportacaoImp dadosImportacao = new ImportacaoImp();
262     dadosImportacao.setDataHoraImp(new Date());
263     dadosImportacao.setNomeArquivoImp(arquivoGravado.getName());
264 
265     Date inicioPeriodo = null;
266     Date fimPeriodo = null;
267 
268     List registrosValidos = new ArrayList();
269     List<EfImportOcorrenciasEfio> ocorrencias = new ArrayList<EfImportOcorrenciasEfio>();
270     Long totalRegistros01 = 0L;
271 
272     List sistemasExistentes = getSistemasAtivos();
273     List contasOrcamentarias = itemEstContaDao.listar(EfItemEstContaEfiec.class, new String[] { "contaSistemaOrcEfiec", "asc" });
274 
275     ConfigSisExecFinanCsef sistemaValido = null;
276     boolean existeSistema = false;
277 
278     // Inicialização do Total
279     BigDecimal[] total = new BigDecimal[6];
280     for (int i = 0; i < 6; i++)
281       total[i] = new BigDecimal("0");
282 
283     if (contasOrcamentarias == null)
284       contasOrcamentarias = new ArrayList();
285 
286     try {
287       BufferedReader in = new BufferedReader(new FileReader(arquivoGravado));
288       String linha = "";
289 
290       // Dados para TR00
291       String sistema = "";
292       String mesIni = "";
293       String anoIni = "";
294       String mesFim = "";
295       String anoFim = "";
296       String dataHoraGeracao = "";
297       String dataHoraCarga = "";
298 
299       long registrosLidos = 0;
300       while ((linha = in.readLine()) != null) {
301         String tr = "";
302         try {
303           tr = linha.substring(0, 2);
304         } catch (StringIndexOutOfBoundsException siobe) {
305           // Não conseguiu executar substring de 2 posições na linha
306           // ou seja, a linha tem zero ou só um caracter.
307           relatarOcorrencia("TR deve ser válido - " + linha + " linha:" + registrosLidos, ocorrencias, new TipoOcorrencia(TipoOcorrencia.TR_INVALIDO), dadosImportacao);
308           // this.logger.error(siobe); //Não é necessário logar essa exceção
309           continue;
310         }
311 
312         if (TR_HEADER.equals(tr)) { // 00
313 
314           registrosLidos++;
315 
316           sistema = linha.substring(2, 8);
317           mesIni = linha.substring(8, 10);
318           anoIni = linha.substring(10, 14);
319           mesFim = linha.substring(14, 16);
320           anoFim = linha.substring(16, 20);
321           dataHoraGeracao = linha.substring(20, 34);
322 
323           inicioPeriodo = new SimpleDateFormat("MMyyyy").parse(mesIni + anoIni);
324           fimPeriodo = new SimpleDateFormat("MMyyyy").parse(mesFim + anoFim);
325 
326           try {
327             dataHoraCarga = linha.substring(34, 48);
328           } catch (StringIndexOutOfBoundsException siobe) {
329             // DataHora Carga inválida: O Arquivo não foi gerado para
330             // importação!!!
331             relatarOcorrencia("TR" + TR_HEADER + " linha:" + registrosLidos + " - Data/Hora da carga não informada.", ocorrencias, new TipoOcorrencia(TipoOcorrencia.DATA_HORA_CARGA_INEXISTENTE), dadosImportacao);
332             // this.logger.error(siobe); //Não é necessário logar essa exceção
333             continue;
334           }
335           // Verificar se o Sistema existe
336           sistema = sistema.trim();
337           Iterator itSis = sistemasExistentes.iterator();
338           while (itSis.hasNext()) {
339             ConfigSisExecFinanCsef sis = (ConfigSisExecFinanCsef) itSis.next();
340             if (sistema.equals(sis.getSiglaCsef())) {
341               sistemaValido = sis;
342               existeSistema = true;
343               break;
344             }
345           }
346           if (!existeSistema) {
347             relatarOcorrencia("TR" + TR_HEADER + " linha:" + registrosLidos + " - Sistema inválido - " + sistema, ocorrencias, new TipoOcorrencia(TipoOcorrencia.SISTEMA_INVALIDO), dadosImportacao);
348           }
349 
350           validarMes(mesIni, ocorrencias, "TR" + TR_HEADER + " linha:" + registrosLidos + " - Mês inicial da solicitação", dadosImportacao);
351           validarAno(anoIni, ocorrencias, "TR" + TR_HEADER + " linha:" + registrosLidos + " - Ano inicial da solicitação", dadosImportacao);
352           validarMes(mesFim, ocorrencias, "TR" + TR_HEADER + " linha:" + registrosLidos + " - Mês final da solicitação", dadosImportacao);
353           validarAno(anoFim, ocorrencias, "TR" + TR_HEADER + " linha:" + registrosLidos + " - Ano final da solicitação", dadosImportacao);
354           validarDataHora(dataHoraGeracao, ocorrencias, "TR" + TR_HEADER + " linha:" + registrosLidos + " - Data/hora da Geração deve ser válida - " + dataHoraGeracao, dadosImportacao);
355           validarDataHora(dataHoraCarga, ocorrencias, "TR" + TR_HEADER + " linha:" + registrosLidos + " - Data/hora da Carga deve ser válida - " + dataHoraCarga, dadosImportacao);
356 
357           dadosImportacao.setDataHoraGeracaoSisOrigem(new SimpleDateFormat("ddMMyyyyHHmmss").parse(dataHoraGeracao));
358         }
359         else if (TR_REGISTRO.equals(tr)) { // 01
360 
361           totalRegistros01++;
362           registrosLidos++;
363           boolean houveOcorrencia = false;
364           // Dados para TR01
365           String conta = linha.substring(2, 257).toUpperCase();
366           String mesTrRegistro = linha.substring(257, 259);
367           String anoTrRegistro = linha.substring(259, 263);
368 
369           int pos = 263;
370           int posFim = pos + TAMANHO_VALORES;
371           int numeroValores = 6;
372           String[] valores = new String[numeroValores];
373           int cont = 0;
374           while (cont < numeroValores) {
375             valores[cont] = linha.substring(pos, posFim);
376             pos = posFim;
377             posFim = posFim + TAMANHO_VALORES;
378             cont++;
379           }
380           String indContabilidade = linha.substring(pos, pos + 1);
381 
382           String valor1Registro = valores[0].trim();
383           String valor2Registro = valores[1].trim();
384           String valor3Registro = valores[2].trim();
385           String valor4Registro = valores[3].trim();
386           String valor5Registro = valores[4].trim();
387           String valor6Registro = valores[5].trim();
388 
389           // Verifica se existe a acao descrita na descrição da conta.
390           final int ACAO = 3;
391           boolean existeConta = false;
392           String[] decompoeConta = conta.trim().split(" ");
393           String projAtividade = decompoeConta[0];
394           String recursoCta = decompoeConta[2];
395           String fonteCta = decompoeConta[3];
396 
397           Query q = this.session.createQuery("from ItemEstruturaIett iett where iett.estruturaEtt.codEtt = :codEtt and trim( iett.siglaIett ) = :siglaIett and iett.indAtivoIett = 'S'");
398           q.setLong("codEtt", ACAO);
399           q.setString("siglaIett", projAtividade);
400 
401           // Se == 0, então a sigla da acao (projeto atividade) não existe.
402           if (q.list().size() == 0) {
403 
404             relatarOcorrencia("TR" + TR_REGISTRO + " linha:" + registrosLidos + " - Item '" + projAtividade + "' não encontrado - conta:" + conta, ocorrencias, new TipoOcorrencia(TipoOcorrencia.ACAO_INEXISTENTE), dadosImportacao, conta);
405             houveOcorrencia = true;
406 
407           }
408 
409           // Verifica a existencia do recurso
410           q = this.session.createQuery("from FonteRecursoFonr where trim( siglaFonr ) = :siglaFonr");
411           q.setString("siglaFonr", recursoCta);
412 
413           if (q.list().size() == 0) {
414 
415             relatarOcorrencia("TR" + TR_REGISTRO + " linha:" + registrosLidos + " - Item '" + recursoCta + "' não encontrado - conta:" + conta, ocorrencias, new TipoOcorrencia(TipoOcorrencia.FONTE_INEXISTENTE), dadosImportacao, conta);
416             houveOcorrencia = true;
417           }
418 
419           // Verifica a existencia da fonte
420           q = this.session.createQuery("from RecursoRec where trim( siglaRec ) = :siglaRec");
421           q.setString("siglaRec", fonteCta);
422 
423           if (q.list().size() == 0) {
424 
425             relatarOcorrencia("TR" + TR_REGISTRO + " linha:" + registrosLidos + " - Item '" + fonteCta + "' não encontrado - conta:" + conta, ocorrencias, new TipoOcorrencia(TipoOcorrencia.RECURSO_INEXISTENTE), dadosImportacao, conta);
426             houveOcorrencia = true;
427           }
428 
429           // Se não houve nenhuma ocorrência nos passos anteriores, analisa a
430           // existência da conta.
431           if (!houveOcorrencia) {
432             // Verifica se a conta existe no Sistema.
433             conta = conta.trim();
434             existeConta = false;
435             Iterator itConta = contasOrcamentarias.iterator();
436             while (itConta.hasNext()) {
437               EfItemEstContaEfiec con = (EfItemEstContaEfiec) itConta.next();
438 
439               if (conta.trim().equals(con.getContaSistemaOrcEfiec().trim())) {
440                 existeConta = true;
441                 break;
442               }
443             }
444 
445             if (!existeConta) {
446               relatarOcorrencia("TR" + TR_REGISTRO + " linha:" + registrosLidos + " - Conta não econtrada - conta:" + conta, ocorrencias, new TipoOcorrencia(TipoOcorrencia.CONTA_INEXISTENTE), dadosImportacao, conta);
447               houveOcorrencia = true;
448             }
449           }
450 
451           houveOcorrencia = houveOcorrencia || !validarMes(mesTrRegistro, ocorrencias, "TR" + TR_REGISTRO + " linha:" + registrosLidos + " - Mês", dadosImportacao);
452           houveOcorrencia = houveOcorrencia || !validarAno(anoTrRegistro, ocorrencias, "TR" + TR_REGISTRO + " linha:" + registrosLidos + " - Ano", dadosImportacao);
453           houveOcorrencia = houveOcorrencia || !validarSistemaMesAno(conta, sistemaValido, mesTrRegistro, anoTrRegistro, TR_REGISTRO + " linha:" + registrosLidos, ocorrencias, dadosImportacao);
454           houveOcorrencia = houveOcorrencia || !validarValor(valor1Registro, ocorrencias, TR_REGISTRO + " linha:" + registrosLidos, configuracao.getFinanceiroDescValor1Cfg(), dadosImportacao);
455           houveOcorrencia = houveOcorrencia || !validarValor(valor2Registro, ocorrencias, TR_REGISTRO + " linha:" + registrosLidos, configuracao.getFinanceiroDescValor2Cfg(), dadosImportacao);
456           houveOcorrencia = houveOcorrencia || !validarValor(valor3Registro, ocorrencias, TR_REGISTRO + " linha:" + registrosLidos, configuracao.getFinanceiroDescValor3Cfg(), dadosImportacao);
457           houveOcorrencia = houveOcorrencia || !validarValor(valor4Registro, ocorrencias, TR_REGISTRO + " linha:" + registrosLidos, configuracao.getFinanceiroDescValor4Cfg(), dadosImportacao);
458           houveOcorrencia = houveOcorrencia || !validarValor(valor5Registro, ocorrencias, TR_REGISTRO + " linha:" + registrosLidos, configuracao.getFinanceiroDescValor5Cfg(), dadosImportacao);
459           houveOcorrencia = houveOcorrencia || !validarValor(valor6Registro, ocorrencias, TR_REGISTRO + " linha:" + registrosLidos, configuracao.getFinanceiroDescValor6Cfg(), dadosImportacao);
460 
461           if (!"A".equals(indContabilidade) && !"F".equals(indContabilidade)) {
462             relatarOcorrencia("TR" + TR_REGISTRO + " linha:" + registrosLidos + " - Flag indicador de contabilidade encerrada inválido - " + indContabilidade, ocorrencias, new TipoOcorrencia(TipoOcorrencia.FLAG_CONTABILIDADE_INVALIDO), dadosImportacao);
463             houveOcorrencia = true;
464           }
465 
466           if (!houveOcorrencia && !"".equals(dataHoraCarga)) {
467             // Incluir dados na lista de registros válidos.
468             // Dados que entram neste IF estão todos válidos!!!
469             EfItemEstRealizadoEfier registroValido = new EfItemEstRealizadoEfier();
470             registroValido.setDataInclusaoEfier(Data.getDataAtual());
471             registroValido.setUsuarioUsu(usuarioLogado);
472             registroValido.setContaSistemaOrcEfier(conta);
473             registroValido.setMesReferenciaEfier(Long.valueOf(mesTrRegistro));
474             registroValido.setAnoReferenciaEfier(Long.valueOf(anoTrRegistro));
475             registroValido.setDataHoraInfoEfier(Data.parseDate(dataHoraCarga, FORMATO_DATAHORA));
476             registroValido.setIndManualEfier("N");
477             registroValido.setImportacaoImp(dadosImportacao);
478             registroValido.setConfigSisExecFinanCsefv(versaoDao.getConfigSisExecFinanCsefv(Long.valueOf(anoTrRegistro), Long.valueOf(mesTrRegistro), sistemaValido));
479             registroValido.setValor1Efier(toBigDecimal(valor1Registro).doubleValue());
480             registroValido.setValor2Efier(toBigDecimal(valor2Registro).doubleValue());
481             registroValido.setValor3Efier(toBigDecimal(valor3Registro).doubleValue());
482             registroValido.setValor4Efier(toBigDecimal(valor4Registro).doubleValue());
483             registroValido.setValor5Efier(toBigDecimal(valor5Registro).doubleValue());
484             registroValido.setValor6Efier(toBigDecimal(valor6Registro).doubleValue());
485 
486             registroValido.setIndContabilidadeEfier(indContabilidade);
487 
488             registrosValidos.add(registroValido);
489 
490           }
491           total[0] = total[0].add(toBigDecimal(valor1Registro));
492           total[1] = total[1].add(toBigDecimal(valor2Registro));
493           total[2] = total[2].add(toBigDecimal(valor3Registro));
494           total[3] = total[3].add(toBigDecimal(valor4Registro));
495           total[4] = total[4].add(toBigDecimal(valor5Registro));
496           total[5] = total[5].add(toBigDecimal(valor6Registro));
497 
498         }
499         else if (TR_REGISTRO_NAO_REVISTO.equals(tr)) { // 02
500           registrosLidos++;
501           String mesTrNaoPrevisto = linha.substring(2, 4);
502           String anoTrNaoPrevisto = linha.substring(4, 8);
503 
504           int pos = 8;
505           int posFim = pos + TAMANHO_VALORES;
506           int numeroValores = 6;
507           String[] valores = new String[numeroValores];
508           int cont = 0;
509           while (cont < numeroValores) {
510             valores[cont] = linha.substring(pos, posFim);
511             pos = posFim;
512             posFim = posFim + TAMANHO_VALORES;
513             cont++;
514           }
515 
516           String valor1NaoPrevisto = valores[0].trim();
517           String valor2NaoPrevisto = valores[1].trim();
518           String valor3NaoPrevisto = valores[2].trim();
519           String valor4NaoPrevisto = valores[3].trim();
520           String valor5NaoPrevisto = valores[4].trim();
521           String valor6NaoPrevisto = valores[5].trim();
522 
523           boolean houveOcorrencia = false;
524 
525           houveOcorrencia = houveOcorrencia || !validarMes(mesTrNaoPrevisto, ocorrencias, "TR" + TR_REGISTRO_NAO_REVISTO + " linha:" + registrosLidos + " - Mês", dadosImportacao);
526           houveOcorrencia = houveOcorrencia || !validarAno(anoTrNaoPrevisto, ocorrencias, "TR" + TR_REGISTRO_NAO_REVISTO + " linha:" + registrosLidos + " - Ano", dadosImportacao);
527           houveOcorrencia = houveOcorrencia || !validarSistemaMesAno("", sistemaValido, mesTrNaoPrevisto, anoTrNaoPrevisto, TR_REGISTRO_NAO_REVISTO, ocorrencias, dadosImportacao);
528           houveOcorrencia = houveOcorrencia || !validarValor(valor1NaoPrevisto, ocorrencias, TR_REGISTRO_NAO_REVISTO + " linha:" + registrosLidos, configuracao.getFinanceiroDescValor1Cfg(), dadosImportacao);
529           houveOcorrencia = houveOcorrencia || !validarValor(valor2NaoPrevisto, ocorrencias, TR_REGISTRO_NAO_REVISTO + " linha:" + registrosLidos, configuracao.getFinanceiroDescValor2Cfg(), dadosImportacao);
530           houveOcorrencia = houveOcorrencia || !validarValor(valor3NaoPrevisto, ocorrencias, TR_REGISTRO_NAO_REVISTO + " linha:" + registrosLidos, configuracao.getFinanceiroDescValor3Cfg(), dadosImportacao);
531           houveOcorrencia = houveOcorrencia || !validarValor(valor4NaoPrevisto, ocorrencias, TR_REGISTRO_NAO_REVISTO + " linha:" + registrosLidos, configuracao.getFinanceiroDescValor4Cfg(), dadosImportacao);
532           houveOcorrencia = houveOcorrencia || !validarValor(valor5NaoPrevisto, ocorrencias, TR_REGISTRO_NAO_REVISTO + " linha:" + registrosLidos, configuracao.getFinanceiroDescValor5Cfg(), dadosImportacao);
533           houveOcorrencia = houveOcorrencia || !validarValor(valor6NaoPrevisto, ocorrencias, TR_REGISTRO_NAO_REVISTO + " linha:" + registrosLidos, configuracao.getFinanceiroDescValor6Cfg(), dadosImportacao);
534 
535           if (!houveOcorrencia && !"".equals(dataHoraCarga)) {
536             // Incluir dados na lista de registros válidos.
537             // Dados que entram neste IF estão todos válidos!!!
538             EfItemEstRealizadoEfier registroValido = new EfItemEstRealizadoEfier();
539             registroValido.setDataInclusaoEfier(Data.getDataAtual());
540             registroValido.setUsuarioUsu(usuarioLogado);
541             registroValido.setMesReferenciaEfier(Long.valueOf(mesTrNaoPrevisto));
542             registroValido.setAnoReferenciaEfier(Long.valueOf(anoTrNaoPrevisto));
543             registroValido.setDataHoraInfoEfier(Data.parseDate(dataHoraCarga, FORMATO_DATAHORA));
544             registroValido.setIndManualEfier("N");
545             registroValido.setImportacaoImp(dadosImportacao);
546             registroValido.setConfigSisExecFinanCsefv(versaoDao.getConfigSisExecFinanCsefv(Long.valueOf(anoTrNaoPrevisto), Long.valueOf(mesTrNaoPrevisto), sistemaValido));
547             registroValido.setValor1Efier(toBigDecimal(valor1NaoPrevisto).doubleValue());
548             registroValido.setValor2Efier(toBigDecimal(valor2NaoPrevisto).doubleValue());
549             registroValido.setValor3Efier(toBigDecimal(valor3NaoPrevisto).doubleValue());
550             registroValido.setValor4Efier(toBigDecimal(valor4NaoPrevisto).doubleValue());
551             registroValido.setValor5Efier(toBigDecimal(valor5NaoPrevisto).doubleValue());
552             registroValido.setValor6Efier(toBigDecimal(valor6NaoPrevisto).doubleValue());
553 
554             registrosValidos.add(registroValido);
555           }
556 
557           total[0] = total[0].add(toBigDecimal(valor1NaoPrevisto));
558           total[1] = total[1].add(toBigDecimal(valor2NaoPrevisto));
559           total[2] = total[2].add(toBigDecimal(valor3NaoPrevisto));
560           total[3] = total[3].add(toBigDecimal(valor4NaoPrevisto));
561           total[4] = total[4].add(toBigDecimal(valor5NaoPrevisto));
562           total[5] = total[5].add(toBigDecimal(valor6NaoPrevisto));
563 
564         }
565         else if (TR_TRAILER.equals(tr)) { // 99
566           registrosLidos++;
567           String qtdeRegistros = linha.substring(2, 8);
568 
569           int pos = 8;
570           int posFim = pos + TAMANHO_VALORES;
571           int numeroValores = 6;
572           String[] valores = new String[numeroValores];
573           int cont = 0;
574           while (cont < numeroValores) {
575             valores[cont] = linha.substring(pos, posFim);
576             pos = posFim;
577             posFim = posFim + TAMANHO_VALORES;
578             cont++;
579           }
580 
581           String totalValor1 = valores[0].trim();
582           String totalValor2 = valores[1].trim();
583           String totalValor3 = valores[2].trim();
584           String totalValor4 = valores[3].trim();
585           String totalValor5 = valores[4].trim();
586           String totalValor6 = valores[5].trim();
587 
588           boolean houveOcorrencia = false;
589 
590           long qtde = StrToLong(qtdeRegistros);
591           if (qtde == -1) {
592             relatarOcorrencia("TR" + TR_TRAILER + " linha:" + registrosLidos + " - Quantidade de registros deve ser numérico - " + qtdeRegistros, ocorrencias, new TipoOcorrencia(TipoOcorrencia.QTDE_REGISTROS_INVALIDO), dadosImportacao);
593             houveOcorrencia = true;
594           }
595 
596           // Validar os registros lidos com os dados do trailer...(qtos
597           // registros foram lidos, totais de valores....)
598           // Caso ocorra diferença em algum dado, relatar ocorrencia.
599 
600           houveOcorrencia = houveOcorrencia || !validarQtdeRegistrosLidos(qtde, registrosLidos, TR_TRAILER, ocorrencias, dadosImportacao);
601           houveOcorrencia = houveOcorrencia || !validarValor(totalValor1, ocorrencias, TR_TRAILER + " linha:" + registrosLidos, "Total do " + configuracao.getFinanceiroDescValor1Cfg(), dadosImportacao);
602           houveOcorrencia = houveOcorrencia || !validarValor(totalValor2, ocorrencias, TR_TRAILER + " linha:" + registrosLidos, "Total do " + configuracao.getFinanceiroDescValor2Cfg(), dadosImportacao);
603           houveOcorrencia = houveOcorrencia || !validarValor(totalValor3, ocorrencias, TR_TRAILER + " linha:" + registrosLidos, "Total do " + configuracao.getFinanceiroDescValor3Cfg(), dadosImportacao);
604           houveOcorrencia = houveOcorrencia || !validarValor(totalValor4, ocorrencias, TR_TRAILER + " linha:" + registrosLidos, "Total do " + configuracao.getFinanceiroDescValor4Cfg(), dadosImportacao);
605           houveOcorrencia = houveOcorrencia || !validarValor(totalValor5, ocorrencias, TR_TRAILER + " linha:" + registrosLidos, "Total do " + configuracao.getFinanceiroDescValor5Cfg(), dadosImportacao);
606           houveOcorrencia = houveOcorrencia || !validarValor(totalValor6, ocorrencias, TR_TRAILER + " linha:" + registrosLidos, "Total do " + configuracao.getFinanceiroDescValor6Cfg(), dadosImportacao);
607 
608           if (!houveOcorrencia && !"".equals(dataHoraCarga)) {
609             BigDecimal[] totalTrailer = new BigDecimal[6];
610             for (int i = 0; i < 6; i++)
611               totalTrailer[i] = new BigDecimal("0");
612 
613             totalTrailer[0] = toBigDecimal(totalValor1);
614             totalTrailer[1] = toBigDecimal(totalValor2);
615             totalTrailer[2] = toBigDecimal(totalValor3);
616             totalTrailer[3] = toBigDecimal(totalValor4);
617             totalTrailer[4] = toBigDecimal(totalValor5);
618             totalTrailer[5] = toBigDecimal(totalValor6);
619 
620             for (int i = 0; i < 6; i++) {
621               // houveOcorrencia = houveOcorrencia ||
622               // validarTotaisLidos(totalTrailer[i], total[i], TR_TRAILER +
623               // " linha:" + registrosLidos, ocorrencias, dadosImportacao);
624               houveOcorrencia = validarTotaisLidos(totalTrailer[i], total[i], TR_TRAILER + " linha:" + registrosLidos, ocorrencias, dadosImportacao);
625             }
626           }
627 
628           break; // Este break é porque o TR99 é o último registro lido. Se
629                  // chegar ao TR99, acabou o número de registros válidos.
630         }
631         else {
632           try {
633             int numero = Integer.valueOf(tr).intValue();
634             /*
635              * A variável acima só é utilizada para efeito de conversão... Se
636              * caiu neste else e conseguiu converter, então a msg é
637              * "TR deve ser válido," se der exceção, não é número então a msg é
638              * "TR deve ser numerico"
639              */
640             relatarOcorrencia("TR deve ser válido - " + tr + " linha:" + registrosLidos, ocorrencias, new TipoOcorrencia(TipoOcorrencia.TR_INVALIDO), dadosImportacao);
641           } catch (NumberFormatException nfe) {
642             // Não conseguiu converter de string para numérico: Não é um número.
643             relatarOcorrencia("TR deve ser numérico - " + tr + " linha:" + registrosLidos, ocorrencias, new TipoOcorrencia(TipoOcorrencia.TR_INVALIDO), dadosImportacao);
644             // this.logger.error(nfe); Não é necessário logar esta exceção
645           }
646         }
647       }
648     } catch (Exception e) {
649       Logger logger = Logger.getLogger(this.getClass());
650       logger.error(e);
651       throw e;
652     }
653 
654     List<ConfigSisExecFinanCsef> sistema = new ArrayList<ConfigSisExecFinanCsef>();
655     sistema.add(sistemaValido);
656 
657     List<Date> periodo = new ArrayList<Date>();
658     periodo.add(inicioPeriodo);
659     periodo.add(fimPeriodo);
660 
661     // dadosImportacao não precisará ser passado para a próxima camada pois ele
662     // tem referência dentro do objeto 'ocorrências'
663     dadosImportacao.setNumRegistrosValidosImp(registrosValidos.size());
664     dadosImportacao.setNumRegistrosInvalidosImp(totalRegistros01.intValue() - registrosValidos.size());
665     dadosImportacao.setUsuarioUsu(((SegurancaECAR) request.getSession().getAttribute("seguranca")).getUsuario());
666 
667     // Agrupa as ocorrencias do tipo CONTA_INEXISTENTE
668     ocorrencias = agrupaOcorrenciasdoTipoContaInexistente(ocorrencias);
669 
670     List[] retorno = { registrosValidos, ocorrencias, periodo, sistema };
671 
672     request.getSession().setAttribute("dadosImportacao", dadosImportacao);
673 
674     return retorno;
675   }
676 
677   /**
678    * Agrupa as ocorrencias do tipo Contas Inexistentes em apenas uma ocorrência
679    * por conta
680    * @param ocorrencias
681    */
682   public List<EfImportOcorrenciasEfio> agrupaOcorrenciasdoTipoContaInexistente(List<EfImportOcorrenciasEfio> ocorrencias) throws Exception {
683 
684     // Agrupa as contas inexistentes em apenas uma ocorrencia
685     List<EfImportOcorrenciasEfio> contasAgrupadas = new ArrayList<EfImportOcorrenciasEfio>();
686     List<EfImportOcorrenciasEfio> listaRetorno = new ArrayList<EfImportOcorrenciasEfio>();
687 
688     TipoOcorrencia tipoOcorrencia = new TipoOcorrencia(TipoOcorrencia.CONTA_INEXISTENTE);
689 
690     for (EfImportOcorrenciasEfio ocorrencia : ocorrencias) {
691       boolean existe = false;
692       if (ocorrencia.getTipoOcorrencia().equals(tipoOcorrencia)) {
693         for (EfImportOcorrenciasEfio obj : contasAgrupadas) {
694           if (obj.getConta().equals(ocorrencia.getConta())) {
695             existe = true;
696             break;
697           }
698         }
699         if (!existe) {
700           contasAgrupadas.add(ocorrencia);
701         }
702       }
703       else {
704         listaRetorno.add(ocorrencia);
705       }
706     }
707 
708     listaRetorno.addAll(contasAgrupadas);
709 
710     return listaRetorno;
711   }
712 
713   /**
714    * Insere uma ocorrência com a data atual na lista de ocorrencias.
715    * @param String mensagem
716    * @param List ocorrencias
717    */
718   public void relatarOcorrencia(String mensagem, List<EfImportOcorrenciasEfio> ocorrencias, TipoOcorrencia tipoOcorrencia, ImportacaoImp dadosImportacao) {
719 
720     if (ocorrencias == null)
721       ocorrencias = new ArrayList<EfImportOcorrenciasEfio>();
722 
723     EfImportOcorrenciasEfio ocorrencia = new EfImportOcorrenciasEfio();
724 
725     ocorrencia.setDescricaoEfio(mensagem);
726     ocorrencia.setTipoOcorrencia(tipoOcorrencia);
727     ocorrencia.setImportacaoImp(dadosImportacao);
728     ocorrencias.add(ocorrencia);
729   }
730 
731   /**
732    * Insere uma ocorrência com a data atual na lista de ocorrencias.
733    * @param String mensagem
734    * @param List ocorrencias
735    */
736   public void relatarOcorrencia(String mensagem, List<EfImportOcorrenciasEfio> ocorrencias, TipoOcorrencia tipoOcorrencia, ImportacaoImp dadosImportacao, String conta) throws Exception {
737 
738     if (ocorrencias == null)
739       ocorrencias = new ArrayList<EfImportOcorrenciasEfio>();
740 
741     EfImportOcorrenciasEfio ocorrencia = new EfImportOcorrenciasEfio();
742 
743     ocorrencia.setDescricaoEfio(mensagem);
744     ocorrencia.setTipoOcorrencia(tipoOcorrencia);
745     ocorrencia.setImportacaoImp(dadosImportacao);
746     ocorrencia.setConta(conta);
747     ocorrencias.add(ocorrencia);
748   }
749 
750   /**
751    * Transforma um valor em string para um long para importação.
752    * @param numero
753    * @return numero ou -1 se não conseguir tranformar.
754    */
755   private long StrToLong(String numero) throws Exception {
756     long retorno = -1;
757     try {
758       retorno = Long.valueOf(numero.trim()).longValue();
759     } catch (Exception e) {
760       throw e;
761     }
762     return retorno;
763   }
764 
765   /**
766    * Valida mês válido para importação
767    * @param strMes
768    * @param ocorrencias
769    * @param tokenMensagemOcorrencia
770    * @return
771    */
772   private boolean validarMes(String strMes, List ocorrencias, String tokenMensagemOcorrencia, ImportacaoImp dadosImportacao) {
773 
774     long mes = 0;
775 
776     try {
777       mes = StrToLong(strMes);
778     } catch (Exception e) {
779       relatarOcorrencia(tokenMensagemOcorrencia + " deve ser numérico - " + strMes, ocorrencias, new TipoOcorrencia(TipoOcorrencia.VALOR_INVALIDO), dadosImportacao);
780       return false;
781     }
782 
783     if (mes < 1 || mes > 12) {
784       if (mes == -1) {
785         relatarOcorrencia(tokenMensagemOcorrencia + " deve ser numérico - " + strMes, ocorrencias, new TipoOcorrencia(TipoOcorrencia.VALOR_INVALIDO), dadosImportacao);
786         return false;
787       }
788       else {
789         relatarOcorrencia(tokenMensagemOcorrencia + " deve ser válido - " + strMes, ocorrencias, new TipoOcorrencia(TipoOcorrencia.VALOR_INVALIDO), dadosImportacao);
790         return false;
791       }
792     }
793     return true;
794   }
795 
796   /**
797    * Valida um ano válido para importação
798    * @param strAno
799    * @param ocorrencias
800    * @param tokenMensagemOcorrencia
801    * @return
802    */
803   private boolean validarAno(String strAno, List ocorrencias, String tokenMensagemOcorrencia, ImportacaoImp dadosImportados) {
804 
805     long ano = 0;
806 
807     try {
808       ano = StrToLong(strAno);
809     } catch (Exception e) {
810       return false;
811     }
812 
813     if (ano == -1) {
814       relatarOcorrencia(tokenMensagemOcorrencia + " deve ser numérico - " + strAno, ocorrencias, new TipoOcorrencia(TipoOcorrencia.VALOR_INVALIDO), dadosImportados);
815       return false;
816     }
817     return true;
818   }
819 
820   /**
821    * Valida campo de Datahora de importação
822    * @param strDataHora
823    * @param ocorrencias
824    * @param mensagemOcorrencia
825    */
826   private void validarDataHora(String strDataHora, List ocorrencias, String mensagemOcorrencia, ImportacaoImp dadosImportados) {
827     // Verificar a data de carga: Se o método retornar NULL, é porque não
828     // conseguiu converter para uma data válida.
829     if (Data.parseDate(strDataHora, FORMATO_DATAHORA) == null) {
830       relatarOcorrencia(mensagemOcorrencia, ocorrencias, new TipoOcorrencia(TipoOcorrencia.FORMATO_DATA_HORA_INVALIDO), dadosImportados);
831     }
832     else {
833       if (!verificaDataHoraImportacao(strDataHora))
834         relatarOcorrencia(mensagemOcorrencia, ocorrencias, new TipoOcorrencia(TipoOcorrencia.FORMATO_DATA_HORA_INVALIDO), dadosImportados);
835     }
836   }
837 
838   /**
839    * Valida um valor de importação. <br>
840    * Obs.: Se o valor estiver com um sinal de menos (-) na primeira posição do
841    * número, o valor é validado como número negativo. Ex.: Para a string
842    * -0000362418200, o valor será transformado para o número -3.624.182,00, ou
843    * seja, um número válido --> o retorno para este caso é <b>true</b>.
844    * @param strValor
845    * @param ocorrencias
846    * @param tr
847    * @param nomeValor
848    * @return
849    */
850   private boolean validarValor(String strValor, List ocorrencias, String tr, String nomeValor, ImportacaoImp dadosImportados) {
851     if (!"".equals(nomeValor.trim())) { // nomeValor vem da configuracao, se
852                                         // estiver vazio é pq não é para
853                                         // importar.
854 
855       long valor = 0;
856 
857       try {
858         valor = StrToLong(strValor);
859       } catch (Exception e) {
860         relatarOcorrencia("TR" + tr + " - " + nomeValor + " deve ser numérico - " + strValor, ocorrencias, new TipoOcorrencia(TipoOcorrencia.VALOR_INVALIDO), dadosImportados);
861         return false;
862       }
863 
864       /*
865        * if(valor == -1){ relatarOcorrencia("TR" + tr + " - " + nomeValor +
866        * " deve ser numérico - " + strValor, ocorrencias, nomeArquivoImportado);
867        * return false; }
868        */
869     }
870     return true;
871   }
872 
873   /**
874    * Valida a quantidade de registros lidos.
875    * @param qtde
876    * @param qtdeRegistrosLidos
877    * @param tr
878    * @param ocorrencias
879    * @return
880    */
881   private boolean validarQtdeRegistrosLidos(long qtde, long qtdeRegistrosLidos, String tr, List ocorrencias, ImportacaoImp dadosImportados) {
882 
883     if (qtde != qtdeRegistrosLidos) {
884       relatarOcorrencia("TR" + tr + " - Quantidade de registros informados (" + String.valueOf(qtde) + ") é diferente da Quantidade de registros lidos (" + String.valueOf(qtdeRegistrosLidos) + ")", ocorrencias, new TipoOcorrencia(TipoOcorrencia.INCONSISTENCIA_QTDE_REGISTROS_INFORMADOS_x_LIDOS), dadosImportados);
885       return false;
886     }
887 
888     return true;
889   }
890 
891   /**
892    * Valida os totais lidos.
893    * @param totalTrailer
894    * @param totalRegistro
895    * @param tr
896    * @param ocorrencias
897    * @return
898    */
899   private boolean validarTotaisLidos(BigDecimal totalTrailer, BigDecimal totalRegistro, String tr, List ocorrencias, ImportacaoImp dadosImportados) {
900 
901     if (totalTrailer.doubleValue() != totalRegistro.doubleValue()) {
902 
903       DecimalFormat nf = new DecimalFormat("#,###,###,###,###,###.00");
904 
905       relatarOcorrencia("TR" + tr + " - Inconsistência nos valores de totalização -" + " calc: " + nf.format(totalRegistro) + " inf: " + nf.format(totalTrailer) + " dif: " + nf.format((totalRegistro.subtract(totalTrailer))), ocorrencias, new TipoOcorrencia(TipoOcorrencia.INCONSISTENCIA_TOTALIZACAO), dadosImportados);
906       return false;
907     }
908     return true;
909   }
910 
911   /**
912    * Função que valida se o sistema possui versão no Mês/Ano informado.
913    * @param sistema
914    * @param mes
915    * @param ano
916    * @param tr
917    * @param ocorrencias
918    * @return
919    */
920   private boolean validarSistemaMesAno(String conta, ConfigSisExecFinanCsef sistema, String mes, String ano, String tr, List ocorrencias, ImportacaoImp dadosImportados) throws ECARException {
921     ConfigSisExecFinanCsefvDao versaoDao = new ConfigSisExecFinanCsefvDao(null);
922     Long mesLong = Long.valueOf(mes);
923     Long anoLong = Long.valueOf(ano);
924 
925     ConfigSisExecFinanCsefv versao = versaoDao.getConfigSisExecFinanCsefv(anoLong, mesLong, sistema);
926 
927     if (versao == null || (versao != null && !"S".equals(versao.getIndAtivoCsefv()))) {
928       relatarOcorrencia("TR" + tr + " - O Sistema não possui versão no Mês/Ano informado - " + sistema.getNomeCsef() + " (" + mes + "/" + ano + ")", ocorrencias, new TipoOcorrencia(TipoOcorrencia.VERSAO_INEXISTENTE_MES_ANO), dadosImportados);
929       return false;
930     }
931 
932     /* Validação da conta para registros válidos */
933     if (tr.equals(TR_REGISTRO)) {
934       List estruturasContabil = new ConfigExecFinanDao(request).getConfigExecFinanByVersao(versao);
935       int tamanhoConta = 0;
936       if (estruturasContabil != null) {
937 
938         Iterator it = estruturasContabil.iterator();
939         while (it.hasNext()) {
940           ConfigExecFinanCef estruturaContabil = (ConfigExecFinanCef) it.next();
941           /*
942            * Para cada campo da estrutura, na conta é adicionado um espaço em
943            * branco. Portanto, deve-se somar ao tamanho, o numero de
944            * caracteres+1
945            */
946           tamanhoConta += estruturaContabil.getNumCaracteresCef().intValue() + 1;
947         }
948         tamanhoConta--; // Decremento o tamanho conta pq o último espaço em
949                         // branco (final) é retirado com trim().
950       }
951 
952       if (conta.length() != tamanhoConta) {
953         relatarOcorrencia("TR" + tr + " - A conta informada pode estar em leiaute de versão diferente." + conta, ocorrencias, new TipoOcorrencia(TipoOcorrencia.LAYOUT_INVALIDO), dadosImportados);
954         return false;
955       }
956     }
957 
958     return true;
959   }
960 
961   /**
962    * Função que transforma valores da importação de String para Double
963    * @param valor
964    * @return
965    */
966   private Double valoresStringToDouble(String valor) {
967     valor = valor.trim();
968     double inteiro = 0;
969     double decimal = 0;
970     if (!"".equals(valor)) {
971       String parteInteira = valor.substring(0, valor.length() - 2);
972       String parteDecimal = valor.substring(valor.length() - 2, valor.length());
973 
974       inteiro = new Double(parteInteira).doubleValue();
975       decimal = new Double("0." + parteDecimal).doubleValue();
976       inteiro = inteiro + decimal;
977     }
978     Double retorno = new Double(inteiro);
979     return retorno;
980   }
981 
982   /**
983    * Verifica se uma data hora do arquivo de importação é válida. Para isso, a
984    * data hora deve estar no formato "ddMMyyyyHHmmss".
985    * @param dataHora
986    * @return
987    */
988   private boolean verificaDataHoraImportacao(String dataHora) {
989     if (dataHora.length() != TAMANHO_DATAHORA) {
990       return false;
991     }
992     else {
993       try {
994         int dia = Integer.valueOf(dataHora.substring(0, 2)).intValue();
995         int mes = Integer.valueOf(dataHora.substring(2, 4)).intValue();
996         int ano = Integer.valueOf(dataHora.substring(4, 8)).intValue();
997         int hora = Integer.valueOf(dataHora.substring(8, 10)).intValue();
998         int minuto = Integer.valueOf(dataHora.substring(10, 12)).intValue();
999         int segundo = Integer.valueOf(dataHora.substring(12, 14)).intValue();
1000 
1001         if (mes == 1 || mes == 3 || mes == 5 || mes == 7 || mes == 8 || mes == 10 || mes == 12) {
1002           if (dia < 1 || dia > 31) {
1003             return false;
1004           }
1005         }
1006         else if (mes == 4 || mes == 6 || mes == 9 || mes == 11) {
1007           if (dia < 1 || dia > 30) {
1008             return false;
1009           }
1010         }
1011         else if (mes == 2) {
1012           if ((ano % 4) == 0 && (ano % 100) != 0) { // ano bissexto.
1013             if (dia < 1 || dia > 29) {
1014               return false;
1015             }
1016           }
1017           else {
1018             if (dia < 1 || dia > 28) {
1019               return false;
1020             }
1021           }
1022         }
1023         else {
1024           return false;
1025         }
1026 
1027         if (hora < 0 || hora > 23)
1028           return false;
1029         if (minuto < 0 || minuto > 59)
1030           return false;
1031         if (segundo < 0 || segundo > 59)
1032           return false;
1033       } catch (NumberFormatException nfe) {
1034         // this.logger.error(nfe); //Não é necessário logar essa exceção
1035         return false;
1036       }
1037     }
1038     return true;
1039   }
1040 
1041   /**
1042    * Importa os dados do arquivo para a tabela EfItemEstRealizadoEfier. Grava as
1043    * ocorrencias na tabela EfImportOcorrenciasEfio
1044    * @param arquivoImportado
1045    * @param configuracao
1046    * @throws ECARException
1047    * @throws HibernateException
1048    */
1049   public void importarDadosArquivo(File arquivoImportado, ConfiguracaoCfg configuracao, UsuarioUsu usuarioLogado, HttpServletRequest request) throws ECARException, HibernateException, Exception {
1050 
1051     ItemEstruturaRealizadoDao itemEstRealizadoDao = new ItemEstruturaRealizadoDao(null);
1052     List[] critica = this.criticaArquivoImportado(arquivoImportado, configuracao, usuarioLogado, request);
1053     List registrosValidos = critica[0];
1054     List ocorrencias = critica[1];
1055     List periodo = critica[2];
1056     List sistema = critica[3];
1057 
1058     Date inicio = (Date) periodo.get(0);
1059     Date fim = (Date) periodo.get(1);
1060 
1061     Transaction tx = null;
1062     try {
1063 
1064       tx = session.beginTransaction();
1065 
1066       // Deleta ocorrências antes de tudo
1067       List listaExclusao = itemEstRealizadoDao.getItemEstRealizadoEfierToImportacao(inicio, fim, (ConfigSisExecFinanCsef) sistema.get(0));
1068       if (listaExclusao != null) {
1069         for (Iterator it = listaExclusao.iterator(); it.hasNext();) {
1070           EfItemEstRealizadoEfier obj = (EfItemEstRealizadoEfier) it.next();
1071           session.delete(obj);
1072         }
1073       }
1074 
1075       if (!registrosValidos.isEmpty()) {
1076         Iterator itReg = registrosValidos.iterator();
1077         while (itReg.hasNext()) {
1078           EfItemEstRealizadoEfier realizado = (EfItemEstRealizadoEfier) itReg.next();
1079           session.save(realizado);
1080         }
1081 
1082       }
1083 
1084       if (!ocorrencias.isEmpty()) {
1085 
1086         Iterator itOc = ocorrencias.iterator();
1087 
1088         while (itOc.hasNext()) {
1089 
1090           EfImportOcorrenciasEfio oc = (EfImportOcorrenciasEfio) itOc.next();
1091           session.save(oc);
1092         }
1093       }
1094 
1095       tx.commit();
1096     } catch (HibernateException he) {
1097       Logger logger = Logger.getLogger(this.getClass());
1098       logger.error(he);
1099 
1100       if (tx != null) {
1101         tx.rollback();
1102       }
1103 
1104       throw new ECARException("integracaoFinanceira.importarArquivo.importacao.erro");
1105     } catch (Exception e) {
1106       Logger logger = Logger.getLogger(this.getClass());
1107       logger.error(e);
1108       if (tx != null) {
1109         tx.rollback();
1110       }
1111 
1112       throw new ECARException("integracaoFinanceira.importarArquivo.importacao.erro");
1113     }
1114 
1115   }
1116 
1117   /**
1118    * Recebe um array de contas a serem criadas no Sistema.
1119    * @author carlos
1120    * @since 07/06/2007
1121    * @param contas
1122    * @throws ECARException
1123    */
1124   public void criarContas(Object[] contasInexistentes) throws ECARException {
1125 
1126     List<EfItemEstContaEfiec> todasContas = new ArrayList<EfItemEstContaEfiec>();
1127     List<EfIettFonteTotEfieft> fontesTotEfieft = new ArrayList<EfIettFonteTotEfieft>();
1128 
1129     Transaction tx = null;
1130 
1131     try {
1132       // Abre transação
1133       tx = session.beginTransaction();
1134 
1135       Query q = null;
1136 
1137       q = this.session.createQuery("from FonteRecursoFonr");
1138       List<FonteRecursoFonr> fontesRecurso = (List<FonteRecursoFonr>) q.list();
1139 
1140       q = this.session.createQuery("from ExercicioExe exe order by exe.dataInicialExe asc");
1141       List<ExercicioExe> exercicios = (List<ExercicioExe>) q.list();
1142 
1143       q = this.session.createQuery("from RecursoRec");
1144       List<RecursoRec> recursos = (List<RecursoRec>) q.list();
1145 
1146       final int ACAO = 3;
1147 
1148       for (int indice = 0; indice < contasInexistentes.length; indice++) {
1149 
1150         String[] decompoeConta = ((String) contasInexistentes[indice]).trim().toUpperCase().split(" ");
1151         String projAtividade = decompoeConta[0];
1152         String obra = decompoeConta[1];
1153 
1154         q = this.session.createQuery("from ItemEstruturaIett iett where iett.estruturaEtt.codEtt = :codEtt and trim( iett.siglaIett ) = :siglaIett and iett.indAtivoIett = 'S'");
1155         q.setLong("codEtt", ACAO);
1156         q.setString("siglaIett", projAtividade);
1157 
1158         ItemEstruturaIett iett = (ItemEstruturaIett) q.list().get(0);
1159 
1160         /************************************************/
1161         // Verifica se já existe objetos EfIettFonteTotEfieft para esse iett,
1162         // caso contrário inclui o mesmo no banco.
1163         ItemEstruturaFonteRecursoDao dao = new ItemEstruturaFonteRecursoDao(request);
1164         // O ExercicioExe é apenas exigido no método, mas não considerado na
1165         // consulta, a linha referente
1166         // ao ExercicioExe está comentado no método.
1167         List fontesRecursos = dao.getFontesRecursosByExercicio(iett, new ExercicioExe());
1168 
1169         if (fontesRecursos.size() == 0) {
1170 
1171           // Tá invertido, o Recurso responde pela Fonte do recurso e vice-versa
1172           for (Iterator<FonteRecursoFonr> itFontes = fontesRecurso.iterator(); itFontes.hasNext();) {
1173 
1174             FonteRecursoFonr fonte = itFontes.next();
1175 
1176             EfIettFonteTotEfieft efTotEfieft = new EfIettFonteTotEfieft();
1177 
1178             EfIettFonteTotEfieftPK efTotEfieftPK = new EfIettFonteTotEfieftPK();
1179             efTotEfieftPK.setCodFonr(fonte.getCodFonr());
1180             efTotEfieftPK.setCodIett(iett.getCodIett());
1181 
1182             efTotEfieft.setComp_id(efTotEfieftPK);
1183             efTotEfieft.setDataInclusaoEfieft(new Date());
1184             efTotEfieft.setIndAtivoEfieft("S");
1185             efTotEfieft.setItemEstruturaIett(iett);
1186             efTotEfieft.setFonteRecursoFonr(fonte);
1187 
1188             // Acrescenta o objeto na lista que será salva posteriormente no
1189             // banco.
1190             fontesTotEfieft.add(efTotEfieft);
1191           }
1192 
1193         }
1194 
1195         int anoInicio = Integer.parseInt(new SimpleDateFormat("yyyy").format(iett.getDataInicioIett()));
1196         int anoFim = anoInicio;
1197 
1198         if (iett.getDataTerminoIett() != null) {
1199           anoFim = Integer.parseInt(new SimpleDateFormat("yyyy").format((iett.getDataTerminoIett())));
1200         }
1201 
1202         // loop dos anos a serem gerados ocorrências (contas)
1203         for (int inicio = anoInicio; inicio <= anoFim; inicio++) {
1204 
1205           List<EfItemEstContaEfiec> contas = new ArrayList<EfItemEstContaEfiec>();
1206 
1207           int contador = (fontesRecurso.size() * recursos.size());
1208 
1209           for (int i = 1; i <= contador; i++) {
1210 
1211             EfItemEstContaEfiec conta = new EfItemEstContaEfiec();
1212 
1213             for (ExercicioExe exercicio : exercicios) {
1214 
1215               int ano = Integer.parseInt(new SimpleDateFormat("yyyy").format(exercicio.getDataInicialExe()));
1216 
1217               if (inicio == ano) {
1218                 conta.setExercicioExe(exercicio);
1219                 break;
1220               }
1221             }
1222 
1223             conta.setIndAtivoEfiec("S");
1224             conta.setIndAcumuladoEfiec("N");
1225             conta.setFormaInclusao(Dominios.CONTA_FORMA_INCLUSAO_VIA_IMPORTACAO);
1226             conta.setContaSistemaOrcEfiec(iett.getSiglaIett().trim() + " " + obra);
1227             conta.setItemEstruturaIett(iett);
1228 
1229             contas.add(conta);
1230           }
1231 
1232           for (Iterator<EfItemEstContaEfiec> itContas = contas.iterator(); itContas.hasNext();) {
1233 
1234             EfItemEstContaEfiec conta = itContas.next();
1235 
1236             for (Iterator<FonteRecursoFonr> itFontes = fontesRecurso.iterator(); itFontes.hasNext();) {
1237 
1238               FonteRecursoFonr fonte = itFontes.next();
1239               conta.setContaSistemaOrcEfiec(conta.getContaSistemaOrcEfiec() + " " + fonte.getSiglaFonr().trim());
1240               conta.setFonteRecursoFonr(fonte);
1241               // Tá invertido, o Recurso responde pela Fonte do recurso e
1242               // vice-versa
1243               for (Iterator<RecursoRec> itRecursos = recursos.iterator(); itRecursos.hasNext();) {
1244 
1245                 RecursoRec recurso = itRecursos.next();
1246                 conta.setContaSistemaOrcEfiec(conta.getContaSistemaOrcEfiec().trim() + " " + recurso.getSiglaRec().trim());
1247                 conta.setRecursoRec(recurso);
1248 
1249                 if (itContas.hasNext() && itRecursos.hasNext()) {
1250                   conta = itContas.next();
1251                   conta.setFonteRecursoFonr(fonte);
1252                   conta.setContaSistemaOrcEfiec(conta.getContaSistemaOrcEfiec().trim() + " " + fonte.getSiglaFonr().trim());
1253                 }
1254                 else if (itContas.hasNext() && itFontes.hasNext()) {
1255                   conta = itContas.next();
1256                 }
1257               }
1258             }
1259 
1260           }
1261 
1262           todasContas.addAll(contas);
1263         }
1264 
1265         ItemEstruturaPrevisaoDao iePrevisaoDao = new ItemEstruturaPrevisaoDao(request);
1266         List<EfItemEstContaEfiec> listaPersistenciaContas = new ArrayList<EfItemEstContaEfiec>();
1267 
1268         // Verifica se as contas a serem inseridas já não existem no Sistema.
1269         for (EfItemEstContaEfiec objConta : todasContas) {
1270 
1271           q = this.session.createQuery("from EfItemEstContaEfiec where contaSistemaOrcEfiec = :conta and " + "fonteRecursoFonr = :fonteRecursoFonr and " + "exercicioExe = :exercicioExe and " + "recursoRec = :recursoRec");
1272           q.setString("conta", objConta.getContaSistemaOrcEfiec());
1273           q.setLong("fonteRecursoFonr", objConta.getFonteRecursoFonr().getCodFonr());
1274           q.setLong("exercicioExe", objConta.getExercicioExe().getCodExe());
1275           q.setLong("recursoRec", objConta.getRecursoRec().getCodRec());
1276 
1277           if (q.list().size() == 0) {
1278             listaPersistenciaContas.add(objConta);
1279           }
1280         }
1281 
1282         // Salva os objetos no banco
1283         for (EfItemEstContaEfiec obj : listaPersistenciaContas) {
1284 
1285           EfItemEstPrevisaoEfiep objEfiep = null;
1286           try {
1287             objEfiep = iePrevisaoDao.buscar(obj.getItemEstruturaIett().getCodIett(), obj.getFonteRecursoFonr().getCodFonr(), obj.getRecursoRec().getCodRec(), obj.getExercicioExe().getCodExe());
1288 
1289           } catch (Exception e) {
1290             // Significa que não achou registro e poderá ser inserido um novo
1291             // objeto no banco.
1292             objEfiep = new EfItemEstPrevisaoEfiep();
1293 
1294             EfItemEstPrevisaoEfiepPK pk = new EfItemEstPrevisaoEfiepPK();
1295             pk.setCodExe(obj.getExercicioExe().getCodExe());
1296             pk.setCodFonr(obj.getFonteRecursoFonr().getCodFonr());
1297             pk.setCodIett(obj.getItemEstruturaIett().getCodIett());
1298             pk.setCodRec(obj.getRecursoRec().getCodRec());
1299 
1300             objEfiep.setComp_id(pk);
1301             objEfiep.setDataInclusaoEfiep(new Date());
1302             objEfiep.setExercicioExe(obj.getExercicioExe());
1303             objEfiep.setFonteRecursoFonr(obj.getFonteRecursoFonr());
1304             objEfiep.setIndAtivoEfiep("S");
1305             objEfiep.setItemEstruturaIett(obj.getItemEstruturaIett());
1306             objEfiep.setRecursoRec(obj.getRecursoRec());
1307             objEfiep.setValorAprovadoEfiep(new BigDecimal(0));
1308             objEfiep.setValorRevisadoEfiep(new BigDecimal(0));
1309 
1310             /*
1311              * FIXME: Verificar esta regra Está fixo, pois falta fazer na tela
1312              * para informar a espécie e a fonte rec 3 = fonte 49 rec 4 = fonte
1313              * 50 rec 5 = fonte 51
1314              */
1315             if (objEfiep.getEspecieEsp() == null) {
1316               objEfiep.setEspecieEsp((EspecieEsp) buscar(EspecieEsp.class, Long.valueOf(0)));
1317               objEfiep.setEspecieEsp(objEfiep.getEspecieEsp());
1318             }
1319 
1320             // if(objEfiep.getFonteFon() == null){
1321             // if(objEfiep.getRecursoRec().getCodRec().longValue() == 3){
1322             // objEfiep.setFonteFon((FonteFon) buscar(FonteFon.class,
1323             // Long.valueOf(49)));
1324             // }
1325             // if(objEfiep.getRecursoRec().getCodRec().longValue() == 4){
1326             // objEfiep.setFonteFon((FonteFon) buscar(FonteFon.class,
1327             // Long.valueOf(50)));
1328             // }
1329             // if(objEfiep.getRecursoRec().getCodRec().longValue() == 5){
1330             // objEfiep.setFonteFon((FonteFon) buscar(FonteFon.class,
1331             // Long.valueOf(51)));
1332             // }
1333             // objEfiep.getComp_id().setCodFon(objEfiep.getFonteFon().getCodFon());
1334             // }
1335 
1336             session.save(objEfiep);
1337           }
1338 
1339           session.save(obj);
1340         }
1341 
1342         // Salva os objetos no banco
1343         for (EfIettFonteTotEfieft obj : fontesTotEfieft) {
1344           session.save(obj);
1345         }
1346 
1347       }
1348 
1349       tx.commit();
1350 
1351     } catch (ECARException e) {
1352       if (tx != null)
1353         try {
1354           tx.rollback();
1355         } catch (HibernateException r) {
1356           this.logger.error(r);
1357           throw new ECARException("erro.hibernateException");
1358         }
1359       this.logger.error(e);
1360       throw e;
1361     } catch (Exception e) {
1362       if (tx != null)
1363         try {
1364           tx.rollback();
1365         } catch (HibernateException r) {
1366           this.logger.error(r);
1367           throw new ECARException("erro.hibernateException");
1368         }
1369       this.logger.error(e);
1370       throw new ECARException("erro.hibernateException");
1371     }
1372 
1373   }
1374 
1375   /**
1376    * Exclui um objeto passando a classe e a chave como parâmetro. Primeiro
1377    * carrega o objeto<br>
1378    */
1379   public void excluir(ConfigSisExecFinanCsef obj) throws ECARException {
1380 
1381     try {
1382 
1383       boolean excluir = true;
1384 
1385       if ((contar(obj.getFonteRecursoFonrs()) > 0) || (contar(obj.getConfigSisExecFinanCsefvs()) > 0)) {
1386         excluir = false;
1387         throw new ECARException("integracaoFinanceira.sistema.exclusao.erro");
1388       }
1389       if (excluir)
1390         super.excluir(obj);
1391     } catch (ECARException e) {
1392       this.logger.error(e);
1393       throw e;
1394     }
1395 
1396   }
1397 
1398   public static BigDecimal toBigDecimal(String valor) {
1399 
1400     String inteiros = valor.substring(0, valor.length() - 2);
1401     String decimais = valor.substring(valor.length() - 2);
1402 
1403     String valorFormatado = inteiros + "." + decimais;
1404 
1405     BigDecimal retorno = new BigDecimal(valorFormatado);
1406     return retorno;
1407   }
1408 
1409 }