# frozen_string_literal: true require_relative "./usage_report" class CustomerUsage def initialize(customer_id) @customer_id = customer_id end def usage_report(range) EMPromise.all([ messages_by_day(range), minutes_by_day(range) ]).then do |args| UsageReport.new(range, *args) end end def expire_message_usage today = Time.now.utc.to_date REDIS.zremrangebylex( "jmp_customer_outbound_messages-#{@customer_id}", "-", # Store message counts per day for 1 year "[#{(today << 12).strftime('%Y%m%d')}" ) end def incr_message_usage(amount=1) today = Time.now.utc.to_date EMPromise.all([ expire_message_usage, REDIS.zincrby( "jmp_customer_outbound_messages-#{@customer_id}", amount, today.strftime("%Y%m%d") ) ]) end def message_usage(range) messages_by_day(range).then do |by_day| by_day.values.sum end end def messages_by_day(range) EMPromise.all(range.first.downto(range.last).map { |day| REDIS.zscore( "jmp_customer_outbound_messages-#{@customer_id}", day.strftime("%Y%m%d") ).then { |c| [day, c.to_i] if c } }).then { |r| r.compact.to_h.tap { |h| h.default = 0 } } end QUERY_FOR_MINUTES = <<~SQL SELECT date_trunc('day', start)::date as day, CEIL(SUM(billsec)/60.0)::integer as minutes FROM cdr WHERE customer_id=$1 and start >= $3 and date_trunc('day', start) <= $2 GROUP BY date_trunc('day', start); SQL def minutes_by_day(range) DB.query_defer( QUERY_FOR_MINUTES, [@customer_id, range.first, range.last] ).then do |result| result.each_with_object(Hash.new(0)) do |row, minutes| minutes[row["day"]] = row["minutes"] end end end def calling_charges_this_month DB.query_one(<<~SQL, @customer_id).then { |r| r[:charges] } SELECT COALESCE(SUM(charge), 0) AS charges FROM cdr_with_charge WHERE customer_id=$1 AND start >= DATE_TRUNC('month', LOCALTIMESTAMP) SQL end end