Troubleshoot invoice not paid in billing system

This commit is contained in:
Sergei Tsõganov 2022-08-11 10:34:34 +03:00
parent e86dae7eea
commit 91c471049a
5 changed files with 196 additions and 172 deletions

View file

@ -1,8 +1,16 @@
module EisBilling
class LhvConnectTransactionsController < EisBilling::BaseController
def create
if params['_json'].nil? || params['_json'].empty?
render json: { message: 'MISSING PARAMS' }, status: :unprocessable_entity
return
end
bank_statement = BankStatement.create(bank_code: Setting.registry_bank_code,
iban: Setting.registry_iban)
params['_json'].each do |incoming_transaction|
process_transactions(incoming_transaction)
process_transactions(incoming_transaction, bank_statement)
end
render status: :ok, json: { message: 'RECEIVED', params: params }
@ -10,19 +18,13 @@ module EisBilling
private
def process_transactions(incoming_transaction)
def process_transactions(incoming_transaction, bank_statement)
logger.info 'Got incoming transactions'
logger.info incoming_transaction
bank_statement = BankStatement.new(bank_code: Setting.registry_bank_code,
iban: Setting.registry_iban)
bank_statement_transaction(bank_statement: bank_statement, incoming_transaction: incoming_transaction)
end
def bank_statement_transaction(bank_statement:, incoming_transaction:)
ActiveRecord::Base.transaction do
bank_statement.save!
transaction = create_transaction(incoming_transaction: incoming_transaction, bank_statement: bank_statement)
transaction = bank_statement.bank_transactions
.create!(transaction_attributes(incoming_transaction))
next if transaction.registrar.blank?
@ -35,14 +37,14 @@ module EisBilling
transaction.autobind_invoice
end
def create_transaction(incoming_transaction:, bank_statement:)
transaction_attributes = { sum: incoming_transaction['amount'],
def transaction_attributes(incoming_transaction)
{
sum: incoming_transaction['amount'],
currency: incoming_transaction['currency'],
paid_at: incoming_transaction['date'],
reference_no: incoming_transaction['payment_reference_number'],
description: incoming_transaction['payment_description'] }
bank_statement.bank_transactions.create!(transaction_attributes)
description: incoming_transaction['payment_description'],
}
end
end
end

View file

@ -33,10 +33,10 @@ class BankTransaction < ApplicationRecord
return unless autobindable?
channel = manual ? 'admin_payment' : 'system_payment'
create_internal_payment_record(channel: channel, invoice: invoice, registrar: registrar)
create_internal_payment_record(invoice: invoice, registrar: registrar, channel: channel)
end
def create_internal_payment_record(channel: nil, invoice:, registrar:)
def create_internal_payment_record(invoice:, registrar:, channel: nil)
if channel.nil?
create_activity(invoice.buyer, invoice)
return
@ -46,10 +46,17 @@ class BankTransaction < ApplicationRecord
payment_order.save!
if create_activity(registrar, invoice)
status = 'paid'
payment_order.paid!
else
payment_order.update(notes: 'Failed to create activity', status: 'failed')
status = 'failed'
payment_order.update(notes: 'Failed to create activity', status: status)
end
return unless Feature.billing_system_integrated?
EisBilling::SendInvoiceStatus.send_info(invoice_number: invoice.number,
status: status)
end
def bind_invoice(invoice_no, manual: false)
@ -62,8 +69,8 @@ class BankTransaction < ApplicationRecord
validate_invoice_data(invoice)
return if errors.any?
create_internal_payment_record(channel: (manual ? 'admin_payment' : nil), invoice: invoice,
registrar: invoice.buyer)
create_internal_payment_record(invoice: invoice, registrar: invoice.buyer,
channel: (manual ? 'admin_payment' : nil))
end
def validate_invoice_data(invoice)

View file

@ -8,36 +8,36 @@ class LhvConnectTransactionsIntegrationTest < ApplicationIntegrationTest
end
def test_should_saved_transaction_data
if Feature.billing_system_integrated?
return unless Feature.billing_system_integrated?
test_transaction_1 = OpenStruct.new(amount: 0.1,
currency: 'EUR',
date: Time.zone.today,
payment_reference_number: '2199812',
payment_description: "description 2199812")
payment_description: 'description 2199812')
test_transaction_2 = OpenStruct.new(amount: 0.1,
currency: 'EUR',
date: Time.zone.today,
payment_reference_number: '2199813',
payment_description: "description 2199813")
payment_description: 'description 2199813')
test_transaction_3 = OpenStruct.new(amount: 0.1,
currency: 'EUR',
date: Time.zone.today,
payment_reference_number: '2199814',
payment_description: "description 2199814")
payment_description: 'description 2199814')
lhv_transactions = []
lhv_transactions << test_transaction_1
lhv_transactions << test_transaction_2
lhv_transactions << test_transaction_3
assert_difference 'BankStatement.count', 3 do
assert_difference 'BankStatement.count', 1 do
assert_difference 'BankTransaction.count', 3 do
post eis_billing_lhv_connect_transactions_path, params: { "_json" => JSON.parse(lhv_transactions.to_json) },
post eis_billing_lhv_connect_transactions_path, params: { '_json' => JSON.parse(lhv_transactions.to_json) },
headers: { 'HTTP_COOKIE' => 'session=api_bestnames' }
end
end
end
end
end

