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