odorico 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (31) hide show
  1. checksums.yaml +7 -0
  2. data/bin/odorico +3 -0
  3. data/lib/odorico/arquivo_atestado_de_saude_ocupacional.rb +60 -0
  4. data/lib/odorico/arquivo_aviso_previo.rb +69 -0
  5. data/lib/odorico/arquivo_cargo.rb +60 -0
  6. data/lib/odorico/arquivo_comunicacao_de_acidente_de_trabalho.rb +86 -0
  7. data/lib/odorico/arquivo_condicao_ambiental_de_trabalho.rb +83 -0
  8. data/lib/odorico/arquivo_data.rb +251 -0
  9. data/lib/odorico/arquivo_empregado.rb +401 -0
  10. data/lib/odorico/arquivo_empregado_afastamento_inicio.rb +109 -0
  11. data/lib/odorico/arquivo_empregado_afastamento_termino.rb +102 -0
  12. data/lib/odorico/arquivo_empregado_desligamento.rb +237 -0
  13. data/lib/odorico/arquivo_empregado_historico_cadastral.rb +194 -0
  14. data/lib/odorico/arquivo_empregado_historico_contratual.rb +157 -0
  15. data/lib/odorico/arquivo_empresa.rb +158 -0
  16. data/lib/odorico/arquivo_estabelecimento.rb +138 -0
  17. data/lib/odorico/arquivo_horario.rb +69 -0
  18. data/lib/odorico/arquivo_lotacao.rb +60 -0
  19. data/lib/odorico/arquivo_trabalhador_sem_vinculo.rb +305 -0
  20. data/lib/odorico/arquivo_trabalhador_sem_vinculo_historico_contratual.rb +86 -0
  21. data/lib/odorico/arquivo_trabalhador_sem_vinculo_termino.rb +204 -0
  22. data/lib/odorico/console.rb +11 -0
  23. data/lib/odorico/gerador_de_arquivos.rb +126 -0
  24. data/lib/odorico/gerador_de_arquivos_csv.rb +25 -0
  25. data/lib/odorico/jornada.rb +21 -0
  26. data/lib/odorico/processamento.rb +375 -0
  27. data/lib/odorico/sistema_operacional.rb +33 -0
  28. data/lib/odorico/types.rb +203 -0
  29. data/lib/odorico/version.rb +3 -0
  30. data/lib/odorico.rb +115 -0
  31. metadata +184 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 56bf49156867ffd892bbce81cf9910392a83fe1839ee76c707b53b828287e63b
