sunat_invoice 0.0.1 → 0.0.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/Gemfile +1 -0
- data/README.mkd +1 -25
- data/lib/sunat_invoice/client.rb +3 -6
- data/lib/sunat_invoice/clients/consult_client.rb +17 -0
- data/lib/sunat_invoice/clients/invoice_client.rb +11 -3
- data/lib/sunat_invoice/configuration.rb +1 -1
- data/lib/sunat_invoice/credit_note.rb +59 -0
- data/lib/sunat_invoice/credit_note_line.rb +15 -0
- data/lib/sunat_invoice/customer.rb +1 -0
- data/lib/sunat_invoice/daily_summary.rb +46 -0
- data/lib/sunat_invoice/debit_note.rb +33 -0
- data/lib/sunat_invoice/debit_note_line.rb +15 -0
- data/lib/sunat_invoice/invoice.rb +23 -144
- data/lib/sunat_invoice/item.rb +40 -26
- data/lib/sunat_invoice/line.rb +18 -0
- data/lib/sunat_invoice/provider.rb +20 -14
- data/lib/sunat_invoice/response_parser.rb +64 -0
- data/lib/sunat_invoice/signature.rb +29 -15
- data/lib/sunat_invoice/summary_line.rb +75 -0
- data/lib/sunat_invoice/tax.rb +6 -1
- data/lib/sunat_invoice/trade_calculations.rb +68 -0
- data/lib/sunat_invoice/trade_document.rb +85 -0
- data/lib/sunat_invoice/utils.rb +48 -9
- data/lib/sunat_invoice/voided.rb +22 -0
- data/lib/sunat_invoice/voided_line.rb +20 -0
- data/lib/sunat_invoice/xml_document.rb +52 -0
- data/lib/sunat_invoice.rb +14 -0
- data/sunat_invoice.gemspec +5 -5
- data/test/credit_note_test.rb +15 -0
- data/test/daily_summary_test.rb +35 -0
- data/test/debit_note_test.rb +15 -0
- data/test/factories.rb +70 -0
- data/test/fixtures/responses/invoice_success.xml +2 -0
- data/test/fixtures/responses/summary_success.xml +2 -0
- data/test/fixtures/responses/ticket_invalid.xml +2 -0
- data/test/helper.rb +1 -0
- data/test/invoice_client_test.rb +68 -16
- data/test/invoice_test.rb +19 -10
- data/test/item_test.rb +3 -2
- data/test/response_parser_test.rb +28 -0
- data/test/support/response_helper.rb +18 -0
- data/test/support/signature_helper.rb +15 -8
- metadata +34 -13
data/test/factories.rb
CHANGED
@@ -21,6 +21,55 @@ FactoryBot.define do
|
|
21
21
|
initialize_with { new(attributes) }
|
22
22
|
end
|
23
23
|
|
24
|
+
factory :credit_note_line, class: 'SunatInvoice::CreditNoteLine' do
|
25
|
+
quantity 10
|
26
|
+
unit_code 'NIU'
|
27
|
+
price 20
|
28
|
+
price_code '01'
|
29
|
+
description 'Grabadora Externo'
|
30
|
+
taxes { [build(:tax, amount: 3.6)] }
|
31
|
+
end
|
32
|
+
|
33
|
+
factory :credit_note, class: 'SunatInvoice::CreditNote' do
|
34
|
+
provider { build(:provider) }
|
35
|
+
customer { build(:customer) }
|
36
|
+
document_number 'F001-211'
|
37
|
+
currency 'PEN'
|
38
|
+
ref_document_number 'F001-342'
|
39
|
+
ref_document_type '01'
|
40
|
+
response_code '01'
|
41
|
+
document_type '07'
|
42
|
+
description 'Some awesome product'
|
43
|
+
lines { [build(:credit_note_line)] }
|
44
|
+
end
|
45
|
+
|
46
|
+
factory :debit_note_line, class: 'SunatInvoice::DebitNoteLine' do
|
47
|
+
quantity 10
|
48
|
+
unit_code 'NIU'
|
49
|
+
price 20
|
50
|
+
price_code '01'
|
51
|
+
description 'Ajuste de precio'
|
52
|
+
taxes { [build(:tax, amount: 3.6)] }
|
53
|
+
end
|
54
|
+
|
55
|
+
factory :debit_note, class: 'SunatInvoice::DebitNote' do
|
56
|
+
provider { build(:provider) }
|
57
|
+
customer { build(:customer) }
|
58
|
+
document_number 'F001-211'
|
59
|
+
currency 'PEN'
|
60
|
+
ref_document_number 'F001-342'
|
61
|
+
ref_document_type '01'
|
62
|
+
response_code '01'
|
63
|
+
document_type '08'
|
64
|
+
description 'Unidades defectuosas'
|
65
|
+
lines { [build(:debit_note_line)] }
|
66
|
+
end
|
67
|
+
|
68
|
+
factory :daily_summary, class: 'SunatInvoice::DailySummary' do
|
69
|
+
provider { build(:provider) }
|
70
|
+
signature { build(:signature, provider: provider) }
|
71
|
+
end
|
72
|
+
|
24
73
|
factory :provider, class: 'SunatInvoice::Provider' do
|
25
74
|
pk_file File.join(File.dirname(__FILE__), 'certs/pk_file')
|
26
75
|
cert_file File.join(File.dirname(__FILE__), 'certs/cert_file')
|
@@ -45,4 +94,25 @@ FactoryBot.define do
|
|
45
94
|
|
46
95
|
initialize_with { new(attributes) }
|
47
96
|
end
|
97
|
+
|
98
|
+
factory :signature, class: 'SunatInvoice::Signature' do
|
99
|
+
provider { build(:provider) }
|
100
|
+
end
|
101
|
+
|
102
|
+
factory :summary_line, class: 'SunatInvoice::SummaryLine' do
|
103
|
+
document_type '03'
|
104
|
+
document_serial 'BD56'
|
105
|
+
start_document_number 231
|
106
|
+
end_document_number 239
|
107
|
+
taxable 2000
|
108
|
+
taxes { [build(:tax, amount: 360), build(:tax, amount: 0, tax_type: :isc)] }
|
109
|
+
total_amount 2360
|
110
|
+
end
|
111
|
+
|
112
|
+
factory :voided_line, class: 'SunatInvoice::VoidedLine' do
|
113
|
+
document_type '03'
|
114
|
+
document_serial 'BD56'
|
115
|
+
document_number 231
|
116
|
+
description 'Anulación documento'
|
117
|
+
end
|
48
118
|
end
|
@@ -0,0 +1,2 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"><soap-env:Header/><soap-env:Body><br:sendBillResponse xmlns:br="http://service.sunat.gob.pe"><applicationResponse>UEsDBBQAAgAIACV9hEsAAAAAAgAAAAAAAAAGAAAAZHVtbXkvAwBQSwMEFAACAAgAJX2ES7yR4JPEAwAAmgsAAB0AAABSLTIwMTAwNDU0NTIzLTAxLUZZMDItMjM0LnhtbLVWW3PaOhB+76/wmIfOtMeRbCAEj6EDoXRoe3LhkiZ9U2zFqMWSK4lLzq8/km/YxJlCZzrmQV59++3q210Z78MuWhkbzAVhtGfaZ9A0MPVZQGjYMxfzsXVhfui/8RB3B3G8Ij6SCjjFImZUYEM5U+Ei3jPXnLoMCSJciiIsXBFjnzxleHf9uHKFv8QRcnciqKOyHDNjwzt5It0liyJGP+4kpvoY6lVRYirFntR/9P+IdKjgfi0h+jPCQRhyHCKJ60gD0TOXUsYuANvt9mzbPGM8BA6EEMAuUJhAkLCRowVDcYFPA4kztaXtiaNeAEw3eMViDMy+p6R1F8OvhVLipSm1lLSkaiX73oyEFMk1z2p+VJ6qb7QbDib0ifXfGIZ3iSijSp8V+S/R6F8slywwBquQcSKX0Su0NrChprXwzrd8u0Ub3xRaC6r1M0HCXWR4NCls5blaEeO4wQWyxBK1bSejnOInzNU4YGMxnfRMUxuVec4RFU+MRyI1lE2/DVuRKC9OYIk8+zT0iaTHCKQIwWHm3oiEWMgTFVOKNMo6FTx3aLXG/e83P+SmO4w/Or9itI7vyeK2E/8U191x88s5IL+Gnz53tvbFtjm4nTUfYORfT2d3n9q3lyyEfP7j23b3sBt/v4un+Pw64u17/vl90Nn2eh4oR9H1AUWBVKuBaq+VOyL1eHfDyUZNnvETPxtvh1iiGzWiarwxl28NyqSxjt+lNCUv7wt+Tji9+zbsjpBE6Up7pbOumK/U+AeGvzdl/GlAxVDiP3RO2CZCrDGfYU7QqmzRxKfTl3wTrpT3ah09Yn46W8W7HCBPF+yVAYVaex3Vuv5OAS8vH1BzRam7252M+rbqt5bqwo5+PJBZ012dzkiL6UC7Y9mOBVtzCN3kl0ELyN5jTpRANbDEnsDyr9MBd4qtbFbgCYHddlu2a8MqOONGvlvSJzuLtswWV4N56XQFkPHnG8Tlc2pLlpNAyVh8bwoalWdTPU633d4Tgde98o20X7RDsiplku6AAyR4LTk1pkSiVXHAgZTIX0ZJzfW+Li6naLWf3iSqumP7jQMNtC0NVOMEfhcMHOqsXzENMP87UoLaAFPsY7I5JSaErXar7TSPjlkTYsT8tVYhb7w8l+ItacpMSxVi/AAdy2kWvb3fqbT2JQvUzFR7OrElqBEWPidxktlXZIyRr4RHBlWZcGbkIf4xlsgQJGAG8nEsUYBSvrJ3fq5y8vsjVfrmRfKFYHUOqVokJsp+ZEXOLQc63SZ0LlrQPqUmlSigviqg/q91/39QSwECAAAUAAIACAAlfYRLAAAAAAIAAAAAAAAABgAAAAAAAAAAAAAAAAAAAAAAZHVtbXkvUEsBAgAAFAACAAgAJX2ES7yR4JPEAwAAmgsAAB0AAAAAAAAAAQAAAAAAJgAAAFItMjAxMDA0NTQ1MjMtMDEtRlkwMi0yMzQueG1sUEsFBgAAAAACAAIAfwAAACUEAAAAAA==</applicationResponse></br:sendBillResponse></soap-env:Body></soap-env:Envelope>
|
@@ -0,0 +1,2 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"><soap-env:Header/><soap-env:Body><br:sendSummaryResponse xmlns:br="http://service.sunat.gob.pe"><ticket>1512600172234</ticket></br:sendSummaryResponse></soap-env:Body></soap-env:Envelope>
|
@@ -0,0 +1,2 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<S:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"><S:Body><ns2:getStatusResponse xmlns:ns2="http://service.sunat.gob.pe"><status><content>El ticket no existe</content><statusCode>0127</statusCode></status></ns2:getStatusResponse></S:Body></S:Envelope>
|
data/test/helper.rb
CHANGED
data/test/invoice_client_test.rb
CHANGED
@@ -4,38 +4,90 @@ require_relative 'helper'
|
|
4
4
|
|
5
5
|
scope 'SunatInvoice::InvoiceClient' do
|
6
6
|
setup do
|
7
|
-
provider = FactoryBot.build(:provider,
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
customer = FactoryBot.build(:customer,
|
14
|
-
|
15
|
-
|
7
|
+
@provider = FactoryBot.build(:provider,
|
8
|
+
signature_id: 'signatureST',
|
9
|
+
signature_location_id: 'signQWI3',
|
10
|
+
ruc: '20100454523',
|
11
|
+
name: 'SOPORTE TECNOLOGICO EIRL')
|
12
|
+
|
13
|
+
@customer = FactoryBot.build(:customer,
|
14
|
+
ruc: '20293028401',
|
15
|
+
name: 'SOME BUSINESS')
|
16
16
|
SunatInvoice.configure do |c|
|
17
|
-
c.account_ruc = provider.ruc
|
17
|
+
c.account_ruc = @provider.ruc
|
18
18
|
c.account_user = 'MODDATOS'
|
19
19
|
c.account_password = 'moddatos'
|
20
|
-
c.provider = provider
|
21
20
|
end
|
22
21
|
@client = SunatInvoice::InvoiceClient.new
|
23
22
|
|
24
23
|
tax = SunatInvoice::Tax.new(amount: 3.6, tax_type: :igv)
|
25
24
|
item = FactoryBot.build(:item, taxes: [tax])
|
26
|
-
@invoice = SunatInvoice::Invoice.new(provider: provider,
|
27
|
-
customer: customer,
|
25
|
+
@invoice = SunatInvoice::Invoice.new(provider: @provider,
|
26
|
+
customer: @customer,
|
28
27
|
document_number: 'FY02-234')
|
29
|
-
@invoice.
|
28
|
+
@invoice.lines << item
|
30
29
|
end
|
31
30
|
|
32
31
|
test 'should use dev service when not define environment' do
|
33
32
|
assert_equal @client.wsdl, @client.dev_server
|
34
33
|
end
|
35
34
|
|
35
|
+
test 'send invoice success' do
|
36
|
+
response = @client.dispatch(@invoice)
|
37
|
+
assert_equal response.http.code, 200
|
38
|
+
end
|
39
|
+
|
40
|
+
test 'send credit note' do
|
41
|
+
tax = SunatInvoice::Tax.new(amount: 3.6, tax_type: :igv)
|
42
|
+
line = FactoryBot.build(:credit_note_line, taxes: [tax])
|
43
|
+
signature = FactoryBot.build(:signature, provider: @provider)
|
44
|
+
credit_note = FactoryBot.build(:credit_note, provider: @provider,
|
45
|
+
customer: @customer,
|
46
|
+
lines: [line],
|
47
|
+
signature: signature)
|
48
|
+
response = @client.dispatch(credit_note)
|
49
|
+
assert_equal response.http.code, 200
|
50
|
+
end
|
51
|
+
|
52
|
+
test 'send debit note' do
|
53
|
+
tax = SunatInvoice::Tax.new(amount: 3.6, tax_type: :igv)
|
54
|
+
line = FactoryBot.build(:debit_note_line, taxes: [tax])
|
55
|
+
signature = FactoryBot.build(:signature, provider: @provider)
|
56
|
+
debit_note = FactoryBot.build(:debit_note, provider: @provider,
|
57
|
+
customer: @customer,
|
58
|
+
lines: [line],
|
59
|
+
signature: signature)
|
60
|
+
response = @client.dispatch(debit_note)
|
61
|
+
assert_equal response.http.code, 200
|
62
|
+
end
|
63
|
+
|
64
|
+
test 'send summary success' do
|
65
|
+
line = FactoryBot.build(:summary_line)
|
66
|
+
signature = FactoryBot.build(:signature, provider: @provider)
|
67
|
+
summary = SunatInvoice::DailySummary.new(provider: @provider,
|
68
|
+
signature: signature,
|
69
|
+
reference_date: Date.today,
|
70
|
+
currency: 'PEN',
|
71
|
+
lines: [line])
|
72
|
+
response = @client.dispatch(summary)
|
73
|
+
assert_equal response.http.code, 200
|
74
|
+
end
|
75
|
+
|
76
|
+
test 'void document' do
|
77
|
+
line = FactoryBot.build(:voided_line)
|
78
|
+
signature = FactoryBot.build(:signature, provider: @provider)
|
79
|
+
voided = SunatInvoice::Voided.new(provider: @provider,
|
80
|
+
signature: signature,
|
81
|
+
reference_date: Date.today,
|
82
|
+
currency: 'PEN',
|
83
|
+
lines: [line])
|
84
|
+
response = @client.dispatch(voided)
|
85
|
+
assert_equal response.http.code, 200
|
86
|
+
end
|
36
87
|
|
37
|
-
test '
|
38
|
-
|
88
|
+
test 'get status' do
|
89
|
+
ticket = rand(10**15).to_s
|
90
|
+
response = @client.get_status(ticket)
|
39
91
|
assert_equal response.http.code, 200
|
40
92
|
end
|
41
93
|
end
|
data/test/invoice_test.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: false
|
2
|
+
|
2
3
|
require_relative 'helper'
|
3
4
|
include SunatInvoice
|
4
5
|
|
@@ -7,7 +8,7 @@ setup do
|
|
7
8
|
@invoice = FactoryBot.build(:invoice, provider: @provider)
|
8
9
|
tax = SunatInvoice::Tax.new(amount: 3.6, tax_type: :igv)
|
9
10
|
item_attr = { quantity: 10, price: 20, price_code: '01', taxes: [tax] }
|
10
|
-
@invoice.
|
11
|
+
@invoice.lines << SunatInvoice::Item.new(item_attr)
|
11
12
|
@parsed_xml = Nokogiri::XML(@invoice.xml, &:noblanks)
|
12
13
|
end
|
13
14
|
|
@@ -27,7 +28,7 @@ end
|
|
27
28
|
|
28
29
|
test 'has a date' do
|
29
30
|
date = @parsed_xml.xpath('//cbc:IssueDate')
|
30
|
-
assert_equal date.first.content,
|
31
|
+
assert_equal date.first.content, Date.today.strftime('%Y-%m-%d')
|
31
32
|
end
|
32
33
|
|
33
34
|
test 'has a signature' do
|
@@ -110,7 +111,7 @@ test 'has at least one item' do
|
|
110
111
|
end
|
111
112
|
|
112
113
|
test 'has total by kind of sale' do
|
113
|
-
tag = '//ext:
|
114
|
+
tag = '//ext:UBLExtension/ext:ExtensionContent/sac:AdditionalInformation'
|
114
115
|
additional_info = @parsed_xml.xpath(tag)
|
115
116
|
assert additional_info.count.positive?
|
116
117
|
assert_equal additional_info.first.children.count, 1
|
@@ -123,16 +124,16 @@ test 'has total tag' do
|
|
123
124
|
assert total.count.positive?
|
124
125
|
end
|
125
126
|
|
126
|
-
test '#
|
127
|
+
test '#calculate_taxes_totals' do
|
127
128
|
tax = FactoryBot.build(:tax, amount: 15)
|
128
129
|
invoice = FactoryBot.build(:invoice)
|
129
130
|
2.times do
|
130
|
-
invoice.
|
131
|
+
invoice.lines << FactoryBot.build(:item, taxes: [tax])
|
131
132
|
end
|
132
|
-
invoice.
|
133
|
-
|
134
|
-
assert_equal
|
135
|
-
assert_equal
|
133
|
+
invoice.calculate_taxes_totals
|
134
|
+
taxes_totals = invoice.instance_variable_get('@taxes_totals')
|
135
|
+
assert_equal taxes_totals.count, 1
|
136
|
+
assert_equal taxes_totals[:igv], 300
|
136
137
|
end
|
137
138
|
|
138
139
|
test '#get_total_igv_code' do
|
@@ -140,6 +141,14 @@ test '#get_total_igv_code' do
|
|
140
141
|
assert_equal invoice.get_total_igv_code('11'), '1004'
|
141
142
|
assert_equal invoice.get_total_igv_code('15'), '1004'
|
142
143
|
assert_equal invoice.get_total_igv_code('20'), '1003'
|
143
|
-
assert_equal invoice.get_total_igv_code('
|
144
|
+
assert_equal invoice.get_total_igv_code('30'), '1002'
|
145
|
+
assert_equal invoice.get_total_igv_code('32'), '1004'
|
144
146
|
assert invoice.get_total_igv_code('42').nil?
|
145
147
|
end
|
148
|
+
|
149
|
+
test 'could have discounts' do
|
150
|
+
@invoice.discount = 25
|
151
|
+
parsed_xml = Nokogiri::XML(@invoice.xml, &:noblanks)
|
152
|
+
discount_node = parsed_xml.xpath('//sac:AdditionalMonetaryTotal').last
|
153
|
+
assert_equal discount_node.at_xpath('descendant::cbc:ID').content, '2005'
|
154
|
+
end
|
data/test/item_test.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
require_relative 'helper'
|
3
4
|
include SunatInvoice
|
4
5
|
|
@@ -13,7 +14,7 @@ end
|
|
13
14
|
def invoice_setup
|
14
15
|
# add item to invoice in order to setup namespaces
|
15
16
|
invoice = FactoryBot.build(:invoice)
|
16
|
-
invoice.
|
17
|
+
invoice.lines << @item
|
17
18
|
invoice_xml = Nokogiri::XML(invoice.xml, &:noblanks)
|
18
19
|
@item_xml = invoice_xml.xpath('//cac:InvoiceLine')
|
19
20
|
end
|
@@ -104,7 +105,7 @@ scope '#sale_taxes' do
|
|
104
105
|
test 'has sum by tax_type' do
|
105
106
|
@item.taxes << SunatInvoice::Tax.new(amount: 5, tax_type: :isc)
|
106
107
|
assert_equal @item.sale_taxes.count, 2
|
107
|
-
assert_equal @item.sale_taxes.keys, [
|
108
|
+
assert_equal @item.sale_taxes.keys, %i[igv isc]
|
108
109
|
assert_equal @item.sale_taxes.values, [21.6, 10]
|
109
110
|
end
|
110
111
|
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'helper'
|
4
|
+
|
5
|
+
scope 'SunatInvoice::ResponseParser' do
|
6
|
+
test 'invoice success response' do
|
7
|
+
response_xml = ResponseHelper.load('invoice_success.xml')
|
8
|
+
body = ResponseHelper.parse(response_xml)
|
9
|
+
response = SunatInvoice::ResponseParser.new(body, 'invoice')
|
10
|
+
|
11
|
+
assert_equal response.status_code, '0'
|
12
|
+
assert response.message.include?('aceptada')
|
13
|
+
end
|
14
|
+
|
15
|
+
test 'summary success response' do
|
16
|
+
response_xml = ResponseHelper.load('summary_success.xml')
|
17
|
+
body = ResponseHelper.parse(response_xml)
|
18
|
+
response = SunatInvoice::ResponseParser.new(body, 'summary')
|
19
|
+
assert response.ticket.length.positive?
|
20
|
+
end
|
21
|
+
|
22
|
+
test 'get_status response' do
|
23
|
+
response_xml = ResponseHelper.load('ticket_invalid.xml')
|
24
|
+
body = ResponseHelper.parse(response_xml)
|
25
|
+
response = SunatInvoice::ResponseParser.new(body, 'status')
|
26
|
+
assert_equal response.message, 'El ticket no existe'
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'nori'
|
4
|
+
|
5
|
+
module ResponseHelper
|
6
|
+
def self.load(file_name)
|
7
|
+
File.read("#{Dir.pwd}/test/fixtures/responses/#{file_name}")
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.parse(response_xml)
|
11
|
+
parser = Nori.new(delete_namespace_attributes: true,
|
12
|
+
convert_tags_to: ->(tag) { tag.snakecase.to_sym },
|
13
|
+
strip_namespaces: true)
|
14
|
+
hash = parser.parse(response_xml)
|
15
|
+
envelope = parser.find(hash, 'Envelope')
|
16
|
+
parser.find(envelope, 'Body')
|
17
|
+
end
|
18
|
+
end
|
@@ -1,6 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module SignatureHelper
|
2
4
|
def self.generate_keys
|
5
|
+
return if exists?('pk_file')
|
6
|
+
|
3
7
|
pk = OpenSSL::PKey::RSA.new 2048
|
8
|
+
cert = generate_certificate(pk)
|
9
|
+
|
10
|
+
cert_dir = "#{File.dirname(__FILE__)}/../certs"
|
11
|
+
Dir.mkdir(cert_dir) unless Dir.exist?(cert_dir)
|
12
|
+
File.open(file('pk_file'), 'w') { |f| f.puts pk.to_pem }
|
13
|
+
File.open(file('cert_file'), 'w') { |f| f.puts cert.to_pem }
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.generate_certificate(pk)
|
4
17
|
name = OpenSSL::X509::Name.parse('CN=example.com/C=EE')
|
5
18
|
cert = OpenSSL::X509::Certificate.new
|
6
19
|
cert.version = 2
|
@@ -11,13 +24,7 @@ module SignatureHelper
|
|
11
24
|
cert.subject = name
|
12
25
|
cert.issuer = name
|
13
26
|
cert.sign pk, OpenSSL::Digest::SHA1.new
|
14
|
-
|
15
|
-
unless exists?('pk_file')
|
16
|
-
cert_dir = "#{File.dirname(__FILE__)}/../certs"
|
17
|
-
Dir.mkdir(cert_dir) unless Dir.exist?(cert_dir)
|
18
|
-
File.open(file('pk_file'), 'w') { |f| f.puts pk.to_pem }
|
19
|
-
File.open(file('cert_file'), 'w') { |f| f.puts cert.to_pem }
|
20
|
-
end
|
27
|
+
cert
|
21
28
|
end
|
22
29
|
|
23
30
|
def self.file(name)
|
@@ -25,6 +32,6 @@ module SignatureHelper
|
|
25
32
|
end
|
26
33
|
|
27
34
|
def self.exists?(name)
|
28
|
-
File.
|
35
|
+
File.exist?(file(name))
|
29
36
|
end
|
30
37
|
end
|
metadata
CHANGED
@@ -1,57 +1,57 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sunat_invoice
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- César Carruitero
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-12-
|
11
|
+
date: 2017-12-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: nokogiri
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: '1.8'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
26
|
+
version: '1.8'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: rubyzip
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '1.
|
33
|
+
version: '1.2'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '1.
|
40
|
+
version: '1.2'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: savon
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version:
|
47
|
+
version: '2.11'
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version:
|
54
|
+
version: '2.11'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: xmldsig
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -136,7 +136,7 @@ dependencies:
|
|
136
136
|
- - "~>"
|
137
137
|
- !ruby/object:Gem::Version
|
138
138
|
version: '0.51'
|
139
|
-
description:
|
139
|
+
description: Generate and send Electronic Invoices to SUNAT
|
140
140
|
email:
|
141
141
|
- cesar@mozilla.pe
|
142
142
|
executables: []
|
@@ -156,21 +156,42 @@ files:
|
|
156
156
|
- lib/sunat_invoice/clients/invoice_client.rb
|
157
157
|
- lib/sunat_invoice/clients/validate_client.rb
|
158
158
|
- lib/sunat_invoice/configuration.rb
|
159
|
+
- lib/sunat_invoice/credit_note.rb
|
160
|
+
- lib/sunat_invoice/credit_note_line.rb
|
159
161
|
- lib/sunat_invoice/customer.rb
|
162
|
+
- lib/sunat_invoice/daily_summary.rb
|
163
|
+
- lib/sunat_invoice/debit_note.rb
|
164
|
+
- lib/sunat_invoice/debit_note_line.rb
|
160
165
|
- lib/sunat_invoice/invoice.rb
|
161
166
|
- lib/sunat_invoice/item.rb
|
167
|
+
- lib/sunat_invoice/line.rb
|
162
168
|
- lib/sunat_invoice/model.rb
|
163
169
|
- lib/sunat_invoice/provider.rb
|
170
|
+
- lib/sunat_invoice/response_parser.rb
|
164
171
|
- lib/sunat_invoice/signature.rb
|
172
|
+
- lib/sunat_invoice/summary_line.rb
|
165
173
|
- lib/sunat_invoice/tax.rb
|
174
|
+
- lib/sunat_invoice/trade_calculations.rb
|
175
|
+
- lib/sunat_invoice/trade_document.rb
|
166
176
|
- lib/sunat_invoice/tributer.rb
|
167
177
|
- lib/sunat_invoice/utils.rb
|
178
|
+
- lib/sunat_invoice/voided.rb
|
179
|
+
- lib/sunat_invoice/voided_line.rb
|
180
|
+
- lib/sunat_invoice/xml_document.rb
|
168
181
|
- sunat_invoice.gemspec
|
182
|
+
- test/credit_note_test.rb
|
183
|
+
- test/daily_summary_test.rb
|
184
|
+
- test/debit_note_test.rb
|
169
185
|
- test/factories.rb
|
186
|
+
- test/fixtures/responses/invoice_success.xml
|
187
|
+
- test/fixtures/responses/summary_success.xml
|
188
|
+
- test/fixtures/responses/ticket_invalid.xml
|
170
189
|
- test/helper.rb
|
171
190
|
- test/invoice_client_test.rb
|
172
191
|
- test/invoice_test.rb
|
173
192
|
- test/item_test.rb
|
193
|
+
- test/response_parser_test.rb
|
194
|
+
- test/support/response_helper.rb
|
174
195
|
- test/support/signature_helper.rb
|
175
196
|
homepage: https://github.com/ccarruitero/sunat_invoice
|
176
197
|
licenses:
|
@@ -195,5 +216,5 @@ rubyforge_project:
|
|
195
216
|
rubygems_version: 2.6.13
|
196
217
|
signing_key:
|
197
218
|
specification_version: 4
|
198
|
-
summary:
|
219
|
+
summary: Ruby gem to use SUNAT Electronic Billing from your app
|
199
220
|
test_files: []
|