Merge pull request #1510 from internetee/1509-resend-e-invoices

Add idempotent Que job with retries for e-invoice sending
This commit is contained in:
Timo Võhmar 2020-02-20 19:39:59 +02:00 committed by GitHub
commit 00e5885922
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 108 additions and 5 deletions

View file

@ -0,0 +1,43 @@
class SendEInvoiceJob < Que::Job
def run(invoice_id)
invoice = run_condition(Invoice.find_by(id: invoice_id))
invoice.to_e_invoice.deliver
ActiveRecord::Base.transaction do
invoice.update(e_invoice_sent_at: Time.zone.now)
log_success(invoice)
destroy
end
rescue StandardError => e
log_error(invoice: invoice, error: e)
raise e
end
private
def run_condition(invoice)
destroy unless invoice
destroy if invoice.do_not_send_e_invoice?
invoice
end
def log_success(invoice)
id = invoice.try(:id) || invoice
message = "E-Invoice for an invoice with ID # #{id} was sent successfully"
logger.info message
end
def log_error(invoice:, error:)
id = invoice.try(:id) || invoice
message = <<~TEXT.squish
There was an error sending e-invoice for invoice with ID # #{id}.
The error message was the following: #{error}
This job will retry.
TEXT
logger.error message
end
def logger
Rails.logger
end
end

View file

@ -102,6 +102,14 @@ class Invoice < ApplicationRecord
generator.generate
end
def do_not_send_e_invoice?
e_invoice_sent? || cancelled? || paid?
end
def e_invoice_sent?
e_invoice_sent_at.present?
end
private
def apply_default_buyer_vat_no
@ -111,4 +119,4 @@ class Invoice < ApplicationRecord
def calculate_total
self.total = subtotal + vat_amount
end
end
end

View file

@ -99,9 +99,7 @@ class Registrar < ApplicationRecord
}
]
)
e_invoice = invoice.to_e_invoice
e_invoice.deliver
SendEInvoiceJob.enqueue(invoice.id)
invoice
end

View file

@ -0,0 +1,5 @@
class AddEInvoiceSentAtToInvoice < ActiveRecord::Migration[5.0]
def change
add_column :invoices, :e_invoice_sent_at, :datetime
end
end

View file

@ -886,6 +886,7 @@ CREATE TABLE public.invoices (
in_directo boolean DEFAULT false,
buyer_vat_no character varying,
issue_date date NOT NULL,
e_invoice_sent_at timestamp without time zone,
CONSTRAINT invoices_due_date_is_not_before_issue_date CHECK ((due_date >= issue_date))
);
@ -4339,6 +4340,7 @@ INSERT INTO "schema_migrations" (version) VALUES
('20191212133136'),
('20191227110904'),
('20200113091254'),
('20200115102202');
('20200115102202'),
('20200204103125');

View file

@ -0,0 +1,47 @@
require 'test_helper'
class SendEInvoiceJobTest < ActiveSupport::TestCase
def teardown
EInvoice.provider = EInvoice::Providers::TestProvider.new
EInvoice::Providers::TestProvider.deliveries.clear
end
def test_if_invoice_is_sended
@invoice = invoices(:one)
EInvoice.provider = EInvoice::Providers::TestProvider.new
EInvoice::Providers::TestProvider.deliveries.clear
assert_nothing_raised do
SendEInvoiceJob.enqueue(@invoice.id)
end
@invoice.reload
assert_not @invoice.e_invoice_sent_at.blank?
assert_equal 1, EInvoice::Providers::TestProvider.deliveries.count
end
def test_if_invoice_sending_retries
@invoice = invoices(:one)
provider_config = { password: nil,
test_mode: true }
EInvoice.provider = EInvoice::Providers::OmnivaProvider.new(provider_config)
stub_request(:get, "https://testfinance.post.ee/finance/erp/erpServices.wsdl").to_timeout
assert_raise HTTPClient::TimeoutError do
SendEInvoiceJob.enqueue(@invoice.id)
end
assert @invoicee_invoice_sent_at.blank?
EInvoice.provider = EInvoice::Providers::TestProvider.new
EInvoice::Providers::TestProvider.deliveries.clear
assert_nothing_raised do
SendEInvoiceJob.enqueue(@invoice.id)
end
@invoice.reload
assert_not @invoice.e_invoice_sent_at.blank?
assert_equal 1, EInvoice::Providers::TestProvider.deliveries.count
end
end