odorico 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/bin/odorico +3 -0
- data/lib/odorico/arquivo_atestado_de_saude_ocupacional.rb +60 -0
- data/lib/odorico/arquivo_aviso_previo.rb +69 -0
- data/lib/odorico/arquivo_cargo.rb +60 -0
- data/lib/odorico/arquivo_comunicacao_de_acidente_de_trabalho.rb +86 -0
- data/lib/odorico/arquivo_condicao_ambiental_de_trabalho.rb +83 -0
- data/lib/odorico/arquivo_data.rb +251 -0
- data/lib/odorico/arquivo_empregado.rb +401 -0
- data/lib/odorico/arquivo_empregado_afastamento_inicio.rb +109 -0
- data/lib/odorico/arquivo_empregado_afastamento_termino.rb +102 -0
- data/lib/odorico/arquivo_empregado_desligamento.rb +237 -0
- data/lib/odorico/arquivo_empregado_historico_cadastral.rb +194 -0
- data/lib/odorico/arquivo_empregado_historico_contratual.rb +157 -0
- data/lib/odorico/arquivo_empresa.rb +158 -0
- data/lib/odorico/arquivo_estabelecimento.rb +138 -0
- data/lib/odorico/arquivo_horario.rb +69 -0
- data/lib/odorico/arquivo_lotacao.rb +60 -0
- data/lib/odorico/arquivo_trabalhador_sem_vinculo.rb +305 -0
- data/lib/odorico/arquivo_trabalhador_sem_vinculo_historico_contratual.rb +86 -0
- data/lib/odorico/arquivo_trabalhador_sem_vinculo_termino.rb +204 -0
- data/lib/odorico/console.rb +11 -0
- data/lib/odorico/gerador_de_arquivos.rb +126 -0
- data/lib/odorico/gerador_de_arquivos_csv.rb +25 -0
- data/lib/odorico/jornada.rb +21 -0
- data/lib/odorico/processamento.rb +375 -0
- data/lib/odorico/sistema_operacional.rb +33 -0
- data/lib/odorico/types.rb +203 -0
- data/lib/odorico/version.rb +3 -0
- data/lib/odorico.rb +115 -0
- metadata +184 -0
@@ -0,0 +1,126 @@
|
|
1
|
+
require_relative 'gerador_de_arquivos_csv'
|
2
|
+
|
3
|
+
class GeradorDeArquivos
|
4
|
+
private
|
5
|
+
|
6
|
+
def initialize(gerador_de_arquivos_csv:, arquivos_convertidos:)
|
7
|
+
@gerador_de_arquivos_csv = gerador_de_arquivos_csv
|
8
|
+
@arquivos_convertidos = arquivos_convertidos
|
9
|
+
end
|
10
|
+
|
11
|
+
attr_reader :gerador_de_arquivos_csv, :arquivos_convertidos
|
12
|
+
|
13
|
+
public
|
14
|
+
|
15
|
+
def executar
|
16
|
+
cargos =
|
17
|
+
arquivos_convertidos.select { _1[:fw_tipo] == 'cargo' }
|
18
|
+
lotacoes =
|
19
|
+
arquivos_convertidos.select { _1[:fw_tipo] == 'lotacao' }
|
20
|
+
empregado_desligamento =
|
21
|
+
arquivos_convertidos.select { _1[:fw_tipo] == 'empregado_desligamento' }
|
22
|
+
empregado_historico_cadastral =
|
23
|
+
arquivos_convertidos.select { _1[:fw_tipo] == 'empregado_historico_cadastral' }
|
24
|
+
empregado_historico_contratual =
|
25
|
+
arquivos_convertidos.select { _1[:fw_tipo] == 'empregado_historico_contratual' }
|
26
|
+
empregado =
|
27
|
+
arquivos_convertidos.select { _1[:fw_tipo] == 'empregado' }
|
28
|
+
empresa =
|
29
|
+
arquivos_convertidos.select { _1[:fw_tipo] == 'empresa' }
|
30
|
+
estabelecimento =
|
31
|
+
arquivos_convertidos.select { _1[:fw_tipo] == 'estabelecimento' }
|
32
|
+
horario =
|
33
|
+
arquivos_convertidos.select { _1[:fw_tipo] == 'horario' }
|
34
|
+
empregados_afastamentos_inicio =
|
35
|
+
arquivos_convertidos.select { _1[:fw_tipo] == 'empregado_afastamento_inicio' }
|
36
|
+
empregados_afastamentos_termino =
|
37
|
+
arquivos_convertidos.select { _1[:fw_tipo] == 'empregado_afastamento_termino' }
|
38
|
+
trabalhador_sem_vinculo =
|
39
|
+
arquivos_convertidos.select { _1[:fw_tipo] == 'trabalhador_sem_vinculo' }
|
40
|
+
trabalhador_sem_vinculo_historico_contratual =
|
41
|
+
arquivos_convertidos.select { _1[:fw_tipo] == 'trabalhador_sem_vinculo_historico_contratual' }
|
42
|
+
trabalhador_sem_vinculo_termino =
|
43
|
+
arquivos_convertidos.select { _1[:fw_tipo] == 'trabalhador_sem_vinculo_termino' }
|
44
|
+
aviso_previo =
|
45
|
+
arquivos_convertidos.select { _1[:fw_tipo] == 'aviso_previo' }
|
46
|
+
comunicacao_de_acidente_de_trabalho =
|
47
|
+
arquivos_convertidos.select { _1[:fw_tipo] == 'comunicacao_de_acidente_de_trabalho' }
|
48
|
+
atestado_de_saude_ocupacional =
|
49
|
+
arquivos_convertidos.select { _1[:fw_tipo] == 'atestado_de_saude_ocupacional' }
|
50
|
+
condicao_ambiental_de_trabalho =
|
51
|
+
arquivos_convertidos.select { _1[:fw_tipo] == 'condicao_ambiental_de_trabalho' }
|
52
|
+
|
53
|
+
gerador_de_arquivos_csv.executar(
|
54
|
+
nome_do_arquivo: 'cargo',
|
55
|
+
dados: cargos
|
56
|
+
)
|
57
|
+
gerador_de_arquivos_csv.executar(
|
58
|
+
nome_do_arquivo: 'lotacao',
|
59
|
+
dados: lotacoes
|
60
|
+
)
|
61
|
+
gerador_de_arquivos_csv.executar(
|
62
|
+
nome_do_arquivo: 'empregado_desligamento',
|
63
|
+
dados: empregado_desligamento
|
64
|
+
)
|
65
|
+
gerador_de_arquivos_csv.executar(
|
66
|
+
nome_do_arquivo: 'empregado_historico_cadastral',
|
67
|
+
dados: empregado_historico_cadastral
|
68
|
+
)
|
69
|
+
gerador_de_arquivos_csv.executar(
|
70
|
+
nome_do_arquivo: 'empregado_historico_contratual',
|
71
|
+
dados: empregado_historico_contratual
|
72
|
+
)
|
73
|
+
gerador_de_arquivos_csv.executar(
|
74
|
+
nome_do_arquivo: 'empregado',
|
75
|
+
dados: empregado
|
76
|
+
)
|
77
|
+
gerador_de_arquivos_csv.executar(
|
78
|
+
nome_do_arquivo: 'empresa',
|
79
|
+
dados: empresa
|
80
|
+
)
|
81
|
+
gerador_de_arquivos_csv.executar(
|
82
|
+
nome_do_arquivo: 'estabelecimento',
|
83
|
+
dados: estabelecimento
|
84
|
+
)
|
85
|
+
gerador_de_arquivos_csv.executar(
|
86
|
+
nome_do_arquivo: 'horario',
|
87
|
+
dados: horario
|
88
|
+
)
|
89
|
+
gerador_de_arquivos_csv.executar(
|
90
|
+
nome_do_arquivo: 'empregado_afastamento_inicio',
|
91
|
+
dados: empregados_afastamentos_inicio
|
92
|
+
)
|
93
|
+
gerador_de_arquivos_csv.executar(
|
94
|
+
nome_do_arquivo: 'empregado_afastamento_termino',
|
95
|
+
dados: empregados_afastamentos_termino
|
96
|
+
)
|
97
|
+
gerador_de_arquivos_csv.executar(
|
98
|
+
nome_do_arquivo: 'trabalhador_sem_vinculo',
|
99
|
+
dados: trabalhador_sem_vinculo
|
100
|
+
)
|
101
|
+
gerador_de_arquivos_csv.executar(
|
102
|
+
nome_do_arquivo: 'trabalhador_sem_vinculo_historico_contratual',
|
103
|
+
dados: trabalhador_sem_vinculo_historico_contratual
|
104
|
+
)
|
105
|
+
gerador_de_arquivos_csv.executar(
|
106
|
+
nome_do_arquivo: 'trabalhador_sem_vinculo_termino',
|
107
|
+
dados: trabalhador_sem_vinculo_termino
|
108
|
+
)
|
109
|
+
gerador_de_arquivos_csv.executar(
|
110
|
+
nome_do_arquivo: 'aviso_previo',
|
111
|
+
dados: aviso_previo
|
112
|
+
)
|
113
|
+
gerador_de_arquivos_csv.executar(
|
114
|
+
nome_do_arquivo: 'comunicacao_de_acidente_de_trabalho',
|
115
|
+
dados: comunicacao_de_acidente_de_trabalho
|
116
|
+
)
|
117
|
+
gerador_de_arquivos_csv.executar(
|
118
|
+
nome_do_arquivo: 'atestado_de_saude_ocupacional',
|
119
|
+
dados: atestado_de_saude_ocupacional
|
120
|
+
)
|
121
|
+
gerador_de_arquivos_csv.executar(
|
122
|
+
nome_do_arquivo: 'condicao_ambiental_de_trabalho',
|
123
|
+
dados: condicao_ambiental_de_trabalho
|
124
|
+
)
|
125
|
+
end
|
126
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'csv'
|
2
|
+
require_relative 'sistema_operacional'
|
3
|
+
|
4
|
+
class GeradorDeArquivosCsv
|
5
|
+
private
|
6
|
+
|
7
|
+
def initialize(pasta_destino)
|
8
|
+
@pasta_destino = pasta_destino
|
9
|
+
end
|
10
|
+
|
11
|
+
attr_reader :pasta_destino
|
12
|
+
|
13
|
+
public
|
14
|
+
|
15
|
+
def executar(nome_do_arquivo:, dados:)
|
16
|
+
if dados.any?
|
17
|
+
CSV.open("#{pasta_destino}#{SistemaOperacional.separador}#{nome_do_arquivo}.csv", 'w') do |csv|
|
18
|
+
csv << dados.first.keys
|
19
|
+
dados.each { csv << _1.values }
|
20
|
+
end
|
21
|
+
else
|
22
|
+
puts "# Gerador de CSV: Não existe dados para o arquivo: #{nome_do_arquivo}"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
class Jornada
|
2
|
+
def self.consistente?(tipo_jornada, horarios) # rubocop:disable Metrics/CyclomaticComplexity
|
3
|
+
case tipo_jornada
|
4
|
+
when nil
|
5
|
+
true
|
6
|
+
when 1
|
7
|
+
horarios.all? { (1..7).cover? _1[:dia] } &&
|
8
|
+
horarios.map { _1[:dia] }.then { _1 == _1.uniq }
|
9
|
+
when 2
|
10
|
+
horarios.size == 1 && horarios.first[:dia] == 8
|
11
|
+
when 3
|
12
|
+
horarios.all? { _1[:dia] == 8 }
|
13
|
+
when 9
|
14
|
+
horarios.nil? || horarios.empty?
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.reconstrucao_fiel?(tipo_jornada)
|
19
|
+
![2, 3].include? tipo_jornada
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,375 @@
|
|
1
|
+
require_relative 'types'
|
2
|
+
require_relative 'arquivo_data'
|
3
|
+
require_relative 'arquivo_cargo'
|
4
|
+
require_relative 'arquivo_empregado'
|
5
|
+
require_relative 'arquivo_empresa'
|
6
|
+
require_relative 'arquivo_horario'
|
7
|
+
require_relative 'arquivo_lotacao'
|
8
|
+
require_relative 'arquivo_estabelecimento'
|
9
|
+
require_relative 'arquivo_trabalhador_sem_vinculo'
|
10
|
+
require_relative 'arquivo_empregado_historico_cadastral'
|
11
|
+
require_relative 'arquivo_empregado_historico_contratual'
|
12
|
+
require_relative 'arquivo_empregado_desligamento'
|
13
|
+
require_relative 'arquivo_trabalhador_sem_vinculo_historico_contratual'
|
14
|
+
require_relative 'arquivo_empregado_afastamento_inicio'
|
15
|
+
require_relative 'arquivo_empregado_afastamento_termino'
|
16
|
+
require_relative 'arquivo_trabalhador_sem_vinculo_termino'
|
17
|
+
require_relative 'arquivo_aviso_previo'
|
18
|
+
require_relative 'arquivo_comunicacao_de_acidente_de_trabalho'
|
19
|
+
require_relative 'arquivo_atestado_de_saude_ocupacional'
|
20
|
+
require_relative 'arquivo_condicao_ambiental_de_trabalho'
|
21
|
+
require_relative 'gerador_de_arquivos'
|
22
|
+
require_relative 'sistema_operacional'
|
23
|
+
|
24
|
+
class Processamento
|
25
|
+
private
|
26
|
+
|
27
|
+
def initialize(caminho_do_diretorio_data, grupo_informado)
|
28
|
+
@caminho_do_diretorio_data = caminho_do_diretorio_data
|
29
|
+
@grupo_informado = grupo_informado
|
30
|
+
|
31
|
+
@erros = []
|
32
|
+
@erros_lotacoes_gerais = []
|
33
|
+
@alertas = []
|
34
|
+
@arquivos_convertidos = []
|
35
|
+
@prefixos_nao_configurados = Set.new
|
36
|
+
@gerador_de_arquivos_csv = GeradorDeArquivosCsv.new(pasta_destino_csv)
|
37
|
+
end
|
38
|
+
|
39
|
+
attr_reader :caminho_do_diretorio_data,
|
40
|
+
:grupo_informado,
|
41
|
+
:arquivos_convertidos,
|
42
|
+
:alertas,
|
43
|
+
:erros,
|
44
|
+
:prefixos_nao_configurados,
|
45
|
+
:gerador_de_arquivos_csv
|
46
|
+
|
47
|
+
public
|
48
|
+
|
49
|
+
def executar
|
50
|
+
return arquivos_data_nao_encontrados_erro if arquivos_data_nao_encontrados?
|
51
|
+
|
52
|
+
processar_arquivos_data
|
53
|
+
|
54
|
+
ajustar_afastamentos_de_inicio
|
55
|
+
|
56
|
+
gerar_erros_afastamentos_com_termino_sem_inicio
|
57
|
+
gerar_erros_horarios_duplicados
|
58
|
+
gerar_erros_cargos_duplicados
|
59
|
+
gerar_erros_empregado_com_contrato_concomitante
|
60
|
+
|
61
|
+
criar_pasta_destino_csv
|
62
|
+
|
63
|
+
erros_ordenados = erros.sort_by { [_1[:type_file], _1[:file_name], _1[:error_message]] }
|
64
|
+
alertas_ordenados = alertas.sort_by { [_1[:type_file], _1[:file_name], _1[:alert_message]] }
|
65
|
+
gerador_de_arquivos_csv.executar(nome_do_arquivo: 'INFO_erros', dados: erros_ordenados)
|
66
|
+
gerador_de_arquivos_csv.executar(nome_do_arquivo: 'INFO_alertas', dados: alertas_ordenados)
|
67
|
+
GeradorDeArquivos.new(
|
68
|
+
gerador_de_arquivos_csv: gerador_de_arquivos_csv,
|
69
|
+
arquivos_convertidos: arquivos_convertidos
|
70
|
+
).executar
|
71
|
+
|
72
|
+
{
|
73
|
+
arquivos_convertidos: arquivos_convertidos,
|
74
|
+
erros: erros_ordenados,
|
75
|
+
alertas: alertas_ordenados,
|
76
|
+
prefixos_nao_configurados: prefixos_nao_configurados,
|
77
|
+
quantidade_de_erros: erros_ordenados.size,
|
78
|
+
quantidade_de_alertas: alertas_ordenados.size,
|
79
|
+
quantidade_de_arquivos_validos: arquivos_convertidos.size
|
80
|
+
}
|
81
|
+
end
|
82
|
+
|
83
|
+
private
|
84
|
+
|
85
|
+
def arquivos_data_nao_encontrados?
|
86
|
+
arquivos_data_nao_encontrados.any?
|
87
|
+
end
|
88
|
+
|
89
|
+
def arquivos_data_nao_encontrados
|
90
|
+
@arquivos_data_nao_encontrados ||=
|
91
|
+
(arquivos_html_que_requerem_arquivo_data - arquivos_data.map { _1.delete_suffix('.data') })
|
92
|
+
.map { "#{_1}.data" }
|
93
|
+
end
|
94
|
+
|
95
|
+
def arquivos_html_que_requerem_arquivo_data
|
96
|
+
@arquivos_html_que_requerem_arquivo_data ||=
|
97
|
+
[
|
98
|
+
*arquivos_html.select { _1.start_with?('CAR') },
|
99
|
+
*arquivos_html.select { _1.start_with?('HOR') },
|
100
|
+
*arquivos_html.select { _1.start_with?('LOT') },
|
101
|
+
*arquivos_html
|
102
|
+
.select { _1.start_with?('TRA') }
|
103
|
+
.reject { _1.include?('CAD') || _1.include?('CON') || _1.include?('DES') }
|
104
|
+
].map { _1.delete_suffix('.html') }
|
105
|
+
end
|
106
|
+
|
107
|
+
def arquivos_html
|
108
|
+
@arquivos_html ||= arquivos_do_diretorio_data.select { File.extname(_1) == '.html' }
|
109
|
+
end
|
110
|
+
|
111
|
+
def arquivos_do_diretorio_data
|
112
|
+
@arquivos_do_diretorio_data ||= Dir.entries(caminho_do_diretorio_data).sort
|
113
|
+
end
|
114
|
+
|
115
|
+
def arquivos_data_nao_encontrados_erro
|
116
|
+
@arquivos_data_nao_encontrados_erro ||=
|
117
|
+
begin
|
118
|
+
fim_de_linha = SistemaOperacional.windows? ? "\r\n" : "\n"
|
119
|
+
<<~HEREDOC
|
120
|
+
Arquivo(s) .data não encontrado(s):
|
121
|
+
#{arquivos_data_nao_encontrados.join("#{fim_de_linha} ")}
|
122
|
+
|
123
|
+
AÇÃO SUGERIDA:
|
124
|
+
Executar robô novamente. Caso o problema continue, tratar com a equipe do robô.
|
125
|
+
HEREDOC
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
def arquivos_data
|
130
|
+
@arquivos_data ||=
|
131
|
+
arquivos_do_diretorio_data
|
132
|
+
.select { File.extname(_1) == '.data' }
|
133
|
+
.tap do |arquivos|
|
134
|
+
# move para o início da lista para garantir que a empresa seja processada antes dos desligamentos (validação do
|
135
|
+
# grupo)
|
136
|
+
arquivo_de_empresa = arquivos.select { _1.start_with?('EMP') }.min
|
137
|
+
arquivos.insert(0, arquivos.delete(arquivo_de_empresa)) if arquivo_de_empresa
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
def processar_arquivos_data # rubocop:disable Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity
|
142
|
+
grupo_da_empresa = nil
|
143
|
+
arquivos_data.each do |nome_do_arquivo_data| # rubocop:disable Metrics/BlockLength
|
144
|
+
caminho_do_arquivo_data = "#{caminho_do_diretorio_data}#{separador}#{nome_do_arquivo_data}"
|
145
|
+
nome_base_do_arquivo_data = File.basename(nome_do_arquivo_data)
|
146
|
+
prefixo = nome_base_do_arquivo_data[0, 3]
|
147
|
+
|
148
|
+
case prefixo
|
149
|
+
when 'EMP'
|
150
|
+
arquivo_empresa = ArquivoEmpresa.new(caminho_do_arquivo_data, grupo_informado)
|
151
|
+
processar(arquivo_empresa)
|
152
|
+
grupo_da_empresa = arquivo_empresa.grupo_da_empresa
|
153
|
+
when 'EST'
|
154
|
+
processar(ArquivoEstabelecimento.new(caminho_do_arquivo_data))
|
155
|
+
when 'CAR'
|
156
|
+
processar(ArquivoCargo.new(caminho_do_arquivo_data))
|
157
|
+
when 'HOR'
|
158
|
+
processar(ArquivoHorario.new(caminho_do_arquivo_data))
|
159
|
+
when 'LOT'
|
160
|
+
processar(ArquivoLotacao.new(caminho_do_arquivo_data))
|
161
|
+
when 'TRA'
|
162
|
+
sufixo = nome_base_do_arquivo_data.split('-').last[0, 3]
|
163
|
+
if sufixo == 'ADM'
|
164
|
+
if nome_base_do_arquivo_data.include?('TSV_')
|
165
|
+
processar(ArquivoTrabalhadorSemVinculo.new(caminho_do_arquivo_data))
|
166
|
+
else
|
167
|
+
processar(ArquivoEmpregado.new(caminho_do_arquivo_data))
|
168
|
+
end
|
169
|
+
elsif nome_base_do_arquivo_data.include?('-ACA[')
|
170
|
+
processar(ArquivoEmpregadoHistoricoCadastral.new(caminho_do_arquivo_data))
|
171
|
+
elsif nome_base_do_arquivo_data.include?('-ACO[')
|
172
|
+
if nome_base_do_arquivo_data.include?('TSV_')
|
173
|
+
processar(ArquivoTrabalhadorSemVinculoHistoricoContratual.new(caminho_do_arquivo_data))
|
174
|
+
else
|
175
|
+
processar(ArquivoEmpregadoHistoricoContratual.new(caminho_do_arquivo_data))
|
176
|
+
end
|
177
|
+
elsif nome_base_do_arquivo_data.include?('-IAF[') && !nome_base_do_arquivo_data.include?('TSV_')
|
178
|
+
processar(ArquivoEmpregadoAfastamentoInicio.new(caminho_do_arquivo_data))
|
179
|
+
elsif nome_base_do_arquivo_data.include?('-TAF[') && !nome_base_do_arquivo_data.include?('TSV_')
|
180
|
+
processar(ArquivoEmpregadoAfastamentoTermino.new(caminho_do_arquivo_data))
|
181
|
+
elsif sufixo == 'GER'
|
182
|
+
if nome_base_do_arquivo_data.include?('TSV_')
|
183
|
+
processar(ArquivoTrabalhadorSemVinculoTermino.new(caminho_do_arquivo_data))
|
184
|
+
else
|
185
|
+
processar(ArquivoEmpregadoDesligamento.new(caminho_do_arquivo_data, grupo_da_empresa))
|
186
|
+
end
|
187
|
+
elsif sufixo == 'AVI'
|
188
|
+
processar(ArquivoAvisoPrevio.new(caminho_do_arquivo_data))
|
189
|
+
else
|
190
|
+
prefixos_nao_configurados << "#{prefixo}-#{sufixo}"
|
191
|
+
end
|
192
|
+
when 'CAT'
|
193
|
+
processar(ArquivoComunicacaoDeAcidenteDeTrabalho.new(caminho_do_arquivo_data))
|
194
|
+
when 'ASO'
|
195
|
+
processar(ArquivoAtestadoDeSaudeOcupacional.new(caminho_do_arquivo_data))
|
196
|
+
when 'AMB'
|
197
|
+
processar(ArquivoCondicaoAmbientalDeTrabalho.new(caminho_do_arquivo_data))
|
198
|
+
else
|
199
|
+
prefixos_nao_configurados << prefixo
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
def processar(arquivo)
|
205
|
+
arquivo.processar
|
206
|
+
if arquivo.erros.empty?
|
207
|
+
arquivos_convertidos << arquivo.atributos
|
208
|
+
alertas.push(*arquivo.alertas)
|
209
|
+
else
|
210
|
+
erros.push(*arquivo.erros)
|
211
|
+
end
|
212
|
+
arquivo.atributos
|
213
|
+
end
|
214
|
+
|
215
|
+
def ajustar_afastamentos_de_inicio
|
216
|
+
afastamentos_de_inicio.each do |afastamento|
|
217
|
+
afastamentos_no_inicio_da_fase_2
|
218
|
+
.find { _1[:matricula] == afastamento[:matricula] && _1[:data_inicio_afastamento] == afastamento[:data_inicio_afastamento] } # rubocop:disable Layout/LineLength
|
219
|
+
&.then do |afastamento_no_inicio_da_fase_2|
|
220
|
+
afastamento[:codigo_motivo] = afastamento_no_inicio_da_fase_2[:codigo_motivo]
|
221
|
+
end
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
def afastamentos_de_inicio
|
226
|
+
@afastamentos_de_inicio ||= arquivos_convertidos.select { _1[:fw_tipo] == 'empregado_afastamento_inicio' }
|
227
|
+
end
|
228
|
+
|
229
|
+
def afastamentos_no_inicio_da_fase_2
|
230
|
+
@afastamentos_no_inicio_da_fase_2 ||=
|
231
|
+
arquivos_convertidos
|
232
|
+
.select { _1[:fw_tipo] == 'empregado' && _1[:data_inicio_afastamento] }
|
233
|
+
.map do |empregado|
|
234
|
+
{
|
235
|
+
matricula: empregado[:matricula],
|
236
|
+
data_inicio_afastamento: empregado[:data_inicio_afastamento].to_s,
|
237
|
+
codigo_motivo: empregado[:motivo_afastamento]
|
238
|
+
}
|
239
|
+
end
|
240
|
+
end
|
241
|
+
|
242
|
+
def afastamentos_de_termino_ou_completos
|
243
|
+
arquivos_convertidos.select { _1[:fw_tipo] == 'empregado_afastamento_termino' }
|
244
|
+
end
|
245
|
+
|
246
|
+
def gerar_erros_afastamentos_com_termino_sem_inicio
|
247
|
+
afastamentos_incompletos
|
248
|
+
.select { _1[:fw_tipo] == 'empregado_afastamento_termino' && _1[:inicio_termino_enviados_juntos].nil? }
|
249
|
+
.each do |afastamento|
|
250
|
+
erros << {
|
251
|
+
file_name: afastamento[:file_name],
|
252
|
+
type_file: 'empregado_afastamento_termino',
|
253
|
+
error_message: "Empregado #{afastamento[:matricula]} possui afastamento de término " \
|
254
|
+
"#{afastamento[:data_termino_afastamento]} sem início."
|
255
|
+
}
|
256
|
+
end
|
257
|
+
end
|
258
|
+
|
259
|
+
def gerar_erros_horarios_duplicados
|
260
|
+
horarios
|
261
|
+
.map { _1[:codigo_horario_contratual] }
|
262
|
+
.tally
|
263
|
+
.select { |_, qtd| qtd > 1 }
|
264
|
+
.each_key do |codigo_do_horario|
|
265
|
+
erros << {
|
266
|
+
file_name: '- -',
|
267
|
+
type_file: 'horario',
|
268
|
+
error_message: "O Horário com código #{codigo_do_horario} possui histórico."
|
269
|
+
}
|
270
|
+
end
|
271
|
+
end
|
272
|
+
|
273
|
+
def horarios
|
274
|
+
arquivos_convertidos.select { _1[:fw_tipo] == 'horario' }
|
275
|
+
end
|
276
|
+
|
277
|
+
def gerar_erros_cargos_duplicados
|
278
|
+
cargos
|
279
|
+
.map { _1[:codigo_cargo] }
|
280
|
+
.tally
|
281
|
+
.select { |_, qtd| qtd > 1 }
|
282
|
+
.each_key do |codigo_do_cargo|
|
283
|
+
erros << {
|
284
|
+
file_name: '- -',
|
285
|
+
type_file: 'cargo',
|
286
|
+
error_message: "O Cargo com código #{codigo_do_cargo} possui histórico."
|
287
|
+
}
|
288
|
+
end
|
289
|
+
end
|
290
|
+
|
291
|
+
def cargos
|
292
|
+
arquivos_convertidos.select { _1[:fw_tipo] == 'cargo' }
|
293
|
+
end
|
294
|
+
|
295
|
+
def gerar_erros_empregado_com_contrato_concomitante
|
296
|
+
trabalhadores
|
297
|
+
.map { _1[:cpf] }
|
298
|
+
.tally
|
299
|
+
.select { |_, qtd| qtd > 1 }
|
300
|
+
.keys
|
301
|
+
.select { contrato_concomitante?(_1) }
|
302
|
+
.each do |trabalhador_cpf|
|
303
|
+
erros << {
|
304
|
+
file_name: '- -',
|
305
|
+
type_file: 'empregado',
|
306
|
+
error_message: "O Trabalhador com CPF #{trabalhador_cpf} possui contratos de emprego concomitantes."
|
307
|
+
}
|
308
|
+
end
|
309
|
+
end
|
310
|
+
|
311
|
+
def trabalhadores
|
312
|
+
arquivos_convertidos
|
313
|
+
.select { _1[:fw_tipo] == 'empregado' }
|
314
|
+
.sort_by { _1[:data_admissao_celetista] }
|
315
|
+
end
|
316
|
+
|
317
|
+
def contrato_concomitante?(trabalhador_cpf)
|
318
|
+
desligamentos_do_trabalhador = desligamentos.select { _1[:cpf] == trabalhador_cpf }
|
319
|
+
|
320
|
+
contratos_do_trabalhador =
|
321
|
+
trabalhadores
|
322
|
+
.select { _1[:cpf] == trabalhador_cpf }
|
323
|
+
.map do |trabalhador|
|
324
|
+
inicio = trabalhador[:data_admissao_celetista]
|
325
|
+
fim = (desligamentos_do_trabalhador.find { _1[:data_admissao] == inicio } || {})[:data_desligamento]
|
326
|
+
Struct.new(:inicio, :fim).new(inicio, fim)
|
327
|
+
end
|
328
|
+
|
329
|
+
contratos_do_trabalhador
|
330
|
+
.each_cons(2)
|
331
|
+
.any? { |contrato_1, contrato_2| contrato_1.fim.nil? || contrato_1.fim >= contrato_2.inicio }
|
332
|
+
end
|
333
|
+
|
334
|
+
def desligamentos
|
335
|
+
arquivos_convertidos
|
336
|
+
.select { _1[:fw_tipo] == 'empregado_desligamento' }
|
337
|
+
.sort_by { _1[:data_desligamento] }
|
338
|
+
end
|
339
|
+
|
340
|
+
def afastamentos_incompletos
|
341
|
+
@afastamentos_incompletos ||=
|
342
|
+
unir_inicio_termino_afastamentos
|
343
|
+
.values
|
344
|
+
.select { _1.size < 2 }
|
345
|
+
.flatten
|
346
|
+
end
|
347
|
+
|
348
|
+
def unir_inicio_termino_afastamentos
|
349
|
+
(afastamentos_de_inicio + afastamentos_de_termino_ou_completos)
|
350
|
+
.group_by { [_1[:matricula], _1[:data_inicio_afastamento]] }
|
351
|
+
end
|
352
|
+
|
353
|
+
def criar_pasta_destino_csv
|
354
|
+
criar_pasta(pasta_base)
|
355
|
+
criar_pasta(pasta_destino_csv)
|
356
|
+
end
|
357
|
+
|
358
|
+
def criar_pasta(pasta)
|
359
|
+
Dir.mkdir(pasta)
|
360
|
+
rescue Errno::EEXIST
|
361
|
+
nil
|
362
|
+
end
|
363
|
+
|
364
|
+
def pasta_base
|
365
|
+
@pasta_base ||= "#{SistemaOperacional.windows? ? 'C:\\tmp\\' : '/tmp/'}arquivos_csv_fw"
|
366
|
+
end
|
367
|
+
|
368
|
+
def pasta_destino_csv
|
369
|
+
@pasta_destino_csv ||= "#{pasta_base}#{separador}#{Time.now.strftime('%Y%m%d_%H%M%S')}"
|
370
|
+
end
|
371
|
+
|
372
|
+
def separador
|
373
|
+
@separador ||= SistemaOperacional.separador
|
374
|
+
end
|
375
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module SistemaOperacional
|
2
|
+
class << self
|
3
|
+
def separador
|
4
|
+
windows? ? '\\' : '/'
|
5
|
+
end
|
6
|
+
|
7
|
+
def windows?
|
8
|
+
nome == :windows
|
9
|
+
end
|
10
|
+
|
11
|
+
def nome
|
12
|
+
host_os = RbConfig::CONFIG['host_os']
|
13
|
+
case host_os
|
14
|
+
when /mswin|msys|mingw|cygwin|bccwin|wince|emc/
|
15
|
+
:windows
|
16
|
+
when /darwin|mac os/
|
17
|
+
:macosx
|
18
|
+
when /linux/
|
19
|
+
:linux
|
20
|
+
when /solaris|bsd/
|
21
|
+
:unix
|
22
|
+
else
|
23
|
+
raise NaoIdentificado, host_os
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
class NaoIdentificado < StandardError
|
29
|
+
def initialize(nome_do_sistema_operacional)
|
30
|
+
super("Sistema operacional desconhecido: #{nome_do_sistema_operacional}")
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|