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.
- checksums.yaml +4 -4
- data/.gitignore +2 -1
- data/.rspec +2 -0
- data/Gemfile +0 -4
- data/LICENSE.txt +1 -1
- data/README.md +187 -171
- data/bin/console +14 -0
- data/bin/setup +7 -0
- data/doc/Tehnicka specifikacija za korisnike 1.4.pdf +0 -0
- data/fiscalizer.gemspec +14 -13
- data/lib/fiscalizer.rb +33 -4
- data/lib/fiscalizer/constants.rb +11 -0
- data/lib/fiscalizer/data_objects/echo.rb +10 -0
- data/lib/fiscalizer/data_objects/fee.rb +18 -0
- data/lib/fiscalizer/data_objects/invoice.rb +79 -0
- data/lib/fiscalizer/data_objects/office.rb +41 -0
- data/lib/fiscalizer/{tax.rb → data_objects/tax.rb} +3 -5
- data/lib/fiscalizer/deserializers/base.rb +58 -0
- data/lib/fiscalizer/deserializers/echo.rb +13 -0
- data/lib/fiscalizer/deserializers/invoice.rb +9 -0
- data/lib/fiscalizer/deserializers/office.rb +6 -0
- data/lib/fiscalizer/fiscalizer.rb +36 -152
- data/lib/fiscalizer/fiscalizers/base.rb +54 -0
- data/lib/fiscalizer/fiscalizers/echo.rb +13 -0
- data/lib/fiscalizer/fiscalizers/invoice.rb +24 -0
- data/lib/fiscalizer/fiscalizers/office.rb +15 -0
- data/lib/fiscalizer/serializers/base.rb +58 -0
- data/lib/fiscalizer/serializers/echo.rb +21 -0
- data/lib/fiscalizer/serializers/invoice.rb +92 -0
- data/lib/fiscalizer/serializers/office.rb +85 -0
- data/lib/fiscalizer/serializers/signature.rb +62 -0
- data/lib/fiscalizer/serializers/tax.rb +81 -0
- data/lib/fiscalizer/services/request_sender.rb +68 -0
- data/lib/fiscalizer/services/security_code_generator.rb +29 -0
- data/lib/fiscalizer/version.rb +1 -1
- data/spec/fiscalizer_spec.rb +119 -0
- data/spec/spec_helper.rb +9 -0
- metadata +67 -39
- data/doc/README.md +0 -3
- data/doc/Tehnicka_specifikacija_za_korisnike_1.2.pdf +0 -0
- data/example/README.md +0 -25
- data/example/echo_P12.rb +0 -13
- data/example/echo_public_and_private_keys.rb +0 -16
- data/example/invoice_fiscalization_passing_arguments.rb +0 -44
- data/example/invoice_fiscalization_passing_object.rb +0 -48
- data/example/office_fiscalization_passing_arguments.rb +0 -22
- data/example/office_fiscalization_passing_object.rb +0 -26
- data/lib/README.md +0 -0
- data/lib/fiscalizer/README.md +0 -9
- data/lib/fiscalizer/communication.rb +0 -305
- data/lib/fiscalizer/echo.rb +0 -11
- data/lib/fiscalizer/fee.rb +0 -20
- data/lib/fiscalizer/invoice.rb +0 -190
- data/lib/fiscalizer/office.rb +0 -66
- data/lib/fiscalizer/response.rb +0 -124
- data/test/README.md +0 -13
- data/test/test_echo.rb +0 -20
- data/test/test_fee +0 -64
- data/test/test_fiscalizer.rb +0 -222
- data/test/test_fiscalizer_communication.rb +0 -28
- data/test/test_invoice.rb +0 -11
- data/test/test_office.rb +0 -11
- data/test/test_tax.rb +0 -89
@@ -1,44 +0,0 @@
|
|
1
|
-
fiscal = Fiscalizer.new certificate_p12_path: "/path/to/FISKAL 1.p12",
|
2
|
-
password: "12345678"
|
3
|
-
# Generate taxes
|
4
|
-
taxes_vat = []
|
5
|
-
taxes_spending = []
|
6
|
-
taxes_other = []
|
7
|
-
(0..5).each do |i|
|
8
|
-
tax = Fiscalizer::Tax.new
|
9
|
-
tax.base = rand(10000 * 100).to_f / 100.0
|
10
|
-
tax.rate = rand(100 * 100).to_f / 100.0
|
11
|
-
taxes_vat << tax
|
12
|
-
end
|
13
|
-
(0..5).each do |i|
|
14
|
-
tax = Fiscalizer::Tax.new
|
15
|
-
tax.base = rand(10000 * 100).to_f / 100.0
|
16
|
-
tax.rate = rand(100 * 100).to_f / 100.0
|
17
|
-
taxes_spending << tax
|
18
|
-
end
|
19
|
-
(0..5).each do |i|
|
20
|
-
tax = Fiscalizer::Tax.new
|
21
|
-
tax.base = rand(10000 * 100).to_f / 100.0
|
22
|
-
tax.rate = rand(100 * 100).to_f / 100.0
|
23
|
-
tax.name = "My Test Tax #{i}"
|
24
|
-
taxes_other << tax
|
25
|
-
end
|
26
|
-
# Generate invoice
|
27
|
-
invoice_response = fiscal.fiscalize_invoice uuid: UUID,
|
28
|
-
time_sent: Time.now,
|
29
|
-
pin: "00123456789",
|
30
|
-
in_vat_system: true,
|
31
|
-
time_issued: Time.now - 3600,
|
32
|
-
consistance_mark: "P",
|
33
|
-
issued_number: "1",
|
34
|
-
issued_office: "Pm2",
|
35
|
-
issued_machine: "3",
|
36
|
-
tax_vat: taxes_vat,
|
37
|
-
tax_spending: taxes_spending,
|
38
|
-
tax_other: taxes_other,
|
39
|
-
payment_method: "g",
|
40
|
-
operator_pin: "12345678900",
|
41
|
-
subsequent_delivery: false,
|
42
|
-
value_non_taxable: 200.0
|
43
|
-
|
44
|
-
puts "The server returned the following JIR: " + invoice_response.unique_identifier if !invoice_response.errors?
|
@@ -1,48 +0,0 @@
|
|
1
|
-
fiscal = Fiscalizer.new certificate_p12_path: "/path/to/FISKAL 1.p12",
|
2
|
-
password: "12345678"
|
3
|
-
|
4
|
-
# Generate Invoice
|
5
|
-
invoice = Fiscalizer::Invoice.new
|
6
|
-
invoice.uuid = UUID
|
7
|
-
invoice.time_sent = Time.now
|
8
|
-
invoice.pin = "00123456789"
|
9
|
-
invoice.in_vat_system = true
|
10
|
-
invoice.time_issued = Time.now - 3600
|
11
|
-
invoice.consistance_mark = "P"
|
12
|
-
invoice.issued_number = "1"
|
13
|
-
invoice.issued_office = "Pm2"
|
14
|
-
invoice.issued_machine = "3"
|
15
|
-
invoice.payment_method = "g"
|
16
|
-
invoice.operator_pin = "12345678900"
|
17
|
-
invoice.subsequent_delivery = false
|
18
|
-
invoice.value_non_taxable = 200.0
|
19
|
-
|
20
|
-
# Generate taxes
|
21
|
-
(0..5).each do |i|
|
22
|
-
tax = Fiscalizer::Tax.new
|
23
|
-
tax.base = rand(10000 * 100).to_f / 100.0
|
24
|
-
tax.rate = rand(100 * 100).to_f / 100.0
|
25
|
-
invoice.add_tax_vat tax
|
26
|
-
end
|
27
|
-
(0..5).each do |i|
|
28
|
-
tax = Fiscalizer::Tax.new
|
29
|
-
tax.base = rand(10000 * 100).to_f / 100.0
|
30
|
-
tax.rate = rand(100 * 100).to_f / 100.0
|
31
|
-
invoice.add_tax_other base: base, rate: rate, name: "Other tax #{i}"
|
32
|
-
end
|
33
|
-
(0..5).each do |i|
|
34
|
-
fee = Fiscalizer::Fee.new
|
35
|
-
fee.value = rand(10000 * 100).to_f / 100.0
|
36
|
-
fee.name = "My Test Fee #{i}"
|
37
|
-
invoice.add_fee fee
|
38
|
-
end
|
39
|
-
(0..5).each do |i|
|
40
|
-
fee = Fiscalizer::Fee.new
|
41
|
-
fee.value = rand(10000 * 100).to_f / 100.0
|
42
|
-
fee.name = "My Test Fee #{i}"
|
43
|
-
invoice.add_fee value: value, name: name
|
44
|
-
end
|
45
|
-
# Generate invoice
|
46
|
-
invoice_response = fiscal.fiscalize_invoice invoice
|
47
|
-
|
48
|
-
puts "The server returned the following JIR: " + invoice_response.unique_identifier if !invoice_response.errors?
|
@@ -1,22 +0,0 @@
|
|
1
|
-
fiscal = Fiscalizer.new certificate_p12_path: "/path/to/FISKAL 1.p12",
|
2
|
-
password: "12345678"
|
3
|
-
|
4
|
-
# Generate office
|
5
|
-
office_response = fiscal.office uuid: "ca996cc7-fcc3-4c50-961b-40c8b875a5e8",
|
6
|
-
time_sent: Time.now,
|
7
|
-
pin: "00123456789",
|
8
|
-
office_label: "Poslovnica1",
|
9
|
-
adress_street_name: "Somewhere",
|
10
|
-
adress_house_num: "42",
|
11
|
-
adress_house_num_addendum: "AD",
|
12
|
-
adress_post_num: "10000",
|
13
|
-
adress_settlement: "Block 25-C",
|
14
|
-
adress_township: "Vogsphere",
|
15
|
-
adress_other: nil,
|
16
|
-
office_time: "Pon-Pet: 8:00-16:00",
|
17
|
-
take_effect_date: Time.now + 3600 * 24 * 7,
|
18
|
-
closure_mark: nil,
|
19
|
-
specific_purpose: nil
|
20
|
-
|
21
|
-
puts "The server returned the following UUID: " + office_response.uuid if !office_response.errors?
|
22
|
-
puts "Office space fiscalization was successful!" if !office_response.errors?
|
@@ -1,26 +0,0 @@
|
|
1
|
-
fiscal = Fiscalizer.new certificate_p12_path: "/path/to/FISKAL 1.p12",
|
2
|
-
password: "12345678"
|
3
|
-
|
4
|
-
# Generate office
|
5
|
-
office = Fiscalizer::Office.new
|
6
|
-
office.uuid = "ca996cc7-fcc3-4c50-961b-40c8b875a5e8"
|
7
|
-
office.time_sent = Time.now
|
8
|
-
office.pin = "00123456789"
|
9
|
-
office.office_label = "Poslovnica1"
|
10
|
-
office.adress_street_name = "Somewhere"
|
11
|
-
office.adress_house_num = "42"
|
12
|
-
office.adress_house_num_addendum = "AD"
|
13
|
-
office.adress_post_num = "10000"
|
14
|
-
office.adress_settlement = "Block 25-C"
|
15
|
-
office.adress_township = "Vogsphere"
|
16
|
-
office.adress_other = nil
|
17
|
-
office.office_time = "Pon-Pet: 8:00-16:00"
|
18
|
-
office.take_effect_date = Time.now + 3600 * 24 * 7
|
19
|
-
office.closure_mark = nil
|
20
|
-
office.specific_purpose = nil
|
21
|
-
|
22
|
-
# Generate office
|
23
|
-
office_response = fiscal.fiscalize_office office
|
24
|
-
|
25
|
-
puts "The server returned the following UUID: " + office_response.uuid if !office_response.errors?
|
26
|
-
puts "Office space fiscalization was successful!" if !office_response.errors?
|
data/lib/README.md
DELETED
File without changes
|
data/lib/fiscalizer/README.md
DELETED
@@ -1,9 +0,0 @@
|
|
1
|
-
# Fiscalizer
|
2
|
-
|
3
|
-
Fiscalizer is the main class of this gem. It interacts with all other classes, handles certificate decription and connection establishment.
|
4
|
-
|
5
|
-
Methods:
|
6
|
-
|
7
|
-
* `echo` : Creates an echo request to the fiscalization servers
|
8
|
-
* `fiscalize_office` : Creates or recives an office object and fiscalizes it (alias methods `office` and `fiscalize_office_space`)
|
9
|
-
* `fiscalize_invoice` : Creates or recives an invoice object and fiscalizes it (alias methods `invoice`)
|
@@ -1,305 +0,0 @@
|
|
1
|
-
class Fiscalizer
|
2
|
-
class Communication
|
3
|
-
attr_accessor :url, :tns, :schemaLocation,
|
4
|
-
:key_public, :key_private, :certificate,
|
5
|
-
:certificate_issued_by, :timeout
|
6
|
-
|
7
|
-
def initialize( tns: "http://www.apis-it.hr/fin/2012/types/f73",
|
8
|
-
url: "https://cis.porezna-uprava.hr:8449/FiskalizacijaService",
|
9
|
-
schemaLocation: "http://www.apis-it.hr/fin/2012/types/f73 FiskalizacijaSchema.xsd",
|
10
|
-
key_public: nil, key_private: nil, certificate: nil,
|
11
|
-
certificate_issued_by: "OU=RDC,O=FINA,C=HR", timeout:3 )
|
12
|
-
@tns = tns
|
13
|
-
@url = url
|
14
|
-
@schemaLocation = schemaLocation
|
15
|
-
@key_public = key_public
|
16
|
-
@key_private = key_private
|
17
|
-
@certificate = certificate
|
18
|
-
@certificate_issued_by = certificate_issued_by
|
19
|
-
@timeout = timeout
|
20
|
-
end # initialize
|
21
|
-
|
22
|
-
def send object
|
23
|
-
# Check input
|
24
|
-
raise "Missing keys" if @key_public == nil || @key_private == nil
|
25
|
-
raise "Missing certificate" if @certificate == nil
|
26
|
-
raise "Can't send nil object" if object == nil
|
27
|
-
|
28
|
-
# Prepare data
|
29
|
-
uri = URI.parse(@url)
|
30
|
-
http = Net::HTTP.new(uri.host, uri.port)
|
31
|
-
http.read_timeout = @timeout
|
32
|
-
http.use_ssl = true
|
33
|
-
http.cert_store = OpenSSL::X509::Store.new
|
34
|
-
http.cert_store.set_default_paths
|
35
|
-
begin
|
36
|
-
http.cert_store.add_cert(@certificate)
|
37
|
-
rescue OpenSSL::X509::StoreError
|
38
|
-
puts "Certificate alreay exists"
|
39
|
-
end
|
40
|
-
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
41
|
-
|
42
|
-
# Encode object
|
43
|
-
encoded_object = encode_object object
|
44
|
-
return false if encoded_object.nil?
|
45
|
-
|
46
|
-
# Send it
|
47
|
-
request = Net::HTTP::Post.new(uri.request_uri)
|
48
|
-
request.content_type = 'application/xml'
|
49
|
-
request.body = encoded_object
|
50
|
-
response = http.request(request)
|
51
|
-
|
52
|
-
return response
|
53
|
-
end # send
|
54
|
-
|
55
|
-
def encode_object object
|
56
|
-
encoded_object = nil
|
57
|
-
if object.class == Echo
|
58
|
-
encoded_object = encode_echo object
|
59
|
-
elsif object.class == Office
|
60
|
-
encoded_object = encode_office object
|
61
|
-
elsif object.class == Invoice
|
62
|
-
encoded_object = encode_invoice object
|
63
|
-
end
|
64
|
-
return encoded_object
|
65
|
-
end # encode_object
|
66
|
-
|
67
|
-
def generate_security_code invoice
|
68
|
-
# Build data set to generate security code
|
69
|
-
unsigned_code = ""
|
70
|
-
unsigned_code += invoice.pin
|
71
|
-
unsigned_code += invoice.time_issued_str " "
|
72
|
-
unsigned_code += invoice.issued_number.to_s
|
73
|
-
unsigned_code += invoice.issued_office.to_s
|
74
|
-
unsigned_code += invoice.issued_machine.to_s
|
75
|
-
unsigned_code += invoice.summed_total_str
|
76
|
-
# Sign with my private key
|
77
|
-
signed_code = OpenSSL::PKey::RSA.new(key_private).sign(OpenSSL::Digest::SHA1.new, unsigned_code)
|
78
|
-
# Create a MD5 digest from it
|
79
|
-
md5_digest = Digest::MD5.hexdigest(signed_code)
|
80
|
-
invoice.security_code = md5_digest
|
81
|
-
return md5_digest
|
82
|
-
end # generate_security_code
|
83
|
-
|
84
|
-
private
|
85
|
-
def encode_echo object
|
86
|
-
echo_xml = Nokogiri::XML::Builder.new(encoding: 'UTF-8') do |xml|
|
87
|
-
xml['tns'].EchoRequest(
|
88
|
-
'xmlns:tns' => @tns,
|
89
|
-
'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
|
90
|
-
'xsi:schemaLocation' => @schemaLocation
|
91
|
-
) {
|
92
|
-
xml.text object.text
|
93
|
-
}
|
94
|
-
end
|
95
|
-
xml = soap_envelope(echo_xml).to_xml
|
96
|
-
object.generated_xml = soap_envelope(echo_xml).to_xml
|
97
|
-
return xml
|
98
|
-
end # encode_echo
|
99
|
-
|
100
|
-
def encode_office object
|
101
|
-
office_request_xml = Nokogiri::XML::Builder.new(encoding: 'UTF-8') do |xml|
|
102
|
-
xml['tns'].PoslovniProstorZahtjev(
|
103
|
-
'xmlns:tns' => @tns,
|
104
|
-
'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
|
105
|
-
'xsi:schemaLocation' => schemaLocation,
|
106
|
-
'Id' => 'PoslovniProstorZahtjev'
|
107
|
-
) {
|
108
|
-
# Header
|
109
|
-
xml['tns'].Zaglavlje {
|
110
|
-
xml['tns'].IdPoruke object.uuid
|
111
|
-
xml['tns'].DatumVrijeme object.time_sent_str
|
112
|
-
}
|
113
|
-
# Body
|
114
|
-
xml['tns'].PoslovniProstor {
|
115
|
-
# Important info
|
116
|
-
xml['tns'].Oib object.pin
|
117
|
-
xml['tns'].OznPoslProstora object.office_label
|
118
|
-
xml['tns'].AdresniPodatak {
|
119
|
-
xml['tns'].Adresa {
|
120
|
-
xml['tns'].Ulica object.adress_street_name if object.adress_street_name != nil && object.adress_street_name.length != 0
|
121
|
-
xml['tns'].KucniBroj object.adress_house_num if object.adress_house_num != nil && object.adress_house_num.length != 0
|
122
|
-
xml['tns'].KucniBrojDodatak object.adress_house_num_addendum if object.adress_house_num_addendum != nil && object.adress_house_num_addendum.length != 0
|
123
|
-
xml['tns'].BrojPoste object.adress_post_num if object.adress_post_num != nil && object.adress_post_num.length != 0
|
124
|
-
xml['tns'].Naselje object.adress_settlement if object.adress_settlement != nil && object.adress_settlement.length != 0
|
125
|
-
xml['tns'].Opcina object.adress_township if object.adress_township != nil && object.adress_township.length != 0
|
126
|
-
} if object.adress_other == nil || object.adress_other.length == 0
|
127
|
-
xml['tns'].OstaliTipoviPP object.adress_other if object.adress_other != nil && object.adress_other.length != 0
|
128
|
-
}
|
129
|
-
xml['tns'].RadnoVrijeme object.office_time
|
130
|
-
xml['tns'].DatumPocetkaPrimjene object.take_effect_date_str
|
131
|
-
# Optional info
|
132
|
-
xml['tns'].OznakaZatvaranja object.closure_mark if object.closure_mark != nil
|
133
|
-
xml['tns'].SpecNamj object.specific_purpose if object.specific_purpose != nil
|
134
|
-
}
|
135
|
-
xml.Signature('xmlns' => 'http://www.w3.org/2000/09/xmldsig#') {
|
136
|
-
xml.SignedInfo {
|
137
|
-
xml.CanonicalizationMethod('Algorithm' => 'http://www.w3.org/2001/10/xml-exc-c14n#')
|
138
|
-
xml.SignatureMethod('Algorithm' => 'http://www.w3.org/2000/09/xmldsig#rsa-sha1')
|
139
|
-
xml.Reference('URI' => '#PoslovniProstorZahtjev') {
|
140
|
-
xml.Transforms {
|
141
|
-
xml.Transform('Algorithm' => 'http://www.w3.org/2000/09/xmldsig#enveloped-signature')
|
142
|
-
xml.Transform('Algorithm' => 'http://www.w3.org/2001/10/xml-exc-c14n#')
|
143
|
-
}
|
144
|
-
xml.DigestMethod('Algorithm' => 'http://www.w3.org/2000/09/xmldsig#sha1')
|
145
|
-
xml.DigestValue
|
146
|
-
}
|
147
|
-
}
|
148
|
-
xml.SignatureValue
|
149
|
-
xml.KeyInfo {
|
150
|
-
xml.X509Data {
|
151
|
-
xml.X509Certificate key_public.to_s.gsub('-----BEGIN CERTIFICATE-----','').gsub('-----END CERTIFICATE-----','').gsub("\n",'')
|
152
|
-
xml.X509IssuerSerial {
|
153
|
-
xml.X509IssuerName @certificate_issued_by
|
154
|
-
xml.X509SerialNumber "1053520622" # Explane
|
155
|
-
}
|
156
|
-
}
|
157
|
-
}
|
158
|
-
}
|
159
|
-
}
|
160
|
-
end
|
161
|
-
|
162
|
-
body = soap_envelope(office_request_xml)
|
163
|
-
unsigned_document = Xmldsig_fiscalizer::SignedDocument.new(body.doc.root.to_xml)
|
164
|
-
signed_xml = unsigned_document.sign(@key_private)
|
165
|
-
signed_xml.sub! '<?xml version="1.0"?>', ''
|
166
|
-
signed_xml = signed_xml.gsub /^$\n/, ''
|
167
|
-
|
168
|
-
object.generated_xml = signed_xml
|
169
|
-
|
170
|
-
return signed_xml
|
171
|
-
end # encode_office
|
172
|
-
|
173
|
-
def encode_invoice object
|
174
|
-
generate_security_code object
|
175
|
-
invoice_request_xml = Nokogiri::XML::Builder.new(encoding: 'UTF-8') do |xml|
|
176
|
-
xml['tns'].RacunZahtjev(
|
177
|
-
'xmlns:tns' => @tns,
|
178
|
-
'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
|
179
|
-
'xsi:schemaLocation' => schemaLocation,
|
180
|
-
'Id' => 'RacunZahtjev'
|
181
|
-
) {
|
182
|
-
# Header
|
183
|
-
xml['tns'].Zaglavlje {
|
184
|
-
xml['tns'].IdPoruke object.uuid
|
185
|
-
xml['tns'].DatumVrijeme object.time_sent_str
|
186
|
-
}
|
187
|
-
# Body
|
188
|
-
xml['tns'].Racun {
|
189
|
-
# Important info
|
190
|
-
xml['tns'].Oib object.pin
|
191
|
-
xml['tns'].USustPdv object.in_vat_system
|
192
|
-
xml['tns'].DatVrijeme object.time_issued_str
|
193
|
-
xml['tns'].OznSlijed object.consistance_mark
|
194
|
-
# Invoice issued numbers
|
195
|
-
xml['tns'].BrRac {
|
196
|
-
xml['tns'].BrOznRac object.issued_number.to_s
|
197
|
-
xml['tns'].OznPosPr object.issued_office.to_s
|
198
|
-
xml['tns'].OznNapUr object.issued_machine.to_s
|
199
|
-
}
|
200
|
-
# Optional info
|
201
|
-
# Tax VAT
|
202
|
-
xml['tns'].Pdv {
|
203
|
-
object.tax_vat.each do |tax|
|
204
|
-
xml['tns'].Porez {
|
205
|
-
xml['tns'].Stopa tax.rate_str
|
206
|
-
xml['tns'].Osnovica tax.base_str
|
207
|
-
xml['tns'].Iznos tax.total_str
|
208
|
-
}
|
209
|
-
end
|
210
|
-
} if object.tax_vat != nil && object.tax_vat.size != 0
|
211
|
-
# Tax Spending
|
212
|
-
xml['tns'].Pnp {
|
213
|
-
object.tax_spending.each do |tax|
|
214
|
-
xml['tns'].Porez {
|
215
|
-
xml['tns'].Stopa tax.rate_str
|
216
|
-
xml['tns'].Osnovica tax.base_str
|
217
|
-
xml['tns'].Iznos tax.total_str
|
218
|
-
}
|
219
|
-
end
|
220
|
-
} if object.tax_spending != nil && object.tax_spending.size != 0
|
221
|
-
# Tax Other
|
222
|
-
xml['tns'].OstaliPor {
|
223
|
-
object.tax_other.each do |tax|
|
224
|
-
xml['tns'].Porez {
|
225
|
-
xml['tns'].Naziv tax.name
|
226
|
-
xml['tns'].Stopa tax.rate_str
|
227
|
-
xml['tns'].Osnovica tax.base_str
|
228
|
-
xml['tns'].Iznos tax.total_str
|
229
|
-
}
|
230
|
-
end
|
231
|
-
} if object.tax_other != nil && object.tax_other.size != 0
|
232
|
-
# Tax info
|
233
|
-
xml['tns'].IznosOslobPdv object.value_tax_liberation_str if object.value_tax_liberation_str != nil
|
234
|
-
xml['tns'].IznosMarza object.value_tax_margin_str if object.value_tax_margin_str != nil
|
235
|
-
xml['tns'].IznosNePodlOpor object.value_non_taxable_str if object.value_non_taxable_str != nil
|
236
|
-
# Fees
|
237
|
-
xml['tns'].Naknade {
|
238
|
-
object.tax_other.each do |tax|
|
239
|
-
xml['tns'].Naknada {
|
240
|
-
xml['tns'].NazivN tax.name
|
241
|
-
xml['tns'].IznosN tax.rate_str
|
242
|
-
}
|
243
|
-
end
|
244
|
-
} if object.fees != nil && object.fees.size != 0
|
245
|
-
# Important info
|
246
|
-
xml['tns'].IznosUkupno object.summed_total_str
|
247
|
-
xml['tns'].NacinPlac object.payment_method
|
248
|
-
xml['tns'].OibOper object.operator_pin
|
249
|
-
xml['tns'].ZastKod object.security_code
|
250
|
-
xml['tns'].NakDost object.subsequent_delivery
|
251
|
-
# Optional info
|
252
|
-
xml['tns'].ParagonBrRac object.paragon_label if object.paragon_label != nil
|
253
|
-
xml['tns'].SpecNamj object.specific_purpose if object.specific_purpose != nil
|
254
|
-
}
|
255
|
-
xml.Signature('xmlns' => 'http://www.w3.org/2000/09/xmldsig#') {
|
256
|
-
xml.SignedInfo {
|
257
|
-
xml.CanonicalizationMethod('Algorithm' => 'http://www.w3.org/2001/10/xml-exc-c14n#')
|
258
|
-
xml.SignatureMethod('Algorithm' => 'http://www.w3.org/2000/09/xmldsig#rsa-sha1')
|
259
|
-
xml.Reference('URI' => '#RacunZahtjev') {
|
260
|
-
xml.Transforms {
|
261
|
-
xml.Transform('Algorithm' => 'http://www.w3.org/2000/09/xmldsig#enveloped-signature')
|
262
|
-
xml.Transform('Algorithm' => 'http://www.w3.org/2001/10/xml-exc-c14n#')
|
263
|
-
}
|
264
|
-
xml.DigestMethod('Algorithm' => 'http://www.w3.org/2000/09/xmldsig#sha1')
|
265
|
-
xml.DigestValue
|
266
|
-
}
|
267
|
-
}
|
268
|
-
xml.SignatureValue
|
269
|
-
xml.KeyInfo {
|
270
|
-
xml.X509Data {
|
271
|
-
xml.X509Certificate key_public.to_s.gsub('-----BEGIN CERTIFICATE-----','').gsub('-----END CERTIFICATE-----','').gsub("\n",'')
|
272
|
-
xml.X509IssuerSerial {
|
273
|
-
xml.X509IssuerName @certificate_issued_by
|
274
|
-
xml.X509SerialNumber "1053520622" # Explane
|
275
|
-
}
|
276
|
-
}
|
277
|
-
}
|
278
|
-
}
|
279
|
-
}
|
280
|
-
end
|
281
|
-
|
282
|
-
body = soap_envelope(invoice_request_xml)
|
283
|
-
unsigned_document = Xmldsig_fiscalizer::SignedDocument.new(body.doc.root.to_xml)
|
284
|
-
signed_xml = unsigned_document.sign(@key_private)
|
285
|
-
signed_xml.sub! '<?xml version="1.0"?>', ''
|
286
|
-
signed_xml = signed_xml.gsub /^$\n/, ''
|
287
|
-
|
288
|
-
object.generated_xml = signed_xml
|
289
|
-
|
290
|
-
return signed_xml
|
291
|
-
end # encode_invoice
|
292
|
-
|
293
|
-
def soap_envelope req_xml
|
294
|
-
return Nokogiri::XML::Builder.new(encoding: 'UTF-8') do |xml|
|
295
|
-
xml['soapenv'].Envelope('xmlns:soapenv' => 'http://schemas.xmlsoap.org/soap/envelope/') {
|
296
|
-
xml['soapenv'].Body {
|
297
|
-
xml << req_xml.doc.root.to_xml
|
298
|
-
}
|
299
|
-
}
|
300
|
-
end
|
301
|
-
end # soap_envelope
|
302
|
-
|
303
|
-
|
304
|
-
end # Communication
|
305
|
-
end # Fiscalizer
|