call_attempt_repo.rb

 1# frozen_string_literal: true
 2
 3require "value_semantics/monkey_patched"
 4require "lazy_object"
 5
 6require_relative "call_attempt"
 7
 8class CallAttemptRepo
 9	value_semantics do
10		db Anything(), default: LazyObject.new { DB }
11	end
12
13	def find(customer, other_tel, direction: :outbound, **kwargs)
14		EMPromise.all([
15			find_rate(customer.plan_name, other_tel, direction),
16			find_usage(customer.customer_id)
17		]).then do |(rate, usage)|
18			CallAttempt.for(
19				customer, other_tel, rate, usage, direction: direction, **kwargs
20			)
21		end
22	end
23
24protected
25
26	def find_usage(customer_id)
27		promise = db.query_defer(<<~SQL, [customer_id])
28			SELECT COALESCE(SUM(charge), 0) AS a FROM cdr_with_charge
29			WHERE
30				customer_id=$1 AND
31				start > DATE_TRUNC('month', LOCALTIMESTAMP)
32		SQL
33		promise.then { |rows| -(rows.first&.dig("a") || 0) }
34	end
35
36	def find_rate(plan_name, other_tel, direction)
37		promise = db.query_defer(<<~SQL, [plan_name, other_tel, direction])
38			SELECT rate FROM call_rates
39			WHERE
40				plan_name=$1 AND
41				$2 LIKE prefix || '%' AND
42				direction=$3
43			ORDER BY prefix DESC
44			LIMIT 1;
45		SQL
46		promise.then { |rows| rows.first&.dig("rate") }
47	end
48end