4
+ data.tar.gz: de46690502cff15660e29ab86f68b393cb3353ac00c29f89e976234db08d2bac
5
+ SHA512:
6
+ metadata.gz: 20bd1cf24b35050d86b30baacfb50129da548673203f093754788e0119fe328ac9919f76db33e4d6b32718adb45355a5e02a56f996c060023a5010a99067ab52
7
+ data.tar.gz: 24019453108ed35fd44a812336a079174d8b513c953994caa1b17a2b4310a82c656b124d16845803c87b2646e2a86c4eaeea9d385e7650bea6fcf4b9c108c104
data/bin/odorico ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+ require 'odorico'
3
+ Odorico[ARGV]
@@ -0,0 +1,60 @@
1
+ class ArquivoAtestadoDeSaudeOcupacional
2
+ ATRIBUTOS = {
3
+ descricao_proc_emi: { key: 'procEmi', type: Types.Values(*%w[1 2 3 4 22]) },
4
+ cpf_do_trabalhador: { key: 'cpfTrab', type: Types::String },
5
+ matricula_do_trabalhador: { key: 'matricula', type: Types::String.optional },
6
+ categoria_do_trabalhador: { key: 'codCateg', type: Types::CategoriaTrabalhadorTsv.optional },
7
+ data_de_emissao: { key: 'dtAso', type: Types::Date },
8
+ tipo: { key: 'tpExameOcup', type: Types.Values(*%w[0 1 2 3 4 9]) },
9
+ medico_nome: { key: 'medico/nmMed', type: Types::String },
10
+ medico_crm_numero: { key: 'medico/nrCRM', type: Types::String },
11
+ medico_crm_uf: { key: 'medico/ufCRM', type: Types::String },
12
+ medico_pcmso_nome: { key: 'respMonit/nmResp', type: Types::String },
13
+ medico_pcmso_crm_numero: { key: 'respMonit/nrCRM', type: Types::String },
14
+ medico_pcmso_crm_uf: { key: 'respMonit/ufCRM', type: Types::String },
15
+ e_social_recibo: { key: 'nrRecibo', type: Types::String },
16
+ exames: { key: 'exame', attributes: {
17
+ data: { key: 'dtExm', type: Types::Date },
18
+ procedimento_diagnostico_e_social_codigo: { key: 'procRealizado', type: Types::String },
19
+ observacao: { key: 'obsProc', type: Types::String.optional },
20
+ ordem: { key: 'ordExame', type: Types.Values(*%w[1 2]).optional }
21
+ } }
22
+ }.freeze
23
+
24
+ ATRIBUTOS_IGNORADOS = %w[
25
+ Id
26
+ verProc
27
+ ideEmpregador/tpInsc
28
+ ideEmpregador/nrInsc
29
+ resAso
30
+ respMonit/cpfResp
31
+ ].freeze
32
+
33
+ ATRIBUTOS_NAO_SUPORTADOS = {}.freeze
34
+
35
+ ATRIBUTOS_DESCARTADOS = {}.freeze
36
+
37
+ include ArquivoData
38
+
39
+ private
40
+
41
+ def initialize(caminho_do_arquivo_data)
42
+ @caminho_do_arquivo_data = caminho_do_arquivo_data
43
+ end
44
+
45
+ def ajustar_atributos
46
+ atributos[:exames] = atributos[:exames].to_json
47
+ end
48
+
49
+ def regras_que_podem_gerar_erros
50
+ {}
51
+ end
52
+
53
+ def regras_que_podem_gerar_alertas
54
+ {}
55
+ end
56
+
57
+ def identificador
58
+ 'atestado_de_saude_ocupacional'
59
+ end
60
+ end
@@ -0,0 +1,69 @@
1
+ class ArquivoAvisoPrevio
2
+ ATRIBUTOS = {
3
+ matricula: { key: 'IdeVinculo_Matricula', type: Types::String },
4
+ nr_recibo_evento_original: { key: 'NrReciboEventoOriginal', type: Types::String },
5
+ tipo_de_aviso_previo: { key: 'InfoAvisoPrevio_DetalhamentoAvisoPrevio_TipoAvisoPrevio', type: Types::String },
6
+ data_do_aviso_previo: { key: 'InfoAvisoPrevio_DetalhamentoAvisoPrevio_DataAvisoPrevio', type: Types::Date },
7
+ data_prevista_desligamento: { key: 'InfoAvisoPrevio_DetalhamentoAvisoPrevio_DataPrevistaDesligamento',
8
+ type: Types::Date },
9
+ descricao_proc_emi: { key: 'DescricaoProcEmi', type: Types::String.optional }
10
+ }.freeze
11
+
12
+ ATRIBUTOS_IGNORADOS = %w[
13
+ IdEventoXml
14
+ ESX_CPF
15
+ IdContrato
16
+ RequestVerificationToken
17
+ OperacaoAvisoPrevio
18
+ MostrarCancelamento
19
+ MostrarAvisoPrevio
20
+ IdCancelamentoAvisoPrevio
21
+ BloquearCodigo
22
+ BloquearAntigoPeriodoValidade
23
+ IdeVinculo_Cpf
24
+ NomeTrabalhador
25
+ InfoAvisoPrevio_DetalhamentoAvisoPrevio_TipoAvisoPrevio_TEXT
26
+ VerProc
27
+ ESX_DATAADMISSAO
28
+ ESX_SEMVINCULO
29
+ ESX_MATRICULA
30
+ ].freeze
31
+
32
+ ATRIBUTOS_NAO_SUPORTADOS = {
33
+ }.freeze
34
+
35
+ ATRIBUTOS_DESCARTADOS = {
36
+ Observação: %w[
37
+ InfoAvisoPrevio_DetalhamentoAvisoPrevio_Observacao
38
+ ]
39
+ }.freeze
40
+
41
+ include ArquivoData
42
+
43
+ private
44
+
45
+ def initialize(caminho_do_arquivo_data)
46
+ @caminho_do_arquivo_data = caminho_do_arquivo_data
47
+ end
48
+
49
+ def ajustar_atributos; end
50
+
51
+ def regras_que_podem_gerar_erros
52
+ {
53
+ 'Não suportamos aviso prévio dado pelo empregador rural' => aviso_previo_dado_pelo_empregador_rural?
54
+ }
55
+ end
56
+
57
+ def aviso_previo_dado_pelo_empregador_rural?
58
+ atributos[:tipo_de_aviso_previo] == '5'
59
+ end
60
+
61
+ def regras_que_podem_gerar_alertas
62
+ {
63
+ }
64
+ end
65
+
66
+ def identificador
67
+ 'aviso_previo'
68
+ end
69
+ end
@@ -0,0 +1,60 @@
1
+ class ArquivoCargo
2
+ ATRIBUTOS = {
3
+ inicio_validade: { key: 'InicioValidade', type: Types::AnoMes },
4
+ codigo_cargo: { key: 'CodigoCargo', type: Types::String },
5
+ dados_cargo_descricao_cargo: { key: 'DadosCargo_DescricaoCargo', type: Types::String },
6
+ dados_cargo_codigo_cbo: { key: 'DadosCargo_CodigoCBO', type: Types::String },
7
+ descricao_proc_emi: { key: 'DescricaoProcEmi', type: Types::String.optional }
8
+ }.freeze
9
+
10
+ ATRIBUTOS_IGNORADOS = %w[
11
+ IdEventoXml
12
+ NrReciboEventoOriginal
13
+ RequestVerificationToken
14
+ PreencherCargoPublico
15
+ DadosCargo_CodigoCBO_TEXT
16
+ autocomplete_DadosCargo_CodigoCBO
17
+ VerProc
18
+ SomenteVisualizacao
19
+ BloquearCodigo
20
+ BloquearAntigoPeriodoValidade
21
+ ].freeze
22
+
23
+ ATRIBUTOS_NAO_SUPORTADOS = {
24
+ 'Não suportamos encerramento de histórico de evento tabela': %w[
25
+ FimValidade
26
+ ]
27
+ }.freeze
28
+
29
+ ATRIBUTOS_DESCARTADOS = {}.freeze
30
+
31
+ include ArquivoData
32
+
33
+ private
34
+
35
+ def initialize(caminho_do_arquivo_data)
36
+ @caminho_do_arquivo_data = caminho_do_arquivo_data
37
+ end
38
+
39
+ def ajustar_atributos
40
+ atributos[:inicio_validade] = nil if criado_a_partir_da_admissao?
41
+ end
42
+
43
+ def criado_a_partir_da_admissao?
44
+ !tem_o_atributo?('IdEventoXml')
45
+ end
46
+
47
+ def regras_que_podem_gerar_erros
48
+ {
49
+ }
50
+ end
51
+
52
+ def regras_que_podem_gerar_alertas
53
+ {
54
+ }
55
+ end
56
+
57
+ def identificador
58
+ 'cargo'
59
+ end
60
+ end
@@ -0,0 +1,86 @@
1
+ class ArquivoComunicacaoDeAcidenteDeTrabalho
2
+ ATRIBUTOS = {
3
+ descricao_proc_emi: { key: 'procEmi', type: Types.Values(*%w[1 2 3 4 22]) },
4
+ cpf_do_trabalhador: { key: 'cpfTrab', type: Types::String },
5
+ matricula_do_trabalhador: { key: 'matricula', type: Types::String.optional },
6
+ categoria_do_trabalhador: { key: 'codCateg', type: Types::CategoriaTrabalhadorTsv.optional },
7
+ data_do_acidente: { key: 'dtAcid', type: Types::Date },
8
+ tipo_do_acidente: { key: 'tpAcid', type: Types::Values(*%w[1 2 3]) },
9
+ hora_do_acidente: { key: 'hrAcid', type: Types::String.optional },
10
+ horas_trabalhadas_antes_do_acidente: { key: 'hrsTrabAntesAcid', type: Types::String.optional },
11
+ tipo_de_cat: { key: 'tpCat', type: Types.Values(*%w[1 2 3]) },
12
+ houve_obito: { key: 'indCatObito', type: Types::SNBool },
13
+ data_do_obito: { key: 'dtObito', type: Types::Date.optional },
14
+ houve_comunicado_a_policia: { key: 'indComunPolicia', type: Types::SNBool },
15
+ situacao_geradora_e_social_codigo: { key: 'codSitGeradora', type: Types::String },
16
+ iniciativa_da_cat: { key: 'iniciatCAT', type: Types.Values(*%w[1 2 3]) },
17
+ tipo_de_local_do_acidente: { key: 'tpLocal', type: Types.Values(*%w[1 4 5 6 9]) },
18
+ tipo_de_inscricao_do_local_do_acidente: { key: 'tpLocal', type: Types.Values('1') },
19
+ numero_de_inscricao_do_local_do_acidente: { key: 'ideLocalAcid/nrInsc', type: Types::String.optional },
20
+ logradouro: { key: 'dscLograd', type: Types::String },
21
+ numero_do_logradouro: { key: 'nrLograd', type: Types::String },
22
+ cep_logradouro: { key: 'cep', type: Types::String },
23
+ municipio_codigo: { key: 'codMunic', type: Types::String },
24
+ parte_atingida_e_social_codigo: { key: 'codParteAting', type: Types::String },
25
+ parte_atingida_lateralidade: { key: 'lateralidade', type: Types.Values(*%w[0 1 2 3]) },
26
+ agente_causador_e_social_codigo: { key: 'codAgntCausador', type: Types::String },
27
+ atestado_medico_data_do_atendimento: { key: 'dtAtendimento', type: Types::Date },
28
+ atestado_medico_hora_do_atendimento: { key: 'hrAtendimento', type: Types::String },
29
+ atestado_medico_internacao: { key: 'indInternacao', type: Types::SNBool },
30
+ atestado_medico_duracao: { key: 'durTrat', type: Types::Integer },
31
+ atestado_medico_afastamento: { key: 'indAfast', type: Types::SNBool },
32
+ atestado_medico_natureza_da_lesao_e_social_codigo: { key: 'dscLesao', type: Types::String },
33
+ atestado_medico_cid: { key: 'codCID', type: Types::String },
34
+ atestado_medico_emitente_nome: { key: 'nmEmit', type: Types::String },
35
+ atestado_medico_emitente_orgao_de_classe: { key: 'ideOC', type: Types.Values(*%w[1 2 3]) },
36
+ atestado_medico_emitente_orgao_de_classe_numero_de_inscricao: { key: 'nrOC', type: Types::String },
37
+ atestado_medico_emitente_orgao_de_classe_uf: { key: 'ufOC', type: Types::String },
38
+ cat_anterior_e_social_recibo: { key: 'nrRecCatOrig', type: Types::String },
39
+ e_social_recibo: { key: 'nrRecibo', type: Types::String }
40
+ }.freeze
41
+
42
+ ATRIBUTOS_IGNORADOS = %w[
43
+ Id
44
+ verProc
45
+ ideEmpregador/tpInsc
46
+ ideEmpregador/nrInsc
47
+ obsCAT
48
+ dscLocal
49
+ tpLograd
50
+ complemento
51
+ bairro
52
+ uf
53
+ pais
54
+ codPostal
55
+ ideLocalAcid/tpInsc
56
+ dscCompLesao
57
+ diagProvavel
58
+ observacao
59
+ ].freeze
60
+
61
+ ATRIBUTOS_NAO_SUPORTADOS = {}.freeze
62
+
63
+ ATRIBUTOS_DESCARTADOS = {}.freeze
64
+
65
+ include ArquivoData
66
+
67
+ private
68
+
69
+ def initialize(caminho_do_arquivo_data)
70
+ @caminho_do_arquivo_data = caminho_do_arquivo_data
71
+ end
72
+
73
+ def ajustar_atributos; end
74
+
75
+ def regras_que_podem_gerar_erros
76
+ {}
77
+ end
78
+
79
+ def regras_que_podem_gerar_alertas
80
+ {}
81
+ end
82
+
83
+ def identificador
84
+ 'comunicacao_de_acidente_de_trabalho'
85
+ end
86
+ end
@@ -0,0 +1,83 @@
1
+ class ArquivoCondicaoAmbientalDeTrabalho
2
+ ATRIBUTOS = {
3
+ descricao_proc_emi: { key: 'procEmi', type: Types.Values(*%w[1 2 3 4 22]) },
4
+ cpf_do_trabalhador: { key: 'cpfTrab', type: Types::String },
5
+ matricula_do_trabalhador: { key: 'matricula', type: Types::String.optional },
6
+ categoria_do_trabalhador: { key: 'codCateg', type: Types::CategoriaTrabalhadorTsv.optional },
7
+ data_de_inicio: { key: 'dtIniCondicao', type: Types::Date },
8
+ tipo_de_estabelecimento: { key: 'localAmb', type: Types.Values('1') },
9
+ descricao_do_setor: { key: 'dscSetor', type: Types::String },
10
+ tipo_de_inscricao_do_estabelecimento: { key: 'infoAmb/tpInsc', type: Types.Values('1') },
11
+ numero_de_inscricao_do_estabelecimento: { key: 'infoAmb/nrInsc', type: Types::String },
12
+ descricao_das_atividades: { key: 'dscAtivDes', type: Types::String },
13
+ observacoes_complementares: { key: 'obsCompl', type: Types::String.optional },
14
+ e_social_recibo: { key: 'nrRecibo', type: Types::String },
15
+ agentes_nocivos: { key: 'agNoc', attributes: {
16
+ agente_nocivo_e_social_codigo: { key: 'codAgNoc', type: Types::String },
17
+ descricao: { key: 'dscAgNoc', type: Types::String.optional },
18
+ tipo_de_avaliacao: { key: 'tpAval', type: Types.Values(*%w[1 2]).optional },
19
+ intensidade_da_exposicao: { key: 'intConc', type: Types::Decimal.optional },
20
+ limite_de_tolerancia: { key: 'limTol', type: Types::Integer.optional },
21
+ unidade_de_medida: { key: 'unMed', type: Types.Values(*(1..30).map(&:to_s)).optional },
22
+ tecnica_de_medicao: { key: 'tecMedicao', type: Types::String.optional },
23
+ implementa_medidas_de_protecao_coletiva: { key: 'utilizEPC', type: Types.Values(*%w[0 1 2]).optional },
24
+ epcs_neutralizam_o_risco: { key: 'eficEpc', type: Types::SNBool.optional },
25
+ utilizacao_de_epi: { key: 'utilizEPI', type: Types.Values(*%w[0 1 2]).optional },
26
+ epis_neutralizam_o_risco: { key: 'eficEpi', type: Types::SNBool.optional },
27
+ epi_implementacao_de_medidas_de_protecao: { key: 'medProtecao', type: Types::SNBool.optional },
28
+ epi_observadas_as_condicoes_de_funcionamento: { key: 'condFuncto', type: Types::SNBool.optional },
29
+ epi_observado_o_uso_ininterrupto: { key: 'usoInint', type: Types::SNBool.optional },
30
+ epi_observado_o_prazo_de_validade: { key: 'przValid', type: Types::SNBool.optional },
31
+ epi_observada_a_periodicidade_de_troca: { key: 'periodicTroca', type: Types::SNBool.optional },
32
+ epi_observada_a_higienizacao: { key: 'higienizacao', type: Types::SNBool.optional },
33
+ epis: { key: 'epi', attributes: {
34
+ certificado_de_aprovacao: { key: 'docAval', type: Types::String.optional },
35
+ descricao: { key: 'dscEPI', type: Types::String.optional }
36
+ } }
37
+ } },
38
+ responsaveis: { key: 'respReg', attributes: {
39
+ cpf: { key: 'cpfResp', type: Types::String },
40
+ orgao_de_classe: { key: 'ideOC', type: Types.Values(*%w[1 4 9]) },
41
+ orgao_de_classe_outro_descricao: { key: 'dscOC', type: Types::String.optional },
42
+ orgao_de_classe_numero: { key: 'nrOC', type: Types::String },
43
+ orgao_de_classe_uf: { key: 'ufOC', type: Types::String }
44
+ } }
45
+ }.freeze
46
+
47
+ ATRIBUTOS_IGNORADOS = %w[
48
+ Id
49
+ verProc
50
+ ideEmpregador/tpInsc
51
+ ideEmpregador/nrInsc
52
+ obsCompl
53
+ ].freeze
54
+
55
+ ATRIBUTOS_NAO_SUPORTADOS = {}.freeze
56
+
57
+ ATRIBUTOS_DESCARTADOS = {}.freeze
58
+
59
+ include ArquivoData
60
+
61
+ private
62
+
63
+ def initialize(caminho_do_arquivo_data)
64
+ @caminho_do_arquivo_data = caminho_do_arquivo_data
65
+ end
66
+
67
+ def ajustar_atributos
68
+ atributos[:agentes_nocivos] = atributos[:agentes_nocivos].to_json
69
+ atributos[:responsaveis] = atributos[:responsaveis].to_json
70
+ end
71
+
72
+ def regras_que_podem_gerar_erros
73
+ {}
74
+ end
75
+
76
+ def regras_que_podem_gerar_alertas
77
+ {}
78
+ end
79
+
80
+ def identificador
81
+ 'condicao_ambiental_de_trabalho'
82
+ end
83
+ end
@@ -0,0 +1,251 @@
1
+ # rubocop:disable Metrics/ModuleLength
2
+ module ArquivoData
3
+ def processar
4
+ if atributo_nao_identificado?
5
+ adicionar_erro_de_atributos_nao_identificados
6
+ else
7
+ setar_atributos
8
+ ajustar_atributos
9
+ setar_tipo_e_nome_do_arquivo_nos_atributos
10
+ processar_atributos_descartados
11
+ processar_atributos_nao_suportados
12
+ adicionar_erros
13
+ adicionar_alertas
14
+ end
15
+ end
16
+
17
+ def erros
18
+ @erros ||=
19
+ Mensagens.new(tipo_do_arquivo: identificador, nome_do_arquivo: nome_do_arquivo, tipo_de_mensagem: :error)
20
+ end
21
+
22
+ def alertas
23
+ @alertas ||=
24
+ Mensagens.new(tipo_do_arquivo: identificador, nome_do_arquivo: nome_do_arquivo, tipo_de_mensagem: :alert)
25
+ end
26
+
27
+ def atributos
28
+ @atributos ||= {}
29
+ end
30
+
31
+ private
32
+
33
+ attr_reader :caminho_do_arquivo_data
34
+
35
+ def nome_do_arquivo
36
+ @nome_do_arquivo ||= caminho_do_arquivo_data.split('/').last
37
+ end
38
+
39
+ def atributo_nao_identificado?
40
+ erro_de_atributos_nao_identificado
41
+ end
42
+
43
+ def erro_de_atributos_nao_identificado
44
+ @erro_de_atributos_nao_identificado ||=
45
+ if atributos_nao_identificados.any?
46
+ "Atributos não identificados na configuração: #{atributos_nao_identificados.join(', ')}"
47
+ end
48
+ end
49
+
50
+ def atributos_nao_identificados
51
+ @atributos_nao_identificados ||=
52
+ valores_por_chave
53
+ .keys
54
+ .grep_v(/.*_\d+_.*/)
55
+ .then { _1 - atributos_identificados }
56
+ end
57
+
58
+ def atributos_identificados
59
+ self.class::ATRIBUTOS.values.map { _1[:key] } +
60
+ self.class::ATRIBUTOS_IGNORADOS +
61
+ self.class::ATRIBUTOS_DESCARTADOS.values.flatten +
62
+ self.class::ATRIBUTOS_NAO_SUPORTADOS.values.flatten
63
+ end
64
+
65
+ def valores_por_chave
66
+ @valores_por_chave ||=
67
+ conteudo_do_arquivo
68
+ .split(fim_de_linha)
69
+ .reject { _1.include?('UrlRetorno') }
70
+ .to_h { _1.split('=', 2) }
71
+ .transform_values(&:strip)
72
+ .transform_values { _1.empty? ? nil : _1 }
73
+ end
74
+
75
+ def conteudo_do_arquivo
76
+ @conteudo_do_arquivo ||= File.read(caminho_do_arquivo_data, mode: 'r:ISO-8859-1:UTF-8').force_encoding('UTF-8')
77
+ end
78
+
79
+ def fim_de_linha
80
+ @fim_de_linha ||= conteudo_do_arquivo.include?("\r\n") ? /\r\n/ : /\n/
81
+ end
82
+
83
+ def adicionar_erro_de_atributos_nao_identificados
84
+ erros << erro_de_atributos_nao_identificado
85
+ end
86
+
87
+ def setar_atributos
88
+ atributos.merge!(
89
+ extrair_dados_do_arquivo(self.class::ATRIBUTOS)
90
+ )
91
+ end
92
+
93
+ def extrair_dados_do_arquivo(atributos_a_extrair, prefixo = '')
94
+ result = {}
95
+
96
+ atributos_a_extrair.each do |chave_final, config|
97
+ chave_do_atributo = config[:key]
98
+
99
+ tipo_do_atributo = config[:type]
100
+ if tipo_do_atributo
101
+ valor_do_atributo = valores_por_chave["#{prefixo}#{chave_do_atributo}"]
102
+ verificacao_de_tipagem = tipo_do_atributo.try(valor_do_atributo)
103
+ if verificacao_de_tipagem.success?
104
+ result[chave_final] = verificacao_de_tipagem.input
105
+ else
106
+ erros << "Valor [\"#{valor_do_atributo}\"] não permitido para o atributo: #{prefixo}#{chave_final}. Erro: " \
107
+ "#{verificacao_de_tipagem.error}"
108
+ end
109
+ else
110
+ result[chave_final] =
111
+ valores_por_chave
112
+ .keys
113
+ .grep(/^#{prefixo}#{chave_do_atributo}_\d+_/)
114
+ .map { _1.match(/^#{prefixo}#{chave_do_atributo}_(\d+)_/)[1] }
115
+ .uniq
116
+ .map { extrair_dados_do_arquivo(config[:attributes], "#{prefixo}#{chave_do_atributo}_#{_1}_") }
117
+ end
118
+ end
119
+
120
+ result
121
+ end
122
+
123
+ def setar_tipo_e_nome_do_arquivo_nos_atributos
124
+ atributos[:fw_tipo] = identificador
125
+ atributos[:file_name] = nome_do_arquivo
126
+ end
127
+
128
+ def processar_atributos_descartados
129
+ self.class::ATRIBUTOS_DESCARTADOS.each do |mensagem, chaves_dos_atributos|
130
+ chaves_dos_atributos.each do |chave_do_atributo|
131
+ valor_do_atributo = valores_por_chave[chave_do_atributo]
132
+ unless valor_do_atributo.nil?
133
+ alertas << "As informações do #{mensagem} serão descartadas."
134
+ break
135
+ end
136
+ end
137
+ end
138
+ end
139
+
140
+ def processar_atributos_nao_suportados
141
+ self.class::ATRIBUTOS_NAO_SUPORTADOS.each do |mensagem, chaves_dos_atributos|
142
+ chaves_dos_atributos.each do |chave_do_atributo|
143
+ valor_do_atributo = valores_por_chave[chave_do_atributo]
144
+ unless valor_do_atributo.nil?
145
+ erros << mensagem.to_s
146
+ break
147
+ end
148
+ end
149
+ end
150
+ end
151
+
152
+ def adicionar_erros
153
+ regras = regras_que_podem_gerar_erros
154
+ regras = regras.merge(regra_de_processo_de_emissao_nao_suportado) if processo_de_emissao?
155
+
156
+ erros.push(
157
+ *regras
158
+ .select { |_, condicao| condicao }
159
+ .keys
160
+ )
161
+ end
162
+
163
+ def processo_de_emissao?
164
+ atributos[:descricao_proc_emi]
165
+ end
166
+
167
+ def regra_de_processo_de_emissao_nao_suportado
168
+ { "Registro transmitido por processo não suportado: #{processo_de_emissao}." => processo_de_emissao_nao_suportado? }
169
+ end
170
+
171
+ def processo_de_emissao_nao_suportado?
172
+ !%w[1 3].include?(processo_de_emissao[0])
173
+ end
174
+
175
+ def processo_de_emissao
176
+ @processo_de_emissao ||= atributos[:descricao_proc_emi]
177
+ end
178
+
179
+ def adicionar_alertas
180
+ alertas.push(
181
+ *regras_que_podem_gerar_alertas
182
+ .select { |_, condicao| condicao }
183
+ .keys
184
+ )
185
+ end
186
+
187
+ def verificar_se_eh_leiaute_simplificado?(
188
+ atributos_especificos_do_leiaute_simplificado,
189
+ atributos_inexistentes_no_leiaute_simplificado = []
190
+ )
191
+ atributo_especifico_do_leiaute_simplificado?(atributos_especificos_do_leiaute_simplificado) ||
192
+ nenhum_atributo_inexistente_no_leiaute_simplificado?(atributos_inexistentes_no_leiaute_simplificado)
193
+ end
194
+
195
+ def atributo_especifico_do_leiaute_simplificado?(atributos_especificos_do_leiaute_simplificado)
196
+ atributos_especificos_do_leiaute_simplificado.any? &&
197
+ valores_por_chave.keys.intersection(atributos_especificos_do_leiaute_simplificado).any?
198
+ end
199
+
200
+ def nenhum_atributo_inexistente_no_leiaute_simplificado?(atributos_inexistentes_no_leiaute_simplificado)
201
+ atributos_inexistentes_no_leiaute_simplificado.any? &&
202
+ valores_por_chave.keys.intersection(atributos_inexistentes_no_leiaute_simplificado).none?
203
+ end
204
+
205
+ def tem_o_atributo?(atributo)
206
+ valores_por_chave.key?(atributo)
207
+ end
208
+
209
+ class Mensagens
210
+ extend Forwardable
211
+
212
+ def_delegators :itens, :any?, :empty?
213
+
214
+ private
215
+
216
+ def initialize(tipo_do_arquivo:, nome_do_arquivo:, tipo_de_mensagem:)
217
+ @tipo_do_arquivo = tipo_do_arquivo
218
+ @nome_do_arquivo = nome_do_arquivo
219
+ @tipo_de_mensagem = tipo_de_mensagem
220
+ end
221
+
222
+ attr_reader :tipo_do_arquivo, :nome_do_arquivo, :tipo_de_mensagem
223
+
224
+ public
225
+
226
+ def <<(mensagem)
227
+ itens << {
228
+ file_name: nome_do_arquivo,
229
+ type_file: tipo_do_arquivo,
230
+ **[["#{tipo_de_mensagem}_message".to_sym, mensagem]].to_h
231
+ }
232
+ end
233
+
234
+ def push(*mensagens)
235
+ mensagens.each do |mensagem|
236
+ self << mensagem
237
+ end
238
+ end
239
+
240
+ def to_a
241
+ itens
242
+ end
243
+
244
+ private
245
+
246
+ def itens
247
+ @itens ||= []
248
+ end
249
+ end
250
+ end
251
+ # rubocop:enable Metrics/ModuleLength