View file

@ -4,6 +4,10 @@ class BankTransactionTest < ActiveSupport::TestCase
setup do
@registrar = registrars(:bestnames)
@invoice = invoices(:one)
if Feature.billing_system_integrated?
stub_request(:post, 'https://eis_billing_system:3000/api/v1/invoice_generator/invoice_status')
.to_return(status: 200, body: '', headers: {})
end
end
def test_matches_against_invoice_nubmber_and_reference_number
@ -16,10 +20,11 @@ class BankTransactionTest < ActiveSupport::TestCase
end
def test_binds_if_this_sum_invoice_already_present
if Feature.billing_system_integrated?
return unless Feature.billing_system_integrated?
invoice_n = Invoice.order(number: :desc).last.number
stub_request(:post, "https://eis_billing_system:3000/api/v1/invoice_generator/invoice_number_generator").
to_return(status: 200, body: "{\"invoice_number\":\"#{invoice_n + 3}\"}", headers: {})
stub_request(:post, 'https://eis_billing_system:3000/api/v1/invoice_generator/invoice_number_generator')
.to_return(status: 200, body: "{\"invoice_number\":\"#{invoice_n + 3}\"}", headers: {})
create_payable_invoice(number: '2222', total: 10, reference_no: '1234567')
another_invoice = @invoice.dup
another_invoice.save(validate: false)
@ -42,18 +47,17 @@ class BankTransactionTest < ActiveSupport::TestCase
transaction.autobind_invoice
end
end
end
def test_binds_if_this_sum_cancelled_invoice_already_present
if Feature.billing_system_integrated?
return unless Feature.billing_system_integrated?
invoice_n = Invoice.order(number: :desc).last.number
stub_request(:post, "https://eis_billing_system:3000/api/v1/invoice_generator/invoice_number_generator").
to_return(status: 200, body: "{\"invoice_number\":\"#{invoice_n + 3}\"}", headers: {})
stub_request(:post, 'https://eis_billing_system:3000/api/v1/invoice_generator/invoice_number_generator')
.to_return(status: 200, body: "{\"invoice_number\":\"#{invoice_n + 3}\"}", headers: {})
create_payable_invoice(number: '2222', total: 10, reference_no: '1234567')
another_invoice = @invoice.dup
another_invoice.save(validate: false)
another_item = @invoice.items.first.dup
another_item.invoice = another_invoice
@ -68,13 +72,13 @@ class BankTransactionTest < ActiveSupport::TestCase
transaction.autobind_invoice
end
end
end
def test_marks_the_first_one_as_paid_if_same_sum
if Feature.billing_system_integrated?
return unless Feature.billing_system_integrated?
invoice_n = Invoice.order(number: :desc).last.number
stub_request(:post, "https://eis_billing_system:3000/api/v1/invoice_generator/invoice_number_generator").
to_return(status: 200, body: "{\"invoice_number\":\"#{invoice_n + 3}\"}", headers: {})
stub_request(:post, 'https://eis_billing_system:3000/api/v1/invoice_generator/invoice_number_generator')
.to_return(status: 200, body: "{\"invoice_number\":\"#{invoice_n + 3}\"}", headers: {})
create_payable_invoice(number: '2222', total: 10, reference_no: '1234567')
another_invoice = @invoice.dup
another_invoice.save(validate: false)
@ -97,7 +101,6 @@ class BankTransactionTest < ActiveSupport::TestCase
assert(@invoice.paid?)
assert_not(another_invoice.paid?)
end
end
def test_matches_against_invoice_nubmber_and_reference_number_in_description
create_payable_invoice(number: '2222', total: 10, reference_no: '1234567')
@ -192,7 +195,7 @@ class BankTransactionTest < ActiveSupport::TestCase
def test_parsed_ref_no_returns_nil_if_ref_not_found
statement = BankTransaction.new
statement.description = "all invalid 12 123 55 77777 --"
statement.description = 'all invalid 12 123 55 77777 --'
assert_nil statement.parsed_ref_number
end
@ -208,6 +211,7 @@ class BankTransactionTest < ActiveSupport::TestCase
transaction.bind_invoice('2222')
end
end
private
def create_payable_invoice(attributes)

