1# frozen_string_literal: true
2
3require "bigdecimal"
4require "forwardable"
5require "relative_time"
6require "value_semantics/monkey_patched"
7require_relative "proxied_jid"
8require_relative "customer_plan"
9require_relative "form_template"
10require_relative "promise_hash"
11
12class PlanInfo
13 extend Forwardable
14
15 def_delegators :plan, :expires_at, :auto_top_up_amount
16
17 def self.for(plan)
18 return EMPromise.resolve(NoPlan.new) unless plan&.plan_name
19
20 plan.activation_date.then do |adate|
21 new(plan: plan, start_date: adate)
22 end
23 end
24
25 class NoPlan
26 def template
27 FormTemplate.new("")
28 end
29
30 def admin_template
31 FormTemplate.new("")
32 end
33
34 def status
35 "Transitional"
36 end
37 end
38
39 value_semantics do
40 plan CustomerPlan
41 start_date Time
42 end
43
44 def template
45 FormTemplate.for("plan_info", plan_info: self)
46 end
47
48 def admin_template
49 FormTemplate.for("admin_plan_info", plan_info: self)
50 end
51
52 def monthly_price
53 "$%.4f / month" % plan.monthly_price
54 end
55
56 def relative_start_date
57 RelativeTime.in_words(start_date)
58 end
59
60 def formatted_start_date
61 start_date.strftime("%Y-%m-%d %H:%M:%S")
62 end
63
64 def currency
65 (plan.currency || "No Currency").to_s
66 end
67
68 def status
69 plan.active? ? "Active" : "Expired"
70 end
71end
72
73class CustomerInfo
74 value_semantics do
75 plan_info Either(PlanInfo, PlanInfo::NoPlan)
76 tel Either(String, nil)
77 balance BigDecimal
78 cnam Either(String, nil)
79 end
80
81 def self.for(customer, plan)
82 PromiseHash.all(
83 plan_info: PlanInfo.for(plan),
84 tel: customer.registered? ? customer.registered?.phone : nil,
85 balance: customer.balance,
86 cnam: customer.tndetails.dig(:features, :lidb, :subscriber_information)
87 ).then(&method(:new))
88 end
89
90 def form
91 FormTemplate.render("customer_info", info: self)
92 end
93end
94
95class AdminInfo
96 value_semantics do
97 jid ProxiedJID, coerce: ProxiedJID.method(:new)
98 customer_id String
99 fwd Either(CustomerFwd, nil)
100 info CustomerInfo
101 api API
102 call_info String
103 end
104
105 def self.for(customer, plan)
106 PromiseHash.all(
107 jid: customer.jid,
108 customer_id: customer.customer_id,
109 fwd: customer.fwd,
110 info: CustomerInfo.for(customer, plan),
111 api: customer.api,
112 call_info: call_info(customer)
113 ).then(&method(:new))
114 end
115
116 class FakeLowBalance
117 def self.for(_)
118 self
119 end
120
121 def self.notify!
122 EMPromise.resolve(0)
123 end
124 end
125
126 def self.call_info(customer)
127 if customer.registered?
128 CallAttemptRepo.new
129 .find_outbound(customer, "+1", call_id: "", low_balance: FakeLowBalance)
130 .then(&:to_s)
131 else
132 EMPromise.resolve("No calling")
133 end
134 end
135
136 def form
137 FormTemplate.render("admin_info", admin_info: self)
138 end
139
140 def tel_link
141 [
142 "https://dashboard.bandwidth.com/portal/r/a",
143 CONFIG[:creds][:account],
144 "numbers/details",
145 info.tel.gsub(/\A\+1/, "")
146 ].join("/")
147 end
148end