rps_paulistana 0.1.2 → 0.1.3
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 +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: []
|