Skip to content

Commit

Permalink
change logic, added tests
Browse files Browse the repository at this point in the history
  • Loading branch information
olegphenomenon committed Feb 7, 2023
1 parent e00e87a commit d28afca
Show file tree
Hide file tree
Showing 5 changed files with 115 additions and 52 deletions.
43 changes: 0 additions & 43 deletions app/controllers/eis_billing/invoices_controller.rb
Original file line number Diff line number Diff line change
@@ -1,15 +1,8 @@
module EisBilling
class InvoicesController < BaseController
TYPE = 'PaymentOrders::EveryPay'.freeze
PAID = 'paid'.freeze
CANCELLED = 'cancelled'.freeze
ISSUED = 'unpaid'.freeze
FAILED = 'failed'.freeze

before_action :load_invoice, only: :update

def update
# if @invoice.update(modified_params) && payment_orders_handler
state = InvoiceStateMachine.new(invoice: @invoice, status: params[:status])
if @invoice.update(modified_params) && state.call
render json: {
Expand All @@ -26,42 +19,6 @@ def update

private

# def payment_orders_handler
# return false if @invoice.cancelled? && status.paid? || @invoice.cancelled? && status.issued?
# return false if @invoice.paid? && (status.failed? || status.cancelled?)

# case
# when @invoice.paid? && status.paid?
# true
# when @invoice.unpaid? && status.issued?
# true
# when @invoice.cancelled? && (status.cancelled? || status.failed?)
# true
# when status.issued?
# @invoice.cancel_manualy
# when status.paid?
# @invoice.autobind_manually
# else
# @invoice.cancel
# end
# end

# def status
# status = case params[:status]
# when 'paid'
# 'paid'
# when 'cancelled'
# 'cancelled'
# when 'failed'
# 'failed'
# else
# 'unpaid'
# end

# Struct.new(:paid?, :cancelled?, :issued?, :failed?)
# .new(status == PAID, status == CANCELLED, status == ISSUED, status == FAILED)
# end

def load_invoice
@invoice = Invoice.find_by(number: params[:invoice][:invoice_number])
return if @invoice.present?
Expand Down
11 changes: 6 additions & 5 deletions app/models/invoice_state_machine.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
# enum status: %i[unpaid paid cancelled failed]

class InvoiceStateMachine
attr_reader :invoice, :status

Expand All @@ -24,21 +22,24 @@ def call
private

def mark_as_paid
return push_error unless invoice.payable? || invoice.paid?
return push_error unless invoice.payable?
return true if invoice.paid?

invoice.autobind_manually
invoice
end

def mark_as_cancel
return push_error unless invoice.cancellable? || invoice.cancelled?
return push_error unless invoice.cancellable?
return true if invoice.cancelled?

invoice.cancel
invoice
end

def mark_as_unpaid
return push_error if invoice.paid? || !invoice.cancellable?
return push_error if invoice.paid? && invoice.payment_orders.last.payment_reference? || invoice.cancelled?
return true unless invoice.paid?

invoice.cancel_manualy
invoice
Expand Down
4 changes: 4 additions & 0 deletions app/models/payment_order.rb
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ def self.supported_method?(name, shortname: false)
false
end

def payment_reference?
response && response['payment_reference'].present?
end

def base_transaction(sum:, paid_at:, buyer_name:)
BankTransaction.new(
description: invoice.order,
Expand Down
4 changes: 0 additions & 4 deletions app/models/payment_orders/every_pay.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,6 @@ def valid_response_from_intermediary?
valid_hmac? && valid_amount? && valid_account?
end

def payment_reference?
response['payment_reference'].present?
end

def settled_payment?
SUCCESSFUL_PAYMENT.include?(response['payment_state'])
end
Expand Down
105 changes: 105 additions & 0 deletions test/models/invoice_state_machinte_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
require 'test_helper'

class InvoiceTest < ActiveSupport::TestCase
include ActionMailer::TestHelper

setup do
@invoice = invoices(:one)
@unpaid = invoices(:unpaid)

stub_request(:post, 'https://eis_billing_system:3000/api/v1/invoice_generator/invoice_status')
.with(
body: '{"invoice_number":2,"status":"paid"}'
)
.to_return(status: 200, body: '', headers: {})
end

def test_unpaid_invoice_can_be_change_status_to_paid
assert !@unpaid.paid?

InvoiceStateMachine.new(invoice: @unpaid, status: 'paid').call
@unpaid.reload

assert @unpaid.paid?
end

def test_no_any_errors_if_invoice_with_unpaid_status_set_again_unpaid
assert !@unpaid.paid?

InvoiceStateMachine.new(invoice: @unpaid, status: 'unpaid').call
@unpaid.reload

assert !@unpaid.paid?
assert @unpaid.errors.empty?
end

def test_only_unpaid_invoice_can_be_cancelled
assert !@unpaid.paid?

InvoiceStateMachine.new(invoice: @unpaid, status: 'cancelled').call
@unpaid.reload

assert @unpaid.cancelled?

assert @invoice.paid?
InvoiceStateMachine.new(invoice: @invoice, status: 'cancelled').call
@invoice.reload

assert_equal @invoice.errors.full_messages.join, 'Inavalid state cancelled'
assert @invoice.errors.present?
end

def test_cancelled_invoiced_cannot_be_unpaid
assert !@unpaid.paid?

InvoiceStateMachine.new(invoice: @unpaid, status: 'cancelled').call
@unpaid.reload

assert @unpaid.cancelled?

InvoiceStateMachine.new(invoice: @unpaid, status: 'unpaid').call
@unpaid.reload

assert @unpaid.cancelled?

assert @unpaid.errors.present?
assert_equal @unpaid.errors.full_messages.join, 'Inavalid state unpaid'
end

def test_if_paid_invoice_not_have_response_from_everypay_it_can_be_unpaid_back
assert !@unpaid.paid?

InvoiceStateMachine.new(invoice: @unpaid, status: 'paid').call
@unpaid.reload

assert @unpaid.paid?
assert_nil @unpaid.payment_orders.last.payment_reference?

InvoiceStateMachine.new(invoice: @unpaid, status: 'unpaid').call
@unpaid.reload

assert !@unpaid.paid?
end

def test_if_paid_invoice_has_response_from_everypay_it_cannot_be_rollback
assert !@unpaid.paid?

InvoiceStateMachine.new(invoice: @unpaid, status: 'paid').call
@unpaid.reload

assert @unpaid.paid?
payment_order = @unpaid.payment_orders.last
payment_order.response = {}
payment_order.response[:payment_reference] = 'responsefromeveryapy'
payment_order.save && payment_order.reload

assert @unpaid.payment_orders.last.payment_reference?

InvoiceStateMachine.new(invoice: @unpaid, status: 'unpaid').call
@unpaid.reload

assert @unpaid.paid?
assert @unpaid.errors.present?
assert_equal @unpaid.errors.full_messages.join, 'Inavalid state unpaid'
end
end

0 comments on commit d28afca

Please sign in to comment.