teodoro 0.0.8 → 0.0.13

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 (33) hide show
  1. checksums.yaml +4 -4
  2. data/lib/teodoro.rb +3 -9
  3. data/lib/teodoro/arquivo_de_evento.rb +17 -24
  4. data/lib/teodoro/arquivo_de_evento_de_tabela.rb +2 -12
  5. data/lib/teodoro/arquivo_de_evento_exceto_de_exclusao.rb +25 -0
  6. data/lib/teodoro/arquivo_de_evento_nao_periodico.rb +6 -15
  7. data/lib/teodoro/arquivo_de_origem.rb +1 -1
  8. data/lib/teodoro/arquivo_xml.rb +71 -57
  9. data/lib/teodoro/console.rb +2 -6
  10. data/lib/teodoro/empresa.rb +42 -13
  11. data/lib/teodoro/leiaute.rb +24 -0
  12. data/lib/teodoro/{leiaute_2_4_1 → leiaute}/arquivo_s1000.rb +3 -3
  13. data/lib/teodoro/{leiaute_2_4_1 → leiaute}/arquivo_s1005.rb +1 -1
  14. data/lib/teodoro/{leiaute_2_4_1 → leiaute}/arquivo_s1010.rb +2 -2
  15. data/lib/teodoro/{leiaute_2_4_1 → leiaute}/arquivo_s1020.rb +1 -1
  16. data/lib/teodoro/{leiaute_2_4_1 → leiaute}/arquivo_s1030.rb +1 -1
  17. data/lib/teodoro/{leiaute_2_4_1 → leiaute}/arquivo_s1040.rb +1 -1
  18. data/lib/teodoro/{leiaute_2_4_1 → leiaute}/arquivo_s1050.rb +1 -1
  19. data/lib/teodoro/{leiaute_2_4_1 → leiaute}/arquivo_s1070.rb +1 -1
  20. data/lib/teodoro/{leiaute_2_4_1 → leiaute}/arquivo_s2190.rb +2 -2
  21. data/lib/teodoro/{leiaute_2_4_1 → leiaute}/arquivo_s2200.rb +129 -22
  22. data/lib/teodoro/{leiaute_2_4_1 → leiaute}/arquivo_s2205.rb +2 -2
  23. data/lib/teodoro/{leiaute_2_4_1 → leiaute}/arquivo_s2206.rb +15 -4
  24. data/lib/teodoro/{leiaute_2_4_1 → leiaute}/arquivo_s2230.rb +1 -1
  25. data/lib/teodoro/{leiaute_2_4_1 → leiaute}/arquivo_s2250.rb +25 -9
  26. data/lib/teodoro/leiaute/arquivo_s2299.rb +310 -0
  27. data/lib/teodoro/{leiaute_2_4_1 → leiaute}/arquivo_s2300.rb +21 -2
  28. data/lib/teodoro/{leiaute_2_4_1 → leiaute}/arquivo_s2306.rb +27 -7
  29. data/lib/teodoro/leiaute/arquivo_s2399.rb +304 -0
  30. data/lib/teodoro/leiaute/arquivo_s3000.rb +41 -0
  31. data/lib/teodoro/obj.rb +5 -0
  32. metadata +24 -19
  33. data/lib/teodoro/leiaute_2_4_1.rb +0 -21
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 715220b95bb70bc46665ecff3b112fc2d5ed6496ce069c1f186b9c2763b28c90
4
- data.tar.gz: 753ce68d220b8134f457df47ac6cefd007530a10d51534689e816a091819228d
3
+ metadata.gz: d13e1befb47f42baadda75f5ee3fbab43f2903ad4853c22d9f8a5dc2d3e5b484
4
+ data.tar.gz: 7d200caa9e141f52a9a486b033247d4f49c3c158839dd808985e38f9480d2f86
5
5
  SHA512:
