diff --git a/lib/call_attempt.rb b/lib/call_attempt.rb index c08f443efbd50e11db3a5f53bc7fac6a03e1dfe5..072a5c52eac84feaa15e6499d0b22ddab07ea32b 100644 --- a/lib/call_attempt.rb +++ b/lib/call_attempt.rb @@ -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 diff --git a/lib/call_attempt_repo.rb b/lib/call_attempt_repo.rb index 5e34cd9ff3bbbdf8bbe4ce6812982497b6dd2649..89bfc6336a6e2e0636bd8cc424a65d08852abe9c 100644 --- a/lib/call_attempt_repo.rb +++ b/lib/call_attempt_repo.rb @@ -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 diff --git a/views/inbound/expired.slim b/views/inbound/expired.slim new file mode 100644 index 0000000000000000000000000000000000000000..68e146def972c111d1df3a816975dd7482678fb4 --- /dev/null +++ b/views/inbound/expired.slim @@ -0,0 +1,3 @@ +doctype xml +Response + Hangup / diff --git a/views/outbound/expired.slim b/views/outbound/expired.slim new file mode 100644 index 0000000000000000000000000000000000000000..000718004f42ea15dfd69e6e9a8db4faefa9abdb --- /dev/null +++ b/views/outbound/expired.slim @@ -0,0 +1,3 @@ +doctype xml +Response + SpeakSentence Your account is expired, please top up soon to keep your number.