Skip to content

Commit 985d549

Browse files
authored
Merge pull request #157 from internetee/e_invoice-retry-job-when-error-occur
implement retry functional when e-invoice job failed
2 parents 153f650 + ccb9087 commit 985d549

File tree

4 files changed

+180
-30
lines changed

4 files changed

+180
-30
lines changed

Gemfile.lock

Lines changed: 36 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -114,20 +114,21 @@ GEM
114114
mutex_m
115115
securerandom (>= 0.3)
116116
tzinfo (~> 2.0)
117-
addressable (2.8.5)
118-
public_suffix (>= 2.0.2, < 6.0)
117+
addressable (2.8.7)
118+
public_suffix (>= 2.0.2, < 7.0)
119119
aes_key_wrap (1.1.0)
120120
airbrussh (1.5.0)
121121
sshkit (>= 1.6.1, != 1.7.0)
122-
akami (1.3.1)
122+
akami (1.3.3)
123+
base64
123124
gyoku (>= 0.4.0)
124125
nokogiri
125126
apipie-rails (1.4.2)
126127
actionpack (>= 5.0)
127128
activesupport (>= 5.0)
128129
ast (2.4.2)
129130
attr_required (1.0.1)
130-
base64 (0.2.0)
131+
base64 (0.3.0)
131132
bcrypt (3.1.19)
132133
benchmark (0.4.0)
133134
better_html (2.0.2)
@@ -137,7 +138,7 @@ GEM
137138
erubi (~> 1.4)
138139
parser (>= 2.4)
139140
smart_properties
140-
bigdecimal (3.1.9)
141+
bigdecimal (3.2.2)
141142
bindata (2.5.0)
142143
bootsnap (1.17.0)
143144
msgpack (~> 1.2)
@@ -221,12 +222,14 @@ GEM
221222
railties (>= 5.0.0)
222223
faker (3.2.1)
223224
i18n (>= 1.8.11, < 2)
224-
faraday (2.9.0)
225-
faraday-net_http (>= 2.0, < 3.2)
225+
faraday (2.13.3)
226+
faraday-net_http (>= 2.0, < 3.5)
227+
json
228+
logger
226229
faraday-follow_redirects (0.3.0)
227230
faraday (>= 1, < 3)
228-
faraday-net_http (3.1.0)
229-
net-http
231+
faraday-net_http (3.4.1)
232+
net-http (>= 0.5.0)
230233
ffi (1.16.3)
231234
figaro (1.2.0)
232235
thor (>= 0.14.0, < 2)
@@ -242,8 +245,11 @@ GEM
242245
rails (>= 6.0.0)
243246
stimulus-rails
244247
turbo-rails
245-
httpi (3.0.1)
246-
rack
248+
httpi (4.0.4)
249+
base64
250+
mutex_m
251+
nkf
252+
rack (>= 2.0, < 4)
247253
i18n (1.14.6)
248254
concurrent-ruby (~> 1.0)
249255
i18n-tasks (1.0.13)
@@ -265,7 +271,7 @@ GEM
265271
irb (1.14.1)
266272
rdoc (>= 4.0.0)
267273
reline (>= 0.4.2)
268-
json (2.6.3)
274+
json (2.13.1)
269275
json-jwt (1.16.6)
270276
activesupport (>= 4.2)
271277
aes_key_wrap
@@ -289,15 +295,15 @@ GEM
289295
net-smtp
290296
marcel (1.0.4)
291297
mini_mime (1.1.5)
292-
mini_portile2 (2.8.8)
298+
mini_portile2 (2.8.9)
293299
minitest (5.25.4)
294300
money (6.16.0)
295301
i18n (>= 0.6.4, <= 2)
296302
msgpack (1.7.2)
297303
mutex_m (0.3.0)
298-
net-http (0.4.1)
304+
net-http (0.6.0)
299305
uri
300-
net-imap (0.5.6)
306+
net-imap (0.5.9)
301307
date
302308
net-protocol
303309
net-pop (0.1.2)
@@ -306,16 +312,18 @@ GEM
306312
timeout
307313
net-scp (4.0.0)
308314
net-ssh (>= 2.6.5, < 8.0.0)
309-
net-smtp (0.5.0)
315+
net-smtp (0.5.1)
310316
net-protocol
311317
net-ssh (7.2.0)
312318
nio4r (2.7.4)
313-
nokogiri (1.18.7)
319+
nkf (0.2.0)
320+
nokogiri (1.18.9)
314321
mini_portile2 (~> 2.8.2)
315322
racc (~> 1.4)
316-
nokogiri (1.18.7-x86_64-linux-gnu)
323+
nokogiri (1.18.9-x86_64-linux-gnu)
317324
racc (~> 1.4)
318-
nori (2.6.0)
325+
nori (2.7.1)
326+
bigdecimal
319327
omniauth (2.1.1)
320328
hashie (>= 3.4.6)
321329
rack (>= 2.2.3)
@@ -348,11 +356,11 @@ GEM
348356
activesupport (>= 5.2)
349357
psych (5.2.0)
350358
stringio
351-
public_suffix (5.0.3)
359+
public_suffix (6.0.2)
352360
puma (6.6.0)
353361
nio4r (~> 2.0)
354362
racc (1.8.1)
355-
rack (2.2.13)
363+
rack (2.2.17)
356364
rack-oauth2 (2.2.0)
357365
activesupport
358366
attr_required
@@ -452,15 +460,15 @@ GEM
452460
rubocop (>= 1.33.0, < 2.0)
453461
ruby-progressbar (1.13.0)
454462
rubyzip (2.3.2)
455-
savon (2.14.0)
463+
savon (2.15.1)
456464
akami (~> 1.2)
457465
builder (>= 2.1.2)
458466
gyoku (~> 1.2)
459-
httpi (>= 2.4.5)
467+
httpi (>= 4, < 5)
460468
mail (~> 2.5)
461469
nokogiri (>= 1.8.1)
462470
nori (~> 2.4)
463-
wasabi (~> 3.4)
471+
wasabi (>= 3.7, < 6)
464472
securerandom (0.4.1)
465473
selenium-webdriver (4.10.0)
466474
rexml (~> 3.2, >= 3.2.5)
@@ -496,7 +504,7 @@ GEM
496504
faraday-follow_redirects
497505
terminal-table (3.0.2)
498506
unicode-display_width (>= 1.1.1, < 3)
499-
thor (1.3.2)
507+
thor (1.4.0)
500508
timeout (0.4.3)
501509
turbo-rails (1.5.0)
502510
actionpack (>= 6.0.0)
@@ -513,10 +521,10 @@ GEM
513521
validate_url (1.0.15)
514522
activemodel (>= 3.0.0)
515523
public_suffix
516-
wasabi (3.8.0)
524+
wasabi (5.1.0)
517525
addressable
518-
httpi (~> 3.0)
519-
nokogiri (>= 1.4.2)
526+
faraday (>= 1.9, < 3)
527+
nokogiri (>= 1.13.9)
520528
webdrivers (5.3.1)
521529
nokogiri (~> 1.6)
522530
rubyzip (>= 1.3.0)