6
- metadata.gz: 8ae28ea683456163c96e3efa9f78bcc9b3f880826bb46c2267a608757c0d8f8225e5209c19bf1b46e916d4724c240272813274c336c3221cdd46c5e144fa386e
7
- data.tar.gz: f9c43aabab55122d8ca1044da63a0496baeacd6039cfdfc5a00679b508fe9744d2ea1188a6523ab340a44fb03a0c93e8a6543574be364bb12a7147c5f2e4f828
6
+ metadata.gz: 7cb73aef9770bc0de0c95d311257d470166d852509d03977dc8e7aedb77236aca8e1eb7b127ce7d6ddcefc932b4a2ecb7e7b8e80de77068ea2e6a497187956f4
7
+ data.tar.gz: 6d3c6f76c54af41cdde69b54fc2a6d9245dec8e258fada8b22a8162d587b46cdf36c8bfac99bc47af2a13f63614b52f81fab74ba25efa10b27743d9ca6c9dc3d
data/lib/teodoro.rb CHANGED
@@ -4,6 +4,7 @@ require 'zip'
4
4
 
5
5
  require_relative 'teodoro/console'
6
6
  require_relative 'teodoro/empresa'
7
+ require_relative 'teodoro/obj'
7
8
 
8
9
  module Teodoro
9
10
  def self.call(args)
@@ -24,15 +25,6 @@ module Teodoro
24
25
  public
25
26
 
26
27
  def call
27
- executar
28
- rescue StandardError => e
29
- Console.print e.message, *e.backtrace, color: :red
30
- exit
31
- end
32
-
33
- private
34
-
35
- def executar
36
28
  validar_argumentos
37
29
  validar_existencia_do_diretorio_de_origem
38
30
  validar_que_diretorio_de_origem_nao_esta_vazio
@@ -41,6 +33,8 @@ module Teodoro
41
33
  processar_empresas
42
34
  end
43
35
 
36
+ private
37
+
44
38
  def validar_argumentos
45
39
  erro "#{NOME_DO_PROGRAMA} [diretório de origem] [diretório de destino]" unless args.size == 2
46
40
  end
@@ -2,12 +2,21 @@ module Teodoro
2
2
  module ArquivoDeEvento
3
3
  private
4
4
 
5
- attr_reader :xml_do_evento, :xml_do_recibo, :destino_dos_arquivos_data
5
+ def initialize(empresa:, versao_do_leiaute:, evento:, recibo:)
6
+ @empresa = empresa
7
+ @versao_do_leiaute = versao_do_leiaute
8
+ @evento = evento
9
+ @recibo = recibo
10
+ end
11
+
12
+ attr_reader :empresa, :versao_do_leiaute, :evento, :recibo
6
13
 
7
- def criar_arquivo_data
8
- raise caminho_do_arquivo_data if File.exist?(caminho_do_arquivo_data)
14
+ def leiaute_simplificado?
15
+ versao_do_leiaute.start_with?('_S_')
16
+ end
9
17
 
10
- File.write(caminho_do_arquivo_data, conteudo_do_arquivo_data)
18
+ def processo_de_emissao_do_evento
19
+ evento["#{noh_principal_do_evento}/ideEvento/procEmi"]
11
20
  end
12
21
 
13
22
  def criar_caminho_do_arquivo_data(nome_do_arquivo)
@@ -17,28 +26,12 @@ module Teodoro
17
26
  )
18
27
  end
19
28
 
20
- def windows?
21
- OS.windows?
22
- end
23
-
24
- def evento
25
- @evento ||= XML.new(xml_do_evento)
29
+ def destino_dos_arquivos_data
30
+ empresa.destino_dos_arquivos_data
26
31
  end
27
32
 
28
- def conteudo_do_arquivo_data
29
- (itens_do_conteudo_do_arquivo_data.map { "#{_1}=#{_2}" } + ['']).join("\n")
30
- end
31
-
32
- def versao_do_aplicativo_de_processamento_do_evento
33
- recibo['retornoEvento/processamento/versaoAppProcessamento']
34
- end
35
-
36
- def tipo_de_inscricao_do_empregador
37
- @tipo_de_inscricao_do_empregador ||= evento["#{noh_principal_do_evento}/ideEmpregador/tpInsc"]
38
- end
39
-
40
- def recibo
41
- @recibo ||= XML.new(xml_do_recibo)
33
+ def windows?
34
+ OS.windows?
42
35
  end
