Use pending group invite code when finishing

Stephen Paul Weber created

Change summary

lib/invites_repo.rb       | 21 +++++++++++++++++++++
lib/registration.rb       | 26 +++++++++++++++++++++-----
test/test_registration.rb | 31 +++++++++++++++++++++++++++++++
3 files changed, 73 insertions(+), 5 deletions(-)

Detailed changes

lib/invites_repo.rb 🔗

@@ -21,6 +21,20 @@ class InvitesRepo
 		@redis.set("jmp_customer_pending_invite-#{customer_id}", code)
 	end
 
+	def use_pending_group_code(customer_id)
+		@redis.get("jmp_customer_pending_invite-#{customer_id}").then do |code|
+			EMPromise.all([
+				@redis.del("jmp_customer_pending_invite-#{customer_id}"),
+				@redis.hget("jmp_group_codes", code)
+			]).then do |(_, credit_to)|
+				next false if credit_to.to_s.strip == ""
+
+				create_claimed_code(credit_to, customer_id)
+				credit_to
+			end
+		end
+	end
+
 	CLAIM_SQL = <<~SQL
 		UPDATE invites SET used_by_id=$1, used_at=LOCALTIMESTAMP
 		WHERE code=$2 AND used_by_id IS NULL
@@ -39,6 +53,13 @@ class InvitesRepo
 		end
 	end
 
+	def create_claimed_code(creator_id, used_by_id)
+		@db.exec(<<~SQL, [creator_id, used_by_id])
+			INSERT INTO invites (creator_id, used_by_id, used_at)
+			VALUES ($1, $2, LOCALTIMESTAMP)
+		SQL
+	end
+
 	CREATE_N_SQL = <<~SQL
 		INSERT INTO invites
 			SELECT unnest(array_fill($1::text, array[$2::int]))

lib/registration.rb 🔗

@@ -215,10 +215,10 @@ class Registration
 			def activate
 				DB.transaction do
 					if @credit_to
-						DB.exec(<<~SQL, [@credit_to, customer.customer_id])
-							INSERT INTO invites (creator_id, used_by_id, used_at)
-							VALUES ($1, $2, LOCALTIMESTAMP)
-						SQL
+						InvitesRepo.new(DB, REDIS).create_claimed_code(
+							@credit_to,
+							customer.customer_id
+						)
 					end
 					@customer.activate_plan_starting_now
 				end
@@ -519,6 +519,7 @@ class Registration
 		def initialize(customer, tel)
 			@customer = customer
 			@tel = tel
+			@invites = InvitesRepo.new(DB, REDIS)
 		end
 
 		def write
@@ -561,11 +562,26 @@ class Registration
 			))
 		end
 
+		def use_referral_code
+			@invites.use_pending_group_code(@customer.customer_id).then do |credit_to|
+				next unless credit_to
+
+				Transaction.new(
+					customer_id: @customer.customer_id,
+					transaction_id: "referral_#{@customer.customer_id}_#{credit_to}",
+					amount: @customer.monthly_price,
+					note: "Referral Bonus",
+					bonus_eligible?: false
+				).insert
+			end
+		end
+
 		def customer_active_tel_purchased
 			@customer.register!(@tel).catch(&method(:raise_setup_error)).then {
 				EMPromise.all([
 					REDIS.del("pending_tel_for-#{@customer.jid}"),
-					put_default_fwd
+					put_default_fwd,
+					use_referral_code
 				])
 			}.then do
 				FinishOnboarding.for(@customer, @tel).then(&:write)

test/test_registration.rb 🔗

@@ -767,6 +767,7 @@ class RegistrationTest < Minitest::Test
 		Command::COMMAND_MANAGER = Minitest::Mock.new
 		Registration::Finish::TEL_SELECTIONS = FakeTelSelections.new
 		Registration::Finish::REDIS = Minitest::Mock.new
+		Registration::Finish::DB = Minitest::Mock.new
 		Bwmsgsv2Repo::REDIS = Minitest::Mock.new
 		Registration::FinishOnboarding::DB = FakeDB.new
 
@@ -813,6 +814,21 @@ class RegistrationTest < Minitest::Test
 				nil,
 				["pending_tel_for-test@example.net"]
 			)
+			Registration::Finish::REDIS.expect(
+				:get,
+				nil,
+				["jmp_customer_pending_invite-test"]
+			)
+			Registration::Finish::REDIS.expect(
+				:del,
+				nil,
+				["jmp_customer_pending_invite-test"]
+			)
+			Registration::Finish::REDIS.expect(
+				:hget,
+				nil,
+				["jmp_group_codes", nil]
+			)
 			Bwmsgsv2Repo::REDIS.expect(
 				:set,
 				nil,
@@ -902,6 +918,21 @@ class RegistrationTest < Minitest::Test
 				nil,
 				["pending_tel_for-test\\40onboarding.example.com@proxy"]
 			)
+			Registration::Finish::REDIS.expect(
+				:get,
+				nil,
+				["jmp_customer_pending_invite-test"]
+			)
+			Registration::Finish::REDIS.expect(
+				:del,
+				nil,
+				["jmp_customer_pending_invite-test"]
+			)
+			Registration::Finish::REDIS.expect(
+				:hget,
+				nil,
+				["jmp_group_codes", nil]
+			)
 			Bwmsgsv2Repo::REDIS.expect(
 				:set,
 				nil,