parent_code_repo.rb

 1# frozen_string_literal: true
 2
 3require "multibases"
 4require "securerandom"
 5
 6require_relative "customer"
 7require_relative "trust_level_repo"
 8
 9class ParentCodeRepo
10	def initialize(
11		redis: REDIS,
12		db: DB,
13		trust_level_repo: TrustLevelRepo.new(redis: redis, db: db)
14	)
15		@redis = redis
16		@db = db
17		@trust_level_repo = trust_level_repo
18	end
19
20	def find(code)
21		@redis.hget("jmp_parent_codes", code).then do |parent_id|
22			trust_level_guard(parent_id).then { parent_id }
23		end
24	end
25
26	def find_or_create(customer_id)
27		@redis.get("jmp_customer_parent_code-#{customer_id}").then do |code|
28			next code if code
29
30			code = "p#{Multibases.pack('base32upper', SecureRandom.bytes(4))}"
31			EMPromise.all([
32				@redis.set("jmp_customer_parent_code-#{customer_id}", code),
33				@redis.hset("jmp_parent_codes", code, customer_id)
34			]).then { code }
35		end
36	end
37
38	def existing_subaccounts(parent_id)
39		@db.query_one(<<~SQL, parent_id, default: { c: 0 }).then { |r| r[:c] }
40			SELECT COUNT(*) AS c FROM customer_plans WHERE parent_customer_id=$1
41		SQL
42	end
43
44	def trust_level_guard(parent_id)
45		return unless parent_id
46
47		@trust_level_repo.find(Customer.new(parent_id, "")).then { |tl|
48			existing_subaccounts(parent_id).then { |c| [tl, c] }
49		}.then do |(tl, number_of_subaccounts)|
50			unless tl.create_subaccount?(number_of_subaccounts)
51				raise "Please contact support to create a subaccount"
52			end
53		end
54	end
55end