M lib/transaction.rb => lib/transaction.rb +41 -4
@@ 1,5 1,7 @@
# frozen_string_literal: true
+require "bigdecimal"
+
class Transaction
def self.sale(customer, amount:, payment_method: nil)
REDIS.get("jmp_pay_decline-#{customer.customer_id}").then do |declines|
@@ 43,16 45,51 @@ class Transaction
@customer_id = braintree_transaction.customer_details.id
@transaction_id = braintree_transaction.id
@created_at = braintree_transaction.created_at
- @amount = braintree_transaction.amount
+ @amount = BigDecimal.new(braintree_transaction.amount, 4)
end
def insert
+ EM.promise_fiber do
+ DB.transaction do
+ insert_tx
+ insert_bonus
+ end
+ end
+ end
+
+ def bonus
+ return BigDecimal.new(0) if amount <= 15
+ amount *
+ case amount
+ when (15..29.99)
+ 0.01
+ when (30..139.99)
+ 0.03
+ else
+ 0.05
+ end
+ end
+
+protected
+
+ def insert_tx
params = [@customer_id, @transaction_id, @created_at, @amount]
- DB.exec_defer(<<~SQL, params)
+ DB.exec(<<~SQL, params)
+ INSERT INTO transactions
+ (customer_id, transaction_id, created_at, amount, note)
+ VALUES
+ ($1, $2, $3, $4, 'Credit card payment')
+ SQL
+ end
+
+ def insert_bonus
+ return if bonus <= 0
+ params = [@customer_id, "bonus_for_#{@transaction_id}", @created_at, bonus]
+ DB.exec(<<~SQL, params)
INSERT INTO transactions
- (customer_id, transaction_id, created_at, amount)
+ (customer_id, transaction_id, created_at, amount, note)
VALUES
- ($1, $2, $3, $4)
+ ($1, $2, $3, $4, 'Credit card payment bonus')
SQL
end
end
M test/test_transaction.rb => test/test_transaction.rb +36 -3
@@ 14,7 14,7 @@ class TransactionTest < Minitest::Test
customer_details: OpenStruct.new(id: "customer"),
id: "transaction",
created_at: Time.at(0),
- amount: 123
+ amount: 12
)
def test_sale_fails
@@ 85,15 85,48 @@ class TransactionTest < Minitest::Test
em :test_sale
def test_insert
+ Transaction::DB.expect(:transaction, []) do |&block|
+ block.call
+ true
+ end
Transaction::DB.expect(
- :exec_defer,
+ :exec,
EMPromise.resolve(nil),
[
String,
- ["customer", "transaction", Time.at(0), 123]
+ ["customer", "transaction", Time.at(0), 12]
]
)
Transaction.new(FAKE_BRAINTREE_TRANSACTION).insert.sync
+ Transaction::DB.verify
end
em :test_insert
+
+ def test_insert_with_bonus
+ Transaction::DB.expect(:transaction, []) do |&block|
+ block.call
+ true
+ end
+ Transaction::DB.expect(
+ :exec,
+ EMPromise.resolve(nil),
+ [
+ String,
+ ["customer", "transaction", Time.at(0), 100]
+ ]
+ )
+ Transaction::DB.expect(
+ :exec,
+ EMPromise.resolve(nil),
+ [
+ String,
+ ["customer", "bonus_for_transaction", Time.at(0), 3]
+ ]
+ )
+ tx = FAKE_BRAINTREE_TRANSACTION.dup
+ tx.amount = 100
+ Transaction.new(tx).insert.sync
+ Transaction::DB.verify
+ end
+ em :test_insert_with_bonus
end