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 trust_level_guard(customer_id).then {
28 @redis.get("jmp_customer_parent_code-#{customer_id}")
29 }.then do |code|
30 next code if code
31
32 code = "p#{Multibases.pack('base32upper', SecureRandom.bytes(4))}"
33 EMPromise.all([
34 @redis.set("jmp_customer_parent_code-#{customer_id}", code),
35 @redis.hset("jmp_parent_codes", code, customer_id)
36 ]).then { code }
37 end
38 end
39
40 def existing_subaccounts(parent_id)
41 @db.query_one(<<~SQL, parent_id, default: { c: 0 }).then { |r| r[:c] }
42 SELECT COUNT(*) AS c FROM customer_plans WHERE parent_customer_id=$1
43 SQL
44 end
45
46 def trust_level_guard(parent_id)
47 return unless parent_id
48
49 @trust_level_repo.find(Customer.new(parent_id, "", sgx: nil)).then { |tl|
50 existing_subaccounts(parent_id).then { |c| [tl, c] }
51 }.then do |(tl, number_of_subaccounts)|
52 unless tl.create_subaccount?(number_of_subaccounts)
53 raise "Please contact support to create a subaccount"
54 end
55 end
56 end
57end