bill_plan_command.rb

 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