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