43
36
  end
44
37
  end
@@ -1,16 +1,6 @@
1
1
  module Teodoro
2
2
  module ArquivoDeEventoDeTabela
3
- include ArquivoDeEvento
4
-
5
- private
6
-
7
- def initialize(xml_do_evento:, xml_do_recibo:, destino_dos_arquivos_data:)
8
- @xml_do_evento = xml_do_evento
9
- @xml_do_recibo = xml_do_recibo
10
- @destino_dos_arquivos_data = destino_dos_arquivos_data
11
- end
12
-
13
- public
3
+ include ArquivoDeEventoExcetoDeExclusao
14
4
 
15
5
  def processar
16
6
  deletar_arquivo_data_original if alteracao? || exclusao?
@@ -47,7 +37,7 @@ module Teodoro
47
37
  end
48
38
 
49
39
  def caminho_do_arquivo_data
50
- # FIXME: Tales inicio de validade
40
+ # FIXME: Tales inicio de validade ou inicio da nova validade?
51
41
  obter_caminho_do_arquivo_data(inicio_da_validade)
52
42
  end
53
43
 
@@ -0,0 +1,25 @@
1
+ module Teodoro
2
+ module ArquivoDeEventoExcetoDeExclusao
3
+ include ArquivoDeEvento
4
+
5
+ private
6
+
7
+ def criar_arquivo_data
8
+ raise caminho_do_arquivo_data if File.exist?(caminho_do_arquivo_data)
9
+
10
+ File.write(caminho_do_arquivo_data, conteudo_do_arquivo_data)
11
+ end
12
+
13
+ def conteudo_do_arquivo_data
14
+ (itens_do_conteudo_do_arquivo_data.map { "#{_1}=#{_2}" } + ['']).join("\n")
15
+ end
16
+
17
+ def versao_do_aplicativo_de_processamento_do_evento
18
+ recibo['retornoEvento/processamento/versaoAppProcessamento']
19
+ end
20
+
21
+ def tipo_de_inscricao_do_empregador
22
+ @tipo_de_inscricao_do_empregador ||= evento["#{noh_principal_do_evento}/ideEmpregador/tpInsc"]
23
+ end
24
+ end
25
+ end
@@ -1,19 +1,6 @@
1
1
  module Teodoro
2
2
  module ArquivoDeEventoNaoPeriodico
3
- include ArquivoDeEvento
4
-
5
- private
6
-
7
- def initialize(xml_do_evento:, xml_do_recibo:, destino_dos_arquivos_data:, de_recibo_para_nome_do_arquivo_data:)
8
- @xml_do_evento = xml_do_evento
9
- @xml_do_recibo = xml_do_recibo
10
- @destino_dos_arquivos_data = destino_dos_arquivos_data
11
- @de_recibo_para_nome_do_arquivo_data = de_recibo_para_nome_do_arquivo_data
12
- end
13
-
14
- attr_reader :de_recibo_para_nome_do_arquivo_data
15
-
16
- public
3
+ include ArquivoDeEventoExcetoDeExclusao
17
4
 
18
5
  def processar
19
6
  deletar_arquivo_data_original if retificacao?
@@ -39,8 +26,12 @@ module Teodoro
39
26
  de_recibo_para_nome_do_arquivo_data[numero_do_recibo_a_retificar]
40
27
  end
41
28
 
29
+ def de_recibo_para_nome_do_arquivo_data
30
+ empresa.de_recibo_para_nome_do_arquivo_data
31
+ end
32
+
42
33
  def numero_do_recibo_a_retificar
43
- @numero_do_recibo_a_retificar ||= evento["#{noh_principal_do_evento}/ideEvento/nrRecibo"]
34
+ evento["#{noh_principal_do_evento}/ideEvento/nrRecibo"]
44
35
  end
