# 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
end