# frozen_string_literal: true class BillPlanCommand def self.for(customer) return ForUnregistered.new unless customer.registered? unless customer.balance > customer.monthly_price return ForLowBalance.new(customer) end new(customer) end def initialize(customer) @customer = customer end def call @customer.bill_plan Command.reply do |reply| reply.note_type = :info reply.note_text = "Customer billed" end end class ForLowBalance def initialize(customer) @customer = customer end def call LowBalance.for(@customer).then(&:notify!).then do |amount| return command_for(amount).call if amount&.positive? notify_failure Command.reply do |reply| reply.note_type = :error reply.note_text = "Customer balance is too low" end end end protected def notify_failure m = Blather::Stanza::Message.new m.from = CONFIG[:notify_from] m.body = "Failed to renew account for #{@customer.registered?.phone}. " \ "To keep your number, please buy more credit soon." @customer.stanza_to(m) end def command_for(amount) BillPlanCommand.for( @customer.with_balance(@customer.balance + amount) ) end end class ForUnregistered def call Command.reply do |reply| reply.note_type = :error reply.note_text = "Customer is not registered" end end end end