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
FEBRABAN – 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 Como é gerada a Carta 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
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. 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
public List<Long> executar(CartaRemessa
cartaRemessa, String
mesRefLogado)
throws
RestricaoNegocioExcecao, CampoObrigatorioNaoInformadoExcecao
{
//
Gera Ologs
protocololog.info("Gerando AMQPcarta (Advancedremessa Message[{}]", QueuingcartaRemessa.getMesReferencia());
Protocol)log.info("Gerando écarta umremessa protocolomesReferencia Logado [{}]", mesRefLogado);
// Valida se os campos obrigatórios foram preenchidos
validarCamposObrigatorios(cartaRemessa);
// realiza uma série de mensagens assíncronas, utilizado para comunicação entre sistemas distribuídos. Ele foi desenvolvido para facilitar a troca de mensagens entre aplicativos e serviços de forma eficiente e confiável.
O AMQP foi projetado para ser independente de plataforma, permitindo a comunicação entre diferentes sistemas e linguagens de programação. Ele define um conjuntoverificações de regras ede formatosnegócios paraem enviar,um rotearobjeto CartaRemessa.
// Primeiro, verifica se o modelo de CartaRemessa é uma "Carta Acerto" e receberse mensagens,certas garantindo que elas sejam entregues de maneira ordenada e confiável.
Uma das principais características do AMQP é a utilização de filas de mensagens. As mensagenscondições são publicadascumpridas.
em// filasSe 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 podemmodelo. serSe consumidasexistir, poroutra umexceção
ou// maisé consumidores,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 umo modelo deda pub/subcarta (publicação/assinatura).remessa
IssoICartaRemessaServico permitecartaRemessaServico que= oscartaRemessaServicoFabrica.getServico(cartaRemessa.getCartaRemessaModeloEnum());
aplicativos// enviem e recebam mensagens de forma assíncrona, desacoplandoChama o produtormétodo dagerarCartaRemessa(cartaRemessa, mensagemmesRefLogado do consumidor.
Além das filas, o AMQP também define trocas (exchanges) e vinculações (bindings) para rotear as mensagens para as filas corretas. As trocas recebem mensagens dos produtores e as encaminham para as filas com base em regras de roteamento específicas. As vinculações são utilizadas para definir a relação entre as trocas e as filas.
O AMQP suporta diferentes modelos de entrega de mensagens, como confirmação de entrega (acknowledgment), que garante que as mensagens sejam entregues com sucesso, e qualidade de serviço (QoS),cartaRemessaServiço
quereturn permitecartaRemessaServico.gerarCartaRemessa(cartaRemessa, definirmesRefLogado);
níveis}
prioridade para as mensagens.
O protocolo AMQP é amplamente utilizado em sistemas distribuídos e arquiteturas orientadas a mensagens, como em aplicações de mensageria, Internet das Coisas (IoT), sistemas financeiros e sistemas de notificação em tempo real.
Em resumo, o protocolo AMQP é um protocolo de mensagens assíncronas que facilita a comunicação entre sistemas distribuídos, oferecendo confiabilidade, flexibilidade e escalabilidade. Ele utiliza filas, trocas e vinculações para rotear as mensagens de forma eficiente e suporta diferentes modelos de entrega e qualidade de serviço.
Figura
2.2 RabbitMQ
O RabbitMQ é um software de mensagem assíncrona de código aberto, que implementa o protocolo AMQP (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 entre os produtores e consumidores, garantindo a entrega ordenada e controlada.
2.3 Telas em questão
2.4 Objeto JSON
O objeto JSON recebido pelo serviço de mensageria RabbitMQ é proveniente de ações realizadas na entidade "Servidor" no sistema e-Estado. Dentre as ações inclui-se: criação, atualização de dados e exclusão.
O objeto JSON contém diversos campos que representam os dados do servidor, como identificação, matrícula, tipo de vínculo, data de admissão, entre outros. Essas informações são cruciais para acompanhar e registrar o histórico dos servidores no sistema. Abaixo pode-se conferir o objeto de retorno do serviço rabbitMQ.
Quando a ação é INSERT, o RabbitMQ retorna o seguinte objeto:
{
"id": 215349,
"matricula": 600003369,
"tipo_vinculo_id": 7,
"data_admissao": "15/12/2022",
"concurso_id": null,
"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": {
"id": 1758202,
"nome": "Lucas Teste",
"data": "2023-06-23T08:34:21.500402"
},
"pessoa_fisica": {
"pessoa_id": 1758202,
"estado_civil_id": 2,
"sexo_id": 1,
"escolaridade_id": null,
"tipo_sanguineo_id": null,
"cpf": "22******50",
"data_nascimento": "2003-05-10",
"falecimento": null,
"raca": null,
"pcd": null,
"tipo_nacionalidade": null,
"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": 5582
},
"poder": null,
"previdencia": null,
"regime": null,
"registro_ponto": null,
"tipo_vinculo": {
"id": 7,
"nome": "Estagiário",
"grupo": null
},
"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 a ação é UPDATE, o RabbitMQ retorna o seguinte objeto:
{
"id": 1534244,
"nome": "JESSE ELIAS VIEIRA CAMPOS ",
"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": []
}
2.4 Campos Integrados
Os seguintes campos podem refletir-se em ambos os sistemas:
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
Para os campos que não existem no objeto JSON de retorno do serviço RabbitMQ, a seguinte solução pode ser considerada:
- 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 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 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
Neste estudo, analisamos 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, data de admissão, data do efetivo exercício, data do desligamento, lotação de contratação, nome e CPF.
Alguns campos importantes não possuem correspondência direta nos sistemas, como data de progressão, tipo de admissão e tempos de serviço (federal, estadual, municipal e afastamento). Esses campos requerem uma avaliação mais aprofundada e busca por possíveis soluções, como adição de campos.
5. Referências
Como Disponibilizar o RabbitMQ para múltiplos consumos:
AMQP - Documentação oficial:
RabbitMQ - Documentação oficial: