cdr.rb

 1# frozen_string_literal: true
 2
 3require "value_semantics/monkey_patched"
 4
 5class CDR
 6	value_semantics do
 7		cdr_id String
 8		customer_id String
 9		start Time
10		billsec Integer
11		disposition Either("NO ANSWER", "ANSWERED", "BUSY", "FAILED")
12		tel(/\A\+\d+\Z/)
13		direction Either(:inbound, :outbound)
14	end
15
16	def self.for(event, **kwargs)
17		start = Time.parse(event["startTime"])
18
19		new({
20			cdr_id: "sgx-jmp/#{event['callId']}",
21			start: start,
22			billsec: (Time.parse(event["endTime"]) - start).ceil,
23			disposition: Disposition.for(event["cause"])
24		}.merge(kwargs))
25	end
26
27	def self.for_inbound(customer_id, event)
28		self.for(
29			event,
30			customer_id: customer_id,
31			tel: event["from"],
32			direction: :inbound
33		)
34	end
35
36	def self.for_outbound(event)
37		self.for(
38			event,
39			customer_id: event["from"].sub(/^\+/, ""),
40			tel: event["to"],
41			direction: :outbound
42		)
43	end
44
45	def save
46		columns, values = to_h.to_a.transpose
47		DB.query_defer(<<~SQL, values)
48			INSERT INTO cdr (#{columns.join(',')})
49			VALUES ($1, $2, $3, $4, $5, $6, $7)
50		SQL
51	end
52
53	module Disposition
54		def self.for(cause)
55			case cause
56			when "timeout", "rejected", "cancel"
57				"NO ANSWER"
58			when "hangup"
59				"ANSWERED"
60			when "busy"
61				"BUSY"
62			else
63				"FAILED"
64			end
65		end
66	end
67end