app/jobs/send_e_invoice_job.rb

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ class SendEInvoiceJob < ApplicationJob
44
def perform(e_invoice_data)
55
Rails.logger.info "Started to process e-invoice for invoice_id #{e_invoice_data[:invoice_data][:id]}"
66
process(e_invoice_data)
7+
rescue Savon::SOAPFault => e
8+
log_error(invoice: e_invoice_data[:invoice_data][:id], error: e)
9+
retry_job wait: 1.minute, attempts: 3
710
rescue StandardError => e
811
log_error(invoice: e_invoice_data[:invoice_data][:id], error: e)
912
raise e
@@ -19,9 +22,9 @@ def process(e_invoice_data)
1922
message = data.to_hash[:e_invoice_response][:message]
2023

2124
if message.include? 'Success'
22-
EInvoiceResponseSender.send_request(invoice_number: invoice_number,
25+
EInvoiceResponseSender.send_request(invoice_number:,
2326
initiator: e_invoice_data[:initiator])
24-
invoice = Invoice.find_by(invoice_number: invoice_number)
27+
invoice = Invoice.find_by(invoice_number:)
2528
invoice&.update(sent_at_omniva: Time.zone.now)
2629
else
2730
Rails.logger.info 'FAILED IN EINVOICE OMNIVA TRANSFER'

spec/jobs/payment_lhv_connect_job_spec.rb

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,5 +238,105 @@
238238
)
239239
PaymentLhvConnectJob.perform_now
240240
end
241+
242+
it 'should find reference number in end_to_end_id when not found in payment description' do
243+
ref = Billing::ReferenceNo.generate
244+
Reference.create(reference_number: ref, initiator: 'registry')
245+
246+
date = Time.zone.now - 4.hours
247+
params_for_sending = OpenStruct.new(
248+
amount: '10.0',
249+
currency: 'EUR',
250+
date: date,
251+
payment_reference_number: ref,
252+
payment_description: 'Money transfer without reference',
253+
end_to_end_id: ref
254+
)
255+
256+
Lhv::ConnectApi.class_eval do
257+
define_method :credit_debit_notification_messages do
258+
transaction = OpenStruct.new(
259+
amount: '10.0',
260+
currency: 'EUR',
261+
date: date,
262+
payment_reference_number: nil,
263+
payment_description: 'Money transfer without reference',
264+
end_to_end_id: ref
265+
)
266+
message = OpenStruct.new(
267+
bank_account_iban: Setting.registry_bank_account_iban_lhv || 'EE177700771001155322',
268+
credit_transactions: [transaction]
269+
)
270+
[message]
271+
end
272+
end
273+
274+
expect_any_instance_of(PaymentLhvConnectJob).to receive(:send_transactions).with(
275+
params: [params_for_sending],
276+
payment_reference_number: ref
277+
)
278+
PaymentLhvConnectJob.perform_now
279+
end
280+
281+
it 'should not process transaction when end_to_end_id is present but not in database' do
282+
invalid_ref = '12345678'
283+
date = Time.zone.now - 4.hours
284+
285+
Lhv::ConnectApi.class_eval do
286+
define_method :credit_debit_notification_messages do
287+
transaction = OpenStruct.new(
288+
amount: '10.0',
289+
currency: 'EUR',
290+
date: date,
291+
payment_reference_number: nil,
292+
payment_description: 'Money transfer without valid reference',
293+
end_to_end_id: invalid_ref
294+
)
295+
message = OpenStruct.new(
296+
bank_account_iban: Setting.registry_bank_account_iban_lhv || 'EE177700771001155322',
297+
credit_transactions: [transaction]
298+
)
299+
[message]
300+
end
301+
end
302+
303+
expect_any_instance_of(BillingMailer).to receive(:inform_admin).with(
304+
reference_number: invalid_ref,
305+
body: an_instance_of(OpenStruct)
306+
).and_return(double("mailer", deliver_now: true))
307+
308+
expect_any_instance_of(PaymentLhvConnectJob).not_to receive(:send_transactions)
309+
PaymentLhvConnectJob.perform_now
310+
end
311+
312+
it 'should not process transaction when neither payment description nor end_to_end_id contain valid reference' do
313+
date = Time.zone.now - 4.hours
314+
315+
Lhv::ConnectApi.class_eval do
316+
define_method :credit_debit_notification_messages do
317+
transaction = OpenStruct.new(
318+
amount: '10.0',
319+
currency: 'EUR',
320+
date: date,
321+
payment_reference_number: nil,
322+
payment_description: 'Money transfer without any reference',
323+
end_to_end_id: nil
324+
)
325+
message = OpenStruct.new(
326+
bank_account_iban: Setting.registry_bank_account_iban_lhv || 'EE177700771001155322',
327+
credit_transactions: [transaction]
328+
)
329+
[message]
330+
end
331+
end
332+
333+
expect_any_instance_of(BillingMailer).to receive(:inform_admin).with(
334+
reference_number: nil,
335+
body: an_instance_of(OpenStruct)
336+
).and_return(double("mailer", deliver_now: true))
337+
338+
expect_any_instance_of(PaymentLhvConnectJob).not_to receive(:send_transactions)
339+
PaymentLhvConnectJob.perform_now
340+
end
241341
end
242342
end

