Calculate the maximum allowable call length

Stephen Paul Weber created

Asterisk could use this to actually limit the call, for example.

Change summary

lib/call_attempt.rb | 34 +++++++++++++++++++++++++---------
1 file changed, 25 insertions(+), 9 deletions(-)

Detailed changes

lib/call_attempt.rb 🔗

@@ -8,32 +8,42 @@ require_relative "low_balance"
 class CallAttempt
 	def self.for(customer, rate, usage, trust_level, direction:, **kwargs)
 		kwargs.merge!(direction: direction)
-		included_credit = [customer.minute_limit.to_d - usage, 0].max
+		credit = [customer.minute_limit.to_d - usage, 0].max + customer.balance
 		if !rate || !trust_level.support_call?(rate)
 			Unsupported.new(direction: direction)
-		elsif included_credit + customer.balance < rate * 10
+		elsif credit < rate * 10
 			NoBalance.for(customer, rate, usage, trust_level, **kwargs)
 		else
-			for_ask_or_go(customer, rate, usage, **kwargs)
+			for_ask_or_go(customer, rate, usage, credit, **kwargs)
 		end
 	end
 
-	def self.for_ask_or_go(customer, rate, usage, digits: nil, **kwargs)
-		can_use = customer.minute_limit.to_d + customer.monthly_overage_limit
-		kwargs.merge!(customer_id: customer.customer_id)
-		if digits != "1" && can_use - usage < rate * 10
+	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),
+			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
+	end
+
 	value_semantics do
 		customer_id String
 		from String
 		to(/\A\+\d+\Z/)
 		call_id String
 		direction Either(:inbound, :outbound)
+		limit_remaining Integer
+		max_minutes Integer
 	end
 
 	def to_render
@@ -48,7 +58,9 @@ class CallAttempt
 		{
 			from: from,
 			to: to,
-			customer_id: customer_id
+			customer_id: customer_id,
+			limit_remaining: limit_remaining,
+			max_minutes: max_minutes
 		}
 	end
 
@@ -133,6 +145,8 @@ class CallAttempt
 			to(/\A\+\d+\Z/)
 			call_id String
 			direction Either(:inbound, :outbound)
+			limit_remaining Integer
+			max_minutes Integer
 		end
 
 		def view
@@ -156,7 +170,9 @@ class CallAttempt
 				tts: tts,
 				from: from,
 				to: to,
-				customer_id: customer_id
+				customer_id: customer_id,
+				limit_remaining: limit_remaining,
+				max_minutes: max_minutes
 			}
 		end