fiscalizer 0.0.12 → 1.0.0

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 (63) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -1
  3. data/.rspec +2 -0
  4. data/Gemfile +0 -4
  5. data/LICENSE.txt +1 -1
  6. data/README.md +187 -171
  7. data/bin/console +14 -0
  8. data/bin/setup +7 -0
  9. data/doc/Tehnicka specifikacija za korisnike 1.4.pdf +0 -0
  10. data/fiscalizer.gemspec +14 -13
  11. data/lib/fiscalizer.rb +33 -4
  12. data/lib/fiscalizer/constants.rb +11 -0
  13. data/lib/fiscalizer/data_objects/echo.rb +10 -0
  14. data/lib/fiscalizer/data_objects/fee.rb +18 -0
  15. data/lib/fiscalizer/data_objects/invoice.rb +79 -0
  16. data/lib/fiscalizer/data_objects/office.rb +41 -0
  17. data/lib/fiscalizer/{tax.rb → data_objects/tax.rb} +3 -5
  18. data/lib/fiscalizer/deserializers/base.rb +58 -0
  19. data/lib/fiscalizer/deserializers/echo.rb +13 -0
  20. data/lib/fiscalizer/deserializers/invoice.rb +9 -0
  21. data/lib/fiscalizer/deserializers/office.rb +6 -0
  22. data/lib/fiscalizer/fiscalizer.rb +36 -152
  23. data/lib/fiscalizer/fiscalizers/base.rb +54 -0
  24. data/lib/fiscalizer/fiscalizers/echo.rb +13 -0
  25. data/lib/fiscalizer/fiscalizers/invoice.rb +24 -0
  26. data/lib/fiscalizer/fiscalizers/office.rb +15 -0
  27. data/lib/fiscalizer/serializers/base.rb +58 -0
  28. data/lib/fiscalizer/serializers/echo.rb +21 -0
  29. data/lib/fiscalizer/serializers/invoice.rb +92 -0
  30. data/lib/fiscalizer/serializers/office.rb +85 -0
  31. data/lib/fiscalizer/serializers/signature.rb +62 -0
  32. data/lib/fiscalizer/serializers/tax.rb +81 -0
  33. data/lib/fiscalizer/services/request_sender.rb +68 -0
  34. data/lib/fiscalizer/services/security_code_generator.rb +29 -0
  35. data/lib/fiscalizer/version.rb +1 -1
  36. data/spec/fiscalizer_spec.rb +119 -0
  37. data/spec/spec_helper.rb +9 -0
  38. metadata +67 -39
  39. data/doc/README.md +0 -3
  40. data/doc/Tehnicka_specifikacija_za_korisnike_1.2.pdf +0 -0
  41. data/example/README.md +0 -25
  42. data/example/echo_P12.rb +0 -13
  43. data/example/echo_public_and_private_keys.rb +0 -16
  44. data/example/invoice_fiscalization_passing_arguments.rb +0 -44
  45. data/example/invoice_fiscalization_passing_object.rb +0 -48
  46. data/example/office_fiscalization_passing_arguments.rb +0 -22
  47. data/example/office_fiscalization_passing_object.rb +0 -26
  48. data/lib/README.md +0 -0
  49. data/lib/fiscalizer/README.md +0 -9
  50. data/lib/fiscalizer/communication.rb +0 -305
  51. data/lib/fiscalizer/echo.rb +0 -11
  52. data/lib/fiscalizer/fee.rb +0 -20
  53. data/lib/fiscalizer/invoice.rb +0 -190
  54. data/lib/fiscalizer/office.rb +0 -66
  55. data/lib/fiscalizer/response.rb +0 -124
  56. data/test/README.md +0 -13
  57. data/test/test_echo.rb +0 -20
  58. data/test/test_fee +0 -64
  59. data/test/test_fiscalizer.rb +0 -222
  60. data/test/test_fiscalizer_communication.rb +0 -28
  61. data/test/test_invoice.rb +0 -11
  62. data/test/test_office.rb +0 -11
  63. data/test/test_tax.rb +0 -89
