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