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), coerce: :to_sym.to_proc
34		rate Either(nil, BigDecimal), default: nil
35		charge Either(nil, BigDecimal), default: nil
36	end
37
38	def formatted_rate
39		"$%.4f" % rate
40	end
41
42	def formatted_charge
43		"$%.4f" % charge
44	end
45
46	def duration
47		"%02d:%02d:%02d" % [
48			billsec / (60 * 60),
49			billsec % (60 * 60) / 60,
50			billsec % 60
51		]
52	end
53
54	def self.for(event, **kwargs)
55		start = Time.parse(event["startTime"])
56
57		new({
58			cdr_id: "sgx-jmp/#{event['callId']}",
59			start: start,
60			billsec: (Time.parse(event["endTime"]) - start).ceil,
61			disposition: Disposition.for(event["cause"], event["tag"])
62		}.merge(kwargs))
63	end
64
65	def self.for_inbound(customer_id, event)
66		self.for(
67			event,
68			customer_id: customer_id,
69			tel: event["from"],
70			direction: :inbound
71		)
72	end
73
74	def self.for_outbound(customer_id, event)
75		self.for(
76			event,
77			customer_id: customer_id,
78			tel: event["to"],
79			direction: :outbound
80		)
81	end
82end