teodoro 0.0.1

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: f52315cdc04dcedfa262aeffbbcf9b562edaeca3a7b6fa628790965eb7e6350d
4
+ data.tar.gz: 4aa688c1be3f577d88961bd083c2f1a70fa6a63bb7e652ea16bd4ddc79ff4c15
5
+ SHA512:
6
+ metadata.gz: 6ed9f5becb3bb8e962c67498c2c5ce28bc38699328c51697d59e2e0f41385512d15c2f8b67b23f1355727458c52043b8660f59ad7b13446c84c37c81babb171a
7
+ data.tar.gz: 563df80495ef39e03876bb3a0c8a15729c94f1cd7fbb21d5e375d53daabce2d20dc95e110eca9453c547bf616e017cde8798ca6c4c2a0b4bd5f69e9b74adc408
data/bin/teodoro ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+ require 'teodoro'
3
+ Teodoro.call
data/lib/teodoro.rb ADDED
@@ -0,0 +1,7 @@
1
+ require_relative 'teodoro/execucao'
2
+
3
+ module Teodoro
4
+ def self.call
5
+ Execucao.new(origem: ARGV[0], destino: ARGV[1]).call
6
+ end
7
+ end
@@ -0,0 +1,31 @@
1
+ module Teodoro
2
+ module ArquivoDeEvento
3
+ private
4
+
5
+ attr_reader :xml_do_evento, :xml_do_recibo, :destino_dos_arquivos_data
6
+
7
+ def criar_arquivo_data
8
+ File.write(caminho_do_arquivo_data, conteudo_do_arquivo_data)
9
+ end
10
+
11
+ def evento
12
+ @evento ||= XML.new(xml_do_evento)
13
+ end
14
+
15
+ def conteudo_do_arquivo_data
16
+ (itens_do_conteudo_do_arquivo_data.map { "#{_1}=#{_2}" } + ['']).join("\n")
17
+ end
18
+
19
+ def versao_do_aplicativo_de_processamento_do_evento
20
+ recibo['retornoEvento/processamento/versaoAppProcessamento']
21
+ end
22
+
23
+ def tipo_de_inscricao_do_empregador
24
+ @tipo_de_inscricao_do_empregador ||= evento["#{noh_principal_do_evento}/ideEmpregador/tpInsc"]
25
+ end
26
+
27
+ def recibo
28
+ @recibo ||= XML.new(xml_do_recibo)
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,86 @@
1
+ module Teodoro
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
14
+
15
+ def processar
16
+ deletar_arquivo_data_original if alteracao? || exclusao?
17
+ return if exclusao?
18
+
19
+ criar_arquivo_data
20
+ end
21
+
22
+ private
23
+
24
+ def alteracao?
25
+ @alteracao ||= evento[noh_principal_do_evento, noh_de_informacoes_do_evento, 'alteracao']
26
+ end
27
+
28
+ def exclusao?
29
+ @exclusao ||= evento[noh_principal_do_evento, noh_de_informacoes_do_evento, 'exclusao']
30
+ end
31
+
32
+ def deletar_arquivo_data_original
33
+ File.delete(obter_caminho_do_arquivo_data(inicio_da_validade_original))
34
+ end
35
+
36
+ def inicio_da_validade_original
37
+ evento[noh_principal_do_evento, noh_de_informacoes_do_evento, '*', noh_de_identificacao_do_periodo, 'iniValid']
38
+ end
39
+
40
+ def obter_caminho_do_arquivo_data(inicio_da_validade)
41
+ File.join(
42
+ destino_dos_arquivos_data,
43
+ "#{nome_base_do_arquivo_data}[#{inicio_da_validade.delete('-')}].data"
44
+ )
45
+ end
46
+
47
+ def nome_base_do_arquivo_data
48
+ @nome_base_do_arquivo_data ||=
49
+ identificacao_do_arquivo_data[0] + identificacao_do_arquivo_data[1..].map { "[#{_1}]" }.join
50
+ end
51
+
52
+ def caminho_do_arquivo_data
53
+ # FIXME: Tales inicio de validade
54
+ obter_caminho_do_arquivo_data(inicio_da_validade)
55
+ end
56
+
57
+ def inicio_da_validade
58
+ @inicio_da_validade ||= validade['iniValid']
59
+ end
60
+
61
+ def validade
62
+ @validade ||=
63
+ if inclusao? || (alteracao? && !nova_validade?)
64
+ evento[noh_principal_do_evento, noh_de_informacoes_do_evento, '*', noh_de_identificacao_do_periodo]
65
+ elsif alteracao?
66
+ nova_validade
67
+ end
68
+ end
69
+
70
+ def inclusao?
71
+ @inclusao ||= evento[noh_principal_do_evento, noh_de_informacoes_do_evento, 'inclusao']
72
+ end
73
+
74
+ def nova_validade?
75
+ nova_validade
76
+ end
77
+
78
+ def nova_validade
79
+ @nova_validade ||= evento[noh_principal_do_evento, noh_de_informacoes_do_evento, 'alteracao', 'novaValidade']
80
+ end
81
+
82
+ def fim_da_validade
83
+ validade['fimValid']
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,58 @@
1
+ module Teodoro
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
17
+
18
+ def processar
19
+ deletar_arquivo_data_original if retificacao?
20
+ registrar_recibo
21
+ criar_arquivo_data
22
+ end
23
+
24
+ private
25
+
26
+ def retificacao?
27
+ evento["#{noh_principal_do_evento}/ideEvento/indRetif"] == '2'
28
+ end
29
+
30
+ def deletar_arquivo_data_original
31
+ File.delete(caminho_do_arquivo_data_original)
32
+ end
33
+
34
+ def caminho_do_arquivo_data_original
35
+ File.join(destino_dos_arquivos_data, "#{nome_do_arquivo_original}.data")
36
+ end
37
+
38
+ def nome_do_arquivo_original
39
+ de_recibo_para_nome_do_arquivo_data[numero_do_recibo_a_retificar]
40
+ end
41
+
42
+ def numero_do_recibo_a_retificar
43
+ @numero_do_recibo_a_retificar ||= evento["#{noh_principal_do_evento}/ideEvento/nrRecibo"]
44
+ end
45
+
46
+ def registrar_recibo
47
+ de_recibo_para_nome_do_arquivo_data[numero_do_recibo] = nome_do_arquivo_data
48
+ end
49
+
50
+ def numero_do_recibo
51
+ recibo['retornoEvento/recibo/nrRecibo']
52
+ end
53
+
54
+ def caminho_do_arquivo_data
55
+ File.join(destino_dos_arquivos_data, "#{nome_do_arquivo_data}.data")
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,28 @@
1
+ module Teodoro
2
+ class ArquivoDeOrigem
3
+ PREFIXO_DE_TOTALIZADOR = '5'.freeze
4
+
5
+ private
6
+
7
+ def initialize(caminho:, destino_dos_arquivos_xml:)
8
+ @caminho = caminho
9
+ @destino_dos_arquivos_xml = destino_dos_arquivos_xml
10
+ end
11
+
12
+ attr_reader :caminho, :destino_dos_arquivos_xml
13
+
14
+ public
15
+
16
+ def descompactar
17
+ puts File.basename(caminho)
18
+
19
+ Zip::File.open(caminho) do |zip|
20
+ zip
21
+ .reject { |entrada| entrada.name[-8] == PREFIXO_DE_TOTALIZADOR }
22
+ .each do |entrada|
23
+ entrada.extract(File.join(destino_dos_arquivos_xml, entrada.name))
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,112 @@
1
+ require_relative 'arquivo_de_evento'
2
+ require_relative 'arquivo_de_evento_de_tabela'
3
+ require_relative 'arquivo_de_evento_nao_periodico'
4
+ require_relative 'cnpj'
5
+ require_relative 'leiaute_2_4_1'
6
+ require_relative 'xml'
7
+
8
+ module Teodoro
9
+ class ArquivoXML
10
+ private
11
+
12
+ def initialize(caminho:, destino_dos_arquivos_data:, de_recibo_para_nome_do_arquivo_data:)
13
+ @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
+ end
17
+
18
+ attr_reader :caminho, :destino_dos_arquivos_data, :de_recibo_para_nome_do_arquivo_data
19
+
20
+ public
21
+
22
+ def nome
23
+ @nome ||= File.basename(caminho, '.xml')
24
+ end
25
+
26
+ def processar
27
+ return unless %w[S1000 S1005 S1010 S1020 S1030 S1040 S1050 S1070 S2190 S2200 S2205 S2206 S2230 S2250 S2300 S2306]
28
+ .include?(tipo_de_evento)
29
+
30
+ arquivo.processar
31
+ end
32
+
33
+ private
34
+
35
+ def tipo_de_evento
36
+ nome[-6..].delete('-')
37
+ end
38
+
39
+ def arquivo
40
+ if evento_de_tabela?
41
+ evento_de_tabela
42
+ elsif evento_nao_periodico?
43
+ evento_nao_periodico
44
+ end
45
+ end
46
+
47
+ def evento_de_tabela?
48
+ tipo_de_evento.start_with?('S10')
49
+ end
50
+
51
+ def evento_de_tabela
52
+ classe_do_arquivo.new(
53
+ xml_do_evento: xml_do_evento,
54
+ xml_do_recibo: xml_do_recibo,
55
+ destino_dos_arquivos_data: destino_dos_arquivos_data
56
+ )
57
+ end
58
+
59
+ def evento_nao_periodico?
60
+ tipo_de_evento.start_with?('S2')
61
+ end
62
+
63
+ def evento_nao_periodico
64
+ classe_do_arquivo.new(
65
+ xml_do_evento: xml_do_evento,
66
+ xml_do_recibo: xml_do_recibo,
67
+ destino_dos_arquivos_data: destino_dos_arquivos_data,
68
+ de_recibo_para_nome_do_arquivo_data: de_recibo_para_nome_do_arquivo_data
69
+ )
70
+ end
71
+
72
+ def classe_do_arquivo
73
+ modulo_do_leiaute.const_get("Arquivo#{tipo_de_evento}")
74
+ end
75
+
76
+ def modulo_do_leiaute
77
+ {
78
+ '02_04_01' => Leiaute_2_4_1,
79
+ '02_04_02' => Leiaute_2_4_1, # FIXME: Tales
80
+ '02_05_00' => Leiaute_2_4_1, # FIXME: Tales
81
+ '01_00_00' => Leiaute_2_4_1 # FIXME: Tales
82
+ }[versao_do_leiaute_no_xml]
83
+ end
84
+
85
+ def versao_do_leiaute_no_xml
86
+ namespace_do_evento.match(%r{.+/v(.+)$})[1]
87
+ end
88
+
89
+ def namespace_do_evento
90
+ xml_do_evento.css('eSocial')[0].namespace.href
91
+ end
92
+
93
+ def xml_do_evento
94
+ @xml_do_evento ||= Nokogiri::XML(xml.css('eSocial/retornoProcessamentoDownload/evento/*').to_s)
95
+ end
96
+
97
+ def xml
98
+ @xml ||= Nokogiri::XML(conteudo)
99
+ end
100
+
101
+ def conteudo
102
+ File.read(caminho)
103
+ end
104
+
105
+ def xml_do_recibo
106
+ Nokogiri::XML(xml.css('eSocial/retornoProcessamentoDownload/recibo/*').to_s)
107
+ end
108
+
109
+ module Base
110
+ end
111
+ end
112
+ end
@@ -0,0 +1,64 @@
1
+ module Teodoro
2
+ class CNPJ
3
+ class Raiz
4
+ private
5
+
6
+ def initialize(string)
7
+ @string = string
8
+ end
9
+
10
+ attr_reader :string
11
+
12
+ public
13
+
14
+ def cnpj0001
15
+ RaizSufixo.new("#{string}0001").cnpj
16
+ end
17
+ end
18
+
19
+ class RaizSufixo
20
+ private
21
+
22
+ def initialize(string)
23
+ @string = string
24
+ end
25
+
26
+ attr_reader :string
27
+
28
+ public
29
+
30
+ def cnpj
31
+ "#{string}#{dv}"
32
+ end
33
+
34
+ def dv
35
+ Numero.new(string).dv.then do |dv|
36
+ dv + Numero.new(string + dv).dv
37
+ end
38
+ end
39
+
40
+ class Numero
41
+ private
42
+
43
+ attr_reader :string
44
+
45
+ def initialize(string)
46
+ @string = string
47
+ end
48
+
49
+ public
50
+
51
+ def dv
52
+ string.chars
53
+ .reverse
54
+ .map(&:to_i)
55
+ .map.with_index { |digito, indice| [digito, indice % 8 + 2] }
56
+ .sum { |digito, peso| digito * peso }
57
+ .then { |r| 11 - r % 11 }
58
+ .then { |r| r >= 10 ? 0 : r }
59
+ .to_s
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,9 @@
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
8
+ end
9
+ end
@@ -0,0 +1,85 @@
1
+ require_relative 'arquivo_de_origem'
2
+ require_relative 'arquivo_xml'
3
+
4
+ module Teodoro
5
+ class Empresa
6
+ private
7
+
8
+ def initialize(caminho:, destino:)
9
+ @caminho = caminho
10
+ @destino = File.join(destino, nome_do_diretorio)
11
+ end
12
+
13
+ attr_reader :caminho, :destino
14
+
15
+ public
16
+
17
+ def processar
18
+ dar_feedback_para_o_usuario
19
+ criar_diretorio_destino
20
+ criar_diretorio_dos_arquivos_xml
21
+ descompactar_arquivos_de_origem
22
+ criar_diretorio_dos_arquivos_data
23
+ processar_arquivos_xml
24
+ end
25
+
26
+ private
27
+
28
+ def dar_feedback_para_o_usuario
29
+ puts ''
30
+ Console.print nome_do_diretorio, color: :green
31
+ end
32
+
33
+ def nome_do_diretorio
34
+ @nome_do_diretorio ||= File.basename(caminho)
35
+ end
36
+
37
+ def criar_diretorio_destino
38
+ Dir.mkdir(destino)
39
+ end
40
+
41
+ def criar_diretorio_dos_arquivos_xml
42
+ Dir.mkdir(destino_dos_arquivos_xml)
43
+ end
44
+
45
+ def destino_dos_arquivos_xml
46
+ @destino_dos_arquivos_xml ||= File.join(destino, 'xmls')
47
+ end
48
+
49
+ def descompactar_arquivos_de_origem
50
+ arquivos_de_origem.each(&:descompactar)
51
+ end
52
+
53
+ def arquivos_de_origem
54
+ Dir[File.join(caminho, '*.zip')]
55
+ .map { |caminho| ArquivoDeOrigem.new(caminho: caminho, destino_dos_arquivos_xml: destino_dos_arquivos_xml) }
56
+ end
57
+
58
+ def criar_diretorio_dos_arquivos_data
59
+ Dir.mkdir(destino_dos_arquivos_data)
60
+ end
61
+
62
+ def destino_dos_arquivos_data
63
+ @destino_dos_arquivos_data ||= File.join(destino, 'data')
64
+ end
65
+
66
+ def processar_arquivos_xml
67
+ arquivos_xml.each(&:processar)
68
+ end
69
+
70
+ 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
79
+ end
80
+
81
+ def de_recibo_para_nome_do_arquivo_data
82
+ @de_recibo_para_nome_do_arquivo_data ||= {}
83
+ end
84
+ end
85
+ end