45
36
 
46
37
  def registrar_recibo
@@ -14,7 +14,7 @@ module Teodoro
14
14
  public
15
15
 
16
16
  def descompactar
17
- print "\e[2Kdescompactando #{File.basename(caminho)}...\r"
17
+ Console.print "descompactando #{File.basename(caminho)}..."
18
18
 
19
19
  Zip::File.open(caminho) do |zip|
20
20
  zip
@@ -1,114 +1,128 @@
1
1
  require_relative 'arquivo_de_evento'
2
+ require_relative 'arquivo_de_evento_exceto_de_exclusao'
2
3
  require_relative 'arquivo_de_evento_de_tabela'
3
4
  require_relative 'arquivo_de_evento_nao_periodico'
4
5
  require_relative 'cnpj'
5
- require_relative 'leiaute_2_4_1'
6
+ require_relative 'leiaute'
6
7
  require_relative 'xml'
7
8
 
8
9
  module Teodoro
9
10
  class ArquivoXML
11
+ TIPOS_DE_EVENTO_PROCESSAVEIS = %w[
12
+ S1000
13
+ S1005
14
+ S1010
15
+ S1020
16
+ S1030
17
+ S1040
18
+ S1050
19
+ S1070
20
+ S2190
21
+ S2200
22
+ S2205
23
+ S2206
24
+ S2230
25
+ S2250
26
+ S2299
27
+ S2300
28
+ S2306
29
+ S2399
30
+ S3000
31
+ ].freeze
32
+
10
33
  private
11
34
 
12
- def initialize(caminho:, destino_dos_arquivos_data:, de_recibo_para_nome_do_arquivo_data:)
35
+ def initialize(empresa:, caminho:)
36
+ @empresa = empresa
13
37
  @caminho = caminho
14
- @destino_dos_arquivos_data = destino_dos_arquivos_data
15
- @de_recibo_para_nome_do_arquivo_data = de_recibo_para_nome_do_arquivo_data
16
38
  end
17
39
 
18
- attr_reader :caminho, :destino_dos_arquivos_data, :de_recibo_para_nome_do_arquivo_data
40
+ attr_reader :empresa, :caminho
19
41
 
20
42
  public
21
43
 
44
+ def processavel?
45
+ TIPOS_DE_EVENTO_PROCESSAVEIS.include?(tipo_de_evento)
46
+ end
47
+
48
+ def momento_de_processamento_pelo_e_social
49
+ # otimizacao do gerenciamento de memoria
50
+ carregar_xml
51
+ .then { |xml| Nokogiri::XML(xml.css('eSocial/retornoProcessamentoDownload/recibo/*').to_s) }
52
+ .then { |xml_do_recibo| XML.new(xml_do_recibo) }
53
+ .then { |recibo| recibo['retornoEvento/processamento/dhProcessamento'] }
54
+ end
55
+
22
56
  def nome
23
57
  @nome ||= File.basename(caminho, '.xml')
24
58
  end
25
59
 
26
60
  def processar
27
- print "\e[2Kprocessando #{nome}.xml...\r"
28
-
29
- return unless %w[S1000 S1005 S1010 S1020 S1030 S1040 S1050 S1070 S2190 S2200 S2205 S2206 S2230 S2250 S2300 S2306]
30
- .include?(tipo_de_evento)
31
-
32
- arquivo.processar
61
+ dar_feedback_para_o_usuario
62
+ validar_versao_do_leiaute
63
+ processar_arquivo
33
64
  end
34
65
 
35
66
  private
36
67
 
37
68
  def tipo_de_evento
38
- nome[-6..].delete('-')
69
+ @tipo_de_evento ||= nome[-6..].delete('-')
39
70
  end
40
71
 
41
- def arquivo
42
- if evento_de_tabela?
43
- evento_de_tabela
44
- elsif evento_nao_periodico?
45
- evento_nao_periodico
46
- end
72
+ def carregar_xml
73
+ Nokogiri::XML(carregar_conteudo)
47
74
  end
48
75
 
