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