View file

@ -30,6 +30,11 @@ class ProcessPaymentsTaskTest < ActiveJob::TestCase
[message]
end
end
if Feature.billing_system_integrated?
stub_request(:post, 'https://eis_billing_system:3000/api/v1/invoice_generator/invoice_status')
.to_return(status: 200, body: '', headers: {})
end
end
def test_not_raises_error_if_bad_reference
@ -63,7 +68,8 @@ class ProcessPaymentsTaskTest < ActiveJob::TestCase
def test_cannot_create_new_invoice_if_transaction_binded_to_paid_invoice
assert_not @invoice.paid?
@account_activity.update(activity_type: "add_credit", bank_transaction: nil, created_at: Time.zone.today - 1.day, creator_str: 'AdminUser')
@account_activity.update(activity_type: 'add_credit', bank_transaction: nil,
created_at: Time.zone.today - 1.day, creator_str: 'AdminUser')
@invoice.update(account_activity: @account_activity, total: @payment_amount)
assert @invoice.paid?
@ -77,26 +83,28 @@ class ProcessPaymentsTaskTest < ActiveJob::TestCase
end
def test_if_invoice_is_overdue_than_48_hours
if Feature.billing_system_integrated?
return unless Feature.billing_system_integrated?
invoice_n = Invoice.order(number: :desc).last.number
Spy.on_instance_method(SendEInvoiceTwoJob, :perform_now).and_return(true)
stub_request(:post, "https://eis_billing_system:3000/api/v1/e_invoice/e_invoice").
to_return(status: 200, body: "", headers: {})
stub_request(:post, 'https://eis_billing_system:3000/api/v1/e_invoice/e_invoice')
.to_return(status: 200, body: '', headers: {})
stub_request(:put, "https://registry:3000/eis_billing/e_invoice_response").
to_return(status: 200, body: "{\"invoice_number\":\"#{invoice_n + 3}\"}, {\"date\":\"#{Time.zone.now-10.minutes}\"}", headers: {})
stub_request(:put, 'https://registry:3000/eis_billing/e_invoice_response')
.to_return(status: 200, body: "{\"invoice_number\":\"#{invoice_n + 3}\"}, {\"date\":\"#{Time.zone.now-10.minutes}\"}", headers: {})
stub_request(:post, "https://eis_billing_system:3000/api/v1/invoice_generator/invoice_number_generator").
to_return(status: 200, body: "{\"invoice_number\":\"#{invoice_n + 3}\"}", headers: {})
stub_request(:post, 'https://eis_billing_system:3000/api/v1/invoice_generator/invoice_number_generator')
.to_return(status: 200, body: "{\"invoice_number\":\"#{invoice_n + 3}\"}", headers: {})
stub_request(:post, "https://eis_billing_system:3000/api/v1/invoice_generator/invoice_generator").
to_return(status: 200, body: "{\"everypay_link\":\"http://link.test\"}", headers: {})
stub_request(:post, 'https://eis_billing_system:3000/api/v1/invoice_generator/invoice_generator')
.to_return(status: 200, body: "{\"everypay_link\":\"http://link.test\"}", headers: {})
assert_not @invoice.paid?
@account_activity.update(activity_type: "add_credit", bank_transaction: nil, created_at: Time.zone.today - 3.days, creator_str: 'AdminUser')
@account_activity.update(activity_type: 'add_credit', bank_transaction: nil,
created_at: Time.zone.today - 3.days, creator_str: 'AdminUser')
@invoice.update(account_activity: @account_activity, total: @payment_amount)
assert @invoice.paid?
@ -106,7 +114,6 @@ class ProcessPaymentsTaskTest < ActiveJob::TestCase
end
end
end
end
def test_doubles_are_valid
assert Lhv::ConnectApi.method_defined?(:credit_debit_notification_messages)
@ -162,21 +169,24 @@ class ProcessPaymentsTaskTest < ActiveJob::TestCase
end
def test_credits_registrar_athout_invoice_beforehand
if Feature.billing_system_integrated?
invoice_n = Invoice.order(number: :desc).last.number
stub_request(:post, "https://eis_billing_system:3000/api/v1/invoice_generator/invoice_number_generator").
to_return(status: 200, body: "{\"invoice_number\":\"#{invoice_n + 3}\"}")
return unless Feature.billing_system_integrated?
stub_request(:post, "https://eis_billing_system:3000/api/v1/invoice_generator/invoice_generator").
to_return(status: 200, body: "{\"everypay_link\":\"http://link.test\"}", headers: {})
invoice_n = Invoice.order(number: :desc).last.number
stub_request(:post, 'https://eis_billing_system:3000/api/v1/invoice_generator/invoice_number_generator')
.to_return(status: 200, body: "{\"invoice_number\":\"#{invoice_n + 3}\"}")
stub_request(:post, 'https://eis_billing_system:3000/api/v1/invoice_generator/invoice_generator')
.to_return(status: 200, body: "{\"everypay_link\":\"http://link.test\"}", headers: {})
Spy.on_instance_method(SendEInvoiceTwoJob, :perform_now).and_return(true)
stub_request(:post, "https://eis_billing_system:3000/api/v1/e_invoice/e_invoice").
to_return(status: 200, body: "", headers: {})
stub_request(:post, 'https://eis_billing_system:3000/api/v1/e_invoice/e_invoice')
.to_return(status: 200, body: '', headers: {})
stub_request(:put, "https://registry:3000/eis_billing/e_invoice_response").
to_return(status: 200, body: "{\"invoice_number\":\"#{invoice_n + 3}\"}, {\"date\":\"#{Time.zone.now-10.minutes}\"}", headers: {})
stub_request(:put, 'https://registry:3000/eis_billing/e_invoice_response')
.to_return(status: 200,
body: "{\"invoice_number\":\"#{invoice_n + 3}\"}, {\"date\":\"#{Time.zone.now-10.minutes}\"}",
headers: {})
registrar = registrars(:bestnames)
@ -188,7 +198,6 @@ class ProcessPaymentsTaskTest < ActiveJob::TestCase
run_task
end
end
end
def test_topup_creates_invoice_with_total_of_transactioned_amount
registrar = registrars(:bestnames)
@ -198,19 +207,22 @@ class ProcessPaymentsTaskTest < ActiveJob::TestCase
end
def test_topup_creates_invoice_and_send_it_as_paid
if Feature.billing_system_integrated?
stub_request(:post, "https://eis_billing_system:3000/api/v1/e_invoice/e_invoice").
to_return(status: 200, body: "", headers: {})
return unless Feature.billing_system_integrated?
stub_request(:post, 'https://eis_billing_system:3000/api/v1/e_invoice/e_invoice')
.to_return(status: 200, body: '', headers: {})
invoice_n = Invoice.order(number: :desc).last.number
stub_request(:post, "https://eis_billing_system:3000/api/v1/invoice_generator/invoice_number_generator").
to_return(status: 200, body: "{\"invoice_number\":\"#{invoice_n + 3}\"}", headers: {})
stub_request(:post, 'https://eis_billing_system:3000/api/v1/invoice_generator/invoice_number_generator')
.to_return(status: 200, body: "{\"invoice_number\":\"#{invoice_n + 3}\"}", headers: {})
stub_request(:post, "https://eis_billing_system:3000/api/v1/invoice_generator/invoice_generator").
to_return(status: 200, body: "{\"everypay_link\":\"http://link.test\"}", headers: {})
stub_request(:post, 'https://eis_billing_system:3000/api/v1/invoice_generator/invoice_generator')
.to_return(status: 200, body: "{\"everypay_link\":\"http://link.test\"}", headers: {})
stub_request(:put, "https://registry:3000/eis_billing/e_invoice_response").
to_return(status: 200, body: "{\"invoice_number\":\"#{invoice_n + 3}\"}, {\"date\":\"#{Time.zone.now-10.minutes}\"}", headers: {})
stub_request(:put, 'https://registry:3000/eis_billing/e_invoice_response')
.to_return(status: 200,
body: "{\"invoice_number\":\"#{invoice_n + 3}\"}, {\"date\":\"#{Time.zone.now - 10.minutes}\"}",
headers: {})
registrar = registrars(:bestnames)
@invoice.payment_orders.destroy_all
@ -227,12 +239,11 @@ class ProcessPaymentsTaskTest < ActiveJob::TestCase
pdf_source = Invoice::PdfGenerator.new(invoice)
pdf_source.send(:invoice_html).include?('Receipt date')
email= ActionMailer::Base.deliveries.last
email = ActionMailer::Base.deliveries.last
assert email.subject.include?('already paid')
assert_equal 0.1, registrar.invoices.last.total
end
end
def test_output
assert_output "Transactions processed: 1\n" do