Estudo Técnico para separar a Carta Remessa em PDF por Identificador
Data de elaboração | 17/07/2023 |
---|---|
Responsável pelo estudo |
Ádrian Rabelo Mendes (Assessor) |
Equipe do estudo | CAOS |
Alvo |
Sistema Governa |
Origem |
|
Objetivo | para que seja atendida a demanda de agilizar a demanda diária de desbloqueios de pagamentos e a respectiva disponibilização das cartas remessas em cada processo SEI (demanda Nº: 0031.072694/2022-33) |
Glossário
FEBRABANEBRABAN – Federação Brasileira de Bancos
CNAB240 – Centro Nacional de Automação Bancária
1. Introdução
A carta remessa é um documento ou arquivo eletrônico contendo detalhes de uma transação ou série de transações a serem processadas por um banco ou outra instituição financeira. Estes detalhes podem incluir informações sobre o remetente e o destinatário do pagamento, o valor da transação, a data da transação, entre outros.
Atualmente, as Cartas Remessa são produzidas em um formato padrão definido pela Federação Brasileira de Bancos (FEBRABAN), conhecido como CNAB240. Este formato estruturado facilita o processamento automatizado das transações pelos bancos e é amplamente aceito em todo o setor bancário brasileiro.
No sistema Governa, a geração da carta remessa é feita por um processo que envolve várias etapas. Neste estudo, iremos explorar estas etapas em detalhes, e fornecer recomendações para a implementação da separação dos relatórios nela gerados.
2. Desenvolvimento
2.1 ComoGeração é gerada ada Carta Remessa?Remessa
A carta remessa pode ser gerada através do seguinte menu no sistema Governa, módulo de Recursos Humanos:
Movimentação Mensal > Controle Bancário > Carta Remessa > Emitir
Na figura 2, na tela de emissão de Carta Remessa, podemos observar diversas opções para que o usuário possa escolher no evento da geração da mesma.
Para gerar a Carta remessa, o usuário precisará preencher todos os campos obrigatórios, marcados com asterisco * e acionar o botão Executar. Se a carta remessa nas condições que o usuário escolheu já foi gerada, o botão Baixar Relatório estará ativo, permitindo assim, que o usuário faça download do arquivo gerado.
Ao clicar no botão Executar, o sistema começará a realizar as etapas do método executar() na classe CartaRemessaMB.java, conforme podemos ver nos métodos comentados do código abaixo.
CartaRemessaMB.java - Método executar
public void executar() {
try {
// Verifica se há permissão para o usuário inserir sem validar o mês fechado.
isPermissaoBotaoInserirSemValidarMesFechado();
// Define a lista de verbas selecionadas nas verbas da carta remessa
this.cartaRemessa.setVerbas(verbaSelecionadaList);
// Define o mês de referência buscando da classe pai
String mesRefLogado = super.getMesReferenciaFormatado();
// Define a lista de cartaRemessaid de acordo com o retorno do método
// executar(cartaremessa, mesRefLogado) da instância da classe
// CartaRemessaBO. Essa por sua vez, é responsável por gerar as cartas
// remessas e retorna uma lista com as id’s caso sejam geradas.
this.listaCartaRemessaid = cartaRemessaBO.executar(this.cartaRemessa,mesRefLogado);
// Se gerou carta, entao gera o relatório
if (!listaCartaRemessaid.isEmpty()) {
// Define o modelo de acordo com o modelo da carta remessa enviado pelo usuário
setModelo(this.cartaRemessa.getModelo());
// Gera o arquivo zip de saída contendo os relatórios
file = this.gerarRelatorioCartaRemessa("", CartaRemessaModeloEnum.parse(
cartaRemessa.getModelo()).getDescricaoFormatada(), MesReferenciaUtil
.converterMesAnoParaAnoMesReferencia(
cartaRemessa.getMesReferencia()).toString(), ""
);
// Envia uma mensagem para o usuário informando que o registro foi //cadastrado com sucesso
super.enviarMensagemInfo(msgServico.getMsgGenericaRegistroCadastradoComSucesso(EntidadeRhEnum.CARTA_REMESSA));
// Envia uma mensagem para o usuário informando que o relatório foi gerado
super.enviarMensagemInfo(msgServico.getMensagem(MensagemChaveRh.CARTA_REMESSA_IMPRIMIR_RELATORIO));
} else {
// Envia uma mensagem para o usuário informando que não foi gerado carta remessa
super.enviarMensagemInfo(msgServico.getMensagem(MensagemChaveRh.CARTA_REMESSA_NAO_GERADAS));
}
// Captura os erros caso ocorram e retornam ao usuário a mensagem do erro
} catch (RestricaoNegocioExcecao e) {
log.warn(e.getMessage());
super.enviarMensagemErro(e.getMessage());
} catch (CampoObrigatorioNaoInformadoExcecao e) {
log.warn(e.getMessage());
super.enviarMensagemErro(msgServico.getMsgGenericaCampoObrigatorioNaoInformado(
e.getCamposNaoInformadosFormatado()));
} catch (RelatorioGeracaoExcecao e) {
log.error(e.getMessage(), e);
super.enviarMensagemErro(msgServico.getMsgGenericaErroInesperado(e.getMessage()));
} finally {
System.gc();
}
}
CartaRemessaBO.java - Método executar
public List<Long> executar(CartaRemessa cartaRemessa, String mesRefLogado)
throws RestricaoNegocioExcecao, CampoObrigatorioNaoInformadoExcecao {
// Gera logs
log.info("Gerando carta remessa [{}]", cartaRemessa.getMesReferencia());
log.info("Gerando carta remessa mesReferencia Logado [{}]", mesRefLogado);
// Valida se os campos obrigatórios foram preenchidos
validarCamposObrigatorios(cartaRemessa);
// realiza uma série de verificações de regras de negócios em um objeto CartaRemessa.
// Primeiro, verifica se o modelo de CartaRemessa é uma "Carta Acerto" e se certas condições são cumpridas.
// Se não forem, uma exceção é lançada. Em seguida, se o objeto CartaRemessa tiver um número, o método
// verifica se já existe um arquivo bancário associado a esse número e modelo. Se existir, outra exceção
// é lançada. Depois, procura uma CartaRemessa existente com o mesmo número e, se encontrada, atualiza os
// valores de lotacaoInicial e lotacaoFinal e o modelo do objeto CartaRemessa original, e então exclui
// a CartaRemessa encontrada.
validarRegraNegocio(cartaRemessa);
// Instancia a interface ICartaRemessaServiço de acordo com o modelo da carta remessa
ICartaRemessaServico cartaRemessaServico = cartaRemessaServicoFabrica.getServico(cartaRemessa.getCartaRemessaModeloEnum());
// Chama o método gerarCartaRemessa(cartaRemessa, mesRefLogado do serviço cartaRemessaServiço
return cartaRemessaServico.gerarCartaRemessa(cartaRemessa, mesRefLogado);
}
CartaRemessaAcertoSalarioLiquidoServico.java - Método gerarCartaRemessa
public List<Long> gerarCartaRemessa(CartaRemessa cartaRemessa, String mesRefLogado) throws RestricaoNegocioExcecao {
// Log
log.debug("Gerando o Acerto da Carta Remessa do Tipo {}", cartaRemessa.getCartaRemessaModeloEnum().getDescricaoFormatada());
// Retorna o resultado da função gerarAcerto(cartaRemessa, mesRefLogado)
return gerarAcerto(cartaRemessa, mesRefLogado);
}
AbstractCartaRemessaServico.java - Método gerarAcerto
protected List<Long> gerarAcerto(CartaRemessa cartaRemessa, String mesRefLogado) throws RestricaoNegocioExcecao {
// cria lista de objetos do tipo CartaRemessaDetalhe
List<CartaRemessaDetalhe> cartaRemessaDetalheList = cartaRemessaDetalhePersistencia.buscarCartaRemessaDetalheGerarCartaRemessaDoisAcerto(
QueryUtil.prepararParametro(cartaRemessa.getLotacaoInicial()), cartaRemessa.getLotacaoFinal(),
QueryUtil.prepararParametro(cartaRemessa.getMatriculaInicial()), QueryUtil.prepararParametro(cartaRemessa.getMatriculaFinal()),
QueryUtil.prepararParametro(cartaRemessa.getIdentificadorUnidadeGestora()), QueryUtil.prepararParametro(cartaRemessa.getRotina()),
MesReferenciaUtil.converterMesAnoParaAnoMesReferencia(cartaRemessa.getMesReferencia()),
QueryUtil.prepararParametro(cartaRemessa.getCartaRemessaModeloEnum().getDuasPosicoesFinais()));
// Adiciona diversos parâmetros ao final da lista cartaRemessaDetalheList
cartaRemessaDetalheList.addAll(cartaRemessaDetalhePersistencia.buscarCartaRemessaDetalheGerarCartaRemessaAcerto(
QueryUtil.prepararParametro(cartaRemessa.getLotacaoInicial()), cartaRemessa.getLotacaoFinal(),
QueryUtil.prepararParametro(cartaRemessa.getMatriculaInicial()), QueryUtil.prepararParametro(cartaRemessa.getMatriculaFinal()),
QueryUtil.prepararParametro(cartaRemessa.getIdentificadorUnidadeGestora()), QueryUtil.prepararParametro(cartaRemessa.getRotina()),
MesReferenciaUtil.converterMesAnoParaAnoMesReferencia(cartaRemessa.getMesReferencia()),
QueryUtil.prepararParametro(cartaRemessa.getCartaRemessaModeloEnum().getDuasPosicoesFinais())));
// retorna o resultado da função montarCartaAcerto(cartaRemessa, cartaRemessaDetalheList, mesRefLogado)
return montarCartaAcerto(cartaRemessa, cartaRemessaDetalheList, mesRefLogado);
}
AbstractCartaRemessaServico.java - Método montarCartaAcerto
private List<Long> montarCartaAcerto(CartaRemessa cartaRemessa, List<CartaRemessaDetalhe> detalhes, String mesRefLogado)
throws RestricaoNegocioExcecao {
// Verifica se a lista de detalhes da carta de remessa está vazia. Se estiver, retorna uma lista vazia.
if (detalhes.isEmpty()) {
return Collections.emptyList();
}
// Verifica se ja tem algum arquivo bancário gerado sem retorno
List<Long> servidoresParaAcerto = new ArrayList<>();
detalhes.forEach(item -> servidoresParaAcerto.add(item.getServidorMensal().getId()));
// A lista de chave sera utilizada para verificar se o servidor/pensao
// judicial/pensao vitalicia ja tiveram acerto gerado, ou carta sem retorno
List<String> detalhesChaves = new ArrayList<>();
detalhes.forEach(item -> detalhesChaves.add(item.getChave()));
// Busca os servidor que ja tem acerto
List<ArquivoBancario> arquivoJaGerado = new ArrayList<>();
int cont = 0;
int it = servidoresParaAcerto.size();
List<Long> idsServidorTemp = new ArrayList<>();
for (Long id : servidoresParaAcerto) {
idsServidorTemp.add(id);
cont++;
if (idsServidorTemp.size() == 2000 || cont == it) {
arquivoJaGerado.addAll(cartaRemessaDetalhePersistencia.buscarServidorQueJaTenhamAcerto(idsServidorTemp,
MesReferenciaUtil.converterMesAnoParaAnoMesReferencia(cartaRemessa.getMesReferencia()), cartaRemessa.getModelo(),
cartaRemessa.getRotina()));
idsServidorTemp.clear();
}
}
// Verifica se ja teve algum retorno com sucesso, caso tenha o mesmo sera
// retirado da nova carta
List<String> retirar = new ArrayList<>();
for (String chave : detalhesChaves) {
arquivoJaGerado.stream().forEach(arq -> {
if (chave.equals(arq.getChave())
&& ("00".equals(arq.getStatusRetorno()) || "BD".equals(arq.getStatusRetorno()) || "".equals(arq.getStatusRetorno()))) {
retirar.add(arq.getChave());
}
});
}
// Remove os servidores que ja teve sucesso
detalhes = detalhes.stream().filter(item -> !retirar.contains(item.getChave())).collect(Collectors.toList());
// Remover os servidores que estao sem arquivo, ou seja, ja estao em carta mais
// não tem arquivo gerado
arquivoJaGerado.clear();
retirar.clear();
List<CartaRemessaDetalhe> servidoresSemArquivo = new ArrayList<>();
cont = 0;
it = servidoresParaAcerto.size();
idsServidorTemp = new ArrayList<>();
for (Long id : servidoresParaAcerto) {
idsServidorTemp.add(id);
cont++;
if (idsServidorTemp.size() == 2000 || cont == it) {
servidoresSemArquivo.addAll(cartaRemessaDetalhePersistencia.buscarServidorQueJaTenhamAcertoENaoTermArquivoBancario(idsServidorTemp,
MesReferenciaUtil.converterMesAnoParaAnoMesReferencia(cartaRemessa.getMesReferencia()), cartaRemessa.getModelo(),
cartaRemessa.getRotina()));
idsServidorTemp.clear();
}
}
servidoresSemArquivo.forEach(item -> retirar.add(item.getChave()));
detalhes = detalhes.stream().filter(item -> !retirar.contains(item.getChave())).collect(Collectors.toList());
// Se não tiver resultado envia mensagem
if (detalhes.isEmpty()) {
throw new RestricaoNegocioExcecao(mensagemServicoRh.getMensagem(MensagemChaveRh.MENSAGEM_GERACAO_CARTA_REMESSA_SEM_RESULTADO));
}
// Agrupa os detalhes da carta remessa restantes por lotacaoMensalId e armazena em um mapa.
Map<Long, List<CartaRemessaDetalhe>> cartaRemessaDetalhePorLotacaoMensalId = new HashMap<>();
detalhes.forEach(item -> {
Long lotacaoMensalId = item.getCartaRemessa().getLotacaoMensal().getId();
if (cartaRemessaDetalhePorLotacaoMensalId.containsKey(lotacaoMensalId)) {
cartaRemessaDetalhePorLotacaoMensalId.get(lotacaoMensalId).add(item);
} else {
cartaRemessaDetalhePorLotacaoMensalId.put(lotacaoMensalId, new ArrayList<CartaRemessaDetalhe>(Arrays.asList(item)));
}
});
List<Long> cartaRemessaGeradaIdList = new ArrayList<>();
List<String> matriculasJaEnviadas = new ArrayList<>();
// Para cada lotacaoMensalId, cria uma nova carta remessa. Calcula o valor total da nova
// carta remessa somando os valores de todos os detalhes da carta remessa que pertencem a essa lotacaoMensalId.
for (Long chave : cartaRemessaDetalhePorLotacaoMensalId.keySet()) {
List<CartaRemessaDetalhe> cartaRemessaDetalheMapList = cartaRemessaDetalhePorLotacaoMensalId.get(chave);
// Soma Total da Carta Remessa
Fracao valorTotalCarta = new Fracao(0d);
// Lista para armazenas os detalhes da carta remessa
List<CartaRemessaDetalhe> cartaRemessaDetalheList = new ArrayList<>();
// Cria a Carta Remessa
CartaRemessa novaCartaRemessa = criarCartaRemessa(cartaRemessa.getRotinaCalculoEnum(), cartaRemessa.getCartaRemessaModeloEnum(),
cartaRemessaDetalheMapList.get(0).getCartaRemessa().getLotacaoMensal().getContaDebito().getContaDebito(),
cartaRemessaDetalheMapList.get(0).getCartaRemessa().getLotacaoMensal().getContaDebito().getConvenio(),
cartaRemessaDetalheMapList.get(0).getCartaRemessa().getLotacaoMensal().getContaDebito().getAgencia(),
cartaRemessaDetalheMapList.get(0).getCartaRemessa().getLotacaoMensal(), cartaRemessa.getNumero());
for (CartaRemessaDetalhe item : cartaRemessaDetalheMapList) {
if (item.getValor() > 0d) {
if (!matriculasJaEnviadas.contains(item.getChave())) {
matriculasJaEnviadas.add(item.getChave());
valorTotalCarta = valorTotalCarta.somarCom(new Fracao(item.getValor()));
cartaRemessaDetalheList.add(item);
}
}
}
// Atualiza os dados bancários para os detalhes da carta de remessa,
// salva a nova carta de remessa, e salva os detalhes da carta de remessa.
if (!cartaRemessaDetalheList.isEmpty()) {
atualizarDadosBancarios(cartaRemessaDetalheList);
// Valor Total da Carta
novaCartaRemessa.setValor(valorTotalCarta.doubleValor());
// Salva a Carta Remessa
salvarCartaRemessa(novaCartaRemessa);
// Salva os Itens da Carta Remessa Detalhe
salvarCartaRemessaDetalhe(novaCartaRemessa, cartaRemessaDetalheList, mesRefLogado);
// preenche a lista com todos os ids das carta remessas geradas
cartaRemessaGeradaIdList.add(novaCartaRemessa.getId());
}
}
// Retorna uma lista de IDs de todas as cartas de remessa que foram geradas
return cartaRemessaGeradaIdList;
}
Como podemos perceber no código acima, dentro do método montarCartaAcerto, nas linhas 78 a 86 , a organização de cartas remessa por lotação mensal já é executada de forma integral. Isso é feito por meio da construção de um mapa, no qual o ID da lotação mensal atua como chave, e os detalhes da carta remessa que correspondem àquela lotação mensal se tornam os valores associados a essa chave. Essa estruturação permite que todas as cartas remessa sejam automaticamente categorizadas de acordo com a respectiva lotação mensal.
2.2 RabbitMQ
Separação dos Relatórios
O RabbitMQ é um software de mensagem assíncrona de código aberto, que implementaAtualmente, o protocolosistema AMQPGoverna (Advanced Message Queuing Protocol). Ele é amplamente utilizado como um intermediário de mensagens entre diferentes sistemas e serviços distribuídos.
O RabbitMQ fornece uma plataforma robusta para a troca de mensagens, permitindo que aplicativos e serviços se comuniquem de maneira eficiente e confiável. Ele utiliza filas de mensagens para armazenar e entregar as mensagens entregera os produtoresrelatórios eda consumidores,Carta garantindo a entrega ordenada e controlada.
2.3 TelasRemessa em questão
Na Etapa 1, a função buscarListaCartaremessaDetalheVisao() é chamada para buscar os detalhes da Carta Remessa. Os detalhes são retornados como uma lista de objetos CartaRemessaDetalheVisao.
Na 2.4Etapa Objeto2, JSONa função gerarRelatorioCartaRemessa()
Oé objetochamada JSONcom recebidoa pelo serviçolista de mensageriadetalhes RabbitMQda éCarta provenienteRemessa de ações realizadasobtida na entidadeetapa "Servidor"1. noEsta sistema e-Estado. Dentre as ações inclui-se: criação, atualizaçfunção degera dadosum relatório baseado nos detalhes fornecidos e exclusão.
Oum objetoByteArrayOutputStream JSONque contém diversos campos que representam os dados do servidor,relatório.
Na identificaçEtapa 3, a função,o matrícula,gerarStreamZip() é chamada com o ByteArrayOutputStream gerado na etapa 2. Esta função define o nome do arquivo zip, prepara um fluxo de download com o arquivo para o relatório, que pode ser enviado para o cliente para download.
Etapa 1 - CartaRemessaBO - Método - BuscarListaCartaRemessaDetalheVisao
public List<CartaRemessaDetalheVisao> buscarListaCartaremessaDetalheVisao(CartaRemessa cartaRemessa, List<Long> idsCarta) {
// Verifica se a lista de idsCarta possui menos de 2000 elementos
if (idsCarta.size() < 2000) {
// Verifica o tipo de vínculo, datamodelo de admissão,carta entreremessa
outros.if Essas(CartaRemessaModeloEnum.eCartaConsignacao(cartaRemessa.getCartaRemessaModeloEnum())) informações{
sã// Busca os detalhes da carta remessa consignação cruciaispelo idCartaRemessaDetalhe
return cartaRemessaDetalheConsignacaoRepositorio
.findCartaRemessaDetalheVisaoByIdCartaRemessaDetalhe(QueryUtil.preparaParametroListaNaoVazia(idsCarta));
} else {
// Busca os detalhes da carta remessa pelo idCartaRemessaDetalhe
return cartaRemessaDetalheRepositorio
.findCartaRemessaDetalheVisaoByIdCartaRemessaDetalhe(QueryUtil.preparaParametroListaNaoVazia(idsCarta));
}
}
List<CartaRemessaDetalheVisao> lista = new ArrayList<>();
List<Long> idsCartaTemp = new ArrayList<>();
// Itera sobre os idsCarta
for (int i = 0; i < idsCarta.size(); i++) {
// Adiciona o idCarta atual na lista temporária idsCartaTemp
idsCartaTemp.add(idsCarta.get(i));
// Verifica se atingiu o limite de 2000 elementos na lista temporária
if (i % 2000 == 0) {
// Verifica o tipo de modelo de carta remessa
if (CartaRemessaModeloEnum.eCartaConsignacao(cartaRemessa.getCartaRemessaModeloEnum())) {
// Busca os detalhes da carta remessa consignação pelo idCartaRemessaDetalhe na lista temporária
lista.addAll(cartaRemessaDetalheConsignacaoRepositorio
.findCartaRemessaDetalheVisaoByIdCartaRemessaDetalhe(QueryUtil.preparaParametroListaNaoVazia(idsCartaTemp)));
// Limpa a lista temporária para acompanharos epróximos registrarelementos
idsCartaTemp.clear();
} else {
// Busca os detalhes da carta remessa pelo idCartaRemessaDetalhe na lista temporária
lista.addAll(cartaRemessaDetalheRepositorio
.findCartaRemessaDetalheVisaoByIdCartaRemessaDetalhe(QueryUtil.preparaParametroListaNaoVazia(idsCartaTemp)));
// Limpa a lista temporária para os próximos elementos
idsCartaTemp.clear();
}
}
}
// Busca os detalhes restantes que não históricoforam dosbuscados servidoresna no sistema. Abaixo pode-se conferir iteração objetoanterior
deif retorno(CartaRemessaModeloEnum.eCartaConsignacao(cartaRemessa.getCartaRemessaModeloEnum())) do{
serviç// Busca os detalhes da carta remessa consignação rabbitMQ.pelo idCartaRemessaDetalhe na lista temporária
lista.addAll(cartaRemessaDetalheConsignacaoRepositorio
.findCartaRemessaDetalheVisaoByIdCartaRemessaDetalhe(QueryUtil.preparaParametroListaNaoVazia(idsCartaTemp)));
} else {
// Busca os detalhes da carta remessa pelo idCartaRemessaDetalhe na lista temporária
lista.addAll(cartaRemessaDetalheRepositorio
.findCartaRemessaDetalheVisaoByIdCartaRemessaDetalhe(QueryUtil.preparaParametroListaNaoVazia(idsCartaTemp)));
}
return lista;
}
QuandoEtapa a2 ação- éAbstractCartaRemessaMB.java INSERT,- oMétodo RabbitMQ retorna o seguinte objeto:gerarRelatorioCartaRemessa
{public "id":StreamedContent 215349,gerarRelatorioCartaRemessa(String "matricula":numeroCarta, 600003369,String "tipo_vinculo_id":nomeCartaRemessa, 7,String "data_admissao":mesReferencia, "15/12/2022",String "concurso_id":lotacaoCodigo)
null,throws "numero_decreto": null,
"data_decreto": null,
"numero_diario_oficial": null,
"data_diario_oficial": null,
"data_posse": null,
"data_efetivo_exercicio": null,
"cargo_efetivo_id": null,
"cargo_cds_id": null,
"funcao_id": null,
"unidade_vinculo_id": 2,
"previdencia_id": null,
"vinculo_original_id": null,
"estado_id": null,
"municipio_id": null,
"poder_id": null,
"regime_id": null,
"conta_fgts": null,
"unidade_pagamento_id": null,
"conta_pagamento_id": null,
"padrao_id": null,
"horas_semanais": null,
"horas_extras": null,
"registro_ponto_id": null,
"pessoa_id": 1758202,
"plantonista": null,
"habilidade_cargo_efetivo_id": null,
"inscricao_concurso": null,
"nota_final_concurso": null,
"classificacao_concurso": null,
"pcd": null,
"negro": null,
"processo_judicial": null,
"ocupa_cargo_publico": null,
"processo_sei": null,
"oficio_apresentacao": null,
"municipio_concurso_lotacao_id": null,
"data_desligamento": null,
"siape": null,
"atividade_privativa_cargo": null,
"matricula_antiga": null,
"matricula_nome": "600003369 - Lucas Teste",
"estado": null,
"municipio": null,
"departamento_id": "",
"cargo_efetivo": null,
"cargo_cds": null,
"concurso": null,
"funcao": null,
"padrao": null,
"pessoa":RelatorioGeracaoExcecao {
"id": 1758202,
"nome": "Lucas Teste",
"data": "2023-06-23T08:34:21.500402"
},
"pessoa_fisica":try {
"pessoa_id":List<CartaRemessaDetalheVisao> 1758202,listaCartaRemessaDetalheVisao "estado_civil_id":= 2,this.buscarListaCartaRemessaDetalheVisao();
"sexo_id":// 1,Removida "escolaridade_id":a null,geração "tipo_sanguineo_id":do null,arquivo "cpf":para "22******50"o banco a pedido do cliente
// ByteArrayOutputStream relatorioCartaRemessaViaBanco = geradorCartaRemessa.gerarRelatorioCartaRemessa(
// super.getEmpresaAutenticada(),
"data_nascimento":// "2003-05-10"this.cartaRemessa, listaCartaRemessaDetalheVisao, IRelatorioCartaRemessaGerador.ViaCartaRemessa.BANCO);
ByteArrayOutputStream relatorioCartaRemessaViaFinanceiro = geradorCartaRemessa.gerarRelatorioCartaRemessa(
super.getEmpresaAutenticada(), "falecimento":this.cartaRemessa, null,listaCartaRemessaDetalheVisao,
"raca":IRelatorioCartaRemessaGerador.ViaCartaRemessa.FINANCEIRO);
null,return "pcd":this.gerarStreamZip(relatorioCartaRemessaViaFinanceiro, null,numeroCarta, "tipo_nacionalidade":nomeCartaRemessa,
null,mesReferencia, "nacionalidade": null,
"pais": null,
"estado": null,
"naturalidade": null,
"data_entrada": "2003-05-10",
"pis_pasep": null,
"email": "sor*****@g****.com",
"doador_de_sangue": null,
"raca_id": 5,
"tipo_nacionalidade_id": 2,
"pais_id": 1,
"nacionalidade_id": 1,
"estado_id": 21,
"naturalidade_id": 5582lotacaoCodigo);
}, "poder":catch null,(Exception "previdencia": null,
"regime": null,
"registro_ponto": null,
"tipo_vinculo":e) {
"id":throw 7,new "nome": "Estagiário",
"grupo": nullRelatorioGeracaoExcecao(e);
},
"unidade_vinculo": {
"id": 2,
"instituicao_id": 1,
"unidade_id": null,
"responsavel_id": 1744688,
"nome": "Superintendência Estadual de Tecnologia da Informação e Comunicação",
"sigla": "SETIC",
"gestora": 1,
"orcamentaria": 1,
"administrativa": 1,
"cnpj": "17.*****/******",
"id_departamento_sinvrea": null,
"tipo_normatizacao_id": 2,
"numero_normatizacao": "27.577",
"staff": null,
"colegiada": null,
"codigo_orcamentario": "110007",
"data_normatizacao": "2022-11-04",
"extincao_organograma_id": null,
"endereco_id": 49685,
"departamento_id": null,
"orgao_sei_id": 73,
"unidade_sei_id": null,
"data_criacao": null
},
"unidade_pagamento": null,
"vinculo_original": null,
"nome": "Lucas Teste"
}
Quando
Etapa 3 - AbstractCartaRemessaMB.java - Método gerarStreamZip
private StreamedContent gerarStreamZip(ByteArrayOutputStream relatorioCartaRemessaViaFinanceiro, String numeroCarta, String modeloArquivo, String mesReferencia, String lotacaoCodigo) throws IOException {
// Removido geração do arquivo para o banco a açpedido do cliente
// ArquivoOutputStream relatorioOutBanco = new ArquivoOutputStream(relatorioCartaRemessaViaBanco,
// String.format(IRelatorioCartaRemessaGerador.ARQUIVO_PDF_BANCO, numeroCarta, modeloArquivo, mesReferencia, lotacaoCodigo));
// recebe o relatorioCartaRemessaViaFinanceiro como entrada e utiliza a formatação éadequada UPDATE,para o RabbitMQnome do arquivo PDF financeiro, utilizando os parâmetros fornecidos.
ArquivoOutputStream relatorioOutFinanceiro = new ArquivoOutputStream(relatorioCartaRemessaViaFinanceiro,
String.format(IRelatorioCartaRemessaGerador.ARQUIVO_PDF_FINANCEIRO, numeroCarta, modeloArquivo, mesReferencia, lotacaoCodigo));
// Aqui, é criado um ByteArrayOutputStream chamado out para armazenar os dados do arquivo ZIP. A função ZipUtil.zipar() é chamada para compactar o relatorioOutFinanceiro e armazenar o resultado no out.
ByteArrayOutputStream out = new ByteArrayOutputStream();
ZipUtil.zipar(out, relatorioOutFinanceiro);
// permite que os dados do arquivo ZIP sejam lidos a partir de um fluxo de entrada.
InputStream is = new ByteArrayInputStream(out.toByteArray());
gerouRelatorio = true;
// O nome do arquivo ZIP é formatado e é removido qualquer espaço em branco ou acentuação indesejada utilizando funções auxiliares.
String zipNome = String.format(IRelatorioCartaRemessaGerador.ARQUIVO_ZIP, numeroCarta, modeloArquivo, mesReferencia, lotacaoCodigo)
.replace(" ", "");
zipNome = StringUtil.removerAcentos(zipNome);
// retorna o seguintearquivo objeto:
zip {para download com nome definido
return new DefaultStreamedContent(is, "id": 1534244,
"nome": "JESSE ELIAS VIEIRA CAMPOS "application/zip", "cpf": "00******56",
"data_nascimento": "****-**-**",
"rg": {
"registro": 3**6,
"rg": "1******5",
"orgao_emissor": "SSP",
"estado": "RO",
"data_emissao": "15/02/2008"
},
"nome_mae": null,
"data_nascimento_mae": null,
"sexo": 1,
"estado_civil": 1,
"raca": 2,
"tipo_sanguineo": 1,
"escolaridade": 5,
"nacionalidade_bacen": 1058,
"naturalidade": "Porto Velho",
"pis": {
"pessoa_id": 1534244,
"tipo_documento_id": 11,
"numero": "1*******7"
},
"titulo_eleitor": {
"pessoa_id": 1534244,
"tipo_documento_id": 3,
"registro": 4***7,
"numero": "0**********6",
"complemento1": "0*2",
"complemento2": "0**7",
"data_emissao": null
},
"endereco": {
"rua": "Rua *******",
"numero": ****,
"complemento": "RE******** *****A",
"bairro": "Nova Esperança",
"cep": 7*****8,
"cidade": {
"id": 5582,
"nome": "Porto Velho",
"cod_ibge": 1100205,
"estado_id": 21
},
"estado": {
"id": 21,
"nome": "Rondônia",
"sigla": "RO",
"codigo_ibge": 11,
"pais_id": 1
}
},
"deficiencias": [],
"parentes": []zipNome);
}
2.43 CamposSeparação Integradosdos Relatórios por Lotação
OsWORK seguintesIN campos podem refletir-se em ambos os sistemas:PROGRESS....
Tabela Governa
Campo
Governa
e-Estado
Obs
rh.servidor
Matrícula
matricula
matricula
--
Data de Admissão
admissao
objeto servidor.data_admissao
--
Data do Efetivo Exercício
data_efetivo_exercicio
objeto servidor.data_efetivo_exercicio
--
Data de Progressão
data_progressao
não existe campo que possa ser utilizado no objeto de retorno
--
Tipo de Admissão
tipo_admissao
[Admissão primeiro emprego,
Admissão com emprego anterior,
Transf. com ônus para cedente,
Transf. sem ônus para cedente,
Outros]
não existe campo que possa ser utilizado no objeto de retorno
--
tempo de serviço Federal
tempo_anterior_federal
não existe campo que possa ser utilizado no objeto de retorno
--
tempo de serviço Estadual
tempo_anterior_estadual
não existe campo que possa ser utilizado no objeto de retorno
--
tempo de serviço Municipal
tempo_anterior_municipal
não existe campo que possa ser utilizado no objeto de retorno
--
tempo de serviço Afastamento
tempo_anterior_afastamento
não existe campo que possa ser utilizado no objeto de retorno
rh.servidor_desligamento
Data do Desligamento
data_desligamento
objeto servidor.data_desligamento
rh.lotacao_mensal
Lotação de Contratação
(id, descricao)
descricao
objeto servidor.municipio_concurso_lotacao_id
admin.pessoa_fisica
Pessoa
(id, nome)
nome
objeto servidor.pessoa
campos pessoa.id e pessoa.nome
propriedade nome = Protected - Precisa usar getNome(id) ou setNome(nome)
--
CPF
cpf
objeto servidor.pessoa_fisica.cpf
--
RG
rg
objeto servidor.pessoa_fisica.rg.rg
--
data de Nascimento
data_nascimento
objeto servidor.pessoa_fisica.data_nascimento
3. Possíveis Soluções
ParaWORK osIN campos que não existem no objeto JSON de retorno do serviço RabbitMQ, a seguinte solução pode ser considerada:PROGRESS....
Verificar se os campos existem no banco do e-Estado e adicioná-los ao objeto JSON caso existam
História
O quê: Eu, dev, preciso criar uma propriedade Matrícula na entidade de Servidorxxxxxxxxxxxxxxxxxxxxxx
Por quê: para realizar a integração de dados de Informações cadastradas no sistema e-Estadoxxxxxxxxxxxxxxxxxxxxxxxxx
Regras e Validações
--
Pontuação
2?
História
O quê: Eu, dev, preciso criar uma propriedade Data do Efetivo Exercício na entidade de Servidor
Por quê: para realizar a integração de dados de Informações cadastradas no sistema e-Estado
Regras e Validações
--
Pontuação
2
História
O quê: Eu, dev, preciso criar uma propriedade Data do Desligamento na entidade de Servidor
Por quê: para realizar a integração de dados de Informações cadastradas no sistema e-Estado
Regras e Validações
--
Pontuação
2
História
O quê: Eu, dev, preciso criar uma propriedade Lotação de Contratação na entidade de Servidor
Por quê: para realizar a integração de dados de Informações cadastradas no sistema e-Estado
Regras e Validações
--
Pontuação
2
História
O quê: Eu, dev, preciso criar uma propriedade Pessoa na entidade de Servidor
Por quê: para realizar a integração de dados de Informações cadastradas no sistema e-Estado
Regras e Validações
--
Pontuação
2
História
O quê: Eu, dev, preciso criar uma propriedade CPF na entidade de Servidor
Por quê: para realizar a integração de dados de Informações cadastradas no sistema e-Estado
Regras e Validações
--
Pontuação
2
História
O quê: Eu, dev, preciso criar uma propriedade RG na entidade de Servidor
Por quê: para realizar a integração de dados de Informações cadastradas no sistema e-Estado
Regras e Validações
--
Pontuação
2
História
O quê: Eu, dev, preciso criar uma propriedade Data de Nascimento na entidade de Servidor
Por quê: para realizar a integração de dados de Informações cadastradas no sistema e-Estado
Regras e Validações
--
Pontuação
2
História
O quê: Eu, dev, preciso criar uma propriedade a entidade de Servidor
Por quê: para realizar a integração de dados de Informações cadastradas no sistema e-Estado
Regras e Validações
--
4. Conclusão
NesteAo estudo,estudar analisamoso código fonte do Governa, foi possível identificar a integração entre os sistemas e-Estado e Governa, focando nos dados da entidade "Servidor" e suas correspondências em ambos os sistemas. Através dessa análise, chegamos a algumas conclusões:
A integração entre os sistemas e-Estado e Governa requer a associação correta dos campos compartilhados entre eles, como matrícula, datafuncionalidade de admissão, data do efetivo exercício, data do desligamento, lotaçgeração de contratação,Carta nomeRemessa e CPF.
Algunsde camposseus importantesrelatórios em PDF. O processo atual consiste em buscar os detalhes da carta remessa, gerar os relatórios em PDF, criar um arquivo ZIP contendo os relatórios. No entanto, o código não possuemsepara correspondênciaos diretarelatórios nospor sistemas, como data de progressãlotação, tipo de admissão eque tempospode dedemonstrar serviço (federal, estadual, municipal e afastamento). Esses campos requeremser uma avaliaçlimitação maisem aprofundadacenários eem buscaque é necessário agrupar os relatórios por possíveisessa soluções, como adiçinformação de campos.o.
5.Com Referênciasbase
nessa Comoanálise, Disponibilizaré opossível RabbitMQconcluir que é necessário fazer modificações no código fonte para múltiplosseparar consumos:os relatórios PDF por lotação.
AMQP - Documentação oficial:
RabbitMQ - Documentação oficial: