added state machine for invoice

This commit is contained in:
olegphenomenon 2023-02-07 11:05:40 +02:00
parent c9ed31771b
commit a4bf967e1d
3 changed files with 83 additions and 34 deletions

View file

@ -9,8 +9,9 @@ module EisBilling
before_action :load_invoice, only: :update before_action :load_invoice, only: :update
def update def update
if @invoice.update(modified_params) && payment_orders_handler # 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: { render json: {
message: 'Invoice data was successfully updated', message: 'Invoice data was successfully updated',
}, status: :ok }, status: :ok
@ -25,41 +26,41 @@ module EisBilling
private private
def payment_orders_handler # def payment_orders_handler
return false if @invoice.cancelled? && status.paid? || @invoice.cancelled? && status.issued? # return false if @invoice.cancelled? && status.paid? || @invoice.cancelled? && status.issued?
return false if @invoice.paid? && (status.failed? || status.cancelled?) # return false if @invoice.paid? && (status.failed? || status.cancelled?)
case # case
when @invoice.paid? && status.paid? # when @invoice.paid? && status.paid?
true # true
when @invoice.unpaid? && status.issued? # when @invoice.unpaid? && status.issued?
true # true
when @invoice.cancelled? && (status.cancelled? || status.failed?) # when @invoice.cancelled? && (status.cancelled? || status.failed?)
true # true
when status.issued? # when status.issued?
@invoice.cancel_manualy # @invoice.cancel_manualy
when status.paid? # when status.paid?
@invoice.autobind_manually # @invoice.autobind_manually
else # else
@invoice.cancel # @invoice.cancel
end # end
end # end
def status # def status
status = case params[:status] # status = case params[:status]
when 'paid' # when 'paid'
'paid' # 'paid'
when 'cancelled' # when 'cancelled'
'cancelled' # 'cancelled'
when 'failed' # when 'failed'
'failed' # 'failed'
else # else
'unpaid' # 'unpaid'
end # end
Struct.new(:paid?, :cancelled?, :issued?, :failed?) # Struct.new(:paid?, :cancelled?, :issued?, :failed?)
.new(status == PAID, status == CANCELLED, status == ISSUED, status == FAILED) # .new(status == PAID, status == CANCELLED, status == ISSUED, status == FAILED)
end # end
def load_invoice def load_invoice
@invoice = Invoice.find_by(number: params[:invoice][:invoice_number]) @invoice = Invoice.find_by(number: params[:invoice][:invoice_number])

View file

@ -0,0 +1,44 @@
# enum status: %i[unpaid paid cancelled failed]
class InvoiceStateMachine
attr_reader :invoice, :status
def initialize(invoice:, status:)
@invoice = invoice
@status = status.to_sym
end
def call
case status
when :paid
mark_as_paid
when :cancelled
mark_as_cancel
when :unpaid
mark_as_unpaid
else
raise "Inavalid state #{invoice.status}"
end
end
private
def mark_as_paid
raise "Inavalid state #{invoice.status}" unless invoice.unpaid? || invoice.paid?
invoice.autobind_manually
end
def mark_as_cancel
# Paid invoice cannot be cancelled?
raise "Inavalid state #{invoice.status}" unless invoice.cancellable? || invoice.cancelled?
invoice.cancel
end
def mark_as_unpaid
raise "Inavalid state #{invoice.status}" unless invoice.paid? && invoice.payment_orders.present? || invoice.unpaid?
invoice.cancel_manualy
end
end

View file

@ -30,6 +30,10 @@ module PaymentOrders
valid_hmac? && valid_amount? && valid_account? valid_hmac? && valid_amount? && valid_account?
end end
def payment_reference?
response['payment_reference'].present?
end
def settled_payment? def settled_payment?
SUCCESSFUL_PAYMENT.include?(response['payment_state']) SUCCESSFUL_PAYMENT.include?(response['payment_state'])
end end