# 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) promise = db.query_defer(<<~SQL, [customer_id]) SELECT COALESCE(SUM(charge), 0) AS a FROM cdr_with_charge WHERE customer_id=$1 AND start > DATE_TRUNC('month', LOCALTIMESTAMP) SQL promise.then { |rows| rows.first&.dig("a") || 0 } end def find_rate(plan_name, other_tel, direction) promise = db.query_defer(<<~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 { |rows| rows.first&.dig("rate") } end end