rps_paulistana 0.1.2 → 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/detail.rb +90 -0
- data/lib/errors/errors.rb +16 -0
- data/lib/footer.rb +19 -0
- data/lib/header.rb +22 -0
- data/lib/register.rb +90 -0
- data/lib/rps.rb +65 -0
- data/lib/rps_field.rb +192 -0
- metadata +8 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7f409e1953d515e209cd2299aadd76739f8548da
|
4
|
+
data.tar.gz: 2a5bf1ba7153b977c2603473d9075eebbd880b5a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c45abce2c25a2f3e48108b5c8fb0d83b3a45cfc9a0ae4cc4741feec2442802554d1c14e4243ea5d69eb5ae22ab77b54b1febedc2dd35b15247d1002df8794a34
|
7
|
+
data.tar.gz: c5a68745ba2074a92d2302775388bfb03ff43db83a94ee0063c2d99dd07e7c9986a3207dea452640044a168fd120628db1d731f3da8dcaa105d919a36f72cb85
|
data/lib/detail.rb
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
module NFE
|
2
|
+
class Detail < Register
|
3
|
+
REQUIRED_FIELDS = [
|
4
|
+
:rps_type,
|
5
|
+
:rps_number,
|
6
|
+
:issuing_date,
|
7
|
+
:rps_status,
|
8
|
+
:amount,
|
9
|
+
:tax_amount,
|
10
|
+
:service_code,
|
11
|
+
:aliquot,
|
12
|
+
:iss_by,
|
13
|
+
:taker_type,
|
14
|
+
:taker_document,
|
15
|
+
:service_description
|
16
|
+
]
|
17
|
+
|
18
|
+
VALID_FIELDS = [
|
19
|
+
:rps_type,
|
20
|
+
:rps_serial,
|
21
|
+
:rps_number,
|
22
|
+
:issuing_date,
|
23
|
+
:rps_status,
|
24
|
+
:amount,
|
25
|
+
:tax_amount,
|
26
|
+
:service_code,
|
27
|
+
:aliquot,
|
28
|
+
:iss_by,
|
29
|
+
:taker_type,
|
30
|
+
:taker_document,
|
31
|
+
:taker_ccm,
|
32
|
+
:state_registration,
|
33
|
+
:taker_name,
|
34
|
+
:address_type,
|
35
|
+
:address,
|
36
|
+
:address_number,
|
37
|
+
:complement,
|
38
|
+
:district,
|
39
|
+
:city,
|
40
|
+
#:uf,
|
41
|
+
:zip_code,
|
42
|
+
:taker_email,
|
43
|
+
:pis_pasep,
|
44
|
+
:cofins,
|
45
|
+
:inss,
|
46
|
+
:ir,
|
47
|
+
:cssl,
|
48
|
+
:total_tax_amount,
|
49
|
+
:tributary_percentage,
|
50
|
+
:tributary_source,
|
51
|
+
:cei,
|
52
|
+
:matriculation,
|
53
|
+
:city_ibge_code,
|
54
|
+
:private_blank_field,
|
55
|
+
:service_description
|
56
|
+
]
|
57
|
+
|
58
|
+
DEFAULTS = {
|
59
|
+
rps_type: "RPS",
|
60
|
+
issuing_date: Time.now.to_date.strftime("%Y%m%d")
|
61
|
+
}
|
62
|
+
|
63
|
+
def initialize
|
64
|
+
super 6
|
65
|
+
end
|
66
|
+
|
67
|
+
def valid?
|
68
|
+
fields_hash = self.to_hash
|
69
|
+
if fields_hash[:taker_type].eql? "2"
|
70
|
+
@required_fields.concat([
|
71
|
+
:taker_name,
|
72
|
+
:taker_email,
|
73
|
+
:address_type,
|
74
|
+
:address,
|
75
|
+
:address_number,
|
76
|
+
:district,
|
77
|
+
:city,
|
78
|
+
#:uf,
|
79
|
+
:zip_code
|
80
|
+
])
|
81
|
+
end
|
82
|
+
|
83
|
+
if ["F", "B", "N", "V"].include?(fields_hash[:rps_status])
|
84
|
+
@required_fields << :city_ibge_code
|
85
|
+
end
|
86
|
+
|
87
|
+
super
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module NFE
|
2
|
+
module Errors
|
3
|
+
class RPSRegisterTypeError < StandardError; end
|
4
|
+
class InvalidParamError < StandardError; end
|
5
|
+
class LayoutVersionError < StandardError; end
|
6
|
+
class RPSTypeError < StandardError; end
|
7
|
+
class RPSStatusError < StandardError; end
|
8
|
+
class ISSByError < StandardError; end
|
9
|
+
class TakerTypeError < StandardError; end
|
10
|
+
class NonExistentFieldError< StandardError; end
|
11
|
+
class InvalidFieldError < StandardError; end
|
12
|
+
class InvalidDetailError < StandardError; end
|
13
|
+
class InvalidHeaderError < StandardError; end
|
14
|
+
class InvalidRPSError < StandardError; end
|
15
|
+
end
|
16
|
+
end
|
data/lib/footer.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
module NFE
|
2
|
+
class Footer < Register
|
3
|
+
REQUIRED_FIELDS = [
|
4
|
+
:total_detail_lines,
|
5
|
+
:total_amount,
|
6
|
+
:total_tax_amount
|
7
|
+
]
|
8
|
+
|
9
|
+
VALID_FIELDS = REQUIRED_FIELDS
|
10
|
+
|
11
|
+
DEFAULTS = {
|
12
|
+
total_detail_lines: "0"
|
13
|
+
}
|
14
|
+
|
15
|
+
def initialize
|
16
|
+
super 9
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/header.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
module NFE
|
2
|
+
class Header < Register
|
3
|
+
REQUIRED_FIELDS = [
|
4
|
+
:layout_version,
|
5
|
+
:municipal_registration,
|
6
|
+
:start_date,
|
7
|
+
:end_date
|
8
|
+
]
|
9
|
+
|
10
|
+
VALID_FIELDS = REQUIRED_FIELDS
|
11
|
+
|
12
|
+
DEFAULTS = {
|
13
|
+
layout_version: "002",
|
14
|
+
start_date: Time.now.to_date.strftime("%Y%m%d"),
|
15
|
+
end_date: Time.now.to_date.strftime("%Y%m%d")
|
16
|
+
}
|
17
|
+
|
18
|
+
def initialize
|
19
|
+
super 1
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/lib/register.rb
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
module NFE
|
2
|
+
class Register
|
3
|
+
VALID_TYPES = [1, 6, 9]
|
4
|
+
REQUIRED_FIELDS = []
|
5
|
+
VALID_FIELDS = []
|
6
|
+
DEFAULTS = {}
|
7
|
+
|
8
|
+
attr_reader :fields, :type, :required_fields
|
9
|
+
|
10
|
+
def validate!
|
11
|
+
if !@type.is_a? String and !@type.is_a? Integer
|
12
|
+
raise Errors::InvalidParamError, /Parameter type must be String or Integer/
|
13
|
+
end
|
14
|
+
|
15
|
+
if !VALID_TYPES.include?(@type.to_i)
|
16
|
+
raise Errors::RPSRegisterTypeError, /Invalid RPS Register type/
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def initialize type
|
21
|
+
@type = type
|
22
|
+
@fields = Array.new
|
23
|
+
@required_fields = Array.new(self.class::REQUIRED_FIELDS)
|
24
|
+
validate!
|
25
|
+
end
|
26
|
+
|
27
|
+
def valid?
|
28
|
+
set_non_filled
|
29
|
+
return (@required_fields - self.to_hash.keys).empty?
|
30
|
+
end
|
31
|
+
|
32
|
+
def valid_register_field? name
|
33
|
+
return (self.class::VALID_FIELDS).include?(name)
|
34
|
+
end
|
35
|
+
|
36
|
+
def << fields
|
37
|
+
raise Errors::InvalidParamError, /Expecting Hash parameter/ if !fields.is_a? Hash
|
38
|
+
fields = self.class::DEFAULTS.merge(fields)
|
39
|
+
|
40
|
+
fields.each do |name, value|
|
41
|
+
if valid_register_field?(name)
|
42
|
+
field = RPSField.new name, value
|
43
|
+
|
44
|
+
if field.valid?
|
45
|
+
field.check_value
|
46
|
+
@fields << field
|
47
|
+
else
|
48
|
+
raise Errors::InvalidFieldError, /The field #{field.name}; Value: #{field.value} is invalid. Check its value/
|
49
|
+
end
|
50
|
+
else
|
51
|
+
raise Errors::NonExistentFieldError, /Register: #{self.class}; Name: #{name}; Value: #{value}/
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
return @fields
|
56
|
+
end
|
57
|
+
|
58
|
+
private def set_non_filled
|
59
|
+
non_filled = (self.class::VALID_FIELDS - @required_fields) - self.to_hash.keys
|
60
|
+
|
61
|
+
non_filled.each do |field_name|
|
62
|
+
field = RPSField.new field_name
|
63
|
+
if field.valid?
|
64
|
+
field.check_value
|
65
|
+
@fields << field
|
66
|
+
else
|
67
|
+
raise Errors::InvalidFieldError, /The field #{field.name}; Value: #{field.value} is invalid. Check its value/
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def to_hash
|
73
|
+
fields_hash = Hash.new
|
74
|
+
@fields.each do |field|
|
75
|
+
fields_hash[field.name] = field.value
|
76
|
+
end
|
77
|
+
|
78
|
+
return fields_hash
|
79
|
+
end
|
80
|
+
|
81
|
+
def to_s
|
82
|
+
string = @type.to_s
|
83
|
+
self.class::VALID_FIELDS.each do |field_name|
|
84
|
+
string += self.to_hash[field_name]
|
85
|
+
end
|
86
|
+
|
87
|
+
return "#{string}\n"
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
data/lib/rps.rb
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
module NFE
|
2
|
+
class RPS
|
3
|
+
attr_reader :header, :details, :footer
|
4
|
+
|
5
|
+
def initialize
|
6
|
+
@header = Header.new
|
7
|
+
@footer = Footer.new
|
8
|
+
@details = Array.new
|
9
|
+
end
|
10
|
+
|
11
|
+
def add_header fields
|
12
|
+
@header << fields
|
13
|
+
raise Errors::InvalidHeaderError, /Invalid Header: #{@header.to_hash}/ if !@header.valid?
|
14
|
+
return @header.fields
|
15
|
+
end
|
16
|
+
|
17
|
+
def add_detail fields
|
18
|
+
detail = Detail.new
|
19
|
+
detail << fields
|
20
|
+
if detail.valid?
|
21
|
+
@details << detail
|
22
|
+
else
|
23
|
+
raise Errors::InvalidDetailError, /Invalid Detail: #{detail.to_hash}/
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def set_footer
|
28
|
+
total_amount = 0
|
29
|
+
total_tax_amount = 0
|
30
|
+
@details.each do |detail|
|
31
|
+
total_amount += detail.to_hash[:amount].to_i
|
32
|
+
total_tax_amount += detail.to_hash[:tax_amount].to_i
|
33
|
+
end
|
34
|
+
|
35
|
+
@footer << {total_detail_lines: @details.count.to_s, total_amount: total_amount.to_s, total_tax_amount: total_tax_amount.to_s}
|
36
|
+
end
|
37
|
+
|
38
|
+
def valid?
|
39
|
+
return (@header.valid? and @details.count and @footer.valid?)
|
40
|
+
end
|
41
|
+
|
42
|
+
def to_s
|
43
|
+
if self.valid?
|
44
|
+
string = @header.to_s
|
45
|
+
@details.each do |detail|
|
46
|
+
string += detail.to_s
|
47
|
+
end
|
48
|
+
string += @footer.to_s
|
49
|
+
|
50
|
+
return string
|
51
|
+
else
|
52
|
+
raise Errors::InvalidRPSError
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def save_to_file path = "./"
|
57
|
+
filename = "#{path}/RPS_#{@details.first.to_hash[:issuing_date]}.txt"
|
58
|
+
file = File.new(filename, "w")
|
59
|
+
saved = file.write(self.to_s)
|
60
|
+
file.close
|
61
|
+
|
62
|
+
return filename if saved
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
data/lib/rps_field.rb
ADDED
@@ -0,0 +1,192 @@
|
|
1
|
+
module NFE
|
2
|
+
class RPSField
|
3
|
+
attr_reader :name, :value, :type, :size, :auto_fill
|
4
|
+
|
5
|
+
module Type
|
6
|
+
ALPHA = "ALPHA"
|
7
|
+
NUM = "NUM"
|
8
|
+
EMAIL = "EMAIL"
|
9
|
+
end
|
10
|
+
|
11
|
+
def validate!
|
12
|
+
raise Errors::InvalidParamError, /Parameter name must be String or Symbol/ if !@name .is_a? String and !@name.is_a? Symbol
|
13
|
+
raise Errors::InvalidParamError, /Parameter value must be String/ if !@value.is_a? String
|
14
|
+
raise Errors::InvalidParamError if @name.empty?
|
15
|
+
end
|
16
|
+
|
17
|
+
def initialize name, value = ""
|
18
|
+
@name = name
|
19
|
+
@value = value
|
20
|
+
@auto_fill = true
|
21
|
+
validate!
|
22
|
+
@name = @name.to_sym
|
23
|
+
@value.upcase!
|
24
|
+
set_configs
|
25
|
+
end
|
26
|
+
|
27
|
+
def set_configs
|
28
|
+
case @name
|
29
|
+
when :taker_email
|
30
|
+
@size = 75
|
31
|
+
@type = Type::EMAIL
|
32
|
+
when :aliquot
|
33
|
+
@size = 4
|
34
|
+
@type = Type::NUM
|
35
|
+
when :total_detail_lines
|
36
|
+
@size = 7
|
37
|
+
@type = Type::NUM
|
38
|
+
when :taker_document
|
39
|
+
@size = 14
|
40
|
+
@type = Type::NUM
|
41
|
+
when :amount, :tax_amount, :total_amount, :total_tax_amount, :pis_pasep, :cofins, :inss, :ir, :cssl
|
42
|
+
@size = 15
|
43
|
+
@type = Type::NUM
|
44
|
+
when :rps_number, :matriculation
|
45
|
+
@size = 12
|
46
|
+
@type = Type::NUM
|
47
|
+
when :taker_ccm
|
48
|
+
@size = 8
|
49
|
+
@type = Type::NUM
|
50
|
+
when :private_blank_field
|
51
|
+
@size = 200
|
52
|
+
@type = Type::ALPHA
|
53
|
+
when :taker_name
|
54
|
+
@size = 75
|
55
|
+
@type = Type::ALPHA
|
56
|
+
when :address_type
|
57
|
+
@size = 3
|
58
|
+
@type = Type::ALPHA
|
59
|
+
when :address, :city
|
60
|
+
@size = 50
|
61
|
+
@type = Type::ALPHA
|
62
|
+
when :address_number, :tributary_source
|
63
|
+
@size = 10
|
64
|
+
@type = Type::ALPHA
|
65
|
+
when :complement, :district
|
66
|
+
@size = 30
|
67
|
+
@type = Type::ALPHA
|
68
|
+
when :service_description
|
69
|
+
@size = @value.length
|
70
|
+
@type = Type::ALPHA
|
71
|
+
when :rps_type, :rps_serial
|
72
|
+
@size = 5
|
73
|
+
@type = Type::ALPHA
|
74
|
+
when :layout_version
|
75
|
+
@size = 3
|
76
|
+
@type = Type::NUM
|
77
|
+
@auto_fill = false
|
78
|
+
when :start_date, :end_date, :issuing_date, :municipal_registration
|
79
|
+
@size = 8
|
80
|
+
@type = Type::NUM
|
81
|
+
@auto_fill = false
|
82
|
+
when :zip_code
|
83
|
+
@size = 8
|
84
|
+
@type = Type::NUM
|
85
|
+
when :state_registration, :cei
|
86
|
+
@size = 12
|
87
|
+
@type = Type::NUM
|
88
|
+
when :service_code
|
89
|
+
@size = 5
|
90
|
+
@type = Type::NUM
|
91
|
+
@auto_fill = false
|
92
|
+
when :tributary_percentage
|
93
|
+
@size = 5
|
94
|
+
@type = Type::NUM
|
95
|
+
when :iss_by, :taker_type
|
96
|
+
@size = 1
|
97
|
+
@type = Type::NUM
|
98
|
+
@auto_fill = false
|
99
|
+
when :city_ibge_code
|
100
|
+
@size = 7
|
101
|
+
@type = Type::NUM
|
102
|
+
when :rps_status
|
103
|
+
@size = 1
|
104
|
+
@type = Type::ALPHA
|
105
|
+
@auto_fill = false
|
106
|
+
when :uf
|
107
|
+
@size = 2
|
108
|
+
@type = Type::ALPHA
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def default_char
|
113
|
+
case @type
|
114
|
+
when Type::NUM
|
115
|
+
return "0"
|
116
|
+
else
|
117
|
+
return " "
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
def valid?
|
122
|
+
if @value.empty?
|
123
|
+
valid = true
|
124
|
+
else
|
125
|
+
case @type
|
126
|
+
when Type::ALPHA
|
127
|
+
valid = self.alphanumeric?
|
128
|
+
when Type::EMAIL
|
129
|
+
valid = self.email?
|
130
|
+
when Type::NUM
|
131
|
+
valid = self.numeric?
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
self.fill! if @auto_fill == true
|
136
|
+
return (valid and self.length == @size)
|
137
|
+
end
|
138
|
+
|
139
|
+
def check_value
|
140
|
+
case @name
|
141
|
+
when :layout_version
|
142
|
+
if !["001", "002"].include? @value
|
143
|
+
raise Errors::LayoutVersionError, /Only 001 and 002 versions supported/
|
144
|
+
end
|
145
|
+
when :rps_type
|
146
|
+
if !@value.strip.eql?("RPS") and !@value.strip.eql?("RPS-M")
|
147
|
+
raise Errors::RPSTypeError, /RPS types allowed: RPS and RPS-M/
|
148
|
+
end
|
149
|
+
when :rps_status
|
150
|
+
if !["T", "F", "A", "B", "M", "N", "X", "V", "P", "C"].include? @value
|
151
|
+
raise Errors::RPSStatusError, /Invalid RPS situation\/status. Please, check the manual (section 4.3.6)/
|
152
|
+
end
|
153
|
+
when :iss_by
|
154
|
+
if !["1", "2", "3"].include? @value
|
155
|
+
raise Errors::ISSByError, /Invalid ISS. Please, check the manual (section 4.3.11)/
|
156
|
+
end
|
157
|
+
when :taker_type
|
158
|
+
if !["1", "2", "3"].include? @value
|
159
|
+
raise Errors::TakerTypeError, /Invalid Taker type. Please, check the manual (section 4.3.12)/
|
160
|
+
end
|
161
|
+
when :start_date, :end_date, :issuing_date
|
162
|
+
Date.strptime(@value, "%Y%m%d")
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
def alphanumeric?
|
167
|
+
return @value.match(/^[[:alnum:]\s]+$/) != nil
|
168
|
+
end
|
169
|
+
|
170
|
+
def numeric?
|
171
|
+
return @value.match(/^[0-9]+$/) != nil
|
172
|
+
end
|
173
|
+
|
174
|
+
def email?
|
175
|
+
return @value.match(/\A[\w+\-.]+@[a-z\d\-]+(\.[a-z]+)*\.[a-z]+\z/i) != nil
|
176
|
+
end
|
177
|
+
|
178
|
+
def length
|
179
|
+
return @value.length
|
180
|
+
end
|
181
|
+
|
182
|
+
def fill!
|
183
|
+
while self.length < @size do
|
184
|
+
if self.default_char.eql? "0"
|
185
|
+
@value = self.default_char + @value
|
186
|
+
else
|
187
|
+
@value << self.default_char
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rps_paulistana
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Júlia M. Birkett
|
@@ -32,6 +32,13 @@ executables: []
|
|
32
32
|
extensions: []
|
33
33
|
extra_rdoc_files: []
|
34
34
|
files:
|
35
|
+
- lib/detail.rb
|
36
|
+
- lib/errors/errors.rb
|
37
|
+
- lib/footer.rb
|
38
|
+
- lib/header.rb
|
39
|
+
- lib/register.rb
|
40
|
+
- lib/rps.rb
|
41
|
+
- lib/rps_field.rb
|
35
42
|
- lib/rps_paulistana.rb
|
36
43
|
homepage: http://rubygems.org/gems/rps_paulistana
|
37
44
|
licenses: []
|