1# frozen_string_literal: true
2
3require_relative "./payment_methods"
4require_relative "./plan"
5
6class Customer
7 def self.for_jid(jid)
8 REDIS.get("jmp_customer_id-#{jid}").then do |customer_id|
9 raise "No customer id" unless customer_id
10 for_customer_id(customer_id)
11 end
12 end
13
14 def self.for_customer_id(customer_id)
15 result = DB.query_defer(<<~SQL, [customer_id])
16 SELECT COALESCE(balance,0) AS balance, plan_name, expires_at
17 FROM customer_plans LEFT JOIN balances USING (customer_id)
18 WHERE customer_id=$1 LIMIT 1
19 SQL
20 result.then do |rows|
21 new(customer_id, **rows.first&.transform_keys(&:to_sym) || {})
22 end
23 end
24
25 attr_reader :customer_id, :balance
26
27 def initialize(
28 customer_id,
29 plan_name: nil,
30 expires_at: Time.now,
31 balance: BigDecimal.new(0)
32 )
33 @plan = plan_name && Plan.for(plan_name)
34 @expires_at = expires_at
35 @customer_id = customer_id
36 @balance = balance
37 end
38
39 def with_plan(plan_name)
40 self.class.new(
41 @customer_id,
42 balance: @balance,
43 expires_at: @expires_at,
44 plan_name: plan_name
45 )
46 end
47
48 def plan_name
49 @plan.name
50 end
51
52 def currency
53 @plan.currency
54 end
55
56 def merchant_account
57 @plan.merchant_account
58 end
59
60 def payment_methods
61 @payment_methods ||=
62 BRAINTREE
63 .customer
64 .find(@customer_id)
65 .then(PaymentMethods.method(:for_braintree_customer))
66 end
67
68 def active?
69 @plan && @expires_at > Time.now
70 end
71
72 def registered?
73 ibr = IBR.new(:get, CONFIG[:sgx])
74 ibr.from = "customer_#{@customer_id}@#{CONFIG[:component][:jid]}"
75 IQ_MANAGER.write(ibr).catch { nil }.then do |result|
76 result&.respond_to?(:registered?) && result&.registered?
77 end
78 end
79end