spec/jobs/send_e_invoice_job_spec.rb

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
require 'rails_helper'
2+
require 'httpi' # HTTPI::Response
3+
require 'nori' # Nori для парсинга SOAP
24

35
RSpec.describe "SendEInvoiceJob", type: :job do
46
let!(:admin) { create(:user) }
@@ -67,5 +69,42 @@
6769

6870
expect { SendEInvoiceJob.perform_now(params) }.to change { ActionMailer::Base.deliveries.count }.by(1)
6971
end
72+
73+
it 'retries the job when Savon::SOAPFault is raised' do
74+
params = {
75+
invoice_data: {
76+
id: '2',
77+
number: invoice.invoice_number,
78+
}
79+
}
80+
81+
fault_xml = <<~XML
82+
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
83+
<soap:Body>
84+
<soap:Fault>
85+
<faultcode>Server</faultcode>
86+
<faultstring>Something went wrong</faultstring>
87+
</soap:Fault>
88+
</soap:Body>
89+
</soap:Envelope>
90+
XML
91+
92+
real_response = HTTPI::Response.new(500, {}, fault_xml)
93+
soap_fault = Savon::SOAPFault.new(real_response, Nori.new)
94+
95+
allow_any_instance_of(SendEInvoiceJob)
96+
.to receive(:process)
97+
.and_raise(soap_fault)
98+
99+
job = SendEInvoiceJob.new
100+
101+
expect(job)
102+
.to receive(:retry_job)
103+
.with(wait: 1.minute, attempts: 3)
104+
105+
# просто запускаем – никаких SOAPFault наружу не уходит
106+
expect { job.perform(params) }.not_to raise_error
107+
end
108+
70109
end
71110
end

0 commit comments

Comments
 (0)