@@ 6,33 6,32 @@ require_relative "tts_template"
require_relative "low_balance"
class CallAttempt
- def self.for(customer, rate, usage, supported, **kwargs)
+ def self.for(customer:, usage:, **kwargs)
credit = [customer.minute_limit.to_d - usage, 0].max + customer.balance
- if !supported
- Unsupported.new(**kwargs.slice(:direction))
- elsif credit < rate * 10
- NoBalance.for(customer, rate, usage, supported, **kwargs)
- else
- for_ask_or_go(customer, rate, usage, credit, **kwargs)
+ @kinds.each do |kind|
+ ca = kind.call(
+ customer: customer, usage: usage, credit: credit,
+ **kwargs.merge(limits(customer, usage, credit, **kwargs))
+ )
+ return ca if ca
end
+
+ raise "No CallAttempt matched"
end
- def self.for_ask_or_go(customer, rate, usage, credit, digits: nil, **kwargs)
- kwargs.merge!(
- customer_id: customer.customer_id,
- limit_remaining: limit_remaining(customer, usage, rate),
+ def self.limits(customer, usage, credit, rate:, **)
+ return {} unless customer && usage && rate
+
+ can_use = customer.minute_limit.to_d + customer.monthly_overage_limit
+ {
+ limit_remaining: ([can_use - usage, 0].max / rate).to_i,
max_minutes: (credit / rate).to_i
- )
- if digits != "1" && limit_remaining(customer, usage, rate) < 10
- AtLimit.new(**kwargs)
- else
- new(**kwargs)
- end
+ }
end
- def self.limit_remaining(customer, usage, rate)
- can_use = customer.minute_limit.to_d + customer.monthly_overage_limit
- ([can_use - usage, 0].max / rate).to_i
+ def self.register(&maybe_mk)
+ @kinds ||= []
+ @kinds << maybe_mk
end
value_semantics do
@@ 67,7 66,43 @@ class CallAttempt
as_json.to_json(*args)
end
+ class Expired
+ CallAttempt.register do |customer:, direction:, **|
+ new(direction: direction) if customer.plan_name && !customer.active?
+ end
+
+ value_semantics do
+ direction Either(:inbound, :outbound)
+ end
+
+ def view
+ "#{direction}/expired"
+ end
+
+ def tts
+ TTSTemplate.new(view).tts(self)
+ end
+
+ def to_render
+ [view]
+ end
+
+ def create_call(*); end
+
+ def as_json(*)
+ { tts: tts }
+ end
+
+ def to_json(*args)
+ as_json.to_json(*args)
+ end
+ end
+
class Unsupported
+ CallAttempt.register do |supported:, direction:, **|
+ new(direction: direction) unless supported
+ end
+
value_semantics do
direction Either(:inbound, :outbound)
end
@@ 96,12 131,16 @@ class CallAttempt
end
class NoBalance
- def self.for(customer, rate, usage, supported, direction:, **kwargs)
+ CallAttempt.register do |credit:, rate:, **kwargs|
+ self.for(rate: rate, **kwargs) if credit < rate * 10
+ end
+
+ def self.for(customer:, direction:, **kwargs)
LowBalance.for(customer).then(&:notify!).then do |amount|
if amount&.positive?
CallAttempt.for(
- customer.with_balance(customer.balance + amount),
- rate, usage, supported, direction: direction, **kwargs
+ customer: customer.with_balance(customer.balance + amount),
+ **kwargs.merge(direction: direction)
)
else
NoBalance.new(balance: customer.balance, direction: direction)
@@ 148,6 187,18 @@ class CallAttempt
max_minutes Integer
end
+ CallAttempt.register do |digits: nil, limit_remaining:, customer:, **kwargs|
+ if digits != "1" && limit_remaining < 10
+ new(
+ **kwargs
+ .merge(
+ limit_remaining: limit_remaining,
+ customer_id: customer.customer_id
+ ).slice(*value_semantics.attributes.map(&:name))
+ )
+ end
+ end
+
def view
"#{direction}/at_limit"
end
@@ 179,4 230,12 @@ class CallAttempt
as_json.to_json(*args)
end
end
+
+ register do |**kwargs|
+ new(
+ **kwargs
+ .merge(customer_id: customer.customer_id)
+ .slice(*value_semantics.attributes.map(&:name))
+ )
+ end
end
@@ 58,8 58,8 @@ protected
def find(customer, other_tel, direction:, **kwargs)
find_all(customer, other_tel, direction).then do |(rate, usage, tl, c)|
CallAttempt.for(
- customer, rate, usage,
- rate && tl.support_call?(rate, c || 0),
+ customer: customer, rate: rate, usage: usage,
+ supported: rate && tl.support_call?(rate, c || 0),
direction: direction, **kwargs
)
end