customer.rb

 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