sunat_invoice 0.0.1 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- 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: []
|