~singpolyma/sgx-jmp

sgx-jmp/lib/call_attempt_repo.rb -rw-r--r-- 2.1 KiB
4ace3417Stephen Paul Weber Log errors from rev.ai 8 days ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# frozen_string_literal: true

require "value_semantics/monkey_patched"
require "lazy_object"

require_relative "call_attempt"
require_relative "trust_level_repo"

class CallAttemptRepo
	value_semantics do
		db    Anything(), default: LazyObject.new { DB }
		redis Anything(), default: LazyObject.new { REDIS }
	end

	def find_outbound(customer, to, **kwargs)
		find(
			customer,
			to,
			direction: :outbound,
			from: customer.registered?.phone,
			to: to,
			**kwargs
		)
	end

	def find_inbound(customer, from, **kwargs)
		find(
			customer,
			from,
			direction: :inbound,
			from: from,
			to: customer.registered?.phone,
			**kwargs
		)
	end

	def starting_call(customer, call_id)
		redis.sadd(
			"jmp_customer_ongoing_calls-#{customer.customer_id}",
			call_id
		).then do
			redis.expire(
				"jmp_customer_ongoing_calls-#{customer.customer_id}",
				60 * 60
			)
		end
	end

	def ending_call(customer, call_id)
		redis.srem(
			"jmp_customer_ongoing_calls-#{customer.customer_id}",
			call_id
		)
	end

protected

	def find(customer, other_tel, direction:, **kwargs)
		find_all(customer, other_tel, direction).then do |(rate, usage, tl, c)|
			CallAttempt.for(
				customer: customer, rate: rate, usage: usage,
				supported: rate && tl.support_call?(rate, c || 0),
				direction: direction, **kwargs
			)
		end
	end

	def find_all(customer, other_tel, direction)
		EMPromise.all([
			find_rate(customer.plan_name, other_tel, direction),
			find_usage(customer.customer_id),
			TrustLevelRepo.new(db: db, redis: redis).find(customer),
			redis.scard("jmp_customer_ongoing_calls-#{customer.customer_id}")
		])
	end

	def find_usage(customer_id)
		db.query_one(<<~SQL, customer_id, default: { a: 0 }).then { |r| r[:a] }
			SELECT COALESCE(SUM(charge), 0) AS a FROM cdr_with_charge
			WHERE
				customer_id=$1 AND
				start > DATE_TRUNC('month', LOCALTIMESTAMP)
		SQL
	end

	def find_rate(plan_name, other_tel, direction)
		promise = db.query_one(<<~SQL, plan_name, other_tel, direction)
			SELECT rate FROM call_rates
			WHERE
				plan_name=$1 AND
				$2 LIKE prefix || '%' AND
				direction=$3
			ORDER BY prefix DESC
			LIMIT 1
		SQL
		promise.then { |row| row&.dig(:rate) }
	end
end