fiscalizer 0.0.12 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|