# 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
protected
def find(customer, other_tel, direction:, **kwargs)
EMPromise.all([
find_rate(customer.plan_name, other_tel, direction),
find_usage(customer.customer_id),
TrustLevelRepo.new(db: db, redis: redis).find(customer)
]).then do |(rate, usage, trust_level)|
CallAttempt.for(
customer, rate, usage, trust_level, direction: direction, **kwargs
)
end
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