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