number_change.rb

 1# frozen_string_literal: true
 2
 3require "value_semantics/monkey_patched"
 4require_relative "../admin_action"
 5require_relative "../form_to_h"
 6
 7class AdminAction
 8	class NumberChange < AdminAction
 9		include Isomorphic
10		class Command
11			using FormToH
12
13			def self.for(target_customer, reply:)
14				EMPromise.resolve(
15					new(
16						customer_id: target_customer.customer_id,
17						old_tel: target_customer.registered?.phone
18					)
19				).then { |x|
20					reply.call(x.form).then(&x.method(:change))
21				}
22			end
23
24			def initialize(**bag)
25				@bag = bag
26			end
27
28			def form
29				FormTemplate.render("admin_number_change")
30			end
31
32			def change(result)
33				AdminAction::NumberChange.for(
34					**@bag,
35					**result.form.to_h
36						.reject { |_k, v| v == "nil" }.transform_keys(&:to_sym)
37				)
38			end
39		end
40
41		NilKey = Struct.new(:key) {
42			def to_s
43			 "Expected a key with a value, but #{key} has no value."
44			end
45		}
46
47		def customer_id
48			@attributes[:customer_id]
49		end
50
51		def old_tel
52			@attributes[:old_tel]
53		end
54
55		def new_tel
56			@attributes[:new_tel]
57		end
58
59		def check_forward
60			EMPromise.all([
61				check_noop,
62				check_exist
63			])
64		end
65
66		def forward
67			sgx = TrivialBackendSgxRepo.new.get(customer_id)
68			EMPromise.all([
69				REDIS.rename("catapult_fwd-#{old_tel}", "catapult_fwd-#{new_tel}"),
70				sgx.register!(new_tel)
71			]).then { self }
72		end
73
74		def to_reverse
75			with(
76			 old_tel: new_tel,
77			 new_tel: old_tel
78			)
79		end
80
81		def to_s
82			"number_change(#{customer_id}): #{old_tel} -> #{new_tel}"
83		end
84
85	protected
86
87		def check_noop
88		 EMPromise.reject(NoOp.new) if new_tel == old_tel
89		end
90
91		def check_exist
92			cat_jid = "catapult_jid-#{old_tel}"
93			REDIS.exists(cat_jid).then { |v|
94				EMPromise.reject(NilKey.new(cat_jid)) unless v == 1
95			}
96		end
97	end
98end