odorico 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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