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