afd_parser 0.2.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 +7 -0
- data/lib/afd_parser.rb +257 -0
- data/lib/afd_parser/clock_in_out.rb +71 -0
- data/lib/afd_parser/header.rb +144 -0
- data/lib/afd_parser/record_parser.rb +65 -0
- data/lib/afd_parser/set_employee.rb +98 -0
- data/lib/afd_parser/set_employer.rb +109 -0
- data/lib/afd_parser/set_time.rb +77 -0
- data/lib/afd_parser/trailer.rb +83 -0
- data/lib/afd_parser/version.rb +3 -0
- data/test/afd_file +11 -0
- data/test/afd_invalid_utf-8_chars +2 -0
- data/test/afd_parser_test.rb +633 -0
- data/test/clock_in_out_test.rb +32 -0
- data/test/header_test.rb +52 -0
- data/test/set_employee_test.rb +67 -0
- data/test/set_employer_test.rb +29 -0
- data/test/set_time_test.rb +23 -0
- data/test/test_helper.rb +25 -0
- data/test/trailer_test.rb +26 -0
- metadata +85 -0
@@ -0,0 +1,65 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
# Controle de Horas - Sistema para gestão de horas trabalhadas
|
3
|
+
# Copyright (C) 2009 O.S. Systems Softwares Ltda.
|
4
|
+
|
5
|
+
# This program is free software: you can redistribute it and/or modify
|
6
|
+
# it under the terms of the GNU Affero General Public License as
|
7
|
+
# published by the Free Software Foundation, either version 3 of the
|
8
|
+
# License, or (at your option) any later version.
|
9
|
+
|
10
|
+
# This program is distributed in the hope that it will be useful,
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
# GNU Affero General Public License for more details.
|
14
|
+
|
15
|
+
# You should have received a copy of the GNU Affero General Public License
|
16
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
17
|
+
|
18
|
+
# Rua Clóvis Gularte Candiota 132, Pelotas-RS, Brasil.
|
19
|
+
# e-mail: contato@ossystems.com.br
|
20
|
+
|
21
|
+
class AfdParser::RecordParser
|
22
|
+
def self.size
|
23
|
+
raise "record size not defined for parser class '#{self.class.to_s}'"
|
24
|
+
end
|
25
|
+
|
26
|
+
def export
|
27
|
+
raise "record export is not defined for parser class '#{self.class.to_s}'"
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
def parse_date(date_array)
|
32
|
+
day = date_array[0..1].to_i
|
33
|
+
month = date_array[2..3].to_i
|
34
|
+
year = date_array[4..7].to_i
|
35
|
+
Date.civil(year,month,day)
|
36
|
+
end
|
37
|
+
|
38
|
+
def parse_time(date_array)
|
39
|
+
day = date_array[0..1].to_i
|
40
|
+
month = date_array[2..3].to_i
|
41
|
+
year = date_array[4..7].to_i
|
42
|
+
hour = date_array[8..9].to_i
|
43
|
+
minute = date_array[10..11].to_i
|
44
|
+
Time.local(year,month,day,hour,minute)
|
45
|
+
end
|
46
|
+
|
47
|
+
def format_date(date)
|
48
|
+
date.class == Date ? date.strftime("%d%m%Y") : date.to_s
|
49
|
+
end
|
50
|
+
|
51
|
+
def format_time(time)
|
52
|
+
time.class == Time ? time.strftime("%d%m%Y%H%M") : time.to_s
|
53
|
+
end
|
54
|
+
|
55
|
+
def well_formed_number_string?(string)
|
56
|
+
string.to_i.to_s.rjust(string.size, "0") == string
|
57
|
+
end
|
58
|
+
|
59
|
+
# Destructively removes invalid utf-8 chars from strings. Ignores data from
|
60
|
+
# other classes.
|
61
|
+
def _clean!(string)
|
62
|
+
return string unless string.class == String
|
63
|
+
string.force_encoding('ISO-8859-1').encode('UTF-8', {:invalid => :replace, :replace => ""})
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
# Controle de Horas - Sistema para gestão de horas trabalhadas
|
3
|
+
# Copyright (C) 2009 O.S. Systems Softwares Ltda.
|
4
|
+
|
5
|
+
# This program is free software: you can redistribute it and/or modify
|
6
|
+
# it under the terms of the GNU Affero General Public License as
|
7
|
+
# published by the Free Software Foundation, either version 3 of the
|
8
|
+
# License, or (at your option) any later version.
|
9
|
+
|
10
|
+
# This program is distributed in the hope that it will be useful,
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
# GNU Affero General Public License for more details.
|
14
|
+
|
15
|
+
# You should have received a copy of the GNU Affero General Public License
|
16
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
17
|
+
|
18
|
+
# Rua Clóvis Gularte Candiota 132, Pelotas-RS, Brasil.
|
19
|
+
# e-mail: contato@ossystems.com.br
|
20
|
+
|
21
|
+
require 'afd_parser/record_parser'
|
22
|
+
|
23
|
+
class AfdParser::SetEmployee < AfdParser::RecordParser
|
24
|
+
attr_reader :line_id, :record_type_id, :creation_time, :operation_type,
|
25
|
+
:pis, :name
|
26
|
+
|
27
|
+
OPERATION_TYPE = {"I" => :add, "A" => :edit, "E" => :remove}
|
28
|
+
|
29
|
+
def initialize(line)
|
30
|
+
self.line_id, self.record_type_id, self.creation_time,
|
31
|
+
self.operation_type =
|
32
|
+
line.unpack("A9AA12A").collect{|str| _clean!(str)}
|
33
|
+
self.pis, self.name = line[23..-1].match(/\A(\d{1,12})(.{1,52})/)[1..2].collect{|str| _clean!(str)}
|
34
|
+
end
|
35
|
+
|
36
|
+
def export
|
37
|
+
line_export = ""
|
38
|
+
line_export += @line_id.to_s.rjust(9,"0")
|
39
|
+
line_export += @record_type_id.to_s
|
40
|
+
line_export += format_time(@creation_time)
|
41
|
+
line_export += get_operation_letter(@operation_type).to_s
|
42
|
+
line_export += @pis.to_s.rjust(12,"0")
|
43
|
+
line_export += @name.ljust(52, " ")
|
44
|
+
line_export
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.size
|
48
|
+
87
|
49
|
+
end
|
50
|
+
|
51
|
+
def ==(other)
|
52
|
+
return self.class == other.class && [:line_id, :record_type_id, :creation_time, :operation_type, :pis, :name].all? do |reader|
|
53
|
+
self.send(reader) == other.send(reader)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
def line_id=(data)
|
59
|
+
@line_id = well_formed_number_string?(data) ? data.to_i : data
|
60
|
+
end
|
61
|
+
|
62
|
+
def record_type_id=(data)
|
63
|
+
@record_type_id = well_formed_number_string?(data) ? data.to_i : data
|
64
|
+
end
|
65
|
+
|
66
|
+
def pis=(data)
|
67
|
+
@pis = well_formed_number_string?(data) ? data.to_i : data
|
68
|
+
end
|
69
|
+
|
70
|
+
def operation_type=(data)
|
71
|
+
@operation_type = get_operation_type(data)
|
72
|
+
end
|
73
|
+
|
74
|
+
def name=(data)
|
75
|
+
@name = data.rstrip
|
76
|
+
end
|
77
|
+
|
78
|
+
def creation_time=(raw_time)
|
79
|
+
begin
|
80
|
+
parsed_time = parse_time(raw_time)
|
81
|
+
@creation_time = parsed_time
|
82
|
+
rescue
|
83
|
+
@creation_time = ""
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def get_operation_type(operation_type_letter)
|
88
|
+
type = OPERATION_TYPE[operation_type_letter]
|
89
|
+
if type.nil?
|
90
|
+
raise AfdParser::AfdParserException.new("Unknown employee operation type letter '#{operation_type_letter}' found in line #{@line_id.to_s}")
|
91
|
+
end
|
92
|
+
type
|
93
|
+
end
|
94
|
+
|
95
|
+
def get_operation_letter(operation_type)
|
96
|
+
OPERATION_TYPE.invert[operation_type]
|
97
|
+
end
|
98
|
+
end
|
@@ -0,0 +1,109 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
# Controle de Horas - Sistema para gestão de horas trabalhadas
|
3
|
+
# Copyright (C) 2009 O.S. Systems Softwares Ltda.
|
4
|
+
|
5
|
+
# This program is free software: you can redistribute it and/or modify
|
6
|
+
# it under the terms of the GNU Affero General Public License as
|
7
|
+
# published by the Free Software Foundation, either version 3 of the
|
8
|
+
# License, or (at your option) any later version.
|
9
|
+
|
10
|
+
# This program is distributed in the hope that it will be useful,
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
# GNU Affero General Public License for more details.
|
14
|
+
|
15
|
+
# You should have received a copy of the GNU Affero General Public License
|
16
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
17
|
+
|
18
|
+
# Rua Clóvis Gularte Candiota 132, Pelotas-RS, Brasil.
|
19
|
+
# e-mail: contato@ossystems.com.br
|
20
|
+
|
21
|
+
require 'afd_parser/record_parser'
|
22
|
+
|
23
|
+
class AfdParser::SetEmployer < AfdParser::RecordParser
|
24
|
+
attr_accessor :line_id, :record_type_id, :creation_time, :document_type,
|
25
|
+
:document_number, :cei, :name, :location
|
26
|
+
|
27
|
+
DOCUMENT_TYPES = {1 => :cnpj, 2 => :cpf}
|
28
|
+
|
29
|
+
def initialize(line)
|
30
|
+
self.line_id, self.record_type_id, self.creation_time,
|
31
|
+
self.document_type, self.document_number, self.cei, self.name,
|
32
|
+
self.location = line.unpack("A9AA12AA14A12A150A100").collect do |str|
|
33
|
+
_clean!(str)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def export
|
38
|
+
line_export = ""
|
39
|
+
line_export += @line_id.to_s.rjust(9,"0")
|
40
|
+
line_export += @record_type_id.to_s
|
41
|
+
line_export += format_time(@creation_time)
|
42
|
+
line_export += get_document_type_number(@document_type).to_s
|
43
|
+
line_export += @document_number.to_s.rjust(14, "0")
|
44
|
+
line_export += @cei.to_s.rjust(12, "0")
|
45
|
+
line_export += @name.ljust(150, " ")
|
46
|
+
line_export += @location.ljust(100, " ")
|
47
|
+
line_export
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.size
|
51
|
+
299
|
52
|
+
end
|
53
|
+
|
54
|
+
def ==(other)
|
55
|
+
return self.class == other.class && [:line_id, :record_type_id, :creation_time, :document_type, :document_number, :cei, :name, :location].all? do |reader|
|
56
|
+
self.send(reader) == other.send(reader)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
def line_id=(data)
|
62
|
+
@line_id = well_formed_number_string?(data) ? data.to_i : data
|
63
|
+
end
|
64
|
+
|
65
|
+
def record_type_id=(data)
|
66
|
+
@record_type_id = well_formed_number_string?(data) ? data.to_i : data
|
67
|
+
end
|
68
|
+
|
69
|
+
def document_type=(data)
|
70
|
+
@document_type = get_document_type(data.to_i)
|
71
|
+
end
|
72
|
+
|
73
|
+
def document_number=(data)
|
74
|
+
@document_number = well_formed_number_string?(data) ? data.to_i : data
|
75
|
+
end
|
76
|
+
|
77
|
+
def cei=(data)
|
78
|
+
@cei = well_formed_number_string?(data) ? data.to_i : data
|
79
|
+
end
|
80
|
+
|
81
|
+
def name=(data)
|
82
|
+
@name = data.rstrip
|
83
|
+
end
|
84
|
+
|
85
|
+
def location=(data)
|
86
|
+
@location = data.rstrip
|
87
|
+
end
|
88
|
+
|
89
|
+
def creation_time=(raw_time)
|
90
|
+
begin
|
91
|
+
parsed_time = parse_time(raw_time)
|
92
|
+
@creation_time = parsed_time
|
93
|
+
rescue
|
94
|
+
@creation_time = ""
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def get_document_type(document_type_id)
|
99
|
+
type = DOCUMENT_TYPES[document_type_id]
|
100
|
+
if type.nil?
|
101
|
+
raise AfdParser::AfdParserException.new("Unknown employer type id '#{document_type_id.to_s}' found in set employer record on line #{@line_id.to_s}")
|
102
|
+
end
|
103
|
+
type
|
104
|
+
end
|
105
|
+
|
106
|
+
def get_document_type_number(document_type_id)
|
107
|
+
DOCUMENT_TYPES.invert[document_type_id]
|
108
|
+
end
|
109
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
# Controle de Horas - Sistema para gestão de horas trabalhadas
|
3
|
+
# Copyright (C) 2009 O.S. Systems Softwares Ltda.
|
4
|
+
|
5
|
+
# This program is free software: you can redistribute it and/or modify
|
6
|
+
# it under the terms of the GNU Affero General Public License as
|
7
|
+
# published by the Free Software Foundation, either version 3 of the
|
8
|
+
# License, or (at your option) any later version.
|
9
|
+
|
10
|
+
# This program is distributed in the hope that it will be useful,
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
# GNU Affero General Public License for more details.
|
14
|
+
|
15
|
+
# You should have received a copy of the GNU Affero General Public License
|
16
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
17
|
+
|
18
|
+
# Rua Clóvis Gularte Candiota 132, Pelotas-RS, Brasil.
|
19
|
+
# e-mail: contato@ossystems.com.br
|
20
|
+
|
21
|
+
require 'afd_parser/record_parser'
|
22
|
+
|
23
|
+
class AfdParser::SetTime < AfdParser::RecordParser
|
24
|
+
attr_reader :line_id, :record_type_id, :before_time, :after_time
|
25
|
+
alias :creation_time :before_time
|
26
|
+
|
27
|
+
def initialize(line)
|
28
|
+
self.line_id, self.record_type_id, self.before_time,
|
29
|
+
self.after_time = line.unpack("A9AA12A12").collect{|str| _clean!(str)}
|
30
|
+
end
|
31
|
+
|
32
|
+
def export
|
33
|
+
line_export = ""
|
34
|
+
line_export += @line_id.to_s.rjust(9,"0")
|
35
|
+
line_export += @record_type_id.to_s
|
36
|
+
line_export += format_time(@before_time)
|
37
|
+
line_export += format_time(@after_time)
|
38
|
+
line_export
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.size
|
42
|
+
34
|
43
|
+
end
|
44
|
+
|
45
|
+
def ==(other)
|
46
|
+
return self.class == other.class && [:line_id, :record_type_id, :before_time, :after_time].all? do |reader|
|
47
|
+
self.send(reader) == other.send(reader)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
def line_id=(data)
|
53
|
+
@line_id = well_formed_number_string?(data) ? data.to_i : data
|
54
|
+
end
|
55
|
+
|
56
|
+
def record_type_id=(data)
|
57
|
+
@record_type_id = well_formed_number_string?(data) ? data.to_i : data
|
58
|
+
end
|
59
|
+
|
60
|
+
def before_time=(raw_time)
|
61
|
+
begin
|
62
|
+
parsed_time = parse_time(raw_time)
|
63
|
+
@before_time = parsed_time
|
64
|
+
rescue
|
65
|
+
@before_time = ""
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def after_time=(raw_time)
|
70
|
+
begin
|
71
|
+
parsed_time = parse_time(raw_time)
|
72
|
+
@after_time = parsed_time
|
73
|
+
rescue
|
74
|
+
@after_time = ""
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
# Controle de Horas - Sistema para gestão de horas trabalhadas
|
3
|
+
# Copyright (C) 2009 O.S. Systems Softwares Ltda.
|
4
|
+
|
5
|
+
# This program is free software: you can redistribute it and/or modify
|
6
|
+
# it under the terms of the GNU Affero General Public License as
|
7
|
+
# published by the Free Software Foundation, either version 3 of the
|
8
|
+
# License, or (at your option) any later version.
|
9
|
+
|
10
|
+
# This program is distributed in the hope that it will be useful,
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
# GNU Affero General Public License for more details.
|
14
|
+
|
15
|
+
# You should have received a copy of the GNU Affero General Public License
|
16
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
17
|
+
|
18
|
+
# Rua Clóvis Gularte Candiota 132, Pelotas-RS, Brasil.
|
19
|
+
# e-mail: contato@ossystems.com.br
|
20
|
+
|
21
|
+
require 'afd_parser/record_parser'
|
22
|
+
|
23
|
+
class AfdParser::Trailer < AfdParser::RecordParser
|
24
|
+
attr_reader :line_id, :set_employer, :clock_in_out, :set_time, :set_employee, :record_type_id
|
25
|
+
|
26
|
+
def initialize(*args)
|
27
|
+
if args.size == 1
|
28
|
+
counter = args[0]
|
29
|
+
@line_id = 999999999
|
30
|
+
@set_employer = counter[:set_employer]
|
31
|
+
@clock_in_out = counter[:clock_in_out]
|
32
|
+
@set_time = counter[:set_time]
|
33
|
+
@set_employee = counter[:set_employee]
|
34
|
+
@record_type_id = 9
|
35
|
+
|
36
|
+
elsif args.size == 2
|
37
|
+
line = args[0]
|
38
|
+
counter = args[1]
|
39
|
+
|
40
|
+
line_id, set_employer, clock_in_out, set_time, set_employee,
|
41
|
+
record_type_id = line.unpack("A9A9A9A9A9A").collect{|str| _clean!(str)}
|
42
|
+
|
43
|
+
@line_id = line_id.to_i
|
44
|
+
@set_employer = set_employer.to_i
|
45
|
+
@clock_in_out = clock_in_out.to_i
|
46
|
+
@set_time = set_time.to_i
|
47
|
+
@set_employee = set_employee.to_i
|
48
|
+
@record_type_id = record_type_id.to_i
|
49
|
+
|
50
|
+
["set_employer", "clock_in_out", "set_time", "set_employee"].each do |key|
|
51
|
+
value = eval("@"+key)
|
52
|
+
if value != counter[key.to_sym]
|
53
|
+
raise AfdParser::AfdParserException.new("Mismatch counting changes of #{key} in REP!\n" +
|
54
|
+
"REP: #{value.to_s} | System: #{counter[key.to_sym].to_s}")
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
else
|
59
|
+
raise AfdParser::AfdParserException.new("wrong number of arguments for trailer object, should be 1 or 2")
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def export
|
64
|
+
line_export = ""
|
65
|
+
line_export += @line_id.to_s.rjust(9,"0")
|
66
|
+
line_export += @set_employer.to_s.rjust(9,"0")
|
67
|
+
line_export += @clock_in_out.to_s.rjust(9,"0")
|
68
|
+
line_export += @set_time.to_s.rjust(9,"0")
|
69
|
+
line_export += @set_employee.to_s.rjust(9,"0")
|
70
|
+
line_export += @record_type_id.to_s
|
71
|
+
line_export
|
72
|
+
end
|
73
|
+
|
74
|
+
def self.time
|
75
|
+
46
|
76
|
+
end
|
77
|
+
|
78
|
+
def ==(other)
|
79
|
+
return self.class == other.class && [:line_id, :set_employer, :clock_in_out, :set_time, :set_employee, :record_type_id].all? do |reader|
|
80
|
+
self.send(reader) == other.send(reader)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
data/test/afd_file
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
0000000001100000000067890000000009876RAZAO_SOCIAL 000040000700044032001201122022011210220111048
|
2
|
+
0000000014280120111112280120111113
|
3
|
+
0000000022270120111756108682040000172000000000000O.S. SYSTEMS SOFTWARES LTDA. PELOTAS - RS
|
4
|
+
0000000035270120111759I111111111111TESTE 1 2 3
|
5
|
+
0000000045080220111709I222222222222TESTE 2
|
6
|
+
0000000055110220111719A222222222222TESTE 2
|
7
|
+
0000000065110220111723E222222222222TESTE 2
|
8
|
+
0000000073190220111814111111111111
|
9
|
+
0000000083210220111133111111111111
|
10
|
+
0000000093210220111134111111111111
|
11
|
+
9999999990000000010000000030000000010000000049
|