~singpolyma/sgx-jmp

2cf86cf6f0dc9c2c5ba296348d8e3a1bd6e6b7c4 — Stephen Paul Weber 3 years ago 33ea52c
Insert bonus when paying by credit card
2 files changed, 77 insertions(+), 7 deletions(-)

M lib/transaction.rb
M test/test_transaction.rb
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