~singpolyma/sgx-jmp

ref: 847be4f6375b8cb1a0597d25ee390ad7d0542e0f sgx-jmp/lib/customer.rb -rw-r--r-- 3.0 KiB
847be4f6Stephen Paul Weber Add btc_addresses to Customer 1 year, 1 month ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# frozen_string_literal: true

require "forwardable"

require_relative "./blather_ext"
require_relative "./customer_plan"
require_relative "./customer_usage"
require_relative "./backend_sgx"
require_relative "./ibr"
require_relative "./payment_methods"
require_relative "./plan"
require_relative "./sip_account"

class Customer
	def self.for_jid(jid)
		REDIS.get("jmp_customer_id-#{jid}").then do |customer_id|
			raise "No customer id" unless customer_id
			for_customer_id(customer_id)
		end
	end

	def self.for_customer_id(customer_id)
		result = DB.query_defer(<<~SQL, [customer_id])
			SELECT COALESCE(balance,0) AS balance, plan_name, expires_at
			FROM customer_plans LEFT JOIN balances USING (customer_id)
			WHERE customer_id=$1 LIMIT 1
		SQL
		result.then do |rows|
			new(customer_id, **rows.first&.transform_keys(&:to_sym) || {})
		end
	end

	def self.create(jid)
		BRAINTREE.customer.create.then do |result|
			raise "Braintree customer create failed" unless result.success?
			cid = result.customer.id
			REDIS.msetnx(
				"jmp_customer_id-#{jid}", cid, "jmp_customer_jid-#{cid}", jid
			).then do |redis_result|
				raise "Saving new customer to redis failed" unless redis_result == 1
				new(cid)
			end
		end
	end

	extend Forwardable

	attr_reader :customer_id, :balance
	def_delegators :@plan, :active?, :activate_plan_starting_now, :bill_plan,
	               :currency, :merchant_account, :plan_name
	def_delegators :@sgx, :register!, :registered?
	def_delegator :@usage, :report, :usage_report

	def initialize(
		customer_id,
		plan_name: nil,
		expires_at: Time.now,
		balance: BigDecimal.new(0),
		sgx: BackendSgx.new(customer_id)
	)
		@plan = CustomerPlan.new(
			customer_id,
			plan: plan_name && Plan.for(plan_name),
			expires_at: expires_at
		)
		@usage = CustomerUsage.new(customer_id)
		@customer_id = customer_id
		@balance = balance
		@sgx = sgx
	end

	def with_plan(plan_name)
		self.class.new(
			@customer_id,
			balance: @balance,
			expires_at: expires_at,
			plan_name: plan_name
		)
	end

	def payment_methods
		BRAINTREE
			.customer
			.find(@customer_id)
			.then(PaymentMethods.method(:for_braintree_customer))
	end

	def jid
		@jid ||= REDIS.get("jmp_customer_jid-#{customer_id}").then do |sjid|
			Blather::JID.new(sjid)
		end
	end

	def stanza_to(stanza)
		jid.then do |jid|
			stanza = stanza.dup
			stanza.to = jid.with(resource: stanza.to&.resource)
			stanza.from = stanza.from.with(domain: CONFIG[:component][:jid])
			BLATHER << stanza
		end
	end

	def stanza_from(stanza)
		BLATHER << @sgx.stanza(stanza)
	end

	def sip_account
		SipAccount.find(customer_id)
	end

	def reset_sip_account
		SipAccount::New.new(username: customer_id).put.catch do
			sip_account.then { |acct| acct.with_random_password.put }
		end
	end

	def btc_addresses
		REDIS.smembers("jmp_customer_btc_addresses-#{customer_id}")
	end

	def add_btc_address
		ELECTRUM.createnewaddress.then do |addr|
			REDIS.sadd("jmp_customer_btc_addresses-#{customer_id}", addr).then do
				addr
			end
		end
	end

	protected def_delegator :@plan, :expires_at
end