@@ -1,11 +0,0 @@
1
- class Fiscalizer
2
- class Echo
3
-
4
- attr_accessor :text, :generated_xml
5
-
6
- def initialize text: "Hello World!"
7
- @text = text
8
- end # initialize
9
-
10
- end # Echo
11
- end # Fiscalizer
@@ -1,20 +0,0 @@
1
- class Fiscalizer
2
- class Fee
3
-
4
- attr_accessor :name, :value
5
-
6
- def initialize name: "", value: 0.0
7
- @name = name
8
- @value = value
9
- end # initialize
10
-
11
- def value
12
- return @value.to_f.round(2)
13
- end # value
14
-
15
- def value_str
16
- return ("%15.2f" % value).strip
17
- end # value_str
18
-
19
- end # Fee
20
- end # Fiscalizer
@@ -1,190 +0,0 @@
1
- require 'fiscalizer/tax'
2
- require 'fiscalizer/fee'
3
-
4
- class Fiscalizer
5
- class Invoice
6
-
7
- attr_accessor :uuid, :time_sent, :pin,
8
- :in_vat_system, :time_issued, :consistance_mark,
9
- :issued_number, :issued_office, :issued_machine,
10
- :tax_vat, :tax_spending, :tax_other,
11
- :value_tax_liberation, :value_tax_margin, :value_non_taxable,
12
- :fees, :summed_total, :payment_method,
13
- :operator_pin, :security_code, :subsequent_delivery,
14
- :paragon_label, :specific_purpose, :unique_identifier,
15
- :automatic, :generated_xml
16
-
17
- def initialize( uuid: nil, time_sent: nil, pin: nil,
18
- in_vat_system: nil, time_issued: nil, consistance_mark: nil,
19
- issued_number: nil, issued_office: nil, issued_machine: nil,
20
- tax_vat: [], tax_spending: [], tax_other: [],
21
- value_tax_liberation: nil, value_tax_margin: nil, value_non_taxable: nil,
22
- fees: [], summed_total: nil, payment_method: nil,
23
- operator_pin: nil, security_code: nil, subsequent_delivery: nil,
24
- paragon_label: nil, specific_purpose: nil, unique_identifier: nil,
25
- automatic: true)
26
- @uuid = uuid
27
- @time_sent = time_sent
28
- @pin = pin
29
- @in_vat_system = in_vat_system
30
- @time_issued = time_issued
31
- @consistance_mark = consistance_mark
32
- @issued_number = issued_number
33
- @issued_office = issued_office
34
- @issued_machine = issued_machine
35
- @tax_vat = tax_vat
36
- @tax_spending = tax_spending
37
- @tax_other = tax_other
38
- @value_tax_liberation = value_tax_liberation
39
- @value_tax_margin = value_tax_margin
40
- @value_non_taxable = value_non_taxable
41
- @fees = fees
42
- @summed_total = summed_total
43
- @payment_method = payment_method
44
- @operator_pin = operator_pin
45
- @security_code = security_code
46
- @subsequent_delivery = subsequent_delivery
47
- @paragon_label = paragon_label
48
- @specific_purpose = specific_purpose
49
- @unique_identifier = unique_identifier
50
- @automatic = automatic
51
-
52
- autocomplete_data_set if @automatic
53
- end # initialize
54
-
55
- # Add taxes
56
- def add_tax_vat tax=nil, base: 0.0, rate: 0.0, name: ""
57
- tax = Fiscalizer::Tax.new base: base, rate: rate, name: name if tax == nil
58
- @tax_vat = Array.new if @tax_vat.class != Array
59
- @tax_vat << tax
60
- end # add_tax_vat
61
-
62
- def add_tax_spending tax=nil, base: 0.0, rate: 0.0, name: ""
63
- tax = Fiscalizer::Tax.new base: base, rate: rate, name: name if tax == nil
64
- @tax_spending = Array.new if @tax_spending.class != Array
65
- @tax_spending << tax
66
- end # add_tax_spending
67
-
68
- def add_tax_other tax=nil, base: 0.0, rate: 0.0, name: ""
69
- tax = Fiscalizer::Tax.new base: base, rate: rate, name: name if tax == nil
70
- @tax_other = Array.new if @tax_other.class != Array
71
- @tax_other << tax
72
- end # add_tax_spending
73
-
74
- # Add fees
75
- def add_fee fee=nil, name: "", value: 0.0
76
- fee = Fiscalizer::Fee.new name: base, value: rate if fee == nil
77
- @fee << fee
78
- end # add_fee
79
-
80
- # Check if all necessary values are present
81
- def is_valid
82
- # Check values
83
- return false if @uuid == nil
84
- return false if @time_sent == nil
85
- return false if @pin == nil
86
- return false if @in_vat_system == nil
87
- return false if @time_issued == nil
88
- return false if @consistance_mark == nil
89
- return false if @issued_number == nil
90
- return false if @issued_office == nil
91
- return false if @issued_machine == nil
92
- return false if summed_total == nil
93
- return false if @payment_method == nil
94
- return false if @operator_pin == nil
95
- return false if @security_code == nil
96
- return false if @subsequent_delivery == nil
97
-
98
- # Check taxes
99
- tax_vat.each do |tax|
100
- return false if tax.name == nil || tax.name.class != String
101
- return false if tax.base == nil
102
- return false if tax.rate == nil
103
- end # tax_vat.each
104
-
105
- tax_spending.each do |tax|
106
- return false if tax.name == nil || tax.name.class != String
107
- return false if tax.base == nil
108
- return false if tax.rate == nil
109
- end # tax_spending.each
110
-
111
- tax_other.each do |tax|
112
- return false if tax.name == nil || tax.name.class != String
113
- return false if tax.base == nil
114
- return false if tax.rate == nil
115
- end # tax_other.each
116
-
117
- # Check fees
118
- fees.each do |fee|
119
- return false if fee.name == nil || fee.name.class != String
120
- return false if fee.value == nil || fee.value.class != Float
121
- end # fees.each
122
-
123
- return true
124
- end # is_valid
125
- alias_method :valid?, :is_valid
126
- alias_method :valdate, :is_valid
127
-
128
- # Getters
129
- def time_issued_str separator="T"
130
- return @time_issued.strftime('%d.%m.%Y') + separator + @time_issued.strftime('%H:%M:%S')
131
- end # time_issued_str
132
-
133
- def time_sent_str separator="T"
134
- return @time_sent.strftime('%d.%m.%Y') + separator + @time_sent.strftime('%H:%M:%S')
135
- end # time_sent_str
136
-
137
- def summed_total
138
- return @summed_total if @summed_total != nil
139
- total = 0.0
140
- tax_vat.each do |tax|
141
- total += tax.summed
142
- end
143
- tax_spending.each do |tax|
144
- total += tax.summed
145
- end
146
- tax_other.each do |tax|
147
- total += tax.summed
148
- end
149
- return total.round(2)
150
- end # summed_total
151
-
152
- def summed_total_str
153
- return ("%15.2f" % summed_total).strip
154
- end # summed_total_str
155
-
156
- def payment_method
157
- return "G" if @payment_method[0].downcase == "g"
158
- return "K" if @payment_method[0].downcase == "k"
159
- return "C" if @payment_method[0].downcase == "c"
160
- return "T" if @payment_method[0].downcase == "t"
161
- return "O" if @payment_method[0].downcase == "o"
162
- raise "Invalid payment method type!"
163
- end # payment_method
164
-
165
- def consistance_mark
166
- return @consistance_mark.upcase
167
- end # consistance_mark
168
-
169
- def value_tax_liberation_str
170
- return nil if @value_tax_liberation == nil
171
- return ("%15.2f" % @value_tax_liberation.round(2)).strip
172
- end # value_tax_liberation_str
173
-
174
- def value_tax_margin_str
175
- return nil if @value_tax_margin == nil
176
- return ("%15.2f" % @value_tax_margin.round(2)).strip
177
- end # value_tax_margin_str
178
-
179
- def value_non_taxable_str
180
- return nil if @value_non_taxable == nil
181
- return ("%15.2f" % @value_non_taxable.round(2)).strip
182
- end # value_non_taxable_str
183
-
184
-
185
- # Helpers
186
- def autocomplete_data_set
187
- end # autocomplete_data_set
188
-
189
- end # Invoice
190
- end # Fiscalizer
@@ -1,66 +0,0 @@
1
- class Fiscalizer
2
- class Office
3
-
4
- attr_accessor :uuid, :time_sent, :pin,
5
- :office_label, :adress_street_name, :adress_house_num,
6
- :adress_house_num_addendum, :adress_post_num, :adress_settlement,
7
- :adress_township, :adress_other, :office_time,
8
- :take_effect_date, :closure_mark, :specific_purpose,
9
- :generated_xml
10
-
11
- def initialize( uuid: nil, time_sent: nil, pin: nil,
12
- office_label: nil, adress_street_name: nil, adress_house_num: nil,
13
- adress_house_num_addendum: nil, adress_post_num: nil, adress_settlement: nil,
14
- adress_township: nil, adress_other: nil, office_time: nil, take_effect_date: nil,
15
- closure_mark: nil, specific_purpose: nil)
16
- @uuid = uuid
17
- @time_sent = time_sent
18
- @pin = pin
19
- @office_label = office_label
20
- @adress_street_name = adress_street_name
21
- @adress_house_num = adress_house_num
22
- @adress_house_num_addendum = adress_house_num_addendum
23
- @adress_post_num = adress_post_num
24
- @adress_settlement = adress_settlement
25
- @adress_township = adress_township
26
- @adress_other = adress_other
27
- @office_time = office_time
28
- @take_effect_date = take_effect_date
29
- @closure_mark = closure_mark
30
- @specific_purpose = specific_purpose
31
-
32
- end # initialize
33
-
34
- # Getters
35
- def time_sent_str separator="T"
36
- return @time_sent.strftime('%d.%m.%Y') + separator + @time_sent.strftime('%H:%M:%S')
37
- end # time_issued_str
38
-
39
- def take_effect_date_str
40
- return @take_effect_date.strftime('%d.%m.%Y')
41
- end # time_sent_str
42
-
43
- def is_valid
44
- # Check values
45
- return false if @uuid == nil
46
- return false if @time_sent == nil
47
- return false if @pin == nil
48
- return false if @office_label == nil
49
- return false if @office_time == nil
50
- return false if @take_effect_date == nil
51
- # Check adress
52
- if @adress_other == nil
53
- return false if @adress_street_name == nil
54
- return false if @adress_house_num == nil
55
- return false if @adress_house_num_addendum == nil
56
- return false if @adress_post_num == nil
57
- return false if @adress_settlement == nil
58
- return false if @adress_township == nil
59
- end
60
- return true
61
- end # is_valid
62
- alias_method :valid?, :is_valid
63
- alias_method :valdate, :is_valid
64
-
65
- end # Office
66
- end # Fiscalizer
@@ -1,124 +0,0 @@
1
- require 'fiscalizer/echo'
2
- require 'fiscalizer/office'
3
- require 'fiscalizer/invoice'
4
-
5
- class Fiscalizer
6
- class Response
7
-
8
- attr_accessor :type, :errors, :object,
9
- :uuid, :processed_at, :response,
10
- :unique_identifier, :tns, :html_response
11
-
12
- def initialize( type: 0, errors: {}, object: nil, html_response: nil,
13
- tns: "http://www.apis-it.hr/fin/2012/types/f73", automatic: true)
14
- # Save
15
- @type = type
16
- @errors = errors
17
- @object = object
18
- @uuid = uuid
19
- @processed_at = processed_at
20
- @response = response
21
- @unique_identifier = unique_identifier
22
- @tns = tns
23
- @html_response = html_response
24
-
25
- if automatic && @object != nil
26
- @type = 0
27
- @type = 1 if @object.class == Echo
28
- @type = 2 if @object.class == Office
29
- @type = 3 if @object.class == Invoice
30
- end
31
-
32
- # Automatically fill
33
- parse_response @html_response.body if @html_response != nil && automatic
34
- end # initialize
35
-
36
- def generated_xml
37
- return @object.generated_xml if @object != nil && @object.respond_to?(:generated_xml)
38
- return nil
39
- end # generated_xml
40
-
41
- def has_error
42
- return true if @errors.count > 0
43
- return false
44
- end # has_error
45
- alias_method :errors?, :has_error
46
-
47
- def error_codes
48
- return errors.keys
49
- end # error_keys
50
-
51
- def error_messages
52
- return errors.values
53
- end # error_messages
54
-
55
- def type_str
56
- if @type == 0
57
- return "Error"
58
- elsif @type == 1
59
- return "Echo"
60
- elsif @type == 2
61
- return "Office"
62
- elsif @type == 3
63
- return "Invoice"
64
- end
65
- return "Unknown"
66
- end # type_str
67
-
68
- def echo_succeeded
69
- return false if @object == nil
70
- parse_response_echo @html_response.body if @response == nil && @html_response != nil
71
- return false if @response == nil
72
- return true if @object.text == @response
73
- return false
74
- end
75
- alias_method :echo?, :echo_succeeded
76
-
77
-
78
- private
79
- def parse_response object
80
- return nil if object == nil || object.class != String
81
- if @type == 1
82
- parse_response_echo object
83
- elsif @type == 2
84
- parse_response_office object
85
- elsif @type == 3
86
- parse_response_invoice object
87
- end
88
- parse_response_errors object
89
- end # parse_response
90
-
91
- def parse_response_echo object
92
- @response = Nokogiri::XML(object).root.xpath('//tns:EchoResponse', 'tns' => @tns).first
93
- @response = @response.text if @response != nil
94
- end # parse_response_echo
95
-
96
- def parse_response_office object
97
- @uuid = Nokogiri::XML(object).root.xpath('//tns:IdPoruke', 'tns' => @tns).first
98
- @processed_at = Nokogiri::XML(object).root.xpath('//tns:DatumVrijeme', 'tns' => @tns).first
99
- @uuid = @uuid.text if @uuid != nil
100
- @processed_at = @processed_at.text if @processed_at != nil
101
- end # parse_response_office
102
-
103
- def parse_response_invoice object
104
- @uuid = Nokogiri::XML(object).root.xpath('//tns:IdPoruke', 'tns' => @tns).first
105
- @processed_at = Nokogiri::XML(object).root.xpath('//tns:DatumVrijeme', 'tns' => @tns).first
106
- @unique_identifier = Nokogiri::XML(object).root.xpath('//tns:Jir', 'tns' => @tns).first
107
- @uuid = @uuid.text if @uuid != nil
108
- @processed_at = @processed_at.text if @processed_at != nil
109
- @unique_identifier = @unique_identifier.text if @unique_identifier != nil
110
- end # parse_response_office
111
-
112
- def parse_response_errors object
113
- raw_errors = Nokogiri::XML(object).root.xpath('//tns:Greska', 'tns' => @tns)
114
- raw_errors.each do |raw_error|
115
- error_code = raw_error.xpath('//tns:SifraGreske', 'tns' => @tns).first
116
- error_message = raw_error.xpath('//tns:PorukaGreske', 'tns' => @tns).first
117
- error_code = error_code.text.strip if error_code != nil
118
- error_message = error_message.text.strip if error_message != nil
119
- @errors[error_code] = error_message if error_code != nil
120
- end
121
- end
122
-
123
- end # Response
124
- end # Fiscalizer
@@ -1,13 +0,0 @@
1
- # Test
2
-
3
- ## Setup
4
-
5
- It is important that in test enviroments both a P12 certificate (`certificate_p12_path`) and a signing certificate are passed to the Fiscalizer object (`certificate_path`). This is important because the test P12 certificates (suffixed with `.pfx`) don't contain signing certificates in them!
6
-
7
- Don't forget to configutre all static variables in `test_fiscalizer.rb`
8
-
9
- `EXPORTED_KEYS` specifies weather to initialize a Fiscalizer object with a P12 key or to use public and private kays instead.
10
-
11
- __Note:__ If `EXPORTED_KEYS` is set to `true` than `KEY_PUBLIC_PATH` and `KEY_PRIVATE_PATH` have to be set.
12
-
13
- __Note:__ On some machines the path to the certificates has to be an absolut path
@@ -1,20 +0,0 @@
1
- require "test/unit"
2
- require "fiscalizer"
3
-
4
- class EchoTest < Test::Unit::TestCase
5
-
6
- def test_initialization
7
- # Manual build
8
- echo = Fiscalizer::Echo.new
9
- echo.text = "This is a test of text assignment"
10
- # Test
11
- assert_equal "This is a test of text assignment", echo.text, "Text was not assigned"
12
-
13
- # Automatic test
14
- echo = nil
15
- echo = Fiscalizer::Echo.new text: "This is a test of text assignment"
16
- # Test
17
- assert_equal "This is a test of text assignment", echo.text, "Text was not automatically assigned"
18
- end # test_initialization
19
-
20
- end # EchoTest