# 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) 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 def save columns, values = to_h.to_a.transpose DB.query_defer(<<~SQL, values) INSERT INTO cdr (#{columns.join(',')}) VALUES ($1, $2, $3, $4, $5, $6, $7) SQL end end