customer.rb

 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