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