49
- def evento_de_tabela?
50
- tipo_de_evento.start_with?('S10')
76
+ def carregar_conteudo
77
+ File.read(caminho)
51
78
  end
52
79
 
53
- def evento_de_tabela
54
- classe_do_arquivo.new(
55
- xml_do_evento: xml_do_evento,
56
- xml_do_recibo: xml_do_recibo,
57
- destino_dos_arquivos_data: destino_dos_arquivos_data
58
- )
80
+ def dar_feedback_para_o_usuario
81
+ Console.print "processando #{nome}.xml..."
59
82
  end
60
83
 
61
- def evento_nao_periodico?
62
- tipo_de_evento.start_with?('S2')
84
+ def validar_versao_do_leiaute
85
+ raise unless %w[02_04_01 02_04_02 02_05_00 _S_01_00_00].include?(versao_do_leiaute)
63
86
  end
64
87
 
65
- def evento_nao_periodico
66
- classe_do_arquivo.new(
67
- xml_do_evento: xml_do_evento,
68
- xml_do_recibo: xml_do_recibo,
69
- destino_dos_arquivos_data: destino_dos_arquivos_data,
70
- de_recibo_para_nome_do_arquivo_data: de_recibo_para_nome_do_arquivo_data
71
- )
88
+ def versao_do_leiaute
89
+ @versao_do_leiaute ||= namespace_do_evento.match(%r{.+/v(.+)$})[1]
72
90
  end
73
91
 
74
- def classe_do_arquivo
75
- modulo_do_leiaute.const_get("Arquivo#{tipo_de_evento}")
92
+ def namespace_do_evento
93
+ xml_do_evento.css('eSocial')[0].namespace.href
76
94
  end
77
95
 
78
- def modulo_do_leiaute
79
- {
80
- '02_04_01' => Leiaute_2_4_1,
81
- '02_04_02' => Leiaute_2_4_1, # FIXME: Tales
82
- '02_05_00' => Leiaute_2_4_1, # FIXME: Tales
83
- '01_00_00' => Leiaute_2_4_1 # FIXME: Tales
84
- }[versao_do_leiaute_no_xml]
96
+ def xml_do_evento
97
+ @xml_do_evento ||= Nokogiri::XML(xml.css('eSocial/retornoProcessamentoDownload/evento/*').to_s)
85
98
  end
86
99
 
87
- def versao_do_leiaute_no_xml
88
- namespace_do_evento.match(%r{.+/v(.+)$})[1]
100
+ def xml
101
+ @xml ||= carregar_xml
89
102
  end
90
103
 
91
- def namespace_do_evento
92
- xml_do_evento.css('eSocial')[0].namespace.href
104
+ def processar_arquivo
105
+ arquivo.processar
93
106
  end
94
107
 
95
- def xml_do_evento
96
- @xml_do_evento ||= Nokogiri::XML(xml.css('eSocial/retornoProcessamentoDownload/evento/*').to_s)
108
+ def arquivo
109
+ classe_do_arquivo.new(empresa: empresa, versao_do_leiaute: versao_do_leiaute, evento: evento, recibo: recibo)
97
110
  end
98
111
 
99
- def xml
100
- @xml ||= Nokogiri::XML(conteudo)
112
+ def classe_do_arquivo
113
+ Leiaute.const_get("Arquivo#{tipo_de_evento}")
101
114
  end
102
115
 
103
- def conteudo
104
- File.read(caminho)
116
+ def evento
117
+ XML.new(xml_do_evento)
105
118
  end
106
119
 
107
- def xml_do_recibo
108
- Nokogiri::XML(xml.css('eSocial/retornoProcessamentoDownload/recibo/*').to_s)
120
+ def recibo
121
+ @recibo ||= XML.new(xml_do_recibo)
109
122
  end
110
123
 
111
- module Base
124
+ def xml_do_recibo
125
+ Nokogiri::XML(xml.css('eSocial/retornoProcessamentoDownload/recibo/*').to_s)
112
126
  end
113
127
  end
