mirror of
https://github.com/LaCasemate/fab-manager.git
synced 2025-02-21 15:54:22 +01:00
refactroing wallet service, credit/debit in transaction of db, if have an error we rollback all
This commit is contained in:
parent
56f2ea4172
commit
9ba8e46450
@ -7,4 +7,5 @@ class WalletTransaction < ActiveRecord::Base
|
|||||||
belongs_to :transactable, polymorphic: true
|
belongs_to :transactable, polymorphic: true
|
||||||
|
|
||||||
validates_inclusion_of :transaction_type, in: %w( credit debit )
|
validates_inclusion_of :transaction_type, in: %w( credit debit )
|
||||||
|
validates :user, :wallet, presence: true
|
||||||
end
|
end
|
||||||
|
@ -4,25 +4,36 @@ class WalletService
|
|||||||
@wallet = wallet
|
@wallet = wallet
|
||||||
end
|
end
|
||||||
|
|
||||||
|
## credit an amount to wallet, if credit success then return a wallet transaction and notify to admin
|
||||||
def credit(amount)
|
def credit(amount)
|
||||||
if @wallet.credit(amount)
|
ActiveRecord::Base.transaction do
|
||||||
transaction = WalletTransaction.create(user: @user, wallet: @wallet, transaction_type: 'credit', amount: amount)
|
if @wallet.credit(amount)
|
||||||
|
transaction = WalletTransaction.new(user: @user, wallet: @wallet, transaction_type: 'credit', amount: amount)
|
||||||
NotificationCenter.call type: 'notify_user_wallet_is_credited',
|
if transaction.save
|
||||||
receiver: @wallet.user,
|
NotificationCenter.call type: 'notify_user_wallet_is_credited',
|
||||||
attached_object: transaction
|
receiver: @wallet.user,
|
||||||
NotificationCenter.call type: 'notify_admin_user_wallet_is_credited',
|
attached_object: transaction
|
||||||
receiver: User.admins,
|
NotificationCenter.call type: 'notify_admin_user_wallet_is_credited',
|
||||||
attached_object: transaction
|
receiver: User.admins,
|
||||||
return true
|
attached_object: transaction
|
||||||
|
return transaction
|
||||||
|
end
|
||||||
|
end
|
||||||
|
raise ActiveRecord::Rollback
|
||||||
end
|
end
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
## debit an amount to wallet, if debit success then return a wallet transaction
|
||||||
def debit(amount, transactable)
|
def debit(amount, transactable)
|
||||||
if @wallet.debit(amount)
|
ActiveRecord::Base.transaction do
|
||||||
WalletTransaction.create(user: @user, wallet: @wallet, transaction_type: 'debit', amount: amount, transactable: transactable)
|
if @wallet.debit(amount)
|
||||||
return true
|
transaction = WalletTransaction.new(user: @user, wallet: @wallet, transaction_type: 'debit', amount: amount, transactable: transactable)
|
||||||
|
if transaction.save
|
||||||
|
return transaction
|
||||||
|
end
|
||||||
|
end
|
||||||
|
raise ActiveRecord::Rollback
|
||||||
end
|
end
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
@ -2,7 +2,9 @@ require 'test_helper'
|
|||||||
|
|
||||||
class WalletTransactionTest < ActiveSupport::TestCase
|
class WalletTransactionTest < ActiveSupport::TestCase
|
||||||
test 'transaction type must be credit or debit' do
|
test 'transaction type must be credit or debit' do
|
||||||
transaction = WalletTransaction.new amount: 5
|
@jdupond = User.find_by(username: 'jdupond')
|
||||||
|
@jdupond_wallet = @jdupond.wallet
|
||||||
|
transaction = WalletTransaction.new amount: 5, user: @jdupond, wallet: @jdupond_wallet
|
||||||
transaction.transaction_type = 'credit'
|
transaction.transaction_type = 'credit'
|
||||||
assert transaction.valid?
|
assert transaction.valid?
|
||||||
transaction.transaction_type = 'debit'
|
transaction.transaction_type = 'debit'
|
||||||
|
@ -18,22 +18,45 @@ class WalletServiceTest < ActiveSupport::TestCase
|
|||||||
|
|
||||||
test 'create a credit transaction after credit amount to wallet' do
|
test 'create a credit transaction after credit amount to wallet' do
|
||||||
service = WalletService.new(user: @admin, wallet: @jdupond_wallet)
|
service = WalletService.new(user: @admin, wallet: @jdupond_wallet)
|
||||||
|
expected_amount = @jdupond_wallet.amount + 10
|
||||||
assert_equal 0, @jdupond_wallet.wallet_transactions.count
|
assert_equal 0, @jdupond_wallet.wallet_transactions.count
|
||||||
assert service.credit(10)
|
transaction = service.credit(10)
|
||||||
transaction = @jdupond_wallet.wallet_transactions.first
|
@jdupond_wallet.reload
|
||||||
|
assert transaction
|
||||||
|
assert_equal @jdupond_wallet.amount, expected_amount
|
||||||
assert_equal transaction.transaction_type, 'credit'
|
assert_equal transaction.transaction_type, 'credit'
|
||||||
assert_equal transaction.amount, 10
|
assert_equal transaction.amount, 10
|
||||||
assert_equal transaction.user, @admin
|
assert_equal transaction.user, @admin
|
||||||
assert_equal transaction.wallet, @jdupond_wallet
|
assert_equal transaction.wallet, @jdupond_wallet
|
||||||
end
|
end
|
||||||
|
|
||||||
test 'create a debit transaction after debit amoutn to wallet' do
|
test 'create a debit transaction after debit amount to wallet' do
|
||||||
service = WalletService.new(user: @vlonchamp, wallet: @vlonchamp_wallet)
|
service = WalletService.new(user: @vlonchamp, wallet: @vlonchamp_wallet)
|
||||||
assert service.debit(5, nil)
|
expected_amount = @vlonchamp_wallet.amount - 5
|
||||||
transaction = @vlonchamp_wallet.wallet_transactions.last
|
transaction = service.debit(5, nil)
|
||||||
|
@vlonchamp_wallet.reload
|
||||||
|
assert transaction
|
||||||
|
assert_equal @vlonchamp_wallet.amount, expected_amount
|
||||||
assert_equal transaction.transaction_type, 'debit'
|
assert_equal transaction.transaction_type, 'debit'
|
||||||
assert_equal transaction.amount, 5
|
assert_equal transaction.amount, 5
|
||||||
assert_equal transaction.user, @vlonchamp
|
assert_equal transaction.user, @vlonchamp
|
||||||
assert_equal transaction.wallet, @vlonchamp_wallet
|
assert_equal transaction.wallet, @vlonchamp_wallet
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test 'dont debit amount > wallet amount' do
|
||||||
|
service = WalletService.new(user: @vlonchamp, wallet: @vlonchamp_wallet)
|
||||||
|
expected_amount = @vlonchamp_wallet.amount
|
||||||
|
service.debit(100, nil)
|
||||||
|
@vlonchamp_wallet.reload
|
||||||
|
assert_equal @vlonchamp_wallet.amount, expected_amount
|
||||||
|
end
|
||||||
|
|
||||||
|
test 'rollback debited amount if has an error when create wallet transaction' do
|
||||||
|
service = WalletService.new(wallet: @vlonchamp_wallet)
|
||||||
|
expected_amount = @vlonchamp_wallet.amount
|
||||||
|
transaction = service.debit(5, nil)
|
||||||
|
@vlonchamp_wallet.reload
|
||||||
|
assert_equal @vlonchamp_wallet.amount, expected_amount
|
||||||
|
assert_not transaction
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
Loading…
x
Reference in New Issue
Block a user