customer_finacials.rb

 1# frozen_string_literal: true
 2
 3class CustomerFinancials
 4	def initialize(customer_id)
 5		@customer_id = customer_id
 6	end
 7
 8	def payment_methods
 9		EMPromise.all([
10			BRAINTREE
11				.customer
12				.find(@customer_id)
13				.catch { OpenStruct.new(payment_methods: []) },
14			REDIS.smembers("block_credit_cards")
15		]).then { |(braintree, badcards)| PaymentMethods.for(braintree, badcards) }
16	end
17
18	def btc_addresses
19		REDIS.smembers("jmp_customer_btc_addresses-#{@customer_id}")
20	end
21
22	def add_btc_address
23		REDIS.spopsadd([
24			"jmp_available_btc_addresses",
25			"jmp_customer_btc_addresses-#{@customer_id}"
26		]).then do |addr|
27			ELECTRUM.notify(
28				addr,
29				CONFIG[:electrum_notify_url].call(addr, @customer_id)
30			)
31			addr
32		end
33	end
34
35	def declines
36		REDIS.get("jmp_pay_decline-#{@customer_id}").then(&:to_i)
37	end
38
39	def mark_decline
40		REDIS.incr("jmp_pay_decline-#{@customer_id}").then do
41			REDIS.expire("jmp_pay_decline-#{@customer_id}", 60 * 60 * 24)
42		end
43	end
44
45	class TransactionInfo
46		value_semantics do
47			transaction_id String
48			created_at Time
49			amount BigDecimal
50			note String, coerce: ->(x) { x || "" }
51		end
52
53		def formatted_amount
54			"$%.4f" % amount
55		end
56	end
57
58	TRANSACTIONS_SQL = <<~SQL
59		SELECT
60			transaction_id,
61			created_at,
62			amount,
63			note
64		FROM transactions
65		WHERE customer_id = $1
66		ORDER BY created_at;
67	SQL
68
69	def transactions
70		txns = DB.query_defer(TRANSACTIONS_SQL, [@customer_id])
71
72		txns.then do |rows|
73			rows.map { |row|
74				TransactionInfo.new(**row.transform_keys(&:to_sym))
75			}
76		end
77	end
78end