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	def set_declines(num)
46		if num.positive?
47			REDIS.set("jmp_pay_decline-#{@customer_id}", num)
48		else
49			REDIS.del("jmp_pay_decline-#{@customer_id}")
50		end
51	end
52
53	class TransactionInfo
54		value_semantics do
55			transaction_id String
56			created_at Time
57			amount BigDecimal
58			note String, coerce: ->(x) { x || "" }
59		end
60
61		def formatted_amount
62			"$%.4f" % amount
63		end
64	end
65
66	TRANSACTIONS_SQL = <<~SQL
67		SELECT
68			transaction_id,
69			created_at,
70			amount,
71			note
72		FROM transactions
73		WHERE customer_id = $1
74		ORDER BY created_at;
75	SQL
76
77	def transactions
78		txns = DB.query_defer(TRANSACTIONS_SQL, [@customer_id])
79
80		txns.then do |rows|
81			rows.map { |row|
82				TransactionInfo.new(**row.transform_keys(&:to_sym))
83			}
84		end
85	end
86end