114
128
  end
@@ -1,9 +1,5 @@
1
1
  module Console
2
- class << self
3
- def print(*strings, color: nil)
4
- color_codes = { green: 32, red: 31 }
5
- strings = strings.map { |string| "\e[#{color_codes[color]}m#{string}\e[0m" } if color
6
- puts strings
7
- end
2
+ def self.print(string = nil)
3
+ Kernel.print "\r\e[2K#{string}"
8
4
  end
9
5
  end
@@ -20,6 +20,7 @@ module Teodoro
20
20
  criar_diretorio_dos_arquivos_xml
21
21
  descompactar_arquivos_de_origem
22
22
  criar_diretorio_dos_arquivos_data
23
+ ordenar_arquivos_xml
23
24
  processar_arquivos_xml
24
25
  limpar_linha_de_feedback
25
26
  end
@@ -27,7 +28,7 @@ module Teodoro
27
28
  private
28
29
 
29
30
  def dar_feedback_para_o_usuario
30
- Console.print nome_do_diretorio, color: :green
31
+ puts "\e[32m#{nome_do_diretorio}\e[0m" # green
31
32
  end
32
33
 
33
34
  def nome_do_diretorio
@@ -63,27 +64,55 @@ module Teodoro
63
64
  @destino_dos_arquivos_data ||= File.join(destino, 'data')
64
65
  end
65
66
 
67
+ def ordenar_arquivos_xml
68
+ Console.print 'ordenando os arquivos XML...'
69
+ arquivos_xml.sort_by! { [_1.momento_de_processamento_pelo_e_social, _1.nome] }
70
+ end
71
+
66
72
  def processar_arquivos_xml
67
- arquivos_xml.each(&:processar)
73
+ # otimizacao do gerenciamento de memoria
74
+ arquivos_xml.shift.processar while arquivos_xml.any?
68
75
  end
69
76
 
70
77
  def arquivos_xml
71
- Dir[File.join(destino_dos_arquivos_xml, '*.xml')]
72
- .map do |caminho|
73
- ArquivoXML.new(
74
- caminho: caminho,
75
- destino_dos_arquivos_data: destino_dos_arquivos_data,
76
- de_recibo_para_nome_do_arquivo_data: de_recibo_para_nome_do_arquivo_data
77
- )
78
- end
78
+ @arquivos_xml ||= Dir[File.join(destino_dos_arquivos_xml, '*.xml')]
79
+ .map { |caminho| ArquivoXML.new(empresa: empresa, caminho: caminho) }
80
+ .select(&:processavel?)
79
81
  end
80
82
 
81
- def de_recibo_para_nome_do_arquivo_data
82
- @de_recibo_para_nome_do_arquivo_data ||= {}
83
+ def empresa
84
+ @empresa ||= Obj.new(
85
+ destino_dos_arquivos_data: destino_dos_arquivos_data,
86
+ de_recibo_para_nome_do_arquivo_data: {},
87
+ admissoes_por_matricula: {},
88
+ contratos_de_trabalhado_sem_vinculo: ContratosDeTrabalhadorSemVinculo.new
89
+ )
83
90
  end
84
91
 
85
92
  def limpar_linha_de_feedback
86
- print "\e[2K"
93
+ Console.print
94
+ end
95
+
96
+ class ContratosDeTrabalhadorSemVinculo
97
+ def <<(contrato)
98
+ contratos << contrato
99
+ end
100
+
101
+ def [](cpf_do_trabalhador:, categoria_do_trabalhador:, data:)
102
+ contratos
103
+ .select {
104
+ [_1.cpf_do_trabalhador, _1.categoria_do_trabalhador] == [cpf_do_trabalhador, categoria_do_trabalhador]
105
+ }
106
+ .sort_by(&:data_de_inicio)
107
+ .reverse
108
+ .find { _1.data_de_inicio <= data }
109
+ end
110
+
111
+ private
112
+
113
+ def contratos
114
+ @contratos ||= []
115
+ end
87
116
  end
88
117
  end
89
118
  end