plan.rb

  1# frozen_string_literal: true
  2
  3class Plan
  4	def self.for(plan_name)
  5		return plan_name if plan_name.is_a?(Plan)
  6
  7		plan = CONFIG[:plans].find { |p| p[:name] == plan_name }
  8		raise "No plan by that name" unless plan
  9
 10		new(plan)
 11	end
 12
 13	def self.for_registration(plan_name)
 14		plan = self.for(plan_name)
 15		raise "No registration plan by that name" unless plan.allow_register?
 16
 17		plan
 18	end
 19
 20	def initialize(plan)
 21		@plan = plan
 22	end
 23
 24	def name
 25		@plan[:name]
 26	end
 27
 28	def currency
 29		@plan[:currency]
 30	end
 31
 32	def monthly_price
 33		BigDecimal(@plan[:monthly_price]) / 10000
 34	end
 35
 36	def allow_register?
 37		!!@plan[:allow_register]
 38	end
 39
 40	def merchant_account
 41		CONFIG[:braintree][:merchant_accounts].fetch(currency) do
 42			raise "No merchant account for this currency"
 43		end
 44	end
 45
 46	def minute_limit
 47		CallingLimit.new(Limit.for("minute", @plan[:minutes]))
 48	end
 49
 50	def message_limit
 51		Limit.for("message", @plan[:messages])
 52	end
 53
 54	class Limit
 55		def self.for(unit, from_config)
 56			case from_config
 57			when :unlimited
 58				Unlimited.new(unit)
 59			else
 60				new(unit: unit, **from_config)
 61			end
 62		end
 63
 64		value_semantics do
 65			unit String
 66			included Integer
 67			price Integer
 68		end
 69
 70		def to_s
 71			"#{included} #{unit}s " \
 72			"(overage $#{'%.4f' % (price.to_d / 10000)} / #{unit})"
 73		end
 74
 75		def to_d
 76			included.to_d / 10000
 77		end
 78
 79		class Unlimited
 80			def initialize(unit)
 81				@unit = unit
 82			end
 83
 84			def to_s
 85				"unlimited #{@unit}s"
 86			end
 87		end
 88	end
 89
 90	class CallingLimit
 91		def initialize(limit)
 92			@limit = limit
 93		end
 94
 95		def to_d
 96			@limit.to_d
 97		end
 98
 99		def to_s
100			"#{'$%.4f' % to_d} of calling credit per calendar month " \
101			"(overage $#{'%.4f' % (@limit.price.to_d / 10000)} / minute)"
102		end
103	end
104end