customer.rb

 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