# frozen_string_literal: true require "value_semantics/monkey_patched" class CDR module Disposition def self.===(other) ["NO ANSWER", "ANSWERED", "BUSY", "FAILED", "VOICEMAIL"].include?(other) end CAUSES = { timeout: "NO ANSWER", rejected: "NO ANSWER", cancel: "NO ANSWER", hangup: "ANSWERED", busy: "BUSY" }.freeze def self.for(cause, tag) return tag if tag == "VOICEMAIL" CAUSES.fetch(cause.to_sym, "FAILED") end end value_semantics do cdr_id String customer_id String start Time billsec Integer disposition Disposition tel(/\A\+\d+\Z/) direction Either(:inbound, :outbound), coerce: :to_sym.to_proc rate Either(nil, BigDecimal), default: nil charge Either(nil, BigDecimal), default: nil end def formatted_rate "$%.4f" % rate end def formatted_charge "$%.4f" % charge end def duration "%02d:%02d:%02d" % [ billsec / (60 * 60), billsec % (60 * 60) / 60, billsec % 60 ] end def self.for(event, **kwargs) start = Time.parse(event["startTime"]) new({ cdr_id: "sgx-jmp/#{event['callId']}", start: start, billsec: (Time.parse(event["endTime"]) - start).ceil, disposition: Disposition.for(event["cause"], event["tag"]) }.merge(kwargs)) end def self.for_inbound(customer_id, event) self.for( event, customer_id: customer_id, tel: event["from"], direction: :inbound ) end def self.for_outbound(event) self.for( event, customer_id: event["from"].sub(/^\+/, ""), tel: event["to"], direction: :outbound ) end end