bill_plan_command.rb

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