# 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