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