1# frozen_string_literal: true
2
3class BillPlanCommand
4 def self.for(customer)
5 return ForUnregistered.new(customer) unless customer.registered?
6 return ForNotExpired.new(customer) unless customer.expires_at <= Time.now
7
8 unless customer.balance > customer.monthly_price
9 return ForLowBalance.new(customer)
10 end
11
12 new(customer)
13 end
14
15 def initialize(customer)
16 @customer = customer
17 end
18
19 def call
20 billed = @customer.bill_plan(note: "Renew account plan") { |db|
21 @customer = Command.execution.customer_repo.with(db: db)
22 .find(@customer.customer_id).sync
23 @customer.balance > @customer.monthly_price &&
24 @customer.expires_at <= Time.now
25 }
26 Command.reply do |reply|
27 reply.note_type = billed ? :info : :error
28 reply.note_text = "#{@customer.customer_id}#{billed ? '' : ' not'} billed"
29 end
30 end
31
32 class ForLowBalance
33 def initialize(customer)
34 @customer = customer
35 end
36
37 def call
38 LowBalance.for(@customer).then(&:notify!).then do |amount|
39 next command_for(amount).call if amount&.positive?
40
41 notify_failure
42 Command.reply do |reply|
43 reply.note_type = :error
44 reply.note_text = "#{@customer.customer_id} balance is too low"
45 end
46 end
47 end
48
49 protected
50
51 def notify_failure
52 m = Blather::Stanza::Message.new
53 m.from = CONFIG[:notify_from]
54 m.body =
55 "Failed to renew account for #{@customer.registered?.phone}. " \
56 "To keep your number, please buy more credit soon."
57 @customer.stanza_to(m)
58 end
59
60 def command_for(amount)
61 BillPlanCommand.for(
62 @customer.with_balance(@customer.balance + amount)
63 )
64 end
65 end
66
67 class ForUnregistered
68 def initialize(customer)
69 @customer = customer
70 end
71
72 def call
73 Command.reply do |reply|
74 reply.note_type = :error
75 reply.note_text = "#{@customer.customer_id} is not registered"
76 end
77 end
78 end
79
80 class ForNotExpired
81 def initialize(customer)
82 @customer = customer
83 end
84
85 def call
86 Command.reply do |reply|
87 reply.note_type = :error
88 reply.note_text = "#{@customer.customer_id} is not expired"
89 end
90 end
91 end
92end