diff --git a/lib/transaction.rb b/lib/transaction.rb index 3cc8df6d6af9000fb6fa6b4b884ed85c57e2af8c..0f297cac563d878919f99815af465602d0f6cb26 100644 --- a/lib/transaction.rb +++ b/lib/transaction.rb @@ -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 diff --git a/test/test_transaction.rb b/test/test_transaction.rb index f12944c7cb9e55140b689ad186031dceaf9919b2..443541196b3776f3ab007325aa9d29a32db25ca5 100644 --- a/test/test_transaction.rb +++ b/test/test_transaction.rb @@ -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