# frozen_string_literal: true class BillPlanCommand def self.for(customer) return ForUnregistered.new(customer) 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(note: "Renew account plan") Command.reply do |reply| reply.note_type = :info reply.note_text = "#{@customer.customer_id} billed" end end class ForLowBalance def initialize(customer) @customer = customer end def call LowBalance.for(@customer).then(&:notify!).then do |amount| next command_for(amount).call if amount&.positive? notify_failure Command.reply do |reply| reply.note_type = :error reply.note_text = "#{@customer.customer_id} 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 initialize(customer) @customer = customer end def call Command.reply do |reply| reply.note_type = :error reply.note_text = "#{@customer.customer_id